From: <one...@us...> - 2003-03-01 06:14:17
|
Update of /cvsroot/hibernate/Hibernate2/src/net/sf/hibernate/hql In directory sc8-pr-cvs1:/tmp/cvs-serv8308/sf/hibernate/hql Modified Files: FromParser.java PathExpressionParser.java QueryTranslator.java WhereParser.java Log Message: outer join support in HQL Index: FromParser.java =================================================================== RCS file: /cvsroot/hibernate/Hibernate2/src/net/sf/hibernate/hql/FromParser.java,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** FromParser.java 1 Mar 2003 02:45:26 -0000 1.8 --- FromParser.java 1 Mar 2003 06:14:10 -0000 1.9 *************** *** 2,7 **** --- 2,11 ---- package net.sf.hibernate.hql; + import java.util.HashMap; + import java.util.Map; + import net.sf.hibernate.QueryException; import net.sf.hibernate.persister.Loadable; + import net.sf.hibernate.sql.JoinFragment; import net.sf.hibernate.util.StringHelper; *************** *** 22,26 **** --- 26,42 ---- private boolean expectingIn; private boolean expectingAs; + private boolean afterJoinType; private Loadable classPersister; + private int joinType; + + private static final int NONE = -666; + + private static final Map joinTypes = new HashMap(); + static { + joinTypes.put( "left", new Integer(JoinFragment.LEFT_OUTER_JOIN) ); + joinTypes.put( "right", new Integer(JoinFragment.RIGHT_OUTER_JOIN) ); + joinTypes.put( "full", new Integer(JoinFragment.FULL_JOIN) ); + joinTypes.put( "inner", new Integer(JoinFragment.INNER_JOIN) ); + } public void token(String token, QueryTranslator q) throws QueryException { *************** *** 29,37 **** String lcToken = token.toLowerCase(); if ( lcToken.equals(StringHelper.COMMA) ) { ! if (!expectingJoin) throw new QueryException("unexpected join: " + token); expectingJoin = false; } else if ( lcToken.equals("class") ) { if (!afterIn) throw new QueryException("unexpected token: class"); afterClass=true; } --- 45,64 ---- String lcToken = token.toLowerCase(); if ( lcToken.equals(StringHelper.COMMA) ) { ! if (!expectingJoin) throw new QueryException("unexpected token: ,"); ! expectingJoin = false; ! } ! else if ( lcToken.equals("join") ) { ! if (!afterJoinType) throw new QueryException("unexpected token: join"); ! afterJoinType = false; ! } ! else if ( joinTypes.containsKey(lcToken) ) { ! if (!expectingJoin) throw new QueryException("unexpected token: " + token); ! joinType = ( (Integer) joinTypes.get(lcToken) ).intValue(); ! afterJoinType = true; expectingJoin = false; } else if ( lcToken.equals("class") ) { if (!afterIn) throw new QueryException("unexpected token: class"); + if (joinType!=NONE) throw new QueryException("outer or full join must be followed by path expression"); afterClass=true; } *************** *** 48,54 **** else { ! if (expectingIn || expectingJoin) { // AS is optional ! throw new QueryException("in or join expected: " + token); ! } // now anything that is not a HQL keyword --- 75,81 ---- else { ! if (afterJoinType) throw new QueryException("join expected: " + token); ! if (expectingJoin) throw new QueryException("unexpected token: " + token); ! if (expectingIn) throw new QueryException("in expected: " + token); // now anything that is not a HQL keyword *************** *** 85,88 **** --- 112,117 ---- if (alias==null) throw new QueryException("alias not specified for: " + token); + if (joinType!=NONE) throw new QueryException("outer or full join must be followed by path expression"); + if (afterClass) { // treat it as a classname *************** *** 114,117 **** --- 143,147 ---- if (p!=null) { // starts with the name of a mapped class (new style) + if (joinType!=NONE) throw new QueryException("outer or full join must be followed by path expression"); classPersister = p; expectingAs = true; *************** *** 124,128 **** --- 154,163 ---- } else { + // starts with a path expression (new style) + + if (joinType==NONE) throw new QueryException("path expression must be preceded by full, left, right or inner join"); + /*if (joinType!=NONE) */peParser.setJoinType(joinType); + ParserHelper.parse(peParser, q.unalias(token), ParserHelper.PATH_SEPARATORS, q); if ( peParser.isCollectionValued() ) { *************** *** 133,136 **** --- 168,173 ---- } expectingAs = true; + joinType = NONE; + peParser.setJoinType(JoinFragment.INNER_JOIN); } } *************** *** 149,152 **** --- 186,190 ---- expectingIn = false; expectingAs = false; + joinType = NONE; } Index: PathExpressionParser.java =================================================================== RCS file: /cvsroot/hibernate/Hibernate2/src/net/sf/hibernate/hql/PathExpressionParser.java,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** PathExpressionParser.java 28 Feb 2003 07:01:28 -0000 1.9 --- PathExpressionParser.java 1 Mar 2003 06:14:10 -0000 1.10 *************** *** 11,15 **** import net.sf.hibernate.persister.Queryable; import net.sf.hibernate.sql.JoinFragment; - import net.sf.hibernate.sql.QueryJoinFragment; import net.sf.hibernate.type.EntityType; import net.sf.hibernate.type.PersistentCollectionType; --- 11,14 ---- *************** *** 48,60 **** 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, JoinFragment.INNER_JOIN); } --- 47,59 ---- private boolean skippedId; private boolean continuation; ! private int joinType = JoinFragment.INNER_JOIN; //default mode + void setJoinType(int joinType) { + this.joinType = joinType; + } + private void addJoin(String table, String name, String[] rhsCols, QueryTranslator q) throws QueryException { String[] lhsCols = currentColumns(q); ! join.addJoin(table, name, lhsCols, rhsCols, joinType); } *************** *** 65,69 **** q.addType(currentName, clazz); Loadable p = q.getPersister(clazz); ! join.addJoin( p.getTableName(), currentName, joinColumns, p.getIdentifierColumnNames(), JoinFragment.INNER_JOIN ); return currentName; } --- 64,68 ---- q.addType(currentName, clazz); Loadable p = q.getPersister(clazz); ! join.addJoin( p.getTableName(), currentName, joinColumns, p.getIdentifierColumnNames(), joinType ); return currentName; } *************** *** 75,79 **** String alias = q.getPathAlias(path); if (alias!=null) { ! reset(); //reset the dotcount (but not the path) currentName = alias; //after reset! JoinFragment ojf = q.getPathJoin(path); --- 74,78 ---- String alias = q.getPathAlias(path); if (alias!=null) { ! reset(q); //reset the dotcount (but not the path) currentName = alias; //after reset! JoinFragment ojf = q.getPathJoin(path); *************** *** 157,167 **** String name= q.createNameForCollection(collectionRole); - /*if ( presetCollectionName==null || !p.isOneToMany() ) { - name = q.createNameForCollection(collectionRole); - } - else { - name = presetCollectionName; - } - presetCollectionName = null;*/ addJoin( p.getQualifiedTableName(), name, colNames, q ); --- 156,159 ---- *************** *** 215,220 **** } ! private void reset() { ! join = new QueryJoinFragment(); dotcount=0; currentName=null; --- 207,212 ---- } ! private void reset(QueryTranslator q) { ! join = q.createJoinFragment(); dotcount=0; currentName=null; *************** *** 236,240 **** public void start(QueryTranslator q) { if (!continuation) { ! reset(); path = StringHelper.EMPTY_STRING; } --- 228,232 ---- public void start(QueryTranslator q) { if (!continuation) { ! reset(q); path = StringHelper.EMPTY_STRING; } *************** *** 283,287 **** q.addCollection(collectionName, collectionRole); ! JoinFragment ojf = new QueryJoinFragment(); ojf.addCrossJoin( memberPersister.getQualifiedTableName(), collectionName ); q.addJoin(collectionName, ojf); --- 275,279 ---- q.addCollection(collectionName, collectionRole); ! JoinFragment ojf = q.createJoinFragment(); ojf.addCrossJoin( memberPersister.getQualifiedTableName(), collectionName ); q.addJoin(collectionName, ojf); *************** *** 296,300 **** //important!! continuation=false; - //presetCollectionName = null; } --- 288,291 ---- *************** *** 392,396 **** elementName = q.createNameFor(clazz); String[] keyColumnNames = p.getIdentifierColumnNames(); ! join.addJoin( p.getTableName(), elementName, collectionElementColumns, keyColumnNames, JoinFragment.INNER_JOIN); } q.addFromType(elementName, clazz, join); --- 383,387 ---- elementName = q.createNameFor(clazz); String[] keyColumnNames = p.getIdentifierColumnNames(); ! join.addJoin( p.getTableName(), elementName, collectionElementColumns, keyColumnNames, joinType); } q.addFromType(elementName, clazz, join); Index: QueryTranslator.java =================================================================== RCS file: /cvsroot/hibernate/Hibernate2/src/net/sf/hibernate/hql/QueryTranslator.java,v retrieving revision 1.14 retrieving revision 1.15 diff -C2 -d -r1.14 -r1.15 *** QueryTranslator.java 1 Mar 2003 02:45:26 -0000 1.14 --- QueryTranslator.java 1 Mar 2003 06:14:10 -0000 1.15 *************** *** 42,45 **** --- 42,46 ---- import net.sf.hibernate.util.StringHelper; + import org.apache.commons.collections.SequencedHashMap; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; *************** *** 51,56 **** public class QueryTranslator extends Loader { ! private final Map typeMap = new HashMap(); ! private final Map collections = new HashMap(); private List returnTypes = new ArrayList(); private final List fromTypes = new ArrayList(); --- 52,57 ---- public class QueryTranslator extends Loader { ! private final Map typeMap = new SequencedHashMap(); ! private final Map collections = new SequencedHashMap(); private List returnTypes = new ArrayList(); private final List fromTypes = new ArrayList(); *************** *** 324,328 **** void addCrossJoinedFromType(String name, Loadable classPersister) { ! JoinFragment ojf = new QueryJoinFragment(); ojf.addCrossJoin( classPersister.getTableName(), name ); addFromType( name, classPersister.getMappedClass(), ojf ); --- 325,329 ---- void addCrossJoinedFromType(String name, Loadable classPersister) { ! JoinFragment ojf = createJoinFragment(); ojf.addCrossJoin( classPersister.getTableName(), name ); addFromType( name, classPersister.getMappedClass(), ojf ); *************** *** 444,448 **** } ! QuerySelect sql = new QuerySelect(); sql.setDistinct(distinct); --- 445,449 ---- } ! QuerySelect sql = new QuerySelect( factory.getDialect() ); sql.setDistinct(distinct); *************** *** 656,660 **** if (keyColumnNames.length!=1) throw new QueryException("composite-key collection in filter: " + collectionRole); ! JoinFragment join = new QueryJoinFragment(); if ( persister.isOneToMany() ) { join.addCrossJoin( persister.getQualifiedTableName(), elementName ); --- 657,661 ---- if (keyColumnNames.length!=1) throw new QueryException("composite-key collection in filter: " + collectionRole); ! JoinFragment join = createJoinFragment(); if ( persister.isOneToMany() ) { join.addCrossJoin( persister.getQualifiedTableName(), elementName ); *************** *** 837,841 **** return (row.length==1) ? row[0] : row; } ! } --- 838,845 ---- return (row.length==1) ? row[0] : row; } ! } ! ! QueryJoinFragment createJoinFragment() { ! return new QueryJoinFragment( factory.getDialect() ); } Index: WhereParser.java =================================================================== RCS file: /cvsroot/hibernate/Hibernate2/src/net/sf/hibernate/hql/WhereParser.java,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** WhereParser.java 28 Feb 2003 07:01:28 -0000 1.7 --- WhereParser.java 1 Mar 2003 06:14:10 -0000 1.8 *************** *** 15,19 **** import net.sf.hibernate.persister.Queryable; import net.sf.hibernate.sql.JoinFragment; - import net.sf.hibernate.sql.QueryJoinFragment; import net.sf.hibernate.type.EntityType; import net.sf.hibernate.type.LiteralType; --- 15,18 ---- *************** *** 373,377 **** else { JoinFragment ojf = pathExpressionParser.getWhereJoin(); ! JoinFragment fromClause = new QueryJoinFragment(); fromClause.addJoins( ojf.toFromFragmentString(), StringHelper.EMPTY_STRING ); q.addJoin( pathExpressionParser.getName(), fromClause ); --- 372,376 ---- else { JoinFragment ojf = pathExpressionParser.getWhereJoin(); ! JoinFragment fromClause = q.createJoinFragment(); fromClause.addJoins( ojf.toFromFragmentString(), StringHelper.EMPTY_STRING ); q.addJoin( pathExpressionParser.getName(), fromClause ); |