Search in sources :

Example 1 with Every

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());
    }
}
Also used : ComparisonOperator(org.hibernate.query.sqm.ComparisonOperator) Expression(org.hibernate.sql.ast.tree.expression.Expression) BinaryArithmeticExpression(org.hibernate.sql.ast.tree.expression.BinaryArithmeticExpression) SelfRenderingExpression(org.hibernate.sql.ast.tree.expression.SelfRenderingExpression) OrderedSetAggregateFunctionExpression(org.hibernate.sql.ast.tree.expression.OrderedSetAggregateFunctionExpression) CaseSimpleExpression(org.hibernate.sql.ast.tree.expression.CaseSimpleExpression) SqlSelectionExpression(org.hibernate.sql.ast.tree.expression.SqlSelectionExpression) CaseSearchedExpression(org.hibernate.sql.ast.tree.expression.CaseSearchedExpression) ModifiedSubQueryExpression(org.hibernate.sql.ast.tree.expression.ModifiedSubQueryExpression) QueryPart(org.hibernate.sql.ast.tree.select.QueryPart) Every(org.hibernate.sql.ast.tree.expression.Every) SqlTuple(org.hibernate.sql.ast.tree.expression.SqlTuple) Any(org.hibernate.sql.ast.tree.expression.Any) QueryGroup(org.hibernate.sql.ast.tree.select.QueryGroup)

Aggregations

ComparisonOperator (org.hibernate.query.sqm.ComparisonOperator)1 Any (org.hibernate.sql.ast.tree.expression.Any)1 BinaryArithmeticExpression (org.hibernate.sql.ast.tree.expression.BinaryArithmeticExpression)1 CaseSearchedExpression (org.hibernate.sql.ast.tree.expression.CaseSearchedExpression)1 CaseSimpleExpression (org.hibernate.sql.ast.tree.expression.CaseSimpleExpression)1 Every (org.hibernate.sql.ast.tree.expression.Every)1 Expression (org.hibernate.sql.ast.tree.expression.Expression)1 ModifiedSubQueryExpression (org.hibernate.sql.ast.tree.expression.ModifiedSubQueryExpression)1 OrderedSetAggregateFunctionExpression (org.hibernate.sql.ast.tree.expression.OrderedSetAggregateFunctionExpression)1 SelfRenderingExpression (org.hibernate.sql.ast.tree.expression.SelfRenderingExpression)1 SqlSelectionExpression (org.hibernate.sql.ast.tree.expression.SqlSelectionExpression)1 SqlTuple (org.hibernate.sql.ast.tree.expression.SqlTuple)1 QueryGroup (org.hibernate.sql.ast.tree.select.QueryGroup)1 QueryPart (org.hibernate.sql.ast.tree.select.QueryPart)1