From 23153d5d559214652a6d40de25fd2367d163e301 Mon Sep 17 00:00:00 2001 From: Guillaume Smet Date: Thu, 17 Jan 2019 13:23:31 +0100 Subject: [PATCH] HHH-13016 Bring back CaseLiteralExpression It was removed as part of https://github.com/hibernate/hibernate-orm/pull/1361 but this PR didn't fix all the issues as there are still cases where we don't deduce the expected type and we need to have a proper cast. --- .../expression/CaseLiteralExpression.java | 38 +++++++++++++++++++ .../expression/SearchedCaseExpression.java | 4 +- .../expression/SimpleCaseExpression.java | 2 +- 3 files changed, 41 insertions(+), 3 deletions(-) create mode 100644 hibernate-core/src/main/java/org/hibernate/query/criteria/internal/expression/CaseLiteralExpression.java diff --git a/hibernate-core/src/main/java/org/hibernate/query/criteria/internal/expression/CaseLiteralExpression.java b/hibernate-core/src/main/java/org/hibernate/query/criteria/internal/expression/CaseLiteralExpression.java new file mode 100644 index 0000000000..20ca52b05c --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/query/criteria/internal/expression/CaseLiteralExpression.java @@ -0,0 +1,38 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * License: GNU Lesser General Public License (LGPL), version 2.1 or later. + * See the lgpl.txt file in the root directory or . + */ +package org.hibernate.query.criteria.internal.expression; + +import org.hibernate.query.criteria.internal.CriteriaBuilderImpl; +import org.hibernate.query.criteria.internal.compile.RenderingContext; +import org.hibernate.query.criteria.internal.expression.function.CastFunction; + +/** + * @author Andrea Boriero + */ +public class CaseLiteralExpression extends LiteralExpression { + + public CaseLiteralExpression(CriteriaBuilderImpl criteriaBuilder, Class type, T literal) { + super( criteriaBuilder, type, literal ); + } + + @Override + public String render(RenderingContext renderingContext) { + // There's no need to cast a boolean value and it actually breaks on + // MySQL and MariaDB because they don't support casting to bit. + // Skip the cast for a boolean literal. + if ( getJavaType() == Boolean.class && Boolean.class.isInstance( getLiteral() ) ) { + return super.render( renderingContext ); + } + + // wrapping the result in a cast to determine the node type during the antlr hql parsing phase + return CastFunction.CAST_NAME + '(' + + super.render( renderingContext ) + + " as " + + renderingContext.getCastType( getJavaType() ) + + ')'; + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/query/criteria/internal/expression/SearchedCaseExpression.java b/hibernate-core/src/main/java/org/hibernate/query/criteria/internal/expression/SearchedCaseExpression.java index 8caab31ec3..659f34fda5 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/criteria/internal/expression/SearchedCaseExpression.java +++ b/hibernate-core/src/main/java/org/hibernate/query/criteria/internal/expression/SearchedCaseExpression.java @@ -9,7 +9,7 @@ package org.hibernate.query.criteria.internal.expression; import java.io.Serializable; import java.util.ArrayList; import java.util.List; -import java.util.function.BiFunction; + import javax.persistence.criteria.CriteriaBuilder.Case; import javax.persistence.criteria.Expression; @@ -69,7 +69,7 @@ public class SearchedCaseExpression final Class type = result != null ? (Class) result.getClass() : getJavaType(); - return new LiteralExpression( criteriaBuilder(), type, result ); + return new CaseLiteralExpression( criteriaBuilder(), type, result ); } public Case when(Expression condition, Expression result) { diff --git a/hibernate-core/src/main/java/org/hibernate/query/criteria/internal/expression/SimpleCaseExpression.java b/hibernate-core/src/main/java/org/hibernate/query/criteria/internal/expression/SimpleCaseExpression.java index d75a8bccc9..c5b8a3440c 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/criteria/internal/expression/SimpleCaseExpression.java +++ b/hibernate-core/src/main/java/org/hibernate/query/criteria/internal/expression/SimpleCaseExpression.java @@ -76,7 +76,7 @@ public class SimpleCaseExpression final Class type = result != null ? (Class) result.getClass() : getJavaType(); - return new LiteralExpression( criteriaBuilder(), type, result ); + return new CaseLiteralExpression( criteriaBuilder(), type, result ); } public SimpleCase when(C condition, Expression result) {