HHH-10861 - Fix nullLiteral in select expression
This commit is contained in:
parent
e71af130f0
commit
597183a3b9
|
@ -689,7 +689,7 @@ functionCall
|
||||||
constant
|
constant
|
||||||
: literal
|
: literal
|
||||||
| NULL
|
| NULL
|
||||||
| TRUE { processBoolean(#constant); }
|
| TRUE { processBoolean(#constant); }
|
||||||
| FALSE { processBoolean(#constant); }
|
| FALSE { processBoolean(#constant); }
|
||||||
| JAVA_CONSTANT
|
| JAVA_CONSTANT
|
||||||
;
|
;
|
||||||
|
|
|
@ -15,6 +15,7 @@ import org.hibernate.hql.internal.ast.tree.BinaryArithmeticOperatorNode;
|
||||||
import org.hibernate.hql.internal.ast.tree.BinaryLogicOperatorNode;
|
import org.hibernate.hql.internal.ast.tree.BinaryLogicOperatorNode;
|
||||||
import org.hibernate.hql.internal.ast.tree.BooleanLiteralNode;
|
import org.hibernate.hql.internal.ast.tree.BooleanLiteralNode;
|
||||||
import org.hibernate.hql.internal.ast.tree.CastFunctionNode;
|
import org.hibernate.hql.internal.ast.tree.CastFunctionNode;
|
||||||
|
import org.hibernate.hql.internal.ast.tree.NullNode;
|
||||||
import org.hibernate.hql.internal.ast.tree.SearchedCaseNode;
|
import org.hibernate.hql.internal.ast.tree.SearchedCaseNode;
|
||||||
import org.hibernate.hql.internal.ast.tree.SimpleCaseNode;
|
import org.hibernate.hql.internal.ast.tree.SimpleCaseNode;
|
||||||
import org.hibernate.hql.internal.ast.tree.CollectionFunction;
|
import org.hibernate.hql.internal.ast.tree.CollectionFunction;
|
||||||
|
@ -192,6 +193,9 @@ public class SqlASTFactory extends ASTFactory implements HqlSqlTokenTypes {
|
||||||
case ENTRY: {
|
case ENTRY: {
|
||||||
return MapEntryNode.class;
|
return MapEntryNode.class;
|
||||||
}
|
}
|
||||||
|
case NULL : {
|
||||||
|
return NullNode.class;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
return SqlNode.class;
|
return SqlNode.class;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||||
|
*/
|
||||||
|
package org.hibernate.hql.internal.ast.tree;
|
||||||
|
|
||||||
|
import antlr.SemanticException;
|
||||||
|
|
||||||
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
|
import org.hibernate.hql.internal.ast.util.ColumnHelper;
|
||||||
|
import org.hibernate.type.Type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Andrea Boriero
|
||||||
|
*/
|
||||||
|
public class NullNode extends AbstractSelectExpression {
|
||||||
|
|
||||||
|
public Type getDataType() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setScalarColumnText(int i) throws SemanticException {
|
||||||
|
ColumnHelper.generateSingleScalarColumn( this, i );
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object getValue() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SuppressWarnings({"unchecked"})
|
||||||
|
public String getRenderText(SessionFactoryImplementor sessionFactory) {
|
||||||
|
return "null";
|
||||||
|
}
|
||||||
|
}
|
|
@ -191,6 +191,10 @@ public class LiteralProcessor implements HqlSqlTokenTypes {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void processNull(AST constant) {
|
||||||
|
constant.setText( "null" );
|
||||||
|
}
|
||||||
|
|
||||||
private void processLiteral(AST constant) {
|
private void processLiteral(AST constant) {
|
||||||
String replacement = (String) walker.getTokenReplacements().get( constant.getText() );
|
String replacement = (String) walker.getTokenReplacements().get( constant.getText() );
|
||||||
if ( replacement != null ) {
|
if ( replacement != null ) {
|
||||||
|
|
|
@ -301,12 +301,14 @@ public final class ReflectHelper {
|
||||||
*/
|
*/
|
||||||
public static Constructor getConstructor(Class clazz, Type[] types) throws PropertyNotFoundException {
|
public static Constructor getConstructor(Class clazz, Type[] types) throws PropertyNotFoundException {
|
||||||
final Constructor[] candidates = clazz.getConstructors();
|
final Constructor[] candidates = clazz.getConstructors();
|
||||||
for ( final Constructor constructor : candidates ) {
|
Constructor constructor = null;
|
||||||
final Class[] params = constructor.getParameterTypes();
|
int numberOfMatchingConstructors = 0;
|
||||||
|
for ( final Constructor candidate : candidates ) {
|
||||||
|
final Class[] params = candidate.getParameterTypes();
|
||||||
if ( params.length == types.length ) {
|
if ( params.length == types.length ) {
|
||||||
boolean found = true;
|
boolean found = true;
|
||||||
for ( int j = 0; j < params.length; j++ ) {
|
for ( int j = 0; j < params.length; j++ ) {
|
||||||
final boolean ok = params[j].isAssignableFrom( types[j].getReturnedClass() ) || (
|
final boolean ok = types[j] == null || params[j].isAssignableFrom( types[j].getReturnedClass() ) || (
|
||||||
types[j] instanceof PrimitiveType &&
|
types[j] instanceof PrimitiveType &&
|
||||||
params[j] == ( (PrimitiveType) types[j] ).getPrimitiveClass()
|
params[j] == ( (PrimitiveType) types[j] ).getPrimitiveClass()
|
||||||
);
|
);
|
||||||
|
@ -316,12 +318,18 @@ public final class ReflectHelper {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ( found ) {
|
if ( found ) {
|
||||||
constructor.setAccessible( true );
|
numberOfMatchingConstructors ++;
|
||||||
return constructor;
|
candidate.setAccessible( true );
|
||||||
|
constructor = candidate;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( numberOfMatchingConstructors == 1 ) {
|
||||||
|
return constructor;
|
||||||
|
}
|
||||||
throw new PropertyNotFoundException( "no appropriate constructor in class: " + clazz.getName() );
|
throw new PropertyNotFoundException( "no appropriate constructor in class: " + clazz.getName() );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Method getMethod(Class clazz, Method method) {
|
public static Method getMethod(Class clazz, Method method) {
|
||||||
|
|
|
@ -11,6 +11,7 @@ import java.io.Serializable;
|
||||||
import org.hibernate.query.criteria.internal.CriteriaBuilderImpl;
|
import org.hibernate.query.criteria.internal.CriteriaBuilderImpl;
|
||||||
import org.hibernate.query.criteria.internal.ParameterRegistry;
|
import org.hibernate.query.criteria.internal.ParameterRegistry;
|
||||||
import org.hibernate.query.criteria.internal.compile.RenderingContext;
|
import org.hibernate.query.criteria.internal.compile.RenderingContext;
|
||||||
|
import org.hibernate.query.criteria.internal.expression.function.CastFunction;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a <tt>NULL</tt>literal expression.
|
* Represents a <tt>NULL</tt>literal expression.
|
||||||
|
@ -27,7 +28,7 @@ public class NullLiteralExpression<T> extends ExpressionImpl<T> implements Seria
|
||||||
}
|
}
|
||||||
|
|
||||||
public String render(RenderingContext renderingContext) {
|
public String render(RenderingContext renderingContext) {
|
||||||
return "null";
|
return CastFunction.CAST_NAME + "( null as " + renderingContext.getCastType( getJavaType() ) + ')';
|
||||||
}
|
}
|
||||||
|
|
||||||
public String renderProjection(RenderingContext renderingContext) {
|
public String renderProjection(RenderingContext renderingContext) {
|
||||||
|
|
Loading…
Reference in New Issue