FileDocCategorySizeDatePackage
HQLQueryPlan.javaAPI DocHibernate 3.2.510966Wed Jun 28 08:25:00 BST 2006org.hibernate.engine.query

HQLQueryPlan

public class HQLQueryPlan extends Object implements Serializable
Defines a query execution plan for an HQL query (or filter).
author
Steve Ebersole

Fields Summary
private static final Log
log
private final String
sourceQuery
private final org.hibernate.hql.QueryTranslator[]
translators
private final String[]
sqlStrings
private final ParameterMetadata
parameterMetadata
private final ReturnMetadata
returnMetadata
private final Set
querySpaces
private final Set
enabledFilterNames
private final boolean
shallow
Constructors Summary
public HQLQueryPlan(String hql, boolean shallow, Map enabledFilters, org.hibernate.engine.SessionFactoryImplementor factory)



	         
		this( hql, null, shallow, enabledFilters, factory );
	
protected HQLQueryPlan(String hql, String collectionRole, boolean shallow, Map enabledFilters, org.hibernate.engine.SessionFactoryImplementor factory)

		this.sourceQuery = hql;
		this.shallow = shallow;

		Set copy = new HashSet();
		copy.addAll( enabledFilters.keySet() );
		this.enabledFilterNames = java.util.Collections.unmodifiableSet( copy );

		Set combinedQuerySpaces = new HashSet();
		String[] concreteQueryStrings = QuerySplitter.concreteQueries( hql, factory );
		final int length = concreteQueryStrings.length;
		translators = new QueryTranslator[length];
		List sqlStringList = new ArrayList();
		for ( int i=0; i<length; i++ ) {
			if ( collectionRole == null ) {
				translators[i] = factory.getSettings()
						.getQueryTranslatorFactory()
						.createQueryTranslator( hql, concreteQueryStrings[i], enabledFilters, factory );
				translators[i].compile( factory.getSettings().getQuerySubstitutions(), shallow );
			}
			else {
				translators[i] = factory.getSettings()
						.getQueryTranslatorFactory()
						.createFilterTranslator( hql, concreteQueryStrings[i], enabledFilters, factory );
				( ( FilterTranslator ) translators[i] ).compile( collectionRole, factory.getSettings().getQuerySubstitutions(), shallow );
			}
			combinedQuerySpaces.addAll( translators[i].getQuerySpaces() );
			sqlStringList.addAll( translators[i].collectSqlStrings() );
		}

		this.sqlStrings = ArrayHelper.toStringArray( sqlStringList );
		this.querySpaces = combinedQuerySpaces;

		if ( length == 0 ) {
			parameterMetadata = new ParameterMetadata( null, null );
			returnMetadata = null;
		}
		else {
			this.parameterMetadata = buildParameterMetadata( translators[0].getParameterTranslations(), hql );
			if ( translators[0].isManipulationStatement() ) {
				returnMetadata = null;
			}
			else {
				if ( length > 1 ) {
					final int returns = translators[0].getReturnTypes().length;
					returnMetadata = new ReturnMetadata( translators[0].getReturnAliases(), new Type[returns] );
				}
				else {
					returnMetadata = new ReturnMetadata( translators[0].getReturnAliases(), translators[0].getReturnTypes() );
				}
			}
		}
	
Methods Summary
private ParameterMetadatabuildParameterMetadata(org.hibernate.hql.ParameterTranslations parameterTranslations, java.lang.String hql)

		long start = System.currentTimeMillis();
		ParamLocationRecognizer recognizer = ParamLocationRecognizer.parseLocations( hql );
		long end = System.currentTimeMillis();
		if ( log.isTraceEnabled() ) {
			log.trace( "HQL param location recognition took " + (end - start) + " mills (" + hql + ")" );
		}

		int ordinalParamCount = parameterTranslations.getOrdinalParameterCount();
		int[] locations = ArrayHelper.toIntArray( recognizer.getOrdinalParameterLocationList() );
		if ( parameterTranslations.supportsOrdinalParameterMetadata() && locations.length != ordinalParamCount ) {
			throw new HibernateException( "ordinal parameter mismatch" );
		}
		ordinalParamCount = locations.length;
		OrdinalParameterDescriptor[] ordinalParamDescriptors = new OrdinalParameterDescriptor[ordinalParamCount];
		for ( int i = 1; i <= ordinalParamCount; i++ ) {
			ordinalParamDescriptors[ i - 1 ] = new OrdinalParameterDescriptor(
					i,
			        parameterTranslations.supportsOrdinalParameterMetadata()
		                    ? parameterTranslations.getOrdinalParameterExpectedType( i )
		                    : null,
			        locations[ i - 1 ]
			);
		}

		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 ParamLocationRecognizer.NamedParameterDescription description =
					( ParamLocationRecognizer.NamedParameterDescription ) entry.getValue();
			namedParamDescriptorMap.put(
					name,
					new NamedParameterDescriptor(
							name,
					        parameterTranslations.getNamedParameterExpectedType( name ),
					        description.buildPositionsArray(),
					        description.isJpaStyle()
					)
			);
		}

		return new ParameterMetadata( ordinalParamDescriptors, namedParamDescriptorMap );
	
public java.util.SetgetEnabledFilterNames()

		return enabledFilterNames;
	
public ParameterMetadatagetParameterMetadata()

		return parameterMetadata;
	
public java.util.SetgetQuerySpaces()

		return querySpaces;
	
public ReturnMetadatagetReturnMetadata()

		return returnMetadata;
	
public java.lang.StringgetSourceQuery()

		return sourceQuery;
	
public java.lang.String[]getSqlStrings()

		return sqlStrings;
	
public org.hibernate.hql.QueryTranslator[]getTranslators()

		QueryTranslator[] copy = new QueryTranslator[translators.length];
		System.arraycopy(translators, 0, copy, 0, copy.length);
		return copy;
	
public java.util.SetgetUtilizedFilterNames()

		// TODO : add this info to the translator and aggregate it here...
		return null;
	
public booleanisShallow()

		return shallow;
	
public intperformExecuteUpdate(org.hibernate.engine.QueryParameters queryParameters, org.hibernate.engine.SessionImplementor session)

		if ( log.isTraceEnabled() ) {
			log.trace( "executeUpdate: " + getSourceQuery() );
			queryParameters.traceParameters( session.getFactory() );
		}
		if ( translators.length != 1 ) {
			log.warn( "manipulation query [" + getSourceQuery() + "] resulted in [" + translators.length + "] split queries" );
		}
		int result = 0;
		for ( int i = 0; i < translators.length; i++ ) {
			result += translators[i].executeUpdate( queryParameters, session );
		}
		return result;
	
public java.util.IteratorperformIterate(org.hibernate.engine.QueryParameters queryParameters, org.hibernate.event.EventSource session)

		if ( log.isTraceEnabled() ) {
			log.trace( "iterate: " + getSourceQuery() );
			queryParameters.traceParameters( session.getFactory() );
		}
		if ( translators.length == 0 ) {
			return EmptyIterator.INSTANCE;
		}

		Iterator[] results = null;
		boolean many = translators.length > 1;
		if (many) {
			results = new Iterator[translators.length];
		}

		Iterator result = null;
		for ( int i = 0; i < translators.length; i++ ) {
			result = translators[i].iterate( queryParameters, session );
			if (many) results[i] = result;
		}

		return many ? new JoinedIterator(results) : result;
	
public java.util.ListperformList(org.hibernate.engine.QueryParameters queryParameters, org.hibernate.engine.SessionImplementor session)

		if ( log.isTraceEnabled() ) {
			log.trace( "find: " + getSourceQuery() );
			queryParameters.traceParameters( session.getFactory() );
		}
		boolean hasLimit = queryParameters.getRowSelection() != null &&
		                   queryParameters.getRowSelection().definesLimits();
		boolean needsLimit = hasLimit && translators.length > 1;
		QueryParameters queryParametersToUse;
		if ( needsLimit ) {
			log.warn( "firstResult/maxResults specified on polymorphic query; applying in memory!" );
			RowSelection selection = new RowSelection();
			selection.setFetchSize( queryParameters.getRowSelection().getFetchSize() );
			selection.setTimeout( queryParameters.getRowSelection().getTimeout() );
			queryParametersToUse = queryParameters.createCopyUsing( selection );
		}
		else {
			queryParametersToUse = queryParameters;
		}

		List combinedResults = new ArrayList();
		IdentitySet distinction = new IdentitySet();
		int includedCount = -1;
		translator_loop: for ( int i = 0; i < translators.length; i++ ) {
			List tmp = translators[i].list( session, queryParametersToUse );
			if ( needsLimit ) {
				// NOTE : firstRow is zero-based
				int first = queryParameters.getRowSelection().getFirstRow() == null
				            ? 0
			                : queryParameters.getRowSelection().getFirstRow().intValue();
				int max = queryParameters.getRowSelection().getMaxRows() == null
				            ? -1
			                : queryParameters.getRowSelection().getMaxRows().intValue();
				final int size = tmp.size();
				for ( int x = 0; x < size; x++ ) {
					final Object result = tmp.get( x );
					if ( distinction.add( result ) ) {
						continue;
					}
					includedCount++;
					if ( includedCount < first ) {
						continue;
					}
					combinedResults.add( result );
					if ( max >= 0 && includedCount > max ) {
						// break the outer loop !!!
						break translator_loop;
					}
				}
			}
			else {
				combinedResults.addAll( tmp );
			}
		}
		return combinedResults;
	
public org.hibernate.ScrollableResultsperformScroll(org.hibernate.engine.QueryParameters queryParameters, org.hibernate.engine.SessionImplementor session)

		if ( log.isTraceEnabled() ) {
			log.trace( "iterate: " + getSourceQuery() );
			queryParameters.traceParameters( session.getFactory() );
		}
		if ( translators.length != 1 ) {
			throw new QueryException( "implicit polymorphism not supported for scroll() queries" );
		}
		if ( queryParameters.getRowSelection().definesLimits() && translators[0].containsCollectionFetches() ) {
			throw new QueryException( "firstResult/maxResults not supported in conjunction with scroll() of a query containing collection fetches" );
		}

		return translators[0].scroll( queryParameters, session );