HHH-18720 Type check on select columns in union all gives SemanticException when there is a null column

This commit is contained in:
Andrea Boriero 2024-10-15 19:02:37 +02:00 committed by Andrea Boriero
parent cdca0d34ea
commit 0843f7d3fb
2 changed files with 22 additions and 5 deletions

View File

@ -170,7 +170,8 @@ public class SqmQueryGroup<T> extends SqmQueryPart<T> implements JpaQueryGroup<T
for ( int j = 0; j < firstSelectionSize; j++ ) { for ( int j = 0; j < firstSelectionSize; j++ ) {
final SqmTypedNode<?> firstSqmSelection = typedNodes.get( j ); final SqmTypedNode<?> firstSqmSelection = typedNodes.get( j );
final JavaType<?> firstJavaType = firstSqmSelection.getNodeJavaType(); final JavaType<?> firstJavaType = firstSqmSelection.getNodeJavaType();
if ( firstJavaType != selections.get( j ).getNodeJavaType() ) { final JavaType<?> nodeJavaType = selections.get( j ).getNodeJavaType();
if ( nodeJavaType != null && firstJavaType != null && firstJavaType != nodeJavaType ) {
throw new SemanticException( throw new SemanticException(
"Select items of the same index must have the same java type across all query parts" "Select items of the same index must have the same java type across all query parts"
); );

View File

@ -9,9 +9,15 @@ package org.hibernate.sql.results.jdbc.internal;
import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.query.results.ResultSetMapping; import org.hibernate.query.results.ResultSetMapping;
import org.hibernate.query.results.ResultSetMappingImpl; import org.hibernate.query.results.ResultSetMappingImpl;
import org.hibernate.sql.ast.spi.SqlSelection;
import org.hibernate.sql.ast.tree.select.QueryGroup;
import org.hibernate.sql.ast.tree.select.QueryPart;
import org.hibernate.sql.ast.tree.select.SelectStatement; import org.hibernate.sql.ast.tree.select.SelectStatement;
import org.hibernate.sql.results.jdbc.spi.JdbcValuesMappingProducer; import org.hibernate.sql.results.jdbc.spi.JdbcValuesMappingProducer;
import org.hibernate.sql.results.jdbc.spi.JdbcValuesMappingProducerProvider; import org.hibernate.sql.results.jdbc.spi.JdbcValuesMappingProducerProvider;
import org.hibernate.type.descriptor.jdbc.NullJdbcType;
import java.util.List;
/** /**
* Standard JdbcValuesMappingProducerProvider implementation * Standard JdbcValuesMappingProducerProvider implementation
@ -28,10 +34,20 @@ public class JdbcValuesMappingProducerProviderStandard implements JdbcValuesMapp
public JdbcValuesMappingProducer buildMappingProducer( public JdbcValuesMappingProducer buildMappingProducer(
SelectStatement sqlAst, SelectStatement sqlAst,
SessionFactoryImplementor sessionFactory) { SessionFactoryImplementor sessionFactory) {
return new JdbcValuesMappingProducerStandard( return new JdbcValuesMappingProducerStandard( getSelections( sqlAst ), sqlAst.getDomainResultDescriptors() );
sqlAst.getQuerySpec().getSelectClause().getSqlSelections(), }
sqlAst.getDomainResultDescriptors()
); private static List<SqlSelection> getSelections(SelectStatement selectStatement) {
if ( selectStatement.getQueryPart() instanceof QueryGroup ) {
final QueryGroup queryGroup = (QueryGroup) selectStatement.getQueryPart();
for ( QueryPart queryPart : queryGroup.getQueryParts() ) {
if ( !(queryPart.getFirstQuerySpec().getSelectClause().getSqlSelections()
.get( 0 ).getExpressionType().getSingleJdbcMapping().getJdbcType() instanceof NullJdbcType) ) {
return queryPart.getFirstQuerySpec().getSelectClause().getSqlSelections();
}
}
}
return selectStatement.getQuerySpec().getSelectClause().getSqlSelections();
} }
@Override @Override