Do not reuse join that is treat joined

This commit is contained in:
Christian Beikov 2022-03-24 06:55:09 +01:00
parent 99ed18c228
commit 5a2f92588c
1 changed files with 12 additions and 9 deletions

View File

@ -10,11 +10,11 @@ import org.hibernate.metamodel.model.domain.EntityDomainType;
import org.hibernate.query.SemanticException; import org.hibernate.query.SemanticException;
import org.hibernate.query.hql.spi.DotIdentifierConsumer; import org.hibernate.query.hql.spi.DotIdentifierConsumer;
import org.hibernate.query.hql.spi.SemanticPathPart; import org.hibernate.query.hql.spi.SemanticPathPart;
import org.hibernate.query.hql.spi.SqmCreationProcessingState;
import org.hibernate.query.hql.spi.SqmCreationState;
import org.hibernate.query.hql.spi.SqmPathRegistry; import org.hibernate.query.hql.spi.SqmPathRegistry;
import org.hibernate.query.sqm.SqmJoinable; import org.hibernate.query.sqm.SqmJoinable;
import org.hibernate.query.sqm.SqmPathSource; import org.hibernate.query.sqm.SqmPathSource;
import org.hibernate.query.hql.spi.SqmCreationProcessingState;
import org.hibernate.query.hql.spi.SqmCreationState;
import org.hibernate.query.sqm.spi.SqmCreationHelper; import org.hibernate.query.sqm.spi.SqmCreationHelper;
import org.hibernate.query.sqm.tree.SqmJoinType; import org.hibernate.query.sqm.tree.SqmJoinType;
import org.hibernate.query.sqm.tree.domain.SqmPolymorphicRootDescriptor; import org.hibernate.query.sqm.tree.domain.SqmPolymorphicRootDescriptor;
@ -96,7 +96,7 @@ public class QualifiedJoinPathConsumer implements DotIdentifierConsumer {
} }
else { else {
assert delegate != null; assert delegate != null;
delegate.consumeIdentifier( identifier, !nested && isTerminal ); delegate.consumeIdentifier( identifier, !nested && isTerminal, !( nested && isTerminal ) );
} }
} }
@ -160,6 +160,7 @@ public class QualifiedJoinPathConsumer implements DotIdentifierConsumer {
alias, alias,
fetch, fetch,
isTerminal, isTerminal,
true,
creationState creationState
); );
} }
@ -171,10 +172,11 @@ public class QualifiedJoinPathConsumer implements DotIdentifierConsumer {
String alias, String alias,
boolean fetch, boolean fetch,
boolean isTerminal, boolean isTerminal,
boolean allowReuse,
SqmCreationState creationState) { SqmCreationState creationState) {
//noinspection unchecked //noinspection unchecked
final SqmPathSource<Object> subPathSource = (SqmPathSource<Object>) lhs.getReferencedPathSource().getSubPathSource( name ); final SqmPathSource<Object> subPathSource = (SqmPathSource<Object>) lhs.getReferencedPathSource().getSubPathSource( name );
if ( !isTerminal ) { if ( allowReuse && !isTerminal ) {
for ( SqmJoin<?, ?> sqmJoin : lhs.getSqmJoins() ) { for ( SqmJoin<?, ?> sqmJoin : lhs.getSqmJoins() ) {
if ( sqmJoin.getAlias() == null && sqmJoin.getReferencedPathSource() == subPathSource ) { if ( sqmJoin.getAlias() == null && sqmJoin.getReferencedPathSource() == subPathSource ) {
//noinspection unchecked //noinspection unchecked
@ -186,7 +188,7 @@ public class QualifiedJoinPathConsumer implements DotIdentifierConsumer {
final SqmJoin<Object, Object> join = ( (SqmJoinable<Object, Object>) subPathSource ).createSqmJoin( final SqmJoin<Object, Object> join = ( (SqmJoinable<Object, Object>) subPathSource ).createSqmJoin(
lhs, lhs,
joinType, joinType,
isTerminal ? alias : SqmCreationHelper.IMPLICIT_ALIAS, isTerminal ? alias : allowReuse ? SqmCreationHelper.IMPLICIT_ALIAS : Long.toString( System.nanoTime() ),
fetch, fetch,
creationState creationState
); );
@ -196,7 +198,7 @@ public class QualifiedJoinPathConsumer implements DotIdentifierConsumer {
} }
private interface ConsumerDelegate { private interface ConsumerDelegate {
void consumeIdentifier(String identifier, boolean isTerminal); void consumeIdentifier(String identifier, boolean isTerminal, boolean allowReuse);
void consumeTreat(String entityName, boolean isTerminal); void consumeTreat(String entityName, boolean isTerminal);
SemanticPathPart getConsumedPart(); SemanticPathPart getConsumedPart();
} }
@ -226,7 +228,7 @@ public class QualifiedJoinPathConsumer implements DotIdentifierConsumer {
} }
@Override @Override
public void consumeIdentifier(String identifier, boolean isTerminal) { public void consumeIdentifier(String identifier, boolean isTerminal, boolean allowReuse) {
currentPath = createJoin( currentPath = createJoin(
currentPath, currentPath,
identifier, identifier,
@ -234,6 +236,7 @@ public class QualifiedJoinPathConsumer implements DotIdentifierConsumer {
alias, alias,
fetch, fetch,
isTerminal, isTerminal,
allowReuse,
creationState creationState
); );
} }
@ -283,11 +286,11 @@ public class QualifiedJoinPathConsumer implements DotIdentifierConsumer {
this.fetch = fetch; this.fetch = fetch;
this.alias = alias; this.alias = alias;
consumeIdentifier( identifier, isTerminal ); consumeIdentifier( identifier, isTerminal, true );
} }
@Override @Override
public void consumeIdentifier(String identifier, boolean isTerminal) { public void consumeIdentifier(String identifier, boolean isTerminal, boolean allowReuse) {
if ( path.length() != 0 ) { if ( path.length() != 0 ) {
path.append( '.' ); path.append( '.' );
} }