From cf9d4ec3b3d00265809fd40082f4602e1994d82d Mon Sep 17 00:00:00 2001 From: Andrea Boriero Date: Wed, 14 Oct 2020 12:53:05 +0100 Subject: [PATCH] HHH-14242 Fix issue for Dialects supporting row value constructor Syntax but not in the SET clause --- .../main/java/org/hibernate/dialect/Dialect.java | 13 +++++++++++++ .../java/org/hibernate/dialect/MySQLDialect.java | 5 +++++ .../internal/ast/tree/BinaryLogicOperatorNode.java | 10 +++++++++- 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/Dialect.java b/hibernate-core/src/main/java/org/hibernate/dialect/Dialect.java index 4685e15621..79ecec5309 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/Dialect.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/Dialect.java @@ -2450,6 +2450,19 @@ public abstract class Dialect implements ConversionContext { return false; } + /** + * Is this dialect known to support what ANSI-SQL terms "row value constructor" syntax, + * sometimes called tuple syntax, in the SET clause; + *

+ * Basically, does it support syntax like + * "... SET (FIRST_NAME, LAST_NAME) = ('Steve', 'Ebersole') ...". + * + * @return True if this SQL dialect is known to support "row value constructor" syntax in the SET clause; false otherwise. + */ + public boolean supportsRowValueConstructorSyntaxInSet() { + return supportsRowValueConstructorSyntax(); + } + /** * If the dialect supports {@link #supportsRowValueConstructorSyntax() row values}, * does it offer such support in IN lists as well? diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/MySQLDialect.java b/hibernate-core/src/main/java/org/hibernate/dialect/MySQLDialect.java index 8eb757667e..75b7d66f62 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/MySQLDialect.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/MySQLDialect.java @@ -457,6 +457,11 @@ public class MySQLDialect extends Dialect { return true; } + @Override + public boolean supportsRowValueConstructorSyntaxInSet() { + return false; + } + @Override public String renderOrderByElement(String expression, String collation, String order, NullPrecedence nulls) { final StringBuilder orderByElement = new StringBuilder(); diff --git a/hibernate-core/src/main/java/org/hibernate/hql/internal/ast/tree/BinaryLogicOperatorNode.java b/hibernate-core/src/main/java/org/hibernate/hql/internal/ast/tree/BinaryLogicOperatorNode.java index 49fbdde66d..bbe94719c3 100644 --- a/hibernate-core/src/main/java/org/hibernate/hql/internal/ast/tree/BinaryLogicOperatorNode.java +++ b/hibernate-core/src/main/java/org/hibernate/hql/internal/ast/tree/BinaryLogicOperatorNode.java @@ -10,6 +10,7 @@ import java.util.Arrays; import org.hibernate.HibernateException; import org.hibernate.TypeMismatchException; +import org.hibernate.dialect.Dialect; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.hql.internal.antlr.HqlSqlTokenTypes; import org.hibernate.hql.internal.ast.QuerySyntaxException; @@ -81,13 +82,20 @@ public class BinaryLogicOperatorNode extends AbstractSelectExpression implements if ( lhsColumnSpan > 1 ) { // for dialects which are known to not support ANSI-SQL row-value-constructor syntax, // we should mutate the tree. - if ( !sessionFactory.getDialect().supportsRowValueConstructorSyntax() ) { + if ( !useRowValueConstructorSyntax( sessionFactory.getDialect() ) ) { mutateRowValueConstructorSyntax( lhsColumnSpan ); } } } } + private boolean useRowValueConstructorSyntax(Dialect dialect) { + if ( isInsideSetClause() ) { + return dialect.supportsRowValueConstructorSyntaxInSet(); + } + return dialect.supportsRowValueConstructorSyntax(); + } + private int getColumnSpan(Type type, SessionFactoryImplementor sfi) { int columnSpan = type.getColumnSpan( sfi ); if ( columnSpan == 0 && type instanceof OneToOneType ) {