Skip to content

Commit eade814

Browse files
committed
HHH-16216 - Extend the test cases and fix some errors wrt null comparisons in Sybase ASE
Signed-off-by: Jan Schatteman <[email protected]>
1 parent 8fd9c4b commit eade814

File tree

3 files changed

+315
-209
lines changed

3 files changed

+315
-209
lines changed

hibernate-core/src/main/java/org/hibernate/dialect/SybaseASESqlAstTranslator.java

Lines changed: 59 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import org.hibernate.sql.ast.tree.expression.CaseSimpleExpression;
2828
import org.hibernate.sql.ast.tree.expression.ColumnReference;
2929
import org.hibernate.sql.ast.tree.expression.Expression;
30+
import org.hibernate.sql.ast.tree.expression.JdbcLiteral;
3031
import org.hibernate.sql.ast.tree.expression.Literal;
3132
import org.hibernate.sql.ast.tree.expression.QueryLiteral;
3233
import org.hibernate.sql.ast.tree.expression.SqlTuple;
@@ -357,8 +358,40 @@ protected void renderOffsetExpression(Expression offsetExpression) {
357358

358359
@Override
359360
protected void renderComparison(Expression lhs, ComparisonOperator operator, Expression rhs) {
360-
// In Sybase ASE, XMLTYPE is not "comparable", so we have to cast the two parts to varchar for this purpose
361361
final boolean isLob = isLob( lhs.getExpressionType() );
362+
final boolean isNullComparison =
363+
(rhs instanceof JdbcLiteral || rhs instanceof QueryLiteral) && ((Literal)rhs).getLiteralValue() == null ||
364+
(lhs instanceof JdbcLiteral || lhs instanceof QueryLiteral) && ((Literal)lhs).getLiteralValue() == null;
365+
366+
if ( !getDialect().isAnsiNullOn()) {
367+
// The ansinull setting only matters if using a parameter or literal and the eq operator according to the docs
368+
// http://infocenter.sybase.com/help/index.jsp?topic=/com.sybase.infocenter.dc32300.1570/html/sqlug/sqlug89.htm
369+
boolean rhsNotNullPredicate = lhs instanceof Literal || isParameter( lhs );
370+
boolean lhsNotNullPredicate = rhs instanceof Literal || isParameter( rhs );
371+
if ( rhsNotNullPredicate || lhsNotNullPredicate ) {
372+
switch ( operator ) {
373+
case EQUAL:
374+
lhs.accept( this );
375+
appendSql( isLob ? " like " : operator.sqlText() );
376+
rhs.accept( this );
377+
// Comparisons of null with '=' or '!=' operators should not return any results
378+
if ( isNullComparison ) {
379+
appendSql( " and 1 = 0 " );
380+
}
381+
return;
382+
case NOT_EQUAL:
383+
lhs.accept( this );
384+
appendSql( isLob ? " not like " : operator.sqlText() );
385+
rhs.accept( this );
386+
// Comparisons of null with '=' or '!=' operators should not return any results
387+
if ( isNullComparison ) {
388+
appendSql( " and 1 = 0 " );
389+
}
390+
return;
391+
}
392+
}
393+
}
394+
// In Sybase ASE, XMLTYPE is not "comparable", so we have to cast the two parts to varchar for this purpose
362395
if ( isLob ) {
363396
switch ( operator ) {
364397
case EQUAL:
@@ -371,108 +404,39 @@ protected void renderComparison(Expression lhs, ComparisonOperator operator, Exp
371404
appendSql( " not like " );
372405
rhs.accept( this );
373406
return;
407+
case DISTINCT_FROM:
408+
appendSql( "case when " );
409+
lhs.accept( this );
410+
appendSql( " like " );
411+
rhs.accept( this );
412+
appendSql( " or " );
413+
lhs.accept( this );
414+
appendSql( " is null and " );
415+
rhs.accept( this );
416+
appendSql( " is null then 0 else 1 end=1" );
417+
return;
418+
case NOT_DISTINCT_FROM:
419+
appendSql( "case when " );
420+
lhs.accept( this );
421+
appendSql( " like " );
422+
rhs.accept( this );
423+
appendSql( " or " );
424+
lhs.accept( this );
425+
appendSql( " is null and " );
426+
rhs.accept( this );
427+
appendSql( " is null then 0 else 1 end=0" );
428+
return;
374429
default:
375430
// Fall through
376431
break;
377432
}
378433
}
379434
// I think intersect is only supported in 16.0 SP3
380-
if ( getDialect().isAnsiNullOn() ) {
381-
if ( isLob ) {
382-
switch ( operator ) {
383-
case DISTINCT_FROM:
384-
appendSql( "case when " );
385-
lhs.accept( this );
386-
appendSql( " like " );
387-
rhs.accept( this );
388-
appendSql( " or " );
389-
lhs.accept( this );
390-
appendSql( " is null and " );
391-
rhs.accept( this );
392-
appendSql( " is null then 0 else 1 end=1" );
393-
return;
394-
case NOT_DISTINCT_FROM:
395-
appendSql( "case when " );
396-
lhs.accept( this );
397-
appendSql( " like " );
398-
rhs.accept( this );
399-
appendSql( " or " );
400-
lhs.accept( this );
401-
appendSql( " is null and " );
402-
rhs.accept( this );
403-
appendSql( " is null then 0 else 1 end=0" );
404-
return;
405-
default:
406-
// Fall through
407-
break;
408-
}
409-
}
410-
if ( supportsDistinctFromPredicate() ) {
411-
renderComparisonEmulateIntersect( lhs, operator, rhs );
412-
}
413-
else {
414-
renderComparisonEmulateCase( lhs, operator, rhs );
415-
}
435+
if ( supportsDistinctFromPredicate() ) {
436+
renderComparisonEmulateIntersect( lhs, operator, rhs );
416437
}
417438
else {
418-
// The ansinull setting only matters if using a parameter or literal and the eq operator according to the docs
419-
// http://infocenter.sybase.com/help/index.jsp?topic=/com.sybase.infocenter.dc32300.1570/html/sqlug/sqlug89.htm
420-
boolean rhsNotNullPredicate =
421-
lhs instanceof Literal
422-
|| isParameter( lhs );
423-
boolean lhsNotNullPredicate =
424-
rhs instanceof Literal
425-
|| isParameter( rhs );
426-
if ( rhsNotNullPredicate || lhsNotNullPredicate ) {
427-
lhs.accept( this );
428-
switch ( operator ) {
429-
case DISTINCT_FROM:
430-
if ( isLob ) {
431-
appendSql( " not like " );
432-
}
433-
else {
434-
appendSql( "<>" );
435-
}
436-
break;
437-
case NOT_DISTINCT_FROM:
438-
if ( isLob ) {
439-
appendSql( " like " );
440-
}
441-
else {
442-
appendSql( '=' );
443-
}
444-
break;
445-
case LESS_THAN:
446-
case GREATER_THAN:
447-
case LESS_THAN_OR_EQUAL:
448-
case GREATER_THAN_OR_EQUAL:
449-
// These operators are not affected by ansinull=off
450-
lhsNotNullPredicate = false;
451-
rhsNotNullPredicate = false;
452-
default:
453-
appendSql( operator.sqlText() );
454-
break;
455-
}
456-
rhs.accept( this );
457-
if ( lhsNotNullPredicate ) {
458-
appendSql( " and " );
459-
lhs.accept( this );
460-
appendSql( " is not null" );
461-
}
462-
if ( rhsNotNullPredicate ) {
463-
appendSql( " and " );
464-
rhs.accept( this );
465-
appendSql( " is not null" );
466-
}
467-
}
468-
else {
469-
if ( supportsDistinctFromPredicate() ) {
470-
renderComparisonEmulateIntersect( lhs, operator, rhs );
471-
}
472-
else {
473-
renderComparisonEmulateCase( lhs, operator, rhs );
474-
}
475-
}
439+
renderComparisonEmulateCase( lhs, operator, rhs );
476440
}
477441
}
478442

0 commit comments

Comments
 (0)