org.hibernate.hql.internal.ast.tree.QueryNode Java Examples

The following examples show how to use org.hibernate.hql.internal.ast.tree.QueryNode. 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: JoinProcessor.java    From lams with GNU General Public License v2.0 5 votes vote down vote up
private void addJoinNodes(QueryNode query, JoinSequence join, FromElement fromElement) {
	JoinFragment joinFragment = join.toJoinFragment(
			walker.getEnabledFilters(),
			fromElement.useFromFragment() || fromElement.isDereferencedBySuperclassOrSubclassProperty(),
			fromElement.getWithClauseFragment()
	);

	String frag = joinFragment.toFromFragmentString();
	String whereFrag = joinFragment.toWhereFragmentString();

	// If the from element represents a JOIN_FRAGMENT and it is
	// a theta-style join, convert its type from JOIN_FRAGMENT
	// to FROM_FRAGMENT
	if ( fromElement.getType() == JOIN_FRAGMENT &&
			( join.isThetaStyle() || StringHelper.isNotEmpty( whereFrag ) ) ) {
		fromElement.setType( FROM_FRAGMENT );
		fromElement.getJoinSequence().setUseThetaStyle( true ); // this is used during SqlGenerator processing
	}

	// If there is a FROM fragment and the FROM element is an explicit, then add the from part.
	if ( fromElement.useFromFragment() ||
			( fromElement.getFromClause().isSubQuery()
					&& fromElement.isDereferencedBySuperclassOrSubclassProperty() ) /*&& StringHelper.isNotEmpty( frag )*/ ) {
		String fromFragment = processFromFragment( frag, join ).trim();
		LOG.debugf( "Using FROM fragment [%s]", fromFragment );
		processDynamicFilterParameters(
				fromFragment,
				fromElement,
				walker
		);
	}

	syntheticAndFactory.addWhereFragment(
			joinFragment,
			whereFrag,
			query,
			fromElement,
			walker
	);
}
 
Example #2
Source File: HqlSqlWalker.java    From lams with GNU General Public License v2.0 5 votes vote down vote up
private void createSelectClauseFromFromClause(QueryNode qn) throws SemanticException {
	AST select = astFactory.create( SELECT_CLAUSE, "{derived select clause}" );
	AST sibling = qn.getFromClause();
	qn.setFirstChild( select );
	select.setNextSibling( sibling );
	selectClause = (SelectClause) select;
	selectClause.initializeDerivedSelectClause( currentFromClause );
	LOG.debug( "Derived SELECT clause created." );
}
 
Example #3
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 #4
Source File: QueryLoader.java    From lams with GNU General Public License v2.0 4 votes vote down vote up
@Override
protected String applyLocks(
		String sql,
		QueryParameters parameters,
		Dialect dialect,
		List<AfterLoadAction> afterLoadActions) throws QueryException {
	// can't cache this stuff either (per-invocation)
	// we are given a map of user-alias -> lock mode
	// create a new map of sql-alias -> lock mode

	final LockOptions lockOptions = parameters.getLockOptions();

	if ( lockOptions == null ||
			( lockOptions.getLockMode() == LockMode.NONE && lockOptions.getAliasLockCount() == 0 ) ) {
		return sql;
	}


	// user is request locking, lets see if we can apply locking directly to the SQL...

	// 		some dialects wont allow locking with paging...
	if ( shouldUseFollowOnLocking( parameters, dialect, afterLoadActions ) ) {
		return sql;
	}

	//		there are other conditions we might want to add here, such as checking the result types etc
	//		but those are better served after we have redone the SQL generation to use ASTs.


	// we need both the set of locks and the columns to reference in locks
	// as the ultimate output of this section...
	final LockOptions locks = new LockOptions( lockOptions.getLockMode() );
	final Map<String, String[]> keyColumnNames = dialect.forUpdateOfColumns()
			? new HashMap<>()
			: null;

	locks.setScope( lockOptions.getScope() );
	locks.setTimeOut( lockOptions.getTimeOut() );

	for ( Map.Entry<String, String> entry : sqlAliasByEntityAlias.entrySet() ) {
		final String userAlias = entry.getKey();
		final String drivingSqlAlias = entry.getValue();
		if ( drivingSqlAlias == null ) {
			throw new IllegalArgumentException( "could not locate alias to apply lock mode : " + userAlias );
		}
		// at this point we have (drivingSqlAlias) the SQL alias of the driving table
		// corresponding to the given user alias.  However, the driving table is not
		// (necessarily) the table against which we want to apply locks.  Mainly,
		// the exception case here is joined-subclass hierarchies where we instead
		// want to apply the lock against the root table (for all other strategies,
		// it just happens that driving and root are the same).
		final QueryNode select = (QueryNode) queryTranslator.getSqlAST();
		final Lockable drivingPersister = (Lockable) select.getFromClause()
				.findFromElementByUserOrSqlAlias( userAlias, drivingSqlAlias )
				.getQueryable();
		final String sqlAlias = drivingPersister.getRootTableAlias( drivingSqlAlias );

		final LockMode effectiveLockMode = lockOptions.getEffectiveLockMode( userAlias );
		locks.setAliasSpecificLockMode( sqlAlias, effectiveLockMode );

		if ( keyColumnNames != null ) {
			keyColumnNames.put( sqlAlias, drivingPersister.getRootTableIdentifierColumnNames() );
		}
	}

	// apply the collected locks and columns
	return dialect.applyLocksToSql( sql, locks, keyColumnNames );
}
 
Example #5
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;
}
 
Example #6
Source File: QueryTranslatorImpl.java    From lams with GNU General Public License v2.0 4 votes vote down vote up
@Override
public boolean containsCollectionFetches() {
	errorIfDML();
	List collectionFetches = ( (QueryNode) sqlAst ).getFromClause().getCollectionFetches();
	return collectionFetches != null && collectionFetches.size() > 0;
}
 
Example #7
Source File: QueryTranslatorImpl.java    From lams with GNU General Public License v2.0 4 votes vote down vote up
@Override
public void validateScrollability() throws HibernateException {
	// Impl Note: allows multiple collection fetches as long as the
	// entire fecthed graph still "points back" to a single
	// root entity for return

	errorIfDML();

	final QueryNode query = (QueryNode) sqlAst;

	// If there are no collection fetches, then no further checks are needed
	List collectionFetches = query.getFromClause().getCollectionFetches();
	if ( collectionFetches.isEmpty() ) {
		return;
	}

	// A shallow query is ok (although technically there should be no fetching here...)
	if ( isShallowQuery() ) {
		return;
	}

	// Otherwise, we have a non-scalar select with defined collection fetch(es).
	// Make sure that there is only a single root entity in the return (no tuples)
	if ( getReturnTypes().length > 1 ) {
		throw new HibernateException( "cannot scroll with collection fetches and returned tuples" );
	}

	FromElement owner = null;
	for ( Object o : query.getSelectClause().getFromElementsForLoad() ) {
		// should be the first, but just to be safe...
		final FromElement fromElement = (FromElement) o;
		if ( fromElement.getOrigin() == null ) {
			owner = fromElement;
			break;
		}
	}

	if ( owner == null ) {
		throw new HibernateException( "unable to locate collection fetch(es) owner for scrollability checks" );
	}

	// This is not strictly true.  We actually just need to make sure that
	// it is ordered by root-entity PK and that that order-by comes before
	// any non-root-entity ordering...

	AST primaryOrdering = query.getOrderByClause().getFirstChild();
	if ( primaryOrdering != null ) {
		// TODO : this is a bit dodgy, come up with a better way to check this (plus see above comment)
		String [] idColNames = owner.getQueryable().getIdentifierColumnNames();
		String expectedPrimaryOrderSeq = String.join(
				", ",
				StringHelper.qualify( owner.getTableAlias(), idColNames )
		);
		if (  !primaryOrdering.getText().startsWith( expectedPrimaryOrderSeq ) ) {
			throw new HibernateException( "cannot scroll results with collection fetches which are not ordered primarily by the root entity's PK" );
		}
	}
}