use of org.hibernate.sql.ast.tree.expression.Every in project hibernate-orm by hibernate.
the class AbstractSqlAstTranslator method visitRelationalPredicate.
@Override
public void visitRelationalPredicate(ComparisonPredicate comparisonPredicate) {
// todo (6.0) : do we want to allow multi-valued parameters in a relational predicate?
// yes means we'd have to support dynamically converting this predicate into
// an IN predicate or an OR predicate
//
// NOTE: JPA does not define support for multi-valued parameters here.
//
// If we decide to support that ^^ we should validate that *both* sides of the
// predicate are multi-valued parameters. because...
// well... its stupid :)
final SqlTuple lhsTuple;
final SqlTuple rhsTuple;
if ((lhsTuple = SqlTupleContainer.getSqlTuple(comparisonPredicate.getLeftHandExpression())) != null) {
final Expression rhsExpression = comparisonPredicate.getRightHandExpression();
final boolean all;
final QueryPart subquery;
// Handle emulation of quantified comparison
if (rhsExpression instanceof QueryPart) {
subquery = (QueryPart) rhsExpression;
all = true;
} else if (rhsExpression instanceof Every) {
subquery = ((Every) rhsExpression).getSubquery();
all = true;
} else if (rhsExpression instanceof Any) {
subquery = ((Any) rhsExpression).getSubquery();
all = false;
} else {
subquery = null;
all = false;
}
final ComparisonOperator operator = comparisonPredicate.getOperator();
if (lhsTuple.getExpressions().size() == 1) {
// Special case for tuples with arity 1 as any DBMS supports scalar IN predicates
if (subquery == null) {
renderComparison(lhsTuple.getExpressions().get(0), operator, SqlTupleContainer.getSqlTuple(comparisonPredicate.getRightHandExpression()).getExpressions().get(0));
} else {
renderComparison(lhsTuple.getExpressions().get(0), operator, rhsExpression);
}
} else if (subquery != null && !supportsRowValueConstructorSyntaxInQuantifiedPredicates()) {
// For quantified relational comparisons, we can do an optimized emulation
if (supportsRowValueConstructorSyntax() && all) {
switch(operator) {
case LESS_THAN:
case LESS_THAN_OR_EQUAL:
case GREATER_THAN:
case GREATER_THAN_OR_EQUAL:
{
emulateQuantifiedTupleSubQueryPredicate(comparisonPredicate, subquery, lhsTuple, operator);
return;
}
}
}
emulateSubQueryRelationalRestrictionPredicate(comparisonPredicate, all, subquery, lhsTuple, this::renderSelectTupleComparison, all ? operator.negated() : operator);
} else if (!supportsRowValueConstructorSyntax()) {
rhsTuple = SqlTupleContainer.getSqlTuple(rhsExpression);
assert rhsTuple != null;
// Some DBs like Oracle support tuples only for the IN subquery predicate
if ((operator == ComparisonOperator.EQUAL || operator == ComparisonOperator.NOT_EQUAL) && supportsRowValueConstructorSyntaxInInSubQuery()) {
comparisonPredicate.getLeftHandExpression().accept(this);
if (operator == ComparisonOperator.NOT_EQUAL) {
appendSql(" not");
}
appendSql(" in(");
renderExpressionsAsSubquery(rhsTuple.getExpressions());
appendSql(CLOSE_PARENTHESIS);
} else {
emulateTupleComparison(lhsTuple.getExpressions(), rhsTuple.getExpressions(), operator, true);
}
} else {
renderComparison(comparisonPredicate.getLeftHandExpression(), operator, rhsExpression);
}
} else if ((rhsTuple = SqlTupleContainer.getSqlTuple(comparisonPredicate.getRightHandExpression())) != null) {
final Expression lhsExpression = comparisonPredicate.getLeftHandExpression();
if (lhsExpression instanceof QueryGroup) {
if (rhsTuple.getExpressions().size() == 1) {
// Special case for tuples with arity 1 as any DBMS supports scalar IN predicates
renderComparison(lhsExpression, comparisonPredicate.getOperator(), rhsTuple.getExpressions().get(0));
} else if (supportsRowValueConstructorSyntax()) {
renderComparison(lhsExpression, comparisonPredicate.getOperator(), comparisonPredicate.getRightHandExpression());
} else {
emulateSubQueryRelationalRestrictionPredicate(comparisonPredicate, false, (QueryGroup) lhsExpression, rhsTuple, this::renderSelectTupleComparison, // Since we switch the order of operands, we have to invert the operator
comparisonPredicate.getOperator().invert());
}
} else {
throw new IllegalStateException("Unsupported tuple comparison combination. LHS is neither a tuple nor a tuple subquery but RHS is a tuple: " + comparisonPredicate);
}
} else {
renderComparison(comparisonPredicate.getLeftHandExpression(), comparisonPredicate.getOperator(), comparisonPredicate.getRightHandExpression());
}
}
Aggregations