use of org.hibernate.sql.ast.tree.predicate.Predicate in project hibernate-orm by hibernate.
the class EmbeddedForeignKeyDescriptor method isSimpleJoinPredicate.
@Override
public boolean isSimpleJoinPredicate(Predicate predicate) {
if (!(predicate instanceof Junction)) {
return false;
}
final Junction junction = (Junction) predicate;
if (junction.getNature() != Junction.Nature.CONJUNCTION) {
return false;
}
final List<Predicate> predicates = junction.getPredicates();
if (predicates.size() != keySelectableMappings.getJdbcTypeCount()) {
return false;
}
Boolean lhsIsKey = null;
for (int i = 0; i < predicates.size(); i++) {
final Predicate p = predicates.get(i);
if (!(p instanceof ComparisonPredicate)) {
return false;
}
final ComparisonPredicate comparisonPredicate = (ComparisonPredicate) p;
if (comparisonPredicate.getOperator() != ComparisonOperator.EQUAL) {
return false;
}
final Expression lhsExpr = comparisonPredicate.getLeftHandExpression();
final Expression rhsExpr = comparisonPredicate.getRightHandExpression();
if (!(lhsExpr instanceof ColumnReference) || !(rhsExpr instanceof ColumnReference)) {
return false;
}
final ColumnReference lhs = (ColumnReference) lhsExpr;
final ColumnReference rhs = (ColumnReference) rhsExpr;
if (lhsIsKey == null) {
final String keyExpression = keySelectableMappings.getSelectable(i).getSelectionExpression();
final String targetExpression = targetSelectableMappings.getSelectable(i).getSelectionExpression();
if (keyExpression.equals(targetExpression)) {
if (!lhs.getColumnExpression().equals(keyExpression) || !rhs.getColumnExpression().equals(keyExpression)) {
return false;
}
} else {
if (keyExpression.equals(lhs.getColumnExpression())) {
if (!targetExpression.equals(rhs.getColumnExpression())) {
return false;
}
lhsIsKey = true;
} else if (keyExpression.equals(rhs.getColumnExpression())) {
if (!targetExpression.equals(lhs.getColumnExpression())) {
return false;
}
lhsIsKey = false;
} else {
return false;
}
}
} else {
final String lhsSelectionExpression;
final String rhsSelectionExpression;
if (lhsIsKey) {
lhsSelectionExpression = keySelectableMappings.getSelectable(i).getSelectionExpression();
rhsSelectionExpression = targetSelectableMappings.getSelectable(i).getSelectionExpression();
} else {
lhsSelectionExpression = targetSelectableMappings.getSelectable(i).getSelectionExpression();
rhsSelectionExpression = keySelectableMappings.getSelectable(i).getSelectionExpression();
}
if (!lhs.getColumnExpression().equals(lhsSelectionExpression) || !rhs.getColumnExpression().equals(rhsSelectionExpression)) {
return false;
}
}
}
return true;
}
use of org.hibernate.sql.ast.tree.predicate.Predicate in project hibernate-orm by hibernate.
the class PluralAttributeMappingImpl method createTableGroupJoin.
@Override
public TableGroupJoin createTableGroupJoin(NavigablePath navigablePath, TableGroup lhs, String explicitSourceAlias, SqlAstJoinType requestedJoinType, boolean fetched, boolean addsPredicate, SqlAliasBaseGenerator aliasBaseGenerator, SqlExpressionResolver sqlExpressionResolver, FromClauseAccess fromClauseAccess, SqlAstCreationContext creationContext) {
final SqlAstJoinType joinType;
if (requestedJoinType == null) {
joinType = SqlAstJoinType.INNER;
} else {
joinType = requestedJoinType;
}
final java.util.List<Predicate> predicates = new ArrayList<>(2);
final TableGroup tableGroup = createRootTableGroupJoin(navigablePath, lhs, explicitSourceAlias, requestedJoinType, fetched, predicates::add, aliasBaseGenerator, sqlExpressionResolver, fromClauseAccess, creationContext);
final TableGroupJoin tableGroupJoin = new TableGroupJoin(navigablePath, joinType, tableGroup, null);
predicates.forEach(tableGroupJoin::applyPredicate);
return tableGroupJoin;
}
use of org.hibernate.sql.ast.tree.predicate.Predicate in project hibernate-orm by hibernate.
the class AbstractSqlAstTranslator method visitQuerySpec.
@Override
public void visitQuerySpec(QuerySpec querySpec) {
final QueryPart queryPartForRowNumbering = this.queryPartForRowNumbering;
final int queryPartForRowNumberingClauseDepth = this.queryPartForRowNumberingClauseDepth;
final boolean needsSelectAliases = this.needsSelectAliases;
final Predicate additionalWherePredicate = this.additionalWherePredicate;
final ForUpdateClause forUpdate = this.forUpdate;
try {
this.additionalWherePredicate = null;
this.forUpdate = null;
// See the field documentation of queryPartForRowNumbering etc. for an explanation about this
// In addition, we also reset the row numbering if the currently row numbered query part is a query group
// which means this query spec is a part of that query group.
// We want the row numbering to happen on the query group level, not on the query spec level, so we reset
final QueryPart currentQueryPart = queryPartStack.getCurrent();
if (currentQueryPart != null && (queryPartForRowNumbering instanceof QueryGroup || queryPartForRowNumberingClauseDepth != clauseStack.depth())) {
this.queryPartForRowNumbering = null;
this.queryPartForRowNumberingClauseDepth = -1;
}
String queryGroupAlias = "";
final boolean needsParenthesis;
if (currentQueryPart instanceof QueryGroup) {
// We always need query wrapping if we are in a query group and this query spec has a fetch clause
// because of order by precedence in SQL
needsParenthesis = querySpec.hasOffsetOrFetchClause();
if (needsParenthesis) {
// or if the database does not support simple query grouping, we must use a select wrapper
if (!supportsSimpleQueryGrouping() || currentQueryPart.hasOffsetOrFetchClause()) {
queryGroupAlias = " grp_" + queryGroupAliasCounter + '_';
queryGroupAliasCounter++;
appendSql("select");
appendSql(queryGroupAlias);
appendSql(".* from ");
}
}
} else {
needsParenthesis = !querySpec.isRoot();
}
queryPartStack.push(querySpec);
if (needsParenthesis) {
appendSql(OPEN_PARENTHESIS);
}
visitSelectClause(querySpec.getSelectClause());
visitFromClause(querySpec.getFromClause());
visitWhereClause(querySpec.getWhereClauseRestrictions());
visitGroupByClause(querySpec, getDialect().getGroupBySelectItemReferenceStrategy());
visitHavingClause(querySpec);
visitOrderBy(querySpec.getSortSpecifications());
visitOffsetFetchClause(querySpec);
// We render the FOR UPDATE clause in the parent query
if (queryPartForRowNumbering == null) {
visitForUpdateClause(querySpec);
}
if (needsParenthesis) {
appendSql(CLOSE_PARENTHESIS);
appendSql(queryGroupAlias);
}
} finally {
this.queryPartStack.pop();
this.queryPartForRowNumbering = queryPartForRowNumbering;
this.queryPartForRowNumberingClauseDepth = queryPartForRowNumberingClauseDepth;
this.needsSelectAliases = needsSelectAliases;
this.additionalWherePredicate = additionalWherePredicate;
if (queryPartForRowNumbering == null) {
this.forUpdate = forUpdate;
}
}
}
use of org.hibernate.sql.ast.tree.predicate.Predicate in project hibernate-orm by hibernate.
the class AbstractSqlAstTranslator method emulateSubQueryRelationalRestrictionPredicate.
protected <X extends Expression> void emulateSubQueryRelationalRestrictionPredicate(Predicate predicate, boolean negated, QueryPart queryPart, X lhsTuple, SubQueryRelationalRestrictionEmulationRenderer<X> renderer, ComparisonOperator tupleComparisonOperator) {
final QuerySpec subQuery;
if (queryPart instanceof QuerySpec && queryPart.getFetchClauseExpression() == null && queryPart.getOffsetClauseExpression() == null) {
subQuery = (QuerySpec) queryPart;
// We can only emulate the tuple sub query predicate as exists predicate when there are no limit/offsets
if (negated) {
appendSql("not ");
}
final QueryPart queryPartForRowNumbering = this.queryPartForRowNumbering;
final int queryPartForRowNumberingClauseDepth = this.queryPartForRowNumberingClauseDepth;
final boolean needsSelectAliases = this.needsSelectAliases;
try {
this.queryPartForRowNumbering = null;
this.queryPartForRowNumberingClauseDepth = -1;
this.needsSelectAliases = false;
queryPartStack.push(subQuery);
appendSql("exists (select 1");
visitFromClause(subQuery.getFromClause());
if (!subQuery.getGroupByClauseExpressions().isEmpty() || subQuery.getHavingClauseRestrictions() != null) {
// If we have a group by or having clause, we have to move the tuple comparison emulation to the HAVING clause
visitWhereClause(subQuery.getWhereClauseRestrictions());
visitGroupByClause(subQuery, SelectItemReferenceStrategy.EXPRESSION);
appendSql(" having ");
clauseStack.push(Clause.HAVING);
try {
renderer.renderComparison(subQuery.getSelectClause().getSqlSelections(), lhsTuple, tupleComparisonOperator);
final Predicate havingClauseRestrictions = subQuery.getHavingClauseRestrictions();
if (havingClauseRestrictions != null) {
appendSql(" and (");
havingClauseRestrictions.accept(this);
appendSql(CLOSE_PARENTHESIS);
}
} finally {
clauseStack.pop();
}
} else {
// If we have no group by or having clause, we can move the tuple comparison emulation to the WHERE clause
appendSql(" where ");
clauseStack.push(Clause.WHERE);
try {
renderer.renderComparison(subQuery.getSelectClause().getSqlSelections(), lhsTuple, tupleComparisonOperator);
final Predicate whereClauseRestrictions = subQuery.getWhereClauseRestrictions();
if (whereClauseRestrictions != null) {
appendSql(" and (");
whereClauseRestrictions.accept(this);
appendSql(CLOSE_PARENTHESIS);
}
} finally {
clauseStack.pop();
}
}
appendSql(CLOSE_PARENTHESIS);
} finally {
queryPartStack.pop();
this.queryPartForRowNumbering = queryPartForRowNumbering;
this.queryPartForRowNumberingClauseDepth = queryPartForRowNumberingClauseDepth;
this.needsSelectAliases = needsSelectAliases;
}
} else {
// TODO: We could use nested queries and use row numbers to emulate this
throw new IllegalArgumentException("Can't emulate in predicate with tuples and limit/offset or set operations: " + predicate);
}
}
use of org.hibernate.sql.ast.tree.predicate.Predicate in project hibernate-orm by hibernate.
the class AbstractSqlAstTranslator method visitDecodeCaseSearchedExpression.
protected void visitDecodeCaseSearchedExpression(CaseSearchedExpression caseSearchedExpression) {
appendSql("decode( ");
final SqlAstNodeRenderingMode original = this.parameterRenderingMode;
final List<CaseSearchedExpression.WhenFragment> whenFragments = caseSearchedExpression.getWhenFragments();
final int caseNumber = whenFragments.size();
CaseSearchedExpression.WhenFragment firstWhenFragment = null;
for (int i = 0; i < caseNumber; i++) {
final CaseSearchedExpression.WhenFragment whenFragment = whenFragments.get(i);
Predicate predicate = whenFragment.getPredicate();
if (original != SqlAstNodeRenderingMode.INLINE_ALL_PARAMETERS) {
this.parameterRenderingMode = SqlAstNodeRenderingMode.DEFAULT;
}
if (i != 0) {
appendSql(',');
getLeftHandExpression(predicate).accept(this);
this.parameterRenderingMode = original;
appendSql(',');
whenFragment.getResult().accept(this);
} else {
getLeftHandExpression(predicate).accept(this);
firstWhenFragment = whenFragment;
}
}
this.parameterRenderingMode = original;
appendSql(',');
firstWhenFragment.getResult().accept(this);
final Expression otherwise = caseSearchedExpression.getOtherwise();
if (otherwise != null) {
appendSql(',');
otherwise.accept(this);
}
appendSql(CLOSE_PARENTHESIS);
}
Aggregations