From 8193fe679257446b369f1169760a40ff579b7587 Mon Sep 17 00:00:00 2001 From: Christian Beikov Date: Wed, 5 Oct 2022 15:33:05 +0200 Subject: [PATCH] HHH-15580 Emulate lt/gt/le/ge tuple-comparisons when unsupported --- .../dialect/HANASqlAstTranslator.java | 5 ++ .../sql/ast/spi/AbstractSqlAstTranslator.java | 51 +++++++++++++++---- 2 files changed, 47 insertions(+), 9 deletions(-) diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/HANASqlAstTranslator.java b/hibernate-core/src/main/java/org/hibernate/dialect/HANASqlAstTranslator.java index 72d9005e82..07e2bf47d5 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/HANASqlAstTranslator.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/HANASqlAstTranslator.java @@ -148,6 +148,11 @@ public class HANASqlAstTranslator extends AbstractSqlAs return false; } + @Override + protected boolean supportsRowValueConstructorGtLtSyntax() { + return false; + } + @Override protected String getFromDual() { return " from sys.dummy"; diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/AbstractSqlAstTranslator.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/AbstractSqlAstTranslator.java index 6de549f536..bf439eefe5 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/AbstractSqlAstTranslator.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/AbstractSqlAstTranslator.java @@ -5691,7 +5691,7 @@ public abstract class AbstractSqlAstTranslator implemen } else if ( subquery != null && !supportsRowValueConstructorSyntaxInQuantifiedPredicates() ) { // For quantified relational comparisons, we can do an optimized emulation - if ( supportsRowValueConstructorSyntax() && all ) { + if ( !needsTupleComparisonEmulation( operator ) && all ) { switch ( operator ) { case LESS_THAN: case LESS_THAN_OR_EQUAL: @@ -5705,12 +5705,16 @@ public abstract class AbstractSqlAstTranslator implemen ); return; } - } - // If we get here, this is an equality-like comparison, though we support scalar row value comparison - // For this special case, we can rely on scalar subquery handling, given that the subquery fetches only one row - if ( isFetchFirstRowOnly( subquery ) ) { - renderComparison( lhsTuple, operator, subquery ); - return; + case NOT_EQUAL: + case EQUAL: + case DISTINCT_FROM: + case NOT_DISTINCT_FROM: { + // For this special case, we can rely on scalar subquery handling, given that the subquery fetches only one row + if ( isFetchFirstRowOnly( subquery ) ) { + renderComparison( lhsTuple, operator, subquery ); + return; + } + } } } emulateSubQueryRelationalRestrictionPredicate( @@ -5722,7 +5726,7 @@ public abstract class AbstractSqlAstTranslator implemen all ? operator.negated() : operator ); } - else if ( !supportsRowValueConstructorSyntax() ) { + else if ( needsTupleComparisonEmulation( operator ) ) { rhsTuple = SqlTupleContainer.getSqlTuple( rhsExpression ); assert rhsTuple != null; // Some DBs like Oracle support tuples only for the IN subquery predicate @@ -5760,7 +5764,7 @@ public abstract class AbstractSqlAstTranslator implemen rhsTuple.getExpressions().get( 0 ) ); } - else if ( supportsRowValueConstructorSyntax() ) { + else if ( !needsTupleComparisonEmulation( comparisonPredicate.getOperator() ) ) { renderComparison( lhsExpression, comparisonPredicate.getOperator(), @@ -5793,6 +5797,20 @@ public abstract class AbstractSqlAstTranslator implemen } } + private boolean needsTupleComparisonEmulation(ComparisonOperator operator) { + if ( !supportsRowValueConstructorSyntax() ) { + return true; + } + switch ( operator ) { + case LESS_THAN: + case LESS_THAN_OR_EQUAL: + case GREATER_THAN: + case GREATER_THAN_OR_EQUAL: + return !supportsRowValueConstructorGtLtSyntax(); + } + return false; + } + /** * Is this dialect known to support quantified predicates. *

@@ -5831,6 +5849,21 @@ public abstract class AbstractSqlAstTranslator implemen return true; } + /** + * Is this dialect known to support what ANSI-SQL terms "row value + * constructor" syntax; sometimes called tuple syntax with <, >, + * and operators. + *

+ * Basically, does it support syntax like + * "... where (FIRST_NAME, LAST_NAME) < ('Steve', 'Ebersole') ...". + * + * @return True if this SQL dialect is known to support "row value + * constructor" syntax with relational comparison operators; false otherwise. + */ + protected boolean supportsRowValueConstructorGtLtSyntax() { + return supportsRowValueConstructorSyntax(); + } + /** * Is this dialect known to support what ANSI-SQL terms "row value constructor" syntax, * sometimes called tuple syntax, in the SET clause;