|
From: <ste...@us...> - 2009-12-01 22:08:36
|
Revision: 4886
http://nhibernate.svn.sourceforge.net/nhibernate/?rev=4886&view=rev
Author: steverstrong
Date: 2009-12-01 22:08:23 +0000 (Tue, 01 Dec 2009)
Log Message:
-----------
Changes to HQLQueryPlan and IQueryTranslatorFactory to support polymorphic Linq queries
Modified Paths:
--------------
trunk/nhibernate/src/NHibernate/Engine/Query/FilterQueryPlan.cs
trunk/nhibernate/src/NHibernate/Engine/Query/HQLQueryPlan.cs
trunk/nhibernate/src/NHibernate/Engine/Query/QueryPlanCache.cs
trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/ASTQueryTranslatorFactory.cs
trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/HqlParser.cs
trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/HqlToken.cs
trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/QueryTranslatorImpl.cs
trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/Tree/ASTNode.cs
trunk/nhibernate/src/NHibernate/Hql/Classic/ClassicQueryTranslatorFactory.cs
trunk/nhibernate/src/NHibernate/Hql/IQueryTranslatorFactory.cs
trunk/nhibernate/src/NHibernate/Impl/AbstractSessionImpl.cs
trunk/nhibernate/src/NHibernate/Impl/SessionImpl.cs
trunk/nhibernate/src/NHibernate/Impl/StatelessSessionImpl.cs
trunk/nhibernate/src/NHibernate/Linq/Visitors/HqlGeneratorExpressionTreeVisitor.cs
trunk/nhibernate/src/NHibernate.Test/App.config
trunk/nhibernate/src/NHibernate.Test/BulkManipulation/BaseFixture.cs
trunk/nhibernate/src/NHibernate.Test/HQL/Ast/BaseFixture.cs
trunk/nhibernate/src/NHibernate.Test/HQL/Ast/HqlFixture.cs
trunk/nhibernate/src/NHibernate.Test/Linq/MiscellaneousTextFixture.cs
trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1849/Fixture.cs
Modified: trunk/nhibernate/src/NHibernate/Engine/Query/FilterQueryPlan.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Engine/Query/FilterQueryPlan.cs 2009-12-01 21:03:41 UTC (rev 4885)
+++ trunk/nhibernate/src/NHibernate/Engine/Query/FilterQueryPlan.cs 2009-12-01 22:08:23 UTC (rev 4886)
@@ -8,7 +8,7 @@
/// being filtered.
/// </summary>
[Serializable]
- public class FilterQueryPlan : HQLQueryPlan
+ public class FilterQueryPlan : HQLStringQueryPlan
{
private readonly string collectionRole;
Modified: trunk/nhibernate/src/NHibernate/Engine/Query/HQLQueryPlan.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Engine/Query/HQLQueryPlan.cs 2009-12-01 21:03:41 UTC (rev 4885)
+++ trunk/nhibernate/src/NHibernate/Engine/Query/HQLQueryPlan.cs 2009-12-01 22:08:23 UTC (rev 4886)
@@ -7,258 +7,86 @@
using NHibernate.Event;
using NHibernate.Hql;
using NHibernate.Hql.Ast.ANTLR;
+using NHibernate.Impl;
using NHibernate.Type;
using NHibernate.Util;
namespace NHibernate.Engine.Query
{
+ public interface IQueryPlan
+ {
+ ParameterMetadata ParameterMetadata { get; }
+ ISet<string> QuerySpaces { get; }
+ IQueryTranslator[] Translators { get; }
+ ReturnMetadata ReturnMetadata { get; }
+ void PerformList(QueryParameters queryParameters, ISessionImplementor statelessSessionImpl, IList results);
+ int PerformExecuteUpdate(QueryParameters queryParameters, ISessionImplementor statelessSessionImpl);
+ IEnumerable<T> PerformIterate<T>(QueryParameters queryParameters, IEventSource session);
+ IEnumerable PerformIterate(QueryParameters queryParameters, IEventSource session);
+ }
+
+ public interface IQueryExpressionPlan : IQueryPlan
+ {
+ IQueryExpression QueryExpression { get; }
+ }
+
/// <summary> Defines a query execution plan for an HQL query (or filter). </summary>
[Serializable]
- public class HQLQueryPlan
+ public class HQLQueryPlan : IQueryPlan
{
- private static readonly ILog log = LogManager.GetLogger(typeof(HQLQueryPlan));
+ protected static readonly ILog Log = LogManager.GetLogger(typeof(HQLQueryPlan));
- private readonly string sourceQuery;
- private readonly IQueryTranslator[] translators;
- private readonly string[] sqlStrings;
+ private readonly string _sourceQuery;
- private readonly ParameterMetadata parameterMetadata;
- private readonly ReturnMetadata returnMetadata;
- private readonly HashedSet<string> querySpaces;
-
- private readonly HashedSet<string> enabledFilterNames;
- private readonly bool shallow;
- private IQueryExpression sourceQueryExpression;
-
- public HQLQueryPlan(string hql, bool shallow,
- IDictionary<string, IFilter> enabledFilters, ISessionFactoryImplementor factory)
- : this(hql, (string) null, shallow, enabledFilters, factory)
- {
- }
-
- public HQLQueryPlan(string expressionStr, IQueryExpression queryExpression, bool shallow,
- IDictionary<string, IFilter> enabledFilters, ISessionFactoryImplementor factory)
- : this(expressionStr, queryExpression, null, shallow, enabledFilters, factory)
+ protected HQLQueryPlan(string sourceQuery)
{
+ _sourceQuery = sourceQuery;
}
- protected internal HQLQueryPlan(string hql, string collectionRole, bool shallow,
- IDictionary<string, IFilter> enabledFilters, ISessionFactoryImplementor factory)
- {
- sourceQuery = hql;
- this.shallow = shallow;
-
- enabledFilterNames = new HashedSet<string>(enabledFilters.Keys);
-
- HashedSet<string> combinedQuerySpaces = new HashedSet<string>();
- string[] concreteQueryStrings = QuerySplitter.ConcreteQueries(hql, factory);
- int length = concreteQueryStrings.Length;
- translators = new IQueryTranslator[length];
- List<string> sqlStringList = new List<string>();
- for (int i = 0; i < length; i++)
- {
- if (collectionRole == null)
- {
- translators[i] =
- factory.Settings.QueryTranslatorFactory.CreateQueryTranslator(hql, concreteQueryStrings[i], enabledFilters,
- factory);
- translators[i].Compile(factory.Settings.QuerySubstitutions, shallow);
- }
- else
- {
- translators[i] =
- factory.Settings.QueryTranslatorFactory.CreateFilterTranslator(hql, concreteQueryStrings[i], enabledFilters,
- factory);
- ((IFilterTranslator)translators[i]).Compile(collectionRole, factory.Settings.QuerySubstitutions, shallow);
- }
- foreach (string qs in translators[i].QuerySpaces)
- {
- combinedQuerySpaces.Add(qs);
- }
- sqlStringList.AddRange(translators[i].CollectSqlStrings);
- }
-
- sqlStrings = sqlStringList.ToArray();
- querySpaces = combinedQuerySpaces;
-
- if (length == 0)
- {
- parameterMetadata = new ParameterMetadata(null, null);
- returnMetadata = null;
- }
- else
- {
- parameterMetadata = BuildParameterMetadata(translators[0].GetParameterTranslations(), hql);
- if (translators[0].IsManipulationStatement)
- {
- returnMetadata = null;
- }
- else
- {
- if (length > 1)
- {
- int returns = translators[0].ReturnTypes.Length;
- returnMetadata = new ReturnMetadata(translators[0].ReturnAliases, new IType[returns]);
- }
- else
- {
- returnMetadata = new ReturnMetadata(translators[0].ReturnAliases, translators[0].ReturnTypes);
- }
- }
- }
- }
-
- protected internal HQLQueryPlan(string expressionStr, IQueryExpression queryExpression, string collectionRole, bool shallow,
- IDictionary<string, IFilter> enabledFilters, ISessionFactoryImplementor factory)
- {
- sourceQueryExpression = queryExpression;
- sourceQuery = expressionStr;
- this.shallow = shallow;
-
- enabledFilterNames = new HashedSet<string>(enabledFilters.Keys);
-
- // TODO - no support for polymorphism here - done during Expression -> AST translation?
- // TODO - polymorphism approach used in method above also sucks. Could be done in AST much more cleanly? Look at this...
- IQueryTranslatorFactory2 qtFactory = new ASTQueryTranslatorFactory();
-
- IQueryTranslator translator = qtFactory.CreateQueryTranslator(expressionStr, queryExpression, enabledFilters,
- factory);
-
- translator.Compile(factory.Settings.QuerySubstitutions, shallow);
-
- translators = new[] { translator };
-
- sqlStrings = new List<string>(translator.CollectSqlStrings).ToArray();
-
- querySpaces = new HashedSet<string>(translator.QuerySpaces);
-
- var parameterTranslations = translator.GetParameterTranslations();
-
- var namedParamDescriptorMap = new Dictionary<string, NamedParameterDescriptor>();
- foreach (NamedParameterDescriptor entry in queryExpression.ParameterDescriptors)
- {
- namedParamDescriptorMap[entry.Name] =
- new NamedParameterDescriptor(entry.Name, parameterTranslations.GetNamedParameterExpectedType(entry.Name),
- entry.SourceLocations, entry.JpaStyle);
- }
-
- parameterMetadata = new ParameterMetadata(new OrdinalParameterDescriptor[0], namedParamDescriptorMap);
-
- returnMetadata = new ReturnMetadata(translator.ReturnAliases, translator.ReturnTypes);
- }
-
- public string SourceQuery
- {
- get { return sourceQuery; }
- }
-
public ISet<string> QuerySpaces
{
- get { return querySpaces; }
+ get;
+ protected set;
}
public ParameterMetadata ParameterMetadata
{
- get { return parameterMetadata; }
- }
+ get;
+ protected set;
+ }
public ReturnMetadata ReturnMetadata
{
- get { return returnMetadata; }
- }
+ get;
+ protected set;
+ }
- public ISet EnabledFilterNames
- {
- get { return enabledFilterNames; }
- }
-
public string[] SqlStrings
{
- get { return sqlStrings; }
- }
+ get;
+ protected set;
+ }
- public ISet UtilizedFilterNames
- {
- get
- {
- // TODO : add this info to the translator and aggregate it here...
- return null;
- }
- }
-
- public bool Shallow
- {
- get { return shallow; }
- }
-
public IQueryTranslator[] Translators
{
- get
- {
- IQueryTranslator[] copy = new IQueryTranslator[translators.Length];
- Array.Copy(translators, 0, copy, 0, copy.Length);
- return copy;
- }
- }
+ get;
+ protected set;
+ }
- public IQueryExpression QueryExpression
- {
- get { return sourceQueryExpression; }
- }
-
- private static ParameterMetadata BuildParameterMetadata(IParameterTranslations parameterTranslations, string hql)
- {
- long start = DateTime.Now.Ticks;
- ParamLocationRecognizer recognizer = ParamLocationRecognizer.ParseLocations(hql);
- long end = DateTime.Now.Ticks;
- if (log.IsDebugEnabled)
- {
- log.Debug("HQL param location recognition took " + (end - start) + " mills (" + hql + ")");
- }
-
- int ordinalParamCount = parameterTranslations.OrdinalParameterCount;
- int[] locations = recognizer.OrdinalParameterLocationList.ToArray();
- if (parameterTranslations.SupportsOrdinalParameterMetadata && locations.Length != ordinalParamCount)
- {
- throw new HibernateException("ordinal parameter mismatch");
- }
- ordinalParamCount = locations.Length;
- OrdinalParameterDescriptor[] ordinalParamDescriptors = new OrdinalParameterDescriptor[ordinalParamCount];
- for (int i = 1; i <= ordinalParamCount; i++)
- {
- ordinalParamDescriptors[i - 1] =
- new OrdinalParameterDescriptor(i,
- parameterTranslations.SupportsOrdinalParameterMetadata
- ? parameterTranslations.GetOrdinalParameterExpectedType(i)
- : null, locations[i - 1]);
- }
-
- Dictionary<string, NamedParameterDescriptor> namedParamDescriptorMap = new Dictionary<string, NamedParameterDescriptor>();
- foreach (KeyValuePair<string, ParamLocationRecognizer.NamedParameterDescription> entry in recognizer.NamedParameterDescriptionMap)
- {
- string name = entry.Key;
- ParamLocationRecognizer.NamedParameterDescription description = entry.Value;
- namedParamDescriptorMap[name] =
- new NamedParameterDescriptor(name, parameterTranslations.GetNamedParameterExpectedType(name),
- description.BuildPositionsArray(), description.JpaStyle);
-
- }
- return new ParameterMetadata(ordinalParamDescriptors, namedParamDescriptorMap);
- }
-
public void PerformList(QueryParameters queryParameters, ISessionImplementor session, IList results)
{
- if (log.IsDebugEnabled)
+ if (Log.IsDebugEnabled)
{
- log.Debug("find: " + SourceQuery);
+ Log.Debug("find: " + _sourceQuery);
queryParameters.LogParameters(session.Factory);
}
+
bool hasLimit = queryParameters.RowSelection != null && queryParameters.RowSelection.DefinesLimits;
- bool needsLimit = hasLimit && translators.Length > 1;
+ bool needsLimit = hasLimit && Translators.Length > 1;
QueryParameters queryParametersToUse;
if (needsLimit)
{
- log.Warn("firstResult/maxResults specified on polymorphic query; applying in memory!");
+ Log.Warn("firstResult/maxResults specified on polymorphic query; applying in memory!");
RowSelection selection = new RowSelection();
selection.FetchSize = queryParameters.RowSelection.FetchSize;
selection.Timeout = queryParameters.RowSelection.Timeout;
@@ -272,9 +100,9 @@
IList combinedResults = results ?? new List<object>();
IdentitySet distinction = new IdentitySet();
int includedCount = -1;
- for (int i = 0; i < translators.Length; i++)
+ for (int i = 0; i < Translators.Length; i++)
{
- IList tmp = translators[i].List(session, queryParametersToUse);
+ IList tmp = Translators[i].List(session, queryParametersToUse);
if (needsLimit)
{
// NOTE : firstRow is zero-based
@@ -333,28 +161,28 @@
{
isMany = null;
results = null;
- if (log.IsDebugEnabled)
+ if (Log.IsDebugEnabled)
{
- log.Debug("enumerable: " + SourceQuery);
+ Log.Debug("enumerable: " + _sourceQuery);
queryParameters.LogParameters(session.Factory);
}
- if (translators.Length == 0)
+ if (Translators.Length == 0)
{
result = CollectionHelper.EmptyEnumerable;
}
else
{
results = null;
- bool many = translators.Length > 1;
+ bool many = Translators.Length > 1;
if (many)
{
- results = new IEnumerable[translators.Length];
+ results = new IEnumerable[Translators.Length];
}
result = null;
- for (int i = 0; i < translators.Length; i++)
+ for (int i = 0; i < Translators.Length; i++)
{
- result = translators[i].GetEnumerable(queryParameters, session);
+ result = Translators[i].GetEnumerable(queryParameters, session);
if (many)
results[i] = result;
}
@@ -364,22 +192,191 @@
public int PerformExecuteUpdate(QueryParameters queryParameters, ISessionImplementor session)
{
- if (log.IsDebugEnabled)
+ if (Log.IsDebugEnabled)
{
- log.Debug("executeUpdate: " + SourceQuery);
+ Log.Debug("executeUpdate: " + _sourceQuery);
queryParameters.LogParameters(session.Factory);
}
- if (translators.Length != 1)
+ if (Translators.Length != 1)
{
- log.Warn("manipulation query [" + SourceQuery + "] resulted in [" + translators.Length + "] split queries");
+ Log.Warn("manipulation query [" + _sourceQuery + "] resulted in [" + Translators.Length + "] split queries");
}
int result = 0;
- for (int i = 0; i < translators.Length; i++)
+ for (int i = 0; i < Translators.Length; i++)
{
- result += translators[i].ExecuteUpdate(queryParameters, session);
+ result += Translators[i].ExecuteUpdate(queryParameters, session);
}
return result;
}
- }
+ protected void BuildSqlStringsAndQuerySpaces()
+ {
+ var combinedQuerySpaces = new HashedSet<string>();
+ var sqlStringList = new List<string>();
+
+ foreach (var translator in Translators)
+ {
+ foreach (var qs in translator.QuerySpaces)
+ {
+ combinedQuerySpaces.Add(qs);
+ }
+
+ sqlStringList.AddRange(translator.CollectSqlStrings);
+ }
+
+ SqlStrings = sqlStringList.ToArray();
+ QuerySpaces = combinedQuerySpaces;
+ }
+ }
+
+ [Serializable]
+ public class HQLStringQueryPlan : HQLQueryPlan
+ {
+ public HQLStringQueryPlan(string hql, bool shallow,
+ IDictionary<string, IFilter> enabledFilters, ISessionFactoryImplementor factory)
+ : this(hql, (string) null, shallow, enabledFilters, factory)
+ {
+ }
+
+ protected internal HQLStringQueryPlan(string hql, string collectionRole, bool shallow,
+ IDictionary<string, IFilter> enabledFilters, ISessionFactoryImplementor factory)
+ :base(hql)
+ {
+ Translators = factory.Settings.QueryTranslatorFactory.CreateQueryTranslators(hql, collectionRole, shallow, enabledFilters, factory);
+
+ BuildSqlStringsAndQuerySpaces();
+
+ if (Translators.Length == 0)
+ {
+ ParameterMetadata = new ParameterMetadata(null, null);
+ ReturnMetadata = null;
+ }
+ else
+ {
+ ParameterMetadata = BuildParameterMetadata(Translators[0].GetParameterTranslations(), hql);
+ if (Translators[0].IsManipulationStatement)
+ {
+ ReturnMetadata = null;
+ }
+ else
+ {
+ if (Translators.Length > 1)
+ {
+ int returns = Translators[0].ReturnTypes.Length;
+ ReturnMetadata = new ReturnMetadata(Translators[0].ReturnAliases, new IType[returns]);
+ }
+ else
+ {
+ ReturnMetadata = new ReturnMetadata(Translators[0].ReturnAliases, Translators[0].ReturnTypes);
+ }
+ }
+ }
+ }
+
+ private static ParameterMetadata BuildParameterMetadata(IParameterTranslations parameterTranslations, string hql)
+ {
+ long start = DateTime.Now.Ticks;
+ ParamLocationRecognizer recognizer = ParamLocationRecognizer.ParseLocations(hql);
+ long end = DateTime.Now.Ticks;
+ if (Log.IsDebugEnabled)
+ {
+ Log.Debug("HQL param location recognition took " + (end - start) + " mills (" + hql + ")");
+ }
+
+ int ordinalParamCount = parameterTranslations.OrdinalParameterCount;
+ int[] locations = recognizer.OrdinalParameterLocationList.ToArray();
+ if (parameterTranslations.SupportsOrdinalParameterMetadata && locations.Length != ordinalParamCount)
+ {
+ throw new HibernateException("ordinal parameter mismatch");
+ }
+ ordinalParamCount = locations.Length;
+ OrdinalParameterDescriptor[] ordinalParamDescriptors = new OrdinalParameterDescriptor[ordinalParamCount];
+ for (int i = 1; i <= ordinalParamCount; i++)
+ {
+ ordinalParamDescriptors[i - 1] =
+ new OrdinalParameterDescriptor(i,
+ parameterTranslations.SupportsOrdinalParameterMetadata
+ ? parameterTranslations.GetOrdinalParameterExpectedType(i)
+ : null, locations[i - 1]);
+ }
+
+ Dictionary<string, NamedParameterDescriptor> namedParamDescriptorMap = new Dictionary<string, NamedParameterDescriptor>();
+ foreach (KeyValuePair<string, ParamLocationRecognizer.NamedParameterDescription> entry in recognizer.NamedParameterDescriptionMap)
+ {
+ string name = entry.Key;
+ ParamLocationRecognizer.NamedParameterDescription description = entry.Value;
+ namedParamDescriptorMap[name] =
+ new NamedParameterDescriptor(name, parameterTranslations.GetNamedParameterExpectedType(name),
+ description.BuildPositionsArray(), description.JpaStyle);
+
+ }
+ return new ParameterMetadata(ordinalParamDescriptors, namedParamDescriptorMap);
+ }
+ }
+
+ [Serializable]
+ public class HQLLinqQueryPlan : HQLQueryPlan, IQueryExpressionPlan
+ {
+ public IQueryExpression QueryExpression
+ {
+ get;
+ protected set;
+ }
+
+ public HQLLinqQueryPlan(string expressionStr, IQueryExpression queryExpression, bool shallow,
+ IDictionary<string, IFilter> enabledFilters, ISessionFactoryImplementor factory)
+ : this(expressionStr, queryExpression, null, shallow, enabledFilters, factory)
+ {
+ }
+
+ protected internal HQLLinqQueryPlan(string expressionStr, IQueryExpression queryExpression, string collectionRole, bool shallow,
+ IDictionary<string, IFilter> enabledFilters, ISessionFactoryImplementor factory)
+ : base (expressionStr)
+ {
+ QueryExpression = queryExpression;
+
+ IQueryTranslatorFactory2 qtFactory = new ASTQueryTranslatorFactory();
+
+ Translators = qtFactory.CreateQueryTranslators(expressionStr, queryExpression, collectionRole, shallow, enabledFilters, factory);
+
+ BuildSqlStringsAndQuerySpaces();
+
+ if (Translators.Length == 0)
+ {
+ ParameterMetadata = new ParameterMetadata(null, null);
+ ReturnMetadata = null;
+ }
+ else
+ {
+ var parameterTranslations = Translators[0].GetParameterTranslations();
+
+ var namedParamDescriptorMap = new Dictionary<string, NamedParameterDescriptor>();
+ foreach (NamedParameterDescriptor entry in queryExpression.ParameterDescriptors)
+ {
+ namedParamDescriptorMap[entry.Name] =
+ new NamedParameterDescriptor(entry.Name, parameterTranslations.GetNamedParameterExpectedType(entry.Name),
+ entry.SourceLocations, entry.JpaStyle);
+ }
+
+ ParameterMetadata = new ParameterMetadata(new OrdinalParameterDescriptor[0], namedParamDescriptorMap);
+
+ if (Translators[0].IsManipulationStatement)
+ {
+ ReturnMetadata = null;
+ }
+ else
+ {
+ if (Translators.Length > 1)
+ {
+ int returns = Translators[0].ReturnTypes.Length;
+ ReturnMetadata = new ReturnMetadata(Translators[0].ReturnAliases, new IType[returns]);
+ }
+ else
+ {
+ ReturnMetadata = new ReturnMetadata(Translators[0].ReturnAliases, Translators[0].ReturnTypes);
+ }
+ }
+ }
+ }
+ }
}
Modified: trunk/nhibernate/src/NHibernate/Engine/Query/QueryPlanCache.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Engine/Query/QueryPlanCache.cs 2009-12-01 21:03:41 UTC (rev 4885)
+++ trunk/nhibernate/src/NHibernate/Engine/Query/QueryPlanCache.cs 2009-12-01 22:08:23 UTC (rev 4886)
@@ -47,10 +47,10 @@
return metadata;
}
- public HQLQueryPlan GetHQLQueryPlan(string queryString, bool shallow, IDictionary<string, IFilter> enabledFilters)
+ public IQueryPlan GetHQLQueryPlan(string queryString, bool shallow, IDictionary<string, IFilter> enabledFilters)
{
var key = new HQLQueryPlanKey(queryString, shallow, enabledFilters);
- var plan = (HQLQueryPlan)planCache[key];
+ var plan = (IQueryPlan)planCache[key];
if (plan == null)
{
@@ -58,7 +58,7 @@
{
log.Debug("unable to locate HQL query plan in cache; generating (" + queryString + ")");
}
- plan = new HQLQueryPlan(queryString, shallow, enabledFilters, factory);
+ plan = new HQLStringQueryPlan(queryString, shallow, enabledFilters, factory);
planCache.Put(key, plan);
}
else
@@ -72,12 +72,12 @@
return plan;
}
- public HQLQueryPlan GetHQLQueryPlan(IQueryExpression queryExpression, bool shallow, IDictionary<string, IFilter> enabledFilters)
+ public IQueryExpressionPlan GetHQLQueryPlan(IQueryExpression queryExpression, bool shallow, IDictionary<string, IFilter> enabledFilters)
{
string expressionStr = queryExpression.Key;
var key = new HQLQueryPlanKey(expressionStr, shallow, enabledFilters);
- var plan = (HQLQueryPlan)planCache[key];
+ var plan = (IQueryExpressionPlan)planCache[key];
if (plan == null)
{
@@ -85,7 +85,7 @@
{
log.Debug("unable to locate HQL query plan in cache; generating (" + expressionStr + ")");
}
- plan = new HQLQueryPlan(expressionStr, queryExpression, shallow, enabledFilters, factory);
+ plan = new HQLLinqQueryPlan(expressionStr, queryExpression, shallow, enabledFilters, factory);
planCache.Put(key, plan);
}
else
Modified: trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/ASTQueryTranslatorFactory.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/ASTQueryTranslatorFactory.cs 2009-12-01 21:03:41 UTC (rev 4885)
+++ trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/ASTQueryTranslatorFactory.cs 2009-12-01 22:08:23 UTC (rev 4886)
@@ -1,5 +1,12 @@
-using System.Collections.Generic;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Antlr.Runtime;
using NHibernate.Engine;
+using NHibernate.Hql.Ast.ANTLR.Tree;
+using NHibernate.Hql.Ast.ANTLR.Util;
+using NHibernate.Hql.Util;
namespace NHibernate.Hql.Ast.ANTLR
{
@@ -12,19 +19,247 @@
/// </summary>
public class ASTQueryTranslatorFactory : IQueryTranslatorFactory2
{
- public IQueryTranslator CreateQueryTranslator(string queryIdentifier, string queryString, IDictionary<string, IFilter> filters, ISessionFactoryImplementor factory)
+ public IQueryTranslator[] CreateQueryTranslators(string queryString, string collectionRole, bool shallow, IDictionary<string, IFilter> filters, ISessionFactoryImplementor factory)
{
- return new QueryTranslatorImpl(queryIdentifier, queryString, filters, factory);
- }
+ var isFilter = collectionRole != null;
+ var parser = new HqlParseEngine(queryString, isFilter, factory);
+ parser.Parse();
- public IFilterTranslator CreateFilterTranslator(string queryIdentifier, string queryString, IDictionary<string, IFilter> filters, ISessionFactoryImplementor factory)
- {
- return new QueryTranslatorImpl(queryIdentifier, queryString, filters, factory);
+ HqlParseEngine[] polymorphicParsers = AstPolymorphicProcessor.Process(parser, factory);
+
+ var translators = polymorphicParsers
+ .Select(hql => new QueryTranslatorImpl(queryString, hql, filters, factory))
+ .ToArray();
+
+ foreach (var translator in translators)
+ {
+ if (collectionRole == null)
+ {
+ translator.Compile(factory.Settings.QuerySubstitutions, shallow);
+ }
+ else
+ {
+ translator.Compile(collectionRole, factory.Settings.QuerySubstitutions, shallow);
+ }
+ }
+
+ return translators;
}
- public IQueryTranslator CreateQueryTranslator(string queryIdentifier, IQueryExpression queryExpression, IDictionary<string, IFilter> filters, ISessionFactoryImplementor factory)
+ public IQueryTranslator[] CreateQueryTranslators(string queryIdentifier, IQueryExpression queryExpression, string collectionRole, bool shallow, IDictionary<string, IFilter> filters, ISessionFactoryImplementor factory)
{
- return new QueryTranslatorImpl(queryIdentifier, queryExpression, filters, factory);
+ var isFilter = collectionRole != null;
+ var parser = new HqlParseEngine(queryExpression.Translate(factory), factory);
+
+ HqlParseEngine[] polymorphicParsers = AstPolymorphicProcessor.Process(parser, factory);
+
+ var translators = polymorphicParsers
+ .Select(hql => new QueryTranslatorImpl(queryIdentifier, hql, filters, factory))
+ .ToArray();
+
+ foreach (var translator in translators)
+ {
+ if (collectionRole == null)
+ {
+ translator.Compile(factory.Settings.QuerySubstitutions, shallow);
+ }
+ else
+ {
+ translator.Compile(collectionRole, factory.Settings.QuerySubstitutions, shallow);
+ }
+ }
+
+ return translators;
}
}
+
+ public class AstPolymorphicProcessor
+ {
+ public static HqlParseEngine[] Process(HqlParseEngine parser, ISessionFactoryImplementor factory)
+ {
+ // Find all the polymorphic "froms"
+ var fromDetector = new FromDetector(factory);
+ var polymorphic = new NodeTraverser(fromDetector);
+ polymorphic.TraverseDepthFirst(parser.Ast);
+
+ if (fromDetector.Map.Count > 0)
+ {
+ var parsers = DuplicateTree(parser.Ast, fromDetector.Map);
+
+ return parsers.Select(p => new HqlParseEngine(p, factory)).ToArray();
+ }
+ else
+ {
+ return new [] { parser };
+ }
+ }
+
+ private static IEnumerable<IASTNode> DuplicateTree(IASTNode ast, IEnumerable<KeyValuePair<IASTNode, IASTNode[]>> nodeMapping)
+ {
+ var replacements = ExpandDictionaryArrays(nodeMapping);
+
+ var dups = new IASTNode[replacements.Count()];
+
+ for (var i = 0; i < replacements.Count(); i++)
+ {
+ dups[i] = DuplicateTree(ast, replacements[i]);
+ }
+
+ return dups;
+ }
+
+ private static IASTNode DuplicateTree(IASTNode ast, Dictionary<IASTNode, IASTNode> nodeMapping)
+ {
+ IASTNode candidate;
+
+ if (nodeMapping.TryGetValue(ast, out candidate))
+ {
+ return candidate;
+ }
+
+ var dup = ast.DupNode();
+
+ foreach (var child in ast)
+ {
+ dup.AddChild(DuplicateTree(child, nodeMapping));
+ }
+
+ return dup;
+ }
+
+ static IList<Dictionary<IASTNode, IASTNode>> ExpandDictionaryArrays(IEnumerable<KeyValuePair<IASTNode, IASTNode[]>> input)
+ {
+ return (from list in ExpandDictionaryArraysInner(input)
+ select list.ToDictionary(kvp => kvp.Key, kvp => kvp.Value)).ToList();
+ }
+
+ static IEnumerable<IEnumerable<KeyValuePair<IASTNode, IASTNode>>> ExpandDictionaryArraysInner(IEnumerable<KeyValuePair<IASTNode, IASTNode[]>> input)
+ {
+ var output = new List<IEnumerable<KeyValuePair<IASTNode, IASTNode>>>();
+
+ foreach (var value in input.First().Value)
+ {
+ var inner = new List<KeyValuePair<IASTNode, IASTNode>>
+ {new KeyValuePair<IASTNode, IASTNode>(input.First().Key, value)};
+
+ if (input.Count() > 1)
+ {
+ output.AddRange(ExpandDictionaryArraysInner(input.Skip(1)).Select(c => c.Union(inner)));
+ }
+ else
+ {
+ output.Add(inner);
+ }
+ }
+
+ return output;
+ }
+
+ }
+
+
+ internal class FromDetector : IVisitationStrategy
+ {
+ private readonly ISessionFactoryImplementor _sfi;
+ private readonly Dictionary<IASTNode, IASTNode[]> _map = new Dictionary<IASTNode, IASTNode[]>();
+
+ public FromDetector(ISessionFactoryImplementor sfi)
+ {
+ _sfi = sfi;
+ }
+
+ public IDictionary<IASTNode, IASTNode[]> Map
+ {
+ get { return _map; }
+ }
+
+ public void Visit(IASTNode node)
+ {
+ if (node.Type == HqlSqlWalker.FROM && node.ChildCount > 0)
+ {
+ foreach (var child in node)
+ {
+ string className = null;
+ IASTNode identifer = null;
+
+ if (child.Type == HqlSqlWalker.RANGE)
+ {
+ identifer = child.GetChild(0);
+
+ if (identifer.Type == HqlSqlWalker.IDENT)
+ {
+ className = identifer.Text;
+ }
+ else if (identifer.Type == HqlSqlWalker.DOT)
+ {
+ className = BuildPath(identifer);
+ }
+ else
+ {
+ // TODO
+ throw new NotSupportedException();
+ }
+ }
+ else
+ {
+ // TODO - stuff for joins?
+ }
+
+ if (className != null)
+ {
+ System.Type classType = (new SessionFactoryHelper(_sfi)).GetImportedClass(className);
+
+ if (classType != null)
+ {
+ string[] implementors = _sfi.GetImplementors(classType.FullName);
+
+ if (implementors != null)
+ {
+ if (implementors.Length == 1 &&
+ ((implementors[0] == className) || (implementors[0] == classType.FullName)))
+ {
+ // No need to change things
+ return;
+ }
+
+ Map.Add(identifer,
+ implementors.Select(implementor => MakeIdent(identifer, implementor)).ToArray());
+ }
+ }
+ }
+ }
+ }
+ }
+
+ private IASTNode MakeIdent(IASTNode source, string text)
+ {
+ var ident = source.DupNode();
+ ident.Type = HqlSqlWalker.IDENT;
+ ident.Text = text;
+ return ident;
+ }
+
+ private static string BuildPath(IASTNode node)
+ {
+ var sb = new StringBuilder();
+ BuildPath(node, sb);
+ return sb.ToString();
+ }
+
+ private static void BuildPath(IASTNode node, StringBuilder sb)
+ {
+ if (node.Type == HqlSqlWalker.DOT)
+ {
+ BuildPath(node.GetChild(0), sb);
+
+ sb.Append('.');
+ sb.Append(node.GetChild(1).Text);
+ }
+ else
+ {
+ sb.Append(node.Text);
+ }
+ }
+ }
+
}
Modified: trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/HqlParser.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/HqlParser.cs 2009-12-01 21:03:41 UTC (rev 4885)
+++ trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/HqlParser.cs 2009-12-01 22:08:23 UTC (rev 4886)
@@ -127,7 +127,7 @@
break;
default:
// Case 2: The current token is after FROM and before '.'.
- if (t != IDENT && input.LA(-1) == FROM && input.LA(2) == DOT)
+ if (t != IDENT && input.LA(-1) == FROM && ((input.LA(2) == DOT) || (input.LA(2) == IDENT) || (input.LA(2) == -1)))
{
HqlToken hqlToken = (HqlToken)input.LT(1);
if (hqlToken.PossibleId)
Modified: trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/HqlToken.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/HqlToken.cs 2009-12-01 21:03:41 UTC (rev 4885)
+++ trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/HqlToken.cs 2009-12-01 22:08:23 UTC (rev 4886)
@@ -23,6 +23,20 @@
}
/// <summary>
+ /// Public constructor
+ /// </summary>
+ public HqlToken(IToken other)
+ : base(other)
+ {
+ var hqlToken = other as HqlToken;
+
+ if (hqlToken != null)
+ {
+ _previousTokenType = hqlToken._previousTokenType;
+ }
+ }
+
+ /// <summary>
/// Indicates if the token could be an identifier.
/// </summary>
public bool PossibleId
Modified: trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/QueryTranslatorImpl.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/QueryTranslatorImpl.cs 2009-12-01 21:03:41 UTC (rev 4885)
+++ trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/QueryTranslatorImpl.cs 2009-12-01 22:08:23 UTC (rev 4886)
@@ -46,12 +46,12 @@
/// <param name="factory">The session factory constructing this translator instance.</param>
public QueryTranslatorImpl(
string queryIdentifier,
- string query,
+ HqlParseEngine parsedQuery,
IDictionary<string, IFilter> enabledFilters,
ISessionFactoryImplementor factory)
{
_queryIdentifier = queryIdentifier;
- _hql = query;
+ _parser = parsedQuery;
_compiled = false;
_shallowQuery = false;
_enabledFilters = enabledFilters;
@@ -466,7 +466,7 @@
}
}
- internal class HqlParseEngine
+ public class HqlParseEngine
{
private static readonly ILog log = LogManager.GetLogger(typeof(HqlParseEngine));
@@ -581,7 +581,7 @@
}
}
- internal class HqlSqlTranslator
+ internal class HqlSqlTranslator
{
private readonly IASTNode _inputAst;
private readonly CommonTokenStream _tokens;
Modified: trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/Tree/ASTNode.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/Tree/ASTNode.cs 2009-12-01 21:03:41 UTC (rev 4885)
+++ trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/Tree/ASTNode.cs 2009-12-01 22:08:23 UTC (rev 4886)
@@ -33,10 +33,9 @@
_startIndex = -1;
_stopIndex = -1;
_childIndex = -1;
- _token = other._token;
+ _token = new HqlToken(other._token);
_startIndex = other._startIndex;
_stopIndex = other._stopIndex;
-
}
public bool IsNil
Modified: trunk/nhibernate/src/NHibernate/Hql/Classic/ClassicQueryTranslatorFactory.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Hql/Classic/ClassicQueryTranslatorFactory.cs 2009-12-01 21:03:41 UTC (rev 4885)
+++ trunk/nhibernate/src/NHibernate/Hql/Classic/ClassicQueryTranslatorFactory.cs 2009-12-01 22:08:23 UTC (rev 4886)
@@ -1,4 +1,6 @@
using System.Collections.Generic;
+using System.Linq;
+using Iesi.Collections.Generic;
using NHibernate.Engine;
namespace NHibernate.Hql.Classic
@@ -8,20 +10,25 @@
/// </summary>
public class ClassicQueryTranslatorFactory : IQueryTranslatorFactory
{
- #region IQueryTranslatorFactory Members
-
- public IQueryTranslator CreateQueryTranslator(string queryIdentifier, string queryString, IDictionary<string, IFilter> filters,
- ISessionFactoryImplementor factory)
+ public IQueryTranslator[] CreateQueryTranslators(string queryString, string collectionRole, bool shallow, IDictionary<string, IFilter> filters, ISessionFactoryImplementor factory)
{
- return new QueryTranslator(queryIdentifier, queryString, filters, factory);
- }
+ var translators = QuerySplitter.ConcreteQueries(queryString, factory)
+ .Select(hql => new QueryTranslator(queryString, hql, filters, factory))
+ .ToArray();
- public IFilterTranslator CreateFilterTranslator(string queryIdentifier, string queryString, IDictionary<string, IFilter> filters,
- ISessionFactoryImplementor factory)
- {
- return new QueryTranslator(queryIdentifier, queryString, filters, factory);
+ foreach (var translator in translators)
+ {
+ if (collectionRole == null)
+ {
+ translator.Compile(factory.Settings.QuerySubstitutions, shallow);
+ }
+ else
+ {
+ translator.Compile(collectionRole, factory.Settings.QuerySubstitutions, shallow);
+ }
+ }
+
+ return translators;
}
-
- #endregion
}
}
\ No newline at end of file
Modified: trunk/nhibernate/src/NHibernate/Hql/IQueryTranslatorFactory.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Hql/IQueryTranslatorFactory.cs 2009-12-01 21:03:41 UTC (rev 4885)
+++ trunk/nhibernate/src/NHibernate/Hql/IQueryTranslatorFactory.cs 2009-12-01 22:08:23 UTC (rev 4886)
@@ -1,4 +1,6 @@
+using System;
using System.Collections.Generic;
+using Iesi.Collections.Generic;
using NHibernate.Engine;
namespace NHibernate.Hql
@@ -13,31 +15,11 @@
/// Construct a <see cref="NHibernate.Hql.IQueryTranslator"/> instance
/// capable of translating an HQL query string.
/// </summary>
- /// <param name="queryIdentifier">
- /// The query-identifier (used in <see cref="NHibernate.Stat.QueryStatistics"/> collection).
- /// This is typically the same as the queryString parameter except for the case of
- /// split polymorphic queries which result in multiple physical sql queries.
- /// </param>
/// <param name="queryString">The query string to be translated</param>
/// <param name="filters">Currently enabled filters</param>
/// <param name="factory">The session factory</param>
/// <returns>An appropriate translator.</returns>
- IQueryTranslator CreateQueryTranslator(string queryIdentifier, string queryString, IDictionary<string, IFilter> filters, ISessionFactoryImplementor factory);
-
- /// <summary>
- /// Construct a <see cref="NHibernate.Hql.IFilterTranslator"/> instance capable of
- /// translating an HQL filter string.
- /// </summary>
- /// <param name="queryIdentifier">
- /// The query-identifier (used in <see cref="NHibernate.Stat.QueryStatistics"/> collection).
- /// This is typically the same as the queryString parameter except for the case of
- /// split polymorphic queries which result in multiple physical sql queries.
- /// </param>
- /// <param name="queryString">The query string to be translated</param>
- /// <param name="filters">Currently enabled filters</param>
- /// <param name="factory">The session factory</param>
- /// <returns>An appropriate translator.</returns>
- IFilterTranslator CreateFilterTranslator(string queryIdentifier, string queryString, IDictionary<string, IFilter> filters, ISessionFactoryImplementor factory);
+ IQueryTranslator[] CreateQueryTranslators(string queryString, string collectionRole, bool shallow, IDictionary<string, IFilter> filters, ISessionFactoryImplementor factory);
}
/// <summary>
@@ -59,6 +41,6 @@
/// <param name="filters">Currently enabled filters</param>
/// <param name="factory">The session factory</param>
/// <returns>An appropriate translator.</returns>
- IQueryTranslator CreateQueryTranslator(string queryIdentifier, IQueryExpression queryExpression, IDictionary<string, IFilter> filters, ISessionFactoryImplementor factory);
+ IQueryTranslator[] CreateQueryTranslators(string queryIdentifier, IQueryExpression queryExpression, string collectionRole, bool shallow, IDictionary<string, IFilter> filters, ISessionFactoryImplementor factory);
}
}
\ No newline at end of file
Modified: trunk/nhibernate/src/NHibernate/Impl/AbstractSessionImpl.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Impl/AbstractSessionImpl.cs 2009-12-01 21:03:41 UTC (rev 4885)
+++ trunk/nhibernate/src/NHibernate/Impl/AbstractSessionImpl.cs 2009-12-01 22:08:23 UTC (rev 4886)
@@ -290,7 +290,7 @@
}
}
- protected internal virtual HQLQueryPlan GetHQLQueryPlan(string query, bool shallow)
+ protected internal virtual IQueryPlan GetHQLQueryPlan(string query, bool shallow)
{
using (new SessionIdLoggingContext(SessionId))
{
@@ -298,7 +298,7 @@
}
}
- protected internal virtual HQLQueryPlan GetHQLQueryPlan(IQueryExpression queryExpression, bool shallow)
+ protected internal virtual IQueryExpressionPlan GetHQLQueryPlan(IQueryExpression queryExpression, bool shallow)
{
using (new SessionIdLoggingContext(SessionId))
{
Modified: trunk/nhibernate/src/NHibernate/Impl/SessionImpl.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Impl/SessionImpl.cs 2009-12-01 21:03:41 UTC (rev 4885)
+++ trunk/nhibernate/src/NHibernate/Impl/SessionImpl.cs 2009-12-01 22:08:23 UTC (rev 4886)
@@ -619,7 +619,7 @@
{
CheckAndUpdateSessionStatus();
queryParameters.ValidateParameters();
- HQLQueryPlan plan = GetHQLQueryPlan(query, false);
+ var plan = GetHQLQueryPlan(query, false);
AutoFlushIfRequired(plan.QuerySpaces);
bool success = false;
@@ -663,7 +663,7 @@
{
CheckAndUpdateSessionStatus();
queryParameters.ValidateParameters();
- HQLQueryPlan plan = GetHQLQueryPlan(queryExpression, false);
+ var plan = GetHQLQueryPlan(queryExpression, false);
AutoFlushIfRequired(plan.QuerySpaces);
bool success = false;
@@ -694,7 +694,7 @@
{
using (new SessionIdLoggingContext(SessionId))
{
- HQLQueryPlan plan = Factory.QueryPlanCache.GetHQLQueryPlan(query, scalar, enabledFilters);
+ var plan = Factory.QueryPlanCache.GetHQLQueryPlan(query, scalar, enabledFilters);
AutoFlushIfRequired(plan.QuerySpaces);
return plan.Translators;
}
@@ -730,7 +730,7 @@
{
CheckAndUpdateSessionStatus();
queryParameters.ValidateParameters();
- HQLQueryPlan plan = GetHQLQueryPlan(query, true);
+ var plan = GetHQLQueryPlan(query, true);
AutoFlushIfRequired(plan.QuerySpaces);
dontFlushFromFind++; //stops flush being called multiple times if this method is recursively called
@@ -751,7 +751,7 @@
{
CheckAndUpdateSessionStatus();
queryParameters.ValidateParameters();
- HQLQueryPlan plan = GetHQLQueryPlan(query, true);
+ var plan = GetHQLQueryPlan(query, true);
AutoFlushIfRequired(plan.QuerySpaces);
dontFlushFromFind++; //stops flush being called multiple times if this method is recursively called
@@ -2785,7 +2785,7 @@
{
CheckAndUpdateSessionStatus();
queryParameters.ValidateParameters();
- HQLQueryPlan plan = GetHQLQueryPlan(query, false);
+ var plan = GetHQLQueryPlan(query, false);
AutoFlushIfRequired(plan.QuerySpaces);
bool success = false;
Modified: trunk/nhibernate/src/NHibernate/Impl/StatelessSessionImpl.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Impl/StatelessSessionImpl.cs 2009-12-01 21:03:41 UTC (rev 4885)
+++ trunk/nhibernate/src/NHibernate/Impl/StatelessSessionImpl.cs 2009-12-01 22:08:23 UTC (rev 4886)
@@ -109,7 +109,7 @@
{
CheckAndUpdateSessionStatus();
queryParameters.ValidateParameters();
- HQLQueryPlan plan = GetHQLQueryPlan(query, false);
+ var plan = GetHQLQueryPlan(query, false);
bool success = false;
try
{
@@ -381,7 +381,7 @@
using (new SessionIdLoggingContext(SessionId))
{
// take the union of the query spaces (ie the queried tables)
- HQLQueryPlan plan = Factory.QueryPlanCache.GetHQLQueryPlan(query, scalar, EnabledFilters);
+ var plan = Factory.QueryPlanCache.GetHQLQueryPlan(query, scalar, EnabledFilters);
return plan.Translators;
}
}
@@ -964,7 +964,7 @@
{
CheckAndUpdateSessionStatus();
queryParameters.ValidateParameters();
- HQLQueryPlan plan = GetHQLQueryPlan(query, false);
+ var plan = GetHQLQueryPlan(query, false);
bool success = false;
int result;
try
Modified: trunk/nhibernate/src/NHibernate/Linq/Visitors/HqlGeneratorExpressionTreeVisitor.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Linq/Visitors/HqlGeneratorExpressionTreeVisitor.cs 2009-12-01 21:03:41 UTC (rev 4885)
+++ trunk/nhibernate/src/NHibernate/Linq/Visitors/HqlGeneratorExpressionTreeVisitor.cs 2009-12-01 22:08:23 UTC (rev 4886)
@@ -346,7 +346,7 @@
if (t.IsGenericType && t.GetGenericTypeDefinition() == typeof (NhQueryable<>))
{
- return _hqlTreeBuilder.Ident(t.GetGenericArguments()[0].Name);
+ return _hqlTreeBuilder.Ident(t.GetGenericArguments()[0].FullName);
}
}
Modified: trunk/nhibernate/src/NHibernate.Test/App.config
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/App.config 2009-12-01 21:03:41 UTC (rev 4885)
+++ trunk/nhibernate/src/NHibernate.Test/App.config 2009-12-01 22:08:23 UTC (rev 4886)
@@ -43,7 +43,9 @@
<bytecode-provider type="lcg"/>
<reflection-optimizer use="true"/>
<session-factory name="NHibernate.Test">
- <property name="connection.provider">NHibernate.Test.DebugConnectionProvider, NHibernate.Test</property>
+ <!--<property name="query.factory_class">NHibernate.Hql.Classic.ClassicQueryTranslatorFactory, NHibernate</property>
+-->
+ <property name="connection.provider">NHibernate.Test.DebugConnectionProvider, NHibernate.Test</property>
<property name="cache.provider_class">NHibernate.Cache.HashtableCacheProvider, NHibernate</property>
<property name="cache.use_query_cache">true</property>
<property name="query.startup_check">false</property>
Modified: trunk/nhibernate/src/NHibernate.Test/BulkManipulation/BaseFixture.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/BulkManipulation/BaseFixture.cs 2009-12-01 21:03:41 UTC (rev 4885)
+++ trunk/nhibernate/src/NHibernate.Test/BulkManipulation/BaseFixture.cs 2009-12-01 22:08:23 UTC (rev 4886)
@@ -39,7 +39,7 @@
public string GetSql(string query)
{
- var qt = new QueryTranslatorImpl(null, query, emptyfilters, sessions);
+ var qt = new QueryTranslatorImpl(null, new HqlParseEngine(query, false, sessions), emptyfilters, sessions);
qt.Compile(null, false);
return qt.SQLString;
}
Modified: trunk/nhibernate/src/NHibernate.Test/HQL/Ast/BaseFixture.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/HQL/Ast/BaseFixture.cs 2009-12-01 21:03:41 UTC (rev 4885)
+++ trunk/nhibernate/src/NHibernate.Test/HQL/Ast/BaseFixture.cs 2009-12-01 22:08:23 UTC (rev 4886)
@@ -39,7 +39,9 @@
public string GetSql(string query)
{
- var qt = new QueryTranslatorImpl(null, query, emptyfilters, sessions);
+ var parser = new HqlParseEngine(query, false, sessions);
+ parser.Parse();
+ var qt = new QueryTranslatorImpl(null, parser, emptyfilters, sessions);
qt.Compile(null, false);
return qt.SQLString;
}
Modified: trunk/nhibernate/src/NHibernate.Test/HQL/Ast/HqlFixture.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/HQL/Ast/HqlFixture.cs 2009-12-01 21:03:41 UTC (rev 4885)
+++ trunk/nhibernate/src/NHibernate.Test/HQL/Ast/HqlFixture.cs 2009-12-01 22:08:23 UTC (rev 4886)
@@ -12,7 +12,7 @@
{
protected HQLQueryPlan CreateQueryPlan(string hql, bool scalar)
{
- return new HQLQueryPlan(hql, scalar, new CollectionHelper.EmptyMapClass<string, IFilter>(), sessions);
+ return new HQLStringQueryPlan(hql, scalar, new CollectionHelper.EmptyMapClass<string, IFilter>(), sessions);
}
protected HQLQueryPlan CreateQueryPlan(string hql)
Modified: trunk/nhibernate/src/NHibernate.Test/Linq/MiscellaneousTextFixture.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/Linq/MiscellaneousTextFixture.cs 2009-12-01 21:03:41 UTC (rev 4885)
+++ trunk/nhibernate/src/NHibernate.Test/Linq/MiscellaneousTextFixture.cs 2009-12-01 22:08:23 UTC (rev 4886)
@@ -1,6 +1,7 @@
using System;
using System.Linq;
using System.Linq.Expressions;
+using NHibernate.Linq;
using NHibernate.Test.Linq.Entities;
using NUnit.Framework;
@@ -97,5 +98,20 @@
Assert.AreNotEqual(firstResultOnPage3.ProductId, firstResultOnPage4.ProductId);
Assert.AreNotEqual(firstResultOnPage2.ProductId, firstResultOnPage4.ProductId);
}
+
+ [Test]
+ public void SelectFromObject()
+ {
+ using (var s = OpenSession())
+ {
+ var hql = s.CreateQuery("from System.Object o").List();
+
+ var r = from o in s.Query<object>() select o;
+
+ var l = r.ToList();
+
+ Console.WriteLine(l.Count);
+ }
+ }
}
}
Modified: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1849/Fixture.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1849/Fixture.cs 2009-12-01 21:03:41 UTC (rev 4885)
+++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1849/Fixture.cs 2009-12-01 22:08:23 UTC (rev 4886)
@@ -39,7 +39,7 @@
{
string hql = @"from Customer c where contains(c.Name, :smth)";
- HQLQueryPlan plan = new HQLQueryPlan(hql, false, new CollectionHelper.EmptyMapClass<string, IFilter>(), sessions);
+ HQLQueryPlan plan = new HQLStringQueryPlan(hql, false, new CollectionHelper.EmptyMapClass<string, IFilter>(), sessions);
Assert.AreEqual(1, plan.ParameterMetadata.NamedParameterNames.Count);
Assert.AreEqual(1, plan.QuerySpaces.Count);
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|