Skip to content

Commit 03a5a75

Browse files
committed
HHH-19712 Rework select fragment generation to work with column selection deduplication
1 parent 59ff35c commit 03a5a75

File tree

1 file changed

+89
-82
lines changed

1 file changed

+89
-82
lines changed

hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java

Lines changed: 89 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -1999,63 +1999,59 @@ public String selectFragment(String alias, String suffix) {
19991999
// Wrap expressions with aliases
20002000
final SelectClause selectClause = rootQuerySpec.getSelectClause();
20012001
final List<SqlSelection> sqlSelections = selectClause.getSqlSelections();
2002+
final Set<String> processedExpressions = new HashSet<>( sqlSelections.size() );
20022003
int i = 0;
2003-
int columnIndex = 0;
2004-
final String[] columnAliases = getSubclassColumnAliasClosure();
2005-
final int columnAliasesSize = columnAliases.length;
2006-
for ( String identifierAlias : identifierAliases ) {
2007-
sqlSelections.set(
2008-
i,
2009-
new SqlSelectionImpl(
2010-
i,
2011-
new AliasedExpression( sqlSelections.get( i ).getExpression(), identifierAlias + suffix )
2012-
)
2013-
);
2014-
if ( i < columnAliasesSize && columnAliases[i].equals( identifierAlias ) ) {
2015-
columnIndex++;
2004+
final int identifierSelectionSize = identifierMapping.getJdbcTypeCount();
2005+
for ( int j = 0; j < identifierSelectionSize; j++ ) {
2006+
final SelectableMapping selectableMapping = identifierMapping.getSelectable( j );
2007+
if ( processedExpressions.add( selectableMapping.getSelectionExpression() ) ) {
2008+
aliasSelection( sqlSelections, i, identifierAliases[j] + suffix );
2009+
i++;
20162010
}
2017-
i++;
20182011
}
20192012

2020-
if ( entityMetamodel.hasSubclasses() ) {
2021-
sqlSelections.set(
2022-
i,
2023-
new SqlSelectionImpl(
2024-
i,
2025-
new AliasedExpression( sqlSelections.get( i ).getExpression(), getDiscriminatorAlias() + suffix )
2026-
)
2027-
);
2028-
i++;
2013+
if ( hasSubclasses() ) {
2014+
assert discriminatorMapping.getJdbcTypeCount() == 1;
2015+
final SelectableMapping selectableMapping = discriminatorMapping.getSelectable( 0 );
2016+
if ( processedExpressions.add( selectableMapping.getSelectionExpression() ) ) {
2017+
aliasSelection( sqlSelections, i, getDiscriminatorAlias() + suffix );
2018+
i++;
2019+
}
20292020
}
20302021

20312022
if ( hasRowId() ) {
2032-
sqlSelections.set(
2033-
i,
2034-
new SqlSelectionImpl(
2035-
i,
2036-
new AliasedExpression( sqlSelections.get( i ).getExpression(), ROWID_ALIAS + suffix )
2037-
)
2038-
);
2039-
i++;
2040-
}
2041-
2042-
final String[] formulaAliases = getSubclassFormulaAliasClosure();
2043-
int formulaIndex = 0;
2044-
for ( ; i < sqlSelections.size(); i++ ) {
2045-
final SqlSelection sqlSelection = sqlSelections.get( i );
2046-
final ColumnReference columnReference = (ColumnReference) sqlSelection.getExpression();
2047-
final String selectAlias = !columnReference.isColumnExpressionFormula()
2048-
? columnAliases[columnIndex++] + suffix
2049-
: formulaAliases[formulaIndex++] + suffix;
2050-
sqlSelections.set(
2051-
i,
2052-
new SqlSelectionImpl(
2053-
sqlSelection.getValuesArrayPosition(),
2054-
new AliasedExpression( sqlSelection.getExpression(), selectAlias )
2055-
)
2056-
);
2023+
final SelectableMapping selectableMapping = rowIdMapping;
2024+
if ( processedExpressions.add( selectableMapping.getSelectionExpression() ) ) {
2025+
aliasSelection( sqlSelections, i, ROWID_ALIAS + suffix );
2026+
i++;
2027+
}
20572028
}
20582029

2030+
final String[] columnAliases = getSubclassColumnAliasClosure();
2031+
final String[] formulaAliases = getSubclassFormulaAliasClosure();// getSubclassColumnAliasClosure contains the _identifierMapper columns,
2032+
// which need to be skipped
2033+
int columnIndex = identifierMapping instanceof NonAggregatedIdentifierMapping ? identifierSelectionSize : 0;
2034+
int formulaIndex = 0;
2035+
final int size = getNumberOfFetchables();
2036+
for ( int j = 0; j < size; j++ ) {
2037+
final AttributeMapping fetchable = getFetchable( j );
2038+
if ( !(fetchable instanceof PluralAttributeMapping)
2039+
&& !skipFetchable( fetchable, fetchable.getMappedFetchOptions().getTiming() )
2040+
&& fetchable.isSelectable() ) {
2041+
final int jdbcTypeCount = fetchable.getJdbcTypeCount();
2042+
for ( int k = 0; k < jdbcTypeCount; k++ ) {
2043+
final SelectableMapping selectableMapping = fetchable.getSelectable( k );
2044+
if ( processedExpressions.add( selectableMapping.getSelectionExpression() ) ) {
2045+
final String baseAlias = selectableMapping.isFormula()
2046+
? formulaAliases[formulaIndex++]
2047+
: columnAliases[columnIndex++];
2048+
aliasSelection( sqlSelections, i, baseAlias + suffix );
2049+
i++;
2050+
}
2051+
}
2052+
}
2053+
}
2054+
20592055
final String sql = getFactory().getJdbcServices()
20602056
.getDialect()
20612057
.getSqlAstTranslatorFactory()
@@ -2073,6 +2069,17 @@ public String selectFragment(String alias, String suffix) {
20732069
return expression;
20742070
}
20752071

2072+
private static void aliasSelection(
2073+
List<SqlSelection> sqlSelections,
2074+
int selectionIndex,
2075+
String alias) {
2076+
final Expression expression = sqlSelections.get( selectionIndex ).getExpression();
2077+
sqlSelections.set(
2078+
selectionIndex,
2079+
new SqlSelectionImpl( selectionIndex, new AliasedExpression( expression, alias ) )
2080+
);
2081+
}
2082+
20762083
private ImmutableFetchList fetchProcessor(FetchParent fetchParent, LoaderSqlAstCreationState creationState) {
20772084
final FetchableContainer fetchableContainer = fetchParent.getReferencedMappingContainer();
20782085
final int size = fetchableContainer.getNumberOfFetchables();
@@ -2083,45 +2090,45 @@ private ImmutableFetchList fetchProcessor(FetchParent fetchParent, LoaderSqlAstC
20832090
// Ignore plural attributes
20842091
if ( !( fetchable instanceof PluralAttributeMapping ) ) {
20852092
final FetchTiming fetchTiming = fetchable.getMappedFetchOptions().getTiming();
2086-
if ( fetchable.asBasicValuedModelPart() != null ) {
2087-
// Ignore lazy basic columns
2088-
if ( fetchTiming == FetchTiming.DELAYED ) {
2089-
continue;
2090-
}
2091-
}
2092-
else if ( fetchable instanceof Association ) {
2093-
final Association association = (Association) fetchable;
2094-
// Ignore the fetchable if the FK is on the other side
2095-
if ( association.getSideNature() == ForeignKeyDescriptor.Nature.TARGET ) {
2096-
continue;
2097-
}
2098-
// Ensure the FK comes from the root table
2099-
if ( !getRootTableName().equals( association.getForeignKeyDescriptor().getKeyTable() ) ) {
2100-
continue;
2101-
}
2102-
}
2103-
2104-
if ( fetchTiming == null ) {
2105-
throw new AssertionFailure("fetchTiming was null");
2106-
}
2107-
2108-
if ( fetchable.isSelectable() ) {
2109-
final Fetch fetch = fetchParent.generateFetchableFetch(
2110-
fetchable,
2111-
fetchParent.resolveNavigablePath( fetchable ),
2112-
fetchTiming,
2113-
false,
2114-
null,
2115-
creationState
2116-
);
2117-
fetches.add( fetch );
2118-
}
2093+
if ( !skipFetchable( fetchable, fetchTiming ) ) {
2094+
if ( fetchTiming == null ) {
2095+
throw new AssertionFailure( "fetchTiming was null" );
2096+
}
2097+
if ( fetchable.isSelectable() ) {
2098+
final Fetch fetch = fetchParent.generateFetchableFetch(
2099+
fetchable,
2100+
fetchParent.resolveNavigablePath( fetchable ),
2101+
fetchTiming,
2102+
false,
2103+
null,
2104+
creationState
2105+
);
2106+
fetches.add( fetch );
2107+
}
2108+
}
21192109
}
21202110
}
21212111

21222112
return fetches.build();
21232113
}
21242114

2115+
private boolean skipFetchable(Fetchable fetchable, FetchTiming fetchTiming) {
2116+
if ( fetchable.asBasicValuedModelPart() != null ) {
2117+
// Ignore lazy basic columns
2118+
return fetchTiming == FetchTiming.DELAYED;
2119+
}
2120+
else if ( fetchable instanceof Association ) {
2121+
final Association association = (Association) fetchable;
2122+
// Ignore the fetchable if the FK is on the other side
2123+
return association.getSideNature() == ForeignKeyDescriptor.Nature.TARGET
2124+
// Ensure the FK comes from the root table
2125+
|| !getRootTableName().equals( association.getForeignKeyDescriptor().getKeyTable() );
2126+
}
2127+
else {
2128+
return false;
2129+
}
2130+
}
2131+
21252132
/**
21262133
* @deprecated use {@link Fetchable#isSelectable()} instead.
21272134
*/
@@ -6354,7 +6361,7 @@ public Fetchable getKeyFetchable(int position) {
63546361
}
63556362

63566363
@Override
6357-
public Fetchable getFetchable(int position) {
6364+
public AttributeMapping getFetchable(int position) {
63586365
return getStaticFetchableList().get( position );
63596366
}
63606367

0 commit comments

Comments
 (0)