Skip to content

Commit

Permalink
HHH-15580 Emulate lt/gt/le/ge tuple-comparisons when unsupported
Browse files Browse the repository at this point in the history
  • Loading branch information
beikov committed Oct 5, 2022
1 parent f70d091 commit 8193fe6
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 9 deletions.
Expand Up @@ -148,6 +148,11 @@ protected boolean supportsRowValueConstructorSyntaxInQuantifiedPredicates() {
return false;
}

@Override
protected boolean supportsRowValueConstructorGtLtSyntax() {
return false;
}

@Override
protected String getFromDual() {
return " from sys.dummy";
Expand Down
Expand Up @@ -5691,7 +5691,7 @@ else if ( rhsExpression instanceof Any ) {
}
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:
Expand All @@ -5705,12 +5705,16 @@ else if ( subquery != null && !supportsRowValueConstructorSyntaxInQuantifiedPred
);
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(
Expand All @@ -5722,7 +5726,7 @@ else if ( subquery != null && !supportsRowValueConstructorSyntaxInQuantifiedPred
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
Expand Down Expand Up @@ -5760,7 +5764,7 @@ else if ( ( rhsTuple = SqlTupleContainer.getSqlTuple( comparisonPredicate.getRig
rhsTuple.getExpressions().get( 0 )
);
}
else if ( supportsRowValueConstructorSyntax() ) {
else if ( !needsTupleComparisonEmulation( comparisonPredicate.getOperator() ) ) {
renderComparison(
lhsExpression,
comparisonPredicate.getOperator(),
Expand Down Expand Up @@ -5793,6 +5797,20 @@ else if ( supportsRowValueConstructorSyntax() ) {
}
}

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/>
Expand Down Expand Up @@ -5831,6 +5849,21 @@ protected boolean supportsRowValueConstructorSyntax() {
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;
Expand Down

0 comments on commit 8193fe6

Please sign in to comment.