Author: ste...@jb... Date: 2006-06-28 09:24:59 -0400 (Wed, 28 Jun 2006) New Revision: 10067 Modified: trunk/Hibernate3/src/org/hibernate/engine/query/HQLQueryPlan.java trunk/Hibernate3/src/org/hibernate/engine/query/NamedParameterDescriptor.java trunk/Hibernate3/src/org/hibernate/engine/query/ParamLocationRecognizer.java trunk/Hibernate3/src/org/hibernate/engine/query/ParameterParser.java trunk/Hibernate3/src/org/hibernate/engine/query/QueryPlanCache.java trunk/Hibernate3/src/org/hibernate/impl/AbstractQueryImpl.java trunk/Hibernate3/src/org/hibernate/loader/custom/sql/SQLQueryParser.java trunk/Hibernate3/test/org/hibernate/test/hql/ASTParserLoadingTest.java Log: HHH-1552 : jpa-positional-param (?1) and param-list Modified: trunk/Hibernate3/src/org/hibernate/engine/query/HQLQueryPlan.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/engine/query/HQLQueryPlan.java 2006-06-28 10:02:24 UTC (rev 10066) +++ trunk/Hibernate3/src/org/hibernate/engine/query/HQLQueryPlan.java 2006-06-28 13:24:59 UTC (rev 10067) @@ -286,18 +286,20 @@ ); } - Iterator itr = recognizer.getNamedParameterLocationMap().entrySet().iterator(); + Iterator itr = recognizer.getNamedParameterDescriptionMap().entrySet().iterator(); Map namedParamDescriptorMap = new HashMap(); while( itr.hasNext() ) { final Map.Entry entry = ( Map.Entry ) itr.next(); final String name = ( String ) entry.getKey(); - final int[] locArray = ArrayHelper.toIntArray( ( List ) entry.getValue() ); + final ParamLocationRecognizer.NamedParameterDescription description = + ( ParamLocationRecognizer.NamedParameterDescription ) entry.getValue(); namedParamDescriptorMap.put( name, new NamedParameterDescriptor( name, parameterTranslations.getNamedParameterExpectedType( name ), - locArray + description.buildPositionsArray(), + description.isJpaStyle() ) ); } Modified: trunk/Hibernate3/src/org/hibernate/engine/query/NamedParameterDescriptor.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/engine/query/NamedParameterDescriptor.java 2006-06-28 10:02:24 UTC (rev 10066) +++ trunk/Hibernate3/src/org/hibernate/engine/query/NamedParameterDescriptor.java 2006-06-28 13:24:59 UTC (rev 10067) @@ -5,17 +5,21 @@ import java.io.Serializable; /** - * @author <a href="mailto:st...@hi...">Steve Ebersole </a> + * Descriptor regarding a named parameter. + * + * @author Steve Ebersole */ public class NamedParameterDescriptor implements Serializable { private final String name; private final Type expectedType; private final int[] sourceLocations; + private final boolean jpaStyle; - public NamedParameterDescriptor(String name, Type expectedType, int[] sourceLocations) { + public NamedParameterDescriptor(String name, Type expectedType, int[] sourceLocations, boolean jpaStyle) { this.name = name; this.expectedType = expectedType; this.sourceLocations = sourceLocations; + this.jpaStyle = jpaStyle; } public String getName() { @@ -29,4 +33,8 @@ public int[] getSourceLocations() { return sourceLocations; } + + public boolean isJpaStyle() { + return jpaStyle; + } } Modified: trunk/Hibernate3/src/org/hibernate/engine/query/ParamLocationRecognizer.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/engine/query/ParamLocationRecognizer.java 2006-06-28 10:02:24 UTC (rev 10066) +++ trunk/Hibernate3/src/org/hibernate/engine/query/ParamLocationRecognizer.java 2006-06-28 13:24:59 UTC (rev 10067) @@ -1,5 +1,7 @@ package org.hibernate.engine.query; +import org.hibernate.util.ArrayHelper; + import java.util.Map; import java.util.HashMap; import java.util.List; @@ -9,10 +11,32 @@ * Implements a parameter parser recognizer specifically for the purpose * of journaling parameter locations. * - * @author <a href="mailto:st...@hi...">Steve Ebersole </a> + * @author Steve Ebersole */ public class ParamLocationRecognizer implements ParameterParser.Recognizer { - private Map namedParameterLocationMap = new HashMap(); + + public static class NamedParameterDescription { + private final boolean jpaStyle; + private final List positions = new ArrayList(); + + public NamedParameterDescription(boolean jpaStyle) { + this.jpaStyle = jpaStyle; + } + + public boolean isJpaStyle() { + return jpaStyle; + } + + private void add(int position) { + positions.add( new Integer( position ) ); + } + + public int[] buildPositionsArray() { + return ArrayHelper.toIntArray( positions ); + } + } + + private Map namedParameterDescriptions = new HashMap(); private List ordinalParameterLocationList = new ArrayList(); /** @@ -30,12 +54,12 @@ /** * Returns the map of named parameter locations. The map is keyed by - * parameter name; the corresponding value is an Integer list. + * parameter name; the corresponding value is a (@link NamedParameterDescription}. * * @return The map of named parameter locations. */ - public Map getNamedParameterLocationMap() { - return namedParameterLocationMap; + public Map getNamedParameterDescriptionMap() { + return namedParameterDescriptions; } /** @@ -58,18 +82,22 @@ } public void namedParameter(String name, int position) { - List locations = ( List ) namedParameterLocationMap.get( name ); - if ( locations == null ) { - locations = new ArrayList(); - namedParameterLocationMap.put( name, locations ); - } - locations.add( new Integer( position ) ); + getOrBuildNamedParameterDescription( name, false ).add( position ); } - public void ejb3PositionalParameter(String name, int position) { - namedParameter( name, position ); + public void jpaPositionalParameter(String name, int position) { + getOrBuildNamedParameterDescription( name, true ).add( position ); } + private NamedParameterDescription getOrBuildNamedParameterDescription(String name, boolean jpa) { + NamedParameterDescription desc = ( NamedParameterDescription ) namedParameterDescriptions.get( name ); + if ( desc == null ) { + desc = new NamedParameterDescription( jpa ); + namedParameterDescriptions.put( name, desc ); + } + return desc; + } + public void other(char character) { // don't care... } Modified: trunk/Hibernate3/src/org/hibernate/engine/query/ParameterParser.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/engine/query/ParameterParser.java 2006-06-28 10:02:24 UTC (rev 10066) +++ trunk/Hibernate3/src/org/hibernate/engine/query/ParameterParser.java 2006-06-28 13:24:59 UTC (rev 10067) @@ -7,7 +7,7 @@ /** * The single available method {@link #parse} is responsible for parsing a * query string and recognizing tokens in relation to parameters (either - * named, ejb3-style, or ordinal) and providing callbacks about such + * named, JPA-style, or ordinal) and providing callbacks about such * recognitions. * * @author <a href="mailto:st...@hi...">Steve Ebersole </a> @@ -18,7 +18,7 @@ public void outParameter(int position); public void ordinalParameter(int position); public void namedParameter(String name, int position); - public void ejb3PositionalParameter(String name, int position); + public void jpaPositionalParameter(String name, int position); public void other(char character); } @@ -68,9 +68,9 @@ indx = chopLocation - 1; } else if ( c == '?' ) { - // could be either an ordinal or ejb3-positional parameter + // could be either an ordinal or JPA-positional parameter if ( indx < stringLength - 1 && Character.isDigit( sqlString.charAt( indx + 1 ) ) ) { - // a peek ahead showed this as an ejb3-positional parameter + // a peek ahead showed this as an JPA-positional parameter int right = StringHelper.firstIndexOfChar( sqlString, ParserHelper.HQL_SEPARATORS, indx + 1 ); int chopLocation = right < 0 ? sqlString.length() : right; String param = sqlString.substring( indx + 1, chopLocation ); @@ -79,9 +79,9 @@ new Integer( param ); } catch( NumberFormatException e ) { - throw new QueryException( "ejb3-style positional param was not an integral ordinal" ); + throw new QueryException( "JPA-style positional param was not an integral ordinal" ); } - recognizer.ejb3PositionalParameter( param, indx ); + recognizer.jpaPositionalParameter( param, indx ); indx = chopLocation - 1; } else { Modified: trunk/Hibernate3/src/org/hibernate/engine/query/QueryPlanCache.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/engine/query/QueryPlanCache.java 2006-06-28 10:02:24 UTC (rev 10066) +++ trunk/Hibernate3/src/org/hibernate/engine/query/QueryPlanCache.java 2006-06-28 13:24:59 UTC (rev 10067) @@ -133,15 +133,16 @@ ordinalDescriptors[i] = new OrdinalParameterDescriptor( i, null, position.intValue() ); } - Iterator itr = recognizer.getNamedParameterLocationMap().entrySet().iterator(); + Iterator itr = recognizer.getNamedParameterDescriptionMap().entrySet().iterator(); Map namedParamDescriptorMap = new HashMap(); while( itr.hasNext() ) { final Map.Entry entry = ( Map.Entry ) itr.next(); final String name = ( String ) entry.getKey(); - final List locationList = ( List ) entry.getValue(); + final ParamLocationRecognizer.NamedParameterDescription description = + ( ParamLocationRecognizer.NamedParameterDescription ) entry.getValue(); namedParamDescriptorMap.put( name , - new NamedParameterDescriptor( name, null, ArrayHelper.toIntArray( locationList ) ) + new NamedParameterDescriptor( name, null, description.buildPositionsArray(), description.isJpaStyle() ) ); } Modified: trunk/Hibernate3/src/org/hibernate/impl/AbstractQueryImpl.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/impl/AbstractQueryImpl.java 2006-06-28 10:02:24 UTC (rev 10066) +++ trunk/Hibernate3/src/org/hibernate/impl/AbstractQueryImpl.java 2006-06-28 13:24:59 UTC (rev 10067) @@ -702,16 +702,20 @@ return query; } - StringBuffer list = new StringBuffer(16); + StringBuffer list = new StringBuffer( 16 ); Iterator iter = vals.iterator(); - int i=0; + int i = 0; + boolean isJpaPositionalParam = parameterMetadata.getNamedParameterDescriptor( name ).isJpaStyle(); while ( iter.hasNext() ) { - String alias = name + i++ + '_'; - namedParamsCopy.put(alias, new TypedValue( type, iter.next(), session.getEntityMode() ) ); + String alias = ( isJpaPositionalParam ? 'x' + name : name ) + i++ + '_'; + namedParamsCopy.put( alias, new TypedValue( type, iter.next(), session.getEntityMode() ) ); list.append( ParserHelper.HQL_VARIABLE_PREFIX ).append( alias ); - if ( iter.hasNext() ) list.append(", "); + if ( iter.hasNext() ) { + list.append( ", " ); + } } - return StringHelper.replace( query, ParserHelper.HQL_VARIABLE_PREFIX + name, list.toString(), true ); + String paramPrefix = isJpaPositionalParam ? "?" : ParserHelper.HQL_VARIABLE_PREFIX; + return StringHelper.replace( query, paramPrefix + name, list.toString(), true ); } public Query setParameterList(String name, Collection vals) throws HibernateException { Modified: trunk/Hibernate3/src/org/hibernate/loader/custom/sql/SQLQueryParser.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/loader/custom/sql/SQLQueryParser.java 2006-06-28 10:02:24 UTC (rev 10066) +++ trunk/Hibernate3/src/org/hibernate/loader/custom/sql/SQLQueryParser.java 2006-06-28 13:24:59 UTC (rev 10067) @@ -246,7 +246,7 @@ result.append( '?' ); } - public void ejb3PositionalParameter(String name, int position) { + public void jpaPositionalParameter(String name, int position) { namedParameter( name, position ); } Modified: trunk/Hibernate3/test/org/hibernate/test/hql/ASTParserLoadingTest.java =================================================================== --- trunk/Hibernate3/test/org/hibernate/test/hql/ASTParserLoadingTest.java 2006-06-28 10:02:24 UTC (rev 10066) +++ trunk/Hibernate3/test/org/hibernate/test/hql/ASTParserLoadingTest.java 2006-06-28 13:24:59 UTC (rev 10067) @@ -35,13 +35,10 @@ import org.hibernate.test.any.StringPropertyValue; import org.hibernate.test.any.IntegerPropertyValue; import org.hibernate.test.any.PropertySet; -import org.hibernate.test.legacy.Bar; -import org.hibernate.test.legacy.One; import org.hibernate.test.cid.Customer; import org.hibernate.test.cid.LineItem; import org.hibernate.test.cid.Order; import org.hibernate.test.cid.Product; -import org.hibernate.transform.AliasToBeanResultTransformer; import org.hibernate.transform.DistinctRootEntityResultTransformer; import org.hibernate.transform.Transformers; import org.hibernate.type.ManyToOneType; @@ -67,8 +64,7 @@ private List createdAnimalIds = new ArrayList(); public static Test suite() { - TestSuite suite = new TestSuite( ASTParserLoadingTest.class ); - return suite; + return new TestSuite( ASTParserLoadingTest.class ); } protected String[] getMappings() { @@ -93,6 +89,19 @@ } + public void testJPAPositionalParameterList() { + Session s = openSession(); + s.beginTransaction(); + ArrayList params = new ArrayList(); + params.add( "Doe" ); + params.add( "Public" ); + s.createQuery( "from Human where name.last in (?1)" ) + .setParameterList( "1", params ) + .list(); + s.getTransaction().commit(); + s.close(); + } + public void testComponentQueries() { Session s = openSession(); s.beginTransaction(); |