2727import org .hibernate .sql .ast .tree .expression .CaseSimpleExpression ;
2828import org .hibernate .sql .ast .tree .expression .ColumnReference ;
2929import org .hibernate .sql .ast .tree .expression .Expression ;
30+ import org .hibernate .sql .ast .tree .expression .JdbcLiteral ;
3031import org .hibernate .sql .ast .tree .expression .Literal ;
3132import org .hibernate .sql .ast .tree .expression .QueryLiteral ;
3233import 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