From: <one...@us...> - 2003-01-18 09:03:57
|
Update of /cvsroot/hibernate/Hibernate2/src/net/sf/hibernate/hql In directory sc8-pr-cvs1:/tmp/cvs-serv29740/sf/hibernate/hql Modified Files: QueryTranslator.java Log Message: implemented outerjoin fetching for single-column queries Index: QueryTranslator.java =================================================================== RCS file: /cvsroot/hibernate/Hibernate2/src/net/sf/hibernate/hql/QueryTranslator.java,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** QueryTranslator.java 12 Jan 2003 15:04:51 -0000 1.5 --- QueryTranslator.java 18 Jan 2003 09:03:54 -0000 1.6 *************** *** 16,22 **** import java.util.StringTokenizer; - import org.apache.commons.logging.Log; - import org.apache.commons.logging.LogFactory; - import net.sf.hibernate.Hibernate; import net.sf.hibernate.HibernateException; --- 16,19 ---- *************** *** 29,43 **** import net.sf.hibernate.engine.SessionImplementor; import net.sf.hibernate.engine.TypedValue; - import net.sf.hibernate.util.ArrayHelper; - import net.sf.hibernate.util.JDBCExceptionReporter; - import net.sf.hibernate.util.ReflectHelper; - import net.sf.hibernate.util.StringHelper; import net.sf.hibernate.impl.IteratorImpl; import net.sf.hibernate.impl.ScrollableResultsImpl; - import net.sf.hibernate.engine.TypedValue; import net.sf.hibernate.loader.Loader; ! import net.sf.hibernate.persister.*; import net.sf.hibernate.type.EntityType; import net.sf.hibernate.type.Type; /** --- 26,45 ---- import net.sf.hibernate.engine.SessionImplementor; import net.sf.hibernate.engine.TypedValue; import net.sf.hibernate.impl.IteratorImpl; import net.sf.hibernate.impl.ScrollableResultsImpl; import net.sf.hibernate.loader.Loader; ! 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.type.EntityType; import net.sf.hibernate.type.Type; + import net.sf.hibernate.util.ArrayHelper; + import net.sf.hibernate.util.JDBCExceptionReporter; + import net.sf.hibernate.util.ReflectHelper; + import net.sf.hibernate.util.StringHelper; + + import org.apache.commons.logging.Log; + import org.apache.commons.logging.LogFactory; /** *************** *** 105,108 **** --- 107,111 ---- protected boolean compiled; + private boolean hasScalars; private boolean shallowQuery; private QueryTranslator superQuery; *************** *** 195,199 **** protected boolean hasScalarValues() { ! return types.length!=persisters.length; } --- 198,202 ---- protected boolean hasScalarValues() { ! return hasScalars; } *************** *** 419,422 **** --- 422,427 ---- } + private List associations; + private void renderSQL() throws QueryException, MappingException { *************** *** 426,437 **** } int size = returnTypes.size(); ! ! persisters = new Queryable[size]; ! suffixes = new String[size]; ! for ( int i=0; i<size; i++ ) { ! String name = (String) returnTypes.get(i); if ( !isName(name) ) throw new QueryException("unknown type: " + name); ! persisters[i] = getPersisterForName(name); ! suffixes[i] = (size==1) ? "" : Integer.toString(i); } --- 431,475 ---- } int size = returnTypes.size(); ! ! String outerJoinedProperties=null; ! String outerJoinsAfterFrom=null; ! String outerJoinsAfterWhere=null; ! String selectProperties; ! String selectIdentifiers; ! if ( !isShallowQuery() && size==1 ) { ! OuterJoinLoader ojl = new OuterJoinLoader( factory.getDialect() ); ! String name = (String) returnTypes.get(0); if ( !isName(name) ) throw new QueryException("unknown type: " + name); ! Queryable persister = getPersisterForName(name); ! associations = ojl.walkTree(persister, name, factory); ! int joins=associations.size(); ! String[] ojsuffixes = new String[joins]; ! ojl.setSuffixed(ojsuffixes); ! for ( int i=0; i<joins; i++ ) ojsuffixes[i] = Integer.toString(i); ! selectProperties = persister.propertySelectClauseFragment(name, ""); ! selectIdentifiers = persister.selectIdentifierString(name, ""); ! outerJoinedProperties = ojl.selectString(associations); ! outerJoinsAfterFrom = ojl.outerJoinsAfterFrom(associations); ! outerJoinsAfterWhere = ojl.outerJoinsAfterWhere(associations); ! persisters = new Queryable[joins+1]; ! suffixes = new String[joins+1]; ! persisters[joins] = persister; ! suffixes[joins] = ""; ! for ( int i=0; i<joins; i++ ) { ! suffixes[i] = Integer.toString(i); ! persisters[i] = (Queryable) ( (OuterJoinableAssociation) associations.get(i) ).subpersister; //TODO: dont like the typecast to Queryable ! } ! } ! else { ! persisters = new Queryable[size]; ! suffixes = new String[size]; ! for ( int i=0; i<size; i++ ) { ! String name = (String) returnTypes.get(i); ! if ( !isName(name) ) throw new QueryException("unknown type: " + name); ! persisters[i] = getPersisterForName(name); ! suffixes[i] = (size==1) ? "" : Integer.toString(i); ! } ! selectProperties = renderPropertiesSelect(); ! selectIdentifiers = renderIdentifierSelect(); } *************** *** 440,452 **** String selectScalars = renderScalarSelect(); scalarSelectString = selectPerhapsDistinct + selectScalars; ! String selectIdentifiers = renderIdentifierSelect(); ! selectPropertiesString = selectPerhapsDistinct + selectIdentifiers + renderPropertiesSelect(); //TODO: for some dialiects it would be appropriate to add the renderOrderByPropertiesSelect() to other select strings ! fromWhereString = renderFromClause() + renderWhereClause(); if ( scalarTypes.size()!=size ) { if (size!=0) selectPropertiesString += ", "; selectPropertiesString += selectScalars; } int scalarSize = scalarTypes.size(); --- 478,497 ---- String selectScalars = renderScalarSelect(); scalarSelectString = selectPerhapsDistinct + selectScalars; ! selectPropertiesString = selectPerhapsDistinct + selectIdentifiers + selectProperties; ! 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(); ! if (outerJoinsAfterFrom!=null) fromWhereString += outerJoinsAfterFrom; ! if (outerJoinsAfterWhere!=null) fromWhereString += outerJoinsAfterWhere; ! fromWhereString += renderWhereClause(); if ( scalarTypes.size()!=size ) { + hasScalars=true; if (size!=0) selectPropertiesString += ", "; selectPropertiesString += selectScalars; } + else { + hasScalars=false; + } int scalarSize = scalarTypes.size(); *************** *** 879,882 **** --- 924,964 ---- return names; } + + public final List find( + SessionImplementor session, + Object[] values, + Type[] types, + boolean returnProxies, + RowSelection selection, + Map namedParams) + throws SQLException, HibernateException { + return super.find(session, values, types, returnProxies, selection, namedParams); + } + + protected Object getResultColumnOrRow(Object[] row, ResultSet rs, SessionImplementor session) throws SQLException, HibernateException { + Type[] returnTypes = getReturnTypes(); + if (hasScalars) { + String[][] names = getScalarColumnNames(); + int queryCols = returnTypes.length; + if ( queryCols==1 ) { + return returnTypes[0].nullSafeGet( rs, names[0], session, null ); + } + else { + Object[] queryRow = new Object[queryCols]; + for ( int i=0; i<queryCols; i++ ) + queryRow[i] = returnTypes[i].nullSafeGet( rs, names[i], session, null ); + return queryRow; + } + } + else if ( returnTypes.length==1 && persisters.length>1 ) { + // we are doing some outerjoining + return row[ persisters.length-1 ]; + } + else { + return (row.length==1) ? row[0] : row; + } + + } + } |