From f12c6c3aeda26d614178db5c79d3f8309eb354a8 Mon Sep 17 00:00:00 2001 From: Christian Beikov Date: Wed, 20 Nov 2024 19:59:56 +0100 Subject: [PATCH] Don't render distinct from predicate on SQL Server versions that don't support it --- .../SQLServerLegacySqlAstTranslator.java | 36 ++++++++++++++++--- .../dialect/SQLServerSqlAstTranslator.java | 36 ++++++++++++++++--- 2 files changed, 64 insertions(+), 8 deletions(-) diff --git a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/SQLServerLegacySqlAstTranslator.java b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/SQLServerLegacySqlAstTranslator.java index fe4b65b029..b3011650f5 100644 --- a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/SQLServerLegacySqlAstTranslator.java +++ b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/SQLServerLegacySqlAstTranslator.java @@ -492,10 +492,28 @@ public class SQLServerLegacySqlAstTranslator extends Ab && lhsExpressionType.getSingleJdbcMapping().getJdbcType().getDdlTypeCode() == SqlTypes.SQLXML ) { // In SQL Server, XMLTYPE is not "comparable", so we have to cast the two parts to varchar for this purpose switch ( operator ) { - case EQUAL: - case NOT_DISTINCT_FROM: - case NOT_EQUAL: case DISTINCT_FROM: + if ( !supportsDistinctFromPredicate() ) { + appendSql( "not " ); + } + case NOT_DISTINCT_FROM: { + if ( !supportsDistinctFromPredicate() ) { + appendSql( "exists (select cast(" ); + getClauseStack().push( Clause.SELECT ); + visitSqlSelectExpression( lhs ); + appendSql( " as nvarchar(max))" ); + appendSql( getFromDualForSelectOnly() ); + appendSql( " intersect select cast(" ); + visitSqlSelectExpression( rhs ); + appendSql( " as nvarchar(max))" ); + appendSql( getFromDualForSelectOnly() ); + getClauseStack().pop(); + appendSql( CLOSE_PARENTHESIS ); + return; + } + } + case EQUAL: + case NOT_EQUAL: appendSql( "cast(" ); lhs.accept( this ); appendSql( " as nvarchar(max))" ); @@ -509,7 +527,17 @@ public class SQLServerLegacySqlAstTranslator extends Ab break; } } - renderComparisonEmulateIntersect( lhs, operator, rhs ); + if ( supportsDistinctFromPredicate() ) { + renderComparisonStandard( lhs, operator, rhs ); + } + else { + renderComparisonEmulateIntersect( lhs, operator, rhs ); + } + } + + @Override + protected boolean supportsDistinctFromPredicate() { + return getDialect().getVersion().isSameOrAfter( 16 ); } @Override diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/SQLServerSqlAstTranslator.java b/hibernate-core/src/main/java/org/hibernate/dialect/SQLServerSqlAstTranslator.java index 6262ab70a8..4df00fa290 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/SQLServerSqlAstTranslator.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/SQLServerSqlAstTranslator.java @@ -463,10 +463,28 @@ public class SQLServerSqlAstTranslator extends SqlAstTr && lhsExpressionType.getSingleJdbcMapping().getJdbcType().getDdlTypeCode() == SqlTypes.SQLXML ) { // In SQL Server, XMLTYPE is not "comparable", so we have to cast the two parts to varchar for this purpose switch ( operator ) { - case EQUAL: - case NOT_DISTINCT_FROM: - case NOT_EQUAL: case DISTINCT_FROM: + if ( !supportsDistinctFromPredicate() ) { + appendSql( "not " ); + } + case NOT_DISTINCT_FROM: { + if ( !supportsDistinctFromPredicate() ) { + appendSql( "exists (select cast(" ); + getClauseStack().push( Clause.SELECT ); + visitSqlSelectExpression( lhs ); + appendSql( " as nvarchar(max))" ); + appendSql( getFromDualForSelectOnly() ); + appendSql( " intersect select cast(" ); + visitSqlSelectExpression( rhs ); + appendSql( " as nvarchar(max))" ); + appendSql( getFromDualForSelectOnly() ); + getClauseStack().pop(); + appendSql( CLOSE_PARENTHESIS ); + return; + } + } + case EQUAL: + case NOT_EQUAL: appendSql( "cast(" ); lhs.accept( this ); appendSql( " as nvarchar(max))" ); @@ -480,7 +498,17 @@ public class SQLServerSqlAstTranslator extends SqlAstTr break; } } - renderComparisonEmulateIntersect( lhs, operator, rhs ); + if ( supportsDistinctFromPredicate() ) { + renderComparisonStandard( lhs, operator, rhs ); + } + else { + renderComparisonEmulateIntersect( lhs, operator, rhs ); + } + } + + @Override + protected boolean supportsDistinctFromPredicate() { + return getDialect().getVersion().isSameOrAfter( 16 ); } @Override