Update of /cvsroot/hibernate/Hibernate2/src/net/sf/hibernate/hql In directory sc8-pr-cvs1:/tmp/cvs-serv11798/sf/hibernate/hql Modified Files: FromParser.java GroupByParser.java OrderByParser.java PathExpressionParser.java QueryTranslator.java SelectParser.java WhereParser.java Log Message: refactored hql package (incomplete) Index: FromParser.java =================================================================== RCS file: /cvsroot/hibernate/Hibernate2/src/net/sf/hibernate/hql/FromParser.java,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** FromParser.java 20 Jan 2003 12:48:10 -0000 1.4 --- FromParser.java 23 Feb 2003 01:32:20 -0000 1.5 *************** *** 2,6 **** --- 2,12 ---- package net.sf.hibernate.hql; + import java.util.HashSet; + import java.util.Set; + import net.sf.hibernate.QueryException; + import net.sf.hibernate.persister.Loadable; + import net.sf.hibernate.sql.OuterJoinFragment; + import net.sf.hibernate.sql.QueryOuterJoinFragment; import net.sf.hibernate.util.StringHelper; *************** *** 13,21 **** private boolean expectingIn; ! private boolean expectingComma; private boolean fromClass; private String name; private PathExpressionParser peParser = new PathExpressionParser(); public void token(String token, QueryTranslator q) throws QueryException { --- 19,36 ---- private boolean expectingIn; ! private boolean expectingJoin; ! private boolean expectingJoinToken; private boolean fromClass; + private String joinType; private String name; private PathExpressionParser peParser = new PathExpressionParser(); + private static final Set joinTokens = new HashSet(); + static { + joinTokens.add("left"); + joinTokens.add("right"); + joinTokens.add("full"); + } + public void token(String token, QueryTranslator q) throws QueryException { *************** *** 32,39 **** } } ! else if (expectingComma) { if ( token.equals(StringHelper.COMMA) ) { ! expectingComma = false; fromClass = false; } else { --- 47,65 ---- } } ! else if (expectingJoin) { if ( token.equals(StringHelper.COMMA) ) { ! expectingJoin = false; ! fromClass = false; ! joinType = StringHelper.COMMA; ! } ! else if ( lcToken.equals("join") ) { ! joinType += ' ' + lcToken; ! expectingJoin = false; fromClass = false; + expectingJoinToken=false; + } + else if ( joinTokens.contains(lcToken) ) { + joinType = ' ' + lcToken; + expectingJoinToken = true; } else { *************** *** 48,59 **** else { if (fromClass) { ! q.addFromType(name, token); } else { ParserHelper.parse(peParser, token, ParserHelper.PATH_SEPERATORS, q); ! peParser.addFromCollection(q, name); } name = null; ! expectingComma=true; } } --- 74,89 ---- else { if (fromClass) { ! Loadable p = q.getPersisterUsingImports(token); ! OuterJoinFragment ojf = new QueryOuterJoinFragment(); ! ojf.addCrossJoin( p.getTableName(), name ); ! q.addFromType( name, p.getMappedClass(), ojf ); } else { + peParser.presetCollectionName(name); ParserHelper.parse(peParser, token, ParserHelper.PATH_SEPERATORS, q); ! peParser.addFromCollection(q, name, OuterJoinFragment.INNER_JOIN); } name = null; ! expectingJoin=true; } } *************** *** 62,66 **** public void start(QueryTranslator q) { expectingIn = false; ! expectingComma = false; name = null; fromClass = false; --- 92,98 ---- public void start(QueryTranslator q) { expectingIn = false; ! expectingJoin = false; ! expectingJoinToken = false; ! joinType = null; name = null; fromClass = false; Index: GroupByParser.java =================================================================== RCS file: /cvsroot/hibernate/Hibernate2/src/net/sf/hibernate/hql/GroupByParser.java,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** GroupByParser.java 5 Jan 2003 02:11:21 -0000 1.3 --- GroupByParser.java 23 Feb 2003 01:32:20 -0000 1.4 *************** *** 27,31 **** ParserHelper.parse(pathExpressionParser, token, ParserHelper.PATH_SEPERATORS, q); q.appendGroupByToken( pathExpressionParser.getWhereColumn() ); ! q.addJoin( pathExpressionParser.getWhereJoin() ); } else { --- 27,31 ---- ParserHelper.parse(pathExpressionParser, token, ParserHelper.PATH_SEPERATORS, q); q.appendGroupByToken( pathExpressionParser.getWhereColumn() ); ! q.addJoin( pathExpressionParser.getName(), pathExpressionParser.getWhereJoin() ); } else { Index: OrderByParser.java =================================================================== RCS file: /cvsroot/hibernate/Hibernate2/src/net/sf/hibernate/hql/OrderByParser.java,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** OrderByParser.java 5 Jan 2003 02:11:21 -0000 1.3 --- OrderByParser.java 23 Feb 2003 01:32:20 -0000 1.4 *************** *** 26,30 **** ParserHelper.parse(pathExpressionParser, token, ParserHelper.PATH_SEPERATORS, q); q.appendOrderByToken( pathExpressionParser.getWhereColumn() ); ! q.addJoin( pathExpressionParser.getWhereJoin() ); } else { --- 26,30 ---- ParserHelper.parse(pathExpressionParser, token, ParserHelper.PATH_SEPERATORS, q); q.appendOrderByToken( pathExpressionParser.getWhereColumn() ); ! q.addJoin( pathExpressionParser.getName(), pathExpressionParser.getWhereJoin() ); } else { Index: PathExpressionParser.java =================================================================== RCS file: /cvsroot/hibernate/Hibernate2/src/net/sf/hibernate/hql/PathExpressionParser.java,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** PathExpressionParser.java 20 Jan 2003 12:48:10 -0000 1.6 --- PathExpressionParser.java 23 Feb 2003 01:32:20 -0000 1.7 *************** *** 6,16 **** import net.sf.hibernate.Hibernate; import net.sf.hibernate.QueryException; - import net.sf.hibernate.util.StringHelper; import net.sf.hibernate.collection.CollectionPersister; - import net.sf.hibernate.persister.*; import net.sf.hibernate.persister.ClassPersister; ! import net.sf.hibernate.type.PersistentCollectionType; import net.sf.hibernate.type.EntityType; import net.sf.hibernate.type.Type; /** --- 6,19 ---- import net.sf.hibernate.Hibernate; import net.sf.hibernate.QueryException; import net.sf.hibernate.collection.CollectionPersister; import net.sf.hibernate.persister.ClassPersister; ! import net.sf.hibernate.persister.Loadable; ! import net.sf.hibernate.persister.Queryable; ! import net.sf.hibernate.sql.OuterJoinFragment; ! import net.sf.hibernate.sql.QueryOuterJoinFragment; import net.sf.hibernate.type.EntityType; + import net.sf.hibernate.type.PersistentCollectionType; import net.sf.hibernate.type.Type; + import net.sf.hibernate.util.StringHelper; /** *************** *** 33,37 **** protected String currentName; protected String currentProperty; ! protected StringBuffer join; protected String[] columns; protected String[] collectionElementColumns; --- 36,40 ---- protected String currentName; protected String currentProperty; ! protected OuterJoinFragment join; protected String[] columns; protected String[] collectionElementColumns; *************** *** 45,100 **** private boolean skippedId; private boolean continuation; ! private void addJoin(String name, String[] rhsCols, QueryTranslator q) throws QueryException { String[] lhsCols = currentColumns(q); ! for ( int i=0; i<rhsCols.length; i++) { ! join.append(" and ") ! .append( lhsCols[i] ) ! .append('=') ! .append(name) ! .append(StringHelper.DOT) ! .append( rhsCols[i] ); ! } } ! public String continueFromManyToMany(Class clazz, String[] joinColumns, QueryTranslator q) throws QueryException { start(q); continuation=true; currentName = q.createNameFor(clazz); ! q.addType( currentName, clazz.getName() ); ! ! for ( int i=0; i<joinColumns.length; i++ ) { ! join.append(" and ") ! .append( joinColumns[i] ) ! .append('=') ! .append(currentName) ! .append(StringHelper.DOT) ! .append( q.getPersister(clazz).getIdentifierColumnNames()[i] ); ! } return currentName; } - public String continueFromSubcollection(String role, String[] joinColumns, QueryTranslator q) throws QueryException { - start(q); - continuation=true; - collectionName = q.createNameForCollection(role); - collectionRole = role; - currentName=null; - currentProperty=null; - CollectionPersister p = q.getCollectionPersister(role); - collectionTable = p.getQualifiedTableName(); - - for ( int i=0; i<joinColumns.length; i++ ) { - join.append(" and ") - .append( joinColumns[i] ) - .append('=') - .append(collectionName) - .append(StringHelper.DOT) - .append( p.getKeyColumnNames()[i] ); - } - return collectionName; - } - - public void token(String token, QueryTranslator q) throws QueryException { --- 48,72 ---- private boolean skippedId; private boolean continuation; + private String presetCollectionName; ! void presetCollectionName(String name) { ! presetCollectionName=name; ! } ! ! private void addJoin(String table, String name, String[] rhsCols, QueryTranslator q) throws QueryException { String[] lhsCols = currentColumns(q); ! join.addJoin(table, name, lhsCols, rhsCols, OuterJoinFragment.INNER_JOIN); } ! String continueFromManyToMany(Class clazz, String[] joinColumns, QueryTranslator q) throws QueryException { start(q); continuation=true; currentName = q.createNameFor(clazz); ! q.addType(currentName, clazz); ! Loadable p = q.getPersister(clazz); ! join.addJoin( p.getTableName(), currentName, joinColumns, p.getIdentifierColumnNames(), OuterJoinFragment.INNER_JOIN ); return currentName; } public void token(String token, QueryTranslator q) throws QueryException { *************** *** 105,109 **** reset(); //reset the dotcount (but not the path) currentName = alias; //after reset! ! join.append( q.getPathJoin(path) ); //after reset! } else if ( ".".equals(token) ) { --- 77,85 ---- reset(); //reset the dotcount (but not the path) currentName = alias; //after reset! ! OuterJoinFragment ojf = q.getPathJoin(path); ! join.addJoins( ! StringHelper.EMPTY_STRING, //ojf.toFromFragmentString(), ! ojf.toWhereFragmentString() ! ); //after reset! } else if ( ".".equals(token) ) { *************** *** 167,176 **** String name = q.createNameFor(memberClass); ! q.addType( name, memberClass.getName() ); String[] keyColNames = memberPersister.getIdentifierColumnNames(); ! addJoin(name, keyColNames, q); currentName = name; currentProperty = token; ! q.addPathAliasAndJoin( path.substring( 0, path.lastIndexOf(StringHelper.DOT) ), name, join.toString() ); } --- 143,152 ---- String name = q.createNameFor(memberClass); ! q.addType(name, memberClass); String[] keyColNames = memberPersister.getIdentifierColumnNames(); ! addJoin( memberPersister.getTableName(), name, keyColNames, q ); currentName = name; currentProperty = token; ! q.addPathAliasAndJoin( path.substring( 0, path.lastIndexOf(StringHelper.DOT) ), name, join ); } *************** *** 182,187 **** CollectionPersister p = q.getCollectionPersister(collectionRole); String[] colNames = p.getKeyColumnNames(); ! String name = q.createNameForCollection(collectionRole); ! addJoin(name, colNames, q); doCollectionProperty(token, p, name); collectionName = name; --- 158,172 ---- CollectionPersister p = q.getCollectionPersister(collectionRole); String[] colNames = p.getKeyColumnNames(); ! ! String name; ! if ( presetCollectionName==null || !p.isOneToMany() ) { ! name = q.createNameForCollection(collectionRole); ! } ! else { ! name = presetCollectionName; ! } ! presetCollectionName = null; ! ! addJoin( p.getQualifiedTableName(), name, colNames, q ); doCollectionProperty(token, p, name); collectionName = name; *************** *** 235,239 **** private void reset() { ! join = new StringBuffer(50); dotcount=0; currentName=null; --- 220,224 ---- private void reset() { ! join = new QueryOuterJoinFragment(); dotcount=0; currentName=null; *************** *** 275,293 **** } if (collectionRole!=null) { //special case; expecting: [index] CollectionPersister memberPersister = q.getCollectionPersister(collectionRole); if ( !memberPersister.hasIndex() ) throw new QueryException("unindexed collection before []"); ! String[] keyCols = memberPersister.getKeyColumnNames(); ! if (!continuation) addJoin(collectionName, keyCols, q); ! ! String[] indexCols = memberPersister.getIndexColumnNames(); ! if ( indexCols.length!=1 ) throw new QueryException("composite-index appears in []"); ! join.append(" and ") ! .append(collectionName) ! .append(StringHelper.DOT) ! .append( indexCols[0] ) ! .append("="); String[] eltCols = memberPersister.getElementColumnNames(); --- 260,276 ---- } if (collectionRole!=null) { + //special case; expecting: [index] CollectionPersister memberPersister = q.getCollectionPersister(collectionRole); + if ( !memberPersister.hasIndex() ) throw new QueryException("unindexed collection before []"); ! String[] indexCols = memberPersister.getIndexColumnNames(); ! if ( indexCols.length!=1 ) throw new QueryException("composite-index appears in []"); String[] keyCols = memberPersister.getKeyColumnNames(); ! if (!continuation) { ! addJoin( memberPersister.getQualifiedTableName(), collectionName, keyCols, q ); ! } ! join.addCondition(collectionName, indexCols, " = "); String[] eltCols = memberPersister.getElementColumnNames(); *************** *** 299,307 **** elem.isOneToMany = memberPersister.isOneToMany(); elem.alias = collectionName; ! elem.join = join.toString(); collectionElements.addLast(elem); setExpectingCollectionIndex(); q.addCollection(collectionName, collectionRole); } else { --- 282,293 ---- elem.isOneToMany = memberPersister.isOneToMany(); elem.alias = collectionName; ! elem.join = join; collectionElements.addLast(elem); setExpectingCollectionIndex(); q.addCollection(collectionName, collectionRole); + OuterJoinFragment ojf = new QueryOuterJoinFragment(); + ojf.addCrossJoin( memberPersister.getQualifiedTableName(), collectionName ); + q.addJoin(collectionName, ojf); } else { *************** *** 314,318 **** //important!! continuation=false; ! } --- 300,304 ---- //important!! continuation=false; ! presetCollectionName = null; } *************** *** 322,326 **** String alias; String[] elementColumns; ! String join; StringBuffer indexValue = new StringBuffer(); } --- 308,312 ---- String alias; String[] elementColumns; ! OuterJoinFragment join; StringBuffer indexValue = new StringBuffer(); } *************** *** 328,346 **** private boolean expectingCollectionIndex; private LinkedList collectionElements = new LinkedList(); public CollectionElement lastCollectionElement() { return (CollectionElement) collectionElements.removeLast(); } public void setLastCollectionElementIndexValue(String value) { ( (CollectionElement) collectionElements.getLast() ).indexValue.append(value) ; } public boolean isExpectingCollectionIndex() { return expectingCollectionIndex; } protected void setExpectingCollectionIndex() throws QueryException { expectingCollectionIndex = true; } ! public String getWhereJoin() { ! return join.toString(); } --- 314,336 ---- private boolean expectingCollectionIndex; private LinkedList collectionElements = new LinkedList(); + public CollectionElement lastCollectionElement() { return (CollectionElement) collectionElements.removeLast(); } + public void setLastCollectionElementIndexValue(String value) { ( (CollectionElement) collectionElements.getLast() ).indexValue.append(value) ; } + public boolean isExpectingCollectionIndex() { return expectingCollectionIndex; } + protected void setExpectingCollectionIndex() throws QueryException { expectingCollectionIndex = true; } ! public OuterJoinFragment getWhereJoin() { ! return join; } *************** *** 357,367 **** } ! public String getCollectionSubquery(String extraJoin) throws QueryException { ! if (extraJoin!=null) join.append(extraJoin); return new StringBuffer( "SELECT " ) ! .append( StringHelper.join( ", ", collectionElementColumns ) ) ! .append(" FROM ").append(collectionTable).append(' ').append(collectionName) ! .append(" WHERE ").append( join.substring(5).toString() ) // remove initial " and " ! .toString(); } --- 347,366 ---- } ! public String getName() { ! return currentName==null ? collectionName : currentName; ! } ! ! public String getCollectionSubquery() throws QueryException { ! return new StringBuffer( "SELECT " ) ! .append( StringHelper.join( ", ", collectionElementColumns ) ) ! .append(" FROM ") ! .append(collectionTable) ! .append(' ') ! .append(collectionName) ! //.append( join.toFromFragmentString() ) ! .append(" WHERE ") ! .append( join.toWhereFragmentString().substring(5) ) // remove initial " and " ! .toString(); } *************** *** 370,374 **** } ! public void addFromCollection(QueryTranslator q, String elementName) throws QueryException { if ( collectionElementType==null ) throw new QueryException("must specify 'elements' for collection valued property in from clause: " + elementName); --- 369,373 ---- } ! public void addFromCollection(QueryTranslator q, String elementName, int joinType) throws QueryException { if ( collectionElementType==null ) throw new QueryException("must specify 'elements' for collection valued property in from clause: " + elementName); *************** *** 378,401 **** ); EntityType elemType = (EntityType) collectionElementType; - q.addFromType( elementName, elemType.getPersistentClass().getName() ); CollectionPersister persister = q.getCollectionPersister(collectionRole); if ( persister.isOneToMany() ) { ! q.addJoin( StringHelper.replace( join.toString(), collectionName, elementName ) ); } else { q.addCollection(collectionName, collectionRole); ! String[] keyColumnNames = q.getPersisterForName(elementName).getIdentifierColumnNames(); ! ! for ( int i=0; i<keyColumnNames.length; i++ ) { ! join.append(" and ") ! .append( collectionElementColumns[i] ) //already qualified ! .append('=') ! .append(elementName) ! .append(StringHelper.DOT) ! .append( keyColumnNames[i] ); ! } ! q.addJoin( join.toString() ); } } --- 377,395 ---- ); EntityType elemType = (EntityType) collectionElementType; CollectionPersister persister = q.getCollectionPersister(collectionRole); + if ( persister.isOneToMany() ) { ! //join.addCrossJoin( persister.getQualifiedTableName(), elementName ); } else { q.addCollection(collectionName, collectionRole); ! //join.addCrossJoin( persister.getQualifiedTableName(), collectionName ); ! Loadable p = q.getPersister( elemType.getPersistentClass() ); ! String[] keyColumnNames = p.getIdentifierColumnNames(); ! join.addJoin( p.getTableName(), elementName, collectionElementColumns, keyColumnNames, joinType); } + q.addFromType( elementName, elemType.getPersistentClass(), join ); + // q.addJoin(join); } Index: QueryTranslator.java =================================================================== RCS file: /cvsroot/hibernate/Hibernate2/src/net/sf/hibernate/hql/QueryTranslator.java,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -d -r1.10 -r1.11 *** QueryTranslator.java 24 Jan 2003 13:07:16 -0000 1.10 --- QueryTranslator.java 23 Feb 2003 01:32:20 -0000 1.11 *************** *** 30,38 **** import net.sf.hibernate.loader.Loader; import net.sf.hibernate.loader.OuterJoinLoader; - //import net.sf.hibernate.loader.OuterJoinLoader; - //import net.sf.hibernate.loader.OuterJoinLoader.OuterJoinableAssociation; import net.sf.hibernate.persister.Loadable; import net.sf.hibernate.persister.Queryable; import net.sf.hibernate.sql.OuterJoinFragment; import net.sf.hibernate.type.EntityType; import net.sf.hibernate.type.Type; --- 30,37 ---- import net.sf.hibernate.loader.Loader; import net.sf.hibernate.loader.OuterJoinLoader; import net.sf.hibernate.persister.Loadable; import net.sf.hibernate.persister.Queryable; import net.sf.hibernate.sql.OuterJoinFragment; + import net.sf.hibernate.sql.QueryOuterJoinFragment; import net.sf.hibernate.type.EntityType; import net.sf.hibernate.type.Type; *************** *** 79,94 **** dontSpace.add(StringHelper.CLOSE_PAREN); } ! private final HashMap typeMap = new HashMap(); ! private final HashMap collections = new HashMap(); ! private final HashMap names = new HashMap(); ! private ArrayList returnTypes = new ArrayList(); ! private final ArrayList fromTypes = new ArrayList(); ! private final ArrayList scalarTypes = new ArrayList(); ! private final HashMap namedParameters = new HashMap(); private final List scalarSelectTokens = new ArrayList(); private final List whereTokens = new ArrayList(); private final List havingTokens = new ArrayList(); ! private final StringBuffer joins = new StringBuffer(40); private final List orderByTokens = new ArrayList(); private final List groupByTokens = new ArrayList(); --- 78,94 ---- dontSpace.add(StringHelper.CLOSE_PAREN); } ! ! private final Map typeMap = new HashMap(); ! private final Map collections = new HashMap(); ! private List returnTypes = new ArrayList(); ! private final List fromTypes = new ArrayList(); ! private final Map fromJoins = new HashMap(); ! private final List scalarTypes = new ArrayList(); ! private final Map namedParameters = new HashMap(); private final List scalarSelectTokens = new ArrayList(); private final List whereTokens = new ArrayList(); private final List havingTokens = new ArrayList(); ! private final Map joins = new HashMap(); private final List orderByTokens = new ArrayList(); private final List groupByTokens = new ArrayList(); *************** *** 259,267 **** String createNameForCollection(String role) { ! return prefix( StringHelper.unqualify(role, "/") ) + nextCount() + StringHelper.UNDERSCORE; } ! String getType(String name) { ! String type = (String) typeMap.get(name); if ( type==null && superQuery!=null ) type = superQuery.getType(name); return type; --- 259,267 ---- String createNameForCollection(String role) { ! return prefix( StringHelper.unqualify(role) ) + nextCount() + StringHelper.UNDERSCORE; } ! Class getType(String name) { ! Class type = (Class) typeMap.get(name); if ( type==null && superQuery!=null ) type = superQuery.getType(name); return type; *************** *** 275,296 **** boolean isName(String name) { ! return typeMap.containsKey(name) || collections.containsKey(name) || ( superQuery!=null && superQuery.isName(name) ); } Queryable getPersisterForName(String name) throws QueryException { ! String typeName = getType(name); ! if (typeName==null) { ! return getPersister( ! ( (EntityType) getCollectionPersister( getRole(name) ).getElementType() ).getPersistentClass() ! ); } else { ! Queryable persister = getPersister(typeName); ! if (persister==null) throw new QueryException( "persistent class not found: " + typeName ); return persister; } } ! Queryable getPersister(String className) { String[] imports = factory.getImports(); try { --- 275,309 ---- boolean isName(String name) { ! return typeMap.containsKey(name) || ! collections.containsKey(name) || ( ! superQuery!=null && superQuery.isName(name) ! ); ! } ! ! Queryable getEntityPersisterForName(String name) throws QueryException { ! Class type = getType(name); ! if (type==null) { ! return null; ! } ! else { ! return getPersister(type); ! } } Queryable getPersisterForName(String name) throws QueryException { ! Class type = getType(name); ! if (type==null) { ! Type elemType = getCollectionPersister( getRole(name) ).getElementType(); ! if ( ! (elemType instanceof EntityType) ) return null; //YUCK! bugprone..... ! return getPersister( ( (EntityType) elemType ).getPersistentClass() ); } else { ! Queryable persister = getPersister(type); ! if (persister==null) throw new QueryException( "persistent class not found: " + type.getName() ); return persister; } } ! Queryable getPersisterUsingImports(String className) { String[] imports = factory.getImports(); try { *************** *** 326,332 **** } ! void addType(String name, String type) { typeMap.put(name, type); - names.put(type, name); } --- 339,344 ---- } ! void addType(String name, Class type) { typeMap.put(name, type); } *************** *** 335,341 **** } ! void addFromType(String name, String type) { addType(name, type); fromTypes.add(name); } --- 347,355 ---- } ! void addFromType(String name, Class type, OuterJoinFragment join) { addType(name, type); fromTypes.add(name); + fromJoins.put(name, join); + //addJoin(join); //TODO: remove this!! } *************** *** 372,381 **** } ! void addJoin(String token) { ! if ( joins.length()==0 && token.length()!=0 ) { ! joins.append( token.substring(5) ); // remove leading " and " (ugly and causes bugs!) ! } ! else { ! joins.append(token); } } --- 386,392 ---- } ! void addJoin(String name, OuterJoinFragment newjoin) { ! if ( !joins.containsKey(name) ) { ! joins.put(name, newjoin); } } *************** *** 444,448 **** String selectProperties; String selectIdentifiers; ! if ( !isShallowQuery() && returnTypes.size()==1 && typeMap.size()==1 ) { OuterJoinLoader ojl = new OuterJoinLoader( factory.getDialect() ); String name = (String) returnTypes.get(0); --- 455,460 ---- String selectProperties; String selectIdentifiers; ! if (false) { ! //if ( !isShallowQuery() && returnTypes.size()==1 && typeMap.size()==1 ) { OuterJoinLoader ojl = new OuterJoinLoader( factory.getDialect() ); String name = (String) returnTypes.get(0); *************** *** 487,491 **** if ( outerJoinedProperties!=null && outerJoinedProperties.length() > 0 ) selectPropertiesString += ", " + outerJoinedProperties; //TODO: for some dialiects it would be appropriate to add the renderOrderByPropertiesSelect() to other select strings ! fromWhereString = renderFromClause(outerjoin) + renderWhereClause(outerjoin); if ( scalarTypes.size()!=size ) { --- 499,506 ---- if ( outerJoinedProperties!=null && outerJoinedProperties.length() > 0 ) selectPropertiesString += ", " + outerJoinedProperties; //TODO: for some dialiects it would be appropriate to add the renderOrderByPropertiesSelect() to other select strings ! OuterJoinFragment mergedJoins = mergeJoins(outerjoin); ! fromWhereString = " FROM" + mergedJoins.toFromFragmentString().substring(1) + renderWhereClause(mergedJoins, outerjoin); ! ! //System.out.println( ">>>> " + renderFromClause(outerjoin) ); if ( scalarTypes.size()!=size ) { *************** *** 630,637 **** } ! private String renderFromClause(OuterJoinFragment outerjoin) throws QueryException, MappingException { //FROM StringBuffer buf = new StringBuffer(120) ! .append(" FROM"); Iterator iter = typeMap.keySet().iterator(); while ( iter.hasNext() ) { --- 645,692 ---- } ! private OuterJoinFragment mergeJoins(OuterJoinFragment outerjoin) throws MappingException, QueryException { ! OuterJoinFragment ojf = new QueryOuterJoinFragment(); ! ! //classes ! Iterator iter = typeMap.keySet().iterator(); ! while ( iter.hasNext() ) { ! String name = (String) iter.next(); ! Queryable p = getPersisterForName(name); ! boolean includeSubclasses = returnTypes.contains(name) && !isShallowQuery(); ! ! OuterJoinFragment join = (OuterJoinFragment) fromJoins.get(name); ! if (join!=null) { ! ojf.addFragment(join); ! ojf.addJoins( ! p.fromJoinFragment(name, true, includeSubclasses), ! p.queryWhereFragment(name, includeSubclasses) ! ); ! } ! } ! ! // add any outerjoins required for association fetching ! // TODO: (need to move inside loop, eventually) ! if (outerjoin!=null) ojf.addJoins( outerjoin.toFromFragmentString(), StringHelper.EMPTY_STRING ); ! ! iter = joins.entrySet().iterator(); ! while ( iter.hasNext() ) { ! Map.Entry e = (Map.Entry) iter.next(); ! String name = (String) e.getKey(); ! if ( !fromJoins.containsKey(name) ) { //TODO: I hate this.... ! ojf.addFragment( (OuterJoinFragment) e.getValue() ); ! Queryable p = getEntityPersisterForName(name); ! if (p!=null) { ! ojf.addJoins( p.fromJoinFragment(name, true, false), StringHelper.EMPTY_STRING ); ! } ! } ! } ! ! return ojf; ! } ! ! /*private String renderFromClause(OuterJoinFragment outerjoin) throws QueryException, MappingException { //FROM StringBuffer buf = new StringBuffer(120) ! .append(" FROM"); Iterator iter = typeMap.keySet().iterator(); while ( iter.hasNext() ) { *************** *** 662,699 **** return buf.toString(); ! } ! private String renderWhereClause(OuterJoinFragment outerjoin) throws QueryException, MappingException { Iterator iter = typeMap.keySet().iterator(); - StringBuffer inClassWheres = new StringBuffer(50); - - // add any outerjoins required for fetching associations - // TODO: (need to move inside loop, eventually) - if (outerjoin!=null) inClassWheres.append( outerjoin.toWhereFragmentString() ); - while ( iter.hasNext() ) { - String name = (String) iter.next(); Queryable p = getPersisterForName(name); addIdentifierSpace( p.getIdentifierSpace() ); - - //render the " and foo.class in ( 'Foo', 'Bar' ) " bit - String where = p.queryWhereFragment( name, returnTypes.contains(name) && !isShallowQuery() ); - if ( where!=null ) inClassWheres.append(where); } ! //if ( inClassWheres.toString().toLowerCase().startsWith(" and ") ) { ! inClassWheres.delete(0, 5); //remove the leading " and " ! //} StringBuffer buf = new StringBuffer(120); - //WHERE StringBuffer whereTokenBuf = new StringBuffer(40); appendTokens( whereTokenBuf, whereTokens.iterator() ); ! String part1 = inClassWheres.toString().trim(); ! String part2 = joins.toString().trim(); String part3 = whereTokenBuf.toString().trim(); --- 717,749 ---- return buf.toString(); ! }*/ ! private String renderWhereClause(OuterJoinFragment mergedJoins, OuterJoinFragment outerjoin) throws QueryException, MappingException { ! ! //SET UP IDENTIFIER SPACES. TODO: move elsewhere! Iterator iter = typeMap.keySet().iterator(); while ( iter.hasNext() ) { String name = (String) iter.next(); Queryable p = getPersisterForName(name); addIdentifierSpace( p.getIdentifierSpace() ); } ! // add any outerjoins required for fetching associations ! // TODO: (need to move inside loop, eventually) ! String part1; ! if (outerjoin!=null) { ! part1 = outerjoin.toWhereFragmentString().substring(5); //remove the leading " and " ! } ! else { ! part1=""; ! } StringBuffer buf = new StringBuffer(120); StringBuffer whereTokenBuf = new StringBuffer(40); appendTokens( whereTokenBuf, whereTokens.iterator() ); ! String part2 = mergedJoins.toWhereFragmentString(); String part3 = whereTokenBuf.toString().trim(); *************** *** 705,709 **** if ( hasPart1 ) buf.append(part1); if ( hasPart1 && hasPart2 ) buf.append(" AND "); ! if ( hasPart2 ) buf.append(part2); if ( hasPart3 ) { if ( hasPart1 || hasPart2 ) buf.append(" AND ("); --- 755,759 ---- if ( hasPart1 ) buf.append(part1); if ( hasPart1 && hasPart2 ) buf.append(" AND "); ! if ( hasPart2 ) buf.append( part2.substring(5) ); //remove leading "and " if ( hasPart3 ) { if ( hasPart1 || hasPart2 ) buf.append(" AND ("); *************** *** 780,784 **** ); EntityType elemType = (EntityType) collectionElementType; - addFromType( elementName, elemType.getPersistentClass().getName() ); CollectionPersister persister = getCollectionPersister(collectionRole); --- 830,833 ---- *************** *** 786,820 **** if (keyColumnNames.length!=1) throw new QueryException("composite-key collection in filter: " + collectionRole); ! StringBuffer join = new StringBuffer(25); ! join.append(" and "); // all conditions must begin with " and " ! if ( persister.isOneToMany() ) { ! join.append(elementName) ! .append(StringHelper.DOT) ! .append( keyColumnNames[0] ) ! .append(" = ?"); } else { //many-to-many String collectionName = createNameForCollection(collectionRole); addCollection(collectionName, collectionRole); ! join.append(collectionName) ! .append(StringHelper.DOT) ! .append( keyColumnNames[0] ) ! .append(" = ?"); ! String[] idColumnNames = getPersisterForName(elementName).getIdentifierColumnNames(); String[] eltColumnNames = persister.getElementColumnNames(); ! for ( int i=0; i<idColumnNames.length; i++ ) { ! join.append(" and ") ! .append(collectionName) ! .append(StringHelper.DOT) ! .append( eltColumnNames[i] ) ! .append('=') ! .append(elementName) ! .append(StringHelper.DOT) ! .append( idColumnNames[i] ); ! } } ! addJoin( join.toString() ); } --- 835,863 ---- if (keyColumnNames.length!=1) throw new QueryException("composite-key collection in filter: " + collectionRole); ! OuterJoinFragment join = new QueryOuterJoinFragment(); if ( persister.isOneToMany() ) { ! join.addCrossJoin( persister.getQualifiedTableName(), elementName ); ! join.addCondition(elementName, keyColumnNames, " = ?"); } else { //many-to-many String collectionName = createNameForCollection(collectionRole); addCollection(collectionName, collectionRole); ! join.addCrossJoin( persister.getQualifiedTableName(), collectionName ); ! join.addCondition(collectionName, keyColumnNames, " = ?"); ! Queryable p = getPersister( elemType.getPersistentClass() ); ! String[] idColumnNames = p.getIdentifierColumnNames(); String[] eltColumnNames = persister.getElementColumnNames(); ! join.addJoin( ! p.getTableName(), ! elementName, ! StringHelper.prefix(eltColumnNames, collectionName + StringHelper.DOT), ! idColumnNames, ! OuterJoinFragment.INNER_JOIN ! ); } ! addFromType( elementName, elemType.getPersistentClass(), join ); ! // addJoin(join); ! } *************** *** 826,836 **** } ! String getPathJoin(String path) { ! return (String) pathJoins.get(path); } ! void addPathAliasAndJoin(String path, String alias, String join) { pathAliases.put(path, alias); ! pathJoins.put(path, join); } --- 869,879 ---- } ! OuterJoinFragment getPathJoin(String path) { ! return (OuterJoinFragment) pathJoins.get(path); } ! void addPathAliasAndJoin(String path, String alias, OuterJoinFragment join) { pathAliases.put(path, alias); ! pathJoins.put( path, join.copy() ); } Index: SelectParser.java =================================================================== RCS file: /cvsroot/hibernate/Hibernate2/src/net/sf/hibernate/hql/SelectParser.java,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** SelectParser.java 20 Jan 2003 12:48:11 -0000 1.4 --- SelectParser.java 23 Feb 2003 01:32:20 -0000 1.5 *************** *** 107,111 **** q.appendScalarSelectToken( aggregatePathExpressionParser.getWhereColumn() ); if (!count) q.addScalarType( aggregatePathExpressionParser.getWhereColumnType() ); ! q.addJoin( aggregatePathExpressionParser.getWhereJoin() ); } else { --- 107,111 ---- q.appendScalarSelectToken( aggregatePathExpressionParser.getWhereColumn() ); if (!count) q.addScalarType( aggregatePathExpressionParser.getWhereColumnType() ); ! q.addJoin( aggregatePathExpressionParser.getName(), aggregatePathExpressionParser.getWhereJoin() ); } else { *************** *** 124,128 **** q.appendScalarSelectTokens( pathExpressionParser.getWhereColumns() ); q.addScalarType( pathExpressionParser.getWhereColumnType() ); ! q.addJoin( pathExpressionParser.getWhereJoin() ); ready = false; --- 124,128 ---- q.appendScalarSelectTokens( pathExpressionParser.getWhereColumns() ); q.addScalarType( pathExpressionParser.getWhereColumnType() ); ! q.addJoin( pathExpressionParser.getName(), pathExpressionParser.getWhereJoin() ); ready = false; Index: WhereParser.java =================================================================== RCS file: /cvsroot/hibernate/Hibernate2/src/net/sf/hibernate/hql/WhereParser.java,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** WhereParser.java 20 Jan 2003 12:48:11 -0000 1.4 --- WhereParser.java 23 Feb 2003 01:32:20 -0000 1.5 *************** *** 14,20 **** import net.sf.hibernate.util.StringHelper; import net.sf.hibernate.persister.Queryable; import net.sf.hibernate.type.EntityType; import net.sf.hibernate.type.LiteralType; - import net.sf.hibernate.type.PersistentCollectionType; import net.sf.hibernate.type.Type; import net.sf.hibernate.type.TypeFactory; --- 14,21 ---- import net.sf.hibernate.util.StringHelper; import net.sf.hibernate.persister.Queryable; + import net.sf.hibernate.sql.OuterJoinFragment; + import net.sf.hibernate.sql.QueryOuterJoinFragment; import net.sf.hibernate.type.EntityType; import net.sf.hibernate.type.LiteralType; import net.sf.hibernate.type.Type; import net.sf.hibernate.type.TypeFactory; *************** *** 150,154 **** private LinkedList joins = new LinkedList(); //the join string built up by compound paths inside this expression private LinkedList booleanTests = new LinkedList(); //a flag indicating if the subexpression is known to be boolean - private String collectionJoin; private String getElementName(PathExpressionParser.CollectionElement element, QueryTranslator q) throws QueryException { --- 151,154 ---- *************** *** 164,171 **** name = pathExpressionParser.continueFromManyToMany(clazz, element.elementColumns, q); } ! else if ( type.isPersistentCollectionType() ) { //ie. a subcollection String role = ( (PersistentCollectionType) type ).getRole(); name = pathExpressionParser.continueFromSubcollection(role, element.elementColumns, q); ! } else { throw new QueryException("illegally dereferenced collection element"); --- 164,171 ---- name = pathExpressionParser.continueFromManyToMany(clazz, element.elementColumns, q); } ! /*else if ( type.isPersistentCollectionType() ) { //ie. a subcollection String role = ( (PersistentCollectionType) type ).getRole(); name = pathExpressionParser.continueFromSubcollection(role, element.elementColumns, q); ! }*/ else { throw new QueryException("illegally dereferenced collection element"); *************** *** 203,208 **** doPathExpression( getElementName(element, q) + token, q ); // careful with this! ! addToCurrentJoin(element.join); ! addToCurrentJoin( element.indexValue.toString() ); return; //NOTE: EARLY EXIT! --- 203,207 ---- doPathExpression( getElementName(element, q) + token, q ); // careful with this! ! addToCurrentJoin(element); return; //NOTE: EARLY EXIT! *************** *** 210,215 **** else if ( token.equals("[") ) { doPathExpression( getElementName(element, q), q ); ! addToCurrentJoin(element.join); ! addToCurrentJoin( element.indexValue.toString() ); return; //NOTE: EARLY EXIT! } --- 209,213 ---- else if ( token.equals("[") ) { doPathExpression( getElementName(element, q), q ); ! addToCurrentJoin(element); return; //NOTE: EARLY EXIT! } *************** *** 217,222 **** if ( element.elementColumns.length!=1 ) throw new QueryException("path expression ended in composite collection element"); appendToken( q, element.elementColumns[0] ); ! addToCurrentJoin(element.join); ! addToCurrentJoin( element.indexValue.toString() ); } --- 215,219 ---- if ( element.elementColumns.length!=1 ) throw new QueryException("path expression ended in composite collection element"); appendToken( q, element.elementColumns[0] ); ! addToCurrentJoin(element); } *************** *** 306,311 **** if ( element.elementColumns.length!=1 ) throw new QueryException("path expression ended in composite collection element"); appendToken( q, element.elementColumns[0] ); ! addToCurrentJoin(element.join); ! addToCurrentJoin( element.indexValue.toString() ); } token(StringHelper.CLOSE_PAREN, q); --- 303,307 ---- if ( element.elementColumns.length!=1 ) throw new QueryException("path expression ended in composite collection element"); appendToken( q, element.elementColumns[0] ); ! addToCurrentJoin(element); } token(StringHelper.CLOSE_PAREN, q); *************** *** 366,373 **** if ( pathExpressionParser.isCollectionValued() ) { openExpression(q, StringHelper.EMPTY_STRING); ! appendToken( q, pathExpressionParser.getCollectionSubquery(collectionJoin) ); q.addIdentifierSpace( pathExpressionParser.getCollectionTable() ); closeExpression(q, StringHelper.EMPTY_STRING); - collectionJoin = null; } else { --- 362,368 ---- if ( pathExpressionParser.isCollectionValued() ) { openExpression(q, StringHelper.EMPTY_STRING); ! appendToken( q, pathExpressionParser.getCollectionSubquery() ); q.addIdentifierSpace( pathExpressionParser.getCollectionTable() ); closeExpression(q, StringHelper.EMPTY_STRING); } else { *************** *** 376,380 **** } else { ! addToCurrentJoin( pathExpressionParser.getWhereJoin() ); appendToken( q, pathExpressionParser.getWhereColumn() ); } --- 371,379 ---- } else { ! OuterJoinFragment ojf = pathExpressionParser.getWhereJoin(); ! OuterJoinFragment fromClause = new QueryOuterJoinFragment(); ! fromClause.addJoins( ojf.toFromFragmentString(), StringHelper.EMPTY_STRING ); ! q.addJoin( pathExpressionParser.getName(), fromClause ); ! addToCurrentJoin( ojf.toWhereFragmentString() ); appendToken( q, pathExpressionParser.getWhereColumn() ); } *************** *** 391,395 **** } else { ! Queryable p = q.getPersister(token); if ( p!=null ) { // the name of a class appendToken( q, p.getDiscriminatorSQLString() ); --- 390,394 ---- } else { ! Queryable p = q.getPersisterUsingImports(token); if ( p!=null ) { // the name of a class appendToken( q, p.getDiscriminatorSQLString() ); *************** *** 432,435 **** --- 431,438 ---- private void addToCurrentJoin(String sql) { ( (StringBuffer) joins.getLast() ).append(sql); + } + + private void addToCurrentJoin(PathExpressionParser.CollectionElement ce) { + addToCurrentJoin( ce.join.toWhereFragmentString() + ce.indexValue.toString() ); } |