Skip to content

Commit 4776883

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 19d77c3 commit 4776883

File tree

3 files changed

+313
-209
lines changed

3 files changed

+313
-209
lines changed

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

Lines changed: 57 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -357,8 +357,39 @@ protected void renderOffsetExpression(Expression offsetExpression) {
357357

358358
@Override
359359
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
361360
final boolean isLob = isLob( lhs.getExpressionType() );
361+
final boolean isNullComparison = rhs instanceof Literal && ((Literal)rhs).getLiteralValue() == null ||
362+
lhs instanceof Literal && ((Literal)lhs).getLiteralValue() == null;
363+
364+
if ( !getDialect().isAnsiNullOn()) {
365+
// The ansinull setting only matters if using a parameter or literal and the eq operator according to the docs
366+
// http://infocenter.sybase.com/help/index.jsp?topic=/com.sybase.infocenter.dc32300.1570/html/sqlug/sqlug89.htm
367+
boolean rhsNotNullPredicate = lhs instanceof Literal || isParameter( lhs );
368+
boolean lhsNotNullPredicate = rhs instanceof Literal || isParameter( rhs );
369+
if ( rhsNotNullPredicate || lhsNotNullPredicate ) {
370+
switch ( operator ) {
371+
case EQUAL:
372+
lhs.accept( this );
373+
appendSql( isLob ? " like " : operator.sqlText() );
374+
rhs.accept( this );
375+
// Comparisons of null with '=' or '!=' operators should not return any results
376+
if ( isNullComparison ) {
377+
appendSql( " and 1 = 0 " );
378+
}
379+
return;
380+
case NOT_EQUAL:
381+
lhs.accept( this );
382+
appendSql( isLob ? " not like " : operator.sqlText() );
383+
rhs.accept( this );
384+
// Comparisons of null with '=' or '!=' operators should not return any results
385+
if ( isNullComparison ) {
386+
appendSql( " and 1 = 0 " );
387+
}
388+
return;
389+
}
390+
}
391+
}
392+
// In Sybase ASE, XMLTYPE is not "comparable", so we have to cast the two parts to varchar for this purpose
362393
if ( isLob ) {
363394
switch ( operator ) {
364395
case EQUAL:
@@ -371,108 +402,39 @@ protected void renderComparison(Expression lhs, ComparisonOperator operator, Exp
371402
appendSql( " not like " );
372403
rhs.accept( this );
373404
return;
405+
case DISTINCT_FROM:
406+
appendSql( "case when " );
407+
lhs.accept( this );
408+
appendSql( " like " );
409+
rhs.accept( this );
410+
appendSql( " or " );
411+
lhs.accept( this );
412+
appendSql( " is null and " );
413+
rhs.accept( this );
414+
appendSql( " is null then 0 else 1 end=1" );
415+
return;
416+
case NOT_DISTINCT_FROM:
417+
appendSql( "case when " );
418+
lhs.accept( this );
419+
appendSql( " like " );
420+
rhs.accept( this );
421+
appendSql( " or " );
422+
lhs.accept( this );
423+
appendSql( " is null and " );
424+
rhs.accept( this );
425+
appendSql( " is null then 0 else 1 end=0" );
426+
return;
374427
default:
375428
// Fall through
376429
break;
377430
}
378431
}
379432
// 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-
}
433+
if ( supportsDistinctFromPredicate() ) {
434+
renderComparisonEmulateIntersect( lhs, operator, rhs );
416435
}
417436
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-
}
437+
renderComparisonEmulateCase( lhs, operator, rhs );
476438
}
477439
}
478440

0 commit comments

Comments
 (0)