You can subscribe to this list here.
2004 |
Jan
|
Feb
|
Mar
|
Apr
(248) |
May
(82) |
Jun
(90) |
Jul
(177) |
Aug
(253) |
Sep
(157) |
Oct
(151) |
Nov
(143) |
Dec
(278) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2005 |
Jan
(152) |
Feb
(107) |
Mar
(177) |
Apr
(133) |
May
(259) |
Jun
(81) |
Jul
(119) |
Aug
(306) |
Sep
(416) |
Oct
(240) |
Nov
(329) |
Dec
(206) |
2006 |
Jan
(466) |
Feb
(382) |
Mar
(153) |
Apr
(162) |
May
(133) |
Jun
(21) |
Jul
(18) |
Aug
(37) |
Sep
(97) |
Oct
(114) |
Nov
(110) |
Dec
(28) |
2007 |
Jan
(74) |
Feb
(65) |
Mar
(49) |
Apr
(76) |
May
(43) |
Jun
(15) |
Jul
(68) |
Aug
(55) |
Sep
(63) |
Oct
(59) |
Nov
(70) |
Dec
(66) |
2008 |
Jan
(71) |
Feb
(60) |
Mar
(120) |
Apr
(31) |
May
(48) |
Jun
(81) |
Jul
(107) |
Aug
(51) |
Sep
(80) |
Oct
(83) |
Nov
(83) |
Dec
(79) |
2009 |
Jan
(83) |
Feb
(110) |
Mar
(97) |
Apr
(91) |
May
(291) |
Jun
(250) |
Jul
(197) |
Aug
(58) |
Sep
(54) |
Oct
(122) |
Nov
(68) |
Dec
(34) |
2010 |
Jan
(50) |
Feb
(17) |
Mar
(63) |
Apr
(61) |
May
(84) |
Jun
(81) |
Jul
(138) |
Aug
(144) |
Sep
(78) |
Oct
(26) |
Nov
(30) |
Dec
(61) |
2011 |
Jan
(33) |
Feb
(35) |
Mar
(166) |
Apr
(221) |
May
(109) |
Jun
(76) |
Jul
(27) |
Aug
(37) |
Sep
(1) |
Oct
(4) |
Nov
(2) |
Dec
(1) |
2012 |
Jan
|
Feb
|
Mar
(2) |
Apr
(2) |
May
|
Jun
|
Jul
(1) |
Aug
|
Sep
(1) |
Oct
|
Nov
(1) |
Dec
|
2013 |
Jan
|
Feb
(1) |
Mar
|
Apr
|
May
|
Jun
|
Jul
(1) |
Aug
(1) |
Sep
(3) |
Oct
(2) |
Nov
|
Dec
(1) |
2014 |
Jan
(1) |
Feb
(1) |
Mar
(3) |
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
From: <fab...@us...> - 2011-06-15 19:19:52
|
Revision: 5929 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5929&view=rev Author: fabiomaulo Date: 2011-06-15 19:19:46 +0000 (Wed, 15 Jun 2011) Log Message: ----------- Refactoring: moved extension-method in ISqlCommand instance Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/Loader/QueryLoader.cs trunk/nhibernate/src/NHibernate/Hql/Classic/QueryTranslator.cs trunk/nhibernate/src/NHibernate/Loader/Criteria/CriteriaLoader.cs trunk/nhibernate/src/NHibernate/Param/ParametersBackTrackExtensions.cs trunk/nhibernate/src/NHibernate/SqlCommand/SqlCommandImpl.cs Modified: trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/Loader/QueryLoader.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/Loader/QueryLoader.cs 2011-06-14 23:05:35 UTC (rev 5928) +++ trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/Loader/QueryLoader.cs 2011-06-15 19:19:46 UTC (rev 5929) @@ -469,13 +469,10 @@ /// <returns>A CommandWrapper wrapping an IDbCommand that is ready to be executed.</returns> protected internal override IDbCommand PrepareQueryCommand(QueryParameters queryParameters, bool scroll, ISessionImplementor session) { - var sqlCommand = (SqlCommandImpl)CreateSqlCommand(queryParameters, session); - var parameterSpecs = sqlCommand.Specifications; + var sqlCommand = CreateSqlCommand(queryParameters, session); var sqlString = sqlCommand.Query; - var sqlQueryParametersList = sqlCommand.SqlQueryParametersList; - - parameterSpecs.SetQueryParameterLocations(sqlQueryParametersList, session.Factory); + sqlCommand.ResetParametersIndexesForTheCommand(0); IDbCommand command = session.Batcher.PrepareQueryCommand(CommandType.Text, sqlString, sqlCommand.ParameterTypes); try Modified: trunk/nhibernate/src/NHibernate/Hql/Classic/QueryTranslator.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Hql/Classic/QueryTranslator.cs 2011-06-14 23:05:35 UTC (rev 5928) +++ trunk/nhibernate/src/NHibernate/Hql/Classic/QueryTranslator.cs 2011-06-15 19:19:46 UTC (rev 5929) @@ -337,13 +337,10 @@ /// <returns>A CommandWrapper wrapping an IDbCommand that is ready to be executed.</returns> protected internal override IDbCommand PrepareQueryCommand(QueryParameters queryParameters, bool scroll, ISessionImplementor session) { - var sqlCommand = (SqlCommandImpl)CreateSqlCommand(queryParameters, session); - var parameterSpecs = sqlCommand.Specifications; + var sqlCommand = CreateSqlCommand(queryParameters, session); var query = sqlCommand.Query; - var sqlQueryParametersList = sqlCommand.SqlQueryParametersList; - parameterSpecs.SetQueryParameterLocations(sqlQueryParametersList, session.Factory); - + sqlCommand.ResetParametersIndexesForTheCommand(0); IDbCommand command = session.Batcher.PrepareQueryCommand(CommandType.Text, query, sqlCommand.ParameterTypes); try Modified: trunk/nhibernate/src/NHibernate/Loader/Criteria/CriteriaLoader.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Loader/Criteria/CriteriaLoader.cs 2011-06-14 23:05:35 UTC (rev 5928) +++ trunk/nhibernate/src/NHibernate/Loader/Criteria/CriteriaLoader.cs 2011-06-15 19:19:46 UTC (rev 5929) @@ -215,14 +215,12 @@ /// <returns>A CommandWrapper wrapping an IDbCommand that is ready to be executed.</returns> protected internal override IDbCommand PrepareQueryCommand(QueryParameters queryParameters, bool scroll, ISessionImplementor session) { - var sqlCommand = (SqlCommandImpl)CreateSqlCommand(queryParameters, session); - var parameterSpecs = sqlCommand.Specifications; + var sqlCommand = CreateSqlCommand(queryParameters, session); var sqlString = sqlCommand.Query; - var sqlQueryParametersList = sqlCommand.SqlQueryParametersList; - parameterSpecs.SetQueryParameterLocations(sqlQueryParametersList, session.Factory); - + sqlCommand.ResetParametersIndexesForTheCommand(0); IDbCommand command = session.Batcher.PrepareQueryCommand(CommandType.Text, sqlString, sqlCommand.ParameterTypes); + try { RowSelection selection = queryParameters.RowSelection; Modified: trunk/nhibernate/src/NHibernate/Param/ParametersBackTrackExtensions.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Param/ParametersBackTrackExtensions.cs 2011-06-14 23:05:35 UTC (rev 5928) +++ trunk/nhibernate/src/NHibernate/Param/ParametersBackTrackExtensions.cs 2011-06-15 19:19:46 UTC (rev 5929) @@ -48,34 +48,5 @@ parameterSpecification.SetEffectiveType(queryParameters); } } - - /// <summary> - /// Influence the final name of the parameter. - /// </summary> - /// <param name="parameterSpecs"></param> - /// <param name="sqlQueryParametersList"></param> - /// <param name="factory"></param> - public static void SetQueryParameterLocations(this IEnumerable<IParameterSpecification> parameterSpecs, List<Parameter> sqlQueryParametersList, ISessionFactoryImplementor factory) - { - // due to IType.NullSafeSet(System.Data.IDbCommand , object, int, ISessionImplementor) the SqlType[] is supposed to be in a certain sequence. - // this mean that found the first location of a parameter for the IType span, the others are in secuence - foreach (IParameterSpecification specification in parameterSpecs) - { - string firstParameterId = specification.GetIdsForBackTrack(factory).First(); - int[] effectiveParameterLocations = sqlQueryParametersList.GetEffectiveParameterLocations(firstParameterId).ToArray(); - if (effectiveParameterLocations.Length > 0) // Parameters previously present might have been removed from the SQL at a later point. - { - int firstParamNameIndex = effectiveParameterLocations.First(); - foreach (int location in effectiveParameterLocations) - { - int parameterSpan = specification.ExpectedType.GetColumnSpan(factory); - for (int j = 0; j < parameterSpan; j++) - { - sqlQueryParametersList[location + j].ParameterPosition = firstParamNameIndex + j; - } - } - } - } - } } } \ No newline at end of file Modified: trunk/nhibernate/src/NHibernate/SqlCommand/SqlCommandImpl.cs =================================================================== --- trunk/nhibernate/src/NHibernate/SqlCommand/SqlCommandImpl.cs 2011-06-14 23:05:35 UTC (rev 5928) +++ trunk/nhibernate/src/NHibernate/SqlCommand/SqlCommandImpl.cs 2011-06-15 19:19:46 UTC (rev 5929) @@ -1,4 +1,3 @@ -using System; using System.Collections.Generic; using System.Data; using System.Linq; @@ -15,12 +14,31 @@ QueryParameters QueryParameters { get; } /// <summary> + /// re-set the index of each parameter in the final <see cref="IDbCommand">command</see>. + /// </summary> + /// <param name="singleSqlParametersOffset">The offset from where start the list of <see cref="IDataParameter"/>, in the given command, for the this <see cref="SqlCommandImpl"/>. </param> + /// <remarks> + /// Suppose the final <see cref="IDbCommand">command</see> is composed by two queries. The <paramref name="singleSqlParametersOffset"/> for the first query is zero. + /// If the first query command has 12 parameters (size of its SqlType array) the offset to bind all <see cref="IParameterSpecification"/>s, of the second query in the + /// command, is 12 (for the first query we are using from 0 to 11). + /// <para> + /// This method should be called before call <see cref="IBatcher.PrepareCommand"/>. + /// </para> + /// </remarks> + void ResetParametersIndexesForTheCommand(int singleSqlParametersOffset); // Note: should be included ParameterTypes getter + + /// <summary> /// Bind the appropriate value into the given command. /// </summary> /// <param name="command">The command into which the value should be bound.</param> /// <param name="commandQueryParametersList">The parameter-list of the whole query of the command.</param> /// <param name="singleSqlParametersOffset">The offset from where start the list of <see cref="IDataParameter"/>, in the given <paramref name="command"/>, for the this <see cref="SqlCommandImpl"/>. </param> /// <param name="session">The session against which the current execution is occuring.</param> + /// <remarks> + /// Suppose the <paramref name="command"/> is composed by two queries. The <paramref name="singleSqlParametersOffset"/> for the first query is zero. + /// If the first query in <paramref name="command"/> has 12 parameters (size of its SqlType array) the offset to bind all <see cref="IParameterSpecification"/>s, of the second query in the + /// <paramref name="command"/>, is 12 (for the first query we are using from 0 to 11). + /// </remarks> void Bind(IDbCommand command, IList<Parameter> commandQueryParametersList, int singleSqlParametersOffset, ISessionImplementor session); /// <summary> @@ -77,6 +95,35 @@ get { return queryParameters; } } + public void ResetParametersIndexesForTheCommand(int singleSqlParametersOffset) + { + // a better place could be the Bind of each IParameterSpecification but we have to do it before bind values + // in this way the same parameter of a dynamic-filter will be set with two different parameter-names in the same command (when it is a command-set). + if (singleSqlParametersOffset < 0) + { + throw new AssertionFailure("singleSqlParametersOffset < 0 - this indicate a bug in NHibernate "); + } + // due to IType.NullSafeSet(System.Data.IDbCommand , object, int, ISessionImplementor) the SqlType[] is supposed to be in a certain sequence. + // this mean that found the first location of a parameter for the IType span, the others are in secuence + foreach (IParameterSpecification specification in Specifications) + { + string firstParameterId = specification.GetIdsForBackTrack(factory).First(); + int[] effectiveParameterLocations = SqlQueryParametersList.GetEffectiveParameterLocations(firstParameterId).ToArray(); + if (effectiveParameterLocations.Length > 0) // Parameters previously present might have been removed from the SQL at a later point. + { + int firstParamNameIndex = effectiveParameterLocations.First() + singleSqlParametersOffset; + foreach (int location in effectiveParameterLocations) + { + int parameterSpan = specification.ExpectedType.GetColumnSpan(factory); + for (int j = 0; j < parameterSpan; j++) + { + sqlQueryParametersList[location + j].ParameterPosition = firstParamNameIndex + j; + } + } + } + } + } + /// <summary> /// Bind the appropriate value into the given command. /// </summary> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fab...@us...> - 2011-06-14 23:05:42
|
Revision: 5928 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5928&view=rev Author: fabiomaulo Date: 2011-06-14 23:05:35 +0000 (Tue, 14 Jun 2011) Log Message: ----------- Removed dead code + Added comment with no minor TODO Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Driver/SqlStringFormatter.cs Modified: trunk/nhibernate/src/NHibernate/Driver/SqlStringFormatter.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Driver/SqlStringFormatter.cs 2011-06-14 21:58:36 UTC (rev 5927) +++ trunk/nhibernate/src/NHibernate/Driver/SqlStringFormatter.cs 2011-06-14 23:05:35 UTC (rev 5928) @@ -56,20 +56,20 @@ return; } + // NH: even if using SqlType[] the final commad may have X parameters, with this line we will use Y parameters in the IDbCommand + // for example the ParameterCollection may contains two parameters called @p0 and @p1 but the command contains just @p0. + // In this way the same parameter can be used in different places in the query without create a problem to the dear SQL-server (see NH1981) + // TODO: find a way to have exactly the same amount of parameters between the final IDbCommand and its IDataParameterCollection + // A candidateplace is making DriverBase.SetCommandParameters a little bit more intelligent... perhaps SqlString aware (see also DriverBase.SetCommandText, DriverBase.GenerateCommand) string name = formatter.GetParameterName(parameter.ParameterPosition ?? parameterIndex); parameterIndex++; result.Append(name); } - private int GetNumberOfPreceedingParameters() - { - int queryIndex = parameterIndexToQueryIndex[parameterIndex]; - return queryIndexToNumberOfPreceedingParameters[queryIndex]; - } - private void DetermineNumberOfPreceedingParametersForEachQuery(SqlString text) { + // NH: this code smell very bad. It look like specific for ORACLE and probably unused even for ORACLE int currentParameterIndex = 0; int currentQueryParameterCount = 0; int currentQueryIndex = 0; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fab...@us...> - 2011-06-14 21:58:42
|
Revision: 5927 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5927&view=rev Author: fabiomaulo Date: 2011-06-14 21:58:36 +0000 (Tue, 14 Jun 2011) Log Message: ----------- Minor refactoring Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/Loader/QueryLoader.cs trunk/nhibernate/src/NHibernate/Hql/Classic/QueryTranslator.cs trunk/nhibernate/src/NHibernate/Loader/Criteria/CriteriaLoader.cs trunk/nhibernate/src/NHibernate/Loader/Custom/CustomLoader.cs trunk/nhibernate/src/NHibernate/SqlCommand/SqlCommandImpl.cs Modified: trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/Loader/QueryLoader.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/Loader/QueryLoader.cs 2011-06-14 15:18:00 UTC (rev 5926) +++ trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/Loader/QueryLoader.cs 2011-06-14 21:58:36 UTC (rev 5927) @@ -486,7 +486,7 @@ command.CommandTimeout = selection.Timeout; } - sqlCommand.Bind(command, sqlQueryParametersList, 0, session); + sqlCommand.Bind(command, session); session.Batcher.ExpandQueryParameters(command, sqlString); } Modified: trunk/nhibernate/src/NHibernate/Hql/Classic/QueryTranslator.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Hql/Classic/QueryTranslator.cs 2011-06-14 15:18:00 UTC (rev 5926) +++ trunk/nhibernate/src/NHibernate/Hql/Classic/QueryTranslator.cs 2011-06-14 21:58:36 UTC (rev 5927) @@ -354,7 +354,7 @@ command.CommandTimeout = selection.Timeout; } - sqlCommand.Bind(command, sqlQueryParametersList, 0, session); + sqlCommand.Bind(command, session); session.Batcher.ExpandQueryParameters(command, query); } Modified: trunk/nhibernate/src/NHibernate/Loader/Criteria/CriteriaLoader.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Loader/Criteria/CriteriaLoader.cs 2011-06-14 15:18:00 UTC (rev 5926) +++ trunk/nhibernate/src/NHibernate/Loader/Criteria/CriteriaLoader.cs 2011-06-14 21:58:36 UTC (rev 5927) @@ -231,7 +231,7 @@ command.CommandTimeout = selection.Timeout; } - sqlCommand.Bind(command, sqlQueryParametersList, 0, session); + sqlCommand.Bind(command, session); session.Batcher.ExpandQueryParameters(command, sqlString); } Modified: trunk/nhibernate/src/NHibernate/Loader/Custom/CustomLoader.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Loader/Custom/CustomLoader.cs 2011-06-14 15:18:00 UTC (rev 5926) +++ trunk/nhibernate/src/NHibernate/Loader/Custom/CustomLoader.cs 2011-06-14 21:58:36 UTC (rev 5927) @@ -371,7 +371,7 @@ // After the last modification to the SqlString we can collect all parameters types. parameterSpecs.ResetEffectiveExpectedType(queryParameters); - return new SqlCommand.SqlCommandImpl(sqlString, parameterSpecs, queryParameters, session.Factory); + return new SqlCommandImpl(sqlString, parameterSpecs, queryParameters, session.Factory); } public IType[] ResultTypes Modified: trunk/nhibernate/src/NHibernate/SqlCommand/SqlCommandImpl.cs =================================================================== --- trunk/nhibernate/src/NHibernate/SqlCommand/SqlCommandImpl.cs 2011-06-14 15:18:00 UTC (rev 5926) +++ trunk/nhibernate/src/NHibernate/SqlCommand/SqlCommandImpl.cs 2011-06-14 21:58:36 UTC (rev 5927) @@ -1,3 +1,4 @@ +using System; using System.Collections.Generic; using System.Data; using System.Linq; @@ -21,6 +22,17 @@ /// <param name="singleSqlParametersOffset">The offset from where start the list of <see cref="IDataParameter"/>, in the given <paramref name="command"/>, for the this <see cref="SqlCommandImpl"/>. </param> /// <param name="session">The session against which the current execution is occuring.</param> void Bind(IDbCommand command, IList<Parameter> commandQueryParametersList, int singleSqlParametersOffset, ISessionImplementor session); + + /// <summary> + /// Bind the appropriate value into the given command. + /// </summary> + /// <param name="command">The command into which the value should be bound.</param> + /// <param name="session">The session against which the current execution is occuring.</param> + /// <remarks> + /// Use this method when the <paramref name="command"/> contains just 'this' instance of <see cref="ISqlCommand"/>. + /// Use the overload <see cref="Bind(IDbCommand, IList{Parameter}, int, ISessionImplementor)"/> when the <paramref name="command"/> contains more instances of <see cref="ISqlCommand"/>. + /// </remarks> + void Bind(IDbCommand command, ISessionImplementor session); } public class SqlCommandImpl : ISqlCommand @@ -79,5 +91,22 @@ parameterSpecification.Bind(command, commandQueryParametersList, singleSqlParametersOffset, SqlQueryParametersList, QueryParameters, session); } } + + /// <summary> + /// Bind the appropriate value into the given command. + /// </summary> + /// <param name="command">The command into which the value should be bound.</param> + /// <param name="session">The session against which the current execution is occuring.</param> + /// <remarks> + /// Use this method when the <paramref name="command"/> contains just 'this' instance of <see cref="ISqlCommand"/>. + /// Use the overload <see cref="Bind(IDbCommand, IList{Parameter}, int, ISessionImplementor)"/> when the <paramref name="command"/> contains more instances of <see cref="ISqlCommand"/>. + /// </remarks> + public void Bind(IDbCommand command, ISessionImplementor session) + { + foreach (IParameterSpecification parameterSpecification in Specifications) + { + parameterSpecification.Bind(command, SqlQueryParametersList, QueryParameters, session); + } + } } } \ No newline at end of file This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <jul...@us...> - 2011-06-14 15:18:08
|
Revision: 5926 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5926&view=rev Author: julian-maughan Date: 2011-06-14 15:18:00 +0000 (Tue, 14 Jun 2011) Log Message: ----------- Adds grammar support for Linq queries that have orderby on collection count (NH-2760) Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/Generated/HqlSqlWalker.cs trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/HqlSqlWalker.g trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj Added Paths: ----------- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2760/ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2760/Fixture.cs trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2760/Mappings.hbm.xml trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2760/Model.cs Modified: trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/Generated/HqlSqlWalker.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/Generated/HqlSqlWalker.cs 2011-06-14 14:00:44 UTC (rev 5925) +++ trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/Generated/HqlSqlWalker.cs 2011-06-14 15:18:00 UTC (rev 5926) @@ -1,4 +1,4 @@ -// $ANTLR 3.2 Sep 23, 2009 12:02:23 HqlSqlWalker.g 2011-05-22 07:45:51 +// $ANTLR 3.2 Sep 23, 2009 12:02:23 HqlSqlWalker.g 2011-06-14 20:28:08 // The variable 'variable' is assigned but its value is never used. #pragma warning disable 168, 219 @@ -681,16 +681,16 @@ // AST REWRITE - // elements: f, u, w, s + // elements: w, f, s, u // token labels: u - // rule labels: w, f, retval, s + // rule labels: f, w, retval, s // token list labels: // rule list labels: // wildcard labels: retval.Tree = root_0; RewriteRuleNodeStream stream_u = new RewriteRuleNodeStream(adaptor, "token u", u); + RewriteRuleSubtreeStream stream_f = new RewriteRuleSubtreeStream(adaptor, "rule f", f!=null ? f.Tree : null); RewriteRuleSubtreeStream stream_w = new RewriteRuleSubtreeStream(adaptor, "rule w", w!=null ? w.Tree : null); - RewriteRuleSubtreeStream stream_f = new RewriteRuleSubtreeStream(adaptor, "rule f", f!=null ? f.Tree : null); RewriteRuleSubtreeStream stream_retval = new RewriteRuleSubtreeStream(adaptor, "rule retval", retval!=null ? retval.Tree : null); RewriteRuleSubtreeStream stream_s = new RewriteRuleSubtreeStream(adaptor, "rule s", s!=null ? s.Tree : null); @@ -1845,17 +1845,17 @@ // AST REWRITE - // elements: w, o, f, s, g, tk, sk, h + // elements: sk, o, h, g, s, tk, w, f // token labels: - // rule labels: f, w, sk, g, retval, s, o, tk, h + // rule labels: f, w, g, sk, retval, s, o, tk, h // token list labels: // rule list labels: // wildcard labels: retval.Tree = root_0; RewriteRuleSubtreeStream stream_f = new RewriteRuleSubtreeStream(adaptor, "rule f", f!=null ? f.Tree : null); RewriteRuleSubtreeStream stream_w = new RewriteRuleSubtreeStream(adaptor, "rule w", w!=null ? w.Tree : null); + RewriteRuleSubtreeStream stream_g = new RewriteRuleSubtreeStream(adaptor, "rule g", g!=null ? g.Tree : null); RewriteRuleSubtreeStream stream_sk = new RewriteRuleSubtreeStream(adaptor, "rule sk", sk!=null ? sk.Tree : null); - RewriteRuleSubtreeStream stream_g = new RewriteRuleSubtreeStream(adaptor, "rule g", g!=null ? g.Tree : null); RewriteRuleSubtreeStream stream_retval = new RewriteRuleSubtreeStream(adaptor, "rule retval", retval!=null ? retval.Tree : null); RewriteRuleSubtreeStream stream_s = new RewriteRuleSubtreeStream(adaptor, "rule s", s!=null ? s.Tree : null); RewriteRuleSubtreeStream stream_o = new RewriteRuleSubtreeStream(adaptor, "rule o", o!=null ? o.Tree : null); @@ -1961,7 +1961,7 @@ }; // $ANTLR start "orderClause" - // HqlSqlWalker.g:142:1: orderClause : ^( ORDER orderExprs ) ; + // HqlSqlWalker.g:142:1: orderClause : ^( ORDER ( orderExprs | query ( ASCENDING | DESCENDING )? ) ) ; public HqlSqlWalker.orderClause_return orderClause() // throws RecognitionException [1] { HqlSqlWalker.orderClause_return retval = new HqlSqlWalker.orderClause_return(); @@ -1973,15 +1973,19 @@ IASTNode _last = null; IASTNode ORDER27 = null; + IASTNode set30 = null; HqlSqlWalker.orderExprs_return orderExprs28 = default(HqlSqlWalker.orderExprs_return); + HqlSqlWalker.query_return query29 = default(HqlSqlWalker.query_return); + IASTNode ORDER27_tree=null; + IASTNode set30_tree=null; try { - // HqlSqlWalker.g:143:2: ( ^( ORDER orderExprs ) ) - // HqlSqlWalker.g:143:4: ^( ORDER orderExprs ) + // HqlSqlWalker.g:143:2: ( ^( ORDER ( orderExprs | query ( ASCENDING | DESCENDING )? ) ) ) + // HqlSqlWalker.g:143:4: ^( ORDER ( orderExprs | query ( ASCENDING | DESCENDING )? ) ) { root_0 = (IASTNode)adaptor.GetNilNode(); @@ -1999,13 +2003,92 @@ HandleClauseStart( ORDER ); Match(input, Token.DOWN, null); - _last = (IASTNode)input.LT(1); - PushFollow(FOLLOW_orderExprs_in_orderClause658); - orderExprs28 = orderExprs(); - state.followingStackPointer--; + // HqlSqlWalker.g:143:44: ( orderExprs | query ( ASCENDING | DESCENDING )? ) + int alt17 = 2; + int LA17_0 = input.LA(1); - adaptor.AddChild(root_1, orderExprs28.Tree); + if ( (LA17_0 == COUNT || LA17_0 == DOT || LA17_0 == FALSE || LA17_0 == NULL || LA17_0 == TRUE || LA17_0 == CASE || LA17_0 == AGGREGATE || LA17_0 == CASE2 || LA17_0 == INDEX_OP || LA17_0 == METHOD_CALL || LA17_0 == UNARY_MINUS || (LA17_0 >= VECTOR_EXPR && LA17_0 <= WEIRD_IDENT) || (LA17_0 >= NUM_INT && LA17_0 <= JAVA_CONSTANT) || (LA17_0 >= COLON && LA17_0 <= PARAM) || (LA17_0 >= BNOT && LA17_0 <= DIV) || (LA17_0 >= QUOTED_String && LA17_0 <= IDENT)) ) + { + alt17 = 1; + } + else if ( (LA17_0 == UNION || LA17_0 == QUERY) ) + { + alt17 = 2; + } + else + { + NoViableAltException nvae_d17s0 = + new NoViableAltException("", 17, 0, input); + throw nvae_d17s0; + } + switch (alt17) + { + case 1 : + // HqlSqlWalker.g:143:45: orderExprs + { + _last = (IASTNode)input.LT(1); + PushFollow(FOLLOW_orderExprs_in_orderClause659); + orderExprs28 = orderExprs(); + state.followingStackPointer--; + + adaptor.AddChild(root_1, orderExprs28.Tree); + + } + break; + case 2 : + // HqlSqlWalker.g:143:58: query ( ASCENDING | DESCENDING )? + { + _last = (IASTNode)input.LT(1); + PushFollow(FOLLOW_query_in_orderClause663); + query29 = query(); + state.followingStackPointer--; + + adaptor.AddChild(root_1, query29.Tree); + // HqlSqlWalker.g:143:64: ( ASCENDING | DESCENDING )? + int alt16 = 2; + int LA16_0 = input.LA(1); + + if ( (LA16_0 == ASCENDING || LA16_0 == DESCENDING) ) + { + alt16 = 1; + } + switch (alt16) + { + case 1 : + // HqlSqlWalker.g: + { + _last = (IASTNode)input.LT(1); + set30 = (IASTNode)input.LT(1); + if ( input.LA(1) == ASCENDING || input.LA(1) == DESCENDING ) + { + input.Consume(); + + set30_tree = (IASTNode)adaptor.DupNode(set30); + + adaptor.AddChild(root_1, set30_tree); + + state.errorRecovery = false; + } + else + { + MismatchedSetException mse = new MismatchedSetException(null,input); + throw mse; + } + + + } + break; + + } + + + } + break; + + } + + Match(input, Token.UP, null); adaptor.AddChild(root_0, root_1);_last = _save_last_1; } @@ -2049,13 +2132,13 @@ IASTNode _first_0 = null; IASTNode _last = null; - IASTNode set30 = null; - HqlSqlWalker.expr_return expr29 = default(HqlSqlWalker.expr_return); + IASTNode set32 = null; + HqlSqlWalker.expr_return expr31 = default(HqlSqlWalker.expr_return); - HqlSqlWalker.orderExprs_return orderExprs31 = default(HqlSqlWalker.orderExprs_return); + HqlSqlWalker.orderExprs_return orderExprs33 = default(HqlSqlWalker.orderExprs_return); - IASTNode set30_tree=null; + IASTNode set32_tree=null; try { @@ -2065,33 +2148,33 @@ root_0 = (IASTNode)adaptor.GetNilNode(); _last = (IASTNode)input.LT(1); - PushFollow(FOLLOW_expr_in_orderExprs670); - expr29 = expr(); + PushFollow(FOLLOW_expr_in_orderExprs686); + expr31 = expr(); state.followingStackPointer--; - adaptor.AddChild(root_0, expr29.Tree); + adaptor.AddChild(root_0, expr31.Tree); // HqlSqlWalker.g:147:9: ( ASCENDING | DESCENDING )? - int alt16 = 2; - int LA16_0 = input.LA(1); + int alt18 = 2; + int LA18_0 = input.LA(1); - if ( (LA16_0 == ASCENDING || LA16_0 == DESCENDING) ) + if ( (LA18_0 == ASCENDING || LA18_0 == DESCENDING) ) { - alt16 = 1; + alt18 = 1; } - switch (alt16) + switch (alt18) { case 1 : // HqlSqlWalker.g: { _last = (IASTNode)input.LT(1); - set30 = (IASTNode)input.LT(1); + set32 = (IASTNode)input.LT(1); if ( input.LA(1) == ASCENDING || input.LA(1) == DESCENDING ) { input.Consume(); - set30_tree = (IASTNode)adaptor.DupNode(set30); + set32_tree = (IASTNode)adaptor.DupNode(set32); - adaptor.AddChild(root_0, set30_tree); + adaptor.AddChild(root_0, set32_tree); state.errorRecovery = false; } @@ -2108,24 +2191,24 @@ } // HqlSqlWalker.g:147:37: ( orderExprs )? - int alt17 = 2; - int LA17_0 = input.LA(1); + int alt19 = 2; + int LA19_0 = input.LA(1); - if ( (LA17_0 == COUNT || LA17_0 == DOT || LA17_0 == FALSE || LA17_0 == NULL || LA17_0 == TRUE || LA17_0 == CASE || LA17_0 == AGGREGATE || LA17_0 == CASE2 || LA17_0 == INDEX_OP || LA17_0 == METHOD_CALL || LA17_0 == UNARY_MINUS || (LA17_0 >= VECTOR_EXPR && LA17_0 <= WEIRD_IDENT) || (LA17_0 >= NUM_INT && LA17_0 <= JAVA_CONSTANT) || (LA17_0 >= COLON && LA17_0 <= PARAM) || (LA17_0 >= BNOT && LA17_0 <= DIV) || (LA17_0 >= QUOTED_String && LA17_0 <= IDENT)) ) + if ( (LA19_0 == COUNT || LA19_0 == DOT || LA19_0 == FALSE || LA19_0 == NULL || LA19_0 == TRUE || LA19_0 == CASE || LA19_0 == AGGREGATE || LA19_0 == CASE2 || LA19_0 == INDEX_OP || LA19_0 == METHOD_CALL || LA19_0 == UNARY_MINUS || (LA19_0 >= VECTOR_EXPR && LA19_0 <= WEIRD_IDENT) || (LA19_0 >= NUM_INT && LA19_0 <= JAVA_CONSTANT) || (LA19_0 >= COLON && LA19_0 <= PARAM) || (LA19_0 >= BNOT && LA19_0 <= DIV) || (LA19_0 >= QUOTED_String && LA19_0 <= IDENT)) ) { - alt17 = 1; + alt19 = 1; } - switch (alt17) + switch (alt19) { case 1 : // HqlSqlWalker.g:147:38: orderExprs { _last = (IASTNode)input.LT(1); - PushFollow(FOLLOW_orderExprs_in_orderExprs684); - orderExprs31 = orderExprs(); + PushFollow(FOLLOW_orderExprs_in_orderExprs700); + orderExprs33 = orderExprs(); state.followingStackPointer--; - adaptor.AddChild(root_0, orderExprs31.Tree); + adaptor.AddChild(root_0, orderExprs33.Tree); } break; @@ -2172,13 +2255,13 @@ IASTNode _first_0 = null; IASTNode _last = null; - IASTNode SKIP32 = null; - IASTNode NUM_INT33 = null; - HqlSqlWalker.parameter_return parameter34 = default(HqlSqlWalker.parameter_return); + IASTNode SKIP34 = null; + IASTNode NUM_INT35 = null; + HqlSqlWalker.parameter_return parameter36 = default(HqlSqlWalker.parameter_return); - IASTNode SKIP32_tree=null; - IASTNode NUM_INT33_tree=null; + IASTNode SKIP34_tree=null; + IASTNode NUM_INT35_tree=null; try { @@ -2192,43 +2275,43 @@ IASTNode _save_last_1 = _last; IASTNode _first_1 = null; IASTNode root_1 = (IASTNode)adaptor.GetNilNode();_last = (IASTNode)input.LT(1); - SKIP32=(IASTNode)Match(input,SKIP,FOLLOW_SKIP_in_skipClause698); - SKIP32_tree = (IASTNode)adaptor.DupNode(SKIP32); + SKIP34=(IASTNode)Match(input,SKIP,FOLLOW_SKIP_in_skipClause714); + SKIP34_tree = (IASTNode)adaptor.DupNode(SKIP34); - root_1 = (IASTNode)adaptor.BecomeRoot(SKIP32_tree, root_1); + root_1 = (IASTNode)adaptor.BecomeRoot(SKIP34_tree, root_1); Match(input, Token.DOWN, null); // HqlSqlWalker.g:151:11: ( NUM_INT | parameter ) - int alt18 = 2; - int LA18_0 = input.LA(1); + int alt20 = 2; + int LA20_0 = input.LA(1); - if ( (LA18_0 == NUM_INT) ) + if ( (LA20_0 == NUM_INT) ) { - alt18 = 1; + alt20 = 1; } - else if ( ((LA18_0 >= COLON && LA18_0 <= PARAM)) ) + else if ( ((LA20_0 >= COLON && LA20_0 <= PARAM)) ) { - alt18 = 2; + alt20 = 2; } else { - NoViableAltException nvae_d18s0 = - new NoViableAltException("", 18, 0, input); + NoViableAltException nvae_d20s0 = + new NoViableAltException("", 20, 0, input); - throw nvae_d18s0; + throw nvae_d20s0; } - switch (alt18) + switch (alt20) { case 1 : // HqlSqlWalker.g:151:12: NUM_INT { _last = (IASTNode)input.LT(1); - NUM_INT33=(IASTNode)Match(input,NUM_INT,FOLLOW_NUM_INT_in_skipClause701); - NUM_INT33_tree = (IASTNode)adaptor.DupNode(NUM_INT33); + NUM_INT35=(IASTNode)Match(input,NUM_INT,FOLLOW_NUM_INT_in_skipClause717); + NUM_INT35_tree = (IASTNode)adaptor.DupNode(NUM_INT35); - adaptor.AddChild(root_1, NUM_INT33_tree); + adaptor.AddChild(root_1, NUM_INT35_tree); } @@ -2237,11 +2320,11 @@ // HqlSqlWalker.g:151:22: parameter { _last = (IASTNode)input.LT(1); - PushFollow(FOLLOW_parameter_in_skipClause705); - parameter34 = parameter(); + PushFollow(FOLLOW_parameter_in_skipClause721); + parameter36 = parameter(); state.followingStackPointer--; - adaptor.AddChild(root_1, parameter34.Tree); + adaptor.AddChild(root_1, parameter36.Tree); } break; @@ -2292,13 +2375,13 @@ IASTNode _first_0 = null; IASTNode _last = null; - IASTNode TAKE35 = null; - IASTNode NUM_INT36 = null; - HqlSqlWalker.parameter_return parameter37 = default(HqlSqlWalker.parameter_return); + IASTNode TAKE37 = null; + IASTNode NUM_INT38 = null; + HqlSqlWalker.parameter_return parameter39 = default(HqlSqlWalker.parameter_return); - IASTNode TAKE35_tree=null; - IASTNode NUM_INT36_tree=null; + IASTNode TAKE37_tree=null; + IASTNode NUM_INT38_tree=null; try { @@ -2312,43 +2395,43 @@ IASTNode _save_last_1 = _last; IASTNode _first_1 = null; IASTNode root_1 = (IASTNode)adaptor.GetNilNode();_last = (IASTNode)input.LT(1); - TAKE35=(IASTNode)Match(input,TAKE,FOLLOW_TAKE_in_takeClause719); - TAKE35_tree = (IASTNode)adaptor.DupNode(TAKE35); + TAKE37=(IASTNode)Match(input,TAKE,FOLLOW_TAKE_in_takeClause735); + TAKE37_tree = (IASTNode)adaptor.DupNode(TAKE37); - root_1 = (IASTNode)adaptor.BecomeRoot(TAKE35_tree, root_1); + root_1 = (IASTNode)adaptor.BecomeRoot(TAKE37_tree, root_1); Match(input, Token.DOWN, null); // HqlSqlWalker.g:155:11: ( NUM_INT | parameter ) - int alt19 = 2; - int LA19_0 = input.LA(1); + int alt21 = 2; + int LA21_0 = input.LA(1); - if ( (LA19_0 == NUM_INT) ) + if ( (LA21_0 == NUM_INT) ) { - alt19 = 1; + alt21 = 1; } - else if ( ((LA19_0 >= COLON && LA19_0 <= PARAM)) ) + else if ( ((LA21_0 >= COLON && LA21_0 <= PARAM)) ) { - alt19 = 2; + alt21 = 2; } else { - NoViableAltException nvae_d19s0 = - new NoViableAltException("", 19, 0, input); + NoViableAltException nvae_d21s0 = + new NoViableAltException("", 21, 0, input); - throw nvae_d19s0; + throw nvae_d21s0; } - switch (alt19) + switch (alt21) { case 1 : // HqlSqlWalker.g:155:12: NUM_INT { _last = (IASTNode)input.LT(1); - NUM_INT36=(IASTNode)Match(input,NUM_INT,FOLLOW_NUM_INT_in_takeClause722); - NUM_INT36_tree = (IASTNode)adaptor.DupNode(NUM_INT36); + NUM_INT38=(IASTNode)Match(input,NUM_INT,FOLLOW_NUM_INT_in_takeClause738); + NUM_INT38_tree = (IASTNode)adaptor.DupNode(NUM_INT38); - adaptor.AddChild(root_1, NUM_INT36_tree); + adaptor.AddChild(root_1, NUM_INT38_tree); } @@ -2357,11 +2440,11 @@ // HqlSqlWalker.g:155:22: parameter { _last = (IASTNode)input.LT(1); - PushFollow(FOLLOW_parameter_in_takeClause726); - parameter37 = parameter(); + PushFollow(FOLLOW_parameter_in_takeClause742); + parameter39 = parameter(); state.followingStackPointer--; - adaptor.AddChild(root_1, parameter37.Tree); + adaptor.AddChild(root_1, parameter39.Tree); } break; @@ -2412,11 +2495,11 @@ IASTNode _first_0 = null; IASTNode _last = null; - IASTNode GROUP38 = null; - HqlSqlWalker.expr_return expr39 = default(HqlSqlWalker.expr_return); + IASTNode GROUP40 = null; + HqlSqlWalker.expr_return expr41 = default(HqlSqlWalker.expr_return); - IASTNode GROUP38_tree=null; + IASTNode GROUP40_tree=null; try { @@ -2430,54 +2513,54 @@ IASTNode _save_last_1 = _last; IASTNode _first_1 = null; IASTNode root_1 = (IASTNode)adaptor.GetNilNode();_last = (IASTNode)input.LT(1); - GROUP38=(IASTNode)Match(input,GROUP,FOLLOW_GROUP_in_groupClause740); - GROUP38_tree = (IASTNode)adaptor.DupNode(GROUP38); + GROUP40=(IASTNode)Match(input,GROUP,FOLLOW_GROUP_in_groupClause756); + GROUP40_tree = (IASTNode)adaptor.DupNode(GROUP40); - root_1 = (IASTNode)adaptor.BecomeRoot(GROUP38_tree, root_1); + root_1 = (IASTNode)adaptor.BecomeRoot(GROUP40_tree, root_1); HandleClauseStart( GROUP ); Match(input, Token.DOWN, null); // HqlSqlWalker.g:159:44: ( expr )+ - int cnt20 = 0; + int cnt22 = 0; do { - int alt20 = 2; - int LA20_0 = input.LA(1); + int alt22 = 2; + int LA22_0 = input.LA(1); - if ( (LA20_0 == COUNT || LA20_0 == DOT || LA20_0 == FALSE || LA20_0 == NULL || LA20_0 == TRUE || LA20_0 == CASE || LA20_0 == AGGREGATE || LA20_0 == CASE2 || LA20_0 == INDEX_OP || LA20_0 == METHOD_CALL || LA20_0 == UNARY_MINUS || (LA20_0 >= VECTOR_EXPR && LA20_0 <= WEIRD_IDENT) || (LA20_0 >= NUM_INT && LA20_0 <= JAVA_CONSTANT) || (LA20_0 >= COLON && LA20_0 <= PARAM) || (LA20_0 >= BNOT && LA20_0 <= DIV) || (LA20_0 >= QUOTED_String && LA20_0 <= IDENT)) ) + if ( (LA22_0 == COUNT || LA22_0 == DOT || LA22_0 == FALSE || LA22_0 == NULL || LA22_0 == TRUE || LA22_0 == CASE || LA22_0 == AGGREGATE || LA22_0 == CASE2 || LA22_0 == INDEX_OP || LA22_0 == METHOD_CALL || LA22_0 == UNARY_MINUS || (LA22_0 >= VECTOR_EXPR && LA22_0 <= WEIRD_IDENT) || (LA22_0 >= NUM_INT && LA22_0 <= JAVA_CONSTANT) || (LA22_0 >= COLON && LA22_0 <= PARAM) || (LA22_0 >= BNOT && LA22_0 <= DIV) || (LA22_0 >= QUOTED_String && LA22_0 <= IDENT)) ) { - alt20 = 1; + alt22 = 1; } - switch (alt20) + switch (alt22) { case 1 : // HqlSqlWalker.g:159:45: expr { _last = (IASTNode)input.LT(1); - PushFollow(FOLLOW_expr_in_groupClause745); - expr39 = expr(); + PushFollow(FOLLOW_expr_in_groupClause761); + expr41 = expr(); state.followingStackPointer--; - adaptor.AddChild(root_1, expr39.Tree); + adaptor.AddChild(root_1, expr41.Tree); } break; default: - if ( cnt20 >= 1 ) goto loop20; - EarlyExitException eee20 = - new EarlyExitException(20, input); - throw eee20; + if ( cnt22 >= 1 ) goto loop22; + EarlyExitException eee22 = + new EarlyExitException(22, input); + throw eee22; } - cnt20++; + cnt22++; } while (true); - loop20: - ; // Stops C# compiler whining that label 'loop20' has no statements + loop22: + ; // Stops C# compiler whining that label 'loop22' has no statements Match(input, Token.UP, null); adaptor.AddChild(root_0, root_1);_last = _save_last_1; @@ -2523,11 +2606,11 @@ IASTNode _first_0 = null; IASTNode _last = null; - IASTNode HAVING40 = null; - HqlSqlWalker.logicalExpr_return logicalExpr41 = default(HqlSqlWalker.logicalExpr_return); + IASTNode HAVING42 = null; + HqlSqlWalker.logicalExpr_return logicalExpr43 = default(HqlSqlWalker.logicalExpr_return); - IASTNode HAVING40_tree=null; + IASTNode HAVING42_tree=null; try { @@ -2541,20 +2624,20 @@ IASTNode _save_last_1 = _last; IASTNode _first_1 = null; IASTNode root_1 = (IASTNode)adaptor.GetNilNode();_last = (IASTNode)input.LT(1); - HAVING40=(IASTNode)Match(input,HAVING,FOLLOW_HAVING_in_havingClause761); - HAVING40_tree = (IASTNode)adaptor.DupNode(HAVING40); + HAVING42=(IASTNode)Match(input,HAVING,FOLLOW_HAVING_in_havingClause777); + HAVING42_tree = (IASTNode)adaptor.DupNode(HAVING42); - root_1 = (IASTNode)adaptor.BecomeRoot(HAVING40_tree, root_1); + root_1 = (IASTNode)adaptor.BecomeRoot(HAVING42_tree, root_1); Match(input, Token.DOWN, null); _last = (IASTNode)input.LT(1); - PushFollow(FOLLOW_logicalExpr_in_havingClause763); - logicalExpr41 = logicalExpr(); + PushFollow(FOLLOW_logicalExpr_in_havingClause779); + logicalExpr43 = logicalExpr(); state.followingStackPointer--; - adaptor.AddChild(root_1, logicalExpr41.Tree); + adaptor.AddChild(root_1, logicalExpr43.Tree); Match(input, Token.UP, null); adaptor.AddChild(root_0, root_1);_last = _save_last_1; } @@ -2600,12 +2683,12 @@ IASTNode _last = null; IASTNode d = null; - IASTNode SELECT42 = null; + IASTNode SELECT44 = null; HqlSqlWalker.selectExprList_return x = default(HqlSqlWalker.selectExprList_return); IASTNode d_tree=null; - IASTNode SELECT42_tree=null; + IASTNode SELECT44_tree=null; RewriteRuleNodeStream stream_SELECT = new RewriteRuleNodeStream(adaptor,"token SELECT"); RewriteRuleNodeStream stream_DISTINCT = new RewriteRuleNodeStream(adaptor,"token DISTINCT"); RewriteRuleSubtreeStream stream_selectExprList = new RewriteRuleSubtreeStream(adaptor,"rule selectExprList"); @@ -2619,28 +2702,28 @@ IASTNode _save_last_1 = _last; IASTNode _first_1 = null; IASTNode root_1 = (IASTNode)adaptor.GetNilNode();_last = (IASTNode)input.LT(1); - SELECT42=(IASTNode)Match(input,SELECT,FOLLOW_SELECT_in_selectClause777); - stream_SELECT.Add(SELECT42); + SELECT44=(IASTNode)Match(input,SELECT,FOLLOW_SELECT_in_selectClause793); + stream_SELECT.Add(SELECT44); HandleClauseStart( SELECT ); BeforeSelectClause(); Match(input, Token.DOWN, null); // HqlSqlWalker.g:167:68: (d= DISTINCT )? - int alt21 = 2; - int LA21_0 = input.LA(1); + int alt23 = 2; + int LA23_0 = input.LA(1); - if ( (LA21_0 == DISTINCT) ) + if ( (LA23_0 == DISTINCT) ) { - alt21 = 1; + alt23 = 1; } - switch (alt21) + switch (alt23) { case 1 : // HqlSqlWalker.g:167:69: d= DISTINCT { _last = (IASTNode)input.LT(1); - d=(IASTNode)Match(input,DISTINCT,FOLLOW_DISTINCT_in_selectClause784); + d=(IASTNode)Match(input,DISTINCT,FOLLOW_DISTINCT_in_selectClause800); stream_DISTINCT.Add(d); @@ -2650,7 +2733,7 @@ } _last = (IASTNode)input.LT(1); - PushFollow(FOLLOW_selectExprList_in_selectClause790); + PushFollow(FOLLOW_selectExprList_in_selectClause806); x = selectExprList(); state.followingStackPointer--; @@ -2662,7 +2745,7 @@ // AST REWRITE - // elements: d, x + // elements: x, d // token labels: d // rule labels: retval, x // token list labels: @@ -2735,9 +2818,9 @@ IASTNode _first_0 = null; IASTNode _last = null; - HqlSqlWalker.selectExpr_return selectExpr43 = default(HqlSqlWalker.selectExpr_return); + HqlSqlWalker.selectExpr_return selectExpr45 = default(HqlSqlWalker.selectExpr_return); - HqlSqlWalker.aliasedSelectExpr_return aliasedSelectExpr44 = default(HqlSqlWalker.aliasedSelectExpr_return); + HqlSqlWalker.aliasedSelectExpr_return aliasedSelectExpr46 = default(HqlSqlWalker.aliasedSelectExpr_return); @@ -2753,33 +2836,33 @@ root_0 = (IASTNode)adaptor.GetNilNode(); // HqlSqlWalker.g:175:4: ( selectExpr | aliasedSelectExpr )+ - int cnt22 = 0; + int cnt24 = 0; do { - int alt22 = 3; - int LA22_0 = input.LA(1); + int alt24 = 3; + int LA24_0 = input.LA(1); - if ( (LA22_0 == ALL || LA22_0 == COUNT || LA22_0 == DOT || LA22_0 == ELEMENTS || LA22_0 == INDICES || LA22_0 == UNION || LA22_0 == CASE || LA22_0 == OBJECT || LA22_0 == AGGREGATE || (LA22_0 >= CONSTRUCTOR && LA22_0 <= CASE2) || LA22_0 == METHOD_CALL || LA22_0 == QUERY || LA22_0 == UNARY_MINUS || LA22_0 == WEIRD_IDENT || (LA22_0 >= NUM_INT && LA22_0 <= NUM_LONG) || (LA22_0 >= COLON && LA22_0 <= PARAM) || (LA22_0 >= BNOT && LA22_0 <= DIV) || (LA22_0 >= QUOTED_String && LA22_0 <= IDENT)) ) + if ( (LA24_0 == ALL || LA24_0 == COUNT || LA24_0 == DOT || LA24_0 == ELEMENTS || LA24_0 == INDICES || LA24_0 == UNION || LA24_0 == CASE || LA24_0 == OBJECT || LA24_0 == AGGREGATE || (LA24_0 >= CONSTRUCTOR && LA24_0 <= CASE2) || LA24_0 == METHOD_CALL || LA24_0 == QUERY || LA24_0 == UNARY_MINUS || LA24_0 == WEIRD_IDENT || (LA24_0 >= NUM_INT && LA24_0 <= NUM_LONG) || (LA24_0 >= COLON && LA24_0 <= PARAM) || (LA24_0 >= BNOT && LA24_0 <= DIV) || (LA24_0 >= QUOTED_String && LA24_0 <= IDENT)) ) { - alt22 = 1; + alt24 = 1; } - else if ( (LA22_0 == AS) ) + else if ( (LA24_0 == AS) ) { - alt22 = 2; + alt24 = 2; } - switch (alt22) + switch (alt24) { case 1 : // HqlSqlWalker.g:175:6: selectExpr { _last = (IASTNode)input.LT(1); - PushFollow(FOLLOW_selectExpr_in_selectExprList825); - selectExpr43 = selectExpr(); + PushFollow(FOLLOW_selectExpr_in_selectExprList841); + selectExpr45 = selectExpr(); state.followingStackPointer--; - adaptor.AddChild(root_0, selectExpr43.Tree); + adaptor.AddChild(root_0, selectExpr45.Tree); } break; @@ -2787,26 +2870,26 @@ // HqlSqlWalker.g:175:19: aliasedSelectExpr { _last = (IASTNode)input.LT(1); - PushFollow(FOLLOW_aliasedSelectExpr_in_selectExprList829); - aliasedSelectExpr44 = aliasedSelectExpr(); + PushFollow(FOLLOW_aliasedSelectExpr_in_selectExprList845); + aliasedSelectExpr46 = aliasedSelectExpr(); state.followingStackPointer--; - adaptor.AddChild(root_0, aliasedSelectExpr44.Tree); + adaptor.AddChild(root_0, aliasedSelectExpr46.Tree); } break; default: - if ( cnt22 >= 1 ) goto loop22; - EarlyExitException eee22 = - new EarlyExitException(22, input); - throw eee22; + if ( cnt24 >= 1 ) goto loop24; + EarlyExitException eee24 = + new EarlyExitException(24, input); + throw eee24; } - cnt22++; + cnt24++; } while (true); - loop22: - ; // Stops C# compiler whining that label 'loop22' has no statements + loop24: + ; // Stops C# compiler whining that label 'loop24' has no statements _inSelect = oldInSelect; @@ -2851,13 +2934,13 @@ IASTNode _first_0 = null; IASTNode _last = null; - IASTNode AS45 = null; + IASTNode AS47 = null; HqlSqlWalker.selectExpr_return se = default(HqlSqlWalker.selectExpr_return); HqlSqlWalker.identifier_return i = default(HqlSqlWalker.identifier_return); - IASTNode AS45_tree=null; + IASTNode AS47_tree=null; try { @@ -2871,22 +2954,22 @@ IASTNode _save_last_1 = _last; IASTNode _first_1 = null; IASTNode root_1 = (IASTNode)adaptor.GetNilNode();_last = (IASTNode)input.LT(1); - AS45=(IASTNode)Match(input,AS,FOLLOW_AS_in_aliasedSelectExpr853); - AS45_tree = (IASTNode)adaptor.DupNode(AS45); + AS47=(IASTNode)Match(input,AS,FOLLOW_AS_in_aliasedSelectExpr869); + AS47_tree = (IASTNode)adaptor.DupNode(AS47); - root_1 = (IASTNode)adaptor.BecomeRoot(AS45_tree, root_1); + root_1 = (IASTNode)adaptor.BecomeRoot(AS47_tree, root_1); Match(input, Token.DOWN, null); _last = (IASTNode)input.LT(1); - PushFollow(FOLLOW_selectExpr_in_aliasedSelectExpr857); + PushFollow(FOLLOW_selectExpr_in_aliasedSelectExpr873); se = selectExpr(); state.followingStackPointer--; adaptor.AddChild(root_1, se.Tree); _last = (IASTNode)input.LT(1); - PushFollow(FOLLOW_identifier_in_aliasedSelectExpr861); + PushFollow(FOLLOW_identifier_in_aliasedSelectExpr877); i = identifier(); state.followingStackPointer--; @@ -2939,8 +3022,8 @@ IASTNode _first_0 = null; IASTNode _last = null; - IASTNode ALL46 = null; - IASTNode OBJECT47 = null; + IASTNode ALL48 = null; + IASTNode OBJECT49 = null; HqlSqlWalker.propertyRef_return p = default(HqlSqlWalker.propertyRef_return); HqlSqlWalker.aliasRef_return ar2 = default(HqlSqlWalker.aliasRef_return); @@ -2949,73 +3032,73 @@ HqlSqlWalker.constructor_return con = default(HqlSqlWalker.constructor_return); - HqlSqlWalker.functionCall_return functionCall48 = default(HqlSqlWalker.functionCall_return); + HqlSqlWalker.functionCall_return functionCall50 = default(HqlSqlWalker.functionCall_return); - HqlSqlWalker.parameter_return parameter49 = default(HqlSqlWalker.parameter_return); + HqlSqlWalker.parameter_return parameter51 = default(HqlSqlWalker.parameter_return); - HqlSqlWalker.count_return count50 = default(HqlSqlWalker.count_return); + HqlSqlWalker.count_return count52 = default(HqlSqlWalker.count_return); - HqlSqlWalker.collectionFunction_return collectionFunction51 = default(HqlSqlWalker.collectionFunction_return); + HqlSqlWalker.collectionFunction_return collectionFunction53 = default(HqlSqlWalker.collectionFunction_return); - HqlSqlWalker.literal_return literal52 = default(HqlSqlWalker.literal_return); + HqlSqlWalker.literal_return literal54 = default(HqlSqlWalker.literal_return); - HqlSqlWalker.arithmeticExpr_return arithmeticExpr53 = default(HqlSqlWalker.arithmeticExpr_return); + HqlSqlWalker.arithmeticExpr_return arithmeticExpr55 = default(HqlSqlWalker.arithmeticExpr_return); - HqlSqlWalker.query_return query54 = default(HqlSqlWalker.query_return); + HqlSqlWalker.query_return query56 = default(HqlSqlWalker.query_return); - IASTNode ALL46_tree=null; - IASTNode OBJECT47_tree=null; + IASTNode ALL48_tree=null; + IASTNode OBJECT49_tree=null; try { // HqlSqlWalker.g:189:2: (p= propertyRef | ^( ALL ar2= aliasRef ) | ^( OBJECT ar3= aliasRef ) | con= constructor | functionCall | parameter | count | collectionFunction | literal | arithmeticExpr | query ) - int alt23 = 11; + int alt25 = 11; switch ( input.LA(1) ) { case DOT: case WEIRD_IDENT: case IDENT: { - alt23 = 1; + alt25 = 1; } break; case ALL: { - alt23 = 2; + alt25 = 2; } break; case OBJECT: { - alt23 = 3; + alt25 = 3; } break; case CONSTRUCTOR: { - alt23 = 4; + alt25 = 4; } break; case AGGREGATE: case METHOD_CALL: { - alt23 = 5; + alt25 = 5; } break; case COLON: case PARAM: { - alt23 = 6; + alt25 = 6; } break; case COUNT: { - alt23 = 7; + alt25 = 7; } break; case ELEMENTS: case INDICES: { - alt23 = 8; + alt25 = 8; } break; case NUM_INT: @@ -3025,7 +3108,7 @@ case NUM_LONG: case QUOTED_String: { - alt23 = 9; + alt25 = 9; } break; case CASE: @@ -3040,23 +3123,23 @@ case STAR: case DIV: { - alt23 = 10; + alt25 = 10; } break; case UNION: case QUERY: { - alt23 = 11; + alt25 = 11; } break; default: - NoViableAltException nvae_d23s0 = - new NoViableAltException("", 23, 0, input); + NoViableAltException nvae_d25s0 = + new NoViableAltException("", 25, 0, input); - throw nvae_d23s0; + throw nvae_d25s0; } - switch (alt23) + switch (alt25) { case 1 : // HqlSqlWalker.g:189:4: p= propertyRef @@ -3064,7 +3147,7 @@ root_0 = (IASTNode)adaptor.GetNilNode(); _last = (IASTNode)input.LT(1); - PushFollow(FOLLOW_propertyRef_in_selectExpr876); + PushFollow(FOLLOW_propertyRef_in_selectExpr892); p = propertyRef(); state.followingStackPointer--; @@ -3083,16 +3166,16 @@ IASTNode _save_last_1 = _last; IASTNode _first_1 = null; IASTNode root_1 = (IASTNode)adaptor.GetNilNode();_last = (IASTNode)input.LT(1); - ALL46=(IASTNode)Match(input,ALL,FOLLOW_ALL_in_selectExpr888); - ALL46_tree = (IASTNode)adaptor.DupNode(ALL46); + ALL48=(IASTNode)Match(input,ALL,FOLLOW_ALL_in_selectExpr904); + ALL48_tree = (IASTNode)adaptor.DupNode(ALL48); - root_1 = (IASTNode)adaptor.BecomeRoot(ALL46_tree, root_1); + root_1 = (IASTNode)adaptor.BecomeRoot(ALL48_tree, root_1); Match(input, Token.DOWN, null); _last = (IASTNode)input.LT(1); - PushFollow(FOLLOW_aliasRef_in_selectExpr892); + PushFollow(FOLLOW_aliasRef_in_selectExpr908); ar2 = aliasRef(); state.followingStackPointer--; @@ -3115,16 +3198,16 @@ IASTNode _save_last_1 = _last; IASTNode _first_1 = null; IASTNode root_1 = (IASTNode)adaptor.GetNilNode();_last = (IASTNode)input.LT(1); - OBJECT47=(IASTNode)Match(input,OBJECT,FOLLOW_OBJECT_in_selectExpr904); - OBJECT47_tree = (IASTNode)adaptor.DupNode(OBJECT47); + OBJECT49=(IASTNode)Match(input,OBJECT,FOLLOW_OBJECT_in_selectExpr920); + OBJECT49_tree = (IASTNode)adaptor.DupNode(OBJECT49); - root_1 = (IASTNode)adaptor.BecomeRoot(OBJECT47_tree, root_1); + root_1 = (IASTNode)adaptor.BecomeRoot(OBJECT49_tree, root_1); Match(input, Token.DOWN, null); _last = (IASTNode)input.LT(1); - PushFollow(FOLLOW_aliasRef_in_selectExpr908); + PushFollow(FOLLOW_aliasRef_in_selectExpr924); ar3 = aliasRef(); state.followingStackPointer--; @@ -3143,7 +3226,7 @@ root_0 = (IASTNode)adaptor.GetNilNode(); _last = (IASTNode)input.LT(1); - PushFollow(FOLLOW_constructor_in_selectExpr919); + PushFollow(FOLLOW_constructor_in_selectExpr935); con = constructor(); state.followingStackPointer--; @@ -3158,11 +3241,11 @@ root_0 = (IASTNode)adaptor.GetNilNode(); _last = (IASTNode)input.LT(1); - PushFollow(FOLLOW_functionCall_in_selectExpr930); - functionCall48 = functionCall(); + PushFollow(FOLLOW_functionCall_in_selectExpr946); + functionCall50 = functionCall(); state.followingStackPointer--; - adaptor.AddChild(root_0, functionCall48.Tree); + adaptor.AddChild(root_0, functionCall50.Tree); } break; @@ -3172,11 +3255,11 @@ root_0 = (IASTNode)adaptor.GetNilNode(); _last = (IASTNode)input.LT(1); - PushFollow(FOLLOW_parameter_in_selectExpr935); - parameter49 = parameter(); + PushFollow(FOLLOW_parameter_in_selectExpr951); + parameter51 = parameter(); state.followingStackPointer--; - adaptor.AddChild(root_0, parameter49.Tree); + adaptor.AddChild(root_0, parameter51.Tree); } break; @@ -3186,11 +3269,11 @@ root_0 = (IASTNode)adaptor.GetNilNode(); _last = (IASTNode)input.LT(1); - PushFollow(FOLLOW_count_in_selectExpr940); - count50 = count(); + PushFollow(FOLLOW_count_in_selectExpr956); + count52 = count(); state.followingStackPointer--; - adaptor.AddChild(root_0, count50.Tree); + adaptor.AddChild(root_0, count52.Tree); } break; @@ -3200,11 +3283,11 @@ root_0 = (IASTNode)adaptor.GetNilNode(); _last = (IASTNode)input.LT(1); - PushFollow(FOLLOW_collectionFunction_in_selectExpr945); - collectionFunction51 = collectionFunction(); + PushFollow(FOLLOW_collectionFunction_in_selectExpr961); + collectionFunction53 = collectionFunction(); state.followingStackPointer--; - adaptor.AddChild(root_0, collectionFunction51.Tree); + adaptor.AddChild(root_0, collectionFunction53.Tree); } break; @@ -3214,11 +3297,11 @@ root_0 = (IASTNode)adaptor.GetNilNode(); _last = (IASTNode)input.LT(1); - PushFollow(FOLLOW_literal_in_selectExpr953); - literal52 = literal(); + PushFollow(FOLLOW_literal_in_selectExpr969); + literal54 = literal(); state.followingStackPointer--; - adaptor.AddChild(root_0, literal52.Tree); + adaptor.AddChild(root_0, literal54.Tree); } break; @@ -3228,11 +3311,11 @@ root_0 = (IASTNode)adaptor.GetNilNode(); _last = (IASTNode)input.LT(1); - PushFollow(FOLLOW_arithmeticExpr_in_selectExpr958); - arithmeticExpr53 = arithmeticExpr(); + PushFollow(FOLLOW_arithmeticExpr_in_selectExpr974); + arithmeticExpr55 = arithmeticExpr(); state.followingStackPointer--; - adaptor.AddChild(root_0, arithmeticExpr53.Tree); + adaptor.AddChild(root_0, arithmeticExpr55.Tree); } break; @@ -3242,11 +3325,11 @@ root_0 = (IASTNode)adaptor.GetNilNode(); _last = (IASTNode)input.LT(1); - PushFollow(FOLLOW_query_in_selectExpr963); - query54 = query(); + PushFollow(FOLLOW_query_in_selectExpr979); + query56 = query(); state.followingStackPointer--; - adaptor.AddChild(root_0, query54.Tree); + adaptor.AddChild(root_0, query56.Tree); } break; @@ -3289,15 +3372,15 @@ IASTNode _first_0 = null; IASTNode _last = null; - IASTNode COUNT55 = null; - IASTNode set56 = null; - IASTNode ROW_STAR58 = null; - HqlSqlWalker.aggregateExpr_return aggregateExpr57 = default(HqlSqlWalker.aggregateExpr_return); + IASTNode COUNT57 = null; + IASTNode set58 = null; + IASTNode ROW_STAR60 = null; + HqlSqlWalker.aggregateExpr_return aggregateExpr59 = default(HqlSqlWalker.aggregateExpr_return); - IASTNode COUNT55_tree=null; - IASTNode set56_tree=null; - IASTNode ROW_STAR58_tree=null; + IASTNode COUNT57_tree=null; + IASTNode set58_tree=null; + IASTNode ROW_STAR60_tree=null; try { @@ -3311,36 +3394,36 @@ IASTNode _save_last_1 = _last; IASTNode _first_1 = null; IASTNode root_1 = (IASTNode)adaptor.GetNilNode();_last = (IASTNode)input.LT(1); - COUNT55=(IASTNode)Match(input,COUNT,FOLLOW_COUNT_in_count975); - COUNT55_tree = (IASTNode)adaptor.DupNode(COUNT55); + COUNT57=(IASTNode)Match(input,COUNT,FOLLOW_COUNT_in_count991); + COUNT57_tree = (IASTNode)adaptor.DupNode(COUNT57); - root_1 = (IASTNode)adaptor.BecomeRoot(COUNT55_tree, root_1); + root_1 = (IASTNode)adaptor.BecomeRoot(COUNT57_tree, root_1); Match(input, Token.DOWN, null); // HqlSqlWalker.g:203:12: ( DISTINCT | ALL )? - int alt24 = 2; - int LA24_0 = input.LA(1); + int alt26 = 2; + int LA26_0 = input.LA(1); - if ( (LA24_0 == ALL || LA24_0 == DISTINCT) ) + if ( (LA26_0 == ALL || LA26_0 == DISTINCT) ) { - alt24 = 1; + alt26 = 1; } - switch (alt24) + switch (alt26) { case 1 : // HqlSqlWalker.g: { _last = (IASTNode)input.LT(1); - set56 = (IASTNode)input.LT(1); + set58 = (IASTNode)input.LT(1); if ( input.LA(1) == ALL || input.LA(1) == DISTINCT ) { input.Consume(); - set56_tree = (IASTNode)adaptor.DupNode(set56); + set58_tree = (IASTNode)adaptor.DupNode(set58); - adaptor.AddChild(root_1, set56_tree); + adaptor.AddChild(root_1, set58_tree); state.errorRecovery = false; } @@ -3357,35 +3440,35 @@ } // HqlSqlWalker.g:203:32: ( aggregateExpr | ROW_STAR ) - int alt25 = 2; - int LA25_0 = input.LA(1); + int alt27 = 2; + int LA27_0 = input.LA(1); - if ( (LA25_0 == COUNT || LA25_0 == DOT || LA25_0 == ELEMENTS || LA25_0 == FALSE || LA25_0 == INDICES || LA25_0 == NULL || LA25_0 == TRUE || LA25_0 == CASE || LA25_0 == AGGREGATE || LA25_0 == CASE2 || LA25_0 == INDEX_OP || LA25_0 == METHOD_CALL || LA25_0 == UNARY_MINUS || (LA25_0 >= VECTOR_EXPR && LA25_0 <= WEIRD_IDENT) || (LA25_0 >= NUM_INT && LA25_0 <= JAVA_CONSTANT) || (LA25_0 >= COLON && LA25_0 <= PARAM) || (LA25_0 >= BNOT && LA25_0 <= DIV) || (LA25_0 >= QUOTED_String && LA25_0 <= IDENT)) ) + if ( (LA27_0 == COUNT || LA27_0 == DOT || LA27_0 == ELEMENTS || LA27_0 == FALSE || LA27_0 == INDICES || LA27_0 == NULL || LA27_0 == TRUE || LA27_0 == CASE || LA27_0 == AGGREGATE || LA27_0 == CASE2 || LA27_0 == INDEX_OP || LA27_0 == METHOD_CALL || LA27_0 == UNARY_MINUS || (LA27_0 >= VECTOR_EXPR && LA27_0 <= WEIRD_IDENT) || (LA27_0 >= NUM_INT && LA27_0 <= JAVA_CONSTANT) || (LA27_0 >= COLON && LA27_0 <= PARAM) || (LA27_0 >= BNOT && LA27_0 <= DIV) || (LA27_0 >= QUOTED_String && LA27_0 <= IDENT)) ) { - alt25 = 1; + alt27 = 1; } - else if ( (LA25_0 == ROW_STAR) ) + else if ( (LA27_0 == ROW_STAR) ) { - alt25 = 2; + alt27 = 2; } else { - NoViableAltException nvae_d25s0 = - new NoViableAltException("", 25, 0, input); + NoViableAltException nvae_d27s0 = + new NoViableAltException("", 27, 0, input); - throw nvae_d25s0; + throw nvae_d27s0; } - switch (alt25) + switch (alt27) { case 1 : // HqlSqlWalker.g:203:34: aggregateExpr { _last = (IASTNode)input.LT(1); - PushFollow(FOLLOW_aggregateExpr_in_count990); - aggregateExpr57 = aggregateExpr(); + PushFollow(FOLLOW_aggregateExpr_in_count1006); + aggregateExpr59 = aggregateExpr(); state.followingStackPointer--; - adaptor.AddChild(root_1, aggregateExpr57.Tree); + adaptor.AddChild(root_1, aggregateExpr59.Tree); } break; @@ -3393,10 +3476,10 @@ // HqlSqlWalker.g:203:50: ROW_STAR { _last = (IASTNode)input.LT(1); - ROW_STAR58=(IASTNode)Match(input,ROW_STAR,FOLLOW_ROW_STAR_in_count994); - ROW_STAR58_tree = (IASTNode)adaptor.DupNode(ROW_STAR58); + ROW_STAR60=(IASTNode)Match(input,ROW_STAR,FOLLOW_ROW_STAR_in_count1010); + ROW_STAR60_tree = (IASTNode)adaptor.DupNode(ROW_STAR60); - adaptor.AddChild(root_1, ROW_STAR58_tree); + adaptor.AddChild(root_1, ROW_STAR60_tree); } @@ -3448,15 +3531,15 @@ IASTNode _first_0 = null; IASTNode _last = null; - IASTNode CONSTRUCTOR59 = null; - HqlSqlWalker.path_return path60 = default(HqlSqlWalker.path_return); + IASTNode CONSTRUCTOR61 = null; + HqlSqlWalker.path_return path62 = default(HqlSqlWalker.path_return); - HqlSqlWalker.selectExpr_return selectExpr61 = default(HqlSqlWalker.selectExpr_return); + HqlSqlWalker.selectExpr_return selectExpr63 = default(HqlSqlWalker.selectExpr_return); - HqlSqlWalker.aliasedSelectExpr_return aliasedSelectExpr62 = default(HqlSqlWalker.aliasedSelectExpr_return); + HqlSqlWalker.aliasedSelectExpr_return aliasedSelectExpr64 = default(HqlSqlWalker.aliasedSelectExpr_return); - IASTNode CONSTRUCTOR59_tree=null; + IASTNode CONSTRUCTOR61_tree=null; try { @@ -3470,47 +3553,47 @@ IASTNode _save_last_1 = _last; IASTNode _first_1 = null; IASTNode root_1 = (IASTNode)adaptor.GetNilNode();_last = (IASTNode)input.LT(1); - CONSTRUCTOR59=(IASTNode)Match(input,CONSTRUCTOR,FOLLOW_CONSTRUCTOR_in_constructor1010); - CONSTRUCTOR59_tree = (IASTNode)adaptor.DupNode(CONSTRUCTOR59); + CONSTRUCTOR61=(IASTNode)Match(input,CONSTRUCTOR,FOLLOW_CONSTRUCTOR_in_constructor1026); + CONSTRUCTOR61_tree = (IASTNode)adaptor.DupNode(CONSTRUCTOR61); - root_1 = (IASTNode)adaptor.BecomeRoot(CONSTRUCTOR59_tree, root_1); + root_1 = (IASTNode)adaptor.BecomeRoot(CONSTRUCTOR61_tree, root_1); Match(input, Token.DOWN, null); _last = (IASTNode)input.LT(1); - PushFollow(FOLLOW_path_in_constructor1012); - path60 = path(); + PushFollow(FOLLOW_path_in_constructor1028); + path62 = path(); state.followingStackPointer--; - adaptor.AddChild(root_1, path60.Tree); + adaptor.AddChild(root_1, path62.Tree); // HqlSqlWalker.g:207:23: ( selectExpr | aliasedSelectExpr )* do { - int alt26 = 3; - int LA26_0 = input.LA(1); + int alt28 = 3; + int LA28_0 = input.LA(1); - if ( (LA26_0 == ALL || LA26_0 == COUNT || LA26_0 == DOT || LA26_0 == ELEMENTS || LA26_0 == INDICES || LA26_0 == UNION || LA26_0 == CASE || LA26_0 == OBJECT || LA26_0 == AGGREGATE || (LA26_0 >= CONSTRUCTOR && LA26_0 <= CASE2) || LA26_0 == METHOD_CALL || LA26_0 == QUERY || LA26_0 == UNARY_MINUS || LA26_0 == WEIRD_IDENT || (LA26_0 >= NUM_INT && LA26_0 <= NUM_LONG) || (LA26_0 >= COLON && LA26_0 <= PARAM) || (LA26_0 >= BNOT && LA26_0 <= DIV) || (LA26_0 >= QUOTED_String && LA26_0 <= IDENT)) ) + if ( (LA28_0 == ALL || LA28_0 == COUNT || LA28_0 == DOT || LA28_0 == ELEMENTS || LA28_0 == INDICES || LA28_0 == UNION || LA28_0 == CASE || LA28_0 == OBJECT || LA28_0 == AGGREGATE || (LA28_0 >= CONSTRUCTOR && LA28_0 <= CASE2) || LA28_0 == METHOD_CALL || LA28_0 == QUERY || LA28_0 == UNARY_MINUS || LA28_0 == WEIRD_IDENT || (LA28_0 >= NUM_INT && LA28_0 <= NUM_LONG) || (LA28_0 >= COLON && LA28_0 <= PARAM) || (LA28_0 >= BNOT && LA28_0 <= DIV) || (LA28_0 >= QUOTED_String && LA28_0 <= IDENT)) ) { - alt26 = 1; + alt28 = 1; } - else if ( (LA26_0 == AS) ) + else if ( (LA28_0 == AS) ) { - alt26 = 2; + alt28 = 2; } - switch (alt26) + switch (alt28) { case 1 : // HqlSqlWalker.g:207:25: selectExpr { _last = (IASTNode)input.LT(1); - PushFollow(FOLLOW_selectExpr_in_constructor1016); - selectExpr61 = selectExpr(); + PushFollow(FOLLOW_selectExpr_in_constructor1032); + selectExpr63 = selectExpr(); state.followingStackPointer--; - adaptor.AddChild(root_1, selectExpr61.Tree); + adaptor.AddChild(root_1, selectExpr63.Tree); } break; @@ -3518,22 +3601,22 @@ // HqlSqlWalker.g:207:38: aliasedSelectExpr { _last = (IASTNode)input.LT(1); - PushFollow(FOLLOW_aliasedSelectExpr_in_constructor1020); - aliasedSelectExpr62 = aliasedSelectExpr(); + PushFollow(FOLLOW_aliasedSelectExpr_in_constructor1036); + aliasedSelectExpr64 = aliasedSelectExpr(); state.followingStackPointer--; - adaptor.AddChild(root_1, aliasedSelectExpr62.Tree); + adaptor.AddChild(root_1, aliasedSelectExpr64.Tree); } break; default: - goto loop26; + goto loop28; } } while (true); - loop26: - ; // Stops C# compiler whining that label 'loop26' has no statements + loop28: + ; // Stops C# compiler whining that label 'loop28' has no statements Match(input, Token.UP, null); adaptor.AddChild(root_0, root_1);_last = _save_last_1; @@ -3579,34 +3662,34 @@ IASTNode _first_0 = null; IASTNode _last = null; - HqlSqlWalker.expr_return expr63 = default(HqlSqlWalker.expr_return); + HqlSqlWalker.expr_return expr65 = default(HqlSqlWalker.expr_return); - HqlSqlWalker.collectionFunction_return collectionFunction64 = default(HqlSqlWalker.collectionFunction_return); + HqlSqlWalker.collectionFunction_return collectionFunction66 = default(HqlSqlWalker.collectionFunction_return); try { // HqlSqlWalker.g:211:2: ( expr | collectionFunction ) - int alt27 = 2; - int LA27_0 = input.LA(1); + int alt29 = 2; + int LA29_0 = input.LA(1); - if ( (LA27_0 == COUNT || LA27_0 == DOT || LA27_0 == FALSE || LA27_0 == NULL || LA27_0 == TRUE || LA27_0 == CASE || LA27_0 == AGGREGATE || LA27_0 == CASE2 || LA27_0 == INDEX_OP || LA27_0 == METHOD_CALL || LA27_0 == UNARY_MINUS || (LA27_0 >= VECTOR_EXPR && LA27_0 <= WEIRD_IDENT) || (LA27_0 >= NUM_INT && LA27_0 <= JAVA_CONSTANT) || (LA27_0 >= COLON && LA27_0 <= PARAM) || (LA27_0 >= BNOT && LA27_0 <= DIV) || (LA27_0 >= QUOTED_String && LA27_0 <= IDENT)) ) + if ( (LA29_0 == COUNT || LA29_0 == DOT || LA29_0 == FALSE || LA29_0 == NULL || LA29_0 == TRUE || LA29_0 == CASE || LA29_0 == AGGREGATE || LA29_0 == CASE2 || LA29_0 == INDEX_OP || LA29_0 == METHOD_CALL || LA29_0 == UNARY_MINUS || (LA29_0 >= VECTOR_EXPR && LA29_0 <= WEIRD_IDENT) |... [truncated message content] |
From: <fab...@us...> - 2011-06-14 14:00:54
|
Revision: 5925 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5925&view=rev Author: fabiomaulo Date: 2011-06-14 14:00:44 +0000 (Tue, 14 Jun 2011) Log Message: ----------- Classic QueryTranslator using parameter specifications Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Hql/Classic/GroupByParser.cs trunk/nhibernate/src/NHibernate/Hql/Classic/OrderByParser.cs trunk/nhibernate/src/NHibernate/Hql/Classic/QueryTranslator.cs trunk/nhibernate/src/NHibernate/Hql/Classic/SelectParser.cs trunk/nhibernate/src/NHibernate/Hql/Classic/WhereParser.cs trunk/nhibernate/src/NHibernate/SqlCommand/SqlString.cs Modified: trunk/nhibernate/src/NHibernate/Hql/Classic/GroupByParser.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Hql/Classic/GroupByParser.cs 2011-06-13 16:01:13 UTC (rev 5924) +++ trunk/nhibernate/src/NHibernate/Hql/Classic/GroupByParser.cs 2011-06-14 14:00:44 UTC (rev 5925) @@ -27,9 +27,13 @@ q.AppendGroupByToken(pathExpressionParser.WhereColumn); pathExpressionParser.AddAssociation(q); } - else if (token.StartsWith(ParserHelper.HqlVariablePrefix)) + else if (token.StartsWith(ParserHelper.HqlVariablePrefix)) //named query parameter { - q.AddNamedParameter(token.Substring(1)); + var name = token.Substring(1); + q.AppendGroupByParameter(name); + } + else if (token.Equals(StringHelper.SqlParameter)) + { q.AppendGroupByParameter(); } else Modified: trunk/nhibernate/src/NHibernate/Hql/Classic/OrderByParser.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Hql/Classic/OrderByParser.cs 2011-06-13 16:01:13 UTC (rev 5924) +++ trunk/nhibernate/src/NHibernate/Hql/Classic/OrderByParser.cs 2011-06-14 14:00:44 UTC (rev 5925) @@ -27,7 +27,11 @@ } else if (token.StartsWith(ParserHelper.HqlVariablePrefix)) { - q.AddNamedParameter(token.Substring(1)); + var name = token.Substring(1); + q.AppendOrderByParameter(name); + } + else if (StringHelper.SqlParameter.Equals(token)) + { q.AppendOrderByParameter(); } else Modified: trunk/nhibernate/src/NHibernate/Hql/Classic/QueryTranslator.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Hql/Classic/QueryTranslator.cs 2011-06-13 16:01:13 UTC (rev 5924) +++ trunk/nhibernate/src/NHibernate/Hql/Classic/QueryTranslator.cs 2011-06-14 14:00:44 UTC (rev 5925) @@ -1,4 +1,5 @@ using System; +using System.Linq; using System.Collections; using System.Data; using System.Diagnostics; @@ -11,9 +12,9 @@ using NHibernate.Engine; using NHibernate.Engine.Query; using NHibernate.Event; -using NHibernate.Hql.Util; using NHibernate.Impl; using NHibernate.Loader; +using NHibernate.Param; using NHibernate.Persister.Collection; using NHibernate.Persister.Entity; using NHibernate.SqlCommand; @@ -21,8 +22,8 @@ using NHibernate.Type; using NHibernate.Util; using NHibernate.Dialect.Function; -using System.Collections.Specialized; using System.Collections.Generic; +using IQueryable = NHibernate.Persister.Entity.IQueryable; namespace NHibernate.Hql.Classic { @@ -79,6 +80,8 @@ private bool hasScalars; private bool shallowQuery; private QueryTranslator superQuery; + private IList<IParameterSpecification> collectedParameters = new List<IParameterSpecification>(); + private int positionalParameterFound; private class FetchedCollections { @@ -268,7 +271,108 @@ Compile(); } + private int GetPositionalParameterPosition() + { + return superQuery != null ? superQuery.GetPositionalParameterPosition() : positionalParameterFound++; + } + + public SqlString GetNamedParameter(string name) + { + var parameterSpecification = new NamedParameterSpecification(1, 0, name); + var parameter = Parameter.Placeholder; + parameter.BackTrack = parameterSpecification.GetIdsForBackTrack(Factory).First(); + + AddNamedParameter(name); + collectedParameters.Add(parameterSpecification); + return new SqlString(parameter); + } + + public SqlString GetPositionalParameter() + { + var parameterSpecification = new PositionalParameterSpecification(1, 0, GetPositionalParameterPosition()); + var parameter = Parameter.Placeholder; + parameter.BackTrack = parameterSpecification.GetIdsForBackTrack(Factory).First(); + collectedParameters.Add(parameterSpecification); + return new SqlString(parameter); + } + + public IEnumerable<IParameterSpecification> CollectedParameterSpecifications + { + get { return ((superQuery != null) ? superQuery.CollectedParameterSpecifications:Enumerable.Empty<IParameterSpecification>()).Concat(collectedParameters); } + } + + public override ISqlCommand CreateSqlCommand(QueryParameters queryParameters, ISessionImplementor session) + { + // A distinct-copy of parameter specifications collected during query construction + var parameterSpecs = new HashSet<IParameterSpecification>(CollectedParameterSpecifications); + SqlString sql = SqlString.Copy(); + + // dynamic-filter parameters: during the HQL->SQL parsing, filters can be added as SQL_TOKEN/string and the SqlGenerator will not find it + sql = ExpandDynamicFilterParameters(sql, parameterSpecs, session); + AdjustQueryParametersForSubSelectFetching(sql, parameterSpecs, session, queryParameters); // NOTE: see TODO below + + sql = AddLimitsParametersIfNeeded(sql, parameterSpecs, queryParameters, session); + // TODO: for sub-select fetching we have to try to assign the QueryParameter.ProcessedSQL here (with limits) but only after use IParameterSpecification for any kind of queries + + // The PreprocessSQL method can modify the SqlString but should never add parameters (or we have to override it) + sql = PreprocessSQL(sql, queryParameters, session.Factory.Dialect); + + // After the last modification to the SqlString we can collect all parameters types. + parameterSpecs.ResetEffectiveExpectedType(queryParameters); + + return new SqlCommandImpl(sql, parameterSpecs, queryParameters, session.Factory); + } + /// <summary> + /// Obtain an <c>IDbCommand</c> with all parameters pre-bound. Bind positional parameters, + /// named parameters, and limit parameters. + /// </summary> + /// <remarks> + /// Creates an IDbCommand object and populates it with the values necessary to execute it against the + /// database to Load an Entity. + /// </remarks> + /// <param name="queryParameters">The <see cref="QueryParameters"/> to use for the IDbCommand.</param> + /// <param name="scroll">TODO: find out where this is used...</param> + /// <param name="session">The SessionImpl this Command is being prepared in.</param> + /// <returns>A CommandWrapper wrapping an IDbCommand that is ready to be executed.</returns> + protected internal override IDbCommand PrepareQueryCommand(QueryParameters queryParameters, bool scroll, ISessionImplementor session) + { + var sqlCommand = (SqlCommandImpl)CreateSqlCommand(queryParameters, session); + var parameterSpecs = sqlCommand.Specifications; + var query = sqlCommand.Query; + var sqlQueryParametersList = sqlCommand.SqlQueryParametersList; + + parameterSpecs.SetQueryParameterLocations(sqlQueryParametersList, session.Factory); + + IDbCommand command = session.Batcher.PrepareQueryCommand(CommandType.Text, query, sqlCommand.ParameterTypes); + + try + { + RowSelection selection = queryParameters.RowSelection; + if (selection != null && selection.Timeout != RowSelection.NoValue) + { + command.CommandTimeout = selection.Timeout; + } + + sqlCommand.Bind(command, sqlQueryParametersList, 0, session); + + session.Batcher.ExpandQueryParameters(command, query); + } + catch (HibernateException) + { + session.Batcher.CloseCommand(command, null); + throw; + } + catch (Exception sqle) + { + session.Batcher.CloseCommand(command, null); + ADOExceptionReporter.LogExceptions(sqle); + throw; + } + return command; + } + + /// <summary> /// Compile a "normal" query. This method may be called multiple /// times. Subsequent invocations are no-ops. /// </summary> @@ -672,15 +776,17 @@ internal void AppendOrderByToken(string token) { - if (StringHelper.SqlParameter.Equals(token)) - orderByTokens.Add(SqlString.Parameter); - else - orderByTokens.Add(new SqlString(token)); + orderByTokens.Add(new SqlString(token)); } + internal void AppendOrderByParameter(string name) + { + orderByTokens.Add(GetNamedParameter(name)); + } + internal void AppendOrderByParameter() { - orderByTokens.Add(SqlString.Parameter); + orderByTokens.Add(GetPositionalParameter()); } internal void AppendGroupByToken(string token) @@ -688,9 +794,14 @@ groupByTokens.Add(new SqlString(token)); } + internal void AppendGroupByParameter(string name) + { + groupByTokens.Add(GetNamedParameter(name)); + } + internal void AppendGroupByParameter() { - groupByTokens.Add(SqlString.Parameter); + groupByTokens.Add(GetPositionalParameter()); } internal void AppendScalarSelectToken(string token) @@ -703,9 +814,14 @@ scalarSelectTokens.Add(new SqlString(tokens)); } + internal void AppendScalarSelectParameter(string name) + { + scalarSelectTokens.Add(GetNamedParameter(name)); + } + internal void AppendScalarSelectParameter() { - scalarSelectTokens.Add(SqlString.Parameter); + scalarSelectTokens.Add(GetPositionalParameter()); } internal void AddJoin(string name, JoinSequence joinSequence) @@ -1087,10 +1203,21 @@ int parenCount = 1; for (; tokenIdx < tokens.Count && parenCount > 0; tokenIdx++) { - if (tokens[tokenIdx].StartsWithCaseInsensitive(ParserHelper.HqlVariablePrefix) || tokens[tokenIdx].ToString().Equals(StringHelper.SqlParameter)) + if (tokens[tokenIdx].Parts.Count == 1 && (tokens[tokenIdx].Parts.First() is Parameter)) { - functionTokens.Add(SqlString.Parameter); + // the parameter was processed + functionTokens.Add(tokens[tokenIdx]); + continue; } + if (tokens[tokenIdx].StartsWithCaseInsensitive(ParserHelper.HqlVariablePrefix)) + { + string name = tokens[tokenIdx].Substring(1).ToString(); + functionTokens.Add(GetNamedParameter(name)); + } + else if (StringHelper.SqlParameter.Equals(tokens[tokenIdx].ToString())) + { + functionTokens.Add(GetPositionalParameter()); + } else { functionTokens.Add(tokens[tokenIdx]); Modified: trunk/nhibernate/src/NHibernate/Hql/Classic/SelectParser.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Hql/Classic/SelectParser.cs 2011-06-13 16:01:13 UTC (rev 5924) +++ trunk/nhibernate/src/NHibernate/Hql/Classic/SelectParser.cs 2011-06-14 14:00:44 UTC (rev 5925) @@ -170,7 +170,11 @@ if (token.StartsWith(ParserHelper.HqlVariablePrefix)) { - q.AddNamedParameter(token.Substring(1)); + string name = token.Substring(1); + q.AppendScalarSelectParameter(name); + } + else if (token.Equals(StringHelper.SqlParameter)) + { q.AppendScalarSelectParameter(); } else if (constantToken) @@ -237,7 +241,11 @@ } else if (token.StartsWith(ParserHelper.HqlVariablePrefix)) { - q.AddNamedParameter(token.Substring(1)); + string name = token.Substring(1); + q.AppendScalarSelectParameter(name); + } + else if (token.Equals(StringHelper.SqlParameter)) + { q.AppendScalarSelectParameter(); } else Modified: trunk/nhibernate/src/NHibernate/Hql/Classic/WhereParser.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Hql/Classic/WhereParser.cs 2011-06-13 16:01:13 UTC (rev 5924) +++ trunk/nhibernate/src/NHibernate/Hql/Classic/WhereParser.cs 2011-06-14 14:00:44 UTC (rev 5925) @@ -470,17 +470,17 @@ } else if (token.StartsWith(ParserHelper.HqlVariablePrefix)) //named query parameter { - q.AddNamedParameter(token.Substring(1)); + var name = token.Substring(1); // this is only a temporary parameter to help with the parsing of hql - // when the type becomes known then this will be converted to its real // parameter type. - AppendToken(q, SqlString.Parameter); + AppendToken(q, q.GetNamedParameter(name)); } else if (token.Equals(StringHelper.SqlParameter)) { //if the token is a "?" then we have a Parameter so convert it to a SqlCommand.Parameter // instead of appending a "?" to the WhereTokens - AppendToken(q, SqlString.Parameter); + AppendToken(q, q.GetPositionalParameter()); } else { Modified: trunk/nhibernate/src/NHibernate/SqlCommand/SqlString.cs =================================================================== --- trunk/nhibernate/src/NHibernate/SqlCommand/SqlString.cs 2011-06-13 16:01:13 UTC (rev 5924) +++ trunk/nhibernate/src/NHibernate/SqlCommand/SqlString.cs 2011-06-14 14:00:44 UTC (rev 5925) @@ -26,11 +26,6 @@ public static readonly SqlString Empty = new SqlString(new object[0]); - public static SqlString Parameter - { - get { return new SqlString(SqlCommand.Parameter.Placeholder); } - } - public SqlString(string sqlPart) { if (StringHelper.IsNotEmpty(sqlPart)) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fab...@us...> - 2011-06-13 16:01:19
|
Revision: 5924 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5924&view=rev Author: fabiomaulo Date: 2011-06-13 16:01:13 +0000 (Mon, 13 Jun 2011) Log Message: ----------- Minor (added note) Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Param/ParametersBackTrackExtensions.cs Modified: trunk/nhibernate/src/NHibernate/Param/ParametersBackTrackExtensions.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Param/ParametersBackTrackExtensions.cs 2011-06-13 15:32:42 UTC (rev 5923) +++ trunk/nhibernate/src/NHibernate/Param/ParametersBackTrackExtensions.cs 2011-06-13 16:01:13 UTC (rev 5924) @@ -22,6 +22,8 @@ public static SqlType[] GetQueryParameterTypes(this IEnumerable<IParameterSpecification> parameterSpecs, List<Parameter> sqlQueryParametersList, ISessionFactoryImplementor factory) { + // NOTE: if you have a NullReferenceException probably is because the IParameterSpecification does not have the ExpectedType; use ResetEffectiveExpectedType before call this method. + // due to IType.NullSafeSet(System.Data.IDbCommand , object, int, ISessionImplementor) the SqlType[] is supposed to be in a certain sequence. // here we can check and evetually Assert (see AssertionFailure) the supposition because each individual Parameter has its BackTrackId. // Currently we just take the first BackTrackId of each IParameterSpecification This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fab...@us...> - 2011-06-13 15:32:49
|
Revision: 5923 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5923&view=rev Author: fabiomaulo Date: 2011-06-13 15:32:42 +0000 (Mon, 13 Jun 2011) Log Message: ----------- First step to remove SqlString.Parameter Modified Paths: -------------- trunk/nhibernate/src/NHibernate/SqlCommand/SqlString.cs trunk/nhibernate/src/NHibernate.Test/SqlCommandTest/SqlStringFixture.cs Modified: trunk/nhibernate/src/NHibernate/SqlCommand/SqlString.cs =================================================================== --- trunk/nhibernate/src/NHibernate/SqlCommand/SqlString.cs 2011-06-13 15:18:20 UTC (rev 5922) +++ trunk/nhibernate/src/NHibernate/SqlCommand/SqlString.cs 2011-06-13 15:32:42 UTC (rev 5923) @@ -690,19 +690,24 @@ { foreach (object part in sqlParts) { - string partString = part as string; - SqlString partSqlString = part as SqlString; + var partString = part as string; if (partString != null) { visitor.String(partString); + continue; } - else if (partSqlString != null && !SqlString.Parameter.Equals(partSqlString)) + + var partSqlString = part as SqlString; + if (partSqlString != null) { visitor.String(partSqlString); + continue; } - else + + var partParameter = part as Parameter; + if(partParameter != null) { - visitor.Parameter((Parameter)part); + visitor.Parameter(partParameter); } } } Modified: trunk/nhibernate/src/NHibernate.Test/SqlCommandTest/SqlStringFixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/SqlCommandTest/SqlStringFixture.cs 2011-06-13 15:18:20 UTC (rev 5922) +++ trunk/nhibernate/src/NHibernate.Test/SqlCommandTest/SqlStringFixture.cs 2011-06-13 15:32:42 UTC (rev 5923) @@ -2,6 +2,7 @@ using System.Collections.Generic; using NHibernate.SqlCommand; using NUnit.Framework; +using SharpTestsEx; namespace NHibernate.Test.SqlCommandTest { @@ -374,10 +375,10 @@ Parameter[] parameters1 = new Parameter[1]; Parameter[] parameters2 = new Parameter[1]; - SqlString parameterString1 = SqlString.Parameter; + SqlString parameterString1 = new SqlString(Parameter.Placeholder); parameterString1.Parts.CopyTo(parameters1, 0); - SqlString parameterString2 = SqlString.Parameter; + SqlString parameterString2 = new SqlString(Parameter.Placeholder); parameterString2.Parts.CopyTo(parameters2, 0); Assert.AreEqual(parameterString1, parameterString2); @@ -385,6 +386,9 @@ parameters1[0].ParameterPosition = 231; Assert.IsNull(parameters2[0].ParameterPosition); + + // more simple version of the test + Parameter.Placeholder.Should().Not.Be.SameInstanceAs(Parameter.Placeholder); } } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fab...@us...> - 2011-06-13 15:18:28
|
Revision: 5922 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5922&view=rev Author: fabiomaulo Date: 2011-06-13 15:18:20 +0000 (Mon, 13 Jun 2011) Log Message: ----------- Refactoring: usage of parameter-specification Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Engine/Query/NativeSQLQueryPlan.cs Modified: trunk/nhibernate/src/NHibernate/Engine/Query/NativeSQLQueryPlan.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Engine/Query/NativeSQLQueryPlan.cs 2011-06-13 14:40:27 UTC (rev 5921) +++ trunk/nhibernate/src/NHibernate/Engine/Query/NativeSQLQueryPlan.cs 2011-06-13 15:18:20 UTC (rev 5922) @@ -2,12 +2,15 @@ using System.Collections; using System.Collections.Generic; using System.Data; - +using System.Linq; using NHibernate.Action; using NHibernate.Engine.Query.Sql; using NHibernate.Event; using NHibernate.Exceptions; +using NHibernate.Hql.Classic; +using NHibernate.Impl; using NHibernate.Loader.Custom.Sql; +using NHibernate.Param; using NHibernate.SqlCommand; using NHibernate.SqlTypes; using NHibernate.Type; @@ -40,23 +43,6 @@ get { return customQuery; } } - private int[] GetNamedParameterLocs(string name) - { - object loc = customQuery.NamedParameterBindPoints[name]; - if (loc == null) - { - throw new QueryException("Named parameter does not appear in Query: " + name, customQuery.SQL.ToString()); - } - if (Convert.GetTypeCode(loc) == TypeCode.Int32) - { - return new int[] {Convert.ToInt32(loc)}; - } - else - { - return ArrayHelper.ToIntArray((IList)loc); - } - } - private void CoordinateSharedCacheCleanup(ISessionImplementor session) { BulkOperationCleanupAction action = new BulkOperationCleanupAction(session, CustomQuery.QuerySpaces); @@ -84,9 +70,13 @@ int result; try { - queryParameters.ProcessFilters(customQuery.SQL, session); - SqlString sql = queryParameters.FilteredSQL; - SqlType[] sqlTypes = queryParameters.PrepareParameterTypes(sql, session.Factory, GetNamedParameterLocs, 0, false, false); + var parametersSpecifications = customQuery.CollectedParametersSpecifications.ToList(); + SqlString sql = ExpandDynamicFilterParameters(customQuery.SQL, parametersSpecifications, session); + // After the last modification to the SqlString we can collect all parameters types. + parametersSpecifications.ResetEffectiveExpectedType(queryParameters); + + var sqlParametersList = sql.GetParameters().ToList(); + SqlType[] sqlTypes = parametersSpecifications.GetQueryParameterTypes(sqlParametersList, session.Factory); IDbCommand ps = session.Batcher.PrepareCommand(CommandType.Text, sql, sqlTypes); @@ -97,12 +87,12 @@ // NH Difference : set Timeout for native query ps.CommandTimeout = selection.Timeout; } - // NH Different behavior: - // The inital value is 0 (initialized to 1 in JAVA) - // The responsibility of parameter binding was entirely moved to QueryParameters - // to deal with positionslParameter+NamedParameter+ParameterOfFilters + + foreach (IParameterSpecification parameterSpecification in parametersSpecifications) + { + parameterSpecification.Bind(ps, sqlParametersList, queryParameters, session); + } - queryParameters.BindParameters(ps, 0, session); result = session.Batcher.ExecuteNonQuery(ps); } finally @@ -125,5 +115,82 @@ return result; } + + private SqlString ExpandDynamicFilterParameters(SqlString sqlString, ICollection<IParameterSpecification> parameterSpecs, ISessionImplementor session) + { + var enabledFilters = session.EnabledFilters; + if (enabledFilters.Count == 0 || sqlString.ToString().IndexOf(ParserHelper.HqlVariablePrefix) < 0) + { + return sqlString; + } + + Dialect.Dialect dialect = session.Factory.Dialect; + string symbols = ParserHelper.HqlSeparators + dialect.OpenQuote + dialect.CloseQuote; + + var originSql = sqlString.Compact(); + var result = new SqlStringBuilder(); + foreach (var sqlPart in originSql.Parts) + { + var parameter = sqlPart as Parameter; + if (parameter != null) + { + result.Add(parameter); + continue; + } + + var sqlFragment = sqlPart.ToString(); + var tokens = new StringTokenizer(sqlFragment, symbols, true); + + foreach (string token in tokens) + { + if (token.StartsWith(ParserHelper.HqlVariablePrefix)) + { + string filterParameterName = token.Substring(1); + string[] parts = StringHelper.ParseFilterParameterName(filterParameterName); + string filterName = parts[0]; + string parameterName = parts[1]; + var filter = (FilterImpl)enabledFilters[filterName]; + + object value = filter.GetParameter(parameterName); + IType type = filter.FilterDefinition.GetParameterType(parameterName); + int parameterColumnSpan = type.GetColumnSpan(session.Factory); + var collectionValue = value as ICollection; + int? collectionSpan = null; + + // Add query chunk + string typeBindFragment = string.Join(", ", Enumerable.Repeat("?", parameterColumnSpan).ToArray()); + string bindFragment; + if (collectionValue != null && !type.ReturnedClass.IsArray) + { + collectionSpan = collectionValue.Count; + bindFragment = string.Join(", ", Enumerable.Repeat(typeBindFragment, collectionValue.Count).ToArray()); + } + else + { + bindFragment = typeBindFragment; + } + + // dynamic-filter parameter tracking + var filterParameterFragment = SqlString.Parse(bindFragment); + var dynamicFilterParameterSpecification = new DynamicFilterParameterSpecification(filterName, parameterName, type, collectionSpan); + var parameters = filterParameterFragment.GetParameters().ToArray(); + var sqlParameterPos = 0; + var paramTrackers = dynamicFilterParameterSpecification.GetIdsForBackTrack(session.Factory); + foreach (var paramTracker in paramTrackers) + { + parameters[sqlParameterPos++].BackTrack = paramTracker; + } + + parameterSpecs.Add(dynamicFilterParameterSpecification); + result.Add(filterParameterFragment); + } + else + { + result.Add(token); + } + } + } + return result.ToSqlString().Compact(); + } } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fab...@us...> - 2011-06-13 14:40:35
|
Revision: 5921 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5921&view=rev Author: fabiomaulo Date: 2011-06-13 14:40:27 +0000 (Mon, 13 Jun 2011) Log Message: ----------- Refactoring: removed dead-code, relax Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Driver/BasicResultSetsCommand.cs Modified: trunk/nhibernate/src/NHibernate/Driver/BasicResultSetsCommand.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Driver/BasicResultSetsCommand.cs 2011-06-13 13:04:23 UTC (rev 5920) +++ trunk/nhibernate/src/NHibernate/Driver/BasicResultSetsCommand.cs 2011-06-13 14:40:27 UTC (rev 5921) @@ -11,93 +11,58 @@ public class BasicResultSetsCommand: IResultSetsCommand { private static readonly IInternalLogger log = LoggerProvider.LoggerFor(typeof(BasicResultSetsCommand)); - - private readonly ISessionImplementor session; - private readonly Dialect.Dialect dialect; - private readonly IBatcher batcher; private SqlString sqlString = new SqlString(); - private readonly List<ISqlCommand> commands= new List<ISqlCommand>(); public BasicResultSetsCommand(ISessionImplementor session) { - this.session = session; - dialect = session.Factory.Dialect; - batcher = session.Batcher; + Commands = new List<ISqlCommand>(); + Session = session; } - public void Append(ISqlCommand command) + protected List<ISqlCommand> Commands { get; private set; } + + protected ISessionImplementor Session { get; private set; } + + public virtual void Append(ISqlCommand command) { - commands.Add(command); + Commands.Add(command); sqlString = sqlString.Append(command.Query).Append(";").Append(Environment.NewLine); } public bool HasQueries { - get { return commands.Count > 0; } + get { return Commands.Count > 0; } } - public SqlString Sql + public virtual SqlString Sql { get { return sqlString; } } - public IDataReader GetReader(int? commandTimeout) + public virtual IDataReader GetReader(int? commandTimeout) { - SqlType[] sqlTypes = commands.SelectMany(c => c.ParameterTypes).ToArray(); + var batcher = Session.Batcher; + SqlType[] sqlTypes = Commands.SelectMany(c => c.ParameterTypes).ToArray(); var command = batcher.PrepareQueryCommand(CommandType.Text, sqlString, sqlTypes); if (commandTimeout.HasValue) { command.CommandTimeout = commandTimeout.Value; } log.Info(command.CommandText); - var wholeQueryParametersList = sqlString.GetParameters().ToList(); - var singleQueryParameterOffset = 0; - foreach (var sqlLoaderCommand in commands) - { - sqlLoaderCommand.Bind(command, wholeQueryParametersList, singleQueryParameterOffset, session); - singleQueryParameterOffset += sqlLoaderCommand.ParameterTypes.Length; - } + BindParameters(command); return new BatcherDataReaderWrapper(batcher, command); } - protected virtual void BindParameters(IDbCommand command, Loader.Loader[] queryLoaders, QueryParameters[] queryParameters) + protected virtual void BindParameters(IDbCommand command) { - int colIndex = 0; - - for (int queryIndex = 0; queryIndex < commands.Count; queryIndex++) + var wholeQueryParametersList = Sql.GetParameters().ToList(); + var singleQueryParameterOffset = 0; + foreach (var sqlLoaderCommand in Commands) { - int limitParameterSpan = BindLimitParametersFirstIfNeccesary(command, queryLoaders[queryIndex], queryParameters[queryIndex], colIndex); - colIndex = BindQueryParameters(command, queryLoaders[queryIndex], queryParameters[queryIndex], colIndex + limitParameterSpan); - colIndex += BindLimitParametersLastIfNeccesary(command, queryLoaders[queryIndex], queryParameters[queryIndex], colIndex); + sqlLoaderCommand.Bind(command, wholeQueryParametersList, singleQueryParameterOffset, Session); + singleQueryParameterOffset += sqlLoaderCommand.ParameterTypes.Length; } } - - protected virtual int BindLimitParametersLastIfNeccesary(IDbCommand command, Loader.Loader queryLoader, QueryParameters parameter, int colIndex) - { - RowSelection selection = parameter.RowSelection; - if (queryLoader.UseLimit(selection, dialect) && !dialect.BindLimitParametersFirst) - { - return queryLoader.BindLimitParameters(command, colIndex, selection, session); - } - return 0; - } - - protected virtual int BindQueryParameters(IDbCommand command, Loader.Loader queryLoader, QueryParameters parameter, int colIndex) - { - colIndex += parameter.BindParameters(command, colIndex, session); - return colIndex; - } - - protected virtual int BindLimitParametersFirstIfNeccesary(IDbCommand command, Loader.Loader queryLoader, QueryParameters parameter, int colIndex) - { - int limitParameterSpan = 0; - RowSelection selection = parameter.RowSelection; - if (queryLoader.UseLimit(selection, dialect) && dialect.BindLimitParametersFirst) - { - limitParameterSpan += queryLoader.BindLimitParameters(command, colIndex, selection, session); - } - return limitParameterSpan; - } } /// <summary> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fab...@us...> - 2011-06-13 13:04:30
|
Revision: 5920 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5920&view=rev Author: fabiomaulo Date: 2011-06-13 13:04:23 +0000 (Mon, 13 Jun 2011) Log Message: ----------- Refactoring: - DRY - removed dead-code Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/Loader/QueryLoader.cs trunk/nhibernate/src/NHibernate/Loader/Criteria/CriteriaLoader.cs trunk/nhibernate/src/NHibernate/Loader/Custom/CustomLoader.cs trunk/nhibernate/src/NHibernate/Loader/Loader.cs Modified: trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/Loader/QueryLoader.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/Loader/QueryLoader.cs 2011-06-13 12:51:47 UTC (rev 5919) +++ trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/Loader/QueryLoader.cs 2011-06-13 13:04:23 UTC (rev 5920) @@ -1,5 +1,4 @@ using System; -using System.Linq; using System.Collections; using System.Collections.Generic; using System.Data; @@ -7,14 +6,12 @@ using NHibernate.Engine; using NHibernate.Event; using NHibernate.Hql.Ast.ANTLR.Tree; -using NHibernate.Hql.Classic; using NHibernate.Impl; using NHibernate.Loader; using NHibernate.Param; using NHibernate.Persister.Collection; using NHibernate.Persister.Entity; using NHibernate.SqlCommand; -using NHibernate.SqlTypes; using NHibernate.Transform; using NHibernate.Type; using NHibernate.Util; @@ -506,151 +503,5 @@ } return command; } - - private void AdjustQueryParametersForSubSelectFetching(SqlString sqlString, IEnumerable<IParameterSpecification> parameterSpecs, ISessionImplementor session, QueryParameters queryParameters) - { - // TODO: Remove this when all parameters are managed using IParameterSpecification (QueryParameters does not need to have decomposed values for filters) - - var dynamicFilterParameterSpecifications = parameterSpecs.OfType<DynamicFilterParameterSpecification>().ToList(); - var filteredParameterValues = new List<object>(); - var filteredParameterTypes = new List<IType>(); - var filteredParameterLocations = new List<int>(); - - if (dynamicFilterParameterSpecifications.Count != 0) - { - var sqlQueryParametersList = sqlString.GetParameters().ToList(); - foreach (DynamicFilterParameterSpecification specification in dynamicFilterParameterSpecifications) - { - string backTrackId = specification.GetIdsForBackTrack(session.Factory).First(); - object value = session.GetFilterParameterValue(specification.FilterParameterFullName); - var elementType = specification.ExpectedType; - foreach (int position in sqlQueryParametersList.GetEffectiveParameterLocations(backTrackId)) - { - filteredParameterValues.Add(value); - filteredParameterTypes.Add(elementType); - filteredParameterLocations.Add(position); - } - } - } - - queryParameters.ProcessedSql = sqlString; - queryParameters.FilteredParameterLocations = filteredParameterLocations; - queryParameters.FilteredParameterTypes = filteredParameterTypes; - queryParameters.FilteredParameterValues = filteredParameterValues; - } - - private SqlString ExpandDynamicFilterParameters(SqlString sqlString, ICollection<IParameterSpecification> parameterSpecs, ISessionImplementor session) - { - var enabledFilters = session.EnabledFilters; - if (enabledFilters.Count == 0 || sqlString.ToString().IndexOf(ParserHelper.HqlVariablePrefix) < 0) - { - return sqlString; - } - - Dialect.Dialect dialect = session.Factory.Dialect; - string symbols = ParserHelper.HqlSeparators + dialect.OpenQuote + dialect.CloseQuote; - - var originSql = sqlString.Compact(); - var result = new SqlStringBuilder(); - foreach (var sqlPart in originSql.Parts) - { - var parameter = sqlPart as Parameter; - if (parameter != null) - { - result.Add(parameter); - continue; - } - - var sqlFragment = sqlPart.ToString(); - var tokens = new StringTokenizer(sqlFragment, symbols, true); - - foreach (string token in tokens) - { - if (token.StartsWith(ParserHelper.HqlVariablePrefix)) - { - string filterParameterName = token.Substring(1); - string[] parts = StringHelper.ParseFilterParameterName(filterParameterName); - string filterName = parts[0]; - string parameterName = parts[1]; - var filter = (FilterImpl)enabledFilters[filterName]; - - object value = filter.GetParameter(parameterName); - IType type = filter.FilterDefinition.GetParameterType(parameterName); - int parameterColumnSpan = type.GetColumnSpan(session.Factory); - var collectionValue = value as ICollection; - int? collectionSpan = null; - - // Add query chunk - string typeBindFragment = string.Join(", ", Enumerable.Repeat("?", parameterColumnSpan).ToArray()); - string bindFragment; - if (collectionValue != null && !type.ReturnedClass.IsArray) - { - collectionSpan = collectionValue.Count; - bindFragment = string.Join(", ", Enumerable.Repeat(typeBindFragment, collectionValue.Count).ToArray()); - } - else - { - bindFragment = typeBindFragment; - } - - // dynamic-filter parameter tracking - var filterParameterFragment = SqlString.Parse(bindFragment); - var dynamicFilterParameterSpecification = new DynamicFilterParameterSpecification(filterName, parameterName, type, collectionSpan); - var parameters = filterParameterFragment.GetParameters().ToArray(); - var sqlParameterPos = 0; - var paramTrackers = dynamicFilterParameterSpecification.GetIdsForBackTrack(session.Factory); - foreach (var paramTracker in paramTrackers) - { - parameters[sqlParameterPos++].BackTrack = paramTracker; - } - - parameterSpecs.Add(dynamicFilterParameterSpecification); - result.Add(filterParameterFragment); - } - else - { - result.Add(token); - } - } - } - return result.ToSqlString().Compact(); - } - - private SqlString AddLimitsParametersIfNeeded(SqlString sqlString, ICollection<IParameterSpecification> parameterSpecs, QueryParameters queryParameters, ISessionImplementor session) - { - var sessionFactory = session.Factory; - Dialect.Dialect dialect = sessionFactory.Dialect; - - RowSelection selection = queryParameters.RowSelection; - bool useLimit = UseLimit(selection, dialect); - if (useLimit) - { - bool hasFirstRow = GetFirstRow(selection) > 0; - bool useOffset = hasFirstRow && dialect.SupportsLimitOffset; - int max = GetMaxOrLimit(dialect, selection); - int? skip = useOffset ? (int?) dialect.GetOffsetValue(GetFirstRow(selection)) : null; - int? take = max != int.MaxValue ? (int?) max : null; - - Parameter skipSqlParameter = null; - Parameter takeSqlParameter = null; - if (skip.HasValue) - { - var skipParameter = new QuerySkipParameterSpecification(); - skipSqlParameter = Parameter.Placeholder; - skipSqlParameter.BackTrack = skipParameter.GetIdsForBackTrack(sessionFactory).First(); - parameterSpecs.Add(skipParameter); - } - if (take.HasValue) - { - var takeParameter = new QueryTakeParameterSpecification(); - takeSqlParameter = Parameter.Placeholder; - takeSqlParameter.BackTrack = takeParameter.GetIdsForBackTrack(sessionFactory).First(); - parameterSpecs.Add(takeParameter); - } - // The dialect can move the given parameters where he need, what it can't do is generates new parameters loosing the BackTrack. - return dialect.GetLimitString(sqlString, skip, take, skipSqlParameter, takeSqlParameter); - } - return sqlString; - } } } \ No newline at end of file Modified: trunk/nhibernate/src/NHibernate/Loader/Criteria/CriteriaLoader.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Loader/Criteria/CriteriaLoader.cs 2011-06-13 12:51:47 UTC (rev 5919) +++ trunk/nhibernate/src/NHibernate/Loader/Criteria/CriteriaLoader.cs 2011-06-13 13:04:23 UTC (rev 5920) @@ -2,15 +2,12 @@ using System.Collections; using System.Collections.Generic; using System.Data; -using System.Linq; using Iesi.Collections.Generic; using NHibernate.Engine; -using NHibernate.Hql.Classic; using NHibernate.Impl; using NHibernate.Param; using NHibernate.Persister.Entity; using NHibernate.SqlCommand; -using NHibernate.SqlTypes; using NHibernate.Transform; using NHibernate.Type; using NHibernate.Util; @@ -256,151 +253,5 @@ { return new int[0]; } - - private void AdjustQueryParametersForSubSelectFetching(SqlString sqlString, IEnumerable<IParameterSpecification> parameterSpecs, ISessionImplementor session, QueryParameters queryParameters) - { - // TODO: Remove this when all parameters are managed using IParameterSpecification (QueryParameters does not need to have decomposed values for filters) - - var dynamicFilterParameterSpecifications = parameterSpecs.OfType<DynamicFilterParameterSpecification>().ToList(); - var filteredParameterValues = new List<object>(); - var filteredParameterTypes = new List<IType>(); - var filteredParameterLocations = new List<int>(); - - if (dynamicFilterParameterSpecifications.Count != 0) - { - var sqlQueryParametersList = sqlString.GetParameters().ToList(); - foreach (DynamicFilterParameterSpecification specification in dynamicFilterParameterSpecifications) - { - string backTrackId = specification.GetIdsForBackTrack(session.Factory).First(); - object value = session.GetFilterParameterValue(specification.FilterParameterFullName); - var elementType = specification.ExpectedType; - foreach (int position in sqlQueryParametersList.GetEffectiveParameterLocations(backTrackId)) - { - filteredParameterValues.Add(value); - filteredParameterTypes.Add(elementType); - filteredParameterLocations.Add(position); - } - } - } - - queryParameters.ProcessedSql = sqlString; - queryParameters.FilteredParameterLocations = filteredParameterLocations; - queryParameters.FilteredParameterTypes = filteredParameterTypes; - queryParameters.FilteredParameterValues = filteredParameterValues; - } - - private SqlString ExpandDynamicFilterParameters(SqlString sqlString, ICollection<IParameterSpecification> parameterSpecs, ISessionImplementor session) - { - var enabledFilters = session.EnabledFilters; - if (enabledFilters.Count == 0 || sqlString.ToString().IndexOf(ParserHelper.HqlVariablePrefix) < 0) - { - return sqlString; - } - - Dialect.Dialect dialect = session.Factory.Dialect; - string symbols = ParserHelper.HqlSeparators + dialect.OpenQuote + dialect.CloseQuote; - - var originSql = sqlString.Compact(); - var result = new SqlStringBuilder(); - foreach (var sqlPart in originSql.Parts) - { - var parameter = sqlPart as Parameter; - if (parameter != null) - { - result.Add(parameter); - continue; - } - - var sqlFragment = sqlPart.ToString(); - var tokens = new StringTokenizer(sqlFragment, symbols, true); - - foreach (string token in tokens) - { - if (token.StartsWith(ParserHelper.HqlVariablePrefix)) - { - string filterParameterName = token.Substring(1); - string[] parts = StringHelper.ParseFilterParameterName(filterParameterName); - string filterName = parts[0]; - string parameterName = parts[1]; - var filter = (FilterImpl)enabledFilters[filterName]; - - object value = filter.GetParameter(parameterName); - IType type = filter.FilterDefinition.GetParameterType(parameterName); - int parameterColumnSpan = type.GetColumnSpan(session.Factory); - var collectionValue = value as ICollection; - int? collectionSpan = null; - - // Add query chunk - string typeBindFragment = string.Join(", ", Enumerable.Repeat("?", parameterColumnSpan).ToArray()); - string bindFragment; - if (collectionValue != null && !type.ReturnedClass.IsArray) - { - collectionSpan = collectionValue.Count; - bindFragment = string.Join(", ", Enumerable.Repeat(typeBindFragment, collectionValue.Count).ToArray()); - } - else - { - bindFragment = typeBindFragment; - } - - // dynamic-filter parameter tracking - var filterParameterFragment = SqlString.Parse(bindFragment); - var dynamicFilterParameterSpecification = new DynamicFilterParameterSpecification(filterName, parameterName, type, collectionSpan); - var parameters = filterParameterFragment.GetParameters().ToArray(); - var sqlParameterPos = 0; - var paramTrackers = dynamicFilterParameterSpecification.GetIdsForBackTrack(session.Factory); - foreach (var paramTracker in paramTrackers) - { - parameters[sqlParameterPos++].BackTrack = paramTracker; - } - - parameterSpecs.Add(dynamicFilterParameterSpecification); - result.Add(filterParameterFragment); - } - else - { - result.Add(token); - } - } - } - return result.ToSqlString().Compact(); - } - - private SqlString AddLimitsParametersIfNeeded(SqlString sqlString, ICollection<IParameterSpecification> parameterSpecs, QueryParameters queryParameters, ISessionImplementor session) - { - var sessionFactory = session.Factory; - Dialect.Dialect dialect = sessionFactory.Dialect; - - RowSelection selection = queryParameters.RowSelection; - bool useLimit = UseLimit(selection, dialect); - if (useLimit) - { - bool hasFirstRow = GetFirstRow(selection) > 0; - bool useOffset = hasFirstRow && dialect.SupportsLimitOffset; - int max = GetMaxOrLimit(dialect, selection); - int? skip = useOffset ? (int?)dialect.GetOffsetValue(GetFirstRow(selection)) : null; - int? take = max != int.MaxValue ? (int?)max : null; - - Parameter skipSqlParameter = null; - Parameter takeSqlParameter = null; - if (skip.HasValue) - { - var skipParameter = new QuerySkipParameterSpecification(); - skipSqlParameter = Parameter.Placeholder; - skipSqlParameter.BackTrack = skipParameter.GetIdsForBackTrack(sessionFactory).First(); - parameterSpecs.Add(skipParameter); - } - if (take.HasValue) - { - var takeParameter = new QueryTakeParameterSpecification(); - takeSqlParameter = Parameter.Placeholder; - takeSqlParameter.BackTrack = takeParameter.GetIdsForBackTrack(sessionFactory).First(); - parameterSpecs.Add(takeParameter); - } - // The dialect can move the given parameters where he need, what it can't do is generates new parameters loosing the BackTrack. - return dialect.GetLimitString(sqlString, skip, take, skipSqlParameter, takeSqlParameter); - } - return sqlString; - } } } \ No newline at end of file Modified: trunk/nhibernate/src/NHibernate/Loader/Custom/CustomLoader.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Loader/Custom/CustomLoader.cs 2011-06-13 12:51:47 UTC (rev 5919) +++ trunk/nhibernate/src/NHibernate/Loader/Custom/CustomLoader.cs 2011-06-13 13:04:23 UTC (rev 5920) @@ -374,43 +374,6 @@ return new SqlCommand.SqlCommandImpl(sqlString, parameterSpecs, queryParameters, session.Factory); } - private SqlString AddLimitsParametersIfNeeded(SqlString sqlString, ICollection<IParameterSpecification> parameterSpecs, QueryParameters queryParameters, ISessionImplementor session) - { - var sessionFactory = session.Factory; - Dialect.Dialect dialect = sessionFactory.Dialect; - - RowSelection selection = queryParameters.RowSelection; - bool useLimit = UseLimit(selection, dialect); - if (useLimit) - { - bool hasFirstRow = GetFirstRow(selection) > 0; - bool useOffset = hasFirstRow && dialect.SupportsLimitOffset; - int max = GetMaxOrLimit(dialect, selection); - int? skip = useOffset ? (int?)dialect.GetOffsetValue(GetFirstRow(selection)) : null; - int? take = max != int.MaxValue ? (int?)max : null; - - Parameter skipSqlParameter = null; - Parameter takeSqlParameter = null; - if (skip.HasValue) - { - var skipParameter = new QuerySkipParameterSpecification(); - skipSqlParameter = Parameter.Placeholder; - skipSqlParameter.BackTrack = skipParameter.GetIdsForBackTrack(sessionFactory).First(); - parameterSpecs.Add(skipParameter); - } - if (take.HasValue) - { - var takeParameter = new QueryTakeParameterSpecification(); - takeSqlParameter = Parameter.Placeholder; - takeSqlParameter.BackTrack = takeParameter.GetIdsForBackTrack(sessionFactory).First(); - parameterSpecs.Add(takeParameter); - } - // The dialect can move the given parameters where he need, what it can't do is generates new parameters loosing the BackTrack. - return dialect.GetLimitString(sqlString, skip, take, skipSqlParameter, takeSqlParameter); - } - return sqlString; - } - public IType[] ResultTypes { get { return resultTypes; } Modified: trunk/nhibernate/src/NHibernate/Loader/Loader.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Loader/Loader.cs 2011-06-13 12:51:47 UTC (rev 5919) +++ trunk/nhibernate/src/NHibernate/Loader/Loader.cs 2011-06-13 13:04:23 UTC (rev 5920) @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Data; using System.Diagnostics; +using System.Linq; using System.Runtime.CompilerServices; using Iesi.Collections; using Iesi.Collections.Generic; @@ -13,8 +14,10 @@ using NHibernate.Engine; using NHibernate.Event; using NHibernate.Exceptions; +using NHibernate.Hql.Classic; using NHibernate.Hql.Util; using NHibernate.Impl; +using NHibernate.Param; using NHibernate.Persister.Collection; using NHibernate.Persister.Entity; using NHibernate.Proxy; @@ -1753,43 +1756,157 @@ #region NHibernate specific - public virtual SqlCommandInfo GetQueryStringAndTypes(ISessionImplementor session, QueryParameters parameters, int startParameterIndex) + public virtual ISqlCommand CreateSqlCommand(QueryParameters queryParameters, ISessionImplementor session) { - SqlString sqlString = ProcessFilters(parameters, session); - Dialect.Dialect dialect = session.Factory.Dialect; + throw new NotSupportedException("This loader does not support extraction of single command."); + } - RowSelection selection = parameters.RowSelection; - bool useLimit = UseLimit(selection, dialect); - bool hasFirstRow = GetFirstRow(selection) > 0; - bool useOffset = hasFirstRow && useLimit && dialect.SupportsLimitOffset; - int limitParameterCount = GetFirstLimitParameterCount(dialect, useLimit, hasFirstRow, useOffset); + protected void AdjustQueryParametersForSubSelectFetching(SqlString sqlString, IEnumerable<IParameterSpecification> parameterSpecs, ISessionImplementor session, QueryParameters queryParameters) + { + // TODO: Remove this when all parameters are managed using IParameterSpecification (QueryParameters does not need to have decomposed values for filters) - SqlType[] sqlTypes = parameters.PrepareParameterTypes(sqlString, Factory, GetNamedParameterLocs, startParameterIndex + limitParameterCount, useLimit, useOffset); + var dynamicFilterParameterSpecifications = parameterSpecs.OfType<DynamicFilterParameterSpecification>().ToList(); + var filteredParameterValues = new List<object>(); + var filteredParameterTypes = new List<IType>(); + var filteredParameterLocations = new List<int>(); - if (useLimit) + if (dynamicFilterParameterSpecifications.Count != 0) { - int? offset = GetOffsetUsingDialect(selection, dialect); - int? limit = GetLimitUsingDialect(selection, dialect); - Parameter offsetParameter = parameters.OffsetParameterIndex.HasValue ? Parameter.WithIndex(parameters.OffsetParameterIndex.Value) : null; - Parameter limitParameter = parameters.LimitParameterIndex.HasValue ? Parameter.WithIndex(parameters.LimitParameterIndex.Value) : null; - sqlString = - dialect.GetLimitString( - sqlString.Trim(), - useOffset ? offset : null, - limit, - useOffset ? offsetParameter : null, - limitParameter); - } + var sqlQueryParametersList = sqlString.GetParameters().ToList(); + foreach (DynamicFilterParameterSpecification specification in dynamicFilterParameterSpecifications) + { + string backTrackId = specification.GetIdsForBackTrack(session.Factory).First(); + object value = session.GetFilterParameterValue(specification.FilterParameterFullName); + var elementType = specification.ExpectedType; + foreach (int position in sqlQueryParametersList.GetEffectiveParameterLocations(backTrackId)) + { + filteredParameterValues.Add(value); + filteredParameterTypes.Add(elementType); + filteredParameterLocations.Add(position); + } + } + } - sqlString = PreprocessSQL(sqlString, parameters, dialect); - return new SqlCommandInfo(sqlString, sqlTypes); + queryParameters.ProcessedSql = sqlString; + queryParameters.FilteredParameterLocations = filteredParameterLocations; + queryParameters.FilteredParameterTypes = filteredParameterTypes; + queryParameters.FilteredParameterValues = filteredParameterValues; } - public virtual ISqlCommand CreateSqlCommand(QueryParameters queryParameters, ISessionImplementor session) + protected SqlString ExpandDynamicFilterParameters(SqlString sqlString, ICollection<IParameterSpecification> parameterSpecs, ISessionImplementor session) { - throw new NotSupportedException("This loader does not support extraction of single command."); + var enabledFilters = session.EnabledFilters; + if (enabledFilters.Count == 0 || sqlString.ToString().IndexOf(ParserHelper.HqlVariablePrefix) < 0) + { + return sqlString; + } + + Dialect.Dialect dialect = session.Factory.Dialect; + string symbols = ParserHelper.HqlSeparators + dialect.OpenQuote + dialect.CloseQuote; + + var originSql = sqlString.Compact(); + var result = new SqlStringBuilder(); + foreach (var sqlPart in originSql.Parts) + { + var parameter = sqlPart as Parameter; + if (parameter != null) + { + result.Add(parameter); + continue; + } + + var sqlFragment = sqlPart.ToString(); + var tokens = new StringTokenizer(sqlFragment, symbols, true); + + foreach (string token in tokens) + { + if (token.StartsWith(ParserHelper.HqlVariablePrefix)) + { + string filterParameterName = token.Substring(1); + string[] parts = StringHelper.ParseFilterParameterName(filterParameterName); + string filterName = parts[0]; + string parameterName = parts[1]; + var filter = (FilterImpl)enabledFilters[filterName]; + + object value = filter.GetParameter(parameterName); + IType type = filter.FilterDefinition.GetParameterType(parameterName); + int parameterColumnSpan = type.GetColumnSpan(session.Factory); + var collectionValue = value as ICollection; + int? collectionSpan = null; + + // Add query chunk + string typeBindFragment = string.Join(", ", Enumerable.Repeat("?", parameterColumnSpan).ToArray()); + string bindFragment; + if (collectionValue != null && !type.ReturnedClass.IsArray) + { + collectionSpan = collectionValue.Count; + bindFragment = string.Join(", ", Enumerable.Repeat(typeBindFragment, collectionValue.Count).ToArray()); + } + else + { + bindFragment = typeBindFragment; + } + + // dynamic-filter parameter tracking + var filterParameterFragment = SqlString.Parse(bindFragment); + var dynamicFilterParameterSpecification = new DynamicFilterParameterSpecification(filterName, parameterName, type, collectionSpan); + var parameters = filterParameterFragment.GetParameters().ToArray(); + var sqlParameterPos = 0; + var paramTrackers = dynamicFilterParameterSpecification.GetIdsForBackTrack(session.Factory); + foreach (var paramTracker in paramTrackers) + { + parameters[sqlParameterPos++].BackTrack = paramTracker; + } + + parameterSpecs.Add(dynamicFilterParameterSpecification); + result.Add(filterParameterFragment); + } + else + { + result.Add(token); + } + } + } + return result.ToSqlString().Compact(); } + protected SqlString AddLimitsParametersIfNeeded(SqlString sqlString, ICollection<IParameterSpecification> parameterSpecs, QueryParameters queryParameters, ISessionImplementor session) + { + var sessionFactory = session.Factory; + Dialect.Dialect dialect = sessionFactory.Dialect; + + RowSelection selection = queryParameters.RowSelection; + bool useLimit = UseLimit(selection, dialect); + if (useLimit) + { + bool hasFirstRow = GetFirstRow(selection) > 0; + bool useOffset = hasFirstRow && dialect.SupportsLimitOffset; + int max = GetMaxOrLimit(dialect, selection); + int? skip = useOffset ? (int?)dialect.GetOffsetValue(GetFirstRow(selection)) : null; + int? take = max != int.MaxValue ? (int?)max : null; + + Parameter skipSqlParameter = null; + Parameter takeSqlParameter = null; + if (skip.HasValue) + { + var skipParameter = new QuerySkipParameterSpecification(); + skipSqlParameter = Parameter.Placeholder; + skipSqlParameter.BackTrack = EnumerableExtensions.First(skipParameter.GetIdsForBackTrack(sessionFactory)); + parameterSpecs.Add(skipParameter); + } + if (take.HasValue) + { + var takeParameter = new QueryTakeParameterSpecification(); + takeSqlParameter = Parameter.Placeholder; + takeSqlParameter.BackTrack = EnumerableExtensions.First(takeParameter.GetIdsForBackTrack(sessionFactory)); + parameterSpecs.Add(takeParameter); + } + // The dialect can move the given parameters where he need, what it can't do is generates new parameters loosing the BackTrack. + return dialect.GetLimitString(sqlString, skip, take, skipSqlParameter, takeSqlParameter); + } + return sqlString; + } + #endregion } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fab...@us...> - 2011-06-13 12:51:53
|
Revision: 5919 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5919&view=rev Author: fabiomaulo Date: 2011-06-13 12:51:47 +0000 (Mon, 13 Jun 2011) Log Message: ----------- Refactoring: Extracted extensions method Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/Loader/QueryLoader.cs trunk/nhibernate/src/NHibernate/Loader/Custom/CustomLoader.cs trunk/nhibernate/src/NHibernate/Param/ParametersBackTrackExtensions.cs Modified: trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/Loader/QueryLoader.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/Loader/QueryLoader.cs 2011-06-13 12:48:08 UTC (rev 5918) +++ trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/Loader/QueryLoader.cs 2011-06-13 12:51:47 UTC (rev 5919) @@ -453,7 +453,7 @@ sqlString = PreprocessSQL(sqlString, queryParameters, session.Factory.Dialect); // After the last modification to the SqlString we can collect all parameters types. - ResetEffectiveExpectedType(parameterSpecs, queryParameters); // <= TODO: remove this method when we can infer the type during the parse + parameterSpecs.ResetEffectiveExpectedType(queryParameters); return new SqlCommandImpl(sqlString, parameterSpecs, queryParameters, session.Factory); } @@ -652,13 +652,5 @@ } return sqlString; } - - private void ResetEffectiveExpectedType(IEnumerable<IParameterSpecification> parameterSpecs, QueryParameters queryParameters) - { - foreach (var parameterSpecification in parameterSpecs.OfType<IExplicitParameterSpecification>()) - { - parameterSpecification.SetEffectiveType(queryParameters); - } - } } } \ No newline at end of file Modified: trunk/nhibernate/src/NHibernate/Loader/Custom/CustomLoader.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Loader/Custom/CustomLoader.cs 2011-06-13 12:48:08 UTC (rev 5918) +++ trunk/nhibernate/src/NHibernate/Loader/Custom/CustomLoader.cs 2011-06-13 12:51:47 UTC (rev 5919) @@ -369,7 +369,7 @@ sqlString = PreprocessSQL(sqlString, queryParameters, session.Factory.Dialect); // After the last modification to the SqlString we can collect all parameters types. - ResetEffectiveExpectedType(parameterSpecs, queryParameters); // <= TODO: remove this method when we can infer the type during the parse + parameterSpecs.ResetEffectiveExpectedType(queryParameters); return new SqlCommand.SqlCommandImpl(sqlString, parameterSpecs, queryParameters, session.Factory); } @@ -411,14 +411,6 @@ return sqlString; } - private void ResetEffectiveExpectedType(IEnumerable<IParameterSpecification> parameterSpecs, QueryParameters queryParameters) - { - foreach (var parameterSpecification in parameterSpecs.OfType<IExplicitParameterSpecification>()) - { - parameterSpecification.SetEffectiveType(queryParameters); - } - } - public IType[] ResultTypes { get { return resultTypes; } Modified: trunk/nhibernate/src/NHibernate/Param/ParametersBackTrackExtensions.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Param/ParametersBackTrackExtensions.cs 2011-06-13 12:48:08 UTC (rev 5918) +++ trunk/nhibernate/src/NHibernate/Param/ParametersBackTrackExtensions.cs 2011-06-13 12:51:47 UTC (rev 5919) @@ -38,6 +38,15 @@ return typesSequence.SelectMany(t => t.SqlTypes(factory)).ToArray(); } + public static void ResetEffectiveExpectedType(this IEnumerable<IParameterSpecification> parameterSpecs, QueryParameters queryParameters) + { + // TODO: remove this method when we can infer the type during the parse + foreach (var parameterSpecification in parameterSpecs.OfType<IExplicitParameterSpecification>()) + { + parameterSpecification.SetEffectiveType(queryParameters); + } + } + /// <summary> /// Influence the final name of the parameter. /// </summary> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fab...@us...> - 2011-06-13 12:48:19
|
Revision: 5918 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5918&view=rev Author: fabiomaulo Date: 2011-06-13 12:48:08 +0000 (Mon, 13 Jun 2011) Log Message: ----------- Refactoring: DRY CriteriaLoader Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Loader/Criteria/CriteriaLoader.cs trunk/nhibernate/src/NHibernate/Loader/Custom/CustomLoader.cs Modified: trunk/nhibernate/src/NHibernate/Loader/Criteria/CriteriaLoader.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Loader/Criteria/CriteriaLoader.cs 2011-06-13 12:31:25 UTC (rev 5917) +++ trunk/nhibernate/src/NHibernate/Loader/Criteria/CriteriaLoader.cs 2011-06-13 12:48:08 UTC (rev 5918) @@ -187,12 +187,11 @@ public override ISqlCommand CreateSqlCommand(QueryParameters queryParameters, ISessionImplementor session) { - // NOTE: repeated code PrepareQueryCommand // A distinct-copy of parameter specifications collected during query construction var parameterSpecs = new HashSet<IParameterSpecification>(translator.CollectedParameterSpecifications); SqlString sqlString = SqlString.Copy(); - // dynamic-filter parameters: during the HQL->SQL parsing, filters can be added as SQL_TOKEN/string and the SqlGenerator will not find it + // dynamic-filter parameters: during the Criteria parsing, filters can be added as string. sqlString = ExpandDynamicFilterParameters(sqlString, parameterSpecs, session); AdjustQueryParametersForSubSelectFetching(sqlString, parameterSpecs, session, queryParameters); // NOTE: see TODO below @@ -202,7 +201,7 @@ // The PreprocessSQL method can modify the SqlString but should never add parameters (or we have to override it) sqlString = PreprocessSQL(sqlString, queryParameters, session.Factory.Dialect); - return new SqlCommand.SqlCommandImpl(sqlString, parameterSpecs, queryParameters, session.Factory); + return new SqlCommandImpl(sqlString, parameterSpecs, queryParameters, session.Factory); } /// <summary> @@ -219,29 +218,14 @@ /// <returns>A CommandWrapper wrapping an IDbCommand that is ready to be executed.</returns> protected internal override IDbCommand PrepareQueryCommand(QueryParameters queryParameters, bool scroll, ISessionImplementor session) { - // NOTE: repeated code CreateSqlCommandInfo (here we are reusing some other variables) - // A distinct-copy of parameter specifications collected during query construction - var parameterSpecs = new HashSet<IParameterSpecification>(translator.CollectedParameterSpecifications); - SqlString sqlString = SqlString.Copy(); + var sqlCommand = (SqlCommandImpl)CreateSqlCommand(queryParameters, session); + var parameterSpecs = sqlCommand.Specifications; + var sqlString = sqlCommand.Query; + var sqlQueryParametersList = sqlCommand.SqlQueryParametersList; - // dynamic-filter parameters: during the HQL->SQL parsing, filters can be added as SQL_TOKEN/string and the SqlGenerator will not find it - sqlString = ExpandDynamicFilterParameters(sqlString, parameterSpecs, session); - AdjustQueryParametersForSubSelectFetching(sqlString, parameterSpecs, session, queryParameters); // NOTE: see TODO below - - sqlString = AddLimitsParametersIfNeeded(sqlString, parameterSpecs, queryParameters, session); - // TODO: for sub-select fetching we have to try to assign the QueryParameter.ProcessedSQL here (with limits) but only after use IParameterSpecification for any kind of queries - - // The PreprocessSQL method can modify the SqlString but should never add parameters (or we have to override it) - sqlString = PreprocessSQL(sqlString, queryParameters, session.Factory.Dialect); - - // After the last modification to the SqlString we can collect all parameters. - var sqlQueryParametersList = sqlString.GetParameters().ToList(); - SqlType[] parameterTypes = parameterSpecs.GetQueryParameterTypes(sqlQueryParametersList, session.Factory); - parameterSpecs.SetQueryParameterLocations(sqlQueryParametersList, session.Factory); - IDbCommand command = session.Batcher.PrepareQueryCommand(CommandType.Text, sqlString, parameterTypes); - + IDbCommand command = session.Batcher.PrepareQueryCommand(CommandType.Text, sqlString, sqlCommand.ParameterTypes); try { RowSelection selection = queryParameters.RowSelection; @@ -250,7 +234,7 @@ command.CommandTimeout = selection.Timeout; } - BindParametersValues(command, sqlQueryParametersList, parameterSpecs, queryParameters, session); + sqlCommand.Bind(command, sqlQueryParametersList, 0, session); session.Batcher.ExpandQueryParameters(command, sqlString); } @@ -418,21 +402,5 @@ } return sqlString; } - - /// <summary> - /// Bind all parameters values. - /// </summary> - /// <param name="command">The command where bind each value.</param> - /// <param name="sqlQueryParametersList">The list of Sql query parameter in the exact sequence they are present in the query.</param> - /// <param name="parameterSpecs">All parameter-specifications collected during query construction.</param> - /// <param name="queryParameters">The encapsulation of the parameter values to be bound.</param> - /// <param name="session">The session from where execute the query.</param> - private void BindParametersValues(IDbCommand command, IList<Parameter> sqlQueryParametersList, IEnumerable<IParameterSpecification> parameterSpecs, QueryParameters queryParameters, ISessionImplementor session) - { - foreach (var parameterSpecification in parameterSpecs) - { - parameterSpecification.Bind(command, sqlQueryParametersList, queryParameters, session); - } - } } } \ No newline at end of file Modified: trunk/nhibernate/src/NHibernate/Loader/Custom/CustomLoader.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Loader/Custom/CustomLoader.cs 2011-06-13 12:31:25 UTC (rev 5917) +++ trunk/nhibernate/src/NHibernate/Loader/Custom/CustomLoader.cs 2011-06-13 12:48:08 UTC (rev 5918) @@ -358,7 +358,7 @@ var parameterSpecs = new HashSet<IParameterSpecification>(parametersSpecifications); SqlString sqlString = SqlString.Copy(); - // dynamic-filter parameters: during the HQL->SQL parsing, filters can be added as SQL_TOKEN/string and the SqlGenerator will not find it + // dynamic-filter parameters ? //sqlString = ExpandDynamicFilterParameters(sqlString, parameterSpecs, session); //AdjustQueryParametersForSubSelectFetching(sqlString, parameterSpecs, session, queryParameters); // NOTE: see TODO below This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fab...@us...> - 2011-06-13 12:31:36
|
Revision: 5917 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5917&view=rev Author: fabiomaulo Date: 2011-06-13 12:31:25 +0000 (Mon, 13 Jun 2011) Log Message: ----------- Refactoring: - method renaming - first DRY in QueryLoader Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/Loader/QueryLoader.cs trunk/nhibernate/src/NHibernate/Impl/MultiCriteriaImpl.cs trunk/nhibernate/src/NHibernate/Impl/MultiQueryImpl.cs trunk/nhibernate/src/NHibernate/Loader/Criteria/CriteriaLoader.cs trunk/nhibernate/src/NHibernate/Loader/Custom/CustomLoader.cs trunk/nhibernate/src/NHibernate/Loader/Loader.cs trunk/nhibernate/src/NHibernate/Param/ParametersBackTrackExtensions.cs trunk/nhibernate/src/NHibernate/SqlCommand/SqlCommandImpl.cs Modified: trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/Loader/QueryLoader.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/Loader/QueryLoader.cs 2011-06-12 22:10:16 UTC (rev 5916) +++ trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/Loader/QueryLoader.cs 2011-06-13 12:31:25 UTC (rev 5917) @@ -436,9 +436,8 @@ return result; } - public override ISqlCommand CreateSqlCommandInfo(QueryParameters queryParameters, ISessionImplementor session) + public override ISqlCommand CreateSqlCommand(QueryParameters queryParameters, ISessionImplementor session) { - // NOTE: repeated code PrepareQueryCommand // A distinct-copy of parameter specifications collected during query construction var parameterSpecs = new HashSet<IParameterSpecification>(_queryTranslator.CollectedParameterSpecifications); SqlString sqlString = SqlString.Copy(); @@ -456,7 +455,7 @@ // After the last modification to the SqlString we can collect all parameters types. ResetEffectiveExpectedType(parameterSpecs, queryParameters); // <= TODO: remove this method when we can infer the type during the parse - return new SqlCommand.SqlCommandImpl(sqlString, parameterSpecs, queryParameters, session.Factory); + return new SqlCommandImpl(sqlString, parameterSpecs, queryParameters, session.Factory); } /// <summary> @@ -473,31 +472,14 @@ /// <returns>A CommandWrapper wrapping an IDbCommand that is ready to be executed.</returns> protected internal override IDbCommand PrepareQueryCommand(QueryParameters queryParameters, bool scroll, ISessionImplementor session) { - // NH: In this QueryLoader we can know better all parameters used so we can simplify the IDbCommand construction - // NH: would be very useful if we can do the same with Criteria. This method works just for HQL and LINQ. - - // A distinct-copy of parameter specifications collected during query construction - var parameterSpecs = new HashSet<IParameterSpecification>(_queryTranslator.CollectedParameterSpecifications); - SqlString sqlString = SqlString.Copy(); - - // dynamic-filter parameters: during the HQL->SQL parsing, filters can be added as SQL_TOKEN/string and the SqlGenerator will not find it - sqlString = ExpandDynamicFilterParameters(sqlString, parameterSpecs, session); - AdjustQueryParametersForSubSelectFetching(sqlString, parameterSpecs, session, queryParameters); // NOTE: see TODO below - - sqlString = AddLimitsParametersIfNeeded(sqlString, parameterSpecs, queryParameters, session); - // TODO: for sub-select fetching we have to try to assign the QueryParameter.ProcessedSQL here (with limits) but only after use IParameterSpecification for any kind of queries - - // The PreprocessSQL method can modify the SqlString but should never add parameters (or we have to override it) - sqlString = PreprocessSQL(sqlString, queryParameters, session.Factory.Dialect); - - // After the last modification to the SqlString we can collect all parameters types. - ResetEffectiveExpectedType(parameterSpecs, queryParameters); // <= TODO: remove this method when we can infer the type during the parse - var sqlQueryParametersList = sqlString.GetParameters().ToList(); - SqlType[] parameterTypes = parameterSpecs.GetQueryParameterTypes(sqlQueryParametersList, session.Factory); + var sqlCommand = (SqlCommandImpl)CreateSqlCommand(queryParameters, session); + var parameterSpecs = sqlCommand.Specifications; + var sqlString = sqlCommand.Query; + var sqlQueryParametersList = sqlCommand.SqlQueryParametersList; parameterSpecs.SetQueryParameterLocations(sqlQueryParametersList, session.Factory); - IDbCommand command = session.Batcher.PrepareQueryCommand(CommandType.Text, sqlString, parameterTypes); + IDbCommand command = session.Batcher.PrepareQueryCommand(CommandType.Text, sqlString, sqlCommand.ParameterTypes); try { @@ -507,7 +489,7 @@ command.CommandTimeout = selection.Timeout; } - BindParametersValues(command, sqlQueryParametersList, parameterSpecs, queryParameters, session); + sqlCommand.Bind(command, sqlQueryParametersList, 0, session); session.Batcher.ExpandQueryParameters(command, sqlString); } @@ -678,21 +660,5 @@ parameterSpecification.SetEffectiveType(queryParameters); } } - - /// <summary> - /// Bind all parameters values. - /// </summary> - /// <param name="command">The command where bind each value.</param> - /// <param name="sqlQueryParametersList">The list of Sql query parameter in the exact sequence they are present in the query.</param> - /// <param name="parameterSpecs">All parameter-specifications collected during query construction.</param> - /// <param name="queryParameters">The encapsulation of the parameter values to be bound.</param> - /// <param name="session">The session from where execute the query.</param> - private void BindParametersValues(IDbCommand command, IList<Parameter> sqlQueryParametersList, IEnumerable<IParameterSpecification> parameterSpecs, QueryParameters queryParameters, ISessionImplementor session) - { - foreach (var parameterSpecification in parameterSpecs) - { - parameterSpecification.Bind(command, sqlQueryParametersList, queryParameters, session); - } - } } } \ No newline at end of file Modified: trunk/nhibernate/src/NHibernate/Impl/MultiCriteriaImpl.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Impl/MultiCriteriaImpl.cs 2011-06-12 22:10:16 UTC (rev 5916) +++ trunk/nhibernate/src/NHibernate/Impl/MultiCriteriaImpl.cs 2011-06-13 12:31:25 UTC (rev 5917) @@ -183,7 +183,7 @@ translators.Add(translator); QueryParameters queryParameters = translator.GetQueryParameters(); parameters.Add(queryParameters); - ISqlCommand singleCommand = loader.CreateSqlCommandInfo(queryParameters, session); + ISqlCommand singleCommand = loader.CreateSqlCommand(queryParameters, session); resultSetsCommand.Append(singleCommand); } } Modified: trunk/nhibernate/src/NHibernate/Impl/MultiQueryImpl.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Impl/MultiQueryImpl.cs 2011-06-12 22:10:16 UTC (rev 5916) +++ trunk/nhibernate/src/NHibernate/Impl/MultiQueryImpl.cs 2011-06-13 12:31:25 UTC (rev 5917) @@ -640,7 +640,7 @@ { translators.Add(translator); parameters.Add(queryParameters); - ISqlCommand singleCommand = translator.Loader.CreateSqlCommandInfo(queryParameters, session); + ISqlCommand singleCommand = translator.Loader.CreateSqlCommand(queryParameters, session); resultSetsCommand.Append(singleCommand); } } Modified: trunk/nhibernate/src/NHibernate/Loader/Criteria/CriteriaLoader.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Loader/Criteria/CriteriaLoader.cs 2011-06-12 22:10:16 UTC (rev 5916) +++ trunk/nhibernate/src/NHibernate/Loader/Criteria/CriteriaLoader.cs 2011-06-13 12:31:25 UTC (rev 5917) @@ -185,7 +185,7 @@ return customResultTransformer.TransformList(results); } - public override ISqlCommand CreateSqlCommandInfo(QueryParameters queryParameters, ISessionImplementor session) + public override ISqlCommand CreateSqlCommand(QueryParameters queryParameters, ISessionImplementor session) { // NOTE: repeated code PrepareQueryCommand // A distinct-copy of parameter specifications collected during query construction Modified: trunk/nhibernate/src/NHibernate/Loader/Custom/CustomLoader.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Loader/Custom/CustomLoader.cs 2011-06-12 22:10:16 UTC (rev 5916) +++ trunk/nhibernate/src/NHibernate/Loader/Custom/CustomLoader.cs 2011-06-13 12:31:25 UTC (rev 5917) @@ -348,7 +348,7 @@ transformerAliases = aliases.ToArray(); } - public override ISqlCommand CreateSqlCommandInfo(QueryParameters queryParameters, ISessionImplementor session) + public override ISqlCommand CreateSqlCommand(QueryParameters queryParameters, ISessionImplementor session) { if(parametersSpecifications == null) { Modified: trunk/nhibernate/src/NHibernate/Loader/Loader.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Loader/Loader.cs 2011-06-12 22:10:16 UTC (rev 5916) +++ trunk/nhibernate/src/NHibernate/Loader/Loader.cs 2011-06-13 12:31:25 UTC (rev 5917) @@ -1785,7 +1785,7 @@ return new SqlCommandInfo(sqlString, sqlTypes); } - public virtual ISqlCommand CreateSqlCommandInfo(QueryParameters queryParameters, ISessionImplementor session) + public virtual ISqlCommand CreateSqlCommand(QueryParameters queryParameters, ISessionImplementor session) { throw new NotSupportedException("This loader does not support extraction of single command."); } Modified: trunk/nhibernate/src/NHibernate/Param/ParametersBackTrackExtensions.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Param/ParametersBackTrackExtensions.cs 2011-06-12 22:10:16 UTC (rev 5916) +++ trunk/nhibernate/src/NHibernate/Param/ParametersBackTrackExtensions.cs 2011-06-13 12:31:25 UTC (rev 5917) @@ -20,7 +20,7 @@ } } - public static SqlType[] GetQueryParameterTypes(this ICollection<IParameterSpecification> parameterSpecs, List<Parameter> sqlQueryParametersList, ISessionFactoryImplementor factory) + public static SqlType[] GetQueryParameterTypes(this IEnumerable<IParameterSpecification> parameterSpecs, List<Parameter> sqlQueryParametersList, ISessionFactoryImplementor factory) { // due to IType.NullSafeSet(System.Data.IDbCommand , object, int, ISessionImplementor) the SqlType[] is supposed to be in a certain sequence. // here we can check and evetually Assert (see AssertionFailure) the supposition because each individual Parameter has its BackTrackId. @@ -44,7 +44,7 @@ /// <param name="parameterSpecs"></param> /// <param name="sqlQueryParametersList"></param> /// <param name="factory"></param> - public static void SetQueryParameterLocations(this ICollection<IParameterSpecification> parameterSpecs, List<Parameter> sqlQueryParametersList, ISessionFactoryImplementor factory) + public static void SetQueryParameterLocations(this IEnumerable<IParameterSpecification> parameterSpecs, List<Parameter> sqlQueryParametersList, ISessionFactoryImplementor factory) { // due to IType.NullSafeSet(System.Data.IDbCommand , object, int, ISessionImplementor) the SqlType[] is supposed to be in a certain sequence. // this mean that found the first location of a parameter for the IType span, the others are in secuence Modified: trunk/nhibernate/src/NHibernate/SqlCommand/SqlCommandImpl.cs =================================================================== --- trunk/nhibernate/src/NHibernate/SqlCommand/SqlCommandImpl.cs 2011-06-12 22:10:16 UTC (rev 5916) +++ trunk/nhibernate/src/NHibernate/SqlCommand/SqlCommandImpl.cs 2011-06-13 12:31:25 UTC (rev 5917) @@ -40,7 +40,7 @@ this.factory = factory; } - private List<Parameter> SqlQueryParametersList + public List<Parameter> SqlQueryParametersList { get { return sqlQueryParametersList ?? (sqlQueryParametersList = query.GetParameters().ToList()); } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fab...@us...> - 2011-06-12 22:10:25
|
Revision: 5916 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5916&view=rev Author: fabiomaulo Date: 2011-06-12 22:10:16 +0000 (Sun, 12 Jun 2011) Log Message: ----------- Minor (was fixed) Modified Paths: -------------- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2660And2661/Test.cs Modified: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2660And2661/Test.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2660And2661/Test.cs 2011-06-12 22:04:44 UTC (rev 5915) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2660And2661/Test.cs 2011-06-12 22:10:16 UTC (rev 5916) @@ -43,7 +43,7 @@ configuration.DataBaseIntegration(x=> x.Driver<Sql2008ClientDriver>()); } - [Test, Ignore("workaround to sqlserver DP, not fixed yet")] + [Test] public void ShouldBeAbleToQueryEntity() { using (ISession session = OpenSession()) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fab...@us...> - 2011-06-12 22:04:51
|
Revision: 5915 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5915&view=rev Author: fabiomaulo Date: 2011-06-12 22:04:44 +0000 (Sun, 12 Jun 2011) Log Message: ----------- - "re-fix" multi-criteria with pagination - re implemented MultiCriteriaImpl/MultiQueryImpl to fix parameters related problems Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Driver/BasicResultSetsCommand.cs trunk/nhibernate/src/NHibernate/Driver/IResultSetsCommand.cs trunk/nhibernate/src/NHibernate/Engine/Query/ParameterParser.cs trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/Loader/QueryLoader.cs trunk/nhibernate/src/NHibernate/Impl/MultiCriteriaImpl.cs trunk/nhibernate/src/NHibernate/Impl/MultiQueryImpl.cs trunk/nhibernate/src/NHibernate/Loader/Criteria/CriteriaLoader.cs trunk/nhibernate/src/NHibernate/Loader/Custom/CustomLoader.cs trunk/nhibernate/src/NHibernate/Loader/Custom/Sql/SQLCustomQuery.cs trunk/nhibernate/src/NHibernate/Loader/Custom/Sql/SQLQueryParser.cs trunk/nhibernate/src/NHibernate/Loader/Loader.cs trunk/nhibernate/src/NHibernate/NHibernate.csproj trunk/nhibernate/src/NHibernate/Param/AbstractExplicitParameterSpecification.cs trunk/nhibernate/src/NHibernate/Param/AggregatedIndexCollectionSelectorParameterSpecifications.cs trunk/nhibernate/src/NHibernate/Param/CollectionFilterKeyParameterSpecification.cs trunk/nhibernate/src/NHibernate/Param/CriteriaNamedParameterSpecification.cs trunk/nhibernate/src/NHibernate/Param/DynamicFilterParameterSpecification.cs trunk/nhibernate/src/NHibernate/Param/IParameterSpecification.cs trunk/nhibernate/src/NHibernate/Param/NamedParameterSpecification.cs trunk/nhibernate/src/NHibernate/Param/PositionalParameterSpecification.cs trunk/nhibernate/src/NHibernate/Param/QuerySkipParameterSpecification.cs trunk/nhibernate/src/NHibernate/Param/QueryTakeParameterSpecification.cs trunk/nhibernate/src/NHibernate/Param/VersionTypeSeedParameterSpecification.cs trunk/nhibernate/src/NHibernate.Test/Pagination/CustomDialectFixture.cs Added Paths: ----------- trunk/nhibernate/src/NHibernate/SqlCommand/SqlCommandImpl.cs Modified: trunk/nhibernate/src/NHibernate/Driver/BasicResultSetsCommand.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Driver/BasicResultSetsCommand.cs 2011-06-07 01:47:49 UTC (rev 5914) +++ trunk/nhibernate/src/NHibernate/Driver/BasicResultSetsCommand.cs 2011-06-12 22:04:44 UTC (rev 5915) @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Data; +using System.Linq; using NHibernate.Engine; using NHibernate.SqlCommand; using NHibernate.SqlTypes; @@ -14,9 +15,8 @@ private readonly ISessionImplementor session; private readonly Dialect.Dialect dialect; private readonly IBatcher batcher; - private int resultSetsCount = 0; - private readonly List<SqlType> types = new List<SqlType>(); private SqlString sqlString = new SqlString(); + private readonly List<ISqlCommand> commands= new List<ISqlCommand>(); public BasicResultSetsCommand(ISessionImplementor session) { @@ -25,21 +25,15 @@ batcher = session.Batcher; } - public virtual void Append(SqlCommandInfo commandInfo) + public void Append(ISqlCommand command) { - resultSetsCount++; - sqlString = sqlString.Append(commandInfo.Text).Append(";").Append(Environment.NewLine); - types.AddRange(commandInfo.ParameterTypes); + commands.Add(command); + sqlString = sqlString.Append(command.Query).Append(";").Append(Environment.NewLine); } - public int ParametersCount - { - get { return types.Count; } - } - public bool HasQueries { - get { return resultSetsCount > 0; } + get { return commands.Count > 0; } } public SqlString Sql @@ -47,17 +41,22 @@ get { return sqlString; } } - public virtual IDataReader GetReader(Loader.Loader[] queryLoaders, QueryParameters[] queryParameters, int? commandTimeout) + public IDataReader GetReader(int? commandTimeout) { - SqlType[] sqlTypes = types.ToArray(); - var command= batcher.PrepareQueryCommand(CommandType.Text, sqlString, sqlTypes); - if(commandTimeout.HasValue) + SqlType[] sqlTypes = commands.SelectMany(c => c.ParameterTypes).ToArray(); + var command = batcher.PrepareQueryCommand(CommandType.Text, sqlString, sqlTypes); + if (commandTimeout.HasValue) { - command.CommandTimeout = commandTimeout.Value; + command.CommandTimeout = commandTimeout.Value; } log.Info(command.CommandText); - - BindParameters(command, queryLoaders, queryParameters); + var wholeQueryParametersList = sqlString.GetParameters().ToList(); + var singleQueryParameterOffset = 0; + foreach (var sqlLoaderCommand in commands) + { + sqlLoaderCommand.Bind(command, wholeQueryParametersList, singleQueryParameterOffset, session); + singleQueryParameterOffset += sqlLoaderCommand.ParameterTypes.Length; + } return new BatcherDataReaderWrapper(batcher, command); } @@ -65,7 +64,7 @@ { int colIndex = 0; - for (int queryIndex = 0; queryIndex < resultSetsCount; queryIndex++) + for (int queryIndex = 0; queryIndex < commands.Count; queryIndex++) { int limitParameterSpan = BindLimitParametersFirstIfNeccesary(command, queryLoaders[queryIndex], queryParameters[queryIndex], colIndex); colIndex = BindQueryParameters(command, queryLoaders[queryIndex], queryParameters[queryIndex], colIndex + limitParameterSpan); Modified: trunk/nhibernate/src/NHibernate/Driver/IResultSetsCommand.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Driver/IResultSetsCommand.cs 2011-06-07 01:47:49 UTC (rev 5914) +++ trunk/nhibernate/src/NHibernate/Driver/IResultSetsCommand.cs 2011-06-12 22:04:44 UTC (rev 5915) @@ -1,15 +1,13 @@ using System.Data; -using NHibernate.Engine; using NHibernate.SqlCommand; namespace NHibernate.Driver { public interface IResultSetsCommand { - void Append(SqlCommandInfo commandInfo); - int ParametersCount { get; } + void Append(ISqlCommand command); bool HasQueries { get; } SqlString Sql { get; } - IDataReader GetReader(Loader.Loader[] queryLoaders, QueryParameters[] queryParameters, int? commandTimeout); + IDataReader GetReader(int? commandTimeout); } } \ No newline at end of file Modified: trunk/nhibernate/src/NHibernate/Engine/Query/ParameterParser.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Engine/Query/ParameterParser.cs 2011-06-07 01:47:49 UTC (rev 5914) +++ trunk/nhibernate/src/NHibernate/Engine/Query/ParameterParser.cs 2011-06-12 22:04:44 UTC (rev 5915) @@ -43,6 +43,7 @@ /// <exception cref="QueryException" /> public static void Parse(string sqlString, IRecognizer recognizer) { + // TODO: WTF? "CALL"... it may work for ORACLE but what about others RDBMS ? (by FM) bool hasMainOutputParameter = sqlString.IndexOf("call") > 0 && sqlString.IndexOf("?") > 0 && sqlString.IndexOf("=") > 0 && Modified: trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/Loader/QueryLoader.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/Loader/QueryLoader.cs 2011-06-07 01:47:49 UTC (rev 5914) +++ trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/Loader/QueryLoader.cs 2011-06-12 22:04:44 UTC (rev 5915) @@ -436,6 +436,29 @@ return result; } + public override ISqlCommand CreateSqlCommandInfo(QueryParameters queryParameters, ISessionImplementor session) + { + // NOTE: repeated code PrepareQueryCommand + // A distinct-copy of parameter specifications collected during query construction + var parameterSpecs = new HashSet<IParameterSpecification>(_queryTranslator.CollectedParameterSpecifications); + SqlString sqlString = SqlString.Copy(); + + // dynamic-filter parameters: during the HQL->SQL parsing, filters can be added as SQL_TOKEN/string and the SqlGenerator will not find it + sqlString = ExpandDynamicFilterParameters(sqlString, parameterSpecs, session); + AdjustQueryParametersForSubSelectFetching(sqlString, parameterSpecs, session, queryParameters); // NOTE: see TODO below + + sqlString = AddLimitsParametersIfNeeded(sqlString, parameterSpecs, queryParameters, session); + // TODO: for sub-select fetching we have to try to assign the QueryParameter.ProcessedSQL here (with limits) but only after use IParameterSpecification for any kind of queries + + // The PreprocessSQL method can modify the SqlString but should never add parameters (or we have to override it) + sqlString = PreprocessSQL(sqlString, queryParameters, session.Factory.Dialect); + + // After the last modification to the SqlString we can collect all parameters types. + ResetEffectiveExpectedType(parameterSpecs, queryParameters); // <= TODO: remove this method when we can infer the type during the parse + + return new SqlCommand.SqlCommandImpl(sqlString, parameterSpecs, queryParameters, session.Factory); + } + /// <summary> /// Obtain an <c>IDbCommand</c> with all parameters pre-bound. Bind positional parameters, /// named parameters, and limit parameters. Modified: trunk/nhibernate/src/NHibernate/Impl/MultiCriteriaImpl.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Impl/MultiCriteriaImpl.cs 2011-06-07 01:47:49 UTC (rev 5914) +++ trunk/nhibernate/src/NHibernate/Impl/MultiCriteriaImpl.cs 2011-06-12 22:04:44 UTC (rev 5915) @@ -183,8 +183,8 @@ translators.Add(translator); QueryParameters queryParameters = translator.GetQueryParameters(); parameters.Add(queryParameters); - SqlCommandInfo commandInfo = loader.GetQueryStringAndTypes(session, queryParameters, resultSetsCommand.ParametersCount); - resultSetsCommand.Append(commandInfo); + ISqlCommand singleCommand = loader.CreateSqlCommandInfo(queryParameters, session); + resultSetsCommand.Append(singleCommand); } } @@ -200,7 +200,7 @@ try { - using (var reader = resultSetsCommand.GetReader(loaders.ToArray(), parameters.ToArray(), null)) + using (var reader = resultSetsCommand.GetReader(null)) { ArrayList[] hydratedObjects = new ArrayList[loaders.Count]; List<EntityKey[]>[] subselectResultKeys = new List<EntityKey[]>[loaders.Count]; Modified: trunk/nhibernate/src/NHibernate/Impl/MultiQueryImpl.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Impl/MultiQueryImpl.cs 2011-06-07 01:47:49 UTC (rev 5914) +++ trunk/nhibernate/src/NHibernate/Impl/MultiQueryImpl.cs 2011-06-12 22:04:44 UTC (rev 5915) @@ -504,7 +504,7 @@ try { - using (var reader = resultSetsCommand.GetReader(translators.Select(t=> t.Loader).ToArray(), Parameters.ToArray(), commandTimeout != RowSelection.NoValue ? commandTimeout : (int?)null)) + using (var reader = resultSetsCommand.GetReader(commandTimeout != RowSelection.NoValue ? commandTimeout : (int?)null)) { if (log.IsDebugEnabled) { @@ -640,9 +640,8 @@ { translators.Add(translator); parameters.Add(queryParameters); - queryParameters = GetFilteredQueryParameters(queryParameters, translator); - SqlCommandInfo commandInfo = translator.Loader.GetQueryStringAndTypes(session, queryParameters, resultSetsCommand.ParametersCount); - resultSetsCommand.Append(commandInfo); + ISqlCommand singleCommand = translator.Loader.CreateSqlCommandInfo(queryParameters, session); + resultSetsCommand.Append(singleCommand); } } } @@ -866,7 +865,7 @@ var sqlQueryImpl = (SqlQueryImpl) sqlQuery; NativeSQLQuerySpecification sqlQuerySpec = sqlQueryImpl.GenerateQuerySpecification(sqlQueryImpl.NamedParams); var sqlCustomQuery = new SQLCustomQuery(sqlQuerySpec.SqlQueryReturns, sqlQuerySpec.QueryString, sqlQuerySpec.QuerySpaces, sessionFactory); - loader = new CustomLoader(sqlCustomQuery, sessionFactory); + loader = new CustomLoader(sqlCustomQuery, sqlCustomQuery.CollectedParametersSpecifications, sessionFactory); } public IType[] ReturnTypes Modified: trunk/nhibernate/src/NHibernate/Loader/Criteria/CriteriaLoader.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Loader/Criteria/CriteriaLoader.cs 2011-06-07 01:47:49 UTC (rev 5914) +++ trunk/nhibernate/src/NHibernate/Loader/Criteria/CriteriaLoader.cs 2011-06-12 22:04:44 UTC (rev 5915) @@ -185,6 +185,26 @@ return customResultTransformer.TransformList(results); } + public override ISqlCommand CreateSqlCommandInfo(QueryParameters queryParameters, ISessionImplementor session) + { + // NOTE: repeated code PrepareQueryCommand + // A distinct-copy of parameter specifications collected during query construction + var parameterSpecs = new HashSet<IParameterSpecification>(translator.CollectedParameterSpecifications); + SqlString sqlString = SqlString.Copy(); + + // dynamic-filter parameters: during the HQL->SQL parsing, filters can be added as SQL_TOKEN/string and the SqlGenerator will not find it + sqlString = ExpandDynamicFilterParameters(sqlString, parameterSpecs, session); + AdjustQueryParametersForSubSelectFetching(sqlString, parameterSpecs, session, queryParameters); // NOTE: see TODO below + + sqlString = AddLimitsParametersIfNeeded(sqlString, parameterSpecs, queryParameters, session); + // TODO: for sub-select fetching we have to try to assign the QueryParameter.ProcessedSQL here (with limits) but only after use IParameterSpecification for any kind of queries + + // The PreprocessSQL method can modify the SqlString but should never add parameters (or we have to override it) + sqlString = PreprocessSQL(sqlString, queryParameters, session.Factory.Dialect); + + return new SqlCommand.SqlCommandImpl(sqlString, parameterSpecs, queryParameters, session.Factory); + } + /// <summary> /// Obtain an <c>IDbCommand</c> with all parameters pre-bound. Bind positional parameters, /// named parameters, and limit parameters. @@ -199,9 +219,7 @@ /// <returns>A CommandWrapper wrapping an IDbCommand that is ready to be executed.</returns> protected internal override IDbCommand PrepareQueryCommand(QueryParameters queryParameters, bool scroll, ISessionImplementor session) { - // NH: In this Loader we can know better all parameters used so we can simplify the IDbCommand construction - // NH: would be very useful if we can do the same with Criteria. This method works just for HQL and LINQ. - + // NOTE: repeated code CreateSqlCommandInfo (here we are reusing some other variables) // A distinct-copy of parameter specifications collected during query construction var parameterSpecs = new HashSet<IParameterSpecification>(translator.CollectedParameterSpecifications); SqlString sqlString = SqlString.Copy(); Modified: trunk/nhibernate/src/NHibernate/Loader/Custom/CustomLoader.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Loader/Custom/CustomLoader.cs 2011-06-07 01:47:49 UTC (rev 5914) +++ trunk/nhibernate/src/NHibernate/Loader/Custom/CustomLoader.cs 2011-06-12 22:04:44 UTC (rev 5915) @@ -1,3 +1,5 @@ +using System; +using System.Linq; using System.Collections; using System.Collections.Generic; using System.Data; @@ -4,12 +6,14 @@ using Iesi.Collections.Generic; using NHibernate.Engine; using NHibernate.Hql; +using NHibernate.Param; using NHibernate.Persister.Collection; using NHibernate.Persister.Entity; using NHibernate.SqlCommand; using NHibernate.Transform; using NHibernate.Type; using NHibernate.Util; +using IQueryable = NHibernate.Persister.Entity.IQueryable; namespace NHibernate.Loader.Custom { @@ -23,6 +27,7 @@ private readonly SqlString sql; private readonly ISet<string> querySpaces = new HashedSet<string>(); private readonly IDictionary<string, object> namedParameterBindPoints; + private List<IParameterSpecification> parametersSpecifications; private readonly IQueryable[] entityPersisters; private readonly int[] entityOwners; @@ -38,6 +43,12 @@ private IType[] resultTypes; private string[] transformerAliases; + public CustomLoader(ICustomQuery customQuery, IEnumerable<IParameterSpecification> parametersSpecifications, ISessionFactoryImplementor factory) + : this(customQuery, factory) + { + this.parametersSpecifications = parametersSpecifications.ToList(); + } + public CustomLoader(ICustomQuery customQuery, ISessionFactoryImplementor factory) : base(factory) { sql = customQuery.SQL; @@ -337,6 +348,92 @@ transformerAliases = aliases.ToArray(); } + public override ISqlCommand CreateSqlCommandInfo(QueryParameters queryParameters, ISessionImplementor session) + { + if(parametersSpecifications == null) + { + throw new InvalidOperationException("The custom SQL loader was not initialized with Parameters Specifications."); + } + // A distinct-copy of parameter specifications collected during query construction + var parameterSpecs = new HashSet<IParameterSpecification>(parametersSpecifications); + SqlString sqlString = SqlString.Copy(); + + // dynamic-filter parameters: during the HQL->SQL parsing, filters can be added as SQL_TOKEN/string and the SqlGenerator will not find it + //sqlString = ExpandDynamicFilterParameters(sqlString, parameterSpecs, session); + //AdjustQueryParametersForSubSelectFetching(sqlString, parameterSpecs, session, queryParameters); // NOTE: see TODO below + + sqlString = AddLimitsParametersIfNeeded(sqlString, parameterSpecs, queryParameters, session); + // TODO: for sub-select fetching we have to try to assign the QueryParameter.ProcessedSQL here (with limits) but only after use IParameterSpecification for any kind of queries + + // The PreprocessSQL method can modify the SqlString but should never add parameters (or we have to override it) + sqlString = PreprocessSQL(sqlString, queryParameters, session.Factory.Dialect); + + // After the last modification to the SqlString we can collect all parameters types. + ResetEffectiveExpectedType(parameterSpecs, queryParameters); // <= TODO: remove this method when we can infer the type during the parse + + return new SqlCommand.SqlCommandImpl(sqlString, parameterSpecs, queryParameters, session.Factory); + } + + private SqlString AddLimitsParametersIfNeeded(SqlString sqlString, ICollection<IParameterSpecification> parameterSpecs, QueryParameters queryParameters, ISessionImplementor session) + { + var sessionFactory = session.Factory; + Dialect.Dialect dialect = sessionFactory.Dialect; + + RowSelection selection = queryParameters.RowSelection; + bool useLimit = UseLimit(selection, dialect); + if (useLimit) + { + bool hasFirstRow = GetFirstRow(selection) > 0; + bool useOffset = hasFirstRow && dialect.SupportsLimitOffset; + int max = GetMaxOrLimit(dialect, selection); + int? skip = useOffset ? (int?)dialect.GetOffsetValue(GetFirstRow(selection)) : null; + int? take = max != int.MaxValue ? (int?)max : null; + + Parameter skipSqlParameter = null; + Parameter takeSqlParameter = null; + if (skip.HasValue) + { + var skipParameter = new QuerySkipParameterSpecification(); + skipSqlParameter = Parameter.Placeholder; + skipSqlParameter.BackTrack = skipParameter.GetIdsForBackTrack(sessionFactory).First(); + parameterSpecs.Add(skipParameter); + } + if (take.HasValue) + { + var takeParameter = new QueryTakeParameterSpecification(); + takeSqlParameter = Parameter.Placeholder; + takeSqlParameter.BackTrack = takeParameter.GetIdsForBackTrack(sessionFactory).First(); + parameterSpecs.Add(takeParameter); + } + // The dialect can move the given parameters where he need, what it can't do is generates new parameters loosing the BackTrack. + return dialect.GetLimitString(sqlString, skip, take, skipSqlParameter, takeSqlParameter); + } + return sqlString; + } + + private void ResetEffectiveExpectedType(IEnumerable<IParameterSpecification> parameterSpecs, QueryParameters queryParameters) + { + foreach (var parameterSpecification in parameterSpecs.OfType<IExplicitParameterSpecification>()) + { + parameterSpecification.SetEffectiveType(queryParameters); + } + } + + public IType[] ResultTypes + { + get { return resultTypes; } + } + + public string[] ReturnAliases + { + get { return transformerAliases; } + } + + public IEnumerable<string> NamedParameters + { + get { return namedParameterBindPoints.Keys; } + } + public class ResultRowProcessor { private readonly bool hasScalars; @@ -402,21 +499,6 @@ } } - public IType[] ResultTypes - { - get { return resultTypes; } - } - - public string[] ReturnAliases - { - get { return transformerAliases; } - } - - public IEnumerable<string> NamedParameters - { - get { return namedParameterBindPoints.Keys; } - } - public interface IResultColumnProcessor { object Extract(object[] data, IDataReader resultSet, ISessionImplementor session); Modified: trunk/nhibernate/src/NHibernate/Loader/Custom/Sql/SQLCustomQuery.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Loader/Custom/Sql/SQLCustomQuery.cs 2011-06-07 01:47:49 UTC (rev 5914) +++ trunk/nhibernate/src/NHibernate/Loader/Custom/Sql/SQLCustomQuery.cs 2011-06-12 22:04:44 UTC (rev 5915) @@ -1,8 +1,10 @@ using System.Collections.Generic; +using System.Linq; using Iesi.Collections.Generic; using NHibernate.Engine; using NHibernate.Engine.Query.Sql; +using NHibernate.Param; using NHibernate.Persister.Collection; using NHibernate.Persister.Entity; using NHibernate.SqlCommand; @@ -20,6 +22,7 @@ private readonly Dictionary<string, object> namedParameterBindPoints = new Dictionary<string, object>(); private readonly ISet<string> querySpaces = new HashedSet<string>(); private readonly SqlString sql; + private List<IParameterSpecification> parametersSpecifications; public SQLCustomQuery(INativeSQLQueryReturn[] queryReturns, string sqlQuery, ICollection<string> additionalQuerySpaces, ISessionFactoryImplementor factory) @@ -28,10 +31,11 @@ SQLQueryReturnProcessor processor = new SQLQueryReturnProcessor(queryReturns, factory); SQLQueryReturnProcessor.ResultAliasContext aliasContext = processor.Process(); - SQLQueryParser parser = new SQLQueryParser(sqlQuery, new ParserContext(aliasContext)); + SQLQueryParser parser = new SQLQueryParser(factory, sqlQuery, new ParserContext(aliasContext)); sql = parser.Process(); ArrayHelper.AddAll(namedParameterBindPoints, parser.NamedParameters); ArrayHelper.AddAll(customQueryReturns, processor.GenerateCustomReturns(parser.QueryHasAliases)); + parametersSpecifications = parser.CollectedParametersSpecifications.ToList(); if (additionalQuerySpaces != null) { @@ -39,6 +43,11 @@ } } + public IEnumerable<IParameterSpecification> CollectedParametersSpecifications + { + get { return parametersSpecifications; } + } + #region ICustomQuery Members public SqlString SQL Modified: trunk/nhibernate/src/NHibernate/Loader/Custom/Sql/SQLQueryParser.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Loader/Custom/Sql/SQLQueryParser.cs 2011-06-07 01:47:49 UTC (rev 5914) +++ trunk/nhibernate/src/NHibernate/Loader/Custom/Sql/SQLQueryParser.cs 2011-06-12 22:04:44 UTC (rev 5915) @@ -1,7 +1,10 @@ using System.Collections; using System.Collections.Generic; +using System.Linq; using System.Text; +using NHibernate.Engine; using NHibernate.Engine.Query; +using NHibernate.Param; using NHibernate.Persister.Collection; using NHibernate.Persister.Entity; using NHibernate.SqlCommand; @@ -21,15 +24,18 @@ IDictionary<string, string[]> GetPropertyResultsMapByAlias(string alias); } + private readonly ISessionFactoryImplementor factory; private readonly string originalQueryString; private readonly IParserContext context; private readonly Dictionary<string, object> namedParameters = new Dictionary<string, object>(); private long aliasesFound; + private IEnumerable<IParameterSpecification> parametersSpecifications; - public SQLQueryParser(string sqlQuery, IParserContext context) + public SQLQueryParser(ISessionFactoryImplementor factory, string sqlQuery, IParserContext context) { + this.factory = factory; originalQueryString = sqlQuery; this.context = context; } @@ -49,6 +55,11 @@ return SubstituteParams(SubstituteBrackets()); } + public IEnumerable<IParameterSpecification> CollectedParametersSpecifications + { + get { return parametersSpecifications; } + } + // TODO: should "record" how many properties we have reffered to - and if we // don't get'em'all we throw an exception! Way better than trial and error ;) private string SubstituteBrackets() @@ -239,9 +250,9 @@ /// <returns> The SQL query with parameter substitution complete. </returns> private SqlString SubstituteParams(string sqlString) { - ParameterSubstitutionRecognizer recognizer = new ParameterSubstitutionRecognizer(); + var recognizer = new ParameterSubstitutionRecognizer(factory); ParameterParser.Parse(sqlString, recognizer); - + parametersSpecifications = recognizer.ParametersSpecifications.ToList(); namedParameters.Clear(); foreach (KeyValuePair<string, object> de in recognizer.namedParameterBindPoints) { @@ -253,24 +264,49 @@ public class ParameterSubstitutionRecognizer : ParameterParser.IRecognizer { + private readonly ISessionFactoryImplementor factory; internal SqlStringBuilder result = new SqlStringBuilder(); internal Dictionary<string, object> namedParameterBindPoints = new Dictionary<string, object>(); internal int parameterCount = 0; + private readonly List<IParameterSpecification> parametersSpecifications = new List<IParameterSpecification>(); + private int positionalParameterCount; + public ParameterSubstitutionRecognizer(ISessionFactoryImplementor factory) + { + this.factory = factory; + } + + public IEnumerable<IParameterSpecification> ParametersSpecifications + { + get { return parametersSpecifications; } + } + public void OutParameter(int position) { - result.Add(Parameter.Placeholder); + var paramSpec = new PositionalParameterSpecification(1, position, positionalParameterCount++); + var parameter = Parameter.Placeholder; + parameter.BackTrack = paramSpec.GetIdsForBackTrack(factory).First(); + parametersSpecifications.Add(paramSpec); + result.Add(parameter); } public void OrdinalParameter(int position) { - result.Add(Parameter.Placeholder); + var paramSpec = new PositionalParameterSpecification(1, position, positionalParameterCount++); + var parameter = Parameter.Placeholder; + parameter.BackTrack = paramSpec.GetIdsForBackTrack(factory).First(); + parametersSpecifications.Add(paramSpec); + result.Add(parameter); } public void NamedParameter(string name, int position) { AddNamedParameter(name); - result.Add(Parameter.Placeholder); + var paramSpec = new NamedParameterSpecification(1, position, name); + var parameter = Parameter.Placeholder; + parameter.BackTrack = paramSpec.GetIdsForBackTrack(factory).First(); + parametersSpecifications.Add(paramSpec); + result.Add(parameter); } public void JpaPositionalParameter(string name, int position) Modified: trunk/nhibernate/src/NHibernate/Loader/Loader.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Loader/Loader.cs 2011-06-07 01:47:49 UTC (rev 5914) +++ trunk/nhibernate/src/NHibernate/Loader/Loader.cs 2011-06-12 22:04:44 UTC (rev 5915) @@ -1785,6 +1785,11 @@ return new SqlCommandInfo(sqlString, sqlTypes); } + public virtual ISqlCommand CreateSqlCommandInfo(QueryParameters queryParameters, ISessionImplementor session) + { + throw new NotSupportedException("This loader does not support extraction of single command."); + } + #endregion } } Modified: trunk/nhibernate/src/NHibernate/NHibernate.csproj =================================================================== --- trunk/nhibernate/src/NHibernate/NHibernate.csproj 2011-06-07 01:47:49 UTC (rev 5914) +++ trunk/nhibernate/src/NHibernate/NHibernate.csproj 2011-06-12 22:04:44 UTC (rev 5915) @@ -569,6 +569,7 @@ <Compile Include="SqlCommand\SqlBaseBuilder.cs" /> <Compile Include="SqlCommand\SqlDeleteBuilder.cs" /> <Compile Include="SqlCommand\SqlInsertBuilder.cs" /> + <Compile Include="SqlCommand\SqlCommandImpl.cs" /> <Compile Include="SqlCommand\SqlSelectBuilder.cs" /> <Compile Include="SqlCommand\SqlSimpleSelectBuilder.cs" /> <Compile Include="SqlCommand\SqlString.cs" /> Modified: trunk/nhibernate/src/NHibernate/Param/AbstractExplicitParameterSpecification.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Param/AbstractExplicitParameterSpecification.cs 2011-06-07 01:47:49 UTC (rev 5914) +++ trunk/nhibernate/src/NHibernate/Param/AbstractExplicitParameterSpecification.cs 2011-06-12 22:04:44 UTC (rev 5915) @@ -40,6 +40,7 @@ public abstract string RenderDisplayInfo(); public abstract IEnumerable<string> GetIdsForBackTrack(IMapping sessionFactory); public abstract void Bind(IDbCommand command, IList<Parameter> sqlQueryParametersList, QueryParameters queryParameters, ISessionImplementor session); + public abstract void Bind(IDbCommand command, IList<Parameter> multiSqlQueryParametersList, int singleSqlParametersOffset, IList<Parameter> sqlQueryParametersList, QueryParameters queryParameters, ISessionImplementor session); public abstract void SetEffectiveType(QueryParameters queryParameters); #endregion Modified: trunk/nhibernate/src/NHibernate/Param/AggregatedIndexCollectionSelectorParameterSpecifications.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Param/AggregatedIndexCollectionSelectorParameterSpecifications.cs 2011-06-07 01:47:49 UTC (rev 5914) +++ trunk/nhibernate/src/NHibernate/Param/AggregatedIndexCollectionSelectorParameterSpecifications.cs 2011-06-12 22:04:44 UTC (rev 5915) @@ -32,6 +32,11 @@ throw new NotImplementedException(); } + public void Bind(IDbCommand command, IList<Parameter> multiSqlQueryParametersList, int singleSqlParametersOffset, IList<Parameter> sqlQueryParametersList, QueryParameters queryParameters, ISessionImplementor session) + { + throw new NotImplementedException(); + } + public IType ExpectedType { get { return null; } Modified: trunk/nhibernate/src/NHibernate/Param/CollectionFilterKeyParameterSpecification.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Param/CollectionFilterKeyParameterSpecification.cs 2011-06-07 01:47:49 UTC (rev 5914) +++ trunk/nhibernate/src/NHibernate/Param/CollectionFilterKeyParameterSpecification.cs 2011-06-12 22:04:44 UTC (rev 5915) @@ -31,6 +31,16 @@ #region IParameterSpecification Members + public void Bind(IDbCommand command, IList<Parameter> multiSqlQueryParametersList, int singleSqlParametersOffset, IList<Parameter> sqlQueryParametersList, QueryParameters queryParameters, ISessionImplementor session) + { + IType type = keyType; + object value = queryParameters.PositionalParameterValues[queryParameterPosition]; + + string backTrackId = GetIdsForBackTrack(session.Factory).First(); // just the first because IType suppose the oders in certain sequence + int position = sqlQueryParametersList.GetEffectiveParameterLocations(backTrackId).Single(); // an HQL positional parameter can't appear more than once + type.NullSafeSet(command, value, position + singleSqlParametersOffset, session); + } + public IType ExpectedType { get { return keyType; } @@ -53,12 +63,7 @@ public void Bind(IDbCommand command, IList<Parameter> sqlQueryParametersList, QueryParameters queryParameters, ISessionImplementor session) { - IType type = keyType; - object value = queryParameters.PositionalParameterValues[queryParameterPosition]; - - string backTrackId = GetIdsForBackTrack(session.Factory).First(); // just the first because IType suppose the oders in certain sequence - int position = sqlQueryParametersList.GetEffectiveParameterLocations(backTrackId).Single(); // an HQL positional parameter can't appear more than once - type.NullSafeSet(command, value, position, session); + Bind(command, sqlQueryParametersList, 0, sqlQueryParametersList, queryParameters, session); } #endregion Modified: trunk/nhibernate/src/NHibernate/Param/CriteriaNamedParameterSpecification.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Param/CriteriaNamedParameterSpecification.cs 2011-06-07 01:47:49 UTC (rev 5914) +++ trunk/nhibernate/src/NHibernate/Param/CriteriaNamedParameterSpecification.cs 2011-06-12 22:04:44 UTC (rev 5915) @@ -23,11 +23,16 @@ public void Bind(IDbCommand command, IList<Parameter> sqlQueryParametersList, QueryParameters queryParameters, ISessionImplementor session) { + Bind(command, sqlQueryParametersList, 0, sqlQueryParametersList, queryParameters, session); + } + + public void Bind(IDbCommand command, IList<Parameter> multiSqlQueryParametersList, int singleSqlParametersOffset, IList<Parameter> sqlQueryParametersList, QueryParameters queryParameters, ISessionImplementor session) + { TypedValue typedValue = queryParameters.NamedParameters[name]; string backTrackId = GetIdsForBackTrack(session.Factory).First(); foreach (int position in sqlQueryParametersList.GetEffectiveParameterLocations(backTrackId)) { - ExpectedType.NullSafeSet(command, typedValue.Value, position, session); + ExpectedType.NullSafeSet(command, typedValue.Value, position + singleSqlParametersOffset, session); } } Modified: trunk/nhibernate/src/NHibernate/Param/DynamicFilterParameterSpecification.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Param/DynamicFilterParameterSpecification.cs 2011-06-07 01:47:49 UTC (rev 5914) +++ trunk/nhibernate/src/NHibernate/Param/DynamicFilterParameterSpecification.cs 2011-06-12 22:04:44 UTC (rev 5915) @@ -37,11 +37,16 @@ public void Bind(IDbCommand command, IList<Parameter> sqlQueryParametersList, QueryParameters queryParameters, ISessionImplementor session) { + Bind(command, sqlQueryParametersList, 0, sqlQueryParametersList, queryParameters, session); + } + + public void Bind(IDbCommand command, IList<Parameter> multiSqlQueryParametersList, int singleSqlParametersOffset, IList<Parameter> sqlQueryParametersList, QueryParameters queryParameters, ISessionImplementor session) + { string backTrackId = GetIdsForBackTrack(session.Factory).First(); // just the first because IType suppose the oders in certain sequence - // The same filterName-parameterName can appear more than once + // The same filterName-parameterName can appear more than once in the whole query object value = session.GetFilterParameterValue(filterParameterFullName); - foreach (int position in sqlQueryParametersList.GetEffectiveParameterLocations(backTrackId)) + foreach (int position in multiSqlQueryParametersList.GetEffectiveParameterLocations(backTrackId)) { ExpectedType.NullSafeSet(command, value, position, session); } Modified: trunk/nhibernate/src/NHibernate/Param/IParameterSpecification.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Param/IParameterSpecification.cs 2011-06-07 01:47:49 UTC (rev 5914) +++ trunk/nhibernate/src/NHibernate/Param/IParameterSpecification.cs 2011-06-12 22:04:44 UTC (rev 5915) @@ -21,6 +21,22 @@ void Bind(IDbCommand command, IList<Parameter> sqlQueryParametersList, QueryParameters queryParameters, ISessionImplementor session); /// <summary> + /// Bind the appropriate value into the given command. + /// </summary> + /// <param name="command">The command into which the value should be bound.</param> + /// <param name="multiSqlQueryParametersList">The parameter-list of the whole query of the command.</param> + /// <param name="singleSqlParametersOffset">The offset from where start the list of <see cref="IDataParameter"/> in the given <paramref name="command"/> for the query where this <see cref="IParameterSpecification"/> was used. </param> + /// <param name="sqlQueryParametersList">The list of Sql query parameter in the exact sequence they are present in the query where this <see cref="IParameterSpecification"/> was used.</param> + /// <param name="queryParameters">The defined values for the query where this <see cref="IParameterSpecification"/> was used.</param> + /// <param name="session">The session against which the current execution is occuring.</param> + /// <remarks> + /// Suppose the <paramref name="command"/> is composed by two queries. The <paramref name="singleSqlParametersOffset"/> for the first query is zero. + /// If the first query in <paramref name="command"/> has 12 parameters (size of its SqlType array) the offset to bind all <see cref="IParameterSpecification"/>s of the second query in the + /// <paramref name="command"/> is 12 (for the first query we are using from 0 to 11). + /// </remarks> + void Bind(IDbCommand command, IList<Parameter> multiSqlQueryParametersList, int singleSqlParametersOffset, IList<Parameter> sqlQueryParametersList, QueryParameters queryParameters, ISessionImplementor session); + + /// <summary> /// Get or set the type which we are expeting for a bind into this parameter based /// on translated contextual information. /// </summary> Modified: trunk/nhibernate/src/NHibernate/Param/NamedParameterSpecification.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Param/NamedParameterSpecification.cs 2011-06-07 01:47:49 UTC (rev 5914) +++ trunk/nhibernate/src/NHibernate/Param/NamedParameterSpecification.cs 2011-06-12 22:04:44 UTC (rev 5915) @@ -52,11 +52,16 @@ public override void Bind(IDbCommand command, IList<Parameter> sqlQueryParametersList, QueryParameters queryParameters, ISessionImplementor session) { + Bind(command, sqlQueryParametersList, 0, sqlQueryParametersList, queryParameters, session); + } + + public override void Bind(IDbCommand command, IList<Parameter> multiSqlQueryParametersList, int singleSqlParametersOffset, IList<Parameter> sqlQueryParametersList, QueryParameters queryParameters, ISessionImplementor session) + { TypedValue typedValue = queryParameters.NamedParameters[name]; string backTrackId = GetIdsForBackTrack(session.Factory).First(); // just the first because IType suppose the oders in certain sequence foreach (int position in sqlQueryParametersList.GetEffectiveParameterLocations(backTrackId)) { - ExpectedType.NullSafeSet(command, typedValue.Value, position, session); + ExpectedType.NullSafeSet(command, typedValue.Value, position + singleSqlParametersOffset, session); } } Modified: trunk/nhibernate/src/NHibernate/Param/PositionalParameterSpecification.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Param/PositionalParameterSpecification.cs 2011-06-07 01:47:49 UTC (rev 5914) +++ trunk/nhibernate/src/NHibernate/Param/PositionalParameterSpecification.cs 2011-06-12 22:04:44 UTC (rev 5915) @@ -52,6 +52,11 @@ public override void Bind(IDbCommand command, IList<Parameter> sqlQueryParametersList, QueryParameters queryParameters, ISessionImplementor session) { + Bind(command, sqlQueryParametersList, 0, sqlQueryParametersList, queryParameters, session); + } + + public override void Bind(IDbCommand command, IList<Parameter> multiSqlQueryParametersList, int singleSqlParametersOffset, IList<Parameter> sqlQueryParametersList, QueryParameters queryParameters, ISessionImplementor session) + { IType type = ExpectedType; object value = queryParameters.PositionalParameterValues[hqlPosition]; @@ -59,7 +64,7 @@ // an HQL positional parameter can appear more than once because a custom HQL-Function can duplicate it foreach (int position in sqlQueryParametersList.GetEffectiveParameterLocations(backTrackId)) { - type.NullSafeSet(command, value, position, session); + type.NullSafeSet(command, value, position + singleSqlParametersOffset, session); } } Modified: trunk/nhibernate/src/NHibernate/Param/QuerySkipParameterSpecification.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Param/QuerySkipParameterSpecification.cs 2011-06-07 01:47:49 UTC (rev 5914) +++ trunk/nhibernate/src/NHibernate/Param/QuerySkipParameterSpecification.cs 2011-06-12 22:04:44 UTC (rev 5915) @@ -27,7 +27,13 @@ public void Bind(IDbCommand command, IList<Parameter> sqlQueryParametersList, QueryParameters queryParameters, ISessionImplementor session) { - var effectiveParameterLocations = sqlQueryParametersList.GetEffectiveParameterLocations(limitParametersNameForThisQuery).ToArray(); + Bind(command, sqlQueryParametersList, 0, sqlQueryParametersList, queryParameters, session); + } + + public void Bind(IDbCommand command, IList<Parameter> multiSqlQueryParametersList, int singleSqlParametersOffset, IList<Parameter> sqlQueryParametersList, QueryParameters queryParameters, ISessionImplementor session) + { + // The QuerySkipParameterSpecification is unique so we can use multiSqlQueryParametersList + var effectiveParameterLocations = multiSqlQueryParametersList.GetEffectiveParameterLocations(limitParametersNameForThisQuery).ToArray(); if (effectiveParameterLocations.Length > 0) { // if the dialect does not support variable limits the parameter may was removed Modified: trunk/nhibernate/src/NHibernate/Param/QueryTakeParameterSpecification.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Param/QueryTakeParameterSpecification.cs 2011-06-07 01:47:49 UTC (rev 5914) +++ trunk/nhibernate/src/NHibernate/Param/QueryTakeParameterSpecification.cs 2011-06-12 22:04:44 UTC (rev 5915) @@ -27,7 +27,13 @@ public void Bind(IDbCommand command, IList<Parameter> sqlQueryParametersList, QueryParameters queryParameters, ISessionImplementor session) { - var effectiveParameterLocations = sqlQueryParametersList.GetEffectiveParameterLocations(limitParametersNameForThisQuery).ToArray(); + Bind(command, sqlQueryParametersList, 0, sqlQueryParametersList, queryParameters, session); + } + + public void Bind(IDbCommand command, IList<Parameter> multiSqlQueryParametersList, int singleSqlParametersOffset, IList<Parameter> sqlQueryParametersList, QueryParameters queryParameters, ISessionImplementor session) + { + // The QueryTakeParameterSpecification is unique so we can use multiSqlQueryParametersList + var effectiveParameterLocations = multiSqlQueryParametersList.GetEffectiveParameterLocations(limitParametersNameForThisQuery).ToArray(); if (effectiveParameterLocations.Any()) { // if the dialect does not support variable limits the parameter may was removed Modified: trunk/nhibernate/src/NHibernate/Param/VersionTypeSeedParameterSpecification.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Param/VersionTypeSeedParameterSpecification.cs 2011-06-07 01:47:49 UTC (rev 5914) +++ trunk/nhibernate/src/NHibernate/Param/VersionTypeSeedParameterSpecification.cs 2011-06-12 22:04:44 UTC (rev 5915) @@ -1,3 +1,4 @@ +using System; using System.Collections.Generic; using System.Data; using System.Linq; @@ -26,6 +27,11 @@ type.NullSafeSet(command, type.Seed(session), position, session); } + public void Bind(IDbCommand command, IList<Parameter> multiSqlQueryParametersList, int singleSqlParametersOffset, IList<Parameter> sqlQueryParametersList, QueryParameters queryParameters, ISessionImplementor session) + { + throw new NotSupportedException("Not supported for multiquery loader."); + } + public IType ExpectedType { get { return type; } Added: trunk/nhibernate/src/NHibernate/SqlCommand/SqlCommandImpl.cs =================================================================== --- trunk/nhibernate/src/NHibernate/SqlCommand/SqlCommandImpl.cs (rev 0) +++ trunk/nhibernate/src/NHibernate/SqlCommand/SqlCommandImpl.cs 2011-06-12 22:04:44 UTC (rev 5915) @@ -0,0 +1,83 @@ +using System.Collections.Generic; +using System.Data; +using System.Linq; +using NHibernate.Engine; +using NHibernate.Param; +using NHibernate.SqlTypes; + +namespace NHibernate.SqlCommand +{ + public interface ISqlCommand + { + SqlType[] ParameterTypes { get; } + SqlString Query { get; } + QueryParameters QueryParameters { get; } + + /// <summary> + /// Bind the appropriate value into the given command. + /// </summary> + /// <param name="command">The command into which the value should be bound.</param> + /// <param name="commandQueryParametersList">The parameter-list of the whole query of the command.</param> + /// <param name="singleSqlParametersOffset">The offset from where start the list of <see cref="IDataParameter"/>, in the given <paramref name="command"/>, for the this <see cref="SqlCommandImpl"/>. </param> + /// <param name="session">The session against which the current execution is occuring.</param> + void Bind(IDbCommand command, IList<Parameter> commandQueryParametersList, int singleSqlParametersOffset, ISessionImplementor session); + } + + public class SqlCommandImpl : ISqlCommand + { + private readonly SqlString query; + private readonly ICollection<IParameterSpecification> specifications; + private readonly QueryParameters queryParameters; + private readonly ISessionFactoryImplementor factory; + private SqlType[] parameterTypes; + List<Parameter> sqlQueryParametersList; + + public SqlCommandImpl(SqlString query, ICollection<IParameterSpecification> specifications, QueryParameters queryParameters, ISessionFactoryImplementor factory) + { + this.query = query; + this.specifications = specifications; + this.queryParameters = queryParameters; + this.factory = factory; + } + + private List<Parameter> SqlQueryParametersList + { + get { return sqlQueryParametersList ?? (sqlQueryParametersList = query.GetParameters().ToList()); } + } + + public SqlType[] ParameterTypes + { + get { return parameterTypes ?? (parameterTypes = specifications.GetQueryParameterTypes(SqlQueryParametersList, factory)); } + } + + public SqlString Query + { + get { return query; } + } + + public IEnumerable<IParameterSpecification> Specifications + { + get { return specifications; } + } + + public QueryParameters QueryParameters + { + get { return queryParameters; } + } + + /// <summary> + /// Bind the appropriate value into the given command. + /// </summary> + /// <param name="command">The command into which the value should be bound.</param> + /// <param name="commandQueryParametersList">The parameter-list of the whole query of the command.</param> + /// <param name="singleSqlParametersOffset">The offset from where start the list of <see cref="IDataParameter"/>, in the given <paramref name="command"/>, for the this <see cref="SqlCommandImpl"/>. </param> + /// <param name="session">The session against which the current execution is occuring.</param> + public void Bind(IDbCommand command, IList<Parameter> commandQueryParametersList, int singleSqlParametersOffset, ISessionImplementor session) + { + foreach (IParameterSpecification parameterSpecification in Specifications) + { + parameterSpecification.Bind(command, commandQueryParametersList, singleSqlParametersOffset, SqlQueryParametersList, QueryParameters, session); + } + } + } +} \ No newline at end of file Modified: trunk/nhibernate/src/NHibernate.Test/Pagination/CustomDialectFixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/Pagination/CustomDialectFixture.cs 2011-06-07 01:47:49 UTC (rev 5914) +++ trunk/nhibernate/src/NHibernate.Test/Pagination/CustomDialectFixture.cs 2011-06-12 22:04:44 UTC (rev 5915) @@ -91,7 +91,7 @@ } } - [Test, Ignore("To be fixed")] + [Test] public void LimitFirstMultiCriteria() { using (ISession s = OpenSession()) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pa...@us...> - 2011-06-07 01:48:11
|
Revision: 5914 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5914&view=rev Author: patearl Date: 2011-06-07 01:47:49 +0000 (Tue, 07 Jun 2011) Log Message: ----------- NH-2318: Fixed compatibility with ANSI Trim function. Modified Paths: -------------- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2318/Fixture.cs Modified: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2318/Fixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2318/Fixture.cs 2011-06-06 16:30:52 UTC (rev 5913) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2318/Fixture.cs 2011-06-07 01:47:49 UTC (rev 5914) @@ -56,6 +56,7 @@ "trim", NHibernateUtil.String, Projections.Constant("f"), + Projections.SqlProjection("from as literal", null, null), // Silly hack to get "from" as a second argument. Projections.Property("Name")), "irst")); IList<A> items = criteria.List<A>(); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pa...@us...> - 2011-06-06 16:30:58
|
Revision: 5913 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5913&view=rev Author: patearl Date: 2011-06-06 16:30:52 +0000 (Mon, 06 Jun 2011) Log Message: ----------- Criteria: Removed a useless line of code. Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Criterion/SqlFunctionProjection.cs Modified: trunk/nhibernate/src/NHibernate/Criterion/SqlFunctionProjection.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Criterion/SqlFunctionProjection.cs 2011-06-06 16:21:55 UTC (rev 5912) +++ trunk/nhibernate/src/NHibernate/Criterion/SqlFunctionProjection.cs 2011-06-06 16:30:52 UTC (rev 5913) @@ -77,8 +77,7 @@ var arguments = new ArrayList(); for (int i = 0; i < args.Length; i++) { - int loc = (position + 1) * 1000 + i; - SqlString projectArg = GetProjectionArgument(criteriaQuery, criteria, args[i], loc, enabledFilters); + SqlString projectArg = GetProjectionArgument(criteriaQuery, criteria, args[i], 0, enabledFilters); // The loc parameter is unused. arguments.Add(projectArg); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pa...@us...> - 2011-06-06 16:22:01
|
Revision: 5912 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5912&view=rev Author: patearl Date: 2011-06-06 16:21:55 +0000 (Mon, 06 Jun 2011) Log Message: ----------- NH-2318: Unignored test. Modified Paths: -------------- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2318/Fixture.cs Modified: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2318/Fixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2318/Fixture.cs 2011-06-06 16:03:06 UTC (rev 5911) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2318/Fixture.cs 2011-06-06 16:21:55 UTC (rev 5912) @@ -43,7 +43,6 @@ } [Test] - [Ignore] public void CriteriaTrimFunctionsWithParameters() { AddObjects(); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pa...@us...> - 2011-06-06 16:03:12
|
Revision: 5911 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5911&view=rev Author: patearl Date: 2011-06-06 16:03:06 +0000 (Mon, 06 Jun 2011) Log Message: ----------- Criteria: Fixed SqlFunctionProjection for cases where arguments are not mapped 1-to-1. Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Criterion/SqlFunctionProjection.cs Modified: trunk/nhibernate/src/NHibernate/Criterion/SqlFunctionProjection.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Criterion/SqlFunctionProjection.cs 2011-06-05 21:24:29 UTC (rev 5910) +++ trunk/nhibernate/src/NHibernate/Criterion/SqlFunctionProjection.cs 2011-06-06 16:03:06 UTC (rev 5911) @@ -73,26 +73,17 @@ IDictionary<string, IFilter> enabledFilters) { ISQLFunction sqlFunction = GetFunction(criteriaQuery); - var tokens = new ArrayList(); - string replacemenToken = Guid.NewGuid().ToString("n"); - for (int i = 0; i < args.Length; i++) - { - tokens.Add(replacemenToken); - } - string functionStatement = sqlFunction.Render(tokens, criteriaQuery.Factory).ToString(); - string[] splitted = functionStatement.Split(new string[] {replacemenToken}, StringSplitOptions.RemoveEmptyEntries); - SqlStringBuilder sb = new SqlStringBuilder(); - for (int i = 0; i < splitted.Length; i++) - { - sb.Add(splitted[i]); - if (i < args.Length) - { - int loc = (position + 1) * 1000 + i; - SqlString projectArg = GetProjectionArgument(criteriaQuery, criteria, args[i], loc, enabledFilters); - sb.Add(projectArg); - } - } + var arguments = new ArrayList(); + for (int i = 0; i < args.Length; i++) + { + int loc = (position + 1) * 1000 + i; + SqlString projectArg = GetProjectionArgument(criteriaQuery, criteria, args[i], loc, enabledFilters); + arguments.Add(projectArg); + } + + SqlStringBuilder sb = new SqlStringBuilder(); + sb.Add(sqlFunction.Render(arguments, criteriaQuery.Factory)); sb.Add(" as "); sb.Add(GetColumnAliases(position)[0]); return sb.ToSqlString(); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fab...@us...> - 2011-06-05 21:24:36
|
Revision: 5910 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5910&view=rev Author: fabiomaulo Date: 2011-06-05 21:24:29 +0000 (Sun, 05 Jun 2011) Log Message: ----------- Refactoring: IResultSetsCommand using Loader instances instead static methods Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Driver/BasicResultSetsCommand.cs trunk/nhibernate/src/NHibernate/Driver/IResultSetsCommand.cs trunk/nhibernate/src/NHibernate/Impl/MultiCriteriaImpl.cs trunk/nhibernate/src/NHibernate/Impl/MultiQueryImpl.cs trunk/nhibernate/src/NHibernate/Loader/Loader.cs Modified: trunk/nhibernate/src/NHibernate/Driver/BasicResultSetsCommand.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Driver/BasicResultSetsCommand.cs 2011-06-05 20:34:11 UTC (rev 5909) +++ trunk/nhibernate/src/NHibernate/Driver/BasicResultSetsCommand.cs 2011-06-05 21:24:29 UTC (rev 5910) @@ -47,7 +47,7 @@ get { return sqlString; } } - public virtual IDataReader GetReader(QueryParameters[] queryParameters, int? commandTimeout) + public virtual IDataReader GetReader(Loader.Loader[] queryLoaders, QueryParameters[] queryParameters, int? commandTimeout) { SqlType[] sqlTypes = types.ToArray(); var command= batcher.PrepareQueryCommand(CommandType.Text, sqlString, sqlTypes); @@ -57,45 +57,45 @@ } log.Info(command.CommandText); - BindParameters(command, queryParameters); + BindParameters(command, queryLoaders, queryParameters); return new BatcherDataReaderWrapper(batcher, command); } - protected virtual void BindParameters(IDbCommand command, QueryParameters[] queryParameters) + protected virtual void BindParameters(IDbCommand command, Loader.Loader[] queryLoaders, QueryParameters[] queryParameters) { int colIndex = 0; for (int queryIndex = 0; queryIndex < resultSetsCount; queryIndex++) { - int limitParameterSpan = BindLimitParametersFirstIfNeccesary(command, queryParameters[queryIndex], colIndex); - colIndex = BindQueryParameters(command, queryParameters[queryIndex], colIndex + limitParameterSpan); - colIndex += BindLimitParametersLastIfNeccesary(command, queryParameters[queryIndex], colIndex); + int limitParameterSpan = BindLimitParametersFirstIfNeccesary(command, queryLoaders[queryIndex], queryParameters[queryIndex], colIndex); + colIndex = BindQueryParameters(command, queryLoaders[queryIndex], queryParameters[queryIndex], colIndex + limitParameterSpan); + colIndex += BindLimitParametersLastIfNeccesary(command, queryLoaders[queryIndex], queryParameters[queryIndex], colIndex); } } - protected virtual int BindLimitParametersLastIfNeccesary(IDbCommand command, QueryParameters parameter, int colIndex) + protected virtual int BindLimitParametersLastIfNeccesary(IDbCommand command, Loader.Loader queryLoader, QueryParameters parameter, int colIndex) { RowSelection selection = parameter.RowSelection; - if (Loader.Loader.UseLimit(selection, dialect) && !dialect.BindLimitParametersFirst) + if (queryLoader.UseLimit(selection, dialect) && !dialect.BindLimitParametersFirst) { - return Loader.Loader.BindLimitParameters(command, colIndex, selection, session); + return queryLoader.BindLimitParameters(command, colIndex, selection, session); } return 0; } - protected virtual int BindQueryParameters(IDbCommand command, QueryParameters parameter, int colIndex) + protected virtual int BindQueryParameters(IDbCommand command, Loader.Loader queryLoader, QueryParameters parameter, int colIndex) { colIndex += parameter.BindParameters(command, colIndex, session); return colIndex; } - protected virtual int BindLimitParametersFirstIfNeccesary(IDbCommand command, QueryParameters parameter, int colIndex) + protected virtual int BindLimitParametersFirstIfNeccesary(IDbCommand command, Loader.Loader queryLoader, QueryParameters parameter, int colIndex) { int limitParameterSpan = 0; RowSelection selection = parameter.RowSelection; - if (Loader.Loader.UseLimit(selection, dialect) && dialect.BindLimitParametersFirst) + if (queryLoader.UseLimit(selection, dialect) && dialect.BindLimitParametersFirst) { - limitParameterSpan += Loader.Loader.BindLimitParameters(command, colIndex, selection, session); + limitParameterSpan += queryLoader.BindLimitParameters(command, colIndex, selection, session); } return limitParameterSpan; } Modified: trunk/nhibernate/src/NHibernate/Driver/IResultSetsCommand.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Driver/IResultSetsCommand.cs 2011-06-05 20:34:11 UTC (rev 5909) +++ trunk/nhibernate/src/NHibernate/Driver/IResultSetsCommand.cs 2011-06-05 21:24:29 UTC (rev 5910) @@ -10,6 +10,6 @@ int ParametersCount { get; } bool HasQueries { get; } SqlString Sql { get; } - IDataReader GetReader(QueryParameters[] queryParameters, int? commandTimeout); + IDataReader GetReader(Loader.Loader[] queryLoaders, QueryParameters[] queryParameters, int? commandTimeout); } } \ No newline at end of file Modified: trunk/nhibernate/src/NHibernate/Impl/MultiCriteriaImpl.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Impl/MultiCriteriaImpl.cs 2011-06-05 20:34:11 UTC (rev 5909) +++ trunk/nhibernate/src/NHibernate/Impl/MultiCriteriaImpl.cs 2011-06-05 21:24:29 UTC (rev 5910) @@ -200,7 +200,7 @@ try { - using (var reader = resultSetsCommand.GetReader(parameters.ToArray(), null)) + using (var reader = resultSetsCommand.GetReader(loaders.ToArray(), parameters.ToArray(), null)) { ArrayList[] hydratedObjects = new ArrayList[loaders.Count]; List<EntityKey[]>[] subselectResultKeys = new List<EntityKey[]>[loaders.Count]; @@ -218,7 +218,7 @@ createSubselects[i] = loader.IsSubselectLoadingEnabled; subselectResultKeys[i] = createSubselects[i] ? new List<EntityKey[]>() : null; int maxRows = Loader.Loader.HasMaxRows(selection) ? selection.MaxRows : int.MaxValue; - if (!dialect.SupportsLimitOffset || !Loader.Loader.UseLimit(selection, dialect)) + if (!dialect.SupportsLimitOffset || !loader.UseLimit(selection, dialect)) { Loader.Loader.Advance(reader, selection); } Modified: trunk/nhibernate/src/NHibernate/Impl/MultiQueryImpl.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Impl/MultiQueryImpl.cs 2011-06-05 20:34:11 UTC (rev 5909) +++ trunk/nhibernate/src/NHibernate/Impl/MultiQueryImpl.cs 2011-06-05 21:24:29 UTC (rev 5910) @@ -504,7 +504,7 @@ try { - using (var reader = resultSetsCommand.GetReader(Parameters.ToArray(), commandTimeout != RowSelection.NoValue ? commandTimeout : (int?)null)) + using (var reader = resultSetsCommand.GetReader(translators.Select(t=> t.Loader).ToArray(), Parameters.ToArray(), commandTimeout != RowSelection.NoValue ? commandTimeout : (int?)null)) { if (log.IsDebugEnabled) { @@ -527,7 +527,7 @@ hydratedObjects[i] = entitySpan > 0 ? new ArrayList() : null; RowSelection selection = parameter.RowSelection; int maxRows = Loader.Loader.HasMaxRows(selection) ? selection.MaxRows : int.MaxValue; - if (!dialect.SupportsLimitOffset || !Loader.Loader.UseLimit(selection, dialect)) + if (!dialect.SupportsLimitOffset || !translator.Loader.UseLimit(selection, dialect)) { Loader.Loader.Advance(reader, selection); } Modified: trunk/nhibernate/src/NHibernate/Loader/Loader.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Loader/Loader.cs 2011-06-05 20:34:11 UTC (rev 5909) +++ trunk/nhibernate/src/NHibernate/Loader/Loader.cs 2011-06-05 21:24:29 UTC (rev 5910) @@ -1093,7 +1093,7 @@ /// <param name="selection"></param> /// <param name="dialect"></param> /// <returns></returns> - internal static bool UseLimit(RowSelection selection, Dialect.Dialect dialect) + internal bool UseLimit(RowSelection selection, Dialect.Dialect dialect) { return dialect.SupportsLimit && (HasMaxRows(selection) || HasOffset(selection)); } @@ -1263,7 +1263,7 @@ /// Bind parameters needed by the dialect-specific LIMIT clause /// </summary> /// <returns>The number of parameters bound</returns> - internal static int BindLimitParameters(IDbCommand st, int index, RowSelection selection, ISessionImplementor session) + internal int BindLimitParameters(IDbCommand st, int index, RowSelection selection, ISessionImplementor session) { Dialect.Dialect dialect = session.Factory.Dialect; if (!dialect.SupportsVariableLimit) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fab...@us...> - 2011-06-05 20:34:19
|
Revision: 5909 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5909&view=rev Author: fabiomaulo Date: 2011-06-05 20:34:11 +0000 (Sun, 05 Jun 2011) Log Message: ----------- Tackable parameters for Criteria (broken some use case with Multi-Criteria) Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Criterion/BetweenExpression.cs trunk/nhibernate/src/NHibernate/Criterion/ConstantProjection.cs trunk/nhibernate/src/NHibernate/Criterion/ICriteriaQuery.cs trunk/nhibernate/src/NHibernate/Criterion/IdentifierEqExpression.cs trunk/nhibernate/src/NHibernate/Criterion/InExpression.cs trunk/nhibernate/src/NHibernate/Criterion/InsensitiveLikeExpression.cs trunk/nhibernate/src/NHibernate/Criterion/LikeExpression.cs trunk/nhibernate/src/NHibernate/Criterion/SQLCriterion.cs trunk/nhibernate/src/NHibernate/Criterion/SimpleExpression.cs trunk/nhibernate/src/NHibernate/Criterion/SimpleSubqueryExpression.cs trunk/nhibernate/src/NHibernate/Criterion/SubqueryExpression.cs trunk/nhibernate/src/NHibernate/Engine/QueryParameters.cs trunk/nhibernate/src/NHibernate/Impl/MultiCriteriaImpl.cs trunk/nhibernate/src/NHibernate/Linq/NhLinqExpression.cs trunk/nhibernate/src/NHibernate/Linq/ParameterAggregator.cs trunk/nhibernate/src/NHibernate/Linq/Visitors/ExpressionKeyVisitor.cs trunk/nhibernate/src/NHibernate/Linq/Visitors/ExpressionParameterVisitor.cs trunk/nhibernate/src/NHibernate/Linq/Visitors/HqlGeneratorExpressionTreeVisitor.cs trunk/nhibernate/src/NHibernate/Linq/Visitors/ResultOperatorProcessors/ProcessCacheable.cs trunk/nhibernate/src/NHibernate/Linq/Visitors/ResultOperatorProcessors/ProcessSkip.cs trunk/nhibernate/src/NHibernate/Linq/Visitors/ResultOperatorProcessors/ProcessTake.cs trunk/nhibernate/src/NHibernate/Linq/Visitors/VisitorParameters.cs trunk/nhibernate/src/NHibernate/Loader/Criteria/CriteriaLoader.cs trunk/nhibernate/src/NHibernate/Loader/Criteria/CriteriaQueryTranslator.cs trunk/nhibernate/src/NHibernate/NHibernate.csproj trunk/nhibernate/src/NHibernate/Param/CriteriaNamedParameterSpecification.cs trunk/nhibernate/src/NHibernate.Test/Criteria/AddNumberProjection.cs trunk/nhibernate/src/NHibernate.Test/Pagination/CustomDialectFixture.cs trunk/nhibernate/src/NHibernate.Test/Pagination/CustomMsSqlDriver.cs trunk/nhibernate/src/NHibernate.Test/ProjectionFixtures/Fixture.cs Added Paths: ----------- trunk/nhibernate/src/NHibernate/Param/NamedParameter.cs Removed Paths: ------------- trunk/nhibernate/src/NHibernate/Linq/NamedParameter.cs Modified: trunk/nhibernate/src/NHibernate/Criterion/BetweenExpression.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Criterion/BetweenExpression.cs 2011-06-04 19:19:12 UTC (rev 5908) +++ trunk/nhibernate/src/NHibernate/Criterion/BetweenExpression.cs 2011-06-05 20:34:11 UTC (rev 5909) @@ -51,9 +51,9 @@ //TODO: add a default capacity SqlStringBuilder sqlBuilder = new SqlStringBuilder(); - IType[] parametersTypes = GetTypedValues(criteria, criteriaQuery).Select(x=> x.Type).ToArray(); - IType lowType = parametersTypes[0]; - IType highType = parametersTypes[1]; + var parametersTypes = GetTypedValues(criteria, criteriaQuery).ToArray(); + var lowType = parametersTypes[0]; + var highType = parametersTypes[1]; SqlString[] columnNames = CriterionUtil.GetColumnNames(_propertyName, _projection, criteriaQuery, criteria, enabledFilters); Modified: trunk/nhibernate/src/NHibernate/Criterion/ConstantProjection.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Criterion/ConstantProjection.cs 2011-06-04 19:19:12 UTC (rev 5908) +++ trunk/nhibernate/src/NHibernate/Criterion/ConstantProjection.cs 2011-06-05 20:34:11 UTC (rev 5909) @@ -14,8 +14,8 @@ public class ConstantProjection : SimpleProjection { private readonly object value; - private readonly IType type; - + private readonly TypedValue typedValue; + public ConstantProjection(object value) : this(value, NHibernateUtil.GuessType(value.GetType())) { } @@ -23,7 +23,7 @@ public ConstantProjection(object value, IType type) { this.value = value; - this.type = type; + typedValue = new TypedValue(type, this.value, EntityMode.Poco); } public override bool IsAggregate @@ -44,7 +44,7 @@ public override SqlString ToSqlString(ICriteria criteria, int position, ICriteriaQuery criteriaQuery, IDictionary<string, IFilter> enabledFilters) { return new SqlStringBuilder() - .Add(criteriaQuery.NewQueryParameter(type).Single()) + .Add(criteriaQuery.NewQueryParameter(typedValue).Single()) .Add(" as ") .Add(GetColumnAliases(position)[0]) .ToSqlString(); @@ -52,12 +52,12 @@ public override IType[] GetTypes(ICriteria criteria, ICriteriaQuery criteriaQuery) { - return new IType[] { type }; + return new IType[] { typedValue.Type }; } public override TypedValue[] GetTypedValues(ICriteria criteria, ICriteriaQuery criteriaQuery) { - return new TypedValue[] { new TypedValue(type, value, EntityMode.Poco) }; + return new TypedValue[] { typedValue }; } } } Modified: trunk/nhibernate/src/NHibernate/Criterion/ICriteriaQuery.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Criterion/ICriteriaQuery.cs 2011-06-04 19:19:12 UTC (rev 5908) +++ trunk/nhibernate/src/NHibernate/Criterion/ICriteriaQuery.cs 2011-06-05 20:34:11 UTC (rev 5909) @@ -1,5 +1,6 @@ using System.Collections.Generic; using NHibernate.Engine; +using NHibernate.Param; using NHibernate.SqlCommand; using NHibernate.Type; @@ -71,14 +72,12 @@ /// <summary> /// Create a new query parameter to use in a <see cref="ICriterion"/> /// </summary> - /// <param name="parameterType">The expected type of the parameter.</param> + /// <param name="parameter">The value and the <see cref="IType"/> of the parameter.</param> /// <returns>A new instance of a query parameter to be added to a <see cref="SqlString"/>.</returns> - IEnumerable<Parameter> NewQueryParameter(IType parameterType); - - /// <summary> - /// Creates a dummy parameter index for the supplied paged value. - /// Returns null if the Dialect does not support limit parameters - /// </summary> - int? CreatePagingParameter(int value); + IEnumerable<Parameter> NewQueryParameter(TypedValue parameter); + ICollection<IParameterSpecification> CollectedParameterSpecifications { get; } + ICollection<NamedParameter> CollectedParameters { get; } + Parameter CreateSkipParameter(int value); + Parameter CreateTakeParameter(int value); } } \ No newline at end of file Modified: trunk/nhibernate/src/NHibernate/Criterion/IdentifierEqExpression.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Criterion/IdentifierEqExpression.cs 2011-06-04 19:19:12 UTC (rev 5908) +++ trunk/nhibernate/src/NHibernate/Criterion/IdentifierEqExpression.cs 2011-06-05 20:34:11 UTC (rev 5909) @@ -34,7 +34,7 @@ { //Implementation changed from H3.2 to use SqlString string[] columns = criteriaQuery.GetIdentifierColumns(criteria); - Parameter[] parameters = GetTypedValues(criteria, criteriaQuery).Select(x => x.Type).SelectMany(t => criteriaQuery.NewQueryParameter(t)).ToArray(); + Parameter[] parameters = GetTypedValues(criteria, criteriaQuery).SelectMany(t => criteriaQuery.NewQueryParameter(t)).ToArray(); SqlStringBuilder result = new SqlStringBuilder(4 * columns.Length + 2); if (columns.Length > 1) Modified: trunk/nhibernate/src/NHibernate/Criterion/InExpression.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Criterion/InExpression.cs 2011-06-04 19:19:12 UTC (rev 5908) +++ trunk/nhibernate/src/NHibernate/Criterion/InExpression.cs 2011-06-05 20:34:11 UTC (rev 5909) @@ -69,7 +69,7 @@ // Generate SqlString of the form: // columnName1 in (values) and columnName2 in (values) and ... - Parameter[] parameters = GetTypedValues(criteria, criteriaQuery).Select(x => x.Type).SelectMany(t => criteriaQuery.NewQueryParameter(t)).ToArray(); + Parameter[] parameters = GetTypedValues(criteria, criteriaQuery).SelectMany(t => criteriaQuery.NewQueryParameter(t)).ToArray(); for (int columnIndex = 0; columnIndex < columnNames.Length; columnIndex++) { Modified: trunk/nhibernate/src/NHibernate/Criterion/InsensitiveLikeExpression.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Criterion/InsensitiveLikeExpression.cs 2011-06-04 19:19:12 UTC (rev 5908) +++ trunk/nhibernate/src/NHibernate/Criterion/InsensitiveLikeExpression.cs 2011-06-05 20:34:11 UTC (rev 5909) @@ -85,7 +85,7 @@ .Add(" like "); } - sqlBuilder.Add(criteriaQuery.NewQueryParameter(NHibernateUtil.String).Single()); + sqlBuilder.Add(criteriaQuery.NewQueryParameter(GetParameterTypedValue(criteria, criteriaQuery)).Single()); return sqlBuilder.ToSqlString(); } @@ -93,18 +93,26 @@ public override TypedValue[] GetTypedValues(ICriteria criteria, ICriteriaQuery criteriaQuery) { List<TypedValue> typedValues = new List<TypedValue>(); - + if (projection != null) { typedValues.AddRange(projection.GetTypedValues(criteria, criteriaQuery)); - typedValues.AddRange(CriterionUtil.GetTypedValues(criteriaQuery, criteria, projection, null, value.ToString().ToLower())); } - else - typedValues.Add(criteriaQuery.GetTypedValue(criteria, propertyName, value.ToString().ToLower())); + typedValues.Add(GetParameterTypedValue(criteria, criteriaQuery)); return typedValues.ToArray(); } + public TypedValue GetParameterTypedValue(ICriteria criteria, ICriteriaQuery criteriaQuery) + { + var matchValue = value.ToString().ToLower(); + if (projection != null) + { + return CriterionUtil.GetTypedValues(criteriaQuery, criteria, projection, null, matchValue).Single(); + } + return criteriaQuery.GetTypedValue(criteria, propertyName, matchValue); + } + public override IProjection[] GetProjections() { if (projection != null) Modified: trunk/nhibernate/src/NHibernate/Criterion/LikeExpression.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Criterion/LikeExpression.cs 2011-06-04 19:19:12 UTC (rev 5908) +++ trunk/nhibernate/src/NHibernate/Criterion/LikeExpression.cs 2011-06-05 20:34:11 UTC (rev 5909) @@ -22,11 +22,14 @@ private char? escapeChar; private readonly bool ignoreCase; private readonly IProjection projection; + private readonly TypedValue typedValue; public LikeExpression(string propertyName, string value, char? escapeChar, bool ignoreCase) { this.projection = Projections.Property(propertyName); this.value = value; + typedValue = new TypedValue(NHibernateUtil.String, this.value, EntityMode.Poco); + this.escapeChar = escapeChar; this.ignoreCase = ignoreCase; } @@ -35,6 +38,7 @@ { this.projection = projection; this.value = matchMode.ToMatchString(value); + typedValue = new TypedValue(NHibernateUtil.String, this.value, EntityMode.Poco); } @@ -80,11 +84,11 @@ lhs.Add(" like ") .Add(dialect.LowercaseFunction) .Add(StringHelper.OpenParen) - .Add(criteriaQuery.NewQueryParameter(NHibernateUtil.String).Single()) + .Add(criteriaQuery.NewQueryParameter(typedValue).Single()) .Add(StringHelper.ClosedParen); } else - lhs.Add(" like ").Add(criteriaQuery.NewQueryParameter(NHibernateUtil.String).Single()); + lhs.Add(" like ").Add(criteriaQuery.NewQueryParameter(typedValue).Single()); if (escapeChar.HasValue) lhs.Add(" escape '" + escapeChar + "'"); @@ -94,7 +98,7 @@ public override TypedValue[] GetTypedValues(ICriteria criteria, ICriteriaQuery criteriaQuery) { - return new TypedValue[] { new TypedValue(NHibernateUtil.String, value, EntityMode.Poco) }; + return new TypedValue[] { typedValue }; } public override IProjection[] GetProjections() Modified: trunk/nhibernate/src/NHibernate/Criterion/SQLCriterion.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Criterion/SQLCriterion.cs 2011-06-04 19:19:12 UTC (rev 5908) +++ trunk/nhibernate/src/NHibernate/Criterion/SQLCriterion.cs 2011-06-05 20:34:11 UTC (rev 5909) @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; using NHibernate.Engine; using NHibernate.SqlCommand; using NHibernate.Type; @@ -32,6 +33,16 @@ public override SqlString ToSqlString(ICriteria criteria, ICriteriaQuery criteriaQuery, IDictionary<string, IFilter> enabledFilters) { + var parameters = _sql.GetParameters().ToList(); + var paramPos = 0; + for (int i = 0; i < _typedValues.Length; i++) + { + var controlledParameters = criteriaQuery.NewQueryParameter(_typedValues[i]); + foreach (Parameter parameter in controlledParameters) + { + parameters[paramPos++].BackTrack = parameter.BackTrack; + } + } return _sql.Replace("{alias}", criteriaQuery.GetSQLAlias(criteria)); } Modified: trunk/nhibernate/src/NHibernate/Criterion/SimpleExpression.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Criterion/SimpleExpression.cs 2011-06-04 19:19:12 UTC (rev 5908) +++ trunk/nhibernate/src/NHibernate/Criterion/SimpleExpression.cs 2011-06-05 20:34:11 UTC (rev 5909) @@ -88,7 +88,7 @@ this, value); - Parameter[] parameters = GetTypedValues(criteria, criteriaQuery).Select(x => x.Type).SelectMany(t => criteriaQuery.NewQueryParameter(t)).ToArray(); + Parameter[] parameters = criteriaQuery.NewQueryParameter(GetParameterTypedValue(criteria, criteriaQuery)).ToArray(); if (ignoreCase) { @@ -105,7 +105,7 @@ .Add(columnNames[0]) .Add(StringHelper.ClosedParen) .Add(Op) - .Add(parameters.FirstOrDefault()) + .Add(parameters.Single()) .ToSqlString(); } else @@ -129,20 +129,27 @@ public override TypedValue[] GetTypedValues(ICriteria criteria, ICriteriaQuery criteriaQuery) { - List<TypedValue> typedValues = new List<TypedValue>(); - object icvalue = ignoreCase ? value.ToString().ToLower() : value; + var typedValues = new List<TypedValue>(); if (_projection != null) { typedValues.AddRange(_projection.GetTypedValues(criteria, criteriaQuery)); - typedValues.AddRange(CriterionUtil.GetTypedValues(criteriaQuery, criteria, _projection, null, icvalue)); } - else - typedValues.Add(criteriaQuery.GetTypedValue(criteria, propertyName, icvalue)); + typedValues.Add(GetParameterTypedValue(criteria, criteriaQuery)); return typedValues.ToArray(); } + public TypedValue GetParameterTypedValue(ICriteria criteria, ICriteriaQuery criteriaQuery) + { + object icvalue = ignoreCase ? value.ToString().ToLower() : value; + if (_projection != null) + { + return CriterionUtil.GetTypedValues(criteriaQuery, criteria, _projection, null, icvalue).Single(); + } + return criteriaQuery.GetTypedValue(criteria, propertyName, icvalue); + } + public override IProjection[] GetProjections() { if (_projection != null) Modified: trunk/nhibernate/src/NHibernate/Criterion/SimpleSubqueryExpression.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Criterion/SimpleSubqueryExpression.cs 2011-06-04 19:19:12 UTC (rev 5908) +++ trunk/nhibernate/src/NHibernate/Criterion/SimpleSubqueryExpression.cs 2011-06-05 20:34:11 UTC (rev 5909) @@ -1,4 +1,6 @@ using System; +using System.Collections.Generic; +using System.Linq; using NHibernate.Engine; using NHibernate.SqlCommand; @@ -23,13 +25,18 @@ TypedValue[] superTv = base.GetTypedValues(criteria, criteriaQuery); TypedValue[] result = new TypedValue[superTv.Length + 1]; superTv.CopyTo(result, 1); - result[0] = new TypedValue(GetTypes()[0], value, EntityMode.Poco); + result[0] = FirstTypedValue(); return result; } + private TypedValue FirstTypedValue() + { + return new TypedValue(GetTypes()[0], value, EntityMode.Poco); + } + protected override SqlString ToLeftSqlString(ICriteria criteria, ICriteriaQuery criteriaQuery) { - return SqlString.Parameter; + return new SqlString(criteriaQuery.NewQueryParameter(FirstTypedValue()).First()); } } } Modified: trunk/nhibernate/src/NHibernate/Criterion/SubqueryExpression.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Criterion/SubqueryExpression.cs 2011-06-04 19:19:12 UTC (rev 5908) +++ trunk/nhibernate/src/NHibernate/Criterion/SubqueryExpression.cs 2011-06-05 20:34:11 UTC (rev 5909) @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; using NHibernate.Engine; using NHibernate.Impl; using NHibernate.Loader.Criteria; @@ -54,27 +55,30 @@ IOuterJoinLoadable persister = (IOuterJoinLoadable)factory.GetEntityPersister(criteriaImpl.EntityOrClassName); - //buffer needs to be before CriteriaJoinWalker for sake of parameter order - SqlStringBuilder buf = new SqlStringBuilder().Add(ToLeftSqlString(criteria, criteriaQuery)); - //patch to generate joins on subqueries //stolen from CriteriaLoader CriteriaJoinWalker walker = new CriteriaJoinWalker(persister, innerQuery, factory, criteriaImpl, criteriaImpl.EntityOrClassName, enabledFilters); + parameters = innerQuery.GetQueryParameters(); // parameters can be inferred only after initialize the walker + SqlString sql = walker.SqlString; if (criteriaImpl.FirstResult != 0 || criteriaImpl.MaxResults != RowSelection.NoValue) { - int? offset = Loader.Loader.GetOffsetUsingDialect(parameters.RowSelection, factory.Dialect); - int? limit = Loader.Loader.GetLimitUsingDialect(parameters.RowSelection, factory.Dialect); - int? offsetParameterIndex = offset.HasValue ? criteriaQuery.CreatePagingParameter(offset.Value) : null; - int? limitParameterIndex = limit.HasValue ? criteriaQuery.CreatePagingParameter(limit.Value) : null; - Parameter offsetParameter = offsetParameterIndex.HasValue ? Parameter.WithIndex(offsetParameterIndex.Value) : null; - Parameter limitParameter = limitParameterIndex.HasValue ? Parameter.WithIndex(limitParameterIndex.Value) : null; - sql = factory.Dialect.GetLimitString(sql, offset, limit, offsetParameter, limitParameter); + int? offset = Loader.Loader.GetOffsetUsingDialect(parameters.RowSelection, factory.Dialect); + int? limit = Loader.Loader.GetLimitUsingDialect(parameters.RowSelection, factory.Dialect); + Parameter offsetParameter = offset.HasValue ? innerQuery.CreateSkipParameter(offset.Value) : null; + Parameter limitParameter = limit.HasValue ? innerQuery.CreateTakeParameter(limit.Value) : null; + sql = factory.Dialect.GetLimitString(sql, offset, limit, offsetParameter, limitParameter); } + // during CriteriaImpl.Clone we are doing a shallow copy of each criterion. + // this is not a problem for common criterion but not for SubqueryExpression because here we are holding the state of inner CriteriaTraslator (ICriteriaQuery). + // After execution (ToSqlString) we have to clean the internal state because the next execution may be performed in a different tree reusing the same istance of SubqueryExpression. + innerQuery = null; + + SqlStringBuilder buf = new SqlStringBuilder().Add(ToLeftSqlString(criteria, criteriaQuery)); if (op != null) { buf.Add(" ").Add(op).Add(" "); @@ -105,15 +109,7 @@ public override TypedValue[] GetTypedValues(ICriteria criteria, ICriteriaQuery criteriaQuery) { - InitializeInnerQueryAndParameters(criteriaQuery); - IType[] paramTypes = parameters.PositionalParameterTypes; - Object[] values = parameters.PositionalParameterValues; - TypedValue[] tv = new TypedValue[paramTypes.Length]; - for (int i = 0; i < paramTypes.Length; i++) - { - tv[i] = new TypedValue(paramTypes[i], values[i], EntityMode.Poco); - } - return tv; + return parameters.NamedParameters.Values.ToArray(); } public override IProjection[] GetProjections() @@ -126,24 +122,15 @@ if (innerQuery == null) { ISessionFactoryImplementor factory = criteriaQuery.Factory; - - innerQuery = - new CriteriaQueryTranslator( - factory, - criteriaImpl, //implicit polymorphism not supported (would need a union) - criteriaImpl.EntityOrClassName, - criteriaQuery.GenerateSQLAlias(), - criteriaQuery); - - if (innerQuery.HasProjection) - { - parameters = innerQuery.GetQueryParameters(); - types = innerQuery.ProjectedTypes; - } - else - { - types = null; - } + + innerQuery = new CriteriaQueryTranslator( + factory, + criteriaImpl, //implicit polymorphism not supported (would need a union) + criteriaImpl.EntityOrClassName, + criteriaQuery.GenerateSQLAlias(), + criteriaQuery); + + types = innerQuery.HasProjection ? innerQuery.ProjectedTypes : null; } } Modified: trunk/nhibernate/src/NHibernate/Engine/QueryParameters.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Engine/QueryParameters.cs 2011-06-04 19:19:12 UTC (rev 5908) +++ trunk/nhibernate/src/NHibernate/Engine/QueryParameters.cs 2011-06-05 20:34:11 UTC (rev 5909) @@ -78,6 +78,12 @@ _tempPagingParameterIndexes = tempPagingParameterIndexes; } + public QueryParameters(IType[] positionalParameterTypes, object[] positionalParameterValues, IDictionary<string, TypedValue> namedParameters, IDictionary<string, LockMode> lockModes, RowSelection rowSelection, bool isReadOnlyInitialized, bool readOnly, bool cacheable, string cacheRegion, string comment, bool isLookupByNaturalKey, IResultTransformer transformer) + : this(positionalParameterTypes, positionalParameterValues, namedParameters, lockModes, rowSelection, isReadOnlyInitialized, readOnly, cacheable, cacheRegion, comment, null, transformer) + { + NaturalKeyLookup = isLookupByNaturalKey; + } + public QueryParameters(IType[] positionalParameterTypes, object[] positionalParameterValues, IDictionary<string, TypedValue> namedParameters, IDictionary<string, LockMode> lockModes, RowSelection rowSelection, bool isReadOnlyInitialized, bool readOnly, bool cacheable, string cacheRegion, string comment, object[] collectionKeys, IResultTransformer transformer) { _positionalParameterTypes = positionalParameterTypes; Modified: trunk/nhibernate/src/NHibernate/Impl/MultiCriteriaImpl.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Impl/MultiCriteriaImpl.cs 2011-06-04 19:19:12 UTC (rev 5908) +++ trunk/nhibernate/src/NHibernate/Impl/MultiCriteriaImpl.cs 2011-06-05 20:34:11 UTC (rev 5909) @@ -436,10 +436,14 @@ combinedQueryParameters.NamedParameters = new Dictionary<string, TypedValue>(); ArrayList positionalParameterTypes = new ArrayList(); ArrayList positionalParameterValues = new ArrayList(); + int index = 0; foreach (QueryParameters queryParameters in parameters) { - // There aren't any named params in criteria queries - //CopyNamedParametersDictionary(combinedQueryParameters.NamedParameters, queryParameters.NamedParameters); + foreach (KeyValuePair<string, TypedValue> dictionaryEntry in queryParameters.NamedParameters) + { + combinedQueryParameters.NamedParameters.Add(dictionaryEntry.Key + index, dictionaryEntry.Value); + } + index += 1; positionalParameterTypes.AddRange(queryParameters.PositionalParameterTypes); positionalParameterValues.AddRange(queryParameters.PositionalParameterValues); } Deleted: trunk/nhibernate/src/NHibernate/Linq/NamedParameter.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Linq/NamedParameter.cs 2011-06-04 19:19:12 UTC (rev 5908) +++ trunk/nhibernate/src/NHibernate/Linq/NamedParameter.cs 2011-06-05 20:34:11 UTC (rev 5909) @@ -1,19 +0,0 @@ -using System; -using NHibernate.Type; - -namespace NHibernate.Linq -{ - public class NamedParameter - { - public NamedParameter(string name, object value, IType type) - { - Name = name; - Value = value; - Type = type; - } - - public string Name { get; private set; } - public object Value { get; internal set; } - public IType Type { get; internal set; } - } -} \ No newline at end of file Modified: trunk/nhibernate/src/NHibernate/Linq/NhLinqExpression.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Linq/NhLinqExpression.cs 2011-06-04 19:19:12 UTC (rev 5908) +++ trunk/nhibernate/src/NHibernate/Linq/NhLinqExpression.cs 2011-06-05 20:34:11 UTC (rev 5909) @@ -5,6 +5,7 @@ using NHibernate.Engine.Query; using NHibernate.Hql.Ast.ANTLR.Tree; using NHibernate.Linq.Visitors; +using NHibernate.Param; using NHibernate.Type; using Remotion.Linq.Parsing.ExpressionTreeVisitors; Modified: trunk/nhibernate/src/NHibernate/Linq/ParameterAggregator.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Linq/ParameterAggregator.cs 2011-06-04 19:19:12 UTC (rev 5908) +++ trunk/nhibernate/src/NHibernate/Linq/ParameterAggregator.cs 2011-06-05 20:34:11 UTC (rev 5909) @@ -1,4 +1,5 @@ using System.Collections.Generic; +using NHibernate.Param; using NHibernate.Type; namespace NHibernate.Linq Modified: trunk/nhibernate/src/NHibernate/Linq/Visitors/ExpressionKeyVisitor.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Linq/Visitors/ExpressionKeyVisitor.cs 2011-06-04 19:19:12 UTC (rev 5908) +++ trunk/nhibernate/src/NHibernate/Linq/Visitors/ExpressionKeyVisitor.cs 2011-06-05 20:34:11 UTC (rev 5909) @@ -4,6 +4,7 @@ using System.Linq.Expressions; using System.Reflection; using System.Text; +using NHibernate.Param; namespace NHibernate.Linq.Visitors { Modified: trunk/nhibernate/src/NHibernate/Linq/Visitors/ExpressionParameterVisitor.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Linq/Visitors/ExpressionParameterVisitor.cs 2011-06-04 19:19:12 UTC (rev 5908) +++ trunk/nhibernate/src/NHibernate/Linq/Visitors/ExpressionParameterVisitor.cs 2011-06-05 20:34:11 UTC (rev 5909) @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; +using NHibernate.Param; using NHibernate.Type; namespace NHibernate.Linq.Visitors Modified: trunk/nhibernate/src/NHibernate/Linq/Visitors/HqlGeneratorExpressionTreeVisitor.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Linq/Visitors/HqlGeneratorExpressionTreeVisitor.cs 2011-06-04 19:19:12 UTC (rev 5908) +++ trunk/nhibernate/src/NHibernate/Linq/Visitors/HqlGeneratorExpressionTreeVisitor.cs 2011-06-05 20:34:11 UTC (rev 5909) @@ -4,6 +4,7 @@ using NHibernate.Hql.Ast; using NHibernate.Linq.Expressions; using NHibernate.Linq.Functions; +using NHibernate.Param; using Remotion.Linq.Clauses.Expressions; namespace NHibernate.Linq.Visitors Modified: trunk/nhibernate/src/NHibernate/Linq/Visitors/ResultOperatorProcessors/ProcessCacheable.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Linq/Visitors/ResultOperatorProcessors/ProcessCacheable.cs 2011-06-04 19:19:12 UTC (rev 5908) +++ trunk/nhibernate/src/NHibernate/Linq/Visitors/ResultOperatorProcessors/ProcessCacheable.cs 2011-06-05 20:34:11 UTC (rev 5909) @@ -1,4 +1,6 @@ -namespace NHibernate.Linq.Visitors.ResultOperatorProcessors +using NHibernate.Param; + +namespace NHibernate.Linq.Visitors.ResultOperatorProcessors { public class ProcessCacheable : IResultOperatorProcessor<CacheableResultOperator> { Modified: trunk/nhibernate/src/NHibernate/Linq/Visitors/ResultOperatorProcessors/ProcessSkip.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Linq/Visitors/ResultOperatorProcessors/ProcessSkip.cs 2011-06-04 19:19:12 UTC (rev 5908) +++ trunk/nhibernate/src/NHibernate/Linq/Visitors/ResultOperatorProcessors/ProcessSkip.cs 2011-06-05 20:34:11 UTC (rev 5909) @@ -1,5 +1,6 @@ using System.Linq.Expressions; using NHibernate.Engine.Query; +using NHibernate.Param; using Remotion.Linq.Clauses.ResultOperators; namespace NHibernate.Linq.Visitors.ResultOperatorProcessors Modified: trunk/nhibernate/src/NHibernate/Linq/Visitors/ResultOperatorProcessors/ProcessTake.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Linq/Visitors/ResultOperatorProcessors/ProcessTake.cs 2011-06-04 19:19:12 UTC (rev 5908) +++ trunk/nhibernate/src/NHibernate/Linq/Visitors/ResultOperatorProcessors/ProcessTake.cs 2011-06-05 20:34:11 UTC (rev 5909) @@ -1,5 +1,6 @@ using System.Linq.Expressions; using NHibernate.Engine.Query; +using NHibernate.Param; using Remotion.Linq.Clauses.ResultOperators; namespace NHibernate.Linq.Visitors.ResultOperatorProcessors Modified: trunk/nhibernate/src/NHibernate/Linq/Visitors/VisitorParameters.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Linq/Visitors/VisitorParameters.cs 2011-06-04 19:19:12 UTC (rev 5908) +++ trunk/nhibernate/src/NHibernate/Linq/Visitors/VisitorParameters.cs 2011-06-05 20:34:11 UTC (rev 5909) @@ -2,6 +2,7 @@ using System.Linq.Expressions; using NHibernate.Engine; using NHibernate.Engine.Query; +using NHibernate.Param; namespace NHibernate.Linq.Visitors { Modified: trunk/nhibernate/src/NHibernate/Loader/Criteria/CriteriaLoader.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Loader/Criteria/CriteriaLoader.cs 2011-06-04 19:19:12 UTC (rev 5908) +++ trunk/nhibernate/src/NHibernate/Loader/Criteria/CriteriaLoader.cs 2011-06-05 20:34:11 UTC (rev 5909) @@ -1,12 +1,16 @@ +using System; using System.Collections; using System.Collections.Generic; using System.Data; +using System.Linq; using Iesi.Collections.Generic; -using NHibernate.Criterion; using NHibernate.Engine; +using NHibernate.Hql.Classic; using NHibernate.Impl; +using NHibernate.Param; using NHibernate.Persister.Entity; using NHibernate.SqlCommand; +using NHibernate.SqlTypes; using NHibernate.Transform; using NHibernate.Type; using NHibernate.Util; @@ -180,5 +184,237 @@ } return customResultTransformer.TransformList(results); } + + /// <summary> + /// Obtain an <c>IDbCommand</c> with all parameters pre-bound. Bind positional parameters, + /// named parameters, and limit parameters. + /// </summary> + /// <remarks> + /// Creates an IDbCommand object and populates it with the values necessary to execute it against the + /// database to Load an Entity. + /// </remarks> + /// <param name="queryParameters">The <see cref="QueryParameters"/> to use for the IDbCommand.</param> + /// <param name="scroll">TODO: find out where this is used...</param> + /// <param name="session">The SessionImpl this Command is being prepared in.</param> + /// <returns>A CommandWrapper wrapping an IDbCommand that is ready to be executed.</returns> + protected internal override IDbCommand PrepareQueryCommand(QueryParameters queryParameters, bool scroll, ISessionImplementor session) + { + // NH: In this Loader we can know better all parameters used so we can simplify the IDbCommand construction + // NH: would be very useful if we can do the same with Criteria. This method works just for HQL and LINQ. + + // A distinct-copy of parameter specifications collected during query construction + var parameterSpecs = new HashSet<IParameterSpecification>(translator.CollectedParameterSpecifications); + SqlString sqlString = SqlString.Copy(); + + // dynamic-filter parameters: during the HQL->SQL parsing, filters can be added as SQL_TOKEN/string and the SqlGenerator will not find it + sqlString = ExpandDynamicFilterParameters(sqlString, parameterSpecs, session); + AdjustQueryParametersForSubSelectFetching(sqlString, parameterSpecs, session, queryParameters); // NOTE: see TODO below + + sqlString = AddLimitsParametersIfNeeded(sqlString, parameterSpecs, queryParameters, session); + // TODO: for sub-select fetching we have to try to assign the QueryParameter.ProcessedSQL here (with limits) but only after use IParameterSpecification for any kind of queries + + // The PreprocessSQL method can modify the SqlString but should never add parameters (or we have to override it) + sqlString = PreprocessSQL(sqlString, queryParameters, session.Factory.Dialect); + + // After the last modification to the SqlString we can collect all parameters. + var sqlQueryParametersList = sqlString.GetParameters().ToList(); + SqlType[] parameterTypes = parameterSpecs.GetQueryParameterTypes(sqlQueryParametersList, session.Factory); + + parameterSpecs.SetQueryParameterLocations(sqlQueryParametersList, session.Factory); + + IDbCommand command = session.Batcher.PrepareQueryCommand(CommandType.Text, sqlString, parameterTypes); + + try + { + RowSelection selection = queryParameters.RowSelection; + if (selection != null && selection.Timeout != RowSelection.NoValue) + { + command.CommandTimeout = selection.Timeout; + } + + BindParametersValues(command, sqlQueryParametersList, parameterSpecs, queryParameters, session); + + session.Batcher.ExpandQueryParameters(command, sqlString); + } + catch (HibernateException) + { + session.Batcher.CloseCommand(command, null); + throw; + } + catch (Exception sqle) + { + session.Batcher.CloseCommand(command, null); + ADOExceptionReporter.LogExceptions(sqle); + throw; + } + return command; + } + + public override int[] GetNamedParameterLocs(string name) + { + return new int[0]; + } + + private void AdjustQueryParametersForSubSelectFetching(SqlString sqlString, IEnumerable<IParameterSpecification> parameterSpecs, ISessionImplementor session, QueryParameters queryParameters) + { + // TODO: Remove this when all parameters are managed using IParameterSpecification (QueryParameters does not need to have decomposed values for filters) + + var dynamicFilterParameterSpecifications = parameterSpecs.OfType<DynamicFilterParameterSpecification>().ToList(); + var filteredParameterValues = new List<object>(); + var filteredParameterTypes = new List<IType>(); + var filteredParameterLocations = new List<int>(); + + if (dynamicFilterParameterSpecifications.Count != 0) + { + var sqlQueryParametersList = sqlString.GetParameters().ToList(); + foreach (DynamicFilterParameterSpecification specification in dynamicFilterParameterSpecifications) + { + string backTrackId = specification.GetIdsForBackTrack(session.Factory).First(); + object value = session.GetFilterParameterValue(specification.FilterParameterFullName); + var elementType = specification.ExpectedType; + foreach (int position in sqlQueryParametersList.GetEffectiveParameterLocations(backTrackId)) + { + filteredParameterValues.Add(value); + filteredParameterTypes.Add(elementType); + filteredParameterLocations.Add(position); + } + } + } + + queryParameters.ProcessedSql = sqlString; + queryParameters.FilteredParameterLocations = filteredParameterLocations; + queryParameters.FilteredParameterTypes = filteredParameterTypes; + queryParameters.FilteredParameterValues = filteredParameterValues; + } + + private SqlString ExpandDynamicFilterParameters(SqlString sqlString, ICollection<IParameterSpecification> parameterSpecs, ISessionImplementor session) + { + var enabledFilters = session.EnabledFilters; + if (enabledFilters.Count == 0 || sqlString.ToString().IndexOf(ParserHelper.HqlVariablePrefix) < 0) + { + return sqlString; + } + + Dialect.Dialect dialect = session.Factory.Dialect; + string symbols = ParserHelper.HqlSeparators + dialect.OpenQuote + dialect.CloseQuote; + + var originSql = sqlString.Compact(); + var result = new SqlStringBuilder(); + foreach (var sqlPart in originSql.Parts) + { + var parameter = sqlPart as Parameter; + if (parameter != null) + { + result.Add(parameter); + continue; + } + + var sqlFragment = sqlPart.ToString(); + var tokens = new StringTokenizer(sqlFragment, symbols, true); + + foreach (string token in tokens) + { + if (token.StartsWith(ParserHelper.HqlVariablePrefix)) + { + string filterParameterName = token.Substring(1); + string[] parts = StringHelper.ParseFilterParameterName(filterParameterName); + string filterName = parts[0]; + string parameterName = parts[1]; + var filter = (FilterImpl)enabledFilters[filterName]; + + object value = filter.GetParameter(parameterName); + IType type = filter.FilterDefinition.GetParameterType(parameterName); + int parameterColumnSpan = type.GetColumnSpan(session.Factory); + var collectionValue = value as ICollection; + int? collectionSpan = null; + + // Add query chunk + string typeBindFragment = string.Join(", ", Enumerable.Repeat("?", parameterColumnSpan).ToArray()); + string bindFragment; + if (collectionValue != null && !type.ReturnedClass.IsArray) + { + collectionSpan = collectionValue.Count; + bindFragment = string.Join(", ", Enumerable.Repeat(typeBindFragment, collectionValue.Count).ToArray()); + } + else + { + bindFragment = typeBindFragment; + } + + // dynamic-filter parameter tracking + var filterParameterFragment = SqlString.Parse(bindFragment); + var dynamicFilterParameterSpecification = new DynamicFilterParameterSpecification(filterName, parameterName, type, collectionSpan); + var parameters = filterParameterFragment.GetParameters().ToArray(); + var sqlParameterPos = 0; + var paramTrackers = dynamicFilterParameterSpecification.GetIdsForBackTrack(session.Factory); + foreach (var paramTracker in paramTrackers) + { + parameters[sqlParameterPos++].BackTrack = paramTracker; + } + + parameterSpecs.Add(dynamicFilterParameterSpecification); + result.Add(filterParameterFragment); + } + else + { + result.Add(token); + } + } + } + return result.ToSqlString().Compact(); + } + + private SqlString AddLimitsParametersIfNeeded(SqlString sqlString, ICollection<IParameterSpecification> parameterSpecs, QueryParameters queryParameters, ISessionImplementor session) + { + var sessionFactory = session.Factory; + Dialect.Dialect dialect = sessionFactory.Dialect; + + RowSelection selection = queryParameters.RowSelection; + bool useLimit = UseLimit(selection, dialect); + if (useLimit) + { + bool hasFirstRow = GetFirstRow(selection) > 0; + bool useOffset = hasFirstRow && dialect.SupportsLimitOffset; + int max = GetMaxOrLimit(dialect, selection); + int? skip = useOffset ? (int?)dialect.GetOffsetValue(GetFirstRow(selection)) : null; + int? take = max != int.MaxValue ? (int?)max : null; + + Parameter skipSqlParameter = null; + Parameter takeSqlParameter = null; + if (skip.HasValue) + { + var skipParameter = new QuerySkipParameterSpecification(); + skipSqlParameter = Parameter.Placeholder; + skipSqlParameter.BackTrack = skipParameter.GetIdsForBackTrack(sessionFactory).First(); + parameterSpecs.Add(skipParameter); + } + if (take.HasValue) + { + var takeParameter = new QueryTakeParameterSpecification(); + takeSqlParameter = Parameter.Placeholder; + takeSqlParameter.BackTrack = takeParameter.GetIdsForBackTrack(sessionFactory).First(); + parameterSpecs.Add(takeParameter); + } + // The dialect can move the given parameters where he need, what it can't do is generates new parameters loosing the BackTrack. + return dialect.GetLimitString(sqlString, skip, take, skipSqlParameter, takeSqlParameter); + } + return sqlString; + } + + /// <summary> + /// Bind all parameters values. + /// </summary> + /// <param name="command">The command where bind each value.</param> + /// <param name="sqlQueryParametersList">The list of Sql query parameter in the exact sequence they are present in the query.</param> + /// <param name="parameterSpecs">All parameter-specifications collected during query construction.</param> + /// <param name="queryParameters">The encapsulation of the parameter values to be bound.</param> + /// <param name="session">The session from where execute the query.</param> + private void BindParametersValues(IDbCommand command, IList<Parameter> sqlQueryParametersList, IEnumerable<IParameterSpecification> parameterSpecs, QueryParameters queryParameters, ISessionImplementor session) + { + foreach (var parameterSpecification in parameterSpecs) + { + parameterSpecification.Bind(command, sqlQueryParametersList, queryParameters, session); + } + } } } \ No newline at end of file Modified: trunk/nhibernate/src/NHibernate/Loader/Criteria/CriteriaQueryTranslator.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Loader/Criteria/CriteriaQueryTranslator.cs 2011-06-04 19:19:12 UTC (rev 5908) +++ trunk/nhibernate/src/NHibernate/Loader/Criteria/CriteriaQueryTranslator.cs 2011-06-05 20:34:11 UTC (rev 5909) @@ -1,8 +1,6 @@ using System; -using System.Collections; using System.Collections.Generic; using System.Linq; -using System.Text; using Iesi.Collections.Generic; using NHibernate.Criterion; using NHibernate.Engine; @@ -23,15 +21,12 @@ private static readonly IInternalLogger logger = LoggerProvider.LoggerFor(typeof(CriteriaQueryTranslator)); private const int AliasCount = 0; - private readonly string queryTranslatorId = Guid.NewGuid().ToString("N"); private readonly ICriteriaQuery outerQueryTranslator; private readonly CriteriaImpl rootCriteria; private readonly string rootEntityName; private readonly string rootSQLAlias; - private int indexForAlias = 0; - private int _tempPagingParameterIndex = -1; - private IDictionary<int, int> _tempPagingParameterIndexes = new Dictionary<int, int>(); + private int indexForAlias = 0; private readonly IDictionary<ICriteria, ICriteriaInfoProvider> criteriaInfoMap = new Dictionary<ICriteria, ICriteriaInfoProvider>(); @@ -45,15 +40,19 @@ private readonly IDictionary<string, ICriteria> associationPathCriteriaMap = new LinkedHashMap<string, ICriteria>(); private readonly IDictionary<string, JoinType> associationPathJoinTypesMap = new LinkedHashMap<string, JoinType>(); private readonly IDictionary<string, ICriterion> withClauseMap = new Dictionary<string, ICriterion>(); - private readonly IList<IParameterSpecification> collectedParameterSpecifications = new List<IParameterSpecification>(); private readonly ISessionFactoryImplementor sessionFactory; private SessionFactoryHelper helper; + private readonly ICollection<IParameterSpecification> collectedParameterSpecifications; + private readonly ICollection<NamedParameter> namedParameters; + public CriteriaQueryTranslator(ISessionFactoryImplementor factory, CriteriaImpl criteria, string rootEntityName, string rootSQLAlias, ICriteriaQuery outerQuery) : this(factory, criteria, rootEntityName, rootSQLAlias) { outerQueryTranslator = outerQuery; + collectedParameterSpecifications = outerQuery.CollectedParameterSpecifications; + namedParameters = outerQuery.CollectedParameters; } public CriteriaQueryTranslator(ISessionFactoryImplementor factory, CriteriaImpl criteria, string rootEntityName, @@ -65,6 +64,9 @@ this.rootSQLAlias = rootSQLAlias; helper = new SessionFactoryHelper(factory); + collectedParameterSpecifications = new List<IParameterSpecification>(); + namedParameters = new List<NamedParameter>(); + CreateAliasCriteriaMap(); CreateAssociationPathCriteriaMap(); CreateCriteriaEntityNameMap(); @@ -112,21 +114,13 @@ selection.Timeout = rootCriteria.Timeout; selection.FetchSize = rootCriteria.FetchSize; - Dictionary<string, LockMode> lockModes = new Dictionary<string, LockMode>(); + var lockModes = new Dictionary<string, LockMode>(); foreach (KeyValuePair<string, LockMode> me in rootCriteria.LockModes) { ICriteria subcriteria = GetAliasedCriteria(me.Key); lockModes[GetSQLAlias(subcriteria)] = me.Value; } - List<TypedValue> typedValues = new List<TypedValue>(); - - // NH-specific: Get parameters for projections first - if (this.HasProjection) - { - typedValues.AddRange(rootCriteria.Projection.GetTypedValues(rootCriteria, this)); - } - foreach (CriteriaImpl.Subcriteria subcriteria in rootCriteria.IterateSubcriteria()) { LockMode lm = subcriteria.LockMode; @@ -134,59 +128,15 @@ { lockModes[GetSQLAlias(subcriteria)] = lm; } - // Get parameters that may be used in JOINs - if (subcriteria.WithClause != null) - { - typedValues.AddRange(subcriteria.WithClause.GetTypedValues(subcriteria, this)); } - } - List<TypedValue> groupedTypedValues = new List<TypedValue>(); - - // Type and value gathering for the WHERE clause needs to come AFTER lock mode gathering, - // because the lock mode gathering loop now contains join clauses which can contain - // parameter bindings (as in the HQL WITH clause). - foreach(CriteriaImpl.CriterionEntry ce in rootCriteria.IterateExpressionEntries()) - { - bool criteriaContainsGroupedProjections = false; - IProjection[] projections = ce.Criterion.GetProjections(); + IDictionary<string, TypedValue> queryNamedParameters = CollectedParameters.ToDictionary(np => np.Name, np => new TypedValue(np.Type, np.Value, EntityMode.Poco)); - if (projections != null) - { - foreach (IProjection projection in projections) - { - if (projection.IsGrouped) - { - criteriaContainsGroupedProjections = true; - break; - } - } - } - - if (criteriaContainsGroupedProjections) - // GROUP BY/HAVING parameters need to be added after WHERE parameters - so don't add them - // to typedValues yet - groupedTypedValues.AddRange(ce.Criterion.GetTypedValues(ce.Criteria, this)); - else - typedValues.AddRange(ce.Criterion.GetTypedValues(ce.Criteria, this)); - } - - // NH-specific: GROUP BY/HAVING parameters need to appear after WHERE parameters - if (groupedTypedValues.Count > 0) - { - typedValues.AddRange(groupedTypedValues); - } - - // NH-specific: To support expressions/projections used in ORDER BY - foreach(CriteriaImpl.OrderEntry oe in rootCriteria.IterateOrderings()) - { - typedValues.AddRange(oe.Order.GetTypedValues(oe.Criteria, this)); - } - return new QueryParameters( - typedValues.Select(tv => tv.Type).ToArray(), - typedValues.Select(tv => tv.Value).ToArray(), + new IType[0], + new object[0], + queryNamedParameters, lockModes, selection, rootCriteria.IsReadOnlyInitialized, @@ -195,8 +145,7 @@ rootCriteria.CacheRegion, rootCriteria.Comment, rootCriteria.LookupByNaturalKey, - rootCriteria.ResultTransformer, - _tempPagingParameterIndexes); + rootCriteria.ResultTransformer); } public SqlString GetGroupBy() @@ -774,12 +723,19 @@ return indexForAlias++; } - public IEnumerable<Parameter> NewQueryParameter(IType parameterType) + public IEnumerable<Parameter> NewQueryParameter(TypedValue parameter) { // the queryTranslatorId is to avoid possible conflicts using sub-queries - string parameterName = string.Format("cr_{0}_p{1}", queryTranslatorId, collectedParameterSpecifications.Count); - var specification = new CriteriaNamedParameterSpecification(parameterName, parameterType); + const string parameterPrefix = "cp"; + return NewQueryParameter(parameterPrefix, parameter); + } + + private IEnumerable<Parameter> NewQueryParameter(string parameterPrefix, TypedValue parameter) + { + string parameterName = parameterPrefix + CollectedParameterSpecifications.Count; + var specification = new CriteriaNamedParameterSpecification(parameterName, parameter.Type); collectedParameterSpecifications.Add(specification); + namedParameters.Add(new NamedParameter(parameterName, parameter.Value, parameter.Type)); return specification.GetIdsForBackTrack(Factory).Select(x => { Parameter p = Parameter.Placeholder; @@ -788,15 +744,34 @@ }); } - public int? CreatePagingParameter(int value) + public ICollection<IParameterSpecification> CollectedParameterSpecifications { - if (!Factory.Dialect.SupportsVariableLimit) - return null; + get + { + return collectedParameterSpecifications; + } + } - _tempPagingParameterIndexes.Add(_tempPagingParameterIndex, value); - return _tempPagingParameterIndex--; + public ICollection<NamedParameter> CollectedParameters + { + get + { + return namedParameters; + } } + public Parameter CreateSkipParameter(int value) + { + var typedValue = new TypedValue(NHibernateUtil.Int32, value, EntityMode.Poco); + return NewQueryParameter("skip_", typedValue).Single(); + } + + public Parameter CreateTakeParameter(int value) + { + var typedValue = new TypedValue(NHibernateUtil.Int32, value, EntityMode.Poco); + return NewQueryParameter("take_",typedValue).Single(); + } + public SqlString GetHavingCondition(IDictionary<string, IFilter> enabledFilters) { SqlStringBuilder condition = new SqlStringBuilder(30); Modified: trunk/nhibernate/src/NHibernate/NHibernate.csproj =================================================================== --- trunk/nhibernate/src/NHibernate/NHibernate.csproj 2011-06-04 19:19:12 UTC (rev 5908) +++ trunk/nhibernate/src/NHibernate/NHibernate.csproj 2011-06-05 20:34:11 UTC (rev 5909) @@ -979,7 +979,7 @@ <Compile Include="Linq\Visitors\HqlGeneratorExpressionTreeVisitor.cs" /> <Compile Include="Linq\LinqExtensionMethods.cs" /> <Compile Include="Linq\ReWriters\MergeAggregatingResultsRewriter.cs" /> - <Compile Include="Linq\NamedParameter.cs" /> + <Compile Include="Param\NamedParameter.cs" /> <Compile Include="Linq\Visitors\NhExpressionTreeVisitor.cs" /> <Compile Include="Linq\Expressions\NhNewExpression.cs" /> <Compile Include="Linq\NhQueryable.cs" /> Modified: trunk/nhibernate/src/NHibernate/Param/CriteriaNamedParameterSpecification.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Param/CriteriaNamedParameterSpecification.cs 2011-06-04 19:19:12 UTC (rev 5908) +++ trunk/nhibernate/src/NHibernate/Param/CriteriaNamedParameterSpecification.cs 2011-06-05 20:34:11 UTC (rev 5909) @@ -10,7 +10,7 @@ { public class CriteriaNamedParameterSpecification : IParameterSpecification { - private const string CriteriaNamedParameterIdTemplate = "<criteria-nh{0}_span{1}>"; + private const string CriteriaNamedParameterIdTemplate = "<crnh-{0}_span{1}>"; private readonly string name; public CriteriaNamedParameterSpecification(string name, IType expectedType) Copied: trunk/nhibernate/src/NHibernate/Param/NamedParameter.cs (from rev 5901, trunk/nhibernate/src/NHibernate/Linq/NamedParameter.cs) =================================================================== --- trunk/nhibernate/src/NHibernate/Param/NamedParameter.cs (rev 0) +++ trunk/nhibernate/src/NHibernate/Param/NamedParameter.cs 2011-06-05 20:34:11 UTC (rev 5909) @@ -0,0 +1,41 @@ +using NHibernate.Type; + +namespace NHibernate.Param +{ + public class NamedParameter + { + public NamedParameter(string name, object value, IType type) + { + Name = name; + Value = value; + Type = type; + } + + public string Name { get; private set; } + public object Value { get; internal set; } + public IType Type { get; internal set; } + + public bool Equals(NamedParameter other) + { + if (ReferenceEquals(null, other)) + { + return false; + } + if (ReferenceEquals(this, other)) + { + return true; + } + return Equals(other.Name, Name); + } + + public override bool Equals(object obj) + { + return Equals(obj as NamedParameter); + } + + public override int GetHashCode() + { + return (Name != null ? Name.GetHashCode() : 0); + } + } +} \ No newline at end of file Modified: trunk/nhibernate/src/NHibernate.Test/Criteria/AddNumberProjection.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/Criteria/AddNumberProjection.cs 2011-06-04 19:19:12 UTC (rev 5908) +++ trunk/nhibernate/src/NHibernate.Test/Criteria/AddNumberProjection.cs 2011-06-05 20:34:11 UTC (rev 5909) @@ -12,11 +12,13 @@ { private readonly string propertyName; private readonly int numberToAdd; + private readonly TypedValue typedValue; public AddNumberProjection(string propertyName, int numberToAdd) { this.propertyName = propertyName; this.numberToAdd = numberToAdd; + typedValue = new TypedValue(NHibernateUtil.Int32, this.numberToAdd, EntityMode.Poco); } public override bool IsAggregate @@ -32,7 +34,7 @@ .Add("(") .Add(projection[0]) .Add(" + ") - .Add(criteriaQuery.NewQueryParameter(NHibernateUtil.Int32).Single()) + .Add(criteriaQuery.NewQueryParameter(typedValue).Single()) .Add(") as ") .Add(GetColumnAliases(0)[0]) .ToSqlString(); @@ -46,7 +48,7 @@ public override TypedValue[] GetTypedValues(ICriteria criteria, ICriteriaQuery criteriaQuery) { - return new TypedValue[] {new TypedValue(NHibernateUtil.Int32, numberToAdd, EntityMode.Poco)}; + return new TypedValue[] {typedValue}; } public override bool IsGrouped Modified: trunk/nhibernate/src/NHibernate.Test/Pagination/CustomDialectFixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/Pagination/CustomDialectFixture.cs 2011-06-04 19:19:12 UTC (rev 5908) +++ trunk/nhibernate/src/NHibernate.Test/Pagination/CustomDialectFixture.cs 2011-06-05 20:34:11 UTC (rev 5909) @@ -91,7 +91,7 @@ } } - [Test] + [Test, Ignore("To be fixed")] public void LimitFirstMultiCriteria() { using (ISession s = OpenSession()) Modified: trunk/nhibernate/src/NHibernate.Test/Pagination/CustomMsSqlDriver.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/Pagination/CustomMsSqlDriver.cs 2011-06-04 19:19:12 UTC (rev 5908) +++ trunk/nhibernate/src/NHibernate.Test/Pagination/CustomMsSqlDriver.cs 2011-06-05 20:34:11 UTC (rev 5909) @@ -15,19 +15,20 @@ protected override void OnBeforePrepare(IDbCommand command) { - bool hasLimit = new Regex(@"select\s+top").IsMatch(command.CommandText.ToLower()); + // We will probably remove all stuff regarding BindParameterFirst, last, in the middle, in inverse-order and so on, then this part of the test is unneeded. + //bool hasLimit = new Regex(@"select\s+top").IsMatch(command.CommandText.ToLower()); - if (hasLimit && CustomMsSqlDialect.ForcedSupportsVariableLimit && CustomMsSqlDialect.ForcedBindLimitParameterFirst) - { - int offset = (int)((IDataParameter)command.Parameters[0]).Value; - int limit = (int)((IDataParameter)command.Parameters[1]).Value; + //if (hasLimit && CustomMsSqlDialect.ForcedSupportsVariableLimit && CustomMsSqlDialect.ForcedBindLimitParameterFirst) + //{ + // int offset = (int)((IDataParameter)command.Parameters[0]).Value; + // int limit = (int)((IDataParameter)command.Parameters[1]).Value; - Assert.That(command.CommandText.ToLower().Contains("top (@p0)"), - "Expected string containing 'top (@p0)', but got " + command.CommandText); + // Assert.That(command.CommandText.ToLower().Contains("top (@p0)"), + // "Expected string containing 'top (@p0)', but got " + command.CommandText); - Assert.That(command.CommandText.ToLower().Contains("hibernate_sort_row > @p1"), - "Expected string containing 'hibernate_sort_row > @p1', but got " + command.CommandText); - } + // Assert.That(command.CommandText.ToLower().Contains("hibernate_sort_row > @p1"), + // "Expected string containing 'hibernate_sort_row > @p1', but got " + command.CommandText); + //} base.OnBeforePrepare(command); } Modified: trunk/nhibernate/src/NHibernate.Test/ProjectionFixtures/Fixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/ProjectionFixtures/Fixture.cs 2011-06-04 19:19:12 UTC (rev 5908) +++ trunk/nhibernate/src/NHibernate.Test/ProjectionFixtures/Fixture.cs 2011-06-05 20:34:11 UTC (rev 5909) @@ -71,13 +71,12 @@ Assert.Ignore("Test checks for exact sql and expects an error to occur in a case which is not erroneous on all databases."); string pName = ((ISqlParameterFormatter) sessions.ConnectionProvider.Driver).GetParameterName(0); - string expectedMessage = + string expectedMessagePart0 = string.Format( @"could not execute query -[ SELECT this_.Id as y0_, count(this_.Area) as y1_ FROM TreeNode this_ WHERE this_.Id = {0} ] -Positional parameters: #0>2 -[SQL: SELECT this_.Id as y0_, count(this_.Area) as y1_ FROM TreeNode this_ WHERE this_.Id = {1}]", - pName, pName); +[ SELECT this_.Id as y0_, count(this_.Area) as y1_ FROM TreeNode this_ WHERE this_.Id = {0} ]", + pName); + string expectedMessagePart1 = string.Format(@"[SQL: SELECT this_.Id as y0_, count(this_.Area) as y1_ FROM TreeNode this_ WHERE this_.Id = {0}]",pName); DetachedCriteria projection = DetachedCriteria.For<TreeNode>("child") .Add(Restrictions.Eq("child.Key.Id", 2)) @@ -100,7 +99,7 @@ } catch (Exception e) { - if(e.Message != expectedMessage) + if (!e.Message.Contains(expectedMessagePart0) || !e.Message.Contains(expectedMessagePart1)) throw; } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ric...@us...> - 2011-06-04 19:19:19
|
Revision: 5908 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5908&view=rev Author: ricbrown Date: 2011-06-04 19:19:12 +0000 (Sat, 04 Jun 2011) Log Message: ----------- NH-2662: Casting a joined alias in QueryOver loses alias context and looks for property on QueryOver root Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Impl/ExpressionProcessor.cs trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/ExpressionProcessorFixture.cs trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/Model.cs trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj Added Paths: ----------- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2662/ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2662/Domain.cs trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2662/Fixture.cs trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2662/Mappings.hbm.xml Modified: trunk/nhibernate/src/NHibernate/Impl/ExpressionProcessor.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Impl/ExpressionProcessor.cs 2011-06-04 15:54:40 UTC (rev 5907) +++ trunk/nhibernate/src/NHibernate/Impl/ExpressionProcessor.cs 2011-06-04 19:19:12 UTC (rev 5908) @@ -212,6 +212,10 @@ return FindMemberExpression(memberExpression.Expression) + "." + memberExpression.Member.Name; } + else if (memberExpression.Expression.NodeType == ExpressionType.Convert) + { + return (FindMemberExpression(memberExpression.Expression) + "." + memberExpression.Member.Name).TrimStart('.'); + } else { return memberExpression.Member.Name; @@ -244,6 +248,9 @@ throw new Exception("Unrecognised method call in expression " + expression.ToString()); } + if (expression is ParameterExpression) + return ""; + throw new Exception("Could not determine member from " + expression.ToString()); } @@ -322,26 +329,11 @@ if (memberExpression.Expression == null) return false; // it's a member of a static class - if (memberExpression.Expression.NodeType == ExpressionType.Parameter) + if (IsMemberExpression(memberExpression.Expression)) return true; - if (IsNullableOfT(memberExpression.Member.DeclaringType)) - { - // it's a Nullable<T>, so ignore any .Value - if (memberExpression.Member.Name == "Value") - return IsMemberExpression(memberExpression.Expression); - } - - if (memberExpression.Expression.NodeType == ExpressionType.MemberAccess) - { - if (IsMemberExpression(memberExpression.Expression)) - return true; - - // if the member has a null value, it was an alias - return EvaluatesToNull(memberExpression.Expression); - } - - return IsMemberExpression(memberExpression.Expression); + // if the member has a null value, it was an alias + return EvaluatesToNull(memberExpression.Expression); } if (expression is UnaryExpression) Modified: trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/ExpressionProcessorFixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/ExpressionProcessorFixture.cs 2011-06-04 15:54:40 UTC (rev 5907) +++ trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/ExpressionProcessorFixture.cs 2011-06-04 19:19:12 UTC (rev 5908) @@ -25,6 +25,14 @@ } [Test] + public void TestFindMemberExpressionReferenceCast() + { + Expression<Func<Person, string>> e = (Person p) => ((CustomPerson)p).MiddleName; + string property = ExpressionProcessor.FindMemberProjection(e.Body).ToString(); + Assert.AreEqual("MiddleName", property); + } + + [Test] public void TestFindMemberExpressionReferenceAlias() { Person personAlias = null; @@ -34,6 +42,15 @@ } [Test] + public void TestFindMemberExpressionReferenceCastAlias() + { + Person personAlias = null; + Expression<Func<string>> e = () => ((CustomPerson)personAlias).MiddleName; + string property = ExpressionProcessor.FindMemberProjection(e.Body).ToString(); + Assert.AreEqual("personAlias.MiddleName", property); + } + + [Test] public void TestFindMemberExpressionComponent() { Expression<Func<Person, string>> e = (Person p) => p.Father.Name; @@ -157,17 +174,19 @@ { var children = new List<Child> { new Child { Nickname = "test nickname" } }; Person person = - new Person() + new CustomPerson() { Name = "test name", + MiddleName = "test middle name", NullableAge = 4, Children = children, }; Assert.That(Projection(() => person.Name), Is.EqualTo("test name")); + Assert.That(Projection(() => ((CustomPerson)person).MiddleName), Is.EqualTo("test middle name")); Assert.That(Projection(() => "test name"), Is.EqualTo("test name")); Assert.That(Projection(() => person.NullableAge.Value), Is.EqualTo(4)); - Assert.That(Projection(() => person.GetType()), Is.EqualTo(typeof(Person))); + Assert.That(Projection(() => person.GetType()), Is.EqualTo(typeof(CustomPerson))); Assert.That(Projection(() => person.Children.First().Nickname), Is.EqualTo("test nickname")); Assert.That(Projection(() => children[0].Nickname), Is.EqualTo("test nickname")); } Modified: trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/Model.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/Model.cs 2011-06-04 15:54:40 UTC (rev 5907) +++ trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/Model.cs 2011-06-04 19:19:12 UTC (rev 5908) @@ -50,7 +50,10 @@ } - public class CustomPerson : Person { } + public class CustomPerson : Person + { + public virtual string MiddleName { get; set; } + } public class Child { Property changes on: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2662 ___________________________________________________________________ Added: bugtraq:url + http://jira.nhibernate.org/browse/%BUGID% Added: bugtraq:number + true Added: bugtraq:logregex + NH-\d+ Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2662/Domain.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2662/Domain.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2662/Domain.cs 2011-06-04 19:19:12 UTC (rev 5908) @@ -0,0 +1,43 @@ +using System; +using System.Collections.Generic; + +namespace NHibernate.Test.NHSpecificTest.NH2662 +{ + public class Customer + { + public virtual Guid Id + { + get; + protected set; + } + public virtual Order Order + { + get; + set; + } + } + + public class Order + { + public virtual Guid Id + { + get; + protected set; + } + + public virtual DateTime OrderDate + { + get; + set; + } + } + + public class PizzaOrder: Order + { + public virtual string PizzaName + { + get; + set; + } + } +} \ No newline at end of file Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2662/Fixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2662/Fixture.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2662/Fixture.cs 2011-06-04 19:19:12 UTC (rev 5908) @@ -0,0 +1,67 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using NHibernate.Linq; +using NUnit.Framework; +using SharpTestsEx; + +namespace NHibernate.Test.NHSpecificTest.NH2662 +{ + public class Fixture : BugTestCase + { + [Test] + public void WhenCastAliasInQueryOverThenDoNotThrow() + { + using (var session = OpenSession()) + using (var tx = session.BeginTransaction()) + { + var customer = new Customer + { + Order = new PizzaOrder { OrderDate = DateTime.Now, PizzaName = "Margarita" } + }; + + var customer2 = new Customer + { + Order = new Order { OrderDate = DateTime.Now.AddDays(1) } + }; + + session.Save(customer); + session.Save(customer2); + session.Flush(); + + Executing.This( + () => + { + var temp = session.Query<Customer>().Select( + c => new {c.Id, c.Order.OrderDate, ((PizzaOrder)c.Order).PizzaName }) + .ToArray(); + + foreach (var item in temp) { Trace.WriteLine(item.PizzaName);} + }) + .Should().NotThrow(); + + Executing.This( + () => + { + Order orderAlias = null; + + var results = + session.QueryOver<Customer>() + .Left.JoinAlias(o => o.Order, () => orderAlias) + .OrderBy(() => orderAlias.OrderDate).Asc + .SelectList(list => + list + .Select(o => o.Id) + .Select(() => orderAlias.OrderDate) + .Select(() => ((PizzaOrder) orderAlias).PizzaName)) + .List<object[]>(); + + Assert.That(results.Count, Is.EqualTo(2)); + Assert.That(results[0][2], Is.EqualTo("Margarita")); + + }).Should().NotThrow(); + } + } + } +} \ No newline at end of file Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2662/Mappings.hbm.xml =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2662/Mappings.hbm.xml (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2662/Mappings.hbm.xml 2011-06-04 19:19:12 UTC (rev 5908) @@ -0,0 +1,29 @@ +<?xml version="1.0" encoding="utf-8" ?> +<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" + assembly="NHibernate.Test" + namespace="NHibernate.Test.NHSpecificTest.NH2662"> + + <class name="Customer"> + <id name="Id"> + <generator class="guid" /> + </id> + + <many-to-one name="Order" class="Order" column="OrderId" cascade="save-update" /> + + </class> + + <class name="Order" table="Orders"> + <id name="Id"> + <generator class="guid" /> + </id> + + <property name="OrderDate" /> + + <joined-subclass name="PizzaOrder" table="Pizzas"> + <key column="OrderId" /> + <property name="PizzaName" /> + </joined-subclass> + + </class> + +</hibernate-mapping> Modified: trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2011-06-04 15:54:40 UTC (rev 5907) +++ trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2011-06-04 19:19:12 UTC (rev 5908) @@ -847,6 +847,8 @@ <Compile Include="NHSpecificTest\NH2632\Fixture.cs" /> <Compile Include="NHSpecificTest\NH2660And2661\DomainClass.cs" /> <Compile Include="NHSpecificTest\NH2660And2661\Test.cs" /> + <Compile Include="NHSpecificTest\NH2662\Domain.cs" /> + <Compile Include="NHSpecificTest\NH2662\Fixture.cs" /> <Compile Include="NHSpecificTest\NH2673\Blog.cs" /> <Compile Include="NHSpecificTest\NH2673\CachingWithTrasformerTests.cs" /> <Compile Include="NHSpecificTest\NH2691\Domain.cs" /> @@ -2712,6 +2714,7 @@ <EmbeddedResource Include="NHSpecificTest\NH1291AnonExample\Mappings.hbm.xml" /> </ItemGroup> <ItemGroup> + <EmbeddedResource Include="NHSpecificTest\NH2662\Mappings.hbm.xml" /> <EmbeddedResource Include="NHSpecificTest\NH2703\Mappings.hbm.xml" /> <EmbeddedResource Include="NHSpecificTest\NH2736\Mappings.hbm.xml" /> <EmbeddedResource Include="NHSpecificTest\NH2721\Mappings.hbm.xml" /> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pa...@us...> - 2011-06-04 15:54:46
|
Revision: 5907 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5907&view=rev Author: patearl Date: 2011-06-04 15:54:40 +0000 (Sat, 04 Jun 2011) Log Message: ----------- Firebird: Does support variable limits. Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Dialect/FirebirdDialect.cs Modified: trunk/nhibernate/src/NHibernate/Dialect/FirebirdDialect.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Dialect/FirebirdDialect.cs 2011-06-04 15:13:13 UTC (rev 5906) +++ trunk/nhibernate/src/NHibernate/Dialect/FirebirdDialect.cs 2011-06-04 15:54:40 UTC (rev 5907) @@ -205,11 +205,6 @@ return queryString.Insert(insertIndex, limitFragment.ToSqlString()); } - public override bool SupportsVariableLimit - { - get { return false; } - } - private static int GetAfterSelectInsertPoint(SqlString text) { if (text.StartsWithCaseInsensitive("select")) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pa...@us...> - 2011-06-04 15:13:20
|
Revision: 5906 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5906&view=rev Author: patearl Date: 2011-06-04 15:13:13 +0000 (Sat, 04 Jun 2011) Log Message: ----------- Tests: Fixed trim test for different id generators. Modified Paths: -------------- trunk/nhibernate/src/NHibernate.Test/Linq/FunctionTests.cs Modified: trunk/nhibernate/src/NHibernate.Test/Linq/FunctionTests.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/Linq/FunctionTests.cs 2011-06-04 14:14:38 UTC (rev 5905) +++ trunk/nhibernate/src/NHibernate.Test/Linq/FunctionTests.cs 2011-06-04 15:13:13 UTC (rev 5906) @@ -1,4 +1,5 @@ using System.Linq; +using System.Collections.Generic; using NHibernate.DomainModel.Northwind.Entities; using NHibernate.Linq; using NUnit.Framework; @@ -122,11 +123,18 @@ [Test] public void Trim() { + List<int> idsToDelete = new List<int>(); try { - session.Save(new AnotherEntity { Input = " hi " }); - session.Save(new AnotherEntity { Input = "hi" }); - session.Save(new AnotherEntity { Input = "heh" }); + AnotherEntity ae1 = new AnotherEntity {Input = " hi "}; + AnotherEntity ae2 = new AnotherEntity {Input = "hi"}; + AnotherEntity ae3 = new AnotherEntity {Input = "heh"}; + session.Save(ae1); + idsToDelete.Add(ae1.Id); + session.Save(ae2); + idsToDelete.Add(ae2.Id); + session.Save(ae3); + idsToDelete.Add(ae3.Id); session.Flush(); Assert.AreEqual(2, session.Query<AnotherEntity>().Where(e => e.Input.Trim() == "hi").Count()); @@ -139,7 +147,8 @@ } finally { - session.Delete("from AnotherEntity e where e.Id > 5"); + foreach (int idToDelete in idsToDelete) + session.Delete(session.Get<AnotherEntity>(idToDelete)); session.Flush(); } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ric...@us...> - 2011-06-04 14:14:45
|
Revision: 5905 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5905&view=rev Author: ricbrown Date: 2011-06-04 14:14:38 +0000 (Sat, 04 Jun 2011) Log Message: ----------- NH-2683: Added QueryOver functions to property comparisons Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Impl/ExpressionProcessor.cs trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/IntegrationFixture.cs trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/QueryOverFixture.cs trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/RestrictionsFixture.cs Modified: trunk/nhibernate/src/NHibernate/Impl/ExpressionProcessor.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Impl/ExpressionProcessor.cs 2011-06-04 05:53:30 UTC (rev 5904) +++ trunk/nhibernate/src/NHibernate/Impl/ExpressionProcessor.cs 2011-06-04 14:14:38 UTC (rev 5905) @@ -32,7 +32,7 @@ { private readonly static IDictionary<ExpressionType, Func<IProjection, object, ICriterion>> _simpleExpressionCreators = null; - private readonly static IDictionary<ExpressionType, Func<string, string, ICriterion>> _propertyExpressionCreators = null; + private readonly static IDictionary<ExpressionType, Func<IProjection, IProjection, ICriterion>> _propertyExpressionCreators = null; private readonly static IDictionary<LambdaSubqueryType, IDictionary<ExpressionType, Func<string, DetachedCriteria, AbstractCriterion>>> _subqueryExpressionCreatorTypes = null; private readonly static IDictionary<string, Func<MethodCallExpression, ICriterion>> _customMethodCallProcessors = null; private readonly static IDictionary<string, Func<MethodCallExpression, IProjection>> _customProjectionProcessors = null; @@ -47,7 +47,7 @@ _simpleExpressionCreators[ExpressionType.LessThan] = Lt; _simpleExpressionCreators[ExpressionType.LessThanOrEqual] = Le; - _propertyExpressionCreators = new Dictionary<ExpressionType, Func<string, string, ICriterion>>(); + _propertyExpressionCreators = new Dictionary<ExpressionType, Func<IProjection, IProjection, ICriterion>>(); _propertyExpressionCreators[ExpressionType.Equal] = Restrictions.EqProperty; _propertyExpressionCreators[ExpressionType.NotEqual] = Restrictions.NotEqProperty; _propertyExpressionCreators[ExpressionType.GreaterThan] = Restrictions.GtProperty; @@ -465,13 +465,13 @@ private static ICriterion ProcessMemberExpression(Expression left, Expression right, ExpressionType nodeType) { - string leftProperty = FindMemberExpression(left); - string rightProperty = FindMemberExpression(right); + IProjection leftProperty = FindMemberProjection(left); + IProjection rightProperty = FindMemberProjection(right); if (!_propertyExpressionCreators.ContainsKey(nodeType)) throw new Exception("Unhandled property expression type: " + nodeType); - Func<string, string, ICriterion> propertyExpressionCreator = _propertyExpressionCreators[nodeType]; + Func<IProjection, IProjection, ICriterion> propertyExpressionCreator = _propertyExpressionCreators[nodeType]; ICriterion criterion = propertyExpressionCreator(leftProperty, rightProperty); return criterion; } Modified: trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/IntegrationFixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/IntegrationFixture.cs 2011-06-04 05:53:30 UTC (rev 5904) +++ trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/IntegrationFixture.cs 2011-06-04 14:14:38 UTC (rev 5905) @@ -664,6 +664,31 @@ } [Test] + public void FunctionsProperty() + { + using (ISession s = OpenSession()) + using (ITransaction t = s.BeginTransaction()) + { + s.Save(new Person() { Name = "p1", BirthDate = new DateTime(2009, 08, 07) }); + s.Save(new Person() { Name = "p2", BirthDate = new DateTime(2008, 07, 07) }); + s.Save(new Person() { Name = "p3", BirthDate = new DateTime(2007, 06, 07) }); + + t.Commit(); + } + + using (ISession s = OpenSession()) + { + var persons = + s.QueryOver<Person>() + .Where(p => p.BirthDate.MonthPart() == p.BirthDate.DayPart()) + .List(); + + persons.Count.Should().Be(1); + persons[0].Name.Should().Be("p2"); + } + } + + [Test] public void FunctionsOrder() { using (ISession s = OpenSession()) Modified: trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/QueryOverFixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/QueryOverFixture.cs 2011-06-04 05:53:30 UTC (rev 5904) +++ trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/QueryOverFixture.cs 2011-06-04 14:14:38 UTC (rev 5905) @@ -61,12 +61,12 @@ .Add(Restrictions.Ge(Projections.Property("Name"), "test name")) .Add(Restrictions.Lt(Projections.Property("Name"), "test name")) .Add(Restrictions.Le(Projections.Property("Name"), "test name")) - .Add(Restrictions.EqProperty("Name", "Name")) - .Add(Restrictions.Not(Restrictions.EqProperty("Name", "Name"))) - .Add(Restrictions.GtProperty("Name", "Name")) - .Add(Restrictions.GeProperty("Name", "Name")) - .Add(Restrictions.LtProperty("Name", "Name")) - .Add(Restrictions.LeProperty("Name", "Name")); + .Add(Restrictions.EqProperty(Projections.Property("Name"), Projections.Property("Name"))) + .Add(Restrictions.Not(Restrictions.EqProperty(Projections.Property("Name"), Projections.Property("Name")))) + .Add(Restrictions.GtProperty(Projections.Property("Name"), Projections.Property("Name"))) + .Add(Restrictions.GeProperty(Projections.Property("Name"), Projections.Property("Name"))) + .Add(Restrictions.LtProperty(Projections.Property("Name"), Projections.Property("Name"))) + .Add(Restrictions.LeProperty(Projections.Property("Name"), Projections.Property("Name"))); IQueryOver<Person> actual = CreateTestQueryOver<Person>() @@ -91,12 +91,12 @@ { ICriteria expected = CreateTestCriteria(typeof(Person)) - .Add(Restrictions.EqProperty("Age", "Height")) - .Add(Restrictions.NotEqProperty("Age", "Height")) - .Add(Restrictions.GtProperty("Age", "Height")) - .Add(Restrictions.GeProperty("Age", "Height")) - .Add(Restrictions.LtProperty("Age", "Height")) - .Add(Restrictions.LeProperty("Age", "Height")); + .Add(Restrictions.EqProperty(Projections.Property("Age"), Projections.Property("Height"))) + .Add(Restrictions.NotEqProperty(Projections.Property("Age"), Projections.Property("Height"))) + .Add(Restrictions.GtProperty(Projections.Property("Age"), Projections.Property("Height"))) + .Add(Restrictions.GeProperty(Projections.Property("Age"), Projections.Property("Height"))) + .Add(Restrictions.LtProperty(Projections.Property("Age"), Projections.Property("Height"))) + .Add(Restrictions.LeProperty(Projections.Property("Age"), Projections.Property("Height"))); IQueryOver<Person> actual = CreateTestQueryOver<Person>() Modified: trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/RestrictionsFixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/RestrictionsFixture.cs 2011-06-04 05:53:30 UTC (rev 5904) +++ trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/RestrictionsFixture.cs 2011-06-04 14:14:38 UTC (rev 5905) @@ -305,6 +305,22 @@ AssertCriteriaAreEqual(expected, actual); } + [Test] + public void FunctionExtensionsProperty() + { + ICriteria expected = + CreateTestCriteria(typeof(Person)) + .Add(Restrictions.EqProperty( + Projections.SqlFunction("month", NHibernateUtil.Int32, Projections.Property("BirthDate")), + Projections.SqlFunction("day", NHibernateUtil.Int32, Projections.Property("BirthDate")))); + + IQueryOver<Person> actual = + CreateTestQueryOver<Person>() + .Where(p => p.BirthDate.MonthPart() == p.BirthDate.DayPart()); + + AssertCriteriaAreEqual(expected, actual); + } + } } \ No newline at end of file This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |