@@ -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