HHH-15580 Emulate lt/gt/le/ge tuple-comparisons when unsupported

This commit is contained in:
Christian Beikov 2022-10-05 15:33:05 +02:00
parent f70d09175a
commit 8193fe6792
2 changed files with 47 additions and 9 deletions

View File

@ -148,6 +148,11 @@ public class HANASqlAstTranslator<T extends JdbcOperation> extends AbstractSqlAs
return false;
}
@Override
protected boolean supportsRowValueConstructorGtLtSyntax() {
return false;
}
@Override
protected String getFromDual() {
return " from sys.dummy";

View File

@ -5691,7 +5691,7 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> 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<T extends JdbcOperation> 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<T extends JdbcOperation> 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<T extends JdbcOperation> 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<T extends JdbcOperation> 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.
* <p/>
@ -5831,6 +5849,21 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
return true;
}
/**
* Is this dialect known to support what ANSI-SQL terms "row value
* constructor" syntax; sometimes called tuple syntax with <code>&lt;</code>, <code>&gt;</code>, <code>&le;</code>
* and <code>&ge;</code> operators.
* <p/>
* 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;