From: Peter S. <sz...@us...> - 2004-04-14 11:36:05
|
Update of /cvsroot/nhibernate/nhibernate/src/NHibernate/Hql In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv12026/NHibernate/Hql Modified Files: ClauseParser.cs FilterTranslator.cs FromParser.cs GroupByParser.cs HavingParser.cs IParser.cs OrderByParser.cs ParserHelper.cs PathExpressionParser.cs PreprocessingParser.cs SelectParser.cs SelectPathExpressionParser.cs WhereParser.cs Log Message: Syncing HQL, not ready yet. Index: ParserHelper.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Hql/ParserHelper.cs,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** ParserHelper.cs 18 Apr 2003 15:32:39 -0000 1.5 --- ParserHelper.cs 14 Apr 2004 11:35:53 -0000 1.6 *************** *** 3,8 **** using NHibernate.Util; ! namespace NHibernate.Hql { ! public class ParserHelper { public const string HqlVariablePrefix = ":"; --- 3,10 ---- using NHibernate.Util; ! namespace NHibernate.Hql ! { ! public class ParserHelper ! { public const string HqlVariablePrefix = ":"; *************** *** 12,26 **** public const string Whitespace = " \n\r\f\t"; ! public static bool IsWhitespace(string str) { return Whitespace.IndexOf(str) > - 1; } ! private ParserHelper() { } ! public static void Parse(IParser p, string text, string seperators, QueryTranslator q) { StringTokenizer tokens = new StringTokenizer(text, seperators, true); p.Start(q); ! foreach(string token in tokens) { p.Token(token, q); } --- 14,32 ---- public const string Whitespace = " \n\r\f\t"; ! public static bool IsWhitespace(string str) ! { return Whitespace.IndexOf(str) > - 1; } ! private ParserHelper() ! { } ! public static void Parse(IParser p, string text, string seperators, QueryTranslator q) ! { StringTokenizer tokens = new StringTokenizer(text, seperators, true); p.Start(q); ! foreach(string token in tokens) ! { p.Token(token, q); } Index: HavingParser.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Hql/HavingParser.cs,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** HavingParser.cs 13 Mar 2003 21:58:48 -0000 1.3 --- HavingParser.cs 14 Apr 2004 11:35:53 -0000 1.4 *************** *** 1,3 **** - //$Id$ using System; --- 1,2 ---- Index: ClauseParser.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Hql/ClauseParser.cs,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** ClauseParser.cs 13 Mar 2003 21:58:48 -0000 1.3 --- ClauseParser.cs 14 Apr 2004 11:35:53 -0000 1.4 *************** *** 1,6 **** - //$Id$ using System; using System.Collections; using NHibernate; namespace NHibernate.Hql { --- 1,6 ---- using System; using System.Collections; using NHibernate; + using NHibernate.Util; namespace NHibernate.Hql { *************** *** 15,65 **** private bool cacheSelectTokens = false; private bool byExpected = false; ! private bool enableSubselect = false; public virtual void Token(string token, QueryTranslator q) { string lcToken = token.ToLower(); if (byExpected && !lcToken.Equals("by")) { throw new QueryException("BY expected after GROUP or ORDER: " + token); } ! ! if (!enableSubselect && lcToken.Equals("select")) { ! selectTokens = new ArrayList(); ! cacheSelectTokens = true; ! } else if (!enableSubselect && lcToken.Equals("from")) { ! child = new FromParser(); ! child.Start(q); ! cacheSelectTokens = false; ! } else if (!enableSubselect && lcToken.Equals("where")) { ! enableSubselect = true; ! EndChild(q); ! child = new WhereParser(); ! child.Start(q); ! } else if (lcToken.Equals("order")) { ! EndChild(q); ! child = new OrderByParser(); ! byExpected = true; ! } else if (lcToken.Equals("having")) { ! EndChild(q); ! enableSubselect = true; ! child = new HavingParser(); ! child.Start(q); ! } else if (lcToken.Equals("group")) { ! EndChild(q); ! child = new GroupByParser(); ! byExpected = true; ! } else if (lcToken.Equals("by")) { ! if (!byExpected) throw new QueryException("GROUP or ORDER expected before BY"); ! child.Start(q); ! byExpected = false; ! } else { ! if (cacheSelectTokens) { selectTokens.Add(token); ! } else { ! if (child == null) { throw new QueryException("query must begin with SELECT or FROM: " + token); } ! else { child.Token(token, q); } --- 15,101 ---- private bool cacheSelectTokens = false; private bool byExpected = false; ! private int parenCount = 0; public virtual void Token(string token, QueryTranslator q) { string lcToken = token.ToLower(); + if ( token.Equals(StringHelper.OpenParen ) ) + { + parenCount++; + } + else if ( token.Equals(StringHelper.ClosedParen ) ) + { + parenCount--; + } + if (byExpected && !lcToken.Equals("by")) { throw new QueryException("BY expected after GROUP or ORDER: " + token); } ! bool isClauseStart = parenCount==0; //ignore subselect keywords ! ! if (isClauseStart) ! { ! if (lcToken.Equals("select")) ! { ! selectTokens = new ArrayList(); ! cacheSelectTokens = true; ! } ! else if (lcToken.Equals("from")) ! { ! child = new FromParser(); ! child.Start(q); ! cacheSelectTokens = false; ! } ! else if (lcToken.Equals("where")) ! { ! EndChild(q); ! child = new WhereParser(); ! child.Start(q); ! } ! else if (lcToken.Equals("order")) ! { ! EndChild(q); ! child = new OrderByParser(); ! byExpected = true; ! } ! else if (lcToken.Equals("having")) ! { ! EndChild(q); ! child = new HavingParser(); ! child.Start(q); ! } ! else if (lcToken.Equals("group")) ! { ! EndChild(q); ! child = new GroupByParser(); ! byExpected = true; ! } ! else if (lcToken.Equals("by")) ! { ! if (!byExpected) throw new QueryException("GROUP or ORDER expected before BY"); ! child.Start(q); ! byExpected = false; ! } ! else ! { ! isClauseStart = false; ! } ! } ! ! if (!isClauseStart) ! { ! if (cacheSelectTokens) ! { selectTokens.Add(token); ! } ! else ! { ! if (child == null) ! { throw new QueryException("query must begin with SELECT or FROM: " + token); } ! else ! { child.Token(token, q); } *************** *** 68,95 **** } ! private void EndChild(QueryTranslator q) { ! if (child == null) { //null child could occur for no from clause in a filter cacheSelectTokens = false; ! } else { child.End(q); } } ! public virtual void Start(QueryTranslator q) { } ! public virtual void End(QueryTranslator q) { EndChild(q); ! if (selectTokens != null) { child = new SelectParser(); child.Start(q); ! foreach (string item in selectTokens) { Token(item, q); } child.End(q); } ! byExpected = false; ! enableSubselect = false; cacheSelectTokens = false; } --- 104,139 ---- } ! private void EndChild(QueryTranslator q) ! { ! if (child == null) ! { //null child could occur for no from clause in a filter cacheSelectTokens = false; ! } ! else ! { child.End(q); } } ! public virtual void Start(QueryTranslator q) ! { } ! public virtual void End(QueryTranslator q) ! { EndChild(q); ! if (selectTokens != null) ! { child = new SelectParser(); child.Start(q); ! foreach (string item in selectTokens) ! { Token(item, q); } child.End(q); } ! byExpected = false; ! parenCount = 0; cacheSelectTokens = false; } Index: OrderByParser.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Hql/OrderByParser.cs,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** OrderByParser.cs 13 Mar 2003 21:58:48 -0000 1.3 --- OrderByParser.cs 14 Apr 2004 11:35:53 -0000 1.4 *************** *** 1,12 **** - //$Id$ using System; using System.Collections; using NHibernate.Util; ! namespace NHibernate.Hql { /// <summary> /// Parses the ORDER BY clause of a query /// </summary> ! public class OrderByParser : IParser { // This uses a PathExpressionParser but notice that compound paths are not valid, // only bare names and simple paths: --- 1,13 ---- using System; using System.Collections; using NHibernate.Util; ! namespace NHibernate.Hql ! { /// <summary> /// Parses the ORDER BY clause of a query /// </summary> ! public class OrderByParser : IParser ! { // This uses a PathExpressionParser but notice that compound paths are not valid, // only bare names and simple paths: *************** *** 19,37 **** private PathExpressionParser pathExpressionParser = new PathExpressionParser(); ! public void Token(string token, QueryTranslator q) { ! if (q.IsName(StringHelper.Root(token))) { ParserHelper.Parse(pathExpressionParser, q.Unalias(token), ParserHelper.PathSeparators, q); q.AppendOrderByToken(pathExpressionParser.WhereColumn); pathExpressionParser.AddAssociation(q); ! } else { q.AppendOrderByToken(token); } } ! public void Start(QueryTranslator q) { } ! public void End(QueryTranslator q) { } } --- 20,49 ---- private PathExpressionParser pathExpressionParser = new PathExpressionParser(); ! public void Token(string token, QueryTranslator q) ! { ! if (q.IsName(StringHelper.Root(token))) ! { ParserHelper.Parse(pathExpressionParser, q.Unalias(token), ParserHelper.PathSeparators, q); q.AppendOrderByToken(pathExpressionParser.WhereColumn); pathExpressionParser.AddAssociation(q); ! } ! else ! { q.AppendOrderByToken(token); } } ! public void Start(QueryTranslator q) ! { } ! public void End(QueryTranslator q) ! { ! } ! ! public OrderByParser() ! { ! pathExpressionParser.UseThetaStyleJoin = true; } } Index: FilterTranslator.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Hql/FilterTranslator.cs,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** FilterTranslator.cs 23 Apr 2003 14:41:17 -0000 1.4 --- FilterTranslator.cs 14 Apr 2004 11:35:53 -0000 1.5 *************** *** 1,3 **** - //$Id$ using System; using System.Collections; --- 1,2 ---- Index: IParser.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Hql/IParser.cs,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** IParser.cs 13 Mar 2003 21:58:48 -0000 1.3 --- IParser.cs 14 Apr 2004 11:35:53 -0000 1.4 *************** *** 1,3 **** - //$Id$ using System; --- 1,2 ---- Index: GroupByParser.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Hql/GroupByParser.cs,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** GroupByParser.cs 13 Mar 2003 21:58:48 -0000 1.3 --- GroupByParser.cs 14 Apr 2004 11:35:53 -0000 1.4 *************** *** 1,3 **** - //$Id$ using System; using System.Collections; --- 1,2 ---- *************** *** 5,14 **** using NHibernate.Util; ! namespace NHibernate.Hql { /// <summary> /// Parses the GROUP BY clause of an aggregate query /// </summary> ! public class GroupByParser : IParser { //this is basically a copy/paste of OrderByParser ... might be worth refactoring --- 4,15 ---- using NHibernate.Util; ! namespace NHibernate.Hql ! { /// <summary> /// Parses the GROUP BY clause of an aggregate query /// </summary> ! public class GroupByParser : IParser ! { //this is basically a copy/paste of OrderByParser ... might be worth refactoring *************** *** 23,41 **** private PathExpressionParser pathExpressionParser = new PathExpressionParser(); ! public void Token(string token, QueryTranslator q) { ! if (q.IsName(StringHelper.Root(token))) { ParserHelper.Parse(pathExpressionParser, q.Unalias(token), ParserHelper.PathSeparators, q); q.AppendGroupByToken(pathExpressionParser.WhereColumn); pathExpressionParser.AddAssociation(q); ! } else { q.AppendGroupByToken(token); } } ! public void Start(QueryTranslator q) { } ! public void End(QueryTranslator q) { } } --- 24,53 ---- private PathExpressionParser pathExpressionParser = new PathExpressionParser(); ! public void Token(string token, QueryTranslator q) ! { ! if (q.IsName(StringHelper.Root(token))) ! { ParserHelper.Parse(pathExpressionParser, q.Unalias(token), ParserHelper.PathSeparators, q); q.AppendGroupByToken(pathExpressionParser.WhereColumn); pathExpressionParser.AddAssociation(q); ! } ! else ! { q.AppendGroupByToken(token); } } ! public void Start(QueryTranslator q) ! { } ! public void End(QueryTranslator q) ! { ! } ! ! public GroupByParser() ! { ! pathExpressionParser.UseThetaStyleJoin = true; } } Index: PathExpressionParser.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Hql/PathExpressionParser.cs,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** PathExpressionParser.cs 10 Feb 2004 18:31:07 -0000 1.9 --- PathExpressionParser.cs 14 Apr 2004 11:35:53 -0000 1.10 *************** *** 9,18 **** using NHibernate.Sql; ! namespace NHibernate.Hql { /// <summary> /// Parses an expression of the form foo.bar.baz and builds up an expression /// involving two less table joins than there are path components. /// </summary> ! public class PathExpressionParser : IParser { //TODO: this class does too many things! we need a different --- 9,20 ---- using NHibernate.Sql; ! namespace NHibernate.Hql ! { /// <summary> /// Parses an expression of the form foo.bar.baz and builds up an expression /// involving two less table joins than there are path components. /// </summary> ! public class PathExpressionParser : IParser ! { //TODO: this class does too many things! we need a different *************** *** 33,37 **** protected string currentName; protected string currentProperty; ! protected JoinFragment join; protected string[] columns; protected string[] collectionElementColumns; --- 35,39 ---- protected string currentName; protected string currentProperty; ! protected QueryJoinFragment join; protected string[] columns; protected string[] collectionElementColumns; *************** *** 39,62 **** private string collectionRole; private string collectionTable; protected IType collectionElementType; private string componentPath; protected IType type; private string path; - private bool skippedId; private bool ignoreInitialJoin; private bool continuation; private JoinType joinType = JoinType.InnerJoin; //default mode ! public JoinType JoinType { ! get { return joinType; } ! set { joinType = value; } } ! private void AddJoin(string table, string name, string[] rhsCols, QueryTranslator q) { string[] lhsCols = CurrentColumns(q); join.AddJoin(table, name, lhsCols, rhsCols, joinType); } ! public string ContinueFromManyToMany(System.Type clazz, string[] joinColumns, QueryTranslator q) { Start(q); continuation = true; --- 41,86 ---- private string collectionRole; private string collectionTable; + private string collectionOwnerName; protected IType collectionElementType; private string componentPath; protected IType type; private string path; private bool ignoreInitialJoin; private bool continuation; private JoinType joinType = JoinType.InnerJoin; //default mode + private bool useThetaStyleJoin = true; ! public JoinType JoinType ! { ! get ! { ! return joinType; ! } ! set ! { ! joinType = value; ! } } ! public bool UseThetaStyleJoin ! { ! get ! { ! return useThetaStyleJoin; ! } ! set ! { ! useThetaStyleJoin = value; ! } ! } ! ! private void AddJoin(string table, string name, string[] rhsCols, QueryTranslator q) ! { string[] lhsCols = CurrentColumns(q); join.AddJoin(table, name, lhsCols, rhsCols, joinType); } ! public string ContinueFromManyToMany(System.Type clazz, string[] joinColumns, QueryTranslator q) ! { Start(q); continuation = true; *************** *** 68,123 **** } ! public void IgnoreInitialJoin() { ignoreInitialJoin = true; } ! public void Token(string token, QueryTranslator q) { ! if (token!=null) path += token; string alias = q.GetPathAlias(path); ! if (alias != null) { Reset(q); //reset the dotcount (but not the path) currentName = alias; //after reset! ! if(!ignoreInitialJoin) { JoinFragment ojf = q.GetPathJoin(path); join.AddCondition( ojf.ToWhereFragmentString ); //after reset! } ! } else if (".".Equals(token)) { dotcount++; ! } else { ! if (dotcount == 0) { ! if (!continuation) { if (!q.IsName(token)) throw new QueryException("undefined alias: " + token); currentName = token; } ! } else if (dotcount == 1) { ! if (currentName != null) { currentProperty = token; ! } else if (collectionName != null) { CollectionPersister p = q.GetCollectionPersister(collectionRole); DoCollectionProperty(token, p, collectionName); continuation = false; ! } else { throw new QueryException("unexpected"); } ! } else { // dotcount>=2 // Do the corresponding RHS IType propertyType = GetPropertyType(q); ! if (propertyType == null) { throw new QueryException("unresolved property: " + currentProperty); } ! if (propertyType.IsComponentType || propertyType.IsObjectType) { ! if (componentPath == null) { componentPath = token; ! } else { ! componentPath += StringHelper.Dot + token; } ! } else { ! ! if (propertyType.IsEntityType) { System.Type memberClass = ((EntityType) propertyType).PersistentClass; IQueryable memberPersister = q.GetPersister(memberClass); --- 92,176 ---- } ! public void IgnoreInitialJoin() ! { ignoreInitialJoin = true; } ! public void Token(string token, QueryTranslator q) ! { if (token!=null) path += token; string alias = q.GetPathAlias(path); ! if (alias != null) ! { Reset(q); //reset the dotcount (but not the path) currentName = alias; //after reset! ! if(!ignoreInitialJoin) ! { JoinFragment ojf = q.GetPathJoin(path); join.AddCondition( ojf.ToWhereFragmentString ); //after reset! + // we don't need to worry about any condition in the ON clause + // here (toFromFragmentString), since anything in the ON condition + // is already applied to the whole query } ! } ! else if (".".Equals(token)) ! { dotcount++; ! } ! else ! { ! if (dotcount == 0) ! { ! if (!continuation) ! { if (!q.IsName(token)) throw new QueryException("undefined alias: " + token); currentName = token; } ! } ! else if (dotcount == 1) ! { ! if (currentName != null) ! { currentProperty = token; ! } ! else if (collectionName != null) ! { CollectionPersister p = q.GetCollectionPersister(collectionRole); DoCollectionProperty(token, p, collectionName); continuation = false; ! } ! else ! { throw new QueryException("unexpected"); } ! } ! else ! { // dotcount>=2 // Do the corresponding RHS IType propertyType = GetPropertyType(q); ! if (propertyType == null) ! { throw new QueryException("unresolved property: " + currentProperty); } ! if (propertyType.IsComponentType || propertyType.IsObjectType) ! { ! if (componentPath == null) ! { componentPath = token; ! } ! else ! { ! if (token != null) ! componentPath += StringHelper.Dot + token; } ! } ! else ! { ! if (propertyType.IsEntityType) ! { System.Type memberClass = ((EntityType) propertyType).PersistentClass; IQueryable memberPersister = q.GetPersister(memberClass); *************** *** 125,135 **** // if its "id" EntityID.Equals(token) || ( ! //or its the id property name ! memberPersister.HasIdentifierProperty && ! memberPersister.IdentifierPropertyName.Equals(token))) { // special shortcut for id properties, skip the join! // this must only occur at the _end_ of a path expression ! skippedId = true; ! } else { string name = q.CreateNameFor(memberClass); --- 178,198 ---- // if its "id" EntityID.Equals(token) || ( ! //or its the id property name ! memberPersister.HasIdentifierProperty && ! memberPersister.IdentifierPropertyName.Equals(token))) ! { // special shortcut for id properties, skip the join! // this must only occur at the _end_ of a path expression ! if (componentPath == null) ! { ! componentPath = "id"; ! } ! else ! { ! componentPath += ".id"; ! } ! } ! else ! { string name = q.CreateNameFor(memberClass); *************** *** 140,147 **** currentProperty = token; q.AddPathAliasAndJoin(path.Substring(0, (path.LastIndexOf((System.Char) StringHelper.Dot)) - (0)), name, join); ! } ! componentPath = null; ! } else if (propertyType.IsPersistentCollectionType) { collectionRole = ((PersistentCollectionType) propertyType).Role; --- 203,211 ---- currentProperty = token; q.AddPathAliasAndJoin(path.Substring(0, (path.LastIndexOf((System.Char) StringHelper.Dot)) - (0)), name, join); ! componentPath = null; } ! } ! else if (propertyType.IsPersistentCollectionType) ! { collectionRole = ((PersistentCollectionType) propertyType).Role; *************** *** 150,163 **** string name = q.CreateNameForCollection(collectionRole); - AddJoin( p.QualifiedTableName, name, colNames, q); if ( p.HasWhere ) join.AddCondition( p.GetSQLWhereString(name) ); DoCollectionProperty(token, p, name); collectionName = name; collectionTable = p.QualifiedTableName; currentName = null; currentProperty = null; componentPath = null; ! } else { if (token != null) throw new QueryException("dereferenced: " + currentProperty); } --- 214,229 ---- string name = q.CreateNameForCollection(collectionRole); AddJoin( p.QualifiedTableName, name, colNames, q); if ( p.HasWhere ) join.AddCondition( p.GetSQLWhereString(name) ); DoCollectionProperty(token, p, name); collectionName = name; + collectionOwnerName = currentName; collectionTable = p.QualifiedTableName; currentName = null; currentProperty = null; componentPath = null; ! } ! else ! { if (token != null) throw new QueryException("dereferenced: " + currentProperty); } *************** *** 169,179 **** } ! private string PropertyPath { ! get { ! if (currentProperty == null) { return EntityID; ! } else { return currentProperty + - (skippedId ? StringHelper.Dot + EntityID : String.Empty) + ((componentPath == null) ? String.Empty : StringHelper.Dot + componentPath); } --- 235,249 ---- } ! private string PropertyPath ! { ! get ! { ! if (currentProperty == null) ! { return EntityID; ! } ! else ! { return currentProperty + ((componentPath == null) ? String.Empty : StringHelper.Dot + componentPath); } *************** *** 181,194 **** } ! private void SetType(QueryTranslator q) { ! if (currentProperty == null) { IClassPersister p = q.GetPersisterForName(currentName); type = NHibernate.Association(p.MappedClass); ! } else { type = GetPropertyType(q); } } ! protected IType GetPropertyType(QueryTranslator q) { string path = PropertyPath; IType type = q.GetPersisterForName(currentName).GetPropertyType(path); --- 251,270 ---- } ! private void SetType(QueryTranslator q) ! { ! if (currentProperty == null) ! { IClassPersister p = q.GetPersisterForName(currentName); + //TODO: entity == assoc?? type = NHibernate.Association(p.MappedClass); ! } ! else ! { type = GetPropertyType(q); } } ! protected IType GetPropertyType(QueryTranslator q) ! { string path = PropertyPath; IType type = q.GetPersisterForName(currentName).GetPropertyType(path); *************** *** 200,204 **** } ! protected string[] CurrentColumns(QueryTranslator q) { string path = PropertyPath; string[] columns = q.GetPersisterForName(currentName).ToColumns(currentName, path); --- 276,281 ---- } ! protected string[] CurrentColumns(QueryTranslator q) ! { string path = PropertyPath; string[] columns = q.GetPersisterForName(currentName).ToColumns(currentName, path); *************** *** 207,212 **** } ! private void Reset(QueryTranslator q) { ! join = q.CreateJoinFragment(); dotcount = 0; currentName = null; --- 284,290 ---- } ! private void Reset(QueryTranslator q) ! { ! join = q.CreateJoinFragment(useThetaStyleJoin); dotcount = 0; currentName = null; *************** *** 222,231 **** columns = null; expectingCollectionIndex = false; - skippedId = false; continuation = false; } ! public void Start(QueryTranslator q) { ! if (!continuation) { Reset(q); path = String.Empty; --- 300,310 ---- columns = null; expectingCollectionIndex = false; continuation = false; } ! public void Start(QueryTranslator q) ! { ! if (!continuation) ! { Reset(q); path = String.Empty; *************** *** 233,251 **** } ! public virtual void End(QueryTranslator q) { ignoreInitialJoin = false; ! if ( IsCollectionValued ) { columns = collectionElementColumns; type = collectionElementType; ! } else { ! if (!continuation) { IType propertyType = GetPropertyType(q); ! if ( propertyType != null && propertyType.IsPersistentCollectionType ) { collectionRole = ((PersistentCollectionType) propertyType).Role; collectionName = q.CreateNameForCollection(collectionRole); } } ! if (collectionRole != null) { //special case; expecting: [index] --- 312,337 ---- } ! public virtual void End(QueryTranslator q) ! { ignoreInitialJoin = false; ! if ( IsCollectionValued ) ! { columns = collectionElementColumns; type = collectionElementType; ! } ! else ! { ! if (!continuation) ! { IType propertyType = GetPropertyType(q); ! if ( propertyType != null && propertyType.IsPersistentCollectionType ) ! { collectionRole = ((PersistentCollectionType) propertyType).Role; collectionName = q.CreateNameForCollection(collectionRole); } } ! if (collectionRole != null) ! { //special case; expecting: [index] *************** *** 256,261 **** if ( indexCols.Length!=1 ) throw new QueryException("composite-index appears in []: " + path); string[] keyCols = memberPersister.KeyColumnNames; ! if (!continuation) { AddJoin( memberPersister.QualifiedTableName, collectionName, keyCols, q); } --- 342,359 ---- if ( indexCols.Length!=1 ) throw new QueryException("composite-index appears in []: " + path); string[] keyCols = memberPersister.KeyColumnNames; + + JoinFragment ojf = q.CreateJoinFragment(useThetaStyleJoin); + ojf.AddCrossJoin( memberPersister.QualifiedTableName, collectionName ); + if ( memberPersister.IsOneToMany ) + { + ILoadable persister = q.GetPersister( ( (EntityType) memberPersister.ElementType ).PersistentClass ); + ojf.AddJoins( + persister.FromJoinFragment(collectionName, true, false), + persister.WhereJoinFragment(collectionName, true, false) + ); + } ! if (!continuation) ! { AddJoin( memberPersister.QualifiedTableName, collectionName, keyCols, q); } *************** *** 275,282 **** q.AddCollection(collectionName, collectionRole); - JoinFragment ojf = q.CreateJoinFragment(); - ojf.AddCrossJoin( memberPersister.QualifiedTableName, collectionName ); q.AddJoin(collectionName, ojf); ! } else { columns = CurrentColumns(q); SetType(q); --- 373,380 ---- q.AddCollection(collectionName, collectionRole); q.AddJoin(collectionName, ojf); ! } ! else ! { columns = CurrentColumns(q); SetType(q); *************** *** 290,294 **** } ! public sealed class CollectionElement { public IType Type; public bool IsOneToMany; --- 388,393 ---- } ! public sealed class CollectionElement ! { public IType Type; public bool IsOneToMany; *************** *** 302,344 **** private ArrayList collectionElements = new ArrayList(); ! public CollectionElement LastCollectionElement() { CollectionElement ce = (CollectionElement) collectionElements[collectionElements.Count-1]; collectionElements.RemoveAt(collectionElements.Count-1); return ce; //remove last } - public string LastCollectionElementIndexValue { - set { ((CollectionElement) collectionElements[collectionElements.Count-1]).IndexValue.Append(value); //getlast } } ! public bool IsExpectingCollectionIndex { ! get { return expectingCollectionIndex; } ! set { expectingCollectionIndex = value; } } ! protected virtual void SetExpectingCollectionIndex() { expectingCollectionIndex = true; } ! public JoinFragment WhereJoin { ! get { return join; } } ! public string WhereColumn { ! get { if (columns.Length != 1) throw new QueryException("path expression ends in a composite value"); return columns[0]; } } ! public string[] WhereColumns { ! get { return columns; } } ! public IType WhereColumnType { ! get { return type; } } ! public string Name { get { return currentName==null ? collectionName : currentName; } } ! public string GetCollectionSubquery() { return new StringBuilder("SELECT ") --- 401,476 ---- private ArrayList collectionElements = new ArrayList(); ! public CollectionElement LastCollectionElement() ! { CollectionElement ce = (CollectionElement) collectionElements[collectionElements.Count-1]; collectionElements.RemoveAt(collectionElements.Count-1); return ce; //remove last } + public string LastCollectionElementIndexValue + { + set + { ((CollectionElement) collectionElements[collectionElements.Count-1]).IndexValue.Append(value); //getlast } } ! ! public bool IsExpectingCollectionIndex ! { ! get ! { ! return expectingCollectionIndex; ! } ! set ! { ! expectingCollectionIndex = value; ! } } ! ! protected virtual void SetExpectingCollectionIndex() ! { expectingCollectionIndex = true; } ! public JoinFragment WhereJoin ! { ! get ! { ! return join; ! } } ! ! public string WhereColumn ! { ! get ! { if (columns.Length != 1) throw new QueryException("path expression ends in a composite value"); return columns[0]; } } ! ! public string[] WhereColumns ! { ! get ! { ! return columns; ! } } ! ! public IType WhereColumnType ! { ! get ! { ! return type; ! } } ! ! public string Name ! { get { return currentName==null ? collectionName : currentName; } } ! public string GetCollectionSubquery() ! { return new StringBuilder("SELECT ") *************** *** 354,371 **** } ! public bool IsCollectionValued { get { return collectionElementColumns!=null; } } ! public void AddAssociation(QueryTranslator q) { q.AddJoin( Name, join ); } ! public string AddFromAssociation(QueryTranslator q) { q.AddFrom(currentName, join); return currentName; } ! public string AddFromCollection(QueryTranslator q) { if ( collectionElementType==null ) throw new QueryException( "must specify 'elements' for collection valued property in from clause: " + path --- 486,507 ---- } ! public bool IsCollectionValued ! { get { return collectionElementColumns!=null; } } ! public void AddAssociation(QueryTranslator q) ! { q.AddJoin( Name, join ); } ! public string AddFromAssociation(QueryTranslator q) ! { q.AddFrom(currentName, join); return currentName; } ! public string AddFromCollection(QueryTranslator q) ! { if ( collectionElementType==null ) throw new QueryException( "must specify 'elements' for collection valued property in from clause: " + path *************** *** 379,385 **** string elementName; ! if ( persister.IsOneToMany ) { elementName = collectionName; ! } else { q.AddCollection(collectionName, collectionRole); ILoadable p = q.GetPersister(clazz); --- 515,524 ---- string elementName; ! if ( persister.IsOneToMany ) ! { elementName = collectionName; ! } ! else ! { q.AddCollection(collectionName, collectionRole); ILoadable p = q.GetPersister(clazz); *************** *** 393,420 **** } ! public string CollectionName { ! get { return collectionName; } } ! public string CollectionRole { ! get { return collectionRole; } } ! public string CollectionTable { ! get { return collectionTable; } } ! private void DoCollectionProperty(string token, CollectionPersister memberPersister, string name) { ! if (token.Equals(CollectionElements)) { string[] cols = memberPersister.ElementColumnNames; collectionElementColumns = StringHelper.Prefix(cols, name + StringHelper.Dot); collectionElementType = memberPersister.ElementType; ! } else if (token.Equals(CollectionIndices)) { if (!memberPersister.HasIndex) throw new QueryException("unindexed collection before .indices"); string[] cols = memberPersister.IndexColumnNames; collectionElementColumns = StringHelper.Prefix(cols, name + StringHelper.Dot); collectionElementType = memberPersister.IndexType; ! } else if (token.Equals(CollectionSize)) { collectionElementColumns = new string[] { "count(*)" }; collectionElementType = NHibernate.Int32; ! } else if (token.Equals(CollectionMaxIndex)) { if (!memberPersister.HasIndex) throw new QueryException("unindexed collection before .maxIndex"); string[] cols = memberPersister.IndexColumnNames; --- 532,579 ---- } ! public string CollectionName ! { ! get ! { ! return collectionName; ! } } ! public string CollectionRole ! { ! get ! { ! return collectionRole; ! } } ! public string CollectionTable ! { ! get ! { ! return collectionTable; ! } } ! private void DoCollectionProperty(string token, CollectionPersister memberPersister, string name) ! { ! if (token.Equals(CollectionElements)) ! { string[] cols = memberPersister.ElementColumnNames; collectionElementColumns = StringHelper.Prefix(cols, name + StringHelper.Dot); collectionElementType = memberPersister.ElementType; ! } ! else if (token.Equals(CollectionIndices)) ! { if (!memberPersister.HasIndex) throw new QueryException("unindexed collection before .indices"); string[] cols = memberPersister.IndexColumnNames; collectionElementColumns = StringHelper.Prefix(cols, name + StringHelper.Dot); collectionElementType = memberPersister.IndexType; ! } ! else if (token.Equals(CollectionSize)) ! { collectionElementColumns = new string[] { "count(*)" }; collectionElementType = NHibernate.Int32; ! } ! else if (token.Equals(CollectionMaxIndex)) ! { if (!memberPersister.HasIndex) throw new QueryException("unindexed collection before .maxIndex"); string[] cols = memberPersister.IndexColumnNames; *************** *** 422,426 **** collectionElementColumns = new string[] { "max(" + cols[0] + StringHelper.ClosedParen }; collectionElementType = memberPersister.IndexType; ! } else if (token.Equals(CollectionMinIndex)) { if (!memberPersister.HasIndex) throw new QueryException("unindexed collection before .minIndex"); string[] cols = memberPersister.IndexColumnNames; --- 581,587 ---- collectionElementColumns = new string[] { "max(" + cols[0] + StringHelper.ClosedParen }; collectionElementType = memberPersister.IndexType; ! } ! else if (token.Equals(CollectionMinIndex)) ! { if (!memberPersister.HasIndex) throw new QueryException("unindexed collection before .minIndex"); string[] cols = memberPersister.IndexColumnNames; *************** *** 428,446 **** collectionElementColumns = new string[] { "min(" + cols[0] + StringHelper.ClosedParen }; collectionElementType = memberPersister.IndexType; ! } else if (token.Equals(CollectionMaxElement)) { string[] cols = memberPersister.ElementColumnNames; if (cols.Length != 1) throw new QueryException("composite collection element in maxElement"); collectionElementColumns = new string[] {"max(" + cols[0] + StringHelper.ClosedParen }; collectionElementType = memberPersister.ElementType; ! } else if (token.Equals(CollectionMinElement)) { string[] cols = memberPersister.ElementColumnNames; if (cols.Length != 1) throw new QueryException("composite collection element in minElement"); collectionElementColumns = new string[] {"min(" + cols[0] + StringHelper.ClosedParen}; collectionElementType = memberPersister.ElementType; ! } else { throw new QueryException("expecting 'elements' or 'indices' after " + path); } } ! } } \ No newline at end of file --- 589,620 ---- collectionElementColumns = new string[] { "min(" + cols[0] + StringHelper.ClosedParen }; collectionElementType = memberPersister.IndexType; ! } ! else if (token.Equals(CollectionMaxElement)) ! { string[] cols = memberPersister.ElementColumnNames; if (cols.Length != 1) throw new QueryException("composite collection element in maxElement"); collectionElementColumns = new string[] {"max(" + cols[0] + StringHelper.ClosedParen }; collectionElementType = memberPersister.ElementType; ! } ! else if (token.Equals(CollectionMinElement)) ! { string[] cols = memberPersister.ElementColumnNames; if (cols.Length != 1) throw new QueryException("composite collection element in minElement"); collectionElementColumns = new string[] {"min(" + cols[0] + StringHelper.ClosedParen}; collectionElementType = memberPersister.ElementType; ! } ! else ! { throw new QueryException("expecting 'elements' or 'indices' after " + path); } } ! ! public String CollectionOwnerName ! { ! get ! { ! return collectionOwnerName; ! } ! } } } \ No newline at end of file Index: FromParser.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Hql/FromParser.cs,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** FromParser.cs 13 Mar 2003 21:58:48 -0000 1.3 --- FromParser.cs 14 Apr 2004 11:35:53 -0000 1.4 *************** *** 1,3 **** - //$Id$ using System; using System.Collections; --- 1,2 ---- *************** *** 24,27 **** --- 23,27 ---- private bool expectingAs; private bool afterJoinType; + private bool afterFetch; private ILoadable classPersister; private JoinType joinType = JoinType.None; *************** *** 40,78 **** // start by looking for HQL keywords.... string lcToken = token.ToLower(); ! if ( lcToken.Equals(StringHelper.Comma) ) { ! if (!expectingJoin) throw new QueryException("unexpected token: "); expectingJoin = false; ! } else if ( lcToken.Equals("join") ) { ! if (!afterJoinType) { ! if (!expectingJoin) throw new QueryException("unexpected token: join"); // inner joings can be abbreviated to 'join' joinType = JoinType.InnerJoin; expectingJoin = false; ! } else { afterJoinType = false; } ! } else if ( lcToken.Equals("outer") ) { // 'outer' is optional and is ignored) ! if ( !afterJoinType || (joinType!=JoinType.LeftOuterJoin && joinType!=JoinType.RightOuterJoin) ) { throw new QueryException("unexpected token: outer"); } ! } else if ( joinTypes.Contains(lcToken) ) { if (!expectingJoin) throw new QueryException("unexpected token: " + token); joinType = (JoinType) joinTypes[lcToken]; afterJoinType = true; expectingJoin = false; ! } else if (lcToken.Equals("class")) { if (!afterIn) throw new QueryException("unexpected token: class"); if (joinType!=JoinType.None) throw new QueryException("outer or full join must be followed by path expression"); afterClass = true; ! } else if ( lcToken.Equals("in") ) { if (!expectingIn) throw new QueryException("unexpected token: in"); afterIn = true; expectingIn = false; ! } else if ( lcToken.Equals("as") ) { if (!expectingAs) throw new QueryException("unexpected token: as"); afterAs = true; expectingAs = false; ! } else { if (afterJoinType) throw new QueryException("join expected: " + token); if (expectingJoin) throw new QueryException("unexpected token: " + token); --- 40,108 ---- // start by looking for HQL keywords.... string lcToken = token.ToLower(); ! if ( lcToken.Equals(StringHelper.Comma) ) ! { ! if (!expectingJoin) throw new QueryException("unexpected token: ,"); expectingJoin = false; ! expectingAs = false; ! } ! else if ( lcToken.Equals("join") ) ! { ! if (!afterJoinType) ! { ! if (!expectingJoin|expectingAs) throw new QueryException("unexpected token: join"); // inner joings can be abbreviated to 'join' joinType = JoinType.InnerJoin; expectingJoin = false; ! expectingAs = false; ! } ! else ! { afterJoinType = false; } ! } ! else if ( lcToken.Equals("fetch") ) ! { ! if ( q.IsShallowQuery ) throw new QueryException("fetch may not be used with scroll() or iterate()"); ! if (joinType==JoinType.None) throw new QueryException("unexpected token: fetch"); ! if (joinType==JoinType.FullJoin || joinType==JoinType.RightOuterJoin) ! throw new QueryException("fetch may only be used with inner join or left outer join"); ! afterFetch = true; ! } ! else if ( lcToken.Equals("outer") ) ! { // 'outer' is optional and is ignored) ! if ( !afterJoinType || (joinType!=JoinType.LeftOuterJoin && joinType!=JoinType.RightOuterJoin) ) ! { throw new QueryException("unexpected token: outer"); } ! } ! else if ( joinTypes.Contains(lcToken) ) ! { if (!expectingJoin) throw new QueryException("unexpected token: " + token); joinType = (JoinType) joinTypes[lcToken]; afterJoinType = true; expectingJoin = false; ! expectingAs = false; ! } ! else if (lcToken.Equals("class")) ! { if (!afterIn) throw new QueryException("unexpected token: class"); if (joinType!=JoinType.None) throw new QueryException("outer or full join must be followed by path expression"); afterClass = true; ! } ! else if ( lcToken.Equals("in") ) ! { if (!expectingIn) throw new QueryException("unexpected token: in"); afterIn = true; expectingIn = false; ! } ! else if ( lcToken.Equals("as") ) ! { if (!expectingAs) throw new QueryException("unexpected token: as"); afterAs = true; expectingAs = false; ! } ! else ! { if (afterJoinType) throw new QueryException("join expected: " + token); if (expectingJoin) throw new QueryException("unexpected token: " + token); *************** *** 81,85 **** // now anything that is not a HQL keyword ! if ( afterAs || expectingAs ) { // (AS is always optional, for consistentcy with SQL/OQL --- 111,116 ---- // now anything that is not a HQL keyword ! if ( afterAs || expectingAs ) ! { // (AS is always optional, for consistentcy with SQL/OQL *************** *** 88,96 **** // AS construction ! if (classPersister!=null) { q.AddFromClass(token, classPersister); ! } else if (entityName!=null) { q.SetAliasName(token, entityName); ! } else { throw new QueryException("unexpected: as " + token); } --- 119,132 ---- // AS construction ! if (classPersister!=null) ! { q.AddFromClass(token, classPersister); ! } ! else if (entityName!=null) ! { q.SetAliasName(token, entityName); ! } ! else ! { throw new QueryException("unexpected: as " + token); } *************** *** 101,105 **** classPersister = null; ! } else if (afterIn) { // process the "old" HQL style where aliases appear _first // ie using the IN or IN CLASS constructions --- 137,143 ---- classPersister = null; ! } ! else if (afterIn) ! { // process the "old" HQL style where aliases appear _first // ie using the IN or IN CLASS constructions *************** *** 108,118 **** if (joinType!=JoinType.None) throw new QueryException("outer or full join must be followed by path expressions"); ! if (afterClass) { // treat it as a classname ILoadable p = q.GetPersisterUsingImports(token); if (p==null) throw new QueryException("persister not found: " + token); q.AddFromClass(alias, p); ! } else { // treat it as a path expression ParserHelper.Parse(peParser, q.Unalias(token), ParserHelper.PathSeparators, q); if ( !peParser.IsCollectionValued ) throw new QueryException("pathe expression did not resolve to collection: " + token); --- 146,161 ---- if (joinType!=JoinType.None) throw new QueryException("outer or full join must be followed by path expressions"); ! if (afterClass) ! { // treat it as a classname ILoadable p = q.GetPersisterUsingImports(token); if (p==null) throw new QueryException("persister not found: " + token); q.AddFromClass(alias, p); ! } ! else ! { // treat it as a path expression + peParser.JoinType = JoinType.InnerJoin; + peParser.UseThetaStyleJoin = true; ParserHelper.Parse(peParser, q.Unalias(token), ParserHelper.PathSeparators, q); if ( !peParser.IsCollectionValued ) throw new QueryException("pathe expression did not resolve to collection: " + token); *************** *** 125,144 **** afterClass = false; expectingJoin = true; ! } else { // handle a path expression or class name that appears // at the start, in the "new" HQL style or an alias that // appears at the start in the "old HQL stype ILoadable p = q.GetPersisterUsingImports(token); ! if (p!=null) { // starts with the name of a mapped class (new style) if (joinType!=JoinType.None) throw new QueryException("outer or full join must be followed by path expression"); classPersister = p; expectingAs = true; ! } else if ( token.IndexOf('.') < 0 ) { // starts with an alias (old style) // semi-bad thing about this: can't re-alias another alias... alias = token; expectingIn = true; ! } else { // starts with a path expression (new style) --- 168,196 ---- afterClass = false; expectingJoin = true; ! } ! else ! { // handle a path expression or class name that appears // at the start, in the "new" HQL style or an alias that // appears at the start in the "old HQL stype ILoadable p = q.GetPersisterUsingImports(token); ! if (p!=null) ! { // starts with the name of a mapped class (new style) if (joinType!=JoinType.None) throw new QueryException("outer or full join must be followed by path expression"); classPersister = p; + entityName = q.CreateNameFor( p.MappedClass ); + q.AddFromClass( entityName, p ); expectingAs = true; ! } ! else if ( token.IndexOf('.') < 0 ) ! { // starts with an alias (old style) // semi-bad thing about this: can't re-alias another alias... alias = token; expectingIn = true; ! } ! else ! { // starts with a path expression (new style) *************** *** 146,160 **** //allow ODMG OQL style: from Person p, p.cars c ! if (joinType!=JoinType.None) peParser.JoinType = joinType; ParserHelper.Parse(peParser, q.Unalias(token), ParserHelper.PathSeparators, q); ! if ( peParser.IsCollectionValued ) { entityName = peParser.AddFromCollection(q); ! } else { entityName = peParser.AddFromAssociation(q); } - expectingAs = true; joinType = JoinType.None; peParser.JoinType = JoinType.InnerJoin; } } --- 198,236 ---- //allow ODMG OQL style: from Person p, p.cars c ! if (joinType!=JoinType.None) ! { ! peParser.JoinType = joinType; ! } ! else ! { ! peParser.JoinType = JoinType.InnerJoin; ! } ! peParser.UseThetaStyleJoin = q.IsSubquery; ParserHelper.Parse(peParser, q.Unalias(token), ParserHelper.PathSeparators, q); ! if ( peParser.IsCollectionValued ) ! { entityName = peParser.AddFromCollection(q); ! } ! else ! { entityName = peParser.AddFromAssociation(q); } joinType = JoinType.None; peParser.JoinType = JoinType.InnerJoin; + + if (afterFetch) + { + + if ( peParser.IsCollectionValued ) + { + q.SetCollectionToFetch( peParser.CollectionRole, peParser.CollectionName, peParser.CollectionOwnerName ); + } + q.addEntityToFetch(entityName); + + afterFetch = false; + } + + expectingAs = true; } } Index: SelectPathExpressionParser.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Hql/SelectPathExpressionParser.cs,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** SelectPathExpressionParser.cs 13 Mar 2003 21:58:49 -0000 1.3 --- SelectPathExpressionParser.cs 14 Apr 2004 11:35:53 -0000 1.4 *************** *** 1,12 **** - //$Id$ using System; using System.Collections; ! namespace NHibernate.Hql { ! public class SelectPathExpressionParser : PathExpressionParser { ! public override void End(QueryTranslator q) { ! if (currentProperty != null && !q.IsShallowQuery) { // "finish off" the join Token(".", q); --- 1,15 ---- using System; using System.Collections; ! namespace NHibernate.Hql ! { ! public class SelectPathExpressionParser : PathExpressionParser ! { ! public override void End(QueryTranslator q) ! { ! if (currentProperty != null && !q.IsShallowQuery) ! { // "finish off" the join Token(".", q); *************** *** 16,25 **** } ! protected override void SetExpectingCollectionIndex() { throw new QueryException("expecting .elements or .indices after collection path expression in select"); } ! public string SelectName { ! get { return currentName; } } } --- 19,33 ---- } ! protected override void SetExpectingCollectionIndex() ! { throw new QueryException("expecting .elements or .indices after collection path expression in select"); } ! public string SelectName ! { ! get ! { ! return currentName; ! } } } Index: WhereParser.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Hql/WhereParser.cs,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** WhereParser.cs 10 Feb 2004 18:31:07 -0000 1.8 --- WhereParser.cs 14 Apr 2004 11:35:53 -0000 1.9 *************** *** 8,12 **** using NHibernate.Sql; ! namespace NHibernate.Hql { /// <summary> Parses the where clause of a hibernate query and translates it to an /// SQL where clause. --- 8,13 ---- using NHibernate.Sql; ! namespace NHibernate.Hql ! { /// <summary> Parses the where clause of a hibernate query and translates it to an /// SQL where clause. *************** *** 23,27 **** // the same thing it does now) ! public class WhereParser : IParser { private PathExpressionParser pathExpressionParser = new PathExpressionParser(); --- 24,29 ---- // the same thing it does now) ! public class WhereParser : IParser ! { private PathExpressionParser pathExpressionParser = new PathExpressionParser(); *************** *** 32,36 **** private static IDictionary negations = new Hashtable(); ! static WhereParser() { expressionTerminators.Add("and"); expressionTerminators.Add("or"); --- 34,44 ---- private static IDictionary negations = new Hashtable(); ! public WhereParser() ! { ! pathExpressionParser.UseThetaStyleJoin = true; ! } ! ! static WhereParser() ! { expressionTerminators.Add("and"); expressionTerminators.Add("or"); *************** *** 124,130 **** // ( foo.Bar.Baz + 1.0 ) < 2.0 (maps to: ( bar.Baz + 1.0 ) < 2.0 and foo.Bar = bar.id) - //private bool quoted = false; //Inside a quoted string private bool betweenSpecialCase = false; //Inside a BETWEEN ... AND ... expression - //private int bracketsSinceFunction = 0; //How deep inside in IN are we? private bool negated = false; --- 132,136 ---- *************** *** 145,162 **** ! private string GetElementName(PathExpressionParser.CollectionElement element, QueryTranslator q) { string name; ! if (element.IsOneToMany) { name = element.Alias; } ! else { IType type = element.Type; System.Type clazz; ! if (type.IsEntityType) { //ie. a many-to-many clazz = ((EntityType) type).PersistentClass; name = pathExpressionParser.ContinueFromManyToMany(clazz, element.ElementColumns, q); ! } else { throw new QueryException("illegally dereferenced collection element"); } --- 151,174 ---- ! private string GetElementName(PathExpressionParser.CollectionElement element, QueryTranslator q) ! { string name; ! if (element.IsOneToMany) ! { name = element.Alias; } ! else ! { IType type = element.Type; System.Type clazz; ! if (type.IsEntityType) ! { //ie. a many-to-many clazz = ((EntityType) type).PersistentClass; name = pathExpressionParser.ContinueFromManyToMany(clazz, element.ElementColumns, q); ! } ! else ! { throw new QueryException("illegally dereferenced collection element"); } *************** *** 165,169 **** } ! public void Token(string token, QueryTranslator q) { string lcToken = token.ToLower(); --- 177,182 ---- } ! public void Token(string token, QueryTranslator q) ! { string lcToken = token.ToLower(); *************** *** 171,179 **** //Cope with [,] ! if (token.Equals("[") && !expectingPathContinuation) { expectingPathContinuation = false; if (expectingIndex == 0) throw new QueryException("unexpected ["); return ; ! } else if (token.Equals("]")) { expectingIndex--; expectingPathContinuation = true; --- 184,195 ---- //Cope with [,] ! if (token.Equals("[") && !expectingPathContinuation) ! { expectingPathContinuation = false; if (expectingIndex == 0) throw new QueryException("unexpected ["); return ; ! } ! else if (token.Equals("]")) ! { expectingIndex--; expectingPathContinuation = true; *************** *** 182,186 **** //Cope with a continued path expression (ie. ].baz) ! if (expectingPathContinuation) { expectingPathContinuation = false; --- 198,203 ---- //Cope with a continued path expression (ie. ].baz) ! if (expectingPathContinuation) ! { expectingPathContinuation = false; *************** *** 188,192 **** PathExpressionParser.CollectionElement element = pathExpressionParser.LastCollectionElement(); ! if (token.StartsWith(".")) { // the path expression continues after a ] DoPathExpression(GetElementName(element, q) + token, q); // careful with this! --- 205,210 ---- PathExpressionParser.CollectionElement element = pathExpressionParser.LastCollectionElement(); ! if (token.StartsWith(".")) ! { // the path expression continues after a ] DoPathExpression(GetElementName(element, q) + token, q); // careful with this! *************** *** 195,203 **** return ; //NOTE: EARLY EXIT! ! } else if (token.Equals("[")) { DoPathExpression(GetElementName(element, q), q); AddToCurrentJoin(element); return ; //NOTE: EARLY EXIT! ! } else { // the path expression ends at the ] if (element.ElementColumns.Length != 1) throw new QueryException("path expression ended in composite collection element"); --- 213,225 ---- return ; //NOTE: EARLY EXIT! ! } ! else if (token.Equals("[")) ! { DoPathExpression(GetElementName(element, q), q); AddToCurrentJoin(element); return ; //NOTE: EARLY EXIT! ! } ! else ! { // the path expression ends at the ] if (element.ElementColumns.Length != 1) throw new QueryException("path expression ended in composite collection element"); *************** *** 211,226 **** //Cope with a subselect ! if (!inSubselect && (lcToken.Equals("select") || lcToken.Equals("from"))) { inSubselect = true; subselect = new StringBuilder(20); } ! if (i... [truncated message content] |