HHH-15929 Handle the possibility of different JdbcMappings for the same column
This commit is contained in:
parent
eedd6197ce
commit
2cc1362df7
|
@ -360,7 +360,7 @@ public class OracleLegacySqlAstTranslator<T extends JdbcOperation> extends Abstr
|
|||
}
|
||||
final QuerySpec subquery = new QuerySpec( false, 1 );
|
||||
for ( ColumnReference idColumnReference : idColumnReferences ) {
|
||||
subquery.getSelectClause().addSqlSelection( new SqlSelectionImpl( 0, -1, idColumnReference ) );
|
||||
subquery.getSelectClause().addSqlSelection( new SqlSelectionImpl( idColumnReference ) );
|
||||
}
|
||||
subquery.getFromClause().addRoot( rootTableGroup );
|
||||
subquery.applyPredicate( querySpec.getWhereClauseRestrictions() );
|
||||
|
|
|
@ -305,7 +305,7 @@ public class OracleSqlAstTranslator<T extends JdbcOperation> extends SqlAstTrans
|
|||
}
|
||||
final QuerySpec subquery = new QuerySpec( false, 1 );
|
||||
for ( ColumnReference idColumnReference : idColumnReferences ) {
|
||||
subquery.getSelectClause().addSqlSelection( new SqlSelectionImpl( 0, -1, idColumnReference ) );
|
||||
subquery.getSelectClause().addSqlSelection( new SqlSelectionImpl( idColumnReference ) );
|
||||
}
|
||||
subquery.getFromClause().addRoot( rootTableGroup );
|
||||
subquery.applyPredicate( querySpec.getWhereClauseRestrictions() );
|
||||
|
|
|
@ -147,7 +147,6 @@ public class AggregateWindowEmulationQueryTransformer implements QueryTransforme
|
|||
columnNames.add( columnName );
|
||||
selectClause.addSqlSelection(
|
||||
new ResolvedSqlSelection(
|
||||
i + 1,
|
||||
i,
|
||||
finalExpression,
|
||||
(BasicType<Object>) mapping.getJdbcMapping()
|
||||
|
@ -193,7 +192,6 @@ public class AggregateWindowEmulationQueryTransformer implements QueryTransforme
|
|||
);
|
||||
final int subValuesPosition = subSelectClause.getSqlSelections().size();
|
||||
final SqlSelection subSelection = new ResolvedSqlSelection(
|
||||
subValuesPosition + 1,
|
||||
subValuesPosition,
|
||||
realExpression,
|
||||
(BasicType<Object>) jdbcMapping
|
||||
|
@ -254,7 +252,6 @@ public class AggregateWindowEmulationQueryTransformer implements QueryTransforme
|
|||
);
|
||||
final int subValuesPosition = subSelectClause.getSqlSelections().size();
|
||||
final SqlSelection subSelection = new ResolvedSqlSelection(
|
||||
subValuesPosition + 1,
|
||||
subValuesPosition,
|
||||
realExpression,
|
||||
(BasicType<Object>) jdbcMapping
|
||||
|
@ -312,7 +309,6 @@ public class AggregateWindowEmulationQueryTransformer implements QueryTransforme
|
|||
);
|
||||
final int subValuesPosition = subSelectClause.getSqlSelections().size();
|
||||
final SqlSelection subSelection = new ResolvedSqlSelection(
|
||||
subValuesPosition + 1,
|
||||
subValuesPosition,
|
||||
realExpression,
|
||||
(BasicType<Object>) jdbcMapping
|
||||
|
@ -352,7 +348,6 @@ public class AggregateWindowEmulationQueryTransformer implements QueryTransforme
|
|||
columnNames.add( columnName );
|
||||
subSelectClause.addSqlSelection(
|
||||
new ResolvedSqlSelection(
|
||||
oldValueIndex + 1,
|
||||
oldValueIndex,
|
||||
sortExpression,
|
||||
(BasicType<Object>) mapping.getJdbcMapping()
|
||||
|
|
|
@ -1179,7 +1179,6 @@ public class LoaderSelectBuilder {
|
|||
);
|
||||
subQuery.getSelectClause().addSqlSelection(
|
||||
new SqlSelectionImpl(
|
||||
valuesPosition + 1,
|
||||
valuesPosition,
|
||||
expression
|
||||
)
|
||||
|
|
|
@ -6,7 +6,9 @@
|
|||
*/
|
||||
package org.hibernate.metamodel.mapping;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.IntFunction;
|
||||
|
||||
/**
|
||||
* Consumer used to visit selectable (column/formula) mappings
|
||||
|
@ -157,7 +159,7 @@ public interface SelectableConsumer {
|
|||
* Very limited functionality in terms of the visited SelectableMappings
|
||||
* will not have any defined JdbcMapping, etc
|
||||
*/
|
||||
default void accept(String tableName, String[] columnNames) {
|
||||
default void accept(String tableName, String[] columnNames, IntFunction<JdbcMapping> jdbcMappings) {
|
||||
class SelectableMappingIterator implements SelectableMapping {
|
||||
|
||||
private int index;
|
||||
|
@ -229,7 +231,7 @@ public interface SelectableConsumer {
|
|||
|
||||
@Override
|
||||
public JdbcMapping getJdbcMapping() {
|
||||
return null;
|
||||
return jdbcMappings.apply( index );
|
||||
}
|
||||
}
|
||||
for (
|
||||
|
|
|
@ -69,7 +69,11 @@ public abstract class AbstractDomainPath implements DomainPath {
|
|||
selection.getContainingTableExpression()
|
||||
);
|
||||
return creationState.getSqlExpressionResolver().resolveSqlExpression(
|
||||
createColumnReferenceKey( tableReference, selection.getSelectionExpression() ),
|
||||
createColumnReferenceKey(
|
||||
tableReference,
|
||||
selection.getSelectionExpression(),
|
||||
selection.getJdbcMapping()
|
||||
),
|
||||
processingState -> new ColumnReference(
|
||||
tableReference,
|
||||
selection
|
||||
|
@ -250,7 +254,11 @@ public abstract class AbstractDomainPath implements DomainPath {
|
|||
SqlAstCreationState creationState) {
|
||||
final TableReference tableReference = tableGroup.resolveTableReference( getNavigablePath(), selection.getContainingTableExpression() );
|
||||
final Expression expression = creationState.getSqlExpressionResolver().resolveSqlExpression(
|
||||
createColumnReferenceKey( tableReference, selection.getSelectionExpression() ),
|
||||
createColumnReferenceKey(
|
||||
tableReference,
|
||||
selection.getSelectionExpression(),
|
||||
selection.getJdbcMapping()
|
||||
),
|
||||
processingState -> new ColumnReference(
|
||||
tableReference,
|
||||
selection
|
||||
|
@ -271,7 +279,6 @@ public abstract class AbstractDomainPath implements DomainPath {
|
|||
if ( selectClause.isDistinct() && selectClauseDoesNotContainOrderExpression( expression, selectClause ) ) {
|
||||
final int valuesArrayPosition = selectClause.getSqlSelections().size();
|
||||
SqlSelection sqlSelection = new SqlSelectionImpl(
|
||||
valuesArrayPosition + 1,
|
||||
valuesArrayPosition,
|
||||
expression
|
||||
);
|
||||
|
|
|
@ -108,7 +108,11 @@ public class CaseStatementDiscriminatorMappingImpl extends AbstractDiscriminator
|
|||
SqlAstCreationState creationState) {
|
||||
final SqlExpressionResolver expressionResolver = creationState.getSqlExpressionResolver();
|
||||
return expressionResolver.resolveSqlExpression(
|
||||
createColumnReferenceKey( tableGroup.getPrimaryTableReference(), getSelectionExpression() ),
|
||||
createColumnReferenceKey(
|
||||
tableGroup.getPrimaryTableReference(),
|
||||
getSelectionExpression(),
|
||||
jdbcMappingToUse
|
||||
),
|
||||
sqlAstProcessingState -> createCaseSearchedExpression( tableGroup )
|
||||
);
|
||||
}
|
||||
|
|
|
@ -21,6 +21,9 @@ import org.hibernate.sql.ast.tree.from.TableGroup;
|
|||
import org.hibernate.sql.ast.tree.from.TableReference;
|
||||
import org.hibernate.sql.ast.tree.select.QuerySpec;
|
||||
import org.hibernate.sql.ast.tree.select.SortSpecification;
|
||||
import org.hibernate.type.NullType;
|
||||
|
||||
import static org.hibernate.sql.ast.spi.SqlExpressionResolver.createColumnReferenceKey;
|
||||
|
||||
/**
|
||||
* Represents a column-reference used in an order-by fragment
|
||||
|
@ -53,13 +56,10 @@ public class ColumnReference implements OrderingExpression, SequencePart {
|
|||
TableGroup tableGroup,
|
||||
String modelPartName,
|
||||
SqlAstCreationState creationState) {
|
||||
TableReference tableReference;
|
||||
|
||||
tableReference = getTableReference( tableGroup );
|
||||
|
||||
final TableReference tableReference = getTableReference( tableGroup );
|
||||
final SqlExpressionResolver sqlExpressionResolver = creationState.getSqlExpressionResolver();
|
||||
return sqlExpressionResolver.resolveSqlExpression(
|
||||
SqlExpressionResolver.createColumnReferenceKey( tableReference, columnExpression ),
|
||||
createColumnReferenceKey( tableReference, columnExpression, NullType.INSTANCE ),
|
||||
sqlAstProcessingState -> new org.hibernate.sql.ast.tree.expression.ColumnReference(
|
||||
tableReference,
|
||||
columnExpression,
|
||||
|
|
|
@ -918,7 +918,6 @@ public abstract class AbstractCollectionPersister
|
|||
i,
|
||||
new SqlSelectionImpl(
|
||||
i,
|
||||
i + 1,
|
||||
new AliasedExpression( sqlSelections.get( i ).getExpression(), keyAlias + columnSuffix )
|
||||
)
|
||||
);
|
||||
|
@ -931,7 +930,6 @@ public abstract class AbstractCollectionPersister
|
|||
i,
|
||||
new SqlSelectionImpl(
|
||||
i,
|
||||
i + 1,
|
||||
new AliasedExpression( sqlSelections.get( i ).getExpression(), indexAlias + columnSuffix )
|
||||
)
|
||||
);
|
||||
|
@ -943,7 +941,6 @@ public abstract class AbstractCollectionPersister
|
|||
i,
|
||||
new SqlSelectionImpl(
|
||||
i,
|
||||
i + 1,
|
||||
new AliasedExpression( sqlSelections.get( i ).getExpression(), identifierColumnAlias + columnSuffix )
|
||||
)
|
||||
);
|
||||
|
@ -956,7 +953,6 @@ public abstract class AbstractCollectionPersister
|
|||
i,
|
||||
new SqlSelectionImpl(
|
||||
sqlSelection.getValuesArrayPosition(),
|
||||
sqlSelection.getJdbcResultSetIndex(),
|
||||
new AliasedExpression( sqlSelection.getExpression(), elementColumnAliases[columnIndex] + columnSuffix )
|
||||
)
|
||||
);
|
||||
|
|
|
@ -1353,7 +1353,11 @@ public abstract class AbstractEntityPersister
|
|||
(columnIndex, selection) -> {
|
||||
final String rootPkColumnName = pkColumnNames[ columnIndex ];
|
||||
final Expression pkColumnExpression = creationState.getSqlExpressionResolver().resolveSqlExpression(
|
||||
createColumnReferenceKey( rootTableReference, rootPkColumnName ),
|
||||
createColumnReferenceKey(
|
||||
rootTableReference,
|
||||
rootPkColumnName,
|
||||
selection.getJdbcMapping()
|
||||
),
|
||||
sqlAstProcessingState -> new ColumnReference(
|
||||
rootTableReference.getIdentificationVariable(),
|
||||
rootPkColumnName,
|
||||
|
@ -1365,7 +1369,11 @@ public abstract class AbstractEntityPersister
|
|||
|
||||
final String fkColumnName = fkColumnNames[ columnIndex ];
|
||||
final Expression fkColumnExpression = creationState.getSqlExpressionResolver().resolveSqlExpression(
|
||||
createColumnReferenceKey( joinedTableReference, fkColumnName ),
|
||||
createColumnReferenceKey(
|
||||
joinedTableReference,
|
||||
fkColumnName,
|
||||
selection.getJdbcMapping()
|
||||
),
|
||||
sqlAstProcessingState -> new ColumnReference(
|
||||
joinedTableReference.getIdentificationVariable(),
|
||||
fkColumnName,
|
||||
|
@ -1743,7 +1751,6 @@ public abstract class AbstractEntityPersister
|
|||
i,
|
||||
new SqlSelectionImpl(
|
||||
i,
|
||||
i + 1,
|
||||
new AliasedExpression( sqlSelections.get( i ).getExpression(), identifierAlias + suffix )
|
||||
)
|
||||
);
|
||||
|
@ -1755,7 +1762,6 @@ public abstract class AbstractEntityPersister
|
|||
i,
|
||||
new SqlSelectionImpl(
|
||||
i,
|
||||
i + 1,
|
||||
new AliasedExpression( sqlSelections.get( i ).getExpression(), getDiscriminatorAlias() + suffix )
|
||||
)
|
||||
);
|
||||
|
@ -1767,7 +1773,6 @@ public abstract class AbstractEntityPersister
|
|||
i,
|
||||
new SqlSelectionImpl(
|
||||
i,
|
||||
i + 1,
|
||||
new AliasedExpression( sqlSelections.get( i ).getExpression(), ROWID_ALIAS + suffix )
|
||||
)
|
||||
);
|
||||
|
@ -1788,7 +1793,6 @@ public abstract class AbstractEntityPersister
|
|||
i,
|
||||
new SqlSelectionImpl(
|
||||
sqlSelection.getValuesArrayPosition(),
|
||||
sqlSelection.getJdbcResultSetIndex(),
|
||||
new AliasedExpression( sqlSelection.getExpression(), selectAlias )
|
||||
)
|
||||
);
|
||||
|
@ -2995,14 +2999,16 @@ public abstract class AbstractEntityPersister
|
|||
discriminatorExpression = getDiscriminatorFormulaTemplate();
|
||||
columnReferenceKey = createColumnReferenceKey(
|
||||
tableGroup.getPrimaryTableReference(),
|
||||
getDiscriminatorFormulaTemplate()
|
||||
getDiscriminatorFormulaTemplate(),
|
||||
getDiscriminatorType()
|
||||
);
|
||||
}
|
||||
else {
|
||||
discriminatorExpression = getDiscriminatorColumnName();
|
||||
columnReferenceKey = createColumnReferenceKey(
|
||||
tableGroup.getPrimaryTableReference(),
|
||||
getDiscriminatorColumnName()
|
||||
getDiscriminatorColumnName(),
|
||||
getDiscriminatorType()
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -1417,7 +1417,11 @@ public class JoinedSubclassEntityPersister extends AbstractEntityPersister {
|
|||
final int tablePosition = i;
|
||||
consumer.consume(
|
||||
tableName,
|
||||
() -> columnConsumer -> columnConsumer.accept( tableName, constraintOrderedKeyColumnNames[tablePosition] )
|
||||
() -> columnConsumer -> columnConsumer.accept(
|
||||
tableName,
|
||||
constraintOrderedKeyColumnNames[tablePosition],
|
||||
getIdentifierMapping()::getJdbcMapping
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -759,7 +759,8 @@ public class SingleTableEntityPersister extends AbstractEntityPersister {
|
|||
tableName,
|
||||
() -> columnConsumer -> columnConsumer.accept(
|
||||
tableName,
|
||||
constraintOrderedKeyColumnNames[tablePosition]
|
||||
constraintOrderedKeyColumnNames[tablePosition],
|
||||
getIdentifierMapping()::getJdbcMapping
|
||||
)
|
||||
);
|
||||
}
|
||||
|
|
|
@ -436,7 +436,11 @@ public class UnionSubclassEntityPersister extends AbstractEntityPersister {
|
|||
final int tablePosition = i;
|
||||
consumer.consume(
|
||||
tableName,
|
||||
() -> columnConsumer -> columnConsumer.accept( tableName, constraintOrderedKeyColumnNames[tablePosition] )
|
||||
() -> columnConsumer -> columnConsumer.accept(
|
||||
tableName,
|
||||
constraintOrderedKeyColumnNames[tablePosition],
|
||||
getIdentifierMapping()::getJdbcMapping
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -351,7 +351,8 @@ public class AnonymousTupleEntityValuedModelPart
|
|||
(ColumnReference) sqlExpressionResolver.resolveSqlExpression(
|
||||
SqlExpressionResolver.createColumnReferenceKey(
|
||||
tableReference,
|
||||
keyMappings.get( i ).getSelectionExpression()
|
||||
keyMappings.get( i ).getSelectionExpression(),
|
||||
keyMappings.get( i ).getJdbcMapping()
|
||||
),
|
||||
state -> new ColumnReference(
|
||||
tableReference,
|
||||
|
@ -371,7 +372,8 @@ public class AnonymousTupleEntityValuedModelPart
|
|||
sqlExpressionResolver.resolveSqlExpression(
|
||||
SqlExpressionResolver.createColumnReferenceKey(
|
||||
tableReference,
|
||||
targetMappings.get( i ).getSelectionExpression()
|
||||
targetMappings.get( i ).getSelectionExpression(),
|
||||
targetMappings.get( i ).getJdbcMapping()
|
||||
),
|
||||
state -> new ColumnReference(
|
||||
tableReference,
|
||||
|
|
|
@ -66,11 +66,6 @@ public class ResultSetMappingSqlSelection implements SqlSelection, Expression, S
|
|||
return valuesArrayPosition;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getJdbcResultSetIndex() {
|
||||
return valuesArrayPosition + 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Expression getExpression() {
|
||||
return this;
|
||||
|
@ -81,6 +76,11 @@ public class ResultSetMappingSqlSelection implements SqlSelection, Expression, S
|
|||
return valueMapping;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isVirtual() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(SqlAstWalker sqlAstWalker) {
|
||||
throw new UnsupportedOperationException();
|
||||
|
|
|
@ -91,7 +91,22 @@ public class SelfRenderingFunctionSqlAstExpression
|
|||
return new SqlSelectionImpl(
|
||||
jdbcPosition,
|
||||
valuesArrayPosition,
|
||||
this
|
||||
this,
|
||||
false
|
||||
);
|
||||
}
|
||||
@Override
|
||||
public SqlSelection createSqlSelection(
|
||||
int jdbcPosition,
|
||||
int valuesArrayPosition,
|
||||
JavaType javaType,
|
||||
boolean virtual,
|
||||
TypeConfiguration typeConfiguration) {
|
||||
return new SqlSelectionImpl(
|
||||
jdbcPosition,
|
||||
valuesArrayPosition,
|
||||
this,
|
||||
virtual
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -165,7 +165,7 @@ public class SimpleDeleteQueryPlan implements NonSelectQueryPlan {
|
|||
sqmInterpretation.getSqlExpressionResolver(),
|
||||
factory
|
||||
);
|
||||
matchingIdSubQuery.getSelectClause().addSqlSelection( new SqlSelectionImpl( 1, 0, fkTargetColumnExpression ) );
|
||||
matchingIdSubQuery.getSelectClause().addSqlSelection( new SqlSelectionImpl( 0, fkTargetColumnExpression ) );
|
||||
|
||||
matchingIdSubQuery.getFromClause().addRoot(
|
||||
tableGroup
|
||||
|
|
|
@ -169,7 +169,6 @@ public class MatchingIdSelectionHelper {
|
|||
idSelectionQuery.getSelectClause().addSqlSelection(
|
||||
new SqlSelectionImpl(
|
||||
position,
|
||||
position + 1,
|
||||
expression
|
||||
)
|
||||
);
|
||||
|
|
|
@ -174,7 +174,7 @@ public abstract class AbstractCteMutationHandler extends AbstractMutationHandler
|
|||
( (SqlExpressible) count).getJdbcMapping()
|
||||
)
|
||||
);
|
||||
querySpec.getSelectClause().addSqlSelection( new SqlSelectionImpl( 1, 0, count ) );
|
||||
querySpec.getSelectClause().addSqlSelection( new SqlSelectionImpl( 0, count ) );
|
||||
querySpec.getFromClause().addRoot(
|
||||
new CteTableGroup(
|
||||
new NamedTableReference(
|
||||
|
@ -280,7 +280,6 @@ public abstract class AbstractCteMutationHandler extends AbstractMutationHandler
|
|||
final CteColumn cteColumn = cteColumns.get( i );
|
||||
subQuerySelectClause.addSqlSelection(
|
||||
new SqlSelectionImpl(
|
||||
i + 1,
|
||||
i,
|
||||
new ColumnReference(
|
||||
idSelectTableReference,
|
||||
|
@ -295,7 +294,6 @@ public abstract class AbstractCteMutationHandler extends AbstractMutationHandler
|
|||
fkModelPart.forEachSelectable(
|
||||
(selectionIndex, selectableMapping) -> subQuerySelectClause.addSqlSelection(
|
||||
new SqlSelectionImpl(
|
||||
selectionIndex + 1,
|
||||
selectionIndex,
|
||||
new ColumnReference(
|
||||
idSelectTableReference,
|
||||
|
|
|
@ -282,7 +282,6 @@ public class CteInsertHandler implements InsertHandler {
|
|||
if ( !assignsId && entityDescriptor.getGenerator().generatedOnExecution() ) {
|
||||
querySpec.getSelectClause().addSqlSelection(
|
||||
new SqlSelectionImpl(
|
||||
1,
|
||||
0,
|
||||
SqmInsertStrategyHelper.createRowNumberingExpression(
|
||||
querySpec,
|
||||
|
@ -312,7 +311,6 @@ public class CteInsertHandler implements InsertHandler {
|
|||
columnNames.add( columnReference.getColumnExpression() );
|
||||
querySpec.getSelectClause().addSqlSelection(
|
||||
new SqlSelectionImpl(
|
||||
1,
|
||||
0,
|
||||
columnReference.getQualifier().equals( valuesAlias )
|
||||
? columnReference
|
||||
|
@ -420,7 +418,6 @@ public class CteInsertHandler implements InsertHandler {
|
|||
);
|
||||
rowsWithSequenceQuery.getSelectClause().addSqlSelection(
|
||||
new SqlSelectionImpl(
|
||||
1,
|
||||
0,
|
||||
rowNumberColumnReference
|
||||
)
|
||||
|
@ -431,7 +428,6 @@ public class CteInsertHandler implements InsertHandler {
|
|||
);
|
||||
rowsWithSequenceQuery.getSelectClause().addSqlSelection(
|
||||
new SqlSelectionImpl(
|
||||
2,
|
||||
1,
|
||||
new SelfRenderingSqlFragmentExpression( fragment )
|
||||
)
|
||||
|
@ -502,7 +498,6 @@ public class CteInsertHandler implements InsertHandler {
|
|||
entityQuery.getFromClause().addRoot( baseTableGroup );
|
||||
entityQuery.getSelectClause().addSqlSelection(
|
||||
new SqlSelectionImpl(
|
||||
1,
|
||||
0,
|
||||
new BinaryArithmeticExpression(
|
||||
new ColumnReference(
|
||||
|
@ -546,7 +541,6 @@ public class CteInsertHandler implements InsertHandler {
|
|||
final CteColumn cteColumn = cteColumns.get( i );
|
||||
entityQuery.getSelectClause().addSqlSelection(
|
||||
new SqlSelectionImpl(
|
||||
i + 1,
|
||||
i,
|
||||
new ColumnReference(
|
||||
"e",
|
||||
|
@ -622,7 +616,7 @@ public class CteInsertHandler implements InsertHandler {
|
|||
( (SqlExpressible) count).getJdbcMapping()
|
||||
)
|
||||
);
|
||||
querySpec.getSelectClause().addSqlSelection( new SqlSelectionImpl( 1, 0, count ) );
|
||||
querySpec.getSelectClause().addSqlSelection( new SqlSelectionImpl( 0, count ) );
|
||||
querySpec.getFromClause().addRoot(
|
||||
new CteTableGroup(
|
||||
new NamedTableReference(
|
||||
|
@ -877,7 +871,6 @@ public class CteInsertHandler implements InsertHandler {
|
|||
final CteColumn idCteColumn = cteColumns.get( 0 );
|
||||
querySpec.getSelectClause().addSqlSelection(
|
||||
new SqlSelectionImpl(
|
||||
1,
|
||||
0,
|
||||
new ColumnReference(
|
||||
"t",
|
||||
|
@ -893,7 +886,6 @@ public class CteInsertHandler implements InsertHandler {
|
|||
final CteColumn cteColumn = cteColumns.get( j );
|
||||
querySpec.getSelectClause().addSqlSelection(
|
||||
new SqlSelectionImpl(
|
||||
1,
|
||||
0,
|
||||
new ColumnReference(
|
||||
"e",
|
||||
|
@ -933,14 +925,12 @@ public class CteInsertHandler implements InsertHandler {
|
|||
);
|
||||
finalResultQuery.getSelectClause().addSqlSelection(
|
||||
new SqlSelectionImpl(
|
||||
1,
|
||||
0,
|
||||
idColumnReference
|
||||
)
|
||||
);
|
||||
finalResultQuery.getSelectClause().addSqlSelection(
|
||||
new SqlSelectionImpl(
|
||||
1,
|
||||
0,
|
||||
SqmInsertStrategyHelper.createRowNumberingExpression(
|
||||
querySpec,
|
||||
|
@ -987,7 +977,6 @@ public class CteInsertHandler implements InsertHandler {
|
|||
);
|
||||
insertSelectSpec.getSelectClause().addSqlSelection(
|
||||
new SqlSelectionImpl(
|
||||
1,
|
||||
0,
|
||||
new ColumnReference(
|
||||
"e",
|
||||
|
@ -1021,7 +1010,6 @@ public class CteInsertHandler implements InsertHandler {
|
|||
final ColumnReference columnReference = assignmentReferences.get( j );
|
||||
insertSelectSpec.getSelectClause().addSqlSelection(
|
||||
new SqlSelectionImpl(
|
||||
1,
|
||||
0,
|
||||
new ColumnReference(
|
||||
"e",
|
||||
|
|
|
@ -203,8 +203,6 @@ public class CteUpdateHandler extends AbstractCteMutationHandler implements Upda
|
|||
final QuerySpec existsQuerySpec = new QuerySpec( false );
|
||||
existsQuerySpec.getSelectClause().addSqlSelection(
|
||||
new SqlSelectionImpl(
|
||||
-1,
|
||||
0,
|
||||
new QueryLiteral<>(
|
||||
1,
|
||||
factory.getTypeConfiguration().getBasicTypeForJavaType( Integer.class )
|
||||
|
@ -243,8 +241,6 @@ public class CteUpdateHandler extends AbstractCteMutationHandler implements Upda
|
|||
targetColumnReferences.addAll( assignment.getAssignable().getColumnReferences() );
|
||||
querySpec.getSelectClause().addSqlSelection(
|
||||
new SqlSelectionImpl(
|
||||
0,
|
||||
-1,
|
||||
assignment.getAssignedValue()
|
||||
)
|
||||
);
|
||||
|
|
|
@ -450,7 +450,7 @@ public class InlineUpdateHandler implements UpdateHandler {
|
|||
)
|
||||
);
|
||||
querySpec.getSelectClause().addSqlSelection(
|
||||
new SqlSelectionImpl( 1, 0, valuesColumnReference )
|
||||
new SqlSelectionImpl( 0, valuesColumnReference )
|
||||
);
|
||||
}
|
||||
);
|
||||
|
@ -482,7 +482,7 @@ public class InlineUpdateHandler implements UpdateHandler {
|
|||
)
|
||||
);
|
||||
querySpec.getSelectClause().addSqlSelection(
|
||||
new SqlSelectionImpl( 1, 0, valuesColumnReference )
|
||||
new SqlSelectionImpl( 0, valuesColumnReference )
|
||||
);
|
||||
}
|
||||
final ValuesTableGroup valuesTableGroup = new ValuesTableGroup(
|
||||
|
@ -528,8 +528,6 @@ public class InlineUpdateHandler implements UpdateHandler {
|
|||
targetColumnReferences.addAll( assignment.getAssignable().getColumnReferences() );
|
||||
querySpec.getSelectClause().addSqlSelection(
|
||||
new SqlSelectionImpl(
|
||||
0,
|
||||
-1,
|
||||
assignment.getAssignedValue()
|
||||
)
|
||||
);
|
||||
|
|
|
@ -91,15 +91,14 @@ public final class ExecuteWithTemporaryTableHelper {
|
|||
matchingIdSelection.getFromClause().addRoot( mutatingTableGroup );
|
||||
|
||||
mutatingEntityDescriptor.getIdentifierMapping().forEachSelectable(
|
||||
(jdbcPosition, selection) -> {
|
||||
(selectionIndex, selection) -> {
|
||||
final TableReference tableReference = mutatingTableGroup.resolveTableReference(
|
||||
mutatingTableGroup.getNavigablePath(),
|
||||
selection.getContainingTableExpression()
|
||||
);
|
||||
matchingIdSelection.getSelectClause().addSqlSelection(
|
||||
new SqlSelectionImpl(
|
||||
jdbcPosition,
|
||||
jdbcPosition + 1,
|
||||
selectionIndex,
|
||||
sqmConverter.getSqlExpressionResolver().resolveSqlExpression(
|
||||
tableReference,
|
||||
selection
|
||||
|
@ -114,7 +113,6 @@ public final class ExecuteWithTemporaryTableHelper {
|
|||
matchingIdSelection.getSelectClause().addSqlSelection(
|
||||
new SqlSelectionImpl(
|
||||
jdbcPosition,
|
||||
jdbcPosition + 1,
|
||||
new QueryLiteral<>(
|
||||
UUID.fromString( sessionUidAccess.apply( executionContext.getSession() ) ),
|
||||
(BasicValuedMapping) idTable.getSessionUidColumn().getJdbcMapping()
|
||||
|
@ -222,7 +220,6 @@ public final class ExecuteWithTemporaryTableHelper {
|
|||
if ( temporaryTableColumn != idTable.getSessionUidColumn() ) {
|
||||
querySpec.getSelectClause().addSqlSelection(
|
||||
new SqlSelectionImpl(
|
||||
i + 1,
|
||||
i,
|
||||
new ColumnReference(
|
||||
tableReference,
|
||||
|
@ -241,7 +238,6 @@ public final class ExecuteWithTemporaryTableHelper {
|
|||
(i, selectableMapping) -> {
|
||||
querySpec.getSelectClause().addSqlSelection(
|
||||
new SqlSelectionImpl(
|
||||
i + 1,
|
||||
i,
|
||||
new ColumnReference(
|
||||
tableReference,
|
||||
|
|
|
@ -58,7 +58,6 @@ public final class ExecuteWithoutIdTableHelper {
|
|||
final SqlSelection sqlSelection = new SqlSelectionImpl(
|
||||
// irrelevant
|
||||
0,
|
||||
0,
|
||||
columnReference
|
||||
);
|
||||
matchingIdSelect.getSelectClause().addSqlSelection( sqlSelection );
|
||||
|
|
|
@ -339,7 +339,6 @@ public class InsertExecutionDelegate implements TableBasedInsertHandler.Executio
|
|||
for ( ColumnReference columnReference : assignable.getColumnReferences() ) {
|
||||
querySpec.getSelectClause().addSqlSelection(
|
||||
new SqlSelectionImpl(
|
||||
1,
|
||||
0,
|
||||
new ColumnReference(
|
||||
updatingTableReference.getIdentificationVariable(),
|
||||
|
@ -369,7 +368,7 @@ public class InsertExecutionDelegate implements TableBasedInsertHandler.Executio
|
|||
identifierMapping.getJdbcMapping()
|
||||
);
|
||||
idSelectQuerySpec.getSelectClause()
|
||||
.addSqlSelection( new SqlSelectionImpl( 1, 0, columnReference ) );
|
||||
.addSqlSelection( new SqlSelectionImpl( 0, columnReference ) );
|
||||
idSelectQuerySpec.addSortSpecification(
|
||||
new SortSpecification(
|
||||
columnReference,
|
||||
|
@ -528,7 +527,6 @@ public class InsertExecutionDelegate implements TableBasedInsertHandler.Executio
|
|||
);
|
||||
querySpec.getSelectClause().addSqlSelection(
|
||||
new SqlSelectionImpl(
|
||||
1,
|
||||
0,
|
||||
new ColumnReference(
|
||||
updatingTableReference.getIdentificationVariable(),
|
||||
|
@ -689,7 +687,6 @@ public class InsertExecutionDelegate implements TableBasedInsertHandler.Executio
|
|||
for ( ColumnReference columnReference : assignment.getAssignable().getColumnReferences() ) {
|
||||
querySpec.getSelectClause().addSqlSelection(
|
||||
new SqlSelectionImpl(
|
||||
1,
|
||||
0,
|
||||
new ColumnReference(
|
||||
updatingTableReference.getIdentificationVariable(),
|
||||
|
@ -734,7 +731,6 @@ public class InsertExecutionDelegate implements TableBasedInsertHandler.Executio
|
|||
);
|
||||
querySpec.getSelectClause().addSqlSelection(
|
||||
new SqlSelectionImpl(
|
||||
1,
|
||||
0,
|
||||
new ColumnReference(
|
||||
updatingTableReference.getIdentificationVariable(),
|
||||
|
|
|
@ -219,7 +219,6 @@ public class TableBasedInsertHandler implements InsertHandler {
|
|||
targetPathColumns.add( new Assignment( columnReference, columnReference ) );
|
||||
querySpec.getSelectClause().addSqlSelection(
|
||||
new SqlSelectionImpl(
|
||||
1,
|
||||
0,
|
||||
SqmInsertStrategyHelper.createRowNumberingExpression(
|
||||
querySpec,
|
||||
|
@ -237,13 +236,12 @@ public class TableBasedInsertHandler implements InsertHandler {
|
|||
null,
|
||||
sessionUidColumn.getJdbcMapping()
|
||||
);
|
||||
insertStatement.getTargetColumns().add( sessionUidColumnReference );
|
||||
targetPathColumns.add( new Assignment( sessionUidColumnReference, sessionUidParameter ) );
|
||||
querySpec.getSelectClause().addSqlSelection( new SqlSelectionImpl(
|
||||
insertStatement.getTargetColumns().size(),
|
||||
insertStatement.getTargetColumns().size() - 1,
|
||||
sessionUidParameter
|
||||
) );
|
||||
insertStatement.getTargetColumns().add( sessionUidColumnReference );
|
||||
targetPathColumns.add( new Assignment( sessionUidColumnReference, sessionUidParameter ) );
|
||||
}
|
||||
}
|
||||
);
|
||||
|
|
|
@ -345,7 +345,7 @@ public class UpdateExecutionDelegate implements TableBasedUpdateHandler.Executio
|
|||
for ( Assignment assignment : assignments ) {
|
||||
targetColumnReferences.addAll( assignment.getAssignable().getColumnReferences() );
|
||||
insertSourceSelectQuerySpec.getSelectClause().addSqlSelection(
|
||||
new SqlSelectionImpl( 0, -1, assignment.getAssignedValue() )
|
||||
new SqlSelectionImpl( assignment.getAssignedValue() )
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -380,8 +380,6 @@ public class UpdateExecutionDelegate implements TableBasedUpdateHandler.Executio
|
|||
final QuerySpec existsSubQuerySpec = new QuerySpec( false );
|
||||
existsSubQuerySpec.getSelectClause().addSqlSelection(
|
||||
new SqlSelectionImpl(
|
||||
-1,
|
||||
0,
|
||||
new QueryLiteral<>(
|
||||
1,
|
||||
sessionFactory.getTypeConfiguration().getBasicTypeForJavaType( Integer.class )
|
||||
|
|
|
@ -1478,14 +1478,14 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
|
|||
if ( versionExpression != null ) {
|
||||
if ( versionSelection == null ) {
|
||||
// The position is irrelevant as this is only needed for insert
|
||||
versionSelection = new SqlSelectionImpl( 1, 0, versionExpression );
|
||||
versionSelection = new SqlSelectionImpl( 0, versionExpression );
|
||||
}
|
||||
selectClause.addSqlSelection( versionSelection );
|
||||
}
|
||||
if ( discriminatorExpression != null ) {
|
||||
if ( discriminatorSelection == null ) {
|
||||
// The position is irrelevant as this is only needed for insert
|
||||
discriminatorSelection = new SqlSelectionImpl( 1, 0, discriminatorExpression );
|
||||
discriminatorSelection = new SqlSelectionImpl( 0, discriminatorExpression );
|
||||
}
|
||||
selectClause.addSqlSelection( discriminatorSelection );
|
||||
}
|
||||
|
@ -1505,7 +1505,6 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
|
|||
return false;
|
||||
}
|
||||
identifierSelection = new SqlSelectionImpl(
|
||||
1,
|
||||
0,
|
||||
SqmInsertStrategyHelper.createRowNumberingExpression( querySpec, sessionFactory )
|
||||
);
|
||||
|
@ -1519,7 +1518,6 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
|
|||
);
|
||||
// The position is irrelevant as this is only needed for insert
|
||||
identifierSelection = new SqlSelectionImpl(
|
||||
1,
|
||||
0,
|
||||
new SelfRenderingSqlFragmentExpression( fragment )
|
||||
);
|
||||
|
@ -2369,7 +2367,8 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
|
|||
new QueryLiteral<>(
|
||||
selection.getValuesArrayPosition(),
|
||||
basicType( Integer.class )
|
||||
)
|
||||
),
|
||||
false
|
||||
)
|
||||
)
|
||||
);
|
||||
|
@ -4469,7 +4468,7 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
|
|||
integerType,
|
||||
integerType
|
||||
);
|
||||
subQuerySpec.getSelectClause().addSqlSelection( new SqlSelectionImpl( 1, 0, expression ) );
|
||||
subQuerySpec.getSelectClause().addSqlSelection( new SqlSelectionImpl( 0, expression ) );
|
||||
|
||||
subQuerySpec.applyPredicate(
|
||||
pluralAttributeMapping.getKeyDescriptor().generateJoinPredicate(
|
||||
|
@ -4653,7 +4652,7 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
|
|||
).getJdbcMapping(),
|
||||
modelPart
|
||||
);
|
||||
subQuerySpec.getSelectClause().addSqlSelection( new SqlSelectionImpl( 1, 0, expression ) );
|
||||
subQuerySpec.getSelectClause().addSqlSelection( new SqlSelectionImpl( 0, expression ) );
|
||||
|
||||
NavigablePath parent = pluralPartPath.getPluralDomainPath().getNavigablePath().getParent();
|
||||
subQuerySpec.applyPredicate(
|
||||
|
@ -4787,7 +4786,6 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
|
|||
for ( int i = 0; i < subQueryColumns.size(); i++ ) {
|
||||
subQuerySpec.getSelectClause().addSqlSelection(
|
||||
new SqlSelectionImpl(
|
||||
i + 1,
|
||||
i,
|
||||
subQueryColumns.get( i )
|
||||
)
|
||||
|
@ -4829,7 +4827,6 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
|
|||
|
||||
subQuerySpec.getSelectClause().addSqlSelection(
|
||||
new SqlSelectionImpl(
|
||||
1,
|
||||
0,
|
||||
expression
|
||||
)
|
||||
|
@ -7444,7 +7441,7 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
|
|||
|
||||
final JdbcLiteral<Integer> jdbcLiteral = new JdbcLiteral<>( 1, basicType( Integer.class ) );
|
||||
subQuerySpec.getSelectClause().addSqlSelection(
|
||||
new SqlSelectionImpl( 1, 0, jdbcLiteral )
|
||||
new SqlSelectionImpl( 0, jdbcLiteral )
|
||||
);
|
||||
|
||||
return new ExistsPredicate( subQuerySpec, !predicate.isNegated(), getBooleanType() );
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
*/
|
||||
package org.hibernate.query.sqm.sql.internal;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
|
@ -109,6 +110,7 @@ public class SqlAstQueryPartProcessingStateImpl
|
|||
// SqlExpressionResolver
|
||||
|
||||
private Map<?, ?> sqlSelectionMap;
|
||||
private int nextJdbcPosition = 1;
|
||||
|
||||
@Override
|
||||
public SqlSelection resolveSqlSelection(
|
||||
|
@ -128,29 +130,21 @@ public class SqlAstQueryPartProcessingStateImpl
|
|||
-1,
|
||||
nestingFetchParent.getReferencedMappingType().getSelectableIndex( selectableName ),
|
||||
javaType,
|
||||
true,
|
||||
typeConfiguration
|
||||
);
|
||||
}
|
||||
final Map<Expression, SqlSelection> selectionMap;
|
||||
final Map<Expression, Object> selectionMap;
|
||||
if ( deduplicateSelectionItems ) {
|
||||
final SqlSelection existing;
|
||||
if ( sqlSelectionMap == null ) {
|
||||
sqlSelectionMap = new HashMap<>();
|
||||
existing = null;
|
||||
}
|
||||
else {
|
||||
existing = (SqlSelection) sqlSelectionMap.get( expression );
|
||||
}
|
||||
|
||||
if ( existing != null ) {
|
||||
return existing;
|
||||
}
|
||||
//noinspection unchecked
|
||||
selectionMap = (Map<Expression, SqlSelection>) sqlSelectionMap;
|
||||
selectionMap = (Map<Expression, Object>) sqlSelectionMap;
|
||||
}
|
||||
else if ( fetchParent != null ) {
|
||||
// De-duplicate selection items within the root of a fetch parent
|
||||
final Map<FetchParent, Map<Expression, SqlSelection>> fetchParentSqlSelectionMap;
|
||||
final Map<FetchParent, Map<Expression, Object>> fetchParentSqlSelectionMap;
|
||||
final FetchParent root = fetchParent.getRoot();
|
||||
if ( sqlSelectionMap == null ) {
|
||||
sqlSelectionMap = fetchParentSqlSelectionMap = new HashMap<>();
|
||||
|
@ -158,8 +152,8 @@ public class SqlAstQueryPartProcessingStateImpl
|
|||
}
|
||||
else {
|
||||
//noinspection unchecked
|
||||
fetchParentSqlSelectionMap = (Map<FetchParent, Map<Expression, SqlSelection>>) sqlSelectionMap;
|
||||
final Map<Expression, SqlSelection> map = fetchParentSqlSelectionMap.get( root );
|
||||
fetchParentSqlSelectionMap = (Map<FetchParent, Map<Expression, Object>>) sqlSelectionMap;
|
||||
final Map<Expression, Object> map = fetchParentSqlSelectionMap.get( root );
|
||||
if ( map == null ) {
|
||||
fetchParentSqlSelectionMap.put( root, selectionMap = new HashMap<>() );
|
||||
}
|
||||
|
@ -167,31 +161,60 @@ public class SqlAstQueryPartProcessingStateImpl
|
|||
selectionMap = map;
|
||||
}
|
||||
}
|
||||
final SqlSelection sqlSelection = selectionMap.get( expression );
|
||||
if ( sqlSelection != null ) {
|
||||
return sqlSelection;
|
||||
}
|
||||
}
|
||||
else {
|
||||
selectionMap = null;
|
||||
}
|
||||
|
||||
final int jdbcPosition;
|
||||
final Object existingSelection;
|
||||
if ( selectionMap != null ) {
|
||||
existingSelection = selectionMap.get( expression );
|
||||
if ( existingSelection != null ) {
|
||||
if ( existingSelection instanceof SqlSelection ) {
|
||||
final SqlSelection sqlSelection = (SqlSelection) existingSelection;
|
||||
if ( sqlSelection.getExpressionType() == expression.getExpressionType() ) {
|
||||
return sqlSelection;
|
||||
}
|
||||
jdbcPosition = sqlSelection.getJdbcResultSetIndex();
|
||||
}
|
||||
else {
|
||||
final SqlSelection[] selections = (SqlSelection[]) existingSelection;
|
||||
for ( SqlSelection sqlSelection : selections ) {
|
||||
if ( sqlSelection.getExpressionType() == expression.getExpressionType() ) {
|
||||
return sqlSelection;
|
||||
}
|
||||
}
|
||||
jdbcPosition = selections[0].getJdbcResultSetIndex();
|
||||
}
|
||||
}
|
||||
else {
|
||||
jdbcPosition = nextJdbcPosition++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
jdbcPosition = nextJdbcPosition++;
|
||||
existingSelection = null;
|
||||
}
|
||||
final boolean virtual = existingSelection != null;
|
||||
final SelectClause selectClause = ( (QuerySpec) queryPart ).getSelectClause();
|
||||
final int valuesArrayPosition = selectClause.getSqlSelections().size();
|
||||
final SqlSelection sqlSelection;
|
||||
if ( isTopLevel() ) {
|
||||
sqlSelection = expression.createDomainResultSqlSelection(
|
||||
valuesArrayPosition + 1,
|
||||
jdbcPosition,
|
||||
valuesArrayPosition,
|
||||
javaType,
|
||||
virtual,
|
||||
typeConfiguration
|
||||
);
|
||||
}
|
||||
else {
|
||||
sqlSelection = expression.createSqlSelection(
|
||||
valuesArrayPosition + 1,
|
||||
jdbcPosition,
|
||||
valuesArrayPosition,
|
||||
javaType,
|
||||
virtual,
|
||||
typeConfiguration
|
||||
);
|
||||
}
|
||||
|
@ -199,7 +222,23 @@ public class SqlAstQueryPartProcessingStateImpl
|
|||
selectClause.addSqlSelection( sqlSelection );
|
||||
|
||||
if ( selectionMap != null ) {
|
||||
selectionMap.put( expression, sqlSelection );
|
||||
if ( virtual ) {
|
||||
final SqlSelection[] selections;
|
||||
if ( existingSelection instanceof SqlSelection ) {
|
||||
selections = new SqlSelection[2];
|
||||
selections[0] = (SqlSelection) existingSelection;
|
||||
}
|
||||
else {
|
||||
final SqlSelection[] existingSelections = (SqlSelection[]) existingSelection;
|
||||
selections = new SqlSelection[existingSelections.length + 1];
|
||||
System.arraycopy( existingSelections, 0, selections, 0, existingSelections.length );
|
||||
}
|
||||
selections[selections.length - 1] = sqlSelection;
|
||||
selectionMap.put( expression, selections );
|
||||
}
|
||||
else {
|
||||
selectionMap.put( expression, sqlSelection );
|
||||
}
|
||||
}
|
||||
|
||||
return sqlSelection;
|
||||
|
|
|
@ -2917,7 +2917,6 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
|
|||
for ( int i = 0; i < sqlSelectionsSize; i++ ) {
|
||||
syntheticSelectClause.addSqlSelection(
|
||||
new SqlSelectionImpl(
|
||||
i + 1,
|
||||
i,
|
||||
new ColumnReference(
|
||||
queryGroupAlias,
|
||||
|
@ -4591,6 +4590,9 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
|
|||
int offset = 0;
|
||||
for ( int i = 0; i < size; i++ ) {
|
||||
final SqlSelection sqlSelection = sqlSelections.get( i );
|
||||
if ( sqlSelection.isVirtual() ) {
|
||||
continue;
|
||||
}
|
||||
if ( selectItemsToInline != null && selectItemsToInline.get( i ) ) {
|
||||
parameterRenderingMode = SqlAstNodeRenderingMode.INLINE_ALL_PARAMETERS;
|
||||
}
|
||||
|
@ -4641,6 +4643,9 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
|
|||
String separator = NO_SEPARATOR;
|
||||
for ( int i = 0; i < size; i++ ) {
|
||||
final SqlSelection sqlSelection = sqlSelections.get( i );
|
||||
if ( sqlSelection.isVirtual() ) {
|
||||
continue;
|
||||
}
|
||||
appendSql( separator );
|
||||
if ( selectItemsToInline != null && selectItemsToInline.get( i ) ) {
|
||||
parameterRenderingMode = SqlAstNodeRenderingMode.INLINE_ALL_PARAMETERS;
|
||||
|
@ -5332,7 +5337,6 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
|
|||
columnNames.add( "sort_col_" + i );
|
||||
sqlSelections.add(
|
||||
new SqlSelectionImpl(
|
||||
sqlSelections.size() + 1,
|
||||
sqlSelections.size(),
|
||||
sortSpecification.getSortExpression()
|
||||
)
|
||||
|
@ -5646,7 +5650,6 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
|
|||
for ( ColumnReference columnReference : columnReferences ) {
|
||||
lhsReferencesQuery.getSelectClause().addSqlSelection(
|
||||
new SqlSelectionImpl(
|
||||
1,
|
||||
0,
|
||||
columnReference
|
||||
)
|
||||
|
@ -5696,7 +5699,6 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
|
|||
final QuerySpec existsQuery = new QuerySpec( false, 1 );
|
||||
existsQuery.getSelectClause().addSqlSelection(
|
||||
new SqlSelectionImpl(
|
||||
1,
|
||||
0,
|
||||
new QueryLiteral<>( 1, getIntegerType() )
|
||||
)
|
||||
|
@ -5749,7 +5751,6 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
|
|||
existsQuery.setHavingClauseRestrictions( querySpec.getHavingClauseRestrictions() );
|
||||
existsQuery.getSelectClause().addSqlSelection(
|
||||
new SqlSelectionImpl(
|
||||
1,
|
||||
0,
|
||||
new QueryLiteral<>( 1, getIntegerType() )
|
||||
)
|
||||
|
@ -5786,7 +5787,6 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
|
|||
countQuery.setHavingClauseRestrictions( querySpec.getHavingClauseRestrictions() );
|
||||
countQuery.getSelectClause().addSqlSelection(
|
||||
new SqlSelectionImpl(
|
||||
1,
|
||||
0,
|
||||
new SelfRenderingAggregateFunctionSqlAstExpression(
|
||||
"count",
|
||||
|
|
|
@ -8,12 +8,14 @@ package org.hibernate.sql.ast.spi;
|
|||
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.hibernate.metamodel.mapping.JdbcMapping;
|
||||
import org.hibernate.metamodel.mapping.SelectableMapping;
|
||||
import org.hibernate.metamodel.mapping.SelectablePath;
|
||||
import org.hibernate.sql.ast.tree.expression.ColumnReference;
|
||||
import org.hibernate.sql.ast.tree.expression.Expression;
|
||||
import org.hibernate.sql.ast.tree.from.TableReference;
|
||||
import org.hibernate.sql.results.graph.FetchParent;
|
||||
import org.hibernate.type.NullType;
|
||||
import org.hibernate.type.descriptor.java.JavaType;
|
||||
import org.hibernate.type.spi.TypeConfiguration;
|
||||
|
||||
|
@ -42,41 +44,42 @@ public interface SqlExpressionResolver {
|
|||
*
|
||||
* @see #resolveSqlExpression
|
||||
*/
|
||||
static ColumnReferenceKey createColumnReferenceKey(String tableExpression, String columnExpression) {
|
||||
return new ColumnReferenceKey(tableExpression, new SelectablePath( columnExpression ) );
|
||||
static ColumnReferenceKey createColumnReferenceKey(String tableExpression, String columnExpression, JdbcMapping jdbcMapping) {
|
||||
return createColumnReferenceKey( tableExpression, new SelectablePath( columnExpression ), jdbcMapping );
|
||||
}
|
||||
/**
|
||||
* Helper for generating an expression key for a column reference.
|
||||
*
|
||||
* @see #resolveSqlExpression
|
||||
*/
|
||||
static ColumnReferenceKey createColumnReferenceKey(TableReference tableReference, String columnExpression) {
|
||||
return createColumnReferenceKey( tableReference, new SelectablePath( columnExpression ) );
|
||||
static ColumnReferenceKey createColumnReferenceKey(TableReference tableReference, String columnExpression, JdbcMapping jdbcMapping) {
|
||||
return createColumnReferenceKey( tableReference, new SelectablePath( columnExpression ), jdbcMapping );
|
||||
}
|
||||
static ColumnReferenceKey createColumnReferenceKey(TableReference tableReference, SelectablePath selectablePath) {
|
||||
static ColumnReferenceKey createColumnReferenceKey(TableReference tableReference, SelectablePath selectablePath, JdbcMapping jdbcMapping) {
|
||||
assert tableReference != null : "tableReference expected to be non-null";
|
||||
assert selectablePath != null : "selectablePath expected to be non-null";
|
||||
assert tableReference.getIdentificationVariable() != null : "tableReference#identificationVariable expected to be non-null";
|
||||
final String qualifier = tableReference.getIdentificationVariable();
|
||||
return createColumnReferenceKey( qualifier, selectablePath );
|
||||
return createColumnReferenceKey( qualifier, selectablePath, jdbcMapping );
|
||||
}
|
||||
|
||||
static ColumnReferenceKey createColumnReferenceKey(String qualifier, SelectablePath selectablePath) {
|
||||
static ColumnReferenceKey createColumnReferenceKey(String qualifier, SelectablePath selectablePath, JdbcMapping jdbcMapping) {
|
||||
assert qualifier != null : "qualifier expected to be non-null";
|
||||
assert selectablePath != null : "selectablePath expected to be non-null";
|
||||
return new ColumnReferenceKey( qualifier, selectablePath );
|
||||
assert jdbcMapping != null : "jdbcMapping expected to be non-null";
|
||||
return new ColumnReferenceKey( qualifier, selectablePath, jdbcMapping );
|
||||
}
|
||||
|
||||
static ColumnReferenceKey createColumnReferenceKey(String columnExpression) {
|
||||
assert columnExpression != null : "columnExpression expected to be non-null";
|
||||
return new ColumnReferenceKey( "", new SelectablePath( columnExpression ) );
|
||||
return createColumnReferenceKey( "", new SelectablePath( columnExpression ), NullType.INSTANCE );
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience form for creating a key from table expression and SelectableMapping
|
||||
*/
|
||||
static ColumnReferenceKey createColumnReferenceKey(String tableExpression, SelectableMapping selectable) {
|
||||
return createColumnReferenceKey( tableExpression, selectable.getSelectablePath() );
|
||||
return createColumnReferenceKey( tableExpression, selectable.getSelectablePath(), selectable.getJdbcMapping() );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -85,7 +88,7 @@ public interface SqlExpressionResolver {
|
|||
static ColumnReferenceKey createColumnReferenceKey(TableReference tableReference, SelectableMapping selectable) {
|
||||
assert tableReference.containsAffectedTableName( selectable.getContainingTableExpression() )
|
||||
: String.format( ROOT, "Expecting tables to match between TableReference (%s) and SelectableMapping (%s)", tableReference.getTableId(), selectable.getContainingTableExpression() );
|
||||
return createColumnReferenceKey( tableReference, selectable.getSelectablePath() );
|
||||
return createColumnReferenceKey( tableReference, selectable.getSelectablePath(), selectable.getJdbcMapping() );
|
||||
}
|
||||
|
||||
default Expression resolveSqlExpression(TableReference tableReference, SelectableMapping selectableMapping) {
|
||||
|
@ -117,10 +120,12 @@ public interface SqlExpressionResolver {
|
|||
final class ColumnReferenceKey {
|
||||
private final String tableQualifier;
|
||||
private final SelectablePath selectablePath;
|
||||
private final JdbcMapping jdbcMapping;
|
||||
|
||||
public ColumnReferenceKey(String tableQualifier, SelectablePath selectablePath) {
|
||||
public ColumnReferenceKey(String tableQualifier, SelectablePath selectablePath, JdbcMapping jdbcMapping) {
|
||||
this.tableQualifier = tableQualifier;
|
||||
this.selectablePath = selectablePath;
|
||||
this.jdbcMapping = jdbcMapping;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -132,18 +137,17 @@ public interface SqlExpressionResolver {
|
|||
return false;
|
||||
}
|
||||
|
||||
ColumnReferenceKey that = (ColumnReferenceKey) o;
|
||||
|
||||
if ( !tableQualifier.equals( that.tableQualifier ) ) {
|
||||
return false;
|
||||
}
|
||||
return selectablePath.equals( that.selectablePath );
|
||||
final ColumnReferenceKey that = (ColumnReferenceKey) o;
|
||||
return tableQualifier.equals( that.tableQualifier )
|
||||
&& selectablePath.equals( that.selectablePath )
|
||||
&& jdbcMapping.equals( that.jdbcMapping );
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = tableQualifier.hashCode();
|
||||
result = 31 * result + selectablePath.hashCode();
|
||||
result = 31 * result + jdbcMapping.hashCode();
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -56,6 +56,12 @@ public interface SqlSelection extends SqlAstNode {
|
|||
*/
|
||||
JdbcMappingContainer getExpressionType();
|
||||
|
||||
/**
|
||||
* Whether this is a virtual or a real selection item.
|
||||
* Virtual selection items are not rendered into the SQL select clause.
|
||||
*/
|
||||
boolean isVirtual();
|
||||
|
||||
void accept(SqlAstWalker sqlAstWalker);
|
||||
|
||||
SqlSelection resolve(JdbcValuesMetadata jdbcResultsMetadata, SessionFactoryImplementor sessionFactory);
|
||||
|
|
|
@ -21,10 +21,28 @@ public interface SqlSelectionProducer {
|
|||
* @param valuesArrayPosition The position in our {@linkplain RowProcessingState#getJdbcValue(SqlSelection) "current JDBC values array"}
|
||||
* @param javaType The descriptor for the Java type to read the value as
|
||||
* @param typeConfiguration The associated TypeConfiguration
|
||||
* @deprecated Use {@link #createSqlSelection(int, int, JavaType, boolean, TypeConfiguration)} instead
|
||||
*/
|
||||
@Deprecated(forRemoval = true)
|
||||
SqlSelection createSqlSelection(
|
||||
int jdbcPosition,
|
||||
int valuesArrayPosition,
|
||||
JavaType javaType,
|
||||
TypeConfiguration typeConfiguration);
|
||||
|
||||
/**
|
||||
* Create a SqlSelection for the given JDBC ResultSet position
|
||||
*
|
||||
* @param jdbcPosition The index position used to read values from JDBC
|
||||
* @param valuesArrayPosition The position in our {@linkplain RowProcessingState#getJdbcValue(SqlSelection) "current JDBC values array"}
|
||||
* @param javaType The descriptor for the Java type to read the value as
|
||||
* @param virtual Whether the select is virtual or real. See {@link SqlSelection#isVirtual()}
|
||||
* @param typeConfiguration The associated TypeConfiguration
|
||||
*/
|
||||
SqlSelection createSqlSelection(
|
||||
int jdbcPosition,
|
||||
int valuesArrayPosition,
|
||||
JavaType javaType,
|
||||
boolean virtual,
|
||||
TypeConfiguration typeConfiguration);
|
||||
}
|
||||
|
|
|
@ -39,14 +39,41 @@ public interface Expression extends SqlAstNode, SqlSelectionProducer {
|
|||
jdbcPosition,
|
||||
valuesArrayPosition,
|
||||
javaType,
|
||||
this
|
||||
this,
|
||||
false
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
default SqlSelection createSqlSelection(
|
||||
int jdbcPosition,
|
||||
int valuesArrayPosition,
|
||||
JavaType javaType,
|
||||
boolean virtual,
|
||||
TypeConfiguration typeConfiguration) {
|
||||
return new SqlSelectionImpl(
|
||||
jdbcPosition,
|
||||
valuesArrayPosition,
|
||||
javaType,
|
||||
this,
|
||||
virtual
|
||||
);
|
||||
}
|
||||
|
||||
@Deprecated(forRemoval = true)
|
||||
default SqlSelection createDomainResultSqlSelection(
|
||||
int jdbcPosition,
|
||||
int valuesArrayPosition,
|
||||
JavaType javaType,
|
||||
TypeConfiguration typeConfiguration) {
|
||||
return createDomainResultSqlSelection( jdbcPosition, valuesArrayPosition, javaType, false, typeConfiguration );
|
||||
}
|
||||
|
||||
default SqlSelection createDomainResultSqlSelection(
|
||||
int jdbcPosition,
|
||||
int valuesArrayPosition,
|
||||
JavaType javaType,
|
||||
boolean virtual,
|
||||
TypeConfiguration typeConfiguration) {
|
||||
// Apply possible jdbc type wrapping
|
||||
final Expression expression;
|
||||
|
@ -58,7 +85,7 @@ public interface Expression extends SqlAstNode, SqlSelectionProducer {
|
|||
expression = expressionType.getJdbcMapping( 0 ).getJdbcType().wrapTopLevelSelectionExpression( this );
|
||||
}
|
||||
return expression == this
|
||||
? createSqlSelection( jdbcPosition, valuesArrayPosition, javaType, typeConfiguration )
|
||||
: new SqlSelectionImpl( jdbcPosition, valuesArrayPosition, expression );
|
||||
? createSqlSelection( jdbcPosition, valuesArrayPosition, javaType, virtual, typeConfiguration )
|
||||
: new SqlSelectionImpl( jdbcPosition, valuesArrayPosition, expression, virtual );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -58,6 +58,22 @@ public abstract class DelegatingTableGroup implements TableGroup {
|
|||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SqlSelection createSqlSelection(
|
||||
int jdbcPosition,
|
||||
int valuesArrayPosition,
|
||||
JavaType javaType,
|
||||
boolean virtual,
|
||||
TypeConfiguration typeConfiguration) {
|
||||
return getTableGroup().createSqlSelection(
|
||||
jdbcPosition,
|
||||
valuesArrayPosition,
|
||||
javaType,
|
||||
virtual,
|
||||
typeConfiguration
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TableReference getTableReference(
|
||||
NavigablePath navigablePath,
|
||||
|
|
|
@ -71,7 +71,8 @@ public abstract class AbstractJdbcParameter
|
|||
jdbcPosition,
|
||||
valuesArrayPosition,
|
||||
javaType,
|
||||
this
|
||||
this,
|
||||
false
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -22,12 +22,20 @@ public class ResolvedSqlSelection extends SqlSelectionImpl {
|
|||
|
||||
private final BasicType<Object> resolvedType;
|
||||
|
||||
public ResolvedSqlSelection(
|
||||
int valuesArrayPosition,
|
||||
Expression sqlExpression,
|
||||
BasicType<Object> resolvedType) {
|
||||
super( valuesArrayPosition + 1, valuesArrayPosition, null, sqlExpression, false );
|
||||
this.resolvedType = resolvedType;
|
||||
}
|
||||
|
||||
public ResolvedSqlSelection(
|
||||
int jdbcPosition,
|
||||
int valuesArrayPosition,
|
||||
Expression sqlExpression,
|
||||
BasicType<Object> resolvedType) {
|
||||
super( jdbcPosition, valuesArrayPosition, null, sqlExpression );
|
||||
super( jdbcPosition, valuesArrayPosition, null, sqlExpression, false );
|
||||
this.resolvedType = resolvedType;
|
||||
}
|
||||
|
||||
|
@ -41,6 +49,11 @@ public class ResolvedSqlSelection extends SqlSelectionImpl {
|
|||
return resolvedType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isVirtual() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SqlSelection resolve(JdbcValuesMetadata jdbcResultsMetadata, SessionFactoryImplementor sessionFactory) {
|
||||
return this;
|
||||
|
|
|
@ -116,7 +116,7 @@ public class RowProcessingStateStandardImpl extends BaseExecutionContext impleme
|
|||
|
||||
@Override
|
||||
public Object getJdbcValue(int position) {
|
||||
return jdbcValues.getCurrentRowValuesArray()[ position ];
|
||||
return jdbcValues.getCurrentRowValue( position );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -130,6 +130,7 @@ public class RowProcessingStateStandardImpl extends BaseExecutionContext impleme
|
|||
|
||||
@Override
|
||||
public void finishRowProcessing() {
|
||||
jdbcValues.finishRowProcessing( this );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -46,16 +46,31 @@ public class SqlSelectionImpl implements SqlSelection, SqlExpressionAccess {
|
|||
private final int valuesArrayPosition;
|
||||
private final Expression sqlExpression;
|
||||
private final JavaType<?> jdbcJavaType;
|
||||
private final boolean virtual;
|
||||
|
||||
public SqlSelectionImpl(int jdbcPosition, int valuesArrayPosition, Expression sqlExpression) {
|
||||
this( jdbcPosition, valuesArrayPosition, null, sqlExpression );
|
||||
public SqlSelectionImpl(Expression sqlExpression) {
|
||||
this( 0, -1, null, sqlExpression, false );
|
||||
}
|
||||
|
||||
public SqlSelectionImpl(int jdbcPosition, int valuesArrayPosition, JavaType<?> jdbcJavaType, Expression sqlExpression) {
|
||||
public SqlSelectionImpl(int valuesArrayPosition, Expression sqlExpression) {
|
||||
this( valuesArrayPosition + 1, valuesArrayPosition, null, sqlExpression, false );
|
||||
}
|
||||
|
||||
public SqlSelectionImpl(int jdbcPosition, int valuesArrayPosition, Expression sqlExpression, boolean virtual) {
|
||||
this( jdbcPosition, valuesArrayPosition, null, sqlExpression, virtual );
|
||||
}
|
||||
|
||||
public SqlSelectionImpl(
|
||||
int jdbcPosition,
|
||||
int valuesArrayPosition,
|
||||
JavaType<?> jdbcJavaType,
|
||||
Expression sqlExpression,
|
||||
boolean virtual) {
|
||||
this.jdbcPosition = jdbcPosition;
|
||||
this.valuesArrayPosition = valuesArrayPosition;
|
||||
this.jdbcJavaType = jdbcJavaType;
|
||||
this.sqlExpression = sqlExpression;
|
||||
this.virtual = virtual;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -87,6 +102,11 @@ public class SqlSelectionImpl implements SqlSelection, SqlExpressionAccess {
|
|||
return getExpression().getExpressionType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isVirtual() {
|
||||
return virtual;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Expression getSqlExpression() {
|
||||
return sqlExpression;
|
||||
|
@ -126,11 +146,12 @@ public class SqlSelectionImpl implements SqlSelection, SqlExpressionAccess {
|
|||
final SqlSelection that = (SqlSelection) o;
|
||||
return jdbcPosition == that.getJdbcResultSetIndex() &&
|
||||
valuesArrayPosition == that.getValuesArrayPosition() &&
|
||||
Objects.equals( sqlExpression, that.getExpression() );
|
||||
Objects.equals( sqlExpression, that.getExpression() ) &&
|
||||
virtual == that.isVirtual();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash( jdbcPosition, valuesArrayPosition, sqlExpression );
|
||||
return Objects.hash( jdbcPosition, valuesArrayPosition, sqlExpression, virtual );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,8 +6,6 @@
|
|||
*/
|
||||
package org.hibernate.sql.results.jdbc.internal;
|
||||
|
||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||
import org.hibernate.sql.results.caching.QueryCachePutManager;
|
||||
import org.hibernate.sql.results.jdbc.spi.JdbcValues;
|
||||
import org.hibernate.sql.results.jdbc.spi.RowProcessingState;
|
||||
|
||||
|
@ -15,22 +13,10 @@ import org.hibernate.sql.results.jdbc.spi.RowProcessingState;
|
|||
* @author Steve Ebersole
|
||||
*/
|
||||
public abstract class AbstractJdbcValues implements JdbcValues {
|
||||
private final QueryCachePutManager queryCachePutManager;
|
||||
|
||||
public AbstractJdbcValues(QueryCachePutManager queryCachePutManager) {
|
||||
if ( queryCachePutManager == null ) {
|
||||
throw new IllegalArgumentException( "QueryCachePutManager cannot be null" );
|
||||
}
|
||||
this.queryCachePutManager = queryCachePutManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean next(RowProcessingState rowProcessingState) {
|
||||
final boolean hadRow = processNext( rowProcessingState );
|
||||
if ( hadRow ) {
|
||||
queryCachePutManager.registerJdbcRow( getCurrentRowValuesArray() );
|
||||
}
|
||||
return hadRow;
|
||||
return processNext( rowProcessingState );
|
||||
}
|
||||
|
||||
protected abstract boolean processNext(RowProcessingState rowProcessingState);
|
||||
|
@ -64,12 +50,4 @@ public abstract class AbstractJdbcValues implements JdbcValues {
|
|||
}
|
||||
|
||||
protected abstract boolean processPosition(int position, RowProcessingState rowProcessingState);
|
||||
|
||||
@Override
|
||||
public final void finishUp(SharedSessionContractImplementor session) {
|
||||
queryCachePutManager.finishUp( session );
|
||||
release();
|
||||
}
|
||||
|
||||
protected abstract void release();
|
||||
}
|
||||
|
|
|
@ -8,9 +8,9 @@ package org.hibernate.sql.results.jdbc.internal;
|
|||
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||
import org.hibernate.internal.util.collections.CollectionHelper;
|
||||
import org.hibernate.sql.results.ResultsLogger;
|
||||
import org.hibernate.sql.results.caching.internal.QueryCachePutManagerDisabledImpl;
|
||||
import org.hibernate.sql.results.jdbc.spi.JdbcValuesMapping;
|
||||
import org.hibernate.sql.results.jdbc.spi.JdbcValuesMetadata;
|
||||
import org.hibernate.sql.results.jdbc.spi.RowProcessingState;
|
||||
|
@ -29,12 +29,6 @@ public class JdbcValuesCacheHit extends AbstractJdbcValues {
|
|||
private int position = -1;
|
||||
|
||||
public JdbcValuesCacheHit(Object[][] cachedData, JdbcValuesMapping resolvedMapping) {
|
||||
// if we have a cache hit we should not be writing back to the cache.
|
||||
// its silly because the state would always be the same.
|
||||
//
|
||||
// well actually, there are times when we want to write values back to the cache even though we had a hit...
|
||||
// the case is related to the domain-data cache
|
||||
super( QueryCachePutManagerDisabledImpl.INSTANCE );
|
||||
this.cachedData = cachedData;
|
||||
this.numberOfRows = cachedData.length;
|
||||
this.resolvedMapping = resolvedMapping;
|
||||
|
@ -237,7 +231,19 @@ public class JdbcValuesCacheHit extends AbstractJdbcValues {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void release() {
|
||||
public Object getCurrentRowValue(int valueIndex) {
|
||||
if ( position >= numberOfRows ) {
|
||||
return null;
|
||||
}
|
||||
return cachedData[position][valueIndex];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finishRowProcessing(RowProcessingState rowProcessingState) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finishUp(SharedSessionContractImplementor session) {
|
||||
cachedData = null;
|
||||
}
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@ package org.hibernate.sql.results.jdbc.internal;
|
|||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Arrays;
|
||||
import java.util.BitSet;
|
||||
|
||||
import org.hibernate.cache.spi.QueryKey;
|
||||
import org.hibernate.cache.spi.QueryResultsCache;
|
||||
|
@ -32,11 +33,14 @@ import org.hibernate.sql.results.jdbc.spi.RowProcessingState;
|
|||
*/
|
||||
public class JdbcValuesResultSetImpl extends AbstractJdbcValues {
|
||||
|
||||
private final QueryCachePutManager queryCachePutManager;
|
||||
private final ResultSetAccess resultSetAccess;
|
||||
private final JdbcValuesMapping valuesMapping;
|
||||
private final ExecutionContext executionContext;
|
||||
|
||||
private final SqlSelection[] sqlSelections;
|
||||
private final SqlSelection[] eagerSqlSelections;
|
||||
private final BitSet initializedIndexes;
|
||||
private final Object[] currentRowJdbcValues;
|
||||
|
||||
public JdbcValuesResultSetImpl(
|
||||
|
@ -47,15 +51,61 @@ public class JdbcValuesResultSetImpl extends AbstractJdbcValues {
|
|||
JdbcValuesMapping valuesMapping,
|
||||
JdbcValuesMetadata metadataForCache,
|
||||
ExecutionContext executionContext) {
|
||||
super( resolveQueryCachePutManager( executionContext, queryOptions, queryCacheKey, queryIdentifier, metadataForCache ) );
|
||||
this.queryCachePutManager = resolveQueryCachePutManager(
|
||||
executionContext,
|
||||
queryOptions,
|
||||
queryCacheKey,
|
||||
queryIdentifier,
|
||||
metadataForCache
|
||||
);
|
||||
this.resultSetAccess = resultSetAccess;
|
||||
this.valuesMapping = valuesMapping;
|
||||
this.executionContext = executionContext;
|
||||
|
||||
this.sqlSelections = valuesMapping.getSqlSelections().toArray( new SqlSelection[0] );
|
||||
this.eagerSqlSelections = extractEagerSqlSelections( sqlSelections );
|
||||
this.initializedIndexes = new BitSet( valuesMapping.getRowSize() );
|
||||
this.currentRowJdbcValues = new Object[ valuesMapping.getRowSize() ];
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine the selections which are eager i.e. safe to always extract.
|
||||
* If a virtual selection exists, we must extract the value for that JDBC position lazily.
|
||||
*/
|
||||
private SqlSelection[] extractEagerSqlSelections(SqlSelection[] sqlSelections) {
|
||||
BitSet lazyValuesPositions = null;
|
||||
for ( int i = 0; i < sqlSelections.length; i++ ) {
|
||||
final SqlSelection sqlSelection = sqlSelections[i];
|
||||
if ( sqlSelection.isVirtual() ) {
|
||||
if ( lazyValuesPositions == null ) {
|
||||
lazyValuesPositions = new BitSet();
|
||||
}
|
||||
lazyValuesPositions.set( sqlSelection.getValuesArrayPosition() );
|
||||
// Find the one preceding selection that refers to the same JDBC position
|
||||
// and treat that as virtual to do lazy extraction
|
||||
for ( int j = 0; j < i; j++ ) {
|
||||
if ( sqlSelections[j].getJdbcResultSetIndex() == sqlSelection.getJdbcResultSetIndex() ) {
|
||||
// There can only be a single selection which also has to be non-virtual
|
||||
assert !sqlSelections[j].isVirtual();
|
||||
lazyValuesPositions.set( sqlSelections[j].getValuesArrayPosition() );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( lazyValuesPositions == null ) {
|
||||
return sqlSelections;
|
||||
}
|
||||
final SqlSelection[] eagerSqlSelections = new SqlSelection[sqlSelections.length - lazyValuesPositions.cardinality()];
|
||||
int i = 0;
|
||||
for ( SqlSelection sqlSelection : sqlSelections ) {
|
||||
if ( !lazyValuesPositions.get( sqlSelection.getValuesArrayPosition() ) ) {
|
||||
eagerSqlSelections[i++] = sqlSelection;
|
||||
}
|
||||
}
|
||||
return eagerSqlSelections;
|
||||
}
|
||||
|
||||
private static QueryCachePutManager resolveQueryCachePutManager(
|
||||
ExecutionContext executionContext,
|
||||
QueryOptions queryOptions,
|
||||
|
@ -257,7 +307,9 @@ public class JdbcValuesResultSetImpl extends AbstractJdbcValues {
|
|||
private void readCurrentRowValues() {
|
||||
final ResultSet resultSet = resultSetAccess.getResultSet();
|
||||
final SharedSessionContractImplementor session = executionContext.getSession();
|
||||
for ( final SqlSelection sqlSelection : sqlSelections ) {
|
||||
initializedIndexes.clear();
|
||||
for ( final SqlSelection sqlSelection : eagerSqlSelections ) {
|
||||
initializedIndexes.set( sqlSelection.getValuesArrayPosition() );
|
||||
try {
|
||||
currentRowJdbcValues[ sqlSelection.getValuesArrayPosition() ] = sqlSelection.getJdbcValueExtractor().extract(
|
||||
resultSet,
|
||||
|
@ -276,7 +328,8 @@ public class JdbcValuesResultSetImpl extends AbstractJdbcValues {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void release() {
|
||||
public final void finishUp(SharedSessionContractImplementor session) {
|
||||
queryCachePutManager.finishUp( session );
|
||||
resultSetAccess.release();
|
||||
}
|
||||
|
||||
|
@ -290,6 +343,34 @@ public class JdbcValuesResultSetImpl extends AbstractJdbcValues {
|
|||
return currentRowJdbcValues;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finishRowProcessing(RowProcessingState rowProcessingState) {
|
||||
queryCachePutManager.registerJdbcRow( currentRowJdbcValues );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getCurrentRowValue(int valueIndex) {
|
||||
if ( !initializedIndexes.get( valueIndex ) ) {
|
||||
initializedIndexes.set( valueIndex );
|
||||
final SqlSelection sqlSelection = sqlSelections[valueIndex];
|
||||
try {
|
||||
currentRowJdbcValues[valueIndex] = sqlSelection.getJdbcValueExtractor().extract(
|
||||
resultSetAccess.getResultSet(),
|
||||
sqlSelection.getJdbcResultSetIndex(),
|
||||
executionContext.getSession()
|
||||
);
|
||||
}
|
||||
catch ( SQLException e ) {
|
||||
// do not want to wrap in ExecutionException here
|
||||
throw executionContext.getSession().getJdbcServices().getSqlExceptionHelper().convert(
|
||||
e,
|
||||
"Could not extract column [" + sqlSelection.getJdbcResultSetIndex() + "] from JDBC ResultSet"
|
||||
);
|
||||
}
|
||||
}
|
||||
return currentRowJdbcValues[valueIndex];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFetchSize(int fetchSize) {
|
||||
try {
|
||||
|
|
|
@ -21,7 +21,7 @@ public interface JdbcValues {
|
|||
|
||||
/**
|
||||
* Advances the "cursor position" and returns a boolean indicating whether
|
||||
* there is a row available to read via {@link #getCurrentRowValuesArray()}.
|
||||
* there is a row available to read via {@link #getCurrentRowValue(int)}.
|
||||
*
|
||||
* @return {@code true} if there are results
|
||||
*/
|
||||
|
@ -29,7 +29,7 @@ public interface JdbcValues {
|
|||
|
||||
/**
|
||||
* Advances the "cursor position" in reverse and returns a boolean indicating whether
|
||||
* there is a row available to read via {@link #getCurrentRowValuesArray()}.
|
||||
* there is a row available to read via {@link #getCurrentRowValue(int)}.
|
||||
*
|
||||
* @return {@code true} if there are results available
|
||||
*/
|
||||
|
@ -37,7 +37,7 @@ public interface JdbcValues {
|
|||
|
||||
/**
|
||||
* Advances the "cursor position" the indicated number of rows and returns a boolean
|
||||
* indicating whether there is a row available to read via {@link #getCurrentRowValuesArray()}.
|
||||
* indicating whether there is a row available to read via {@link #getCurrentRowValue(int)}.
|
||||
*
|
||||
* @param numberOfRows The number of rows to advance. This can also be negative meaning to
|
||||
* move in reverse
|
||||
|
@ -74,6 +74,17 @@ public interface JdbcValues {
|
|||
*/
|
||||
Object[] getCurrentRowValuesArray();
|
||||
|
||||
/**
|
||||
* Get the JDBC value at the given index for the row currently positioned at within
|
||||
* this source.
|
||||
*
|
||||
* @return The current row's JDBC values, or {@code null} if the position
|
||||
* is beyond the end of the available results.
|
||||
*/
|
||||
Object getCurrentRowValue(int valueIndex);
|
||||
|
||||
void finishRowProcessing(RowProcessingState rowProcessingState);
|
||||
|
||||
/**
|
||||
* Give implementations a chance to finish processing
|
||||
*/
|
||||
|
|
|
@ -0,0 +1,170 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||
*/
|
||||
package org.hibernate.orm.test.mapping.basic;
|
||||
|
||||
import org.hibernate.annotations.JdbcTypeCode;
|
||||
import org.hibernate.cfg.AvailableSettings;
|
||||
import org.hibernate.type.SqlTypes;
|
||||
|
||||
import org.hibernate.testing.orm.junit.DomainModel;
|
||||
import org.hibernate.testing.orm.junit.ServiceRegistry;
|
||||
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||
import org.hibernate.testing.orm.junit.Setting;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.Table;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.instanceOf;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
|
||||
/**
|
||||
* @author Christian Beikov
|
||||
*/
|
||||
@DomainModel(annotatedClasses = {
|
||||
PolymorphicJsonTests.EntityWithJson.class,
|
||||
PolymorphicJsonTests.EntityWithJsonA.class,
|
||||
PolymorphicJsonTests.EntityWithJsonB.class
|
||||
})
|
||||
@SessionFactory
|
||||
public abstract class PolymorphicJsonTests {
|
||||
|
||||
@ServiceRegistry(settings = @Setting(name = AvailableSettings.JSON_FORMAT_MAPPER, value = "jsonb"))
|
||||
public static class JsonB extends PolymorphicJsonTests {
|
||||
|
||||
public JsonB() {
|
||||
}
|
||||
}
|
||||
|
||||
@ServiceRegistry(settings = @Setting(name = AvailableSettings.JSON_FORMAT_MAPPER, value = "jackson"))
|
||||
public static class Jackson extends PolymorphicJsonTests {
|
||||
|
||||
public Jackson() {
|
||||
}
|
||||
}
|
||||
|
||||
@BeforeEach
|
||||
public void setup(SessionFactoryScope scope) {
|
||||
scope.inTransaction(
|
||||
(session) -> {
|
||||
session.persist( new EntityWithJsonA( 1, new PropertyA( "e1" ) ) );
|
||||
session.persist( new EntityWithJsonB( 2, new PropertyB( 123 ) ) );
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
public void tearDown(SessionFactoryScope scope) {
|
||||
scope.inTransaction(
|
||||
(session) -> {
|
||||
session.remove( session.find( EntityWithJson.class, 1 ) );
|
||||
session.remove( session.find( EntityWithJson.class, 2 ) );
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void verifyReadWorks(SessionFactoryScope scope) {
|
||||
scope.inTransaction(
|
||||
(session) -> {
|
||||
EntityWithJson entityWithJsonA = session.find( EntityWithJson.class, 1 );
|
||||
EntityWithJson entityWithJsonB = session.find( EntityWithJson.class, 2 );
|
||||
assertThat( entityWithJsonA, instanceOf( EntityWithJsonA.class ) );
|
||||
assertThat( entityWithJsonB, instanceOf( EntityWithJsonB.class ) );
|
||||
assertThat( ( (EntityWithJsonA) entityWithJsonA ).property.value, is( "e1" ) );
|
||||
assertThat( ( (EntityWithJsonB) entityWithJsonB ).property.value, is( 123 ) );
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Entity(name = "EntityWithJson")
|
||||
@Table(name = "EntityWithJson")
|
||||
public static abstract class EntityWithJson {
|
||||
@Id
|
||||
private Integer id;
|
||||
|
||||
public EntityWithJson() {
|
||||
}
|
||||
|
||||
public EntityWithJson(Integer id) {
|
||||
this.id = id;
|
||||
}
|
||||
}
|
||||
|
||||
@Entity(name = "EntityWithJsonA")
|
||||
public static class EntityWithJsonA extends EntityWithJson {
|
||||
|
||||
@JdbcTypeCode( SqlTypes.JSON )
|
||||
private PropertyA property;
|
||||
|
||||
public EntityWithJsonA() {
|
||||
}
|
||||
|
||||
public EntityWithJsonA(Integer id, PropertyA property) {
|
||||
super( id );
|
||||
this.property = property;
|
||||
}
|
||||
}
|
||||
|
||||
@Entity(name = "EntityWithJsonB")
|
||||
public static class EntityWithJsonB extends EntityWithJson {
|
||||
|
||||
@JdbcTypeCode( SqlTypes.JSON )
|
||||
private PropertyB property;
|
||||
|
||||
public EntityWithJsonB() {
|
||||
}
|
||||
|
||||
public EntityWithJsonB(Integer id, PropertyB property) {
|
||||
super( id );
|
||||
this.property = property;
|
||||
}
|
||||
}
|
||||
|
||||
public static class PropertyA {
|
||||
private String value;
|
||||
|
||||
public PropertyA() {
|
||||
}
|
||||
|
||||
public PropertyA(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setValue(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
|
||||
public static class PropertyB {
|
||||
private int value;
|
||||
|
||||
public PropertyB() {
|
||||
}
|
||||
|
||||
public PropertyB(int value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public int getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setValue(int value) {
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue