Various improvements:
* Sprinkle some @Nullable annotations to better understand nullness guarantees * Fix some potential NPEs * Improve Oracle array_agg emulation * Prepare for aggregate component array support
This commit is contained in:
parent
75e1f17139
commit
940c898ecf
|
@ -24,6 +24,7 @@ import org.hibernate.query.sqm.produce.function.ArgumentsValidator;
|
||||||
import org.hibernate.query.sqm.produce.function.FunctionArgumentException;
|
import org.hibernate.query.sqm.produce.function.FunctionArgumentException;
|
||||||
import org.hibernate.query.sqm.produce.function.FunctionReturnTypeResolver;
|
import org.hibernate.query.sqm.produce.function.FunctionReturnTypeResolver;
|
||||||
import org.hibernate.query.sqm.produce.function.StandardFunctionArgumentTypeResolvers;
|
import org.hibernate.query.sqm.produce.function.StandardFunctionArgumentTypeResolvers;
|
||||||
|
import org.hibernate.query.sqm.sql.SqmToSqlAstConverter;
|
||||||
import org.hibernate.query.sqm.tree.SqmTypedNode;
|
import org.hibernate.query.sqm.tree.SqmTypedNode;
|
||||||
import org.hibernate.sql.ast.Clause;
|
import org.hibernate.sql.ast.Clause;
|
||||||
import org.hibernate.sql.ast.SqlAstNodeRenderingMode;
|
import org.hibernate.sql.ast.SqlAstNodeRenderingMode;
|
||||||
|
@ -44,6 +45,8 @@ import org.hibernate.type.descriptor.jdbc.JdbcType;
|
||||||
import org.hibernate.type.descriptor.jdbc.ObjectJdbcType;
|
import org.hibernate.type.descriptor.jdbc.ObjectJdbcType;
|
||||||
import org.hibernate.type.spi.TypeConfiguration;
|
import org.hibernate.type.spi.TypeConfiguration;
|
||||||
|
|
||||||
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
import static org.hibernate.query.sqm.produce.function.FunctionParameterType.NUMERIC;
|
import static org.hibernate.query.sqm.produce.function.FunctionParameterType.NUMERIC;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -240,7 +243,7 @@ public class AvgFunction extends AbstractSqmSelfRenderingFunctionDescriptor {
|
||||||
@Override
|
@Override
|
||||||
public ReturnableType<?> resolveFunctionReturnType(
|
public ReturnableType<?> resolveFunctionReturnType(
|
||||||
ReturnableType<?> impliedType,
|
ReturnableType<?> impliedType,
|
||||||
Supplier<MappingModelExpressible<?>> inferredTypeSupplier,
|
@Nullable SqmToSqlAstConverter converter,
|
||||||
List<? extends SqmTypedNode<?>> arguments,
|
List<? extends SqmTypedNode<?>> arguments,
|
||||||
TypeConfiguration typeConfiguration) {
|
TypeConfiguration typeConfiguration) {
|
||||||
final SqmExpressible<?> expressible = arguments.get( 0 ).getExpressible();
|
final SqmExpressible<?> expressible = arguments.get( 0 ).getExpressible();
|
||||||
|
|
|
@ -10,15 +10,17 @@ import java.util.List;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
import org.hibernate.metamodel.mapping.BasicValuedMapping;
|
import org.hibernate.metamodel.mapping.BasicValuedMapping;
|
||||||
import org.hibernate.metamodel.mapping.MappingModelExpressible;
|
|
||||||
import org.hibernate.query.ReturnableType;
|
import org.hibernate.query.ReturnableType;
|
||||||
import org.hibernate.query.sqm.function.NamedSqmFunctionDescriptor;
|
import org.hibernate.query.sqm.function.NamedSqmFunctionDescriptor;
|
||||||
import org.hibernate.query.sqm.produce.function.FunctionReturnTypeResolver;
|
import org.hibernate.query.sqm.produce.function.FunctionReturnTypeResolver;
|
||||||
|
import org.hibernate.query.sqm.sql.SqmToSqlAstConverter;
|
||||||
import org.hibernate.query.sqm.tree.SqmTypedNode;
|
import org.hibernate.query.sqm.tree.SqmTypedNode;
|
||||||
import org.hibernate.sql.ast.tree.SqlAstNode;
|
import org.hibernate.sql.ast.tree.SqlAstNode;
|
||||||
import org.hibernate.type.BasicTypeReference;
|
import org.hibernate.type.BasicTypeReference;
|
||||||
import org.hibernate.type.spi.TypeConfiguration;
|
import org.hibernate.type.spi.TypeConfiguration;
|
||||||
|
|
||||||
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Simplified API allowing users to contribute
|
* Simplified API allowing users to contribute
|
||||||
* {@link org.hibernate.query.sqm.function.SqmFunctionDescriptor}s
|
* {@link org.hibernate.query.sqm.function.SqmFunctionDescriptor}s
|
||||||
|
@ -42,15 +44,7 @@ public class StandardSQLFunction extends NamedSqmFunctionDescriptor {
|
||||||
@Override
|
@Override
|
||||||
public ReturnableType<?> resolveFunctionReturnType(
|
public ReturnableType<?> resolveFunctionReturnType(
|
||||||
ReturnableType<?> impliedType,
|
ReturnableType<?> impliedType,
|
||||||
List<? extends SqmTypedNode<?>> arguments,
|
@Nullable SqmToSqlAstConverter converter,
|
||||||
TypeConfiguration typeConfiguration) {
|
|
||||||
return resolveFunctionReturnType( impliedType, null, arguments, typeConfiguration );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ReturnableType<?> resolveFunctionReturnType(
|
|
||||||
ReturnableType<?> impliedType,
|
|
||||||
Supplier<MappingModelExpressible<?>> inferredTypeSupplier,
|
|
||||||
List<? extends SqmTypedNode<?>> arguments,
|
List<? extends SqmTypedNode<?>> arguments,
|
||||||
TypeConfiguration typeConfiguration) {
|
TypeConfiguration typeConfiguration) {
|
||||||
return type == null ? null : typeConfiguration.getBasicTypeRegistry().resolve( type );
|
return type == null ? null : typeConfiguration.getBasicTypeRegistry().resolve( type );
|
||||||
|
|
|
@ -11,6 +11,7 @@ import org.hibernate.metamodel.mapping.JdbcMapping;
|
||||||
import org.hibernate.metamodel.mapping.MappingModelExpressible;
|
import org.hibernate.metamodel.mapping.MappingModelExpressible;
|
||||||
import org.hibernate.query.ReturnableType;
|
import org.hibernate.query.ReturnableType;
|
||||||
import org.hibernate.query.sqm.produce.function.FunctionReturnTypeResolver;
|
import org.hibernate.query.sqm.produce.function.FunctionReturnTypeResolver;
|
||||||
|
import org.hibernate.query.sqm.sql.SqmToSqlAstConverter;
|
||||||
import org.hibernate.query.sqm.tree.SqmTypedNode;
|
import org.hibernate.query.sqm.tree.SqmTypedNode;
|
||||||
import org.hibernate.sql.ast.tree.SqlAstNode;
|
import org.hibernate.sql.ast.tree.SqlAstNode;
|
||||||
import org.hibernate.type.BasicType;
|
import org.hibernate.type.BasicType;
|
||||||
|
@ -21,6 +22,8 @@ import java.math.BigInteger;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
import static org.hibernate.query.sqm.produce.function.StandardFunctionReturnTypeResolvers.extractArgumentType;
|
import static org.hibernate.query.sqm.produce.function.StandardFunctionReturnTypeResolvers.extractArgumentType;
|
||||||
import static org.hibernate.query.sqm.produce.function.StandardFunctionReturnTypeResolvers.extractArgumentValuedMapping;
|
import static org.hibernate.query.sqm.produce.function.StandardFunctionReturnTypeResolvers.extractArgumentValuedMapping;
|
||||||
import static org.hibernate.type.SqlTypes.*;
|
import static org.hibernate.type.SqlTypes.*;
|
||||||
|
@ -59,15 +62,7 @@ class SumReturnTypeResolver implements FunctionReturnTypeResolver {
|
||||||
@Override
|
@Override
|
||||||
public ReturnableType<?> resolveFunctionReturnType(
|
public ReturnableType<?> resolveFunctionReturnType(
|
||||||
ReturnableType<?> impliedType,
|
ReturnableType<?> impliedType,
|
||||||
List<? extends SqmTypedNode<?>> arguments,
|
@Nullable SqmToSqlAstConverter converter,
|
||||||
TypeConfiguration typeConfiguration) {
|
|
||||||
return resolveFunctionReturnType( impliedType, null, arguments, typeConfiguration );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ReturnableType<?> resolveFunctionReturnType(
|
|
||||||
ReturnableType<?> impliedType,
|
|
||||||
Supplier<MappingModelExpressible<?>> inferredTypeSupplier,
|
|
||||||
List<? extends SqmTypedNode<?>> arguments,
|
List<? extends SqmTypedNode<?>> arguments,
|
||||||
TypeConfiguration typeConfiguration) {
|
TypeConfiguration typeConfiguration) {
|
||||||
if ( impliedType != null ) {
|
if ( impliedType != null ) {
|
||||||
|
|
|
@ -23,6 +23,7 @@ import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
|
||||||
import org.hibernate.query.sqm.produce.function.StandardFunctionArgumentTypeResolvers;
|
import org.hibernate.query.sqm.produce.function.StandardFunctionArgumentTypeResolvers;
|
||||||
import org.hibernate.query.sqm.produce.function.StandardFunctionReturnTypeResolvers;
|
import org.hibernate.query.sqm.produce.function.StandardFunctionReturnTypeResolvers;
|
||||||
import org.hibernate.query.sqm.produce.function.internal.PatternRenderer;
|
import org.hibernate.query.sqm.produce.function.internal.PatternRenderer;
|
||||||
|
import org.hibernate.query.sqm.sql.SqmToSqlAstConverter;
|
||||||
import org.hibernate.query.sqm.tree.SqmTypedNode;
|
import org.hibernate.query.sqm.tree.SqmTypedNode;
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmDurationUnit;
|
import org.hibernate.query.sqm.tree.expression.SqmDurationUnit;
|
||||||
import org.hibernate.sql.ast.SqlAstTranslator;
|
import org.hibernate.sql.ast.SqlAstTranslator;
|
||||||
|
@ -35,6 +36,7 @@ import org.hibernate.type.StandardBasicTypes;
|
||||||
import org.hibernate.type.spi.TypeConfiguration;
|
import org.hibernate.type.spi.TypeConfiguration;
|
||||||
|
|
||||||
import jakarta.persistence.TemporalType;
|
import jakarta.persistence.TemporalType;
|
||||||
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
import static java.util.Arrays.asList;
|
import static java.util.Arrays.asList;
|
||||||
import static org.hibernate.query.sqm.produce.function.FunctionParameterType.TEMPORAL;
|
import static org.hibernate.query.sqm.produce.function.FunctionParameterType.TEMPORAL;
|
||||||
|
@ -129,15 +131,7 @@ public class TimestampdiffFunction
|
||||||
@Override
|
@Override
|
||||||
public ReturnableType<?> resolveFunctionReturnType(
|
public ReturnableType<?> resolveFunctionReturnType(
|
||||||
ReturnableType<?> impliedType,
|
ReturnableType<?> impliedType,
|
||||||
List<? extends SqmTypedNode<?>> arguments,
|
@Nullable SqmToSqlAstConverter converter,
|
||||||
TypeConfiguration typeConfiguration) {
|
|
||||||
return resolveFunctionReturnType( impliedType, null, arguments, typeConfiguration );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ReturnableType<?> resolveFunctionReturnType(
|
|
||||||
ReturnableType<?> impliedType,
|
|
||||||
Supplier<MappingModelExpressible<?>> inferredTypeSupplier,
|
|
||||||
List<? extends SqmTypedNode<?>> arguments,
|
List<? extends SqmTypedNode<?>> arguments,
|
||||||
TypeConfiguration typeConfiguration) {
|
TypeConfiguration typeConfiguration) {
|
||||||
final BasicType<?> invariantType;
|
final BasicType<?> invariantType;
|
||||||
|
|
|
@ -15,11 +15,14 @@ import org.hibernate.metamodel.model.domain.DomainType;
|
||||||
import org.hibernate.query.ReturnableType;
|
import org.hibernate.query.ReturnableType;
|
||||||
import org.hibernate.query.sqm.SqmExpressible;
|
import org.hibernate.query.sqm.SqmExpressible;
|
||||||
import org.hibernate.query.sqm.produce.function.FunctionReturnTypeResolver;
|
import org.hibernate.query.sqm.produce.function.FunctionReturnTypeResolver;
|
||||||
|
import org.hibernate.query.sqm.sql.SqmToSqlAstConverter;
|
||||||
import org.hibernate.query.sqm.tree.SqmTypedNode;
|
import org.hibernate.query.sqm.tree.SqmTypedNode;
|
||||||
import org.hibernate.sql.ast.tree.SqlAstNode;
|
import org.hibernate.sql.ast.tree.SqlAstNode;
|
||||||
import org.hibernate.type.BasicPluralType;
|
import org.hibernate.type.BasicPluralType;
|
||||||
import org.hibernate.type.spi.TypeConfiguration;
|
import org.hibernate.type.spi.TypeConfiguration;
|
||||||
|
|
||||||
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A {@link FunctionReturnTypeResolver} that resolves the array type based on an argument.
|
* A {@link FunctionReturnTypeResolver} that resolves the array type based on an argument.
|
||||||
* The inferred type and implied type have precedence though.
|
* The inferred type and implied type have precedence though.
|
||||||
|
@ -37,10 +40,12 @@ public class ArrayViaArgumentReturnTypeResolver implements FunctionReturnTypeRes
|
||||||
@Override
|
@Override
|
||||||
public ReturnableType<?> resolveFunctionReturnType(
|
public ReturnableType<?> resolveFunctionReturnType(
|
||||||
ReturnableType<?> impliedType,
|
ReturnableType<?> impliedType,
|
||||||
Supplier<MappingModelExpressible<?>> inferredTypeSupplier,
|
@Nullable SqmToSqlAstConverter converter,
|
||||||
List<? extends SqmTypedNode<?>> arguments,
|
List<? extends SqmTypedNode<?>> arguments,
|
||||||
TypeConfiguration typeConfiguration) {
|
TypeConfiguration typeConfiguration) {
|
||||||
final MappingModelExpressible<?> inferredType = inferredTypeSupplier.get();
|
final MappingModelExpressible<?> inferredType = converter == null
|
||||||
|
? null
|
||||||
|
: converter.resolveFunctionImpliedReturnType();
|
||||||
if ( inferredType != null ) {
|
if ( inferredType != null ) {
|
||||||
if ( inferredType instanceof ReturnableType<?> ) {
|
if ( inferredType instanceof ReturnableType<?> ) {
|
||||||
return (ReturnableType<?>) inferredType;
|
return (ReturnableType<?>) inferredType;
|
||||||
|
|
|
@ -14,10 +14,13 @@ import org.hibernate.metamodel.mapping.MappingModelExpressible;
|
||||||
import org.hibernate.metamodel.model.domain.DomainType;
|
import org.hibernate.metamodel.model.domain.DomainType;
|
||||||
import org.hibernate.query.ReturnableType;
|
import org.hibernate.query.ReturnableType;
|
||||||
import org.hibernate.query.sqm.produce.function.FunctionReturnTypeResolver;
|
import org.hibernate.query.sqm.produce.function.FunctionReturnTypeResolver;
|
||||||
|
import org.hibernate.query.sqm.sql.SqmToSqlAstConverter;
|
||||||
import org.hibernate.query.sqm.tree.SqmTypedNode;
|
import org.hibernate.query.sqm.tree.SqmTypedNode;
|
||||||
import org.hibernate.sql.ast.tree.SqlAstNode;
|
import org.hibernate.sql.ast.tree.SqlAstNode;
|
||||||
import org.hibernate.type.spi.TypeConfiguration;
|
import org.hibernate.type.spi.TypeConfiguration;
|
||||||
|
|
||||||
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A {@link FunctionReturnTypeResolver} that resolves an array type based on the arguments,
|
* A {@link FunctionReturnTypeResolver} that resolves an array type based on the arguments,
|
||||||
* which are supposed to be of the element type. The inferred type and implied type have precedence though.
|
* which are supposed to be of the element type. The inferred type and implied type have precedence though.
|
||||||
|
@ -41,10 +44,12 @@ public class ArrayViaElementArgumentReturnTypeResolver implements FunctionReturn
|
||||||
@Override
|
@Override
|
||||||
public ReturnableType<?> resolveFunctionReturnType(
|
public ReturnableType<?> resolveFunctionReturnType(
|
||||||
ReturnableType<?> impliedType,
|
ReturnableType<?> impliedType,
|
||||||
Supplier<MappingModelExpressible<?>> inferredTypeSupplier,
|
@Nullable SqmToSqlAstConverter converter,
|
||||||
List<? extends SqmTypedNode<?>> arguments,
|
List<? extends SqmTypedNode<?>> arguments,
|
||||||
TypeConfiguration typeConfiguration) {
|
TypeConfiguration typeConfiguration) {
|
||||||
final MappingModelExpressible<?> inferredType = inferredTypeSupplier.get();
|
final MappingModelExpressible<?> inferredType = converter == null
|
||||||
|
? null
|
||||||
|
: converter.resolveFunctionImpliedReturnType();
|
||||||
if ( inferredType != null ) {
|
if ( inferredType != null ) {
|
||||||
if ( inferredType instanceof ReturnableType<?> ) {
|
if ( inferredType instanceof ReturnableType<?> ) {
|
||||||
return (ReturnableType<?>) inferredType;
|
return (ReturnableType<?>) inferredType;
|
||||||
|
|
|
@ -15,11 +15,14 @@ import org.hibernate.metamodel.model.domain.DomainType;
|
||||||
import org.hibernate.query.ReturnableType;
|
import org.hibernate.query.ReturnableType;
|
||||||
import org.hibernate.query.sqm.SqmExpressible;
|
import org.hibernate.query.sqm.SqmExpressible;
|
||||||
import org.hibernate.query.sqm.produce.function.FunctionReturnTypeResolver;
|
import org.hibernate.query.sqm.produce.function.FunctionReturnTypeResolver;
|
||||||
|
import org.hibernate.query.sqm.sql.SqmToSqlAstConverter;
|
||||||
import org.hibernate.query.sqm.tree.SqmTypedNode;
|
import org.hibernate.query.sqm.tree.SqmTypedNode;
|
||||||
import org.hibernate.sql.ast.tree.SqlAstNode;
|
import org.hibernate.sql.ast.tree.SqlAstNode;
|
||||||
import org.hibernate.type.BasicPluralType;
|
import org.hibernate.type.BasicPluralType;
|
||||||
import org.hibernate.type.spi.TypeConfiguration;
|
import org.hibernate.type.spi.TypeConfiguration;
|
||||||
|
|
||||||
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A {@link FunctionReturnTypeResolver} that resolves the array element type based on an argument.
|
* A {@link FunctionReturnTypeResolver} that resolves the array element type based on an argument.
|
||||||
* The inferred type and implied type have precedence though.
|
* The inferred type and implied type have precedence though.
|
||||||
|
@ -37,10 +40,12 @@ public class ElementViaArrayArgumentReturnTypeResolver implements FunctionReturn
|
||||||
@Override
|
@Override
|
||||||
public ReturnableType<?> resolveFunctionReturnType(
|
public ReturnableType<?> resolveFunctionReturnType(
|
||||||
ReturnableType<?> impliedType,
|
ReturnableType<?> impliedType,
|
||||||
Supplier<MappingModelExpressible<?>> inferredTypeSupplier,
|
@Nullable SqmToSqlAstConverter converter,
|
||||||
List<? extends SqmTypedNode<?>> arguments,
|
List<? extends SqmTypedNode<?>> arguments,
|
||||||
TypeConfiguration typeConfiguration) {
|
TypeConfiguration typeConfiguration) {
|
||||||
final MappingModelExpressible<?> inferredType = inferredTypeSupplier.get();
|
final MappingModelExpressible<?> inferredType = converter == null
|
||||||
|
? null
|
||||||
|
: converter.resolveFunctionImpliedReturnType();
|
||||||
if ( inferredType != null ) {
|
if ( inferredType != null ) {
|
||||||
if ( inferredType instanceof ReturnableType<?> ) {
|
if ( inferredType instanceof ReturnableType<?> ) {
|
||||||
return (ReturnableType<?>) inferredType;
|
return (ReturnableType<?>) inferredType;
|
||||||
|
|
|
@ -278,6 +278,7 @@ public abstract class AbstractEmbeddableMapping implements EmbeddableMappingType
|
||||||
containingTableExpression = rootTableExpression;
|
containingTableExpression = rootTableExpression;
|
||||||
columnExpression = rootTableKeyColumnNames[ columnPosition ];
|
columnExpression = rootTableKeyColumnNames[ columnPosition ];
|
||||||
}
|
}
|
||||||
|
final NavigableRole role = navigableRole.append( bootPropertyDescriptor.getName() );
|
||||||
final SelectablePath selectablePath;
|
final SelectablePath selectablePath;
|
||||||
final String columnDefinition;
|
final String columnDefinition;
|
||||||
final Long length;
|
final Long length;
|
||||||
|
@ -310,18 +311,18 @@ public abstract class AbstractEmbeddableMapping implements EmbeddableMappingType
|
||||||
|
|
||||||
attributeMapping = MappingModelCreationHelper.buildBasicAttributeMapping(
|
attributeMapping = MappingModelCreationHelper.buildBasicAttributeMapping(
|
||||||
bootPropertyDescriptor.getName(),
|
bootPropertyDescriptor.getName(),
|
||||||
navigableRole.append( bootPropertyDescriptor.getName() ),
|
role,
|
||||||
attributeIndex,
|
attributeIndex,
|
||||||
attributeIndex,
|
attributeIndex,
|
||||||
bootPropertyDescriptor,
|
bootPropertyDescriptor,
|
||||||
declarer,
|
declarer,
|
||||||
(BasicType<?>) subtype,
|
basicValue.getResolution().getLegacyResolvedBasicType(),
|
||||||
containingTableExpression,
|
containingTableExpression,
|
||||||
columnExpression,
|
columnExpression,
|
||||||
selectablePath,
|
selectablePath,
|
||||||
selectable.isFormula(),
|
selectable.isFormula(),
|
||||||
selectable.getCustomReadExpression(),
|
selectable.getCustomReadExpression(),
|
||||||
selectable.getWriteExpr( ( (BasicType<?>) subtype ).getJdbcMapping(), dialect ),
|
selectable.getWriteExpr( basicValue.getResolution().getJdbcMapping(), dialect ),
|
||||||
columnDefinition,
|
columnDefinition,
|
||||||
length,
|
length,
|
||||||
precision,
|
precision,
|
||||||
|
|
|
@ -5702,6 +5702,7 @@ public abstract class AbstractEntityPersister
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( attrType instanceof BasicType ) {
|
if ( attrType instanceof BasicType ) {
|
||||||
|
final NavigableRole role = getNavigableRole().append( bootProperty.getName() );
|
||||||
final String attrColumnExpression;
|
final String attrColumnExpression;
|
||||||
final boolean isAttrColumnExpressionFormula;
|
final boolean isAttrColumnExpressionFormula;
|
||||||
final String customReadExpr;
|
final String customReadExpr;
|
||||||
|
@ -5774,12 +5775,12 @@ public abstract class AbstractEntityPersister
|
||||||
|
|
||||||
return MappingModelCreationHelper.buildBasicAttributeMapping(
|
return MappingModelCreationHelper.buildBasicAttributeMapping(
|
||||||
attrName,
|
attrName,
|
||||||
getNavigableRole().append( bootProperty.getName() ),
|
role,
|
||||||
stateArrayPosition,
|
stateArrayPosition,
|
||||||
fetchableIndex,
|
fetchableIndex,
|
||||||
bootProperty,
|
bootProperty,
|
||||||
this,
|
this,
|
||||||
(BasicType<?>) attrType,
|
(BasicType<?>) value.getType(),
|
||||||
tableExpression,
|
tableExpression,
|
||||||
attrColumnExpression,
|
attrColumnExpression,
|
||||||
null,
|
null,
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
package org.hibernate.query.criteria;
|
package org.hibernate.query.criteria;
|
||||||
|
|
||||||
import jakarta.persistence.TupleElement;
|
import jakarta.persistence.TupleElement;
|
||||||
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
import org.hibernate.type.descriptor.java.EnumJavaType;
|
import org.hibernate.type.descriptor.java.EnumJavaType;
|
||||||
import org.hibernate.type.descriptor.java.JavaType;
|
import org.hibernate.type.descriptor.java.JavaType;
|
||||||
|
@ -17,10 +18,10 @@ import org.hibernate.type.descriptor.java.JavaType;
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
public interface JpaTupleElement<T> extends TupleElement<T>, JpaCriteriaNode {
|
public interface JpaTupleElement<T> extends TupleElement<T>, JpaCriteriaNode {
|
||||||
JavaType<T> getJavaTypeDescriptor();
|
@Nullable JavaType<T> getJavaTypeDescriptor();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
default Class<? extends T> getJavaType() {
|
default @Nullable Class<? extends T> getJavaType() {
|
||||||
// todo (6.0) : can this signature just return `Class<T>`?
|
// todo (6.0) : can this signature just return `Class<T>`?
|
||||||
return getJavaTypeDescriptor() == null ? null : getJavaTypeDescriptor().getJavaTypeClass();
|
return getJavaTypeDescriptor() == null ? null : getJavaTypeDescriptor().getJavaTypeClass();
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,6 +33,8 @@ import org.hibernate.sql.results.internal.SqlSelectionImpl;
|
||||||
import org.hibernate.type.descriptor.java.JavaType;
|
import org.hibernate.type.descriptor.java.JavaType;
|
||||||
import org.hibernate.type.spi.TypeConfiguration;
|
import org.hibernate.type.spi.TypeConfiguration;
|
||||||
|
|
||||||
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Representation of a function call in the SQL AST for impls that know how to
|
* Representation of a function call in the SQL AST for impls that know how to
|
||||||
* render themselves.
|
* render themselves.
|
||||||
|
@ -44,8 +46,8 @@ public class SelfRenderingFunctionSqlAstExpression
|
||||||
private final String functionName;
|
private final String functionName;
|
||||||
private final FunctionRenderer renderer;
|
private final FunctionRenderer renderer;
|
||||||
private final List<? extends SqlAstNode> sqlAstArguments;
|
private final List<? extends SqlAstNode> sqlAstArguments;
|
||||||
private final ReturnableType<?> type;
|
private final @Nullable ReturnableType<?> type;
|
||||||
private final JdbcMappingContainer expressible;
|
private final @Nullable JdbcMappingContainer expressible;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated Use {@link #SelfRenderingFunctionSqlAstExpression(String, FunctionRenderer, List, ReturnableType, JdbcMappingContainer)} instead
|
* @deprecated Use {@link #SelfRenderingFunctionSqlAstExpression(String, FunctionRenderer, List, ReturnableType, JdbcMappingContainer)} instead
|
||||||
|
@ -55,8 +57,8 @@ public class SelfRenderingFunctionSqlAstExpression
|
||||||
String functionName,
|
String functionName,
|
||||||
FunctionRenderingSupport renderer,
|
FunctionRenderingSupport renderer,
|
||||||
List<? extends SqlAstNode> sqlAstArguments,
|
List<? extends SqlAstNode> sqlAstArguments,
|
||||||
ReturnableType<?> type,
|
@Nullable ReturnableType<?> type,
|
||||||
JdbcMappingContainer expressible) {
|
@Nullable JdbcMappingContainer expressible) {
|
||||||
this.functionName = functionName;
|
this.functionName = functionName;
|
||||||
this.renderer = renderer::render;
|
this.renderer = renderer::render;
|
||||||
this.sqlAstArguments = sqlAstArguments;
|
this.sqlAstArguments = sqlAstArguments;
|
||||||
|
@ -69,8 +71,8 @@ public class SelfRenderingFunctionSqlAstExpression
|
||||||
String functionName,
|
String functionName,
|
||||||
FunctionRenderer renderer,
|
FunctionRenderer renderer,
|
||||||
List<? extends SqlAstNode> sqlAstArguments,
|
List<? extends SqlAstNode> sqlAstArguments,
|
||||||
ReturnableType<?> type,
|
@Nullable ReturnableType<?> type,
|
||||||
JdbcMappingContainer expressible) {
|
@Nullable JdbcMappingContainer expressible) {
|
||||||
this.functionName = functionName;
|
this.functionName = functionName;
|
||||||
this.renderer = renderer;
|
this.renderer = renderer;
|
||||||
this.sqlAstArguments = sqlAstArguments;
|
this.sqlAstArguments = sqlAstArguments;
|
||||||
|
@ -108,7 +110,7 @@ public class SelfRenderingFunctionSqlAstExpression
|
||||||
return renderer;
|
return renderer;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected ReturnableType<?> getType() {
|
protected @Nullable ReturnableType<?> getType() {
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,12 +8,14 @@ package org.hibernate.query.sqm.internal;
|
||||||
|
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmParameter;
|
import org.hibernate.query.sqm.tree.expression.SqmParameter;
|
||||||
|
|
||||||
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Marco Belladelli
|
* @author Marco Belladelli
|
||||||
*/
|
*/
|
||||||
public class NoParamSqmCopyContext extends SimpleSqmCopyContext {
|
public class NoParamSqmCopyContext extends SimpleSqmCopyContext {
|
||||||
@Override
|
@Override
|
||||||
public <T> T getCopy(T original) {
|
public <T> @Nullable T getCopy(T original) {
|
||||||
if ( original instanceof SqmParameter<?> ) {
|
if ( original instanceof SqmParameter<?> ) {
|
||||||
return original;
|
return original;
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,8 @@ import java.util.IdentityHashMap;
|
||||||
|
|
||||||
import org.hibernate.query.sqm.tree.SqmCopyContext;
|
import org.hibernate.query.sqm.tree.SqmCopyContext;
|
||||||
|
|
||||||
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Marco Belladelli
|
* @author Marco Belladelli
|
||||||
*/
|
*/
|
||||||
|
@ -18,7 +20,7 @@ public class SimpleSqmCopyContext implements SqmCopyContext {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@SuppressWarnings( "unchecked" )
|
@SuppressWarnings( "unchecked" )
|
||||||
public <T> T getCopy(T original) {
|
public <T> @Nullable T getCopy(T original) {
|
||||||
return (T) map.get( original );
|
return (T) map.get( original );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -336,10 +336,12 @@ public class TypecheckUtil {
|
||||||
* @see TypecheckUtil#assertAssignable(String, SqmPath, SqmTypedNode, SessionFactoryImplementor)
|
* @see TypecheckUtil#assertAssignable(String, SqmPath, SqmTypedNode, SessionFactoryImplementor)
|
||||||
*/
|
*/
|
||||||
public static void assertComparable(Expression<?> x, Expression<?> y, SessionFactoryImplementor factory) {
|
public static void assertComparable(Expression<?> x, Expression<?> y, SessionFactoryImplementor factory) {
|
||||||
SqmExpression<?> left = (SqmExpression<?>) x;
|
final SqmExpression<?> left = (SqmExpression<?>) x;
|
||||||
SqmExpression<?> right = (SqmExpression<?>) y;
|
final SqmExpression<?> right = (SqmExpression<?>) y;
|
||||||
if ( left.getTupleLength() != null && right.getTupleLength() != null
|
final Integer leftTupleLength = left.getTupleLength();
|
||||||
&& left.getTupleLength().intValue() != right.getTupleLength().intValue() ) {
|
final Integer rightTupleLength;
|
||||||
|
if ( leftTupleLength != null && ( rightTupleLength = right.getTupleLength() ) != null
|
||||||
|
&& leftTupleLength.intValue() != rightTupleLength.intValue() ) {
|
||||||
throw new SemanticException( "Cannot compare tuples of different lengths" );
|
throw new SemanticException( "Cannot compare tuples of different lengths" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,8 @@ package org.hibernate.query.sqm.produce.function;
|
||||||
import org.hibernate.metamodel.mapping.BasicValuedMapping;
|
import org.hibernate.metamodel.mapping.BasicValuedMapping;
|
||||||
import org.hibernate.metamodel.mapping.MappingModelExpressible;
|
import org.hibernate.metamodel.mapping.MappingModelExpressible;
|
||||||
import org.hibernate.query.ReturnableType;
|
import org.hibernate.query.ReturnableType;
|
||||||
|
import org.hibernate.query.sqm.sql.FakeSqmToSqlAstConverter;
|
||||||
|
import org.hibernate.query.sqm.sql.SqmToSqlAstConverter;
|
||||||
import org.hibernate.query.sqm.tree.SqmTypedNode;
|
import org.hibernate.query.sqm.tree.SqmTypedNode;
|
||||||
import org.hibernate.sql.ast.tree.SqlAstNode;
|
import org.hibernate.sql.ast.tree.SqlAstNode;
|
||||||
import org.hibernate.type.spi.TypeConfiguration;
|
import org.hibernate.type.spi.TypeConfiguration;
|
||||||
|
@ -16,6 +18,8 @@ import org.hibernate.type.spi.TypeConfiguration;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pluggable strategy for resolving a function return type for a specific call.
|
* Pluggable strategy for resolving a function return type for a specific call.
|
||||||
*
|
*
|
||||||
|
@ -32,10 +36,10 @@ public interface FunctionReturnTypeResolver {
|
||||||
* of `some_function`.
|
* of `some_function`.
|
||||||
*
|
*
|
||||||
* @return The resolved type.
|
* @return The resolved type.
|
||||||
* @deprecated Use {@link #resolveFunctionReturnType(ReturnableType, Supplier, List, TypeConfiguration)} instead
|
* @deprecated Use {@link #resolveFunctionReturnType(ReturnableType, SqmToSqlAstConverter, List, TypeConfiguration)} instead
|
||||||
*/
|
*/
|
||||||
@Deprecated(forRemoval = true)
|
@Deprecated(forRemoval = true)
|
||||||
default ReturnableType<?> resolveFunctionReturnType(
|
default @Nullable ReturnableType<?> resolveFunctionReturnType(
|
||||||
ReturnableType<?> impliedType,
|
ReturnableType<?> impliedType,
|
||||||
List<? extends SqmTypedNode<?>> arguments,
|
List<? extends SqmTypedNode<?>> arguments,
|
||||||
TypeConfiguration typeConfiguration) {
|
TypeConfiguration typeConfiguration) {
|
||||||
|
@ -52,13 +56,44 @@ public interface FunctionReturnTypeResolver {
|
||||||
* of `some_function`.
|
* of `some_function`.
|
||||||
*
|
*
|
||||||
* @return The resolved type.
|
* @return The resolved type.
|
||||||
|
* @deprecated Use {@link #resolveFunctionReturnType(ReturnableType, SqmToSqlAstConverter, List, TypeConfiguration)} instead
|
||||||
*/
|
*/
|
||||||
default ReturnableType<?> resolveFunctionReturnType(
|
@Deprecated(forRemoval = true)
|
||||||
|
default @Nullable ReturnableType<?> resolveFunctionReturnType(
|
||||||
ReturnableType<?> impliedType,
|
ReturnableType<?> impliedType,
|
||||||
Supplier<MappingModelExpressible<?>> inferredTypeSupplier,
|
Supplier<MappingModelExpressible<?>> inferredTypeSupplier,
|
||||||
List<? extends SqmTypedNode<?>> arguments,
|
List<? extends SqmTypedNode<?>> arguments,
|
||||||
TypeConfiguration typeConfiguration) {
|
TypeConfiguration typeConfiguration) {
|
||||||
return resolveFunctionReturnType( impliedType, arguments, typeConfiguration );
|
return resolveFunctionReturnType( impliedType, new FakeSqmToSqlAstConverter( null ) {
|
||||||
|
@Override
|
||||||
|
public MappingModelExpressible<?> resolveFunctionImpliedReturnType() {
|
||||||
|
return inferredTypeSupplier.get();
|
||||||
|
}
|
||||||
|
}, arguments, typeConfiguration );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resolve the return type for a function given its context-implied type and
|
||||||
|
* the arguments to this call.
|
||||||
|
* <p>
|
||||||
|
* The <em>context-implied</em> type is the type implied by where the function
|
||||||
|
* occurs in the query. E.g., for an equality predicate (`something = some_function`)
|
||||||
|
* the implied type of the return from `some_function` would be defined by the type
|
||||||
|
* of `some_function`.
|
||||||
|
*
|
||||||
|
* @return The resolved type.
|
||||||
|
*/
|
||||||
|
default @Nullable ReturnableType<?> resolveFunctionReturnType(
|
||||||
|
ReturnableType<?> impliedType,
|
||||||
|
@Nullable SqmToSqlAstConverter converter,
|
||||||
|
List<? extends SqmTypedNode<?>> arguments,
|
||||||
|
TypeConfiguration typeConfiguration) {
|
||||||
|
return resolveFunctionReturnType(
|
||||||
|
impliedType,
|
||||||
|
converter == null ? () -> null : converter::resolveFunctionImpliedReturnType,
|
||||||
|
arguments,
|
||||||
|
typeConfiguration
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -19,6 +19,7 @@ import org.hibernate.metamodel.mapping.MappingModelExpressible;
|
||||||
import org.hibernate.query.ReturnableType;
|
import org.hibernate.query.ReturnableType;
|
||||||
import org.hibernate.query.sqm.SqmExpressible;
|
import org.hibernate.query.sqm.SqmExpressible;
|
||||||
import org.hibernate.query.sqm.SqmPathSource;
|
import org.hibernate.query.sqm.SqmPathSource;
|
||||||
|
import org.hibernate.query.sqm.sql.SqmToSqlAstConverter;
|
||||||
import org.hibernate.query.sqm.tree.SqmTypedNode;
|
import org.hibernate.query.sqm.tree.SqmTypedNode;
|
||||||
import org.hibernate.query.sqm.tree.expression.NullSqmExpressible;
|
import org.hibernate.query.sqm.tree.expression.NullSqmExpressible;
|
||||||
import org.hibernate.sql.ast.tree.SqlAstNode;
|
import org.hibernate.sql.ast.tree.SqlAstNode;
|
||||||
|
@ -26,6 +27,8 @@ import org.hibernate.sql.ast.tree.expression.Expression;
|
||||||
import org.hibernate.type.BasicType;
|
import org.hibernate.type.BasicType;
|
||||||
import org.hibernate.type.spi.TypeConfiguration;
|
import org.hibernate.type.spi.TypeConfiguration;
|
||||||
|
|
||||||
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
|
@ -51,15 +54,7 @@ public class StandardFunctionReturnTypeResolvers {
|
||||||
@Override
|
@Override
|
||||||
public ReturnableType<?> resolveFunctionReturnType(
|
public ReturnableType<?> resolveFunctionReturnType(
|
||||||
ReturnableType<?> impliedType,
|
ReturnableType<?> impliedType,
|
||||||
List<? extends SqmTypedNode<?>> arguments,
|
@Nullable SqmToSqlAstConverter converter,
|
||||||
TypeConfiguration typeConfiguration) {
|
|
||||||
return resolveFunctionReturnType( impliedType, null, arguments, typeConfiguration );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ReturnableType<?> resolveFunctionReturnType(
|
|
||||||
ReturnableType<?> impliedType,
|
|
||||||
Supplier<MappingModelExpressible<?>> inferredTypeSupplier,
|
|
||||||
List<? extends SqmTypedNode<?>> arguments,
|
List<? extends SqmTypedNode<?>> arguments,
|
||||||
TypeConfiguration typeConfiguration) {
|
TypeConfiguration typeConfiguration) {
|
||||||
return isAssignableTo( invariantType, impliedType ) ? impliedType : invariantType;
|
return isAssignableTo( invariantType, impliedType ) ? impliedType : invariantType;
|
||||||
|
@ -84,15 +79,7 @@ public class StandardFunctionReturnTypeResolvers {
|
||||||
@Override
|
@Override
|
||||||
public ReturnableType<?> resolveFunctionReturnType(
|
public ReturnableType<?> resolveFunctionReturnType(
|
||||||
ReturnableType<?> impliedType,
|
ReturnableType<?> impliedType,
|
||||||
List<? extends SqmTypedNode<?>> arguments,
|
@Nullable SqmToSqlAstConverter converter,
|
||||||
TypeConfiguration typeConfiguration) {
|
|
||||||
return resolveFunctionReturnType( impliedType, null, arguments, typeConfiguration );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ReturnableType<?> resolveFunctionReturnType(
|
|
||||||
ReturnableType<?> impliedType,
|
|
||||||
Supplier<MappingModelExpressible<?>> inferredTypeSupplier,
|
|
||||||
List<? extends SqmTypedNode<?>> arguments,
|
List<? extends SqmTypedNode<?>> arguments,
|
||||||
TypeConfiguration typeConfiguration) {
|
TypeConfiguration typeConfiguration) {
|
||||||
ReturnableType<?> argType = extractArgumentType( arguments, argPosition );
|
ReturnableType<?> argType = extractArgumentType( arguments, argPosition );
|
||||||
|
@ -133,15 +120,7 @@ public class StandardFunctionReturnTypeResolvers {
|
||||||
@Override
|
@Override
|
||||||
public ReturnableType<?> resolveFunctionReturnType(
|
public ReturnableType<?> resolveFunctionReturnType(
|
||||||
ReturnableType<?> impliedType,
|
ReturnableType<?> impliedType,
|
||||||
List<? extends SqmTypedNode<?>> arguments,
|
@Nullable SqmToSqlAstConverter converter,
|
||||||
TypeConfiguration typeConfiguration) {
|
|
||||||
return resolveFunctionReturnType( impliedType, null, arguments, typeConfiguration );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ReturnableType<?> resolveFunctionReturnType(
|
|
||||||
ReturnableType<?> impliedType,
|
|
||||||
Supplier<MappingModelExpressible<?>> inferredTypeSupplier,
|
|
||||||
List<? extends SqmTypedNode<?>> arguments,
|
List<? extends SqmTypedNode<?>> arguments,
|
||||||
TypeConfiguration typeConfiguration) {
|
TypeConfiguration typeConfiguration) {
|
||||||
for ( int i = 0; i < arguments.size(); i++ ) {
|
for ( int i = 0; i < arguments.size(); i++ ) {
|
||||||
|
|
|
@ -5364,6 +5364,11 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
|
||||||
return inferredType;
|
return inferredType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isInTypeInference() {
|
||||||
|
return inImpliedResultTypeInference || inTypeInference;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public MappingModelExpressible<?> resolveFunctionImpliedReturnType() {
|
public MappingModelExpressible<?> resolveFunctionImpliedReturnType() {
|
||||||
if ( inImpliedResultTypeInference || functionImpliedResultTypeAccess == null ) {
|
if ( inImpliedResultTypeInference || functionImpliedResultTypeAccess == null ) {
|
||||||
|
|
|
@ -95,6 +95,11 @@ public class FakeSqmToSqlAstConverter extends BaseSemanticQueryWalker implements
|
||||||
public void registerQueryTransformer(QueryTransformer transformer) {
|
public void registerQueryTransformer(QueryTransformer transformer) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isInTypeInference() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public MappingModelExpressible<?> resolveFunctionImpliedReturnType() {
|
public MappingModelExpressible<?> resolveFunctionImpliedReturnType() {
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -35,6 +35,12 @@ public interface SqmToSqlAstConverter extends SemanticQueryWalker<Object>, SqlAs
|
||||||
|
|
||||||
void registerQueryTransformer(QueryTransformer transformer);
|
void registerQueryTransformer(QueryTransformer transformer);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether the state of the translation is currently in type inference mode.
|
||||||
|
* This is useful to avoid type inference based on other incomplete inference information.
|
||||||
|
*/
|
||||||
|
boolean isInTypeInference();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the function return type implied from the context within which it is used.
|
* Returns the function return type implied from the context within which it is used.
|
||||||
* If there is no current function being processed or no context implied type, the return is <code>null</code>.
|
* If there is no current function being processed or no context implied type, the return is <code>null</code>.
|
||||||
|
|
|
@ -10,12 +10,14 @@ import org.hibernate.Incubating;
|
||||||
import org.hibernate.query.sqm.internal.NoParamSqmCopyContext;
|
import org.hibernate.query.sqm.internal.NoParamSqmCopyContext;
|
||||||
import org.hibernate.query.sqm.internal.SimpleSqmCopyContext;
|
import org.hibernate.query.sqm.internal.SimpleSqmCopyContext;
|
||||||
|
|
||||||
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public interface SqmCopyContext {
|
public interface SqmCopyContext {
|
||||||
|
|
||||||
<T> T getCopy(T original);
|
<T> @Nullable T getCopy(T original);
|
||||||
|
|
||||||
<T> T registerCopy(T original, T copy);
|
<T> T registerCopy(T original, T copy);
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,8 @@ package org.hibernate.query.sqm.tree;
|
||||||
import org.hibernate.query.sqm.SqmExpressible;
|
import org.hibernate.query.sqm.SqmExpressible;
|
||||||
import org.hibernate.type.descriptor.java.JavaType;
|
import org.hibernate.type.descriptor.java.JavaType;
|
||||||
|
|
||||||
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Optional contract for SqmNode implementations which are
|
* Optional contract for SqmNode implementations which are
|
||||||
* typed
|
* typed
|
||||||
|
@ -19,17 +21,17 @@ public interface SqmTypedNode<T> extends SqmNode, SqmExpressibleAccessor<T>, Sqm
|
||||||
/**
|
/**
|
||||||
* The Java type descriptor for this node.
|
* The Java type descriptor for this node.
|
||||||
*/
|
*/
|
||||||
default JavaType<T> getNodeJavaType() {
|
default @Nullable JavaType<T> getNodeJavaType() {
|
||||||
final SqmExpressible<T> nodeType = getNodeType();
|
final SqmExpressible<T> nodeType = getNodeType();
|
||||||
return nodeType != null ? nodeType.getExpressibleJavaType() : null;
|
return nodeType != null ? nodeType.getExpressibleJavaType() : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
default SqmExpressible<T> getExpressible() {
|
default @Nullable SqmExpressible<T> getExpressible() {
|
||||||
return getNodeType();
|
return getNodeType();
|
||||||
}
|
}
|
||||||
|
|
||||||
SqmExpressible<T> getNodeType();
|
@Nullable SqmExpressible<T> getNodeType();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
SqmTypedNode<T> copy(SqmCopyContext context);
|
SqmTypedNode<T> copy(SqmCopyContext context);
|
||||||
|
|
|
@ -13,6 +13,7 @@ import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
import org.hibernate.internal.util.NullnessUtil;
|
||||||
import org.hibernate.metamodel.mapping.CollectionPart;
|
import org.hibernate.metamodel.mapping.CollectionPart;
|
||||||
import org.hibernate.metamodel.mapping.EntityDiscriminatorMapping;
|
import org.hibernate.metamodel.mapping.EntityDiscriminatorMapping;
|
||||||
import org.hibernate.metamodel.model.domain.DomainType;
|
import org.hibernate.metamodel.model.domain.DomainType;
|
||||||
|
@ -79,12 +80,12 @@ public abstract class AbstractSqmPath<T> extends AbstractSqmExpression<T> implem
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SqmPathSource<T> getNodeType() {
|
public SqmPathSource<T> getNodeType() {
|
||||||
return (SqmPathSource<T>) super.getNodeType();
|
return (SqmPathSource<T>) NullnessUtil.castNonNull( super.getNodeType() );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SqmPathSource<T> getReferencedPathSource() {
|
public SqmPathSource<T> getReferencedPathSource() {
|
||||||
return (SqmPathSource<T>) super.getNodeType();
|
return (SqmPathSource<T>) NullnessUtil.castNonNull( super.getNodeType() );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -14,6 +14,7 @@ import java.util.function.Consumer;
|
||||||
import jakarta.persistence.metamodel.MapAttribute;
|
import jakarta.persistence.metamodel.MapAttribute;
|
||||||
import jakarta.persistence.metamodel.PluralAttribute;
|
import jakarta.persistence.metamodel.PluralAttribute;
|
||||||
import jakarta.persistence.metamodel.SingularAttribute;
|
import jakarta.persistence.metamodel.SingularAttribute;
|
||||||
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
import org.hibernate.metamodel.model.domain.EntityDomainType;
|
import org.hibernate.metamodel.model.domain.EntityDomainType;
|
||||||
import org.hibernate.query.SemanticException;
|
import org.hibernate.query.SemanticException;
|
||||||
|
@ -104,7 +105,7 @@ public interface SqmPath<T> extends SqmExpression<T>, SemanticPathPart, JpaPath<
|
||||||
SqmPathSource<T> getNodeType();
|
SqmPathSource<T> getNodeType();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
default void applyInferableType(SqmExpressible<?> type) {
|
default void applyInferableType(@Nullable SqmExpressible<?> type) {
|
||||||
// do nothing
|
// do nothing
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,7 @@ import org.hibernate.query.sqm.tree.predicate.SqmPredicate;
|
||||||
import org.hibernate.type.descriptor.java.JavaType;
|
import org.hibernate.type.descriptor.java.JavaType;
|
||||||
|
|
||||||
import jakarta.persistence.criteria.Expression;
|
import jakarta.persistence.criteria.Expression;
|
||||||
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
import static org.hibernate.query.internal.QueryHelper.highestPrecedenceType2;
|
import static org.hibernate.query.internal.QueryHelper.highestPrecedenceType2;
|
||||||
|
|
||||||
|
@ -28,7 +29,7 @@ import static org.hibernate.query.internal.QueryHelper.highestPrecedenceType2;
|
||||||
*/
|
*/
|
||||||
public abstract class AbstractSqmExpression<T> extends AbstractJpaSelection<T> implements SqmExpression<T> {
|
public abstract class AbstractSqmExpression<T> extends AbstractJpaSelection<T> implements SqmExpression<T> {
|
||||||
|
|
||||||
public AbstractSqmExpression(SqmExpressible<? super T> type, NodeBuilder criteriaBuilder) {
|
public AbstractSqmExpression(@Nullable SqmExpressible<? super T> type, NodeBuilder criteriaBuilder) {
|
||||||
super( type, criteriaBuilder );
|
super( type, criteriaBuilder );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,10 +39,10 @@ public abstract class AbstractSqmExpression<T> extends AbstractJpaSelection<T> i
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void applyInferableType(SqmExpressible<?> type) {
|
public void applyInferableType(@Nullable SqmExpressible<?> type) {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void internalApplyInferableType(SqmExpressible<?> newType) {
|
protected void internalApplyInferableType(@Nullable SqmExpressible<?> newType) {
|
||||||
SqmTreeCreationLogger.LOGGER.debugf(
|
SqmTreeCreationLogger.LOGGER.debugf(
|
||||||
"Applying inferable type to SqmExpression [%s] : %s -> %s",
|
"Applying inferable type to SqmExpression [%s] : %s -> %s",
|
||||||
this,
|
this,
|
||||||
|
@ -138,13 +139,7 @@ public abstract class AbstractSqmExpression<T> extends AbstractJpaSelection<T> i
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public JpaSelection<T> alias(String name) {
|
public @Nullable JavaType<T> getJavaTypeDescriptor() {
|
||||||
setAlias( name );
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public JavaType<T> getJavaTypeDescriptor() {
|
|
||||||
return getNodeType() == null ? null : getNodeType().getExpressibleJavaType();
|
return getNodeType() == null ? null : getNodeType().getExpressibleJavaType();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,8 @@ import org.hibernate.query.BindableType;
|
||||||
import org.hibernate.query.sqm.NodeBuilder;
|
import org.hibernate.query.sqm.NodeBuilder;
|
||||||
import org.hibernate.query.sqm.SqmExpressible;
|
import org.hibernate.query.sqm.SqmExpressible;
|
||||||
|
|
||||||
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Common support for SqmParameter impls
|
* Common support for SqmParameter impls
|
||||||
*
|
*
|
||||||
|
@ -28,7 +30,7 @@ public abstract class AbstractSqmParameter<T> extends AbstractSqmExpression<T> i
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void applyInferableType(SqmExpressible<?> type) {
|
public void applyInferableType(@Nullable SqmExpressible<?> type) {
|
||||||
if ( type != null ) {
|
if ( type != null ) {
|
||||||
if ( type instanceof PluralPersistentAttribute ) {
|
if ( type instanceof PluralPersistentAttribute ) {
|
||||||
final PluralPersistentAttribute<?, ?, ?> pluralPersistentAttribute =
|
final PluralPersistentAttribute<?, ?, ?> pluralPersistentAttribute =
|
||||||
|
|
|
@ -12,6 +12,8 @@ import org.hibernate.query.sqm.SqmExpressible;
|
||||||
import org.hibernate.query.sqm.tree.SqmCopyContext;
|
import org.hibernate.query.sqm.tree.SqmCopyContext;
|
||||||
import org.hibernate.query.sqm.tree.select.SqmSubQuery;
|
import org.hibernate.query.sqm.tree.select.SqmSubQuery;
|
||||||
|
|
||||||
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Gavin King
|
* @author Gavin King
|
||||||
*/
|
*/
|
||||||
|
@ -25,7 +27,7 @@ public class SqmAny<T> extends AbstractSqmExpression<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SqmExpressible<T> getNodeType() {
|
public @Nullable SqmExpressible<T> getNodeType() {
|
||||||
return subquery.getNodeType();
|
return subquery.getNodeType();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,8 @@ import org.hibernate.query.sqm.SqmExpressible;
|
||||||
import org.hibernate.query.sqm.tree.SqmCopyContext;
|
import org.hibernate.query.sqm.tree.SqmCopyContext;
|
||||||
import org.hibernate.query.sqm.tree.select.SqmSubQuery;
|
import org.hibernate.query.sqm.tree.select.SqmSubQuery;
|
||||||
|
|
||||||
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Gavin King
|
* @author Gavin King
|
||||||
*/
|
*/
|
||||||
|
@ -25,7 +27,7 @@ public class SqmEvery<T> extends AbstractSqmExpression<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SqmExpressible<T> getNodeType() {
|
public @Nullable SqmExpressible<T> getNodeType() {
|
||||||
return subquery.getNodeType();
|
return subquery.getNodeType();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@ import java.math.BigInteger;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import jakarta.persistence.criteria.Expression;
|
import jakarta.persistence.criteria.Expression;
|
||||||
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
import org.hibernate.Internal;
|
import org.hibernate.Internal;
|
||||||
import org.hibernate.query.ReturnableType;
|
import org.hibernate.query.ReturnableType;
|
||||||
|
@ -40,7 +41,7 @@ public interface SqmExpression<T> extends SqmSelectableNode<T>, JpaExpression<T>
|
||||||
* Can change as a result of calls to {@link #applyInferableType}
|
* Can change as a result of calls to {@link #applyInferableType}
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
SqmExpressible<T> getNodeType();
|
@Nullable SqmExpressible<T> getNodeType();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used to apply type information based on the expression's usage
|
* Used to apply type information based on the expression's usage
|
||||||
|
@ -51,7 +52,7 @@ public interface SqmExpression<T> extends SqmSelectableNode<T>, JpaExpression<T>
|
||||||
* an implicit cast)
|
* an implicit cast)
|
||||||
*/
|
*/
|
||||||
@Internal
|
@Internal
|
||||||
void applyInferableType(SqmExpressible<?> type);
|
void applyInferableType(@Nullable SqmExpressible<?> type);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
default void visitSubSelectableNodes(Consumer<SqmSelectableNode<?>> jpaSelectionConsumer) {
|
default void visitSubSelectableNodes(Consumer<SqmSelectableNode<?>> jpaSelectionConsumer) {
|
||||||
|
|
|
@ -29,6 +29,7 @@ import org.hibernate.query.sqm.tree.select.SqmSelectableNode;
|
||||||
import org.hibernate.type.descriptor.java.JavaType;
|
import org.hibernate.type.descriptor.java.JavaType;
|
||||||
|
|
||||||
import jakarta.persistence.criteria.Expression;
|
import jakarta.persistence.criteria.Expression;
|
||||||
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
|
@ -111,7 +112,7 @@ public class SqmFieldLiteral<T> implements SqmExpression<T>, SqmExpressible<T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void applyInferableType(SqmExpressible<?> type) {
|
public void applyInferableType(@Nullable SqmExpressible<?> type) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -11,6 +11,7 @@ import java.math.BigInteger;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
import org.hibernate.HibernateException;
|
import org.hibernate.HibernateException;
|
||||||
|
import org.hibernate.internal.util.NullnessUtil;
|
||||||
import org.hibernate.metamodel.model.domain.BasicDomainType;
|
import org.hibernate.metamodel.model.domain.BasicDomainType;
|
||||||
import org.hibernate.query.sqm.NodeBuilder;
|
import org.hibernate.query.sqm.NodeBuilder;
|
||||||
import org.hibernate.query.sqm.SemanticQueryWalker;
|
import org.hibernate.query.sqm.SemanticQueryWalker;
|
||||||
|
@ -67,7 +68,7 @@ public class SqmHqlNumericLiteral<N extends Number> extends SqmLiteral<N> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BasicDomainType<N> getNodeType() {
|
public BasicDomainType<N> getNodeType() {
|
||||||
return (BasicDomainType<N>) super.getNodeType();
|
return (BasicDomainType<N>) NullnessUtil.castNonNull( super.getNodeType() );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -16,6 +16,8 @@ import org.hibernate.query.sqm.SqmExpressible;
|
||||||
import org.hibernate.query.sqm.tree.SqmCopyContext;
|
import org.hibernate.query.sqm.tree.SqmCopyContext;
|
||||||
import org.hibernate.query.sqm.tree.select.SqmSortSpecification;
|
import org.hibernate.query.sqm.tree.select.SqmSortSpecification;
|
||||||
|
|
||||||
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Christian Beikov
|
* @author Christian Beikov
|
||||||
* @author Marco Belladelli
|
* @author Marco Belladelli
|
||||||
|
@ -86,7 +88,7 @@ public class SqmOver<T> extends AbstractSqmExpression<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SqmExpressible<T> getNodeType() {
|
public @Nullable SqmExpressible<T> getNodeType() {
|
||||||
return expression.getNodeType();
|
return expression.getNodeType();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,6 @@ package org.hibernate.query.sqm.tree.expression;
|
||||||
import org.hibernate.HibernateException;
|
import org.hibernate.HibernateException;
|
||||||
import org.hibernate.query.BindableType;
|
import org.hibernate.query.BindableType;
|
||||||
import org.hibernate.query.criteria.JpaParameterExpression;
|
import org.hibernate.query.criteria.JpaParameterExpression;
|
||||||
import org.hibernate.query.sqm.SqmExpressible;
|
|
||||||
import org.hibernate.query.sqm.tree.SqmCopyContext;
|
import org.hibernate.query.sqm.tree.SqmCopyContext;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -65,9 +64,6 @@ public interface SqmParameter<T> extends SqmExpression<T>, JpaParameterExpressio
|
||||||
*/
|
*/
|
||||||
BindableType<T> getAnticipatedType();
|
BindableType<T> getAnticipatedType();
|
||||||
|
|
||||||
@Override
|
|
||||||
SqmExpressible<T> getNodeType();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Make a copy
|
* Make a copy
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -13,6 +13,8 @@ import org.hibernate.query.sqm.NodeBuilder;
|
||||||
import org.hibernate.query.sqm.SqmExpressible;
|
import org.hibernate.query.sqm.SqmExpressible;
|
||||||
import org.hibernate.query.sqm.tree.select.SqmSelectableNode;
|
import org.hibernate.query.sqm.tree.select.SqmSelectableNode;
|
||||||
|
|
||||||
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base support for {@link JpaSelection} impls.
|
* Base support for {@link JpaSelection} impls.
|
||||||
*
|
*
|
||||||
|
@ -21,7 +23,7 @@ import org.hibernate.query.sqm.tree.select.SqmSelectableNode;
|
||||||
public abstract class AbstractJpaSelection<T>
|
public abstract class AbstractJpaSelection<T>
|
||||||
extends AbstractJpaTupleElement<T>
|
extends AbstractJpaTupleElement<T>
|
||||||
implements SqmSelectableNode<T>, JpaSelection<T> {
|
implements SqmSelectableNode<T>, JpaSelection<T> {
|
||||||
protected AbstractJpaSelection(SqmExpressible<? super T> sqmExpressible, NodeBuilder criteriaBuilder) {
|
protected AbstractJpaSelection(@Nullable SqmExpressible<? super T> sqmExpressible, NodeBuilder criteriaBuilder) {
|
||||||
super( sqmExpressible, criteriaBuilder );
|
super( sqmExpressible, criteriaBuilder );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,8 @@ import org.hibernate.query.sqm.tree.AbstractSqmNode;
|
||||||
import org.hibernate.query.sqm.tree.SqmCopyContext;
|
import org.hibernate.query.sqm.tree.SqmCopyContext;
|
||||||
import org.hibernate.query.sqm.tree.SqmVisitableNode;
|
import org.hibernate.query.sqm.tree.SqmVisitableNode;
|
||||||
|
|
||||||
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base support for {@link JpaTupleElement} impls
|
* Base support for {@link JpaTupleElement} impls
|
||||||
*
|
*
|
||||||
|
@ -22,10 +24,10 @@ public abstract class AbstractJpaTupleElement<T>
|
||||||
extends AbstractSqmNode
|
extends AbstractSqmNode
|
||||||
implements SqmVisitableNode, JpaTupleElement<T> {
|
implements SqmVisitableNode, JpaTupleElement<T> {
|
||||||
|
|
||||||
private SqmExpressible<T> expressibleType;
|
private @Nullable SqmExpressible<T> expressibleType;
|
||||||
private String alias;
|
private @Nullable String alias;
|
||||||
|
|
||||||
protected AbstractJpaTupleElement(SqmExpressible<? super T> expressibleType, NodeBuilder criteriaBuilder) {
|
protected AbstractJpaTupleElement(@Nullable SqmExpressible<? super T> expressibleType, NodeBuilder criteriaBuilder) {
|
||||||
super( criteriaBuilder );
|
super( criteriaBuilder );
|
||||||
setExpressibleType( expressibleType );
|
setExpressibleType( expressibleType );
|
||||||
}
|
}
|
||||||
|
@ -35,22 +37,22 @@ public abstract class AbstractJpaTupleElement<T>
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getAlias() {
|
public @Nullable String getAlias() {
|
||||||
return alias;
|
return alias;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Protected access to set the alias.
|
* Protected access to set the alias.
|
||||||
*/
|
*/
|
||||||
protected void setAlias(String alias) {
|
protected void setAlias(@Nullable String alias) {
|
||||||
this.alias = alias;
|
this.alias = alias;
|
||||||
}
|
}
|
||||||
|
|
||||||
public SqmExpressible<T> getNodeType() {
|
public @Nullable SqmExpressible<T> getNodeType() {
|
||||||
return expressibleType;
|
return expressibleType;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected final void setExpressibleType(SqmExpressible<?> expressibleType) {
|
protected final void setExpressibleType(@Nullable SqmExpressible<?> expressibleType) {
|
||||||
//noinspection unchecked
|
//noinspection unchecked
|
||||||
this.expressibleType = (SqmExpressible<T>) expressibleType;
|
this.expressibleType = (SqmExpressible<T>) expressibleType;
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,6 +69,7 @@ import jakarta.persistence.criteria.Predicate;
|
||||||
import jakarta.persistence.criteria.Root;
|
import jakarta.persistence.criteria.Root;
|
||||||
import jakarta.persistence.criteria.Selection;
|
import jakarta.persistence.criteria.Selection;
|
||||||
import jakarta.persistence.criteria.SetJoin;
|
import jakarta.persistence.criteria.SetJoin;
|
||||||
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
|
@ -600,12 +601,12 @@ public class SqmSubQuery<T> extends AbstractSqmSelectQuery<T> implements SqmSele
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SqmExpressible<T> getNodeType() {
|
public @Nullable SqmExpressible<T> getNodeType() {
|
||||||
return expressibleType;
|
return expressibleType;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void applyInferableType(SqmExpressible<?> type) {
|
public void applyInferableType(@Nullable SqmExpressible<?> type) {
|
||||||
//noinspection unchecked
|
//noinspection unchecked
|
||||||
expressibleType = (SqmExpressible<T>) type;
|
expressibleType = (SqmExpressible<T>) type;
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@ import org.hibernate.collection.spi.MapSemantics;
|
||||||
import org.hibernate.collection.spi.PersistentCollection;
|
import org.hibernate.collection.spi.PersistentCollection;
|
||||||
import org.hibernate.type.descriptor.WrapperOptions;
|
import org.hibernate.type.descriptor.WrapperOptions;
|
||||||
import org.hibernate.type.descriptor.java.AbstractClassJavaType;
|
import org.hibernate.type.descriptor.java.AbstractClassJavaType;
|
||||||
|
import org.hibernate.type.descriptor.java.ArrayJavaType;
|
||||||
import org.hibernate.type.descriptor.java.JavaType;
|
import org.hibernate.type.descriptor.java.JavaType;
|
||||||
import org.hibernate.type.descriptor.java.MutabilityPlan;
|
import org.hibernate.type.descriptor.java.MutabilityPlan;
|
||||||
import org.hibernate.type.descriptor.jdbc.JdbcType;
|
import org.hibernate.type.descriptor.jdbc.JdbcType;
|
||||||
|
@ -58,9 +59,14 @@ public class CollectionJavaType<C> extends AbstractClassJavaType<C> {
|
||||||
TypeConfiguration typeConfiguration) {
|
TypeConfiguration typeConfiguration) {
|
||||||
final Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
|
final Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
|
||||||
final JavaTypeRegistry javaTypeRegistry = typeConfiguration.getJavaTypeRegistry();
|
final JavaTypeRegistry javaTypeRegistry = typeConfiguration.getJavaTypeRegistry();
|
||||||
final JavaType<Object> valueDescriptor = javaTypeRegistry.resolveDescriptor( actualTypeArguments[actualTypeArguments.length - 1] );
|
|
||||||
switch ( semantics.getCollectionClassification() ) {
|
switch ( semantics.getCollectionClassification() ) {
|
||||||
case ARRAY:
|
case ARRAY:
|
||||||
|
//noinspection unchecked
|
||||||
|
return (JavaType<C>) new ArrayJavaType<>(
|
||||||
|
javaTypeRegistry.resolveDescriptor(
|
||||||
|
( (Class<?>) parameterizedType.getRawType() ).getComponentType()
|
||||||
|
)
|
||||||
|
);
|
||||||
case BAG:
|
case BAG:
|
||||||
case ID_BAG:
|
case ID_BAG:
|
||||||
case LIST:
|
case LIST:
|
||||||
|
@ -70,7 +76,7 @@ public class CollectionJavaType<C> extends AbstractClassJavaType<C> {
|
||||||
//noinspection unchecked,rawtypes
|
//noinspection unchecked,rawtypes
|
||||||
return new BasicCollectionJavaType(
|
return new BasicCollectionJavaType(
|
||||||
parameterizedType,
|
parameterizedType,
|
||||||
valueDescriptor,
|
javaTypeRegistry.resolveDescriptor( actualTypeArguments[actualTypeArguments.length - 1] ),
|
||||||
semantics
|
semantics
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -82,7 +88,7 @@ public class CollectionJavaType<C> extends AbstractClassJavaType<C> {
|
||||||
new MapMutabilityPlan<>(
|
new MapMutabilityPlan<>(
|
||||||
(MapSemantics<Map<Object, Object>, Object, Object>) semantics,
|
(MapSemantics<Map<Object, Object>, Object, Object>) semantics,
|
||||||
javaTypeRegistry.resolveDescriptor( actualTypeArguments[0] ),
|
javaTypeRegistry.resolveDescriptor( actualTypeArguments[0] ),
|
||||||
valueDescriptor
|
javaTypeRegistry.resolveDescriptor( actualTypeArguments[actualTypeArguments.length - 1] )
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -192,7 +192,7 @@ public class JdbcTypeJavaClassMappings {
|
||||||
workMap.put( SqlTypes.ARRAY, Array.class );
|
workMap.put( SqlTypes.ARRAY, Array.class );
|
||||||
workMap.put( SqlTypes.STRUCT, Struct.class );
|
workMap.put( SqlTypes.STRUCT, Struct.class );
|
||||||
workMap.put( SqlTypes.REF, Ref.class );
|
workMap.put( SqlTypes.REF, Ref.class );
|
||||||
workMap.put( SqlTypes.JAVA_OBJECT, Class.class );
|
workMap.put( SqlTypes.JAVA_OBJECT, Object.class );
|
||||||
workMap.put( SqlTypes.ROWID, RowId.class );
|
workMap.put( SqlTypes.ROWID, RowId.class );
|
||||||
workMap.put( SqlTypes.SQLXML, SQLXML.class );
|
workMap.put( SqlTypes.SQLXML, SQLXML.class );
|
||||||
workMap.put( SqlTypes.UUID, UUID.class );
|
workMap.put( SqlTypes.UUID, UUID.class );
|
||||||
|
|
|
@ -32,6 +32,7 @@ import org.hibernate.metamodel.model.domain.internal.BasicSqmPathSource;
|
||||||
import org.hibernate.persister.entity.EntityPersister;
|
import org.hibernate.persister.entity.EntityPersister;
|
||||||
import org.hibernate.query.ReturnableType;
|
import org.hibernate.query.ReturnableType;
|
||||||
import org.hibernate.query.sqm.produce.function.FunctionReturnTypeResolver;
|
import org.hibernate.query.sqm.produce.function.FunctionReturnTypeResolver;
|
||||||
|
import org.hibernate.query.sqm.sql.SqmToSqlAstConverter;
|
||||||
import org.hibernate.query.sqm.tree.SqmTypedNode;
|
import org.hibernate.query.sqm.tree.SqmTypedNode;
|
||||||
import org.hibernate.sql.ast.tree.SqlAstNode;
|
import org.hibernate.sql.ast.tree.SqlAstNode;
|
||||||
import org.hibernate.testing.orm.junit.BootstrapServiceRegistry;
|
import org.hibernate.testing.orm.junit.BootstrapServiceRegistry;
|
||||||
|
@ -48,6 +49,8 @@ import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.*;
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -137,15 +140,7 @@ public class DynamicParameterizedTypeTest {
|
||||||
@Override
|
@Override
|
||||||
public ReturnableType<?> resolveFunctionReturnType(
|
public ReturnableType<?> resolveFunctionReturnType(
|
||||||
ReturnableType<?> impliedType,
|
ReturnableType<?> impliedType,
|
||||||
List<? extends SqmTypedNode<?>> arguments,
|
@Nullable SqmToSqlAstConverter converter,
|
||||||
TypeConfiguration typeConfiguration) {
|
|
||||||
return resolveFunctionReturnType( impliedType, null, arguments, typeConfiguration );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ReturnableType<?> resolveFunctionReturnType(
|
|
||||||
ReturnableType<?> impliedType,
|
|
||||||
Supplier<MappingModelExpressible<?>> inferredTypeSupplier,
|
|
||||||
List<? extends SqmTypedNode<?>> arguments,
|
List<? extends SqmTypedNode<?>> arguments,
|
||||||
TypeConfiguration typeConfiguration) {
|
TypeConfiguration typeConfiguration) {
|
||||||
SqmTypedNode<?> sqmTypedNode = arguments.get(0);
|
SqmTypedNode<?> sqmTypedNode = arguments.get(0);
|
||||||
|
|
|
@ -138,7 +138,7 @@ public class OrderByFragmentFunction extends AbstractSqmFunctionDescriptor {
|
||||||
QueryEngine queryEngine) {
|
QueryEngine queryEngine) {
|
||||||
super(
|
super(
|
||||||
orderByFragmentFunction,
|
orderByFragmentFunction,
|
||||||
null,
|
(sqlAppender, sqlAstArguments, returnType, walker) -> {},
|
||||||
arguments,
|
arguments,
|
||||||
impliedResultType,
|
impliedResultType,
|
||||||
orderByFragmentFunction.getArgumentsValidator(),
|
orderByFragmentFunction.getArgumentsValidator(),
|
||||||
|
|
|
@ -2558,9 +2558,14 @@ public class AnnotationMetaEntity extends AnnotationMeta {
|
||||||
// TODO: anything more we can do here? e.g. check constructor
|
// TODO: anything more we can do here? e.g. check constructor
|
||||||
try {
|
try {
|
||||||
final Class<?> javaResultType = selection.getJavaType();
|
final Class<?> javaResultType = selection.getJavaType();
|
||||||
final TypeElement typeElement = context.getTypeElementForFullyQualifiedName( javaResultType.getName() );
|
if ( javaResultType == null ) {
|
||||||
final Types types = context.getTypeUtils();
|
returnTypeCorrect = true;
|
||||||
returnTypeCorrect = types.isAssignable( returnType, types.erasure( typeElement.asType() ) );
|
}
|
||||||
|
else {
|
||||||
|
final TypeElement typeElement = context.getTypeElementForFullyQualifiedName( javaResultType.getName() );
|
||||||
|
final Types types = context.getTypeUtils();
|
||||||
|
returnTypeCorrect = context.getTypeUtils().isAssignable( returnType, types.erasure( typeElement.asType() ) );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (Exception e) {
|
catch (Exception e) {
|
||||||
//ignore
|
//ignore
|
||||||
|
@ -2670,7 +2675,8 @@ public class AnnotationMetaEntity extends AnnotationMeta {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean parameterMatches(VariableElement parameter, JpaSelection<?> item) {
|
private static boolean parameterMatches(VariableElement parameter, JpaSelection<?> item) {
|
||||||
return parameterMatches( parameter.asType(), item.getJavaType() );
|
final Class<?> javaType = item.getJavaType();
|
||||||
|
return javaType != null && parameterMatches( parameter.asType(), javaType );
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean parameterMatches(TypeMirror parameterType, Class<?> itemType) {
|
private static boolean parameterMatches(TypeMirror parameterType, Class<?> itemType) {
|
||||||
|
|
|
@ -104,8 +104,9 @@ class NamedQueryMethod implements MetaAttribute {
|
||||||
else {
|
else {
|
||||||
final List<SqmSelectableNode<?>> items =
|
final List<SqmSelectableNode<?>> items =
|
||||||
select.getQuerySpec().getSelectClause().getSelectionItems();
|
select.getQuerySpec().getSelectClause().getSelectionItems();
|
||||||
if ( items.size() == 1 ) {
|
final SqmExpressible<?> expressible;
|
||||||
final String typeName = items.get(0).getExpressible().getTypeName();
|
if ( items.size() == 1 && ( expressible = items.get( 0 ).getExpressible() ) != null ) {
|
||||||
|
final String typeName = expressible.getTypeName();
|
||||||
final TypeElement entityType = entityType( typeName );
|
final TypeElement entityType = entityType( typeName );
|
||||||
return entityType == null ? typeName : entityType.getQualifiedName().toString();
|
return entityType == null ? typeName : entityType.getQualifiedName().toString();
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue