Java Code Examples for org.hibernate.engine.spi.QueryParameters#getRowSelection()

The following examples show how to use org.hibernate.engine.spi.QueryParameters#getRowSelection() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: DynamicBatchingEntityLoaderBuilder.java    From lams with GNU General Public License v2.0 6 votes vote down vote up
private List doTheLoad(String sql, QueryParameters queryParameters, SharedSessionContractImplementor session) throws SQLException {
	final RowSelection selection = queryParameters.getRowSelection();
	final int maxRows = LimitHelper.hasMaxRows( selection ) ?
			selection.getMaxRows() :
			Integer.MAX_VALUE;

	final List<AfterLoadAction> afterLoadActions = new ArrayList<>();
	final SqlStatementWrapper wrapper = executeQueryStatement( sql, queryParameters, false, afterLoadActions, session );
	final ResultSet rs = wrapper.getResultSet();
	final Statement st = wrapper.getStatement();
	try {
		return processResultSet( rs, queryParameters, session, false, null, maxRows, afterLoadActions );
	}
	finally {
		session.getJdbcCoordinator().getLogicalConnection().getResourceRegistry().release( st );
		session.getJdbcCoordinator().afterStatementExecution();
	}
}
 
Example 2
Source File: DynamicBatchingCollectionInitializerBuilder.java    From lams with GNU General Public License v2.0 6 votes vote down vote up
private void doTheLoad(String sql, QueryParameters queryParameters, SharedSessionContractImplementor session) throws SQLException {
	final RowSelection selection = queryParameters.getRowSelection();
	final int maxRows = LimitHelper.hasMaxRows( selection ) ?
			selection.getMaxRows() :
			Integer.MAX_VALUE;

	final List<AfterLoadAction> afterLoadActions = Collections.emptyList();
	final SqlStatementWrapper wrapper = executeQueryStatement( sql, queryParameters, false, afterLoadActions, session );
	final ResultSet rs = wrapper.getResultSet();
	final Statement st = wrapper.getStatement();
	try {
		processResultSet( rs, queryParameters, session, true, null, maxRows, afterLoadActions );
	}
	finally {
		session.getJdbcCoordinator().getLogicalConnection().getResourceRegistry().release( st );
		session.getJdbcCoordinator().afterStatementExecution();
	}
}
 
Example 3
Source File: Loader.java    From lams with GNU General Public License v2.0 5 votes vote down vote up
private List doQuery(
			final SharedSessionContractImplementor session,
			final QueryParameters queryParameters,
			final boolean returnProxies,
			final ResultTransformer forcedResultTransformer) throws SQLException, HibernateException {

		final RowSelection selection = queryParameters.getRowSelection();
		final int maxRows = LimitHelper.hasMaxRows( selection ) ?
				selection.getMaxRows() :
				Integer.MAX_VALUE;

		final List<AfterLoadAction> afterLoadActions = new ArrayList<AfterLoadAction>();

		final SqlStatementWrapper wrapper = executeQueryStatement( queryParameters, false, afterLoadActions, session );
		final ResultSet rs = wrapper.getResultSet();
		final Statement st = wrapper.getStatement();

// would be great to move all this below here into another method that could also be used
// from the new scrolling stuff.
//
// Would need to change the way the max-row stuff is handled (i.e. behind an interface) so
// that I could do the control breaking at the means to know when to stop

		try {
			return processResultSet(
					rs,
					queryParameters,
					session,
					returnProxies,
					forcedResultTransformer,
					maxRows,
					afterLoadActions
			);
		}
		finally {
			session.getJdbcCoordinator().getLogicalConnection().getResourceRegistry().release( st );
			session.getJdbcCoordinator().afterStatementExecution();
		}

	}
 
Example 4
Source File: ReactiveQueryTranslatorImpl.java    From hibernate-reactive with GNU Lesser General Public License v2.1 4 votes vote down vote up
public CompletionStage<List<Object>> reactiveList(SharedSessionContractImplementor session, QueryParameters queryParameters) throws HibernateException {
	// Delegate to the QueryLoader...
	errorIfDML();

	final QueryNode query = (QueryNode) getSqlAST();
	final boolean hasLimit =
			queryParameters.getRowSelection() != null
					&& queryParameters.getRowSelection().definesLimits();
	final boolean needsDistincting =
			( query.getSelectClause().isDistinct() || getEntityGraphQueryHint() != null || hasLimit )
					&& containsCollectionFetches();

	QueryParameters queryParametersToUse;
	if ( hasLimit && containsCollectionFetches() ) {
		boolean fail = session.getFactory().getSessionFactoryOptions().isFailOnPaginationOverCollectionFetchEnabled();
		if (fail) {
			throw new HibernateException("firstResult/maxResults specified with collection fetch. " +
												 "In memory pagination was about to be applied. " +
												 "Failing because 'Fail on pagination over collection fetch' is enabled.");
		}
		else {
			LOG.firstOrMaxResultsSpecifiedWithCollectionFetch();
		}
		RowSelection selection = new RowSelection();
		selection.setFetchSize( queryParameters.getRowSelection().getFetchSize() );
		selection.setTimeout( queryParameters.getRowSelection().getTimeout() );
		queryParametersToUse = queryParameters.createCopyUsing( selection );
	}
	else {
		queryParametersToUse = queryParameters;
	}

	return queryLoader.reactiveList( (SessionImplementor) session, queryParametersToUse )
			.thenApply(results -> {
				if ( needsDistincting ) {
					int includedCount = -1;
					// NOTE : firstRow is zero-based
					int first = !hasLimit || queryParameters.getRowSelection().getFirstRow() == null
							? 0
							: queryParameters.getRowSelection().getFirstRow();
					int max = !hasLimit || queryParameters.getRowSelection().getMaxRows() == null
							? -1
							: queryParameters.getRowSelection().getMaxRows();
					List<Object> tmp = new ArrayList<>();
					IdentitySet distinction = new IdentitySet();
					for ( final Object result : results ) {
						if ( !distinction.add( result ) ) {
							continue;
						}
						includedCount++;
						if ( includedCount < first ) {
							continue;
						}
						tmp.add( result );
						// NOTE : ( max - 1 ) because first is zero-based while max is not...
						if ( max >= 0 && ( includedCount - first ) >= ( max - 1 ) ) {
							break;
						}
					}
					return tmp;
				}
				return results;
			});
}
 
Example 5
Source File: Loader.java    From lams with GNU General Public License v2.0 4 votes vote down vote up
/**
 * Obtain a <tt>PreparedStatement</tt> with all parameters pre-bound.
 * Bind JDBC-style <tt>?</tt> parameters, named parameters, and
 * limit parameters.
 */
protected final PreparedStatement prepareQueryStatement(
		String sql,
		final QueryParameters queryParameters,
		final LimitHandler limitHandler,
		final boolean scroll,
		final SharedSessionContractImplementor session) throws SQLException, HibernateException {
	final Dialect dialect = getFactory().getDialect();
	final RowSelection selection = queryParameters.getRowSelection();
	final boolean useLimit = LimitHelper.useLimit( limitHandler, selection );
	final boolean hasFirstRow = LimitHelper.hasFirstRow( selection );
	final boolean useLimitOffset = hasFirstRow && useLimit && limitHandler.supportsLimitOffset();
	final boolean callable = queryParameters.isCallable();
	final ScrollMode scrollMode = getScrollMode( scroll, hasFirstRow, useLimitOffset, queryParameters );

	PreparedStatement st = session.getJdbcCoordinator().getStatementPreparer().prepareQueryStatement(
			sql,
			callable,
			scrollMode
	);

	try {

		int col = 1;
		//TODO: can we limit stored procedures ?!
		col += limitHandler.bindLimitParametersAtStartOfQuery( selection, st, col );

		if ( callable ) {
			col = dialect.registerResultSetOutParameter( (CallableStatement) st, col );
		}

		col += bindParameterValues( st, queryParameters, col, session );

		col += limitHandler.bindLimitParametersAtEndOfQuery( selection, st, col );

		limitHandler.setMaxRows( selection, st );

		if ( selection != null ) {
			if ( selection.getTimeout() != null ) {
				st.setQueryTimeout( selection.getTimeout() );
			}
			if ( selection.getFetchSize() != null ) {
				st.setFetchSize( selection.getFetchSize() );
			}
		}

		// handle lock timeout...
		LockOptions lockOptions = queryParameters.getLockOptions();
		if ( lockOptions != null ) {
			if ( lockOptions.getTimeOut() != LockOptions.WAIT_FOREVER ) {
				if ( !dialect.supportsLockTimeouts() ) {
					if ( LOG.isDebugEnabled() ) {
						LOG.debugf(
								"Lock timeout [%s] requested but dialect reported to not support lock timeouts",
								lockOptions.getTimeOut()
						);
					}
				}
				else if ( dialect.isLockTimeoutParameterized() ) {
					st.setInt( col++, lockOptions.getTimeOut() );
				}
			}
		}

		if ( LOG.isTraceEnabled() ) {
			LOG.tracev( "Bound [{0}] parameters total", col );
		}
	}
	catch (SQLException | HibernateException e) {
		session.getJdbcCoordinator().getLogicalConnection().getResourceRegistry().release( st );
		session.getJdbcCoordinator().afterStatementExecution();
		throw e;
	}

	return st;
}
 
Example 6
Source File: ResultSetProcessorImpl.java    From lams with GNU General Public License v2.0 4 votes vote down vote up
@Override
public List extractResults(
		ResultSet resultSet,
		final SharedSessionContractImplementor session,
		QueryParameters queryParameters,
		NamedParameterContext namedParameterContext,
		boolean returnProxies,
		boolean readOnly,
		ResultTransformer forcedResultTransformer,
		List<AfterLoadAction> afterLoadActionList) throws SQLException {

	handlePotentiallyEmptyCollectionRootReturns( loadPlan, queryParameters.getCollectionKeys(), resultSet, session );

	final int maxRows;
	final RowSelection selection = queryParameters.getRowSelection();
	if ( LimitHelper.hasMaxRows( selection ) ) {
		maxRows = selection.getMaxRows();
		LOG.tracef( "Limiting ResultSet processing to just %s rows", maxRows );
	}
	else {
		maxRows = Integer.MAX_VALUE;
	}

	// Handles the "FETCH ALL PROPERTIES" directive in HQL
	final boolean forceFetchLazyAttributes = false;

	final ResultSetProcessingContextImpl context = new ResultSetProcessingContextImpl(
			resultSet,
			session,
			loadPlan,
			aliasResolutionContext,
			readOnly,
			shouldUseOptionalEntityInstance,
			forceFetchLazyAttributes,
			returnProxies,
			queryParameters,
			namedParameterContext,
			hadSubselectFetches
	);

	final List loadResults = new ArrayList();

	LOG.trace( "Processing result set" );
	int count;
	for ( count = 0; count < maxRows && resultSet.next(); count++ ) {
		LOG.debugf( "Starting ResultSet row #%s", count );

		Object logicalRow = rowReader.readRow( resultSet, context );

		// todo : apply transformers here?

		loadResults.add( logicalRow );

		context.finishUpRow();
	}

	LOG.tracev( "Done processing result set ({0} rows)", count );

	rowReader.finishUp( context, afterLoadActionList );
	context.wrapUp();

	session.getPersistenceContext().initializeNonLazyCollections();

	return loadResults;
}
 
Example 7
Source File: AbstractLoadPlanBasedLoader.java    From lams with GNU General Public License v2.0 4 votes vote down vote up
/**
 * Obtain a <tt>PreparedStatement</tt> with all parameters pre-bound.
 * Bind JDBC-style <tt>?</tt> parameters, named parameters, and
 * limit parameters.
 */
protected final PreparedStatement prepareQueryStatement(
		final String sql,
		final QueryParameters queryParameters,
		final LimitHandler limitHandler,
		final boolean scroll,
		final SharedSessionContractImplementor session) throws SQLException, HibernateException {
	final Dialect dialect = session.getJdbcServices().getJdbcEnvironment().getDialect();
	final RowSelection selection = queryParameters.getRowSelection();
	final boolean useLimit = LimitHelper.useLimit( limitHandler, selection );
	final boolean hasFirstRow = LimitHelper.hasFirstRow( selection );
	final boolean useLimitOffset = hasFirstRow && useLimit && limitHandler.supportsLimitOffset();
	final boolean callable = queryParameters.isCallable();
	final ScrollMode scrollMode = getScrollMode( scroll, hasFirstRow, useLimitOffset, queryParameters );

	final PreparedStatement st = session.getJdbcCoordinator()
			.getStatementPreparer().prepareQueryStatement( sql, callable, scrollMode );

	try {

		int col = 1;
		//TODO: can we limit stored procedures ?!
		col += limitHandler.bindLimitParametersAtStartOfQuery( selection, st, col );

		if (callable) {
			col = dialect.registerResultSetOutParameter( (CallableStatement)st, col );
		}

		col += bindParameterValues( st, queryParameters, col, session );

		col += limitHandler.bindLimitParametersAtEndOfQuery( selection, st, col );

		limitHandler.setMaxRows( selection, st );

		if ( selection != null ) {
			if ( selection.getTimeout() != null ) {
				st.setQueryTimeout( selection.getTimeout() );
			}
			if ( selection.getFetchSize() != null ) {
				st.setFetchSize( selection.getFetchSize() );
			}
		}

		// handle lock timeout...
		final LockOptions lockOptions = queryParameters.getLockOptions();
		if ( lockOptions != null ) {
			if ( lockOptions.getTimeOut() != LockOptions.WAIT_FOREVER ) {
				if ( !dialect.supportsLockTimeouts() ) {
					if ( log.isDebugEnabled() ) {
						log.debugf(
								"Lock timeout [%s] requested but dialect reported to not support lock timeouts",
								lockOptions.getTimeOut()
						);
					}
				}
				else if ( dialect.isLockTimeoutParameterized() ) {
					st.setInt( col++, lockOptions.getTimeOut() );
				}
			}
		}

		if ( log.isTraceEnabled() ) {
			log.tracev( "Bound [{0}] parameters total", col );
		}
	}
	catch ( SQLException sqle ) {
		session.getJdbcCoordinator().getResourceRegistry().release( st );
		session.getJdbcCoordinator().afterStatementExecution();
		throw sqle;
	}
	catch ( HibernateException he ) {
		session.getJdbcCoordinator().getResourceRegistry().release( st );
		session.getJdbcCoordinator().afterStatementExecution();
		throw he;
	}

	return st;
}
 
Example 8
Source File: HQLQueryPlan.java    From lams with GNU General Public License v2.0 4 votes vote down vote up
/**
 * Coordinates the efforts to perform a list across all the included query translators.
 *
 * @param queryParameters The query parameters
 * @param session The session
 *
 * @return The query result list
 *
 * @throws HibernateException Indicates a problem performing the query
 */
@SuppressWarnings("unchecked")
public List performList(
		QueryParameters queryParameters,
		SharedSessionContractImplementor session) throws HibernateException {
	if ( traceEnabled ) {
		LOG.tracev( "Find: {0}", getSourceQuery() );
		queryParameters.traceParameters( session.getFactory() );
	}

	final RowSelection rowSelection = queryParameters.getRowSelection();
	final boolean hasLimit = rowSelection != null
			&& rowSelection.definesLimits();
	final boolean needsLimit = hasLimit && translators.length > 1;

	final QueryParameters queryParametersToUse;
	if ( needsLimit ) {
		LOG.needsLimit();
		final RowSelection selection = new RowSelection();
		selection.setFetchSize( queryParameters.getRowSelection().getFetchSize() );
		selection.setTimeout( queryParameters.getRowSelection().getTimeout() );
		queryParametersToUse = queryParameters.createCopyUsing( selection );
	}
	else {
		queryParametersToUse = queryParameters;
	}

	//fast path to avoid unnecessary allocation and copying
	if ( translators.length == 1 ) {
		return translators[0].list( session, queryParametersToUse );
	}
	final int guessedResultSize = guessResultSize( rowSelection );
	final List combinedResults = new ArrayList( guessedResultSize );
	final IdentitySet distinction;
	if ( needsLimit ) {
		distinction = new IdentitySet( guessedResultSize );
	}
	else {
		distinction = null;
	}
	int includedCount = -1;
	translator_loop:
	for ( QueryTranslator translator : translators ) {
		final List tmp = translator.list( session, queryParametersToUse );
		if ( needsLimit ) {
			// NOTE : firstRow is zero-based
			final int first = queryParameters.getRowSelection().getFirstRow() == null
					? 0
					: queryParameters.getRowSelection().getFirstRow();
			final int max = queryParameters.getRowSelection().getMaxRows() == null
					? -1
					: queryParameters.getRowSelection().getMaxRows();
			for ( final Object result : tmp ) {
				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;
}
 
Example 9
Source File: NativeSQLQueryPlan.java    From lams with GNU General Public License v2.0 4 votes vote down vote up
/**
 * Performs the execute query
 *
 * @param queryParameters The query parameters
 * @param session The session
 *
 * @return The number of affected rows as returned by the JDBC driver
 *
 * @throws HibernateException Indicates a problem performing the query execution
 */
public int performExecuteUpdate(
		QueryParameters queryParameters,
		SharedSessionContractImplementor session) throws HibernateException {

	coordinateSharedCacheCleanup( session );

	if ( queryParameters.isCallable() ) {
		throw new IllegalArgumentException("callable not yet supported for native queries");
	}

	int result = 0;
	PreparedStatement ps;
	RowSelection selection = queryParameters.getRowSelection();
	try {
		queryParameters.processFilters( this.customQuery.getSQL(), session );
		final String sql = session.getJdbcServices().getDialect()
				.addSqlHintOrComment(
					queryParameters.getFilteredSQL(),
					queryParameters,
					session.getFactory().getSessionFactoryOptions().isCommentsEnabled()
				);

		ps = session.getJdbcCoordinator().getStatementPreparer().prepareStatement( sql, false );

		try {
			int col = 1;
			for ( ParameterBinder binder : this.customQuery.getParameterValueBinders() ) {
				col += binder.bind( ps, queryParameters, session, col );
			}
			if ( selection != null && selection.getTimeout() != null ) {
				ps.setQueryTimeout( selection.getTimeout() );
			}
			result = session.getJdbcCoordinator().getResultSetReturn().executeUpdate( ps );
		}
		finally {
			if ( ps != null ) {
				session.getJdbcCoordinator().getLogicalConnection().getResourceRegistry().release( ps );
				session.getJdbcCoordinator().afterStatementExecution();
			}
		}
	}
	catch (SQLException sqle) {
		throw session.getFactory().getSQLExceptionHelper().convert(
				sqle,
				"could not execute native bulk manipulation query",
				this.sourceQuery
		);
	}

	return result;
}
 
Example 10
Source File: QueryKey.java    From lams with GNU General Public License v2.0 4 votes vote down vote up
/**
 * Generates a QueryKey.
 *
 * @param queryString The sql query string.
 * @param queryParameters The query parameters
 * @param filterKeys The keys of any enabled filters.
 * @param session The current session.
 * @param customTransformer The result transformer; should be null if data is not transformed before being cached.
 *
 * @return The generate query cache key.
 */
public static QueryKey generateQueryKey(
		String queryString,
		QueryParameters queryParameters,
		Set filterKeys,
		SharedSessionContractImplementor session,
		CacheableResultTransformer customTransformer) {
	// disassemble positional parameters
	final int positionalParameterCount = queryParameters.getPositionalParameterTypes().length;
	final Type[] types = new Type[positionalParameterCount];
	final Object[] values = new Object[positionalParameterCount];
	for ( int i = 0; i < positionalParameterCount; i++ ) {
		types[i] = queryParameters.getPositionalParameterTypes()[i];
		values[i] = types[i].disassemble( queryParameters.getPositionalParameterValues()[i], session, null );
	}

	// disassemble named parameters
	final Map<String,TypedValue> namedParameters;
	if ( queryParameters.getNamedParameters() == null ) {
		namedParameters = null;
	}
	else {
		namedParameters = CollectionHelper.mapOfSize( queryParameters.getNamedParameters().size() );
		for ( Map.Entry<String,TypedValue> namedParameterEntry : queryParameters.getNamedParameters().entrySet() ) {
			namedParameters.put(
					namedParameterEntry.getKey(),
					new TypedValue(
							namedParameterEntry.getValue().getType(),
							namedParameterEntry.getValue().getType().disassemble(
									namedParameterEntry.getValue().getValue(),
									session,
									null
							)
					)
			);
		}
	}

	// decode row selection...
	final RowSelection selection = queryParameters.getRowSelection();
	final Integer firstRow;
	final Integer maxRows;
	if ( selection != null ) {
		firstRow = selection.getFirstRow();
		maxRows = selection.getMaxRows();
	}
	else {
		firstRow = null;
		maxRows = null;
	}

	return new QueryKey(
			queryString,
			types,
			values,
			namedParameters,
			firstRow,
			maxRows,
			filterKeys,
			session.getTenantIdentifier(),
			customTransformer
	);
}
 
Example 11
Source File: BasicExecutor.java    From lams with GNU General Public License v2.0 4 votes vote down vote up
protected int doExecute(QueryParameters parameters, SharedSessionContractImplementor session, String sql,
		List parameterSpecifications) throws HibernateException {
	BulkOperationCleanupAction action = new BulkOperationCleanupAction( session, persister );
	if ( session.isEventSource() ) {
		( (EventSource) session ).getActionQueue().addAction( action );
	}
	else {
		action.getAfterTransactionCompletionProcess().doAfterTransactionCompletion( true, session );
	}

	PreparedStatement st = null;
	RowSelection selection = parameters.getRowSelection();

	try {
		try {
			st = session.getJdbcCoordinator().getStatementPreparer().prepareStatement( sql, false );
			Iterator paramSpecItr = parameterSpecifications.iterator();
			int pos = 1;
			while ( paramSpecItr.hasNext() ) {
				final ParameterSpecification paramSpec = (ParameterSpecification) paramSpecItr.next();
				pos += paramSpec.bind( st, parameters, session, pos );
			}
			if ( selection != null ) {
				if ( selection.getTimeout() != null ) {
					st.setQueryTimeout( selection.getTimeout() );
				}
			}

			return session.getJdbcCoordinator().getResultSetReturn().executeUpdate( st );
		}
		finally {
			if ( st != null ) {
				session.getJdbcCoordinator().getLogicalConnection().getResourceRegistry().release( st );
				session.getJdbcCoordinator().afterStatementExecution();
			}
		}
	}
	catch( SQLException sqle ) {
		throw session.getJdbcServices().getSqlExceptionHelper().convert( sqle, "could not execute update query", sql );
	}
}
 
Example 12
Source File: QueryTranslatorImpl.java    From lams with GNU General Public License v2.0 4 votes vote down vote up
@Override
public List list(SharedSessionContractImplementor session, QueryParameters queryParameters)
		throws HibernateException {
	// Delegate to the QueryLoader...
	errorIfDML();

	final QueryNode query = (QueryNode) sqlAst;
	final boolean hasLimit = queryParameters.getRowSelection() != null && queryParameters.getRowSelection().definesLimits();
	final boolean needsDistincting = (
			query.getSelectClause().isDistinct() ||
			getEntityGraphQueryHint() != null ||
			hasLimit )
	&& containsCollectionFetches();

	QueryParameters queryParametersToUse;
	if ( hasLimit && containsCollectionFetches() ) {
		boolean fail = session.getFactory().getSessionFactoryOptions().isFailOnPaginationOverCollectionFetchEnabled();
		if (fail) {
			throw new HibernateException("firstResult/maxResults specified with collection fetch. " +
					"In memory pagination was about to be applied. " +
					"Failing because 'Fail on pagination over collection fetch' is enabled.");
		}
		else {
			LOG.firstOrMaxResultsSpecifiedWithCollectionFetch();
		}
		RowSelection selection = new RowSelection();
		selection.setFetchSize( queryParameters.getRowSelection().getFetchSize() );
		selection.setTimeout( queryParameters.getRowSelection().getTimeout() );
		queryParametersToUse = queryParameters.createCopyUsing( selection );
	}
	else {
		queryParametersToUse = queryParameters;
	}

	List results = queryLoader.list( session, queryParametersToUse );

	if ( needsDistincting ) {
		int includedCount = -1;
		// NOTE : firstRow is zero-based
		int first = !hasLimit || queryParameters.getRowSelection().getFirstRow() == null
					? 0
					: queryParameters.getRowSelection().getFirstRow();
		int max = !hasLimit || queryParameters.getRowSelection().getMaxRows() == null
					? -1
					: queryParameters.getRowSelection().getMaxRows();
		List tmp = new ArrayList();
		IdentitySet distinction = new IdentitySet();
		for ( final Object result : results ) {
			if ( !distinction.add( result ) ) {
				continue;
			}
			includedCount++;
			if ( includedCount < first ) {
				continue;
			}
			tmp.add( result );
			// NOTE : ( max - 1 ) because first is zero-based while max is not...
			if ( max >= 0 && ( includedCount - first ) >= ( max - 1 ) ) {
				break;
			}
		}
		results = tmp;
	}

	return results;
}