From faf4dd59073bc39cf98e1274e331bafc0c4c6cf1 Mon Sep 17 00:00:00 2001 From: Christian Beikov Date: Thu, 11 Sep 2025 17:16:49 +0200 Subject: [PATCH 1/2] HHH-19768 Make DB2Dialect return true for supportsRowValueConstructorSyntaxInInSubQuery --- .../community/dialect/DB2LegacySqlAstTranslator.java | 9 +++++++-- .../community/dialect/HSQLLegacySqlAstTranslator.java | 7 +++++-- .../java/org/hibernate/dialect/DB2SqlAstTranslator.java | 9 +++++++-- .../java/org/hibernate/dialect/HSQLSqlAstTranslator.java | 7 +++++-- 4 files changed, 24 insertions(+), 8 deletions(-) diff --git a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/DB2LegacySqlAstTranslator.java b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/DB2LegacySqlAstTranslator.java index 5f75a3062dd3..f6e8718b5e26 100644 --- a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/DB2LegacySqlAstTranslator.java +++ b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/DB2LegacySqlAstTranslator.java @@ -597,15 +597,20 @@ protected boolean supportsRowValueConstructorSyntax() { } @Override - protected boolean supportsRowValueConstructorSyntaxInInList() { + protected boolean supportsRowValueConstructorSyntaxInQuantifiedPredicates() { return false; } @Override - protected boolean supportsRowValueConstructorSyntaxInQuantifiedPredicates() { + protected boolean supportsRowValueConstructorSyntaxInInList() { return false; } + @Override + protected boolean supportsRowValueConstructorSyntaxInInSubQuery() { + return true; + } + @Override protected void visitReturningColumns(List returningColumns) { // For DB2 we use #renderReturningClause to render a wrapper around the DML statement diff --git a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/HSQLLegacySqlAstTranslator.java b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/HSQLLegacySqlAstTranslator.java index 1ca3acd135b3..e40a779eeda9 100644 --- a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/HSQLLegacySqlAstTranslator.java +++ b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/HSQLLegacySqlAstTranslator.java @@ -328,16 +328,19 @@ else if ( expression instanceof Summarization ) { @Override protected boolean supportsRowValueConstructorSyntax() { + // It's supported but not usable due to a bug: https://sourceforge.net/p/hsqldb/bugs/1714/ return false; } @Override - protected boolean supportsRowValueConstructorSyntaxInInList() { + protected boolean supportsRowValueConstructorSyntaxInQuantifiedPredicates() { + // It's supported but not usable due to a bug: https://sourceforge.net/p/hsqldb/bugs/1714/ return false; } @Override - protected boolean supportsRowValueConstructorSyntaxInQuantifiedPredicates() { + protected boolean supportsRowValueConstructorSyntaxInInList() { + // It's supported but not usable due to a bug: https://sourceforge.net/p/hsqldb/bugs/1714/ return false; } diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/DB2SqlAstTranslator.java b/hibernate-core/src/main/java/org/hibernate/dialect/DB2SqlAstTranslator.java index daf34f6c1deb..2350522eccd7 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/DB2SqlAstTranslator.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/DB2SqlAstTranslator.java @@ -578,15 +578,20 @@ protected boolean supportsRowValueConstructorSyntax() { } @Override - protected boolean supportsRowValueConstructorSyntaxInInList() { + protected boolean supportsRowValueConstructorSyntaxInQuantifiedPredicates() { return false; } @Override - protected boolean supportsRowValueConstructorSyntaxInQuantifiedPredicates() { + protected boolean supportsRowValueConstructorSyntaxInInList() { return false; } + @Override + protected boolean supportsRowValueConstructorSyntaxInInSubQuery() { + return true; + } + @Override protected void visitReturningColumns(List returningColumns) { // For DB2 we use #renderReturningClause to render a wrapper around the DML statement diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/HSQLSqlAstTranslator.java b/hibernate-core/src/main/java/org/hibernate/dialect/HSQLSqlAstTranslator.java index 1357e12f522c..9ba0d4a5eb9f 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/HSQLSqlAstTranslator.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/HSQLSqlAstTranslator.java @@ -322,16 +322,19 @@ else if ( expression instanceof Summarization ) { @Override protected boolean supportsRowValueConstructorSyntax() { + // It's supported but not usable due to a bug: https://sourceforge.net/p/hsqldb/bugs/1714/ return false; } @Override - protected boolean supportsRowValueConstructorSyntaxInInList() { + protected boolean supportsRowValueConstructorSyntaxInQuantifiedPredicates() { + // It's supported but not usable due to a bug: https://sourceforge.net/p/hsqldb/bugs/1714/ return false; } @Override - protected boolean supportsRowValueConstructorSyntaxInQuantifiedPredicates() { + protected boolean supportsRowValueConstructorSyntaxInInList() { + // It's supported but not usable due to a bug: https://sourceforge.net/p/hsqldb/bugs/1714/ return false; } From e33a2ca5e80a5c503ba1fa3856e70614054145d2 Mon Sep 17 00:00:00 2001 From: Christian Beikov Date: Thu, 11 Sep 2025 19:25:26 +0200 Subject: [PATCH 2/2] HHH-19768 Prefer values list rendering to emulate in-list tuples over select unions --- .../sql/ast/spi/AbstractSqlAstTranslator.java | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/AbstractSqlAstTranslator.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/AbstractSqlAstTranslator.java index 23dde601a093..fa0050b4d72a 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/AbstractSqlAstTranslator.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/AbstractSqlAstTranslator.java @@ -7753,7 +7753,24 @@ public void visitInListPredicate(InListPredicate inListPredicate) { } else if ( !supportsRowValueConstructorSyntaxInInList() ) { // Some DBs like Oracle support tuples only for the IN subquery predicate - if ( supportsRowValueConstructorSyntaxInInSubQuery() && dialect.supportsUnionAll() ) { + if ( supportsRowValueConstructorSyntaxInInSubQuery() && dialect.supportsValuesList() ) { + inListPredicate.getTestExpression().accept( this ); + if ( inListPredicate.isNegated() ) { + appendSql( " not" ); + } + appendSql( " in (select * from (values" ); + char separator = ' '; + for ( Expression expression : listExpressions ) { + appendSql( separator ); + appendSql( OPEN_PARENTHESIS ); + renderCommaSeparated( SqlTupleContainer.getSqlTuple( expression ).getExpressions() ); + appendSql( CLOSE_PARENTHESIS ); + separator = ','; + } + appendSql( CLOSE_PARENTHESIS ); + appendSql( CLOSE_PARENTHESIS ); + } + else if ( supportsRowValueConstructorSyntaxInInSubQuery() && dialect.supportsUnionAll() ) { inListPredicate.getTestExpression().accept( this ); if ( inListPredicate.isNegated() ) { appendSql( " not" );