Initial working support for building and executing JdbcSelect operation from simple HQL for a converted (enum) value
This commit is contained in:
parent
dbd108e0b7
commit
5b1df3c6c9
|
@ -104,7 +104,8 @@ public class BasicValuedSingularAttributeMapping extends AbstractSingularAttribu
|
||||||
sqlSelection.getValuesArrayPosition(),
|
sqlSelection.getValuesArrayPosition(),
|
||||||
resultVariable,
|
resultVariable,
|
||||||
getMappedTypeDescriptor().getMappedJavaTypeDescriptor(),
|
getMappedTypeDescriptor().getMappedJavaTypeDescriptor(),
|
||||||
valueConverter
|
valueConverter,
|
||||||
|
navigablePath
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -67,4 +67,11 @@ public class BasicResultAssembler<J> implements DomainResultAssembler<J> {
|
||||||
public JavaTypeDescriptor<J> getAssembledJavaTypeDescriptor() {
|
public JavaTypeDescriptor<J> getAssembledJavaTypeDescriptor() {
|
||||||
return assembledJavaTypeDescriptor;
|
return assembledJavaTypeDescriptor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Exposed for testing purposes
|
||||||
|
*/
|
||||||
|
public BasicValueConverter<J, ?> getValueConverter() {
|
||||||
|
return valueConverter;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@ package org.hibernate.sql.results.internal;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
import org.hibernate.metamodel.model.convert.spi.BasicValueConverter;
|
import org.hibernate.metamodel.model.convert.spi.BasicValueConverter;
|
||||||
|
import org.hibernate.query.NavigablePath;
|
||||||
import org.hibernate.sql.results.spi.AssemblerCreationState;
|
import org.hibernate.sql.results.spi.AssemblerCreationState;
|
||||||
import org.hibernate.sql.results.spi.DomainResultAssembler;
|
import org.hibernate.sql.results.spi.DomainResultAssembler;
|
||||||
import org.hibernate.sql.results.spi.Initializer;
|
import org.hibernate.sql.results.spi.Initializer;
|
||||||
|
@ -22,15 +23,27 @@ public class ScalarDomainResultImpl<T> implements ScalarDomainResult<T> {
|
||||||
private final String resultVariable;
|
private final String resultVariable;
|
||||||
private final JavaTypeDescriptor<T> javaTypeDescriptor;
|
private final JavaTypeDescriptor<T> javaTypeDescriptor;
|
||||||
|
|
||||||
|
private final NavigablePath navigablePath;
|
||||||
|
|
||||||
private final DomainResultAssembler<T> assembler;
|
private final DomainResultAssembler<T> assembler;
|
||||||
|
|
||||||
public ScalarDomainResultImpl(
|
public ScalarDomainResultImpl(
|
||||||
int jdbcValuesArrayPosition,
|
int jdbcValuesArrayPosition,
|
||||||
String resultVariable,
|
String resultVariable,
|
||||||
JavaTypeDescriptor<T> javaTypeDescriptor) {
|
JavaTypeDescriptor<T> javaTypeDescriptor) {
|
||||||
|
this( jdbcValuesArrayPosition, resultVariable, javaTypeDescriptor, (NavigablePath) null );
|
||||||
|
}
|
||||||
|
|
||||||
|
public ScalarDomainResultImpl(
|
||||||
|
int jdbcValuesArrayPosition,
|
||||||
|
String resultVariable,
|
||||||
|
JavaTypeDescriptor<T> javaTypeDescriptor,
|
||||||
|
NavigablePath navigablePath) {
|
||||||
this.resultVariable = resultVariable;
|
this.resultVariable = resultVariable;
|
||||||
this.javaTypeDescriptor = javaTypeDescriptor;
|
this.javaTypeDescriptor = javaTypeDescriptor;
|
||||||
|
|
||||||
|
this.navigablePath = navigablePath;
|
||||||
|
|
||||||
this.assembler = new BasicResultAssembler<>( jdbcValuesArrayPosition, javaTypeDescriptor );
|
this.assembler = new BasicResultAssembler<>( jdbcValuesArrayPosition, javaTypeDescriptor );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,8 +52,18 @@ public class ScalarDomainResultImpl<T> implements ScalarDomainResult<T> {
|
||||||
String resultVariable,
|
String resultVariable,
|
||||||
JavaTypeDescriptor<T> javaTypeDescriptor,
|
JavaTypeDescriptor<T> javaTypeDescriptor,
|
||||||
BasicValueConverter<T,?> valueConverter) {
|
BasicValueConverter<T,?> valueConverter) {
|
||||||
|
this( valuesArrayPosition, resultVariable, javaTypeDescriptor, valueConverter, null );
|
||||||
|
}
|
||||||
|
|
||||||
|
public ScalarDomainResultImpl(
|
||||||
|
int valuesArrayPosition,
|
||||||
|
String resultVariable,
|
||||||
|
JavaTypeDescriptor<T> javaTypeDescriptor,
|
||||||
|
BasicValueConverter<T,?> valueConverter,
|
||||||
|
NavigablePath navigablePath) {
|
||||||
this.resultVariable = resultVariable;
|
this.resultVariable = resultVariable;
|
||||||
this.javaTypeDescriptor = javaTypeDescriptor;
|
this.javaTypeDescriptor = javaTypeDescriptor;
|
||||||
|
this.navigablePath = navigablePath;
|
||||||
|
|
||||||
this.assembler = new BasicResultAssembler<>( valuesArrayPosition, javaTypeDescriptor, valueConverter );
|
this.assembler = new BasicResultAssembler<>( valuesArrayPosition, javaTypeDescriptor, valueConverter );
|
||||||
}
|
}
|
||||||
|
@ -55,6 +78,11 @@ public class ScalarDomainResultImpl<T> implements ScalarDomainResult<T> {
|
||||||
return javaTypeDescriptor;
|
return javaTypeDescriptor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NavigablePath getNavigablePath() {
|
||||||
|
return navigablePath;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DomainResultAssembler<T> createResultAssembler(
|
public DomainResultAssembler<T> createResultAssembler(
|
||||||
Consumer<Initializer> initializerCollector,
|
Consumer<Initializer> initializerCollector,
|
||||||
|
|
|
@ -14,11 +14,9 @@ import java.sql.SQLException;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Properties;
|
|
||||||
|
|
||||||
import org.hibernate.HibernateException;
|
import org.hibernate.HibernateException;
|
||||||
import org.hibernate.MappingException;
|
import org.hibernate.MappingException;
|
||||||
import org.hibernate.NotYetImplementedFor6Exception;
|
|
||||||
import org.hibernate.dialect.Dialect;
|
import org.hibernate.dialect.Dialect;
|
||||||
import org.hibernate.engine.jdbc.Size;
|
import org.hibernate.engine.jdbc.Size;
|
||||||
import org.hibernate.engine.spi.Mapping;
|
import org.hibernate.engine.spi.Mapping;
|
||||||
|
@ -30,7 +28,6 @@ import org.hibernate.type.descriptor.sql.SqlTypeDescriptor;
|
||||||
import org.hibernate.type.spi.TypeConfiguration;
|
import org.hibernate.type.spi.TypeConfiguration;
|
||||||
import org.hibernate.usertype.EnhancedUserType;
|
import org.hibernate.usertype.EnhancedUserType;
|
||||||
import org.hibernate.usertype.LoggableUserType;
|
import org.hibernate.usertype.LoggableUserType;
|
||||||
import org.hibernate.usertype.ParameterizedType;
|
|
||||||
import org.hibernate.usertype.Sized;
|
import org.hibernate.usertype.Sized;
|
||||||
import org.hibernate.usertype.UserType;
|
import org.hibernate.usertype.UserType;
|
||||||
import org.hibernate.usertype.UserVersionType;
|
import org.hibernate.usertype.UserVersionType;
|
||||||
|
@ -44,7 +41,7 @@ import org.hibernate.usertype.UserVersionType;
|
||||||
*/
|
*/
|
||||||
public class CustomType
|
public class CustomType
|
||||||
extends AbstractType
|
extends AbstractType
|
||||||
implements IdentifierType, DiscriminatorType, VersionType, BasicType, StringRepresentableType, ProcedureParameterNamedBinder, ProcedureParameterExtractionAware {
|
implements BasicType, IdentifierType, DiscriminatorType, VersionType, StringRepresentableType, ProcedureParameterNamedBinder, ProcedureParameterExtractionAware {
|
||||||
|
|
||||||
private final UserType userType;
|
private final UserType userType;
|
||||||
private final String[] registrationKeys;
|
private final String[] registrationKeys;
|
||||||
|
@ -90,8 +87,8 @@ public class CustomType
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String[] getRegistrationKeys() {
|
public SqlTypeDescriptor getSqlTypeDescriptor() {
|
||||||
return registrationKeys;
|
return sqlTypeDescriptor;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -99,6 +96,11 @@ public class CustomType
|
||||||
return new int[] { sqlTypeDescriptor.getSqlType() };
|
return new int[] { sqlTypeDescriptor.getSqlType() };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String[] getRegistrationKeys() {
|
||||||
|
return registrationKeys;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Size[] dictatedSizes(Mapping mapping) throws MappingException {
|
public Size[] dictatedSizes(Mapping mapping) throws MappingException {
|
||||||
return new Size[] {dictatedSize};
|
return new Size[] {dictatedSize};
|
||||||
|
@ -271,13 +273,13 @@ public class CustomType
|
||||||
@Override
|
@Override
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public String toString(Object value) throws HibernateException {
|
public String toString(Object value) throws HibernateException {
|
||||||
if ( StringRepresentableType.class.isInstance( getUserType() ) ) {
|
if ( getUserType() instanceof StringRepresentableType ) {
|
||||||
return ( (StringRepresentableType) getUserType() ).toString( value );
|
return ( (StringRepresentableType) getUserType() ).toString( value );
|
||||||
}
|
}
|
||||||
if ( value == null ) {
|
if ( value == null ) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
if ( EnhancedUserType.class.isInstance( getUserType() ) ) {
|
if ( getUserType() instanceof EnhancedUserType ) {
|
||||||
//noinspection deprecation
|
//noinspection deprecation
|
||||||
return ( (EnhancedUserType) getUserType() ).toXMLString( value );
|
return ( (EnhancedUserType) getUserType() ).toXMLString( value );
|
||||||
}
|
}
|
||||||
|
@ -286,10 +288,10 @@ public class CustomType
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object fromStringValue(String string) throws HibernateException {
|
public Object fromStringValue(String string) throws HibernateException {
|
||||||
if ( StringRepresentableType.class.isInstance( getUserType() ) ) {
|
if ( getUserType() instanceof StringRepresentableType ) {
|
||||||
return ( (StringRepresentableType) getUserType() ).fromStringValue( string );
|
return ( (StringRepresentableType) getUserType() ).fromStringValue( string );
|
||||||
}
|
}
|
||||||
if ( EnhancedUserType.class.isInstance( getUserType() ) ) {
|
if ( getUserType() instanceof EnhancedUserType ) {
|
||||||
//noinspection deprecation
|
//noinspection deprecation
|
||||||
return ( (EnhancedUserType) getUserType() ).fromXMLString( string );
|
return ( (EnhancedUserType) getUserType() ).fromXMLString( string );
|
||||||
}
|
}
|
||||||
|
@ -305,7 +307,7 @@ public class CustomType
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean canDoSetting() {
|
public boolean canDoSetting() {
|
||||||
if ( ProcedureParameterNamedBinder.class.isInstance( getUserType() ) ) {
|
if ( getUserType() instanceof ProcedureParameterNamedBinder ) {
|
||||||
return ((ProcedureParameterNamedBinder) getUserType() ).canDoSetting();
|
return ((ProcedureParameterNamedBinder) getUserType() ).canDoSetting();
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -326,17 +328,12 @@ public class CustomType
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean canDoExtraction() {
|
public boolean canDoExtraction() {
|
||||||
if ( ProcedureParameterExtractionAware.class.isInstance( getUserType() ) ) {
|
if ( getUserType() instanceof ProcedureParameterExtractionAware ) {
|
||||||
return ((ProcedureParameterExtractionAware) getUserType() ).canDoExtraction();
|
return ((ProcedureParameterExtractionAware) getUserType() ).canDoExtraction();
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public SqlTypeDescriptor getSqlTypeDescriptor() {
|
|
||||||
throw new NotYetImplementedFor6Exception( getClass() );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object extract(CallableStatement statement, int startIndex, SharedSessionContractImplementor session) throws SQLException {
|
public Object extract(CallableStatement statement, int startIndex, SharedSessionContractImplementor session) throws SQLException {
|
||||||
if ( canDoExtraction() ) {
|
if ( canDoExtraction() ) {
|
||||||
|
|
|
@ -90,6 +90,10 @@ public class EnumType<T extends Enum>
|
||||||
this.typeConfiguration = typeConfiguration;
|
this.typeConfiguration = typeConfiguration;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public EnumValueConverter getEnumValueConverter() {
|
||||||
|
return enumValueConverter;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setParameterValues(Properties parameters) {
|
public void setParameterValues(Properties parameters) {
|
||||||
// IMPL NOTE: we handle 2 distinct cases here:
|
// IMPL NOTE: we handle 2 distinct cases here:
|
||||||
|
|
|
@ -7,19 +7,34 @@
|
||||||
package org.hibernate.orm.test.sql.ast;
|
package org.hibernate.orm.test.sql.ast;
|
||||||
|
|
||||||
import org.hibernate.cfg.AvailableSettings;
|
import org.hibernate.cfg.AvailableSettings;
|
||||||
|
import org.hibernate.metamodel.mapping.MappingModelExpressable;
|
||||||
|
import org.hibernate.metamodel.mapping.internal.BasicValuedSingularAttributeMapping;
|
||||||
|
import org.hibernate.metamodel.model.convert.internal.OrdinalEnumValueConverter;
|
||||||
|
import org.hibernate.metamodel.model.convert.spi.BasicValueConverter;
|
||||||
|
import org.hibernate.metamodel.model.convert.spi.EnumValueConverter;
|
||||||
|
import org.hibernate.orm.test.metamodel.mapping.SmokeTests.Gender;
|
||||||
|
import org.hibernate.query.NavigablePath;
|
||||||
import org.hibernate.query.hql.spi.HqlQueryImplementor;
|
import org.hibernate.query.hql.spi.HqlQueryImplementor;
|
||||||
import org.hibernate.query.spi.QueryImplementor;
|
import org.hibernate.query.spi.QueryImplementor;
|
||||||
import org.hibernate.query.sqm.internal.QuerySqmImpl;
|
import org.hibernate.query.sqm.internal.QuerySqmImpl;
|
||||||
import org.hibernate.query.sqm.sql.internal.SqmSelectInterpretation;
|
import org.hibernate.query.sqm.sql.internal.SqmSelectInterpretation;
|
||||||
import org.hibernate.query.sqm.sql.internal.SqmSelectToSqlAstConverter;
|
import org.hibernate.query.sqm.sql.internal.SqmSelectToSqlAstConverter;
|
||||||
import org.hibernate.query.sqm.tree.select.SqmSelectStatement;
|
import org.hibernate.query.sqm.tree.select.SqmSelectStatement;
|
||||||
import org.hibernate.sql.ast.spi.SqlAstSelectToJdbcSelectConverter;
|
|
||||||
import org.hibernate.sql.ast.spi.SqlSelection;
|
import org.hibernate.sql.ast.spi.SqlSelection;
|
||||||
|
import org.hibernate.sql.ast.tree.expression.ColumnReference;
|
||||||
|
import org.hibernate.sql.ast.tree.expression.Expression;
|
||||||
import org.hibernate.sql.ast.tree.from.FromClause;
|
import org.hibernate.sql.ast.tree.from.FromClause;
|
||||||
import org.hibernate.sql.ast.tree.from.TableGroup;
|
import org.hibernate.sql.ast.tree.from.TableGroup;
|
||||||
import org.hibernate.sql.ast.tree.select.SelectClause;
|
import org.hibernate.sql.ast.tree.select.SelectClause;
|
||||||
import org.hibernate.sql.ast.tree.select.SelectStatement;
|
import org.hibernate.sql.ast.tree.select.SelectStatement;
|
||||||
import org.hibernate.sql.exec.spi.JdbcSelect;
|
import org.hibernate.sql.results.internal.BasicResultAssembler;
|
||||||
|
import org.hibernate.sql.results.internal.ScalarDomainResultImpl;
|
||||||
|
import org.hibernate.sql.results.internal.SqlSelectionImpl;
|
||||||
|
import org.hibernate.sql.results.spi.DomainResult;
|
||||||
|
import org.hibernate.sql.results.spi.DomainResultAssembler;
|
||||||
|
import org.hibernate.type.CustomType;
|
||||||
|
import org.hibernate.type.EnumType;
|
||||||
|
import org.hibernate.usertype.UserType;
|
||||||
|
|
||||||
import org.hibernate.testing.orm.junit.DomainModel;
|
import org.hibernate.testing.orm.junit.DomainModel;
|
||||||
import org.hibernate.testing.orm.junit.ServiceRegistry;
|
import org.hibernate.testing.orm.junit.ServiceRegistry;
|
||||||
|
@ -27,6 +42,8 @@ import org.hibernate.testing.orm.junit.SessionFactory;
|
||||||
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import static org.hamcrest.CoreMatchers.equalTo;
|
||||||
|
import static org.hamcrest.CoreMatchers.instanceOf;
|
||||||
import static org.hamcrest.CoreMatchers.is;
|
import static org.hamcrest.CoreMatchers.is;
|
||||||
import static org.hamcrest.CoreMatchers.notNullValue;
|
import static org.hamcrest.CoreMatchers.notNullValue;
|
||||||
import static org.hamcrest.MatcherAssert.assertThat;
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
|
@ -47,7 +64,7 @@ import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
@SessionFactory
|
@SessionFactory
|
||||||
public class SmokeTests {
|
public class SmokeTests {
|
||||||
@Test
|
@Test
|
||||||
public void testSimpleHql(SessionFactoryScope scope) {
|
public void testSimpleHqlInterpretation(SessionFactoryScope scope) {
|
||||||
scope.inTransaction(
|
scope.inTransaction(
|
||||||
session -> {
|
session -> {
|
||||||
final QueryImplementor<String> query = session.createQuery( "select e.name from SimpleEntity e", String.class );
|
final QueryImplementor<String> query = session.createQuery( "select e.name from SimpleEntity e", String.class );
|
||||||
|
@ -66,17 +83,32 @@ public class SmokeTests {
|
||||||
final SqmSelectInterpretation sqmInterpretation = sqmConverter.interpret( sqmStatement );
|
final SqmSelectInterpretation sqmInterpretation = sqmConverter.interpret( sqmStatement );
|
||||||
final SelectStatement sqlAst = sqmInterpretation.getSqlAst();
|
final SelectStatement sqlAst = sqmInterpretation.getSqlAst();
|
||||||
|
|
||||||
checkSqmInterpretation( sqlAst );
|
final FromClause fromClause = sqlAst.getQuerySpec().getFromClause();
|
||||||
|
assertThat( fromClause.getRoots().size(), is( 1 ) );
|
||||||
|
|
||||||
final JdbcSelect jdbcSelectOperation = SqlAstSelectToJdbcSelectConverter.interpret(
|
final TableGroup rootTableGroup = fromClause.getRoots().get( 0 );
|
||||||
sqlAst,
|
assertThat( rootTableGroup.getPrimaryTableReference(), notNullValue() );
|
||||||
session.getSessionFactory()
|
assertThat( rootTableGroup.getPrimaryTableReference().getTableExpression(), is( "mapping_simple_entity" ) );
|
||||||
);
|
|
||||||
|
|
||||||
assertThat( jdbcSelectOperation.getSql(), is( "select s1_0.name from mapping_simple_entity as s1_0" ) );
|
assertThat( rootTableGroup.getTableReferenceJoins().size(), is( 0 ) );
|
||||||
|
|
||||||
|
assertThat( rootTableGroup.hasTableGroupJoins(), is( false ) );
|
||||||
|
|
||||||
|
|
||||||
|
// `s` is the "alias stem" for `SimpleEntity` and as it is the first entity with that stem in
|
||||||
|
// the query the base becomes `s1`. The primary table reference is always suffixed as `_0`
|
||||||
|
assertThat( rootTableGroup.getPrimaryTableReference().getIdentificationVariable(), is( "s1_0" ) );
|
||||||
|
|
||||||
|
final SelectClause selectClause = sqlAst.getQuerySpec().getSelectClause();
|
||||||
|
assertThat( selectClause.getSqlSelections().size(), is( 1 ) ) ;
|
||||||
|
final SqlSelection sqlSelection = selectClause.getSqlSelections().get( 0 );
|
||||||
|
assertThat( sqlSelection.getJdbcResultSetIndex(), is( 1 ) );
|
||||||
|
assertThat( sqlSelection.getValuesArrayPosition(), is( 0 ) );
|
||||||
|
assertThat( sqlSelection.getJdbcValueExtractor(), notNullValue() );
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSimpleHqlExecution(SessionFactoryScope scope) {
|
public void testSimpleHqlExecution(SessionFactoryScope scope) {
|
||||||
scope.inTransaction(
|
scope.inTransaction(
|
||||||
|
@ -86,29 +118,96 @@ public class SmokeTests {
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@Test
|
||||||
|
public void testConvertedHqlInterpretation(SessionFactoryScope scope) {
|
||||||
|
scope.inTransaction(
|
||||||
|
session -> {
|
||||||
|
final QueryImplementor<Gender> query = session.createQuery( "select e.gender from SimpleEntity e", Gender.class );
|
||||||
|
final HqlQueryImplementor<Gender> hqlQuery = (HqlQueryImplementor<Gender>) query;
|
||||||
|
//noinspection unchecked
|
||||||
|
final SqmSelectStatement<Gender> sqmStatement = (SqmSelectStatement<Gender>) hqlQuery.getSqmStatement();
|
||||||
|
|
||||||
private void checkSqmInterpretation(SelectStatement sqlAst) {
|
final SqmSelectToSqlAstConverter sqmConverter = new SqmSelectToSqlAstConverter(
|
||||||
final FromClause fromClause = sqlAst.getQuerySpec().getFromClause();
|
hqlQuery.getQueryOptions(),
|
||||||
assertThat( fromClause.getRoots().size(), is( 1 ) );
|
( (QuerySqmImpl) hqlQuery ).getDomainParameterXref(),
|
||||||
|
query.getParameterBindings(),
|
||||||
|
session.getLoadQueryInfluencers(),
|
||||||
|
scope.getSessionFactory()
|
||||||
|
);
|
||||||
|
|
||||||
final TableGroup rootTableGroup = fromClause.getRoots().get( 0 );
|
final SqmSelectInterpretation sqmInterpretation = sqmConverter.interpret( sqmStatement );
|
||||||
assertThat( rootTableGroup.getPrimaryTableReference(), notNullValue() );
|
final SelectStatement sqlAst = sqmInterpretation.getSqlAst();
|
||||||
assertThat( rootTableGroup.getPrimaryTableReference().getTableExpression(), is( "mapping_simple_entity" ) );
|
|
||||||
|
|
||||||
assertThat( rootTableGroup.getTableReferenceJoins().size(), is( 0 ) );
|
final FromClause fromClause = sqlAst.getQuerySpec().getFromClause();
|
||||||
|
assertThat( fromClause.getRoots().size(), is( 1 ) );
|
||||||
|
|
||||||
assertThat( rootTableGroup.hasTableGroupJoins(), is( false ) );
|
final TableGroup rootTableGroup = fromClause.getRoots().get( 0 );
|
||||||
|
assertThat( rootTableGroup.getPrimaryTableReference(), notNullValue() );
|
||||||
|
assertThat( rootTableGroup.getPrimaryTableReference().getTableExpression(), is( "mapping_simple_entity" ) );
|
||||||
|
|
||||||
|
assertThat( rootTableGroup.getTableReferenceJoins().size(), is( 0 ) );
|
||||||
|
|
||||||
|
assertThat( rootTableGroup.hasTableGroupJoins(), is( false ) );
|
||||||
|
|
||||||
|
|
||||||
// `s` is the "alias stem" for `SimpleEntity` and as it is the first entity with that stem in
|
// `s` is the "alias stem" for `SimpleEntity` and as it is the first entity with that stem in
|
||||||
// the query the base becomes `s1`. The primary table reference is always suffixed as `_0`
|
// the query the base becomes `s1`. The primary table reference is always suffixed as `_0`
|
||||||
assertThat( rootTableGroup.getPrimaryTableReference().getIdentificationVariable(), is( "s1_0" ) );
|
assertThat( rootTableGroup.getPrimaryTableReference().getIdentificationVariable(), is( "s1_0" ) );
|
||||||
|
|
||||||
final SelectClause selectClause = sqlAst.getQuerySpec().getSelectClause();
|
final SelectClause selectClause = sqlAst.getQuerySpec().getSelectClause();
|
||||||
assertThat( selectClause.getSqlSelections().size(), is( 1 ) ) ;
|
assertThat( selectClause.getSqlSelections().size(), is( 1 ) ) ;
|
||||||
final SqlSelection sqlSelection = selectClause.getSqlSelections().get( 0 );
|
|
||||||
assertThat( sqlSelection.getJdbcResultSetIndex(), is( 1 ) );
|
final SqlSelection sqlSelection = selectClause.getSqlSelections().get( 0 );
|
||||||
assertThat( sqlSelection.getValuesArrayPosition(), is( 0 ) );
|
assertThat( sqlSelection.getJdbcResultSetIndex(), is( 1 ) );
|
||||||
assertThat( sqlSelection.getJdbcValueExtractor(), notNullValue() );
|
assertThat( sqlSelection.getValuesArrayPosition(), is( 0 ) );
|
||||||
|
assertThat( sqlSelection.getJdbcValueExtractor(), notNullValue() );
|
||||||
|
|
||||||
|
assertThat( sqlSelection, instanceOf( SqlSelectionImpl.class ) );
|
||||||
|
final Expression selectedExpression = ( (SqlSelectionImpl) sqlSelection ).getWrappedSqlExpression();
|
||||||
|
assertThat( selectedExpression, instanceOf( ColumnReference.class ) );
|
||||||
|
final ColumnReference columnReference = (ColumnReference) selectedExpression;
|
||||||
|
assertThat( columnReference.getReferencedColumnExpression(), is( "gender" ) );
|
||||||
|
assertThat( columnReference.renderSqlFragment( scope.getSessionFactory() ), is( "s1_0.gender" ) );
|
||||||
|
|
||||||
|
final MappingModelExpressable selectedExpressable = selectedExpression.getExpressionType();
|
||||||
|
assertThat( selectedExpressable, instanceOf( CustomType.class ) );
|
||||||
|
final UserType userType = ( (CustomType) selectedExpressable ).getUserType();
|
||||||
|
assertThat( userType, instanceOf( EnumType.class ) );
|
||||||
|
final EnumValueConverter enumValueConverter = ( (EnumType) userType ).getEnumValueConverter();
|
||||||
|
assertThat( enumValueConverter, notNullValue() );
|
||||||
|
assertThat( enumValueConverter.getDomainJavaDescriptor().getJavaType(), equalTo( Gender.class ) );
|
||||||
|
|
||||||
|
assertThat( sqlAst.getDomainResultDescriptors().size(), is( 1 ) );
|
||||||
|
final DomainResult domainResult = sqlAst.getDomainResultDescriptors().get( 0 );
|
||||||
|
final NavigablePath expectedSelectedPath = new NavigablePath(
|
||||||
|
org.hibernate.orm.test.metamodel.mapping.SmokeTests.SimpleEntity.class.getName(),
|
||||||
|
"e"
|
||||||
|
).append( "gender" );
|
||||||
|
assertThat( domainResult.getNavigablePath(), equalTo( expectedSelectedPath ) );
|
||||||
|
assertThat( domainResult, instanceOf( ScalarDomainResultImpl.class ) );
|
||||||
|
|
||||||
|
// ScalarDomainResultImpl creates and caches the assembler at its creation.
|
||||||
|
// this just gets access to that cached one
|
||||||
|
final DomainResultAssembler resultAssembler = domainResult.createResultAssembler(
|
||||||
|
null,
|
||||||
|
null
|
||||||
|
);
|
||||||
|
|
||||||
|
assertThat( resultAssembler, instanceOf( BasicResultAssembler.class ) );
|
||||||
|
final BasicValueConverter valueConverter = ( (BasicResultAssembler) resultAssembler ).getValueConverter();
|
||||||
|
assertThat( valueConverter, notNullValue() );
|
||||||
|
assertThat( valueConverter, instanceOf( OrdinalEnumValueConverter.class ) );
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testConvertedHqlExecution(SessionFactoryScope scope) {
|
||||||
|
scope.inTransaction(
|
||||||
|
session -> {
|
||||||
|
final QueryImplementor<Gender> query = session.createQuery( "select e.gender from SimpleEntity e", Gender.class );
|
||||||
|
query.list();
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue