Skip to content

Commit

Permalink
HHH-16733 Use existing SQM copy logic in QuerySplitter
Browse files Browse the repository at this point in the history
  • Loading branch information
mbladel committed Jun 27, 2023
1 parent 0d3628a commit c06d605
Show file tree
Hide file tree
Showing 22 changed files with 180 additions and 1,424 deletions.
1,326 changes: 40 additions & 1,286 deletions hibernate-core/src/main/java/org/hibernate/query/hql/internal/QuerySplitter.java

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*
* 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.query.sqm.internal;

import org.hibernate.query.sqm.tree.expression.SqmParameter;

/**
* @author Marco Belladelli
*/
public class NoParamSqmCopyContext extends SimpleSqmCopyContext {
@Override
public <T> T getCopy(T original) {
if ( original instanceof SqmParameter<?> ) {
return original;
}
return super.getCopy( original );
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
* 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.query.sqm.internal;

import java.util.IdentityHashMap;

import org.hibernate.query.sqm.tree.SqmCopyContext;

/**
* @author Marco Belladelli
*/
public class SimpleSqmCopyContext implements SqmCopyContext {
private final IdentityHashMap<Object, Object> map = new IdentityHashMap<>();

@Override
@SuppressWarnings( "unchecked" )
public <T> T getCopy(T original) {
return (T) map.get( original );
}

@Override
public <T> T registerCopy(T original, T copy) {
final Object old = map.put( original, copy );
if ( old != null ) {
throw new IllegalArgumentException( "Already registered a copy: " + old );
}
return copy;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,8 @@
*/
package org.hibernate.query.sqm.tree;

import java.util.IdentityHashMap;

import org.hibernate.query.sqm.tree.domain.SqmPath;
import org.hibernate.query.sqm.tree.expression.SqmParameter;
import org.hibernate.query.sqm.internal.NoParamSqmCopyContext;
import org.hibernate.query.sqm.internal.SimpleSqmCopyContext;

/**
*
Expand All @@ -21,109 +19,10 @@ public interface SqmCopyContext {
<T> T registerCopy(T original, T copy);

static SqmCopyContext simpleContext() {
final IdentityHashMap<Object, Object> map = new IdentityHashMap<>();
return new SqmCopyContext() {
@Override
@SuppressWarnings("unchecked")
public <T> T getCopy(T original) {
if (original instanceof SqmPath) {
return (T) getPathCopy( (SqmPath<?>) original );
}
else {
return (T) map.get( original );
}
}

@Override
public <T> T registerCopy(T original, T copy) {
final Object old = map.put( original, copy );
if ( old != null ) {
throw new IllegalArgumentException( "Already registered a copy: " + old );
}
return copy;
}

@SuppressWarnings("unchecked")
private <T extends SqmPath<?>> T getPathCopy(T original) {
T existing = (T) map.get( original );
if ( existing != null ) {
return existing;
}

SqmPath<?> root = getRoot( original );
if ( root != original ) {
root.copy( this );
// root path might have already copied original
return (T) map.get( original );
}
else {
return null;
}
}

private SqmPath<?> getRoot(SqmPath<?> path) {
if ( path.getLhs() != null ) {
return getRoot( path.getLhs() );
}
else {
return path;
}
}
};
return new SimpleSqmCopyContext();
}

static SqmCopyContext noParamCopyContext() {
final IdentityHashMap<Object, Object> map = new IdentityHashMap<>();
return new SqmCopyContext() {
@Override
@SuppressWarnings("unchecked")
public <T> T getCopy(T original) {
if ( original instanceof SqmParameter ) {
return original;
}
if (original instanceof SqmPath) {
return (T) getPathCopy( (SqmPath<?>) original );
}
else {
return (T) map.get( original );
}
}

@Override
public <T> T registerCopy(T original, T copy) {
final Object old = map.put( original, copy );
if ( old != null ) {
throw new IllegalArgumentException( "Already registered a copy: " + old );
}
return copy;
}

@SuppressWarnings("unchecked")
private <T extends SqmPath<?>> T getPathCopy(T original) {
T existing = (T) map.get( original );
if ( existing != null ) {
return existing;
}

SqmPath<?> root = getRoot( original );
if ( root != original ) {
root.copy( this );
// root path might have already copied original
return (T) map.get( original );
}
else {
return null;
}
}

private SqmPath<?> getRoot(SqmPath<?> path) {
if ( path.getLhs() != null ) {
return getRoot( path.getLhs() );
}
else {
return path;
}
}
};
return new NoParamSqmCopyContext();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
import java.util.Map;
import java.util.function.Consumer;

import org.hibernate.internal.util.NullnessUtil;
import org.hibernate.metamodel.mapping.CollectionPart;
import org.hibernate.metamodel.mapping.EntityDiscriminatorMapping;
import org.hibernate.metamodel.model.domain.DomainType;
import org.hibernate.metamodel.model.domain.EntityDomainType;
Expand Down Expand Up @@ -56,6 +58,8 @@ protected AbstractSqmPath(
}

protected void copyTo(AbstractSqmPath<T> target, SqmCopyContext context) {
assert lhs == null || lhs.getNavigablePath() == target.getLhs().getNavigablePath()
|| getRoot( lhs ).getNodeType() instanceof SqmPolymorphicRootDescriptor;
super.copyTo( target, context );
if ( reusablePaths != null ) {
target.reusablePaths = new HashMap<>( reusablePaths.size() );
Expand All @@ -65,6 +69,10 @@ protected void copyTo(AbstractSqmPath<T> target, SqmCopyContext context) {
}
}

private SqmPath<?> getRoot(SqmPath<?> lhs) {
return lhs.getLhs() == null ? lhs : getRoot( lhs.getLhs() );
}

@Override
public SqmPathSource<T> getNodeType() {
return (SqmPathSource<T>) super.getNodeType();
Expand Down Expand Up @@ -212,6 +220,28 @@ protected <S extends T> SqmTreatedPath<T, S> getTreatedPath(EntityDomainType<S>
return path;
}

/**
* Utility that checks if this path's parent navigable path is compatible with the specified SQM parent,
* and if not creates a copy of the navigable path with the correct parent.
*/
protected NavigablePath getNavigablePathCopy(SqmPath<?> parent) {
final NavigablePath parentNavigablePath = NullnessUtil.castNonNull( navigablePath.getRealParent() );
if ( parent.getNavigablePath() == parentNavigablePath ) {
return navigablePath;
}
else if ( CollectionPart.Nature.fromNameExact( parentNavigablePath.getLocalName() ) != null ) {
if ( parent.getNavigablePath() == parentNavigablePath.getRealParent() ) {
return navigablePath;
}
else {
return parent.getNavigablePath()
.append( parentNavigablePath.getLocalName() )
.append( navigablePath.getLocalName(), navigablePath.getAlias() );
}
}
return parent.getNavigablePath().append( navigablePath.getLocalName(), navigablePath.getAlias() );
}

@Override
@SuppressWarnings("unchecked")
public <Y> SqmPath<Y> get(SingularAttribute<? super T, Y> jpaAttribute) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,13 @@ public NonAggregatedCompositeSimplePath<T> copy(SqmCopyContext context) {
return existing;
}

final SqmPath<?> lhsCopy = getLhs().copy( context );
final NonAggregatedCompositeSimplePath<T> path = context.registerCopy(
this,
new NonAggregatedCompositeSimplePath<>(
getNavigablePath(),
getNavigablePathCopy( lhsCopy ),
getReferencedPathSource(),
getLhs().copy( context ),
lhsCopy,
nodeBuilder()
)
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,13 @@ public SqmAnyValuedSimplePath<T> copy(SqmCopyContext context) {
return existing;
}

final SqmPath<?> lhsCopy = getLhs().copy( context );
final SqmAnyValuedSimplePath<T> path = context.registerCopy(
this,
new SqmAnyValuedSimplePath<>(
getNavigablePath(),
getNavigablePathCopy( lhsCopy ),
getReferencedPathSource(),
getLhs().copy( context ),
lhsCopy,
getExplicitAlias(),
nodeBuilder()
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,11 +56,12 @@ public SqmBagJoin<O, E> copy(SqmCopyContext context) {
if ( existing != null ) {
return existing;
}
final SqmFrom<?, O> lhsCopy = getLhs().copy( context );
final SqmBagJoin<O, E> path = context.registerCopy(
this,
new SqmBagJoin<>(
getLhs().copy( context ),
getNavigablePath(),
lhsCopy,
getNavigablePathCopy( lhsCopy ),
getAttribute(),
getExplicitAlias(),
getSqmJoinType(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,13 @@ public SqmBasicValuedSimplePath<T> copy(SqmCopyContext context) {
return existing;
}

final SqmPath<?> lhsCopy = getLhs().copy( context );
final SqmBasicValuedSimplePath<T> path = context.registerCopy(
this,
new SqmBasicValuedSimplePath<>(
getNavigablePath(),
getNavigablePathCopy( lhsCopy ),
getReferencedPathSource(),
getLhs().copy( context ),
lhsCopy,
getExplicitAlias(),
nodeBuilder()
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,12 +59,13 @@ public SqmEmbeddedValuedSimplePath<T> copy(SqmCopyContext context) {
return existing;
}

final SqmPath<?> lhsCopy = getLhs().copy( context );
final SqmEmbeddedValuedSimplePath<T> path = context.registerCopy(
this,
new SqmEmbeddedValuedSimplePath<>(
getNavigablePath(),
getNavigablePathCopy( lhsCopy ),
getReferencedPathSource(),
getLhs().copy( context ),
lhsCopy,
getExplicitAlias(),
nodeBuilder()
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,13 @@ public SqmEntityValuedSimplePath<T> copy(SqmCopyContext context) {
return existing;
}

final SqmPath<?> lhsCopy = getLhs().copy( context );
final SqmEntityValuedSimplePath<T> path = context.registerCopy(
this,
new SqmEntityValuedSimplePath<>(
getNavigablePath(),
getNavigablePathCopy( lhsCopy ),
getReferencedPathSource(),
getLhs().copy( context ),
lhsCopy,
nodeBuilder()
)
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,12 @@ public SqmIndexedCollectionAccessPath<T> copy(SqmCopyContext context) {
return existing;
}

final SqmPath<?> lhsCopy = getLhs().copy( context );
final SqmIndexedCollectionAccessPath<T> path = context.registerCopy(
this,
new SqmIndexedCollectionAccessPath<T>(
getNavigablePath(),
getLhs().copy( context ),
getNavigablePathCopy( lhsCopy ),
lhsCopy,
selectorExpression.copy( context )
)
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,11 +59,12 @@ public SqmListJoin<O, E> copy(SqmCopyContext context) {
if ( existing != null ) {
return existing;
}
final SqmFrom<?, O> lhsCopy = getLhs().copy( context );
final SqmListJoin<O, E> path = context.registerCopy(
this,
new SqmListJoin<>(
getLhs().copy( context ),
getNavigablePath(),
lhsCopy,
getNavigablePathCopy( lhsCopy ),
getAttribute(),
getExplicitAlias(),
getSqmJoinType(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,12 @@ public SqmMapJoin<O, K, V> copy(SqmCopyContext context) {
if ( existing != null ) {
return existing;
}
final SqmFrom<?, O> lhsCopy = getLhs().copy( context );
final SqmMapJoin<O, K, V> path = context.registerCopy(
this,
new SqmMapJoin<>(
getLhs().copy( context ),
getNavigablePath(),
lhsCopy,
getNavigablePathCopy( lhsCopy ),
getAttribute(),
getExplicitAlias(),
getSqmJoinType(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,11 +64,12 @@ public SqmPluralPartJoin<O, T> copy(SqmCopyContext context) {
if ( existing != null ) {
return existing;
}
final SqmFrom<?, O> lhsCopy = (SqmFrom<?, O>) getLhs().copy( context );
final SqmPluralPartJoin<O, T> path = context.registerCopy(
this,
new SqmPluralPartJoin<>(
(SqmFrom<?, O>) getLhs().copy( context ),
getNavigablePath(),
lhsCopy,
getNavigablePathCopy( lhsCopy ),
getReferencedPathSource(),
getExplicitAlias(),
getSqmJoinType(),
Expand Down

0 comments on commit c06d605

Please sign in to comment.