use of org.hibernate.hql.internal.ast.tree.FromElement in project hibernate-orm by hibernate.
the class PersistentTableBulkIdStrategy method buildUpdateHandler.
@Override
public UpdateHandler buildUpdateHandler(SessionFactoryImplementor factory, HqlSqlWalker walker) {
final UpdateStatement updateStatement = (UpdateStatement) walker.getAST();
final FromElement fromElement = updateStatement.getFromClause().getFromElement();
final Queryable targetedPersister = fromElement.getQueryable();
return new UpdateHandlerImpl(factory, walker, getIdTableInfo(targetedPersister));
}
use of org.hibernate.hql.internal.ast.tree.FromElement in project hibernate-orm by hibernate.
the class QueryTranslatorImpl method validateScrollability.
@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;
}
// 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");
}
}
}
use of org.hibernate.hql.internal.ast.tree.FromElement in project hibernate-orm by hibernate.
the class HqlSqlWalker method processQuery.
@Override
protected void processQuery(AST select, AST query) throws SemanticException {
if (LOG.isDebugEnabled()) {
LOG.debugf("processQuery() : %s", query.toStringTree());
}
try {
QueryNode qn = (QueryNode) query;
// Was there an explicit select expression?
boolean explicitSelect = select != null && select.getNumberOfChildren() > 0;
// Add in the EntityGraph attribute nodes.
if (queryTranslatorImpl.getEntityGraphQueryHint() != null) {
final boolean oldInEntityGraph = inEntityGraph;
try {
inEntityGraph = true;
qn.getFromClause().getFromElements().addAll(queryTranslatorImpl.getEntityGraphQueryHint().toFromElements(qn.getFromClause(), this));
} finally {
inEntityGraph = oldInEntityGraph;
}
}
if (!explicitSelect) {
// No explicit select expression; render the id and properties
// projection lists for every persister in the from clause into
// a single 'token node'.
// TODO: the only reason we need this stuff now is collection filters,
// we should get rid of derived select clause completely!
createSelectClauseFromFromClause(qn);
} else {
// Use the explicitly declared select expression; determine the
// return types indicated by each select token
useSelectClause(select);
}
// After that, process the JOINs.
// Invoke a delegate to do the work, as this is farily complex.
JoinProcessor joinProcessor = new JoinProcessor(this);
joinProcessor.processJoins(qn);
// Attach any mapping-defined "ORDER BY" fragments
Iterator itr = qn.getFromClause().getProjectionList().iterator();
while (itr.hasNext()) {
final FromElement fromElement = (FromElement) itr.next();
// if ( fromElement.isFetch() && fromElement.isCollectionJoin() ) {
if (fromElement.isFetch() && fromElement.getQueryableCollection() != null) {
// the query's order-by
if (fromElement.getQueryableCollection().hasOrdering()) {
String orderByFragment = fromElement.getQueryableCollection().getSQLOrderByString(fromElement.getCollectionTableAlias());
qn.getOrderByClause().addOrderFragment(orderByFragment);
}
if (fromElement.getQueryableCollection().hasManyToManyOrdering()) {
String orderByFragment = fromElement.getQueryableCollection().getManyToManyOrderByString(fromElement.getTableAlias());
qn.getOrderByClause().addOrderFragment(orderByFragment);
}
}
}
} finally {
popFromClause();
}
}
use of org.hibernate.hql.internal.ast.tree.FromElement in project hibernate-orm by hibernate.
the class HqlSqlWalker method postProcessDML.
protected void postProcessDML(RestrictableStatement statement) throws SemanticException {
statement.getFromClause().resolve();
FromElement fromElement = (FromElement) statement.getFromClause().getFromElements().get(0);
Queryable persister = fromElement.getQueryable();
// Make #@%$^#^&# sure no alias is applied to the table name
fromElement.setText(persister.getTableName());
// }
if (persister.getDiscriminatorType() != null || !queryTranslatorImpl.getEnabledFilters().isEmpty()) {
new SyntheticAndFactory(this).addDiscriminatorWhereFragment(statement, persister, queryTranslatorImpl.getEnabledFilters(), fromElement.getTableAlias());
}
}
use of org.hibernate.hql.internal.ast.tree.FromElement in project hibernate-orm by hibernate.
the class QueryTranslatorImpl method buildAppropriateStatementExecutor.
private StatementExecutor buildAppropriateStatementExecutor(HqlSqlWalker walker) {
final Statement statement = (Statement) walker.getAST();
if (walker.getStatementType() == HqlSqlTokenTypes.DELETE) {
final FromElement fromElement = walker.getFinalFromClause().getFromElement();
final Queryable persister = fromElement.getQueryable();
if (persister.isMultiTable()) {
return new MultiTableDeleteExecutor(walker);
} else {
return new DeleteExecutor(walker, persister);
}
} else if (walker.getStatementType() == HqlSqlTokenTypes.UPDATE) {
final FromElement fromElement = walker.getFinalFromClause().getFromElement();
final Queryable persister = fromElement.getQueryable();
if (persister.isMultiTable()) {
// TODO : decide if it is better performance-wise to doAfterTransactionCompletion that check, or to simply use the MultiTableUpdateDelegate
return new MultiTableUpdateExecutor(walker);
} else {
return new BasicExecutor(walker, persister);
}
} else if (walker.getStatementType() == HqlSqlTokenTypes.INSERT) {
return new BasicExecutor(walker, ((InsertStatement) statement).getIntoClause().getQueryable());
} else {
throw new QueryException("Unexpected statement type");
}
}
Aggregations