mirror of
https://github.com/hibernate/hibernate-orm
synced 2025-02-18 00:55:16 +00:00
Introduce QueryTransformer for functions
This commit is contained in:
parent
c2ee076ce6
commit
f52cf04a16
@ -21,6 +21,8 @@
|
|||||||
import org.hibernate.query.sqm.tree.predicate.SqmPredicate;
|
import org.hibernate.query.sqm.tree.predicate.SqmPredicate;
|
||||||
import org.hibernate.query.sqm.tree.select.SqmSelectableNode;
|
import org.hibernate.query.sqm.tree.select.SqmSelectableNode;
|
||||||
import org.hibernate.sql.ast.tree.SqlAstNode;
|
import org.hibernate.sql.ast.tree.SqlAstNode;
|
||||||
|
import org.hibernate.sql.ast.tree.expression.Expression;
|
||||||
|
import org.hibernate.sql.ast.tree.predicate.Predicate;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Christian Beikov
|
* @author Christian Beikov
|
||||||
@ -73,7 +75,7 @@ public SelfRenderingSqmAggregateFunction<T> copy(SqmCopyContext context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SelfRenderingFunctionSqlAstExpression convertToSqlAst(SqmToSqlAstConverter walker) {
|
public Expression convertToSqlAst(SqmToSqlAstConverter walker) {
|
||||||
final ReturnableType<?> resultType = resolveResultType(
|
final ReturnableType<?> resultType = resolveResultType(
|
||||||
walker.getCreationContext().getMappingMetamodel().getTypeConfiguration()
|
walker.getCreationContext().getMappingMetamodel().getTypeConfiguration()
|
||||||
);
|
);
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
import org.hibernate.query.sqm.tree.SqmVisitableNode;
|
import org.hibernate.query.sqm.tree.SqmVisitableNode;
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmFunction;
|
import org.hibernate.query.sqm.tree.expression.SqmFunction;
|
||||||
import org.hibernate.sql.ast.tree.SqlAstNode;
|
import org.hibernate.sql.ast.tree.SqlAstNode;
|
||||||
|
import org.hibernate.sql.ast.tree.expression.Expression;
|
||||||
import org.hibernate.type.spi.TypeConfiguration;
|
import org.hibernate.type.spi.TypeConfiguration;
|
||||||
|
|
||||||
import static java.util.Collections.emptyList;
|
import static java.util.Collections.emptyList;
|
||||||
@ -109,7 +110,7 @@ protected static List<SqlAstNode> resolveSqlAstArguments(List<? extends SqmTyped
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SelfRenderingFunctionSqlAstExpression convertToSqlAst(SqmToSqlAstConverter walker) {
|
public Expression convertToSqlAst(SqmToSqlAstConverter walker) {
|
||||||
final ReturnableType<?> resultType = resolveResultType(
|
final ReturnableType<?> resultType = resolveResultType(
|
||||||
walker.getCreationContext().getMappingMetamodel().getTypeConfiguration()
|
walker.getCreationContext().getMappingMetamodel().getTypeConfiguration()
|
||||||
);
|
);
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
import org.hibernate.query.sqm.tree.select.SqmSortSpecification;
|
import org.hibernate.query.sqm.tree.select.SqmSortSpecification;
|
||||||
import org.hibernate.sql.ast.Clause;
|
import org.hibernate.sql.ast.Clause;
|
||||||
import org.hibernate.sql.ast.tree.SqlAstNode;
|
import org.hibernate.sql.ast.tree.SqlAstNode;
|
||||||
|
import org.hibernate.sql.ast.tree.expression.Expression;
|
||||||
import org.hibernate.sql.ast.tree.predicate.Predicate;
|
import org.hibernate.sql.ast.tree.predicate.Predicate;
|
||||||
import org.hibernate.sql.ast.tree.select.SortSpecification;
|
import org.hibernate.sql.ast.tree.select.SortSpecification;
|
||||||
|
|
||||||
@ -91,7 +92,7 @@ public SelfRenderingSqmOrderedSetAggregateFunction<T> copy(SqmCopyContext contex
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SelfRenderingFunctionSqlAstExpression convertToSqlAst(SqmToSqlAstConverter walker) {
|
public Expression convertToSqlAst(SqmToSqlAstConverter walker) {
|
||||||
final ReturnableType<?> resultType = resolveResultType(
|
final ReturnableType<?> resultType = resolveResultType(
|
||||||
walker.getCreationContext().getMappingMetamodel().getTypeConfiguration()
|
walker.getCreationContext().getMappingMetamodel().getTypeConfiguration()
|
||||||
);
|
);
|
||||||
|
@ -95,28 +95,28 @@
|
|||||||
import org.hibernate.persister.entity.EntityPersister;
|
import org.hibernate.persister.entity.EntityPersister;
|
||||||
import org.hibernate.persister.entity.Joinable;
|
import org.hibernate.persister.entity.Joinable;
|
||||||
import org.hibernate.persister.entity.SingleTableEntityPersister;
|
import org.hibernate.persister.entity.SingleTableEntityPersister;
|
||||||
import org.hibernate.query.sqm.BinaryArithmeticOperator;
|
|
||||||
import org.hibernate.query.BindableType;
|
import org.hibernate.query.BindableType;
|
||||||
import org.hibernate.query.sqm.CastType;
|
|
||||||
import org.hibernate.query.sqm.ComparisonOperator;
|
|
||||||
import org.hibernate.query.sqm.DynamicInstantiationNature;
|
|
||||||
import org.hibernate.query.sqm.FetchClauseType;
|
|
||||||
import org.hibernate.query.spi.NavigablePath;
|
|
||||||
import org.hibernate.query.QueryLogging;
|
import org.hibernate.query.QueryLogging;
|
||||||
import org.hibernate.query.ReturnableType;
|
import org.hibernate.query.ReturnableType;
|
||||||
import org.hibernate.query.SemanticException;
|
import org.hibernate.query.SemanticException;
|
||||||
import org.hibernate.query.sqm.SortOrder;
|
|
||||||
import org.hibernate.query.sqm.TemporalUnit;
|
|
||||||
import org.hibernate.query.sqm.UnaryArithmeticOperator;
|
|
||||||
import org.hibernate.query.criteria.JpaPath;
|
import org.hibernate.query.criteria.JpaPath;
|
||||||
|
import org.hibernate.query.spi.NavigablePath;
|
||||||
import org.hibernate.query.spi.QueryOptions;
|
import org.hibernate.query.spi.QueryOptions;
|
||||||
import org.hibernate.query.spi.QueryParameterBinding;
|
import org.hibernate.query.spi.QueryParameterBinding;
|
||||||
import org.hibernate.query.spi.QueryParameterBindings;
|
import org.hibernate.query.spi.QueryParameterBindings;
|
||||||
import org.hibernate.query.spi.QueryParameterImplementor;
|
import org.hibernate.query.spi.QueryParameterImplementor;
|
||||||
|
import org.hibernate.query.sqm.BinaryArithmeticOperator;
|
||||||
|
import org.hibernate.query.sqm.CastType;
|
||||||
|
import org.hibernate.query.sqm.ComparisonOperator;
|
||||||
|
import org.hibernate.query.sqm.DynamicInstantiationNature;
|
||||||
|
import org.hibernate.query.sqm.FetchClauseType;
|
||||||
import org.hibernate.query.sqm.InterpretationException;
|
import org.hibernate.query.sqm.InterpretationException;
|
||||||
|
import org.hibernate.query.sqm.SortOrder;
|
||||||
import org.hibernate.query.sqm.SqmExpressible;
|
import org.hibernate.query.sqm.SqmExpressible;
|
||||||
import org.hibernate.query.sqm.SqmPathSource;
|
import org.hibernate.query.sqm.SqmPathSource;
|
||||||
import org.hibernate.query.sqm.SqmQuerySource;
|
import org.hibernate.query.sqm.SqmQuerySource;
|
||||||
|
import org.hibernate.query.sqm.TemporalUnit;
|
||||||
|
import org.hibernate.query.sqm.UnaryArithmeticOperator;
|
||||||
import org.hibernate.query.sqm.function.AbstractSqmSelfRenderingFunctionDescriptor;
|
import org.hibernate.query.sqm.function.AbstractSqmSelfRenderingFunctionDescriptor;
|
||||||
import org.hibernate.query.sqm.function.SelfRenderingAggregateFunctionSqlAstExpression;
|
import org.hibernate.query.sqm.function.SelfRenderingAggregateFunctionSqlAstExpression;
|
||||||
import org.hibernate.query.sqm.function.SelfRenderingFunctionSqlAstExpression;
|
import org.hibernate.query.sqm.function.SelfRenderingFunctionSqlAstExpression;
|
||||||
@ -262,6 +262,7 @@
|
|||||||
import org.hibernate.sql.ast.tree.SqlAstNode;
|
import org.hibernate.sql.ast.tree.SqlAstNode;
|
||||||
import org.hibernate.sql.ast.tree.Statement;
|
import org.hibernate.sql.ast.tree.Statement;
|
||||||
import org.hibernate.sql.ast.tree.cte.CteColumn;
|
import org.hibernate.sql.ast.tree.cte.CteColumn;
|
||||||
|
import org.hibernate.sql.ast.tree.cte.CteContainer;
|
||||||
import org.hibernate.sql.ast.tree.cte.CteStatement;
|
import org.hibernate.sql.ast.tree.cte.CteStatement;
|
||||||
import org.hibernate.sql.ast.tree.cte.CteTable;
|
import org.hibernate.sql.ast.tree.cte.CteTable;
|
||||||
import org.hibernate.sql.ast.tree.cte.SearchClauseSpecification;
|
import org.hibernate.sql.ast.tree.cte.SearchClauseSpecification;
|
||||||
@ -288,6 +289,7 @@
|
|||||||
import org.hibernate.sql.ast.tree.expression.Over;
|
import org.hibernate.sql.ast.tree.expression.Over;
|
||||||
import org.hibernate.sql.ast.tree.expression.Overflow;
|
import org.hibernate.sql.ast.tree.expression.Overflow;
|
||||||
import org.hibernate.sql.ast.tree.expression.QueryLiteral;
|
import org.hibernate.sql.ast.tree.expression.QueryLiteral;
|
||||||
|
import org.hibernate.sql.ast.tree.expression.QueryTransformer;
|
||||||
import org.hibernate.sql.ast.tree.expression.SelfRenderingExpression;
|
import org.hibernate.sql.ast.tree.expression.SelfRenderingExpression;
|
||||||
import org.hibernate.sql.ast.tree.expression.SelfRenderingSqlFragmentExpression;
|
import org.hibernate.sql.ast.tree.expression.SelfRenderingSqlFragmentExpression;
|
||||||
import org.hibernate.sql.ast.tree.expression.SqlSelectionExpression;
|
import org.hibernate.sql.ast.tree.expression.SqlSelectionExpression;
|
||||||
@ -385,6 +387,7 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
|
|||||||
private final SqlAstCreationContext creationContext;
|
private final SqlAstCreationContext creationContext;
|
||||||
private final boolean jpaQueryComplianceEnabled;
|
private final boolean jpaQueryComplianceEnabled;
|
||||||
private final SqmStatement<?> statement;
|
private final SqmStatement<?> statement;
|
||||||
|
private final CteContainer cteContainer = new GlobalCteContainer();
|
||||||
|
|
||||||
private final QueryOptions queryOptions;
|
private final QueryOptions queryOptions;
|
||||||
private final LoadQueryInfluencers loadQueryInfluencers;
|
private final LoadQueryInfluencers loadQueryInfluencers;
|
||||||
@ -430,6 +433,7 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
|
|||||||
private final Stack<Supplier<MappingModelExpressible<?>>> inferrableTypeAccessStack = new StandardStack<>(
|
private final Stack<Supplier<MappingModelExpressible<?>>> inferrableTypeAccessStack = new StandardStack<>(
|
||||||
() -> null
|
() -> null
|
||||||
);
|
);
|
||||||
|
private final Stack<List<QueryTransformer>> queryTransformers = new StandardStack<>();
|
||||||
private boolean inTypeInference;
|
private boolean inTypeInference;
|
||||||
|
|
||||||
private SqmByUnit appliedByUnit;
|
private SqmByUnit appliedByUnit;
|
||||||
@ -659,7 +663,7 @@ public Statement visitStatement(SqmStatement<?> sqmStatement) {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public UpdateStatement visitUpdateStatement(SqmUpdateStatement<?> sqmStatement) {
|
public UpdateStatement visitUpdateStatement(SqmUpdateStatement<?> sqmStatement) {
|
||||||
Map<String, CteStatement> cteStatements = this.visitCteContainer( sqmStatement );
|
final CteContainer cteContainer = this.visitCteContainer( sqmStatement );
|
||||||
|
|
||||||
final SqmRoot<?> sqmTarget = sqmStatement.getTarget();
|
final SqmRoot<?> sqmTarget = sqmStatement.getTarget();
|
||||||
final String entityName = sqmTarget.getEntityName();
|
final String entityName = sqmTarget.getEntityName();
|
||||||
@ -719,7 +723,7 @@ public UpdateStatement visitUpdateStatement(SqmUpdateStatement<?> sqmStatement)
|
|||||||
}
|
}
|
||||||
|
|
||||||
return new UpdateStatement(
|
return new UpdateStatement(
|
||||||
sqmStatement.isWithRecursive(), cteStatements,
|
cteContainer,
|
||||||
(NamedTableReference) rootTableGroup.getPrimaryTableReference(),
|
(NamedTableReference) rootTableGroup.getPrimaryTableReference(),
|
||||||
assignments,
|
assignments,
|
||||||
SqlAstTreeHelper.combinePredicates( suppliedPredicate, additionalRestrictions ),
|
SqlAstTreeHelper.combinePredicates( suppliedPredicate, additionalRestrictions ),
|
||||||
@ -897,7 +901,7 @@ public Expression resolveSqlExpression(
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DeleteStatement visitDeleteStatement(SqmDeleteStatement<?> statement) {
|
public DeleteStatement visitDeleteStatement(SqmDeleteStatement<?> statement) {
|
||||||
Map<String, CteStatement> cteStatements = this.visitCteContainer( statement );
|
final CteContainer cteContainer = this.visitCteContainer( statement );
|
||||||
|
|
||||||
final String entityName = statement.getTarget().getEntityName();
|
final String entityName = statement.getTarget().getEntityName();
|
||||||
final EntityPersister entityDescriptor = creationContext.getSessionFactory()
|
final EntityPersister entityDescriptor = creationContext.getSessionFactory()
|
||||||
@ -947,8 +951,7 @@ public DeleteStatement visitDeleteStatement(SqmDeleteStatement<?> statement) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return new DeleteStatement(
|
return new DeleteStatement(
|
||||||
statement.isWithRecursive(),
|
cteContainer,
|
||||||
cteStatements,
|
|
||||||
(NamedTableReference) rootTableGroup.getPrimaryTableReference(),
|
(NamedTableReference) rootTableGroup.getPrimaryTableReference(),
|
||||||
SqlAstTreeHelper.combinePredicates( suppliedPredicate, additionalRestrictions ),
|
SqlAstTreeHelper.combinePredicates( suppliedPredicate, additionalRestrictions ),
|
||||||
Collections.emptyList()
|
Collections.emptyList()
|
||||||
@ -964,7 +967,7 @@ public DeleteStatement visitDeleteStatement(SqmDeleteStatement<?> statement) {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public InsertStatement visitInsertSelectStatement(SqmInsertSelectStatement<?> sqmStatement) {
|
public InsertStatement visitInsertSelectStatement(SqmInsertSelectStatement<?> sqmStatement) {
|
||||||
Map<String, CteStatement> cteStatements = this.visitCteContainer( sqmStatement );
|
final CteContainer cteContainer = this.visitCteContainer( sqmStatement );
|
||||||
|
|
||||||
final String entityName = sqmStatement.getTarget().getEntityName();
|
final String entityName = sqmStatement.getTarget().getEntityName();
|
||||||
final EntityPersister entityDescriptor = creationContext.getSessionFactory()
|
final EntityPersister entityDescriptor = creationContext.getSessionFactory()
|
||||||
@ -1005,8 +1008,7 @@ public InsertStatement visitInsertSelectStatement(SqmInsertSelectStatement<?> sq
|
|||||||
getFromClauseAccess().registerTableGroup( rootPath, rootTableGroup );
|
getFromClauseAccess().registerTableGroup( rootPath, rootTableGroup );
|
||||||
|
|
||||||
insertStatement = new InsertStatement(
|
insertStatement = new InsertStatement(
|
||||||
sqmStatement.isWithRecursive(),
|
cteContainer,
|
||||||
cteStatements,
|
|
||||||
(NamedTableReference) rootTableGroup.getPrimaryTableReference(),
|
(NamedTableReference) rootTableGroup.getPrimaryTableReference(),
|
||||||
Collections.emptyList()
|
Collections.emptyList()
|
||||||
);
|
);
|
||||||
@ -1051,7 +1053,7 @@ public InsertStatement visitInsertSelectStatement(SqmInsertSelectStatement<?> sq
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public InsertStatement visitInsertValuesStatement(SqmInsertValuesStatement<?> sqmStatement) {
|
public InsertStatement visitInsertValuesStatement(SqmInsertValuesStatement<?> sqmStatement) {
|
||||||
Map<String, CteStatement> cteStatements = this.visitCteContainer( sqmStatement );
|
final CteContainer cteContainer = this.visitCteContainer( sqmStatement );
|
||||||
final String entityName = sqmStatement.getTarget().getEntityName();
|
final String entityName = sqmStatement.getTarget().getEntityName();
|
||||||
final EntityPersister entityDescriptor = creationContext.getSessionFactory()
|
final EntityPersister entityDescriptor = creationContext.getSessionFactory()
|
||||||
.getRuntimeMetamodels()
|
.getRuntimeMetamodels()
|
||||||
@ -1087,8 +1089,7 @@ public InsertStatement visitInsertValuesStatement(SqmInsertValuesStatement<?> sq
|
|||||||
getFromClauseAccess().registerTableGroup( rootPath, rootTableGroup );
|
getFromClauseAccess().registerTableGroup( rootPath, rootTableGroup );
|
||||||
|
|
||||||
final InsertStatement insertStatement = new InsertStatement(
|
final InsertStatement insertStatement = new InsertStatement(
|
||||||
sqmStatement.isWithRecursive(),
|
cteContainer,
|
||||||
cteStatements,
|
|
||||||
(NamedTableReference) rootTableGroup.getPrimaryTableReference(),
|
(NamedTableReference) rootTableGroup.getPrimaryTableReference(),
|
||||||
Collections.emptyList()
|
Collections.emptyList()
|
||||||
);
|
);
|
||||||
@ -1371,10 +1372,10 @@ public Values visitValues(SqmValues sqmValues) {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SelectStatement visitSelectStatement(SqmSelectStatement<?> statement) {
|
public SelectStatement visitSelectStatement(SqmSelectStatement<?> statement) {
|
||||||
Map<String, CteStatement> cteStatements = this.visitCteContainer( statement );
|
final CteContainer cteContainer = this.visitCteContainer( statement );
|
||||||
final QueryPart queryPart = visitQueryPart( statement.getQueryPart() );
|
final QueryPart queryPart = visitQueryPart( statement.getQueryPart() );
|
||||||
final List<DomainResult<?>> domainResults = queryPart.isRoot() ? this.domainResults : Collections.emptyList();
|
final List<DomainResult<?>> domainResults = queryPart.isRoot() ? this.domainResults : Collections.emptyList();
|
||||||
return new SelectStatement( statement.isWithRecursive(), cteStatements, queryPart, domainResults );
|
return new SelectStatement( cteContainer, queryPart, domainResults );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -1560,14 +1561,15 @@ public static CteTable createCteTable(
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<String, CteStatement> visitCteContainer(SqmCteContainer consumer) {
|
public CteContainer visitCteContainer(SqmCteContainer consumer) {
|
||||||
final Collection<SqmCteStatement<?>> sqmCteStatements = consumer.getCteStatements();
|
final Collection<SqmCteStatement<?>> sqmCteStatements = consumer.getCteStatements();
|
||||||
final Map<String, CteStatement> cteStatements = new LinkedHashMap<>( sqmCteStatements.size() );
|
if ( consumer.isWithRecursive() ) {
|
||||||
for ( SqmCteStatement<?> sqmCteStatement : sqmCteStatements ) {
|
cteContainer.setWithRecursive( true );
|
||||||
final CteStatement cteStatement = visitCteStatement( sqmCteStatement );
|
|
||||||
cteStatements.put( cteStatement.getCteTable().getTableExpression(), cteStatement );
|
|
||||||
}
|
}
|
||||||
return cteStatements;
|
for ( SqmCteStatement<?> sqmCteStatement : sqmCteStatements ) {
|
||||||
|
cteContainer.addCteStatement( visitCteStatement( sqmCteStatement ) );
|
||||||
|
}
|
||||||
|
return cteContainer;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean trackSelectionsForGroup;
|
private boolean trackSelectionsForGroup;
|
||||||
@ -1688,6 +1690,7 @@ else if ( sqmQuerySpec.hasPositionalGroupItem() ) {
|
|||||||
// In sub-queries, we can never deduplicate the selection items as that might change semantics
|
// In sub-queries, we can never deduplicate the selection items as that might change semantics
|
||||||
deduplicateSelectionItems = false;
|
deduplicateSelectionItems = false;
|
||||||
pushProcessingState( processingState );
|
pushProcessingState( processingState );
|
||||||
|
queryTransformers.push( new ArrayList<>() );
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// we want to visit the from-clause first
|
// we want to visit the from-clause first
|
||||||
@ -1721,7 +1724,15 @@ else if ( sqmQuerySpec.hasPositionalGroupItem() ) {
|
|||||||
applyCollectionFilterPredicates( sqlQuerySpec );
|
applyCollectionFilterPredicates( sqlQuerySpec );
|
||||||
}
|
}
|
||||||
|
|
||||||
return sqlQuerySpec;
|
QuerySpec finalQuerySpec = sqlQuerySpec;
|
||||||
|
for ( QueryTransformer transformer : queryTransformers.getCurrent() ) {
|
||||||
|
finalQuerySpec = transformer.transform(
|
||||||
|
cteContainer,
|
||||||
|
finalQuerySpec,
|
||||||
|
this
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return finalQuerySpec;
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
if ( additionalRestrictions != null ) {
|
if ( additionalRestrictions != null ) {
|
||||||
@ -1729,6 +1740,7 @@ else if ( sqmQuerySpec.hasPositionalGroupItem() ) {
|
|||||||
}
|
}
|
||||||
additionalRestrictions = originalAdditionalRestrictions;
|
additionalRestrictions = originalAdditionalRestrictions;
|
||||||
popProcessingStateStack();
|
popProcessingStateStack();
|
||||||
|
queryTransformers.pop();
|
||||||
currentSqmQueryPart = sqmQueryPart;
|
currentSqmQueryPart = sqmQueryPart;
|
||||||
deduplicateSelectionItems = originalDeduplicateSelectionItems;
|
deduplicateSelectionItems = originalDeduplicateSelectionItems;
|
||||||
}
|
}
|
||||||
@ -4738,6 +4750,11 @@ public Expression visitFunction(SqmFunction<?> sqmFunction) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void registerQueryTransformer(QueryTransformer transformer) {
|
||||||
|
queryTransformers.getCurrent().add( transformer );
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Star visitStar(SqmStar sqmStar) {
|
public Star visitStar(SqmStar sqmStar) {
|
||||||
return new Star();
|
return new Star();
|
||||||
@ -6564,4 +6581,38 @@ private static JdbcMappingContainer highestPrecedence(JdbcMappingContainer type1
|
|||||||
|
|
||||||
return type1;
|
return type1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class GlobalCteContainer implements CteContainer {
|
||||||
|
private final Map<String, CteStatement> cteStatements;
|
||||||
|
private boolean recursive;
|
||||||
|
|
||||||
|
public GlobalCteContainer() {
|
||||||
|
this.cteStatements = new LinkedHashMap<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isWithRecursive() {
|
||||||
|
return recursive;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setWithRecursive(boolean recursive) {
|
||||||
|
this.recursive = recursive;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, CteStatement> getCteStatements() {
|
||||||
|
return cteStatements;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CteStatement getCteStatement(String cteLabel) {
|
||||||
|
return cteStatements.get( cteLabel );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addCteStatement(CteStatement cteStatement) {
|
||||||
|
cteStatements.put( cteStatement.getCteTable().getTableExpression(), cteStatement );
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
import org.hibernate.sql.ast.spi.SqlAstProcessingState;
|
import org.hibernate.sql.ast.spi.SqlAstProcessingState;
|
||||||
import org.hibernate.sql.ast.spi.SqlExpressionResolver;
|
import org.hibernate.sql.ast.spi.SqlExpressionResolver;
|
||||||
import org.hibernate.sql.ast.tree.expression.Expression;
|
import org.hibernate.sql.ast.tree.expression.Expression;
|
||||||
|
import org.hibernate.sql.ast.tree.expression.QueryTransformer;
|
||||||
import org.hibernate.sql.ast.tree.predicate.Predicate;
|
import org.hibernate.sql.ast.tree.predicate.Predicate;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -75,6 +76,10 @@ public Stack<Clause> getCurrentClauseStack() {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void registerQueryTransformer(QueryTransformer transformer) {
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<Expression> expandSelfRenderingFunctionMultiValueParameter(SqmParameter<?> sqmParameter) {
|
public List<Expression> expandSelfRenderingFunctionMultiValueParameter(SqmParameter<?> sqmParameter) {
|
||||||
return null;
|
return null;
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
import org.hibernate.sql.ast.spi.SqlAstCreationState;
|
import org.hibernate.sql.ast.spi.SqlAstCreationState;
|
||||||
import org.hibernate.sql.ast.Clause;
|
import org.hibernate.sql.ast.Clause;
|
||||||
import org.hibernate.sql.ast.tree.expression.Expression;
|
import org.hibernate.sql.ast.tree.expression.Expression;
|
||||||
|
import org.hibernate.sql.ast.tree.expression.QueryTransformer;
|
||||||
import org.hibernate.sql.ast.tree.predicate.Predicate;
|
import org.hibernate.sql.ast.tree.predicate.Predicate;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -25,6 +26,8 @@
|
|||||||
public interface SqmToSqlAstConverter extends SemanticQueryWalker<Object>, SqlAstCreationState {
|
public interface SqmToSqlAstConverter extends SemanticQueryWalker<Object>, SqlAstCreationState {
|
||||||
Stack<Clause> getCurrentClauseStack();
|
Stack<Clause> getCurrentClauseStack();
|
||||||
|
|
||||||
|
void registerQueryTransformer(QueryTransformer transformer);
|
||||||
|
|
||||||
List<Expression> expandSelfRenderingFunctionMultiValueParameter(SqmParameter<?> sqmParameter);
|
List<Expression> expandSelfRenderingFunctionMultiValueParameter(SqmParameter<?> sqmParameter);
|
||||||
|
|
||||||
Predicate visitNestedTopLevelPredicate(SqmPredicate predicate);
|
Predicate visitNestedTopLevelPredicate(SqmPredicate predicate);
|
||||||
|
@ -1313,7 +1313,7 @@ protected void visitReturningColumns(MutationStatement mutationStatement) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void visitCteContainer(CteContainer cteContainer) {
|
public void visitCteContainer(CteContainer cteContainer) {
|
||||||
final Collection<CteStatement> cteStatements = cteContainer.getCteStatements();
|
final Collection<CteStatement> cteStatements = cteContainer.getCteStatements().values();
|
||||||
if ( cteStatements.isEmpty() ) {
|
if ( cteStatements.isEmpty() ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -250,7 +250,7 @@ public void visitOver(Over over) {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visitSelectStatement(SelectStatement statement) {
|
public void visitSelectStatement(SelectStatement statement) {
|
||||||
for ( CteStatement cteStatement : statement.getCteStatements() ) {
|
for ( CteStatement cteStatement : statement.getCteStatements().values() ) {
|
||||||
cteStatement.getCteDefinition().accept( this );
|
cteStatement.getCteDefinition().accept( this );
|
||||||
}
|
}
|
||||||
statement.getQueryPart().accept( this );
|
statement.getQueryPart().accept( this );
|
||||||
@ -258,7 +258,7 @@ public void visitSelectStatement(SelectStatement statement) {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visitDeleteStatement(DeleteStatement statement) {
|
public void visitDeleteStatement(DeleteStatement statement) {
|
||||||
for ( CteStatement cteStatement : statement.getCteStatements() ) {
|
for ( CteStatement cteStatement : statement.getCteStatements().values() ) {
|
||||||
cteStatement.getCteDefinition().accept( this );
|
cteStatement.getCteDefinition().accept( this );
|
||||||
}
|
}
|
||||||
statement.getRestriction().accept( this );
|
statement.getRestriction().accept( this );
|
||||||
@ -266,7 +266,7 @@ public void visitDeleteStatement(DeleteStatement statement) {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visitUpdateStatement(UpdateStatement statement) {
|
public void visitUpdateStatement(UpdateStatement statement) {
|
||||||
for ( CteStatement cteStatement : statement.getCteStatements() ) {
|
for ( CteStatement cteStatement : statement.getCteStatements().values() ) {
|
||||||
cteStatement.getCteDefinition().accept( this );
|
cteStatement.getCteDefinition().accept( this );
|
||||||
}
|
}
|
||||||
for ( Assignment assignment : statement.getAssignments() ) {
|
for ( Assignment assignment : statement.getAssignments() ) {
|
||||||
@ -277,7 +277,7 @@ public void visitUpdateStatement(UpdateStatement statement) {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visitInsertStatement(InsertStatement statement) {
|
public void visitInsertStatement(InsertStatement statement) {
|
||||||
for ( CteStatement cteStatement : statement.getCteStatements() ) {
|
for ( CteStatement cteStatement : statement.getCteStatements().values() ) {
|
||||||
cteStatement.getCteDefinition().accept( this );
|
cteStatement.getCteDefinition().accept( this );
|
||||||
}
|
}
|
||||||
if ( statement.getSourceSelectStatement() != null ) {
|
if ( statement.getSourceSelectStatement() != null ) {
|
||||||
|
@ -35,8 +35,8 @@ public void setWithRecursive(boolean withRecursive) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<CteStatement> getCteStatements() {
|
public Map<String, CteStatement> getCteStatements() {
|
||||||
return cteStatements.values();
|
return cteStatements;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.hibernate.sql.ast.tree.cte;
|
package org.hibernate.sql.ast.tree.cte;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The consumer part of a CTE statement - the select or insert or delete or update that uses
|
* The consumer part of a CTE statement - the select or insert or delete or update that uses
|
||||||
@ -21,7 +21,7 @@ public interface CteContainer {
|
|||||||
|
|
||||||
void setWithRecursive(boolean recursive);
|
void setWithRecursive(boolean recursive);
|
||||||
|
|
||||||
Collection<CteStatement> getCteStatements();
|
Map<String, CteStatement> getCteStatements();
|
||||||
|
|
||||||
CteStatement getCteStatement(String cteLabel);
|
CteStatement getCteStatement(String cteLabel);
|
||||||
|
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
import org.hibernate.sql.ast.SqlAstWalker;
|
import org.hibernate.sql.ast.SqlAstWalker;
|
||||||
import org.hibernate.sql.ast.spi.SqlAstHelper;
|
import org.hibernate.sql.ast.spi.SqlAstHelper;
|
||||||
import org.hibernate.sql.ast.tree.AbstractMutationStatement;
|
import org.hibernate.sql.ast.tree.AbstractMutationStatement;
|
||||||
|
import org.hibernate.sql.ast.tree.cte.CteContainer;
|
||||||
import org.hibernate.sql.ast.tree.cte.CteStatement;
|
import org.hibernate.sql.ast.tree.cte.CteStatement;
|
||||||
import org.hibernate.sql.ast.tree.expression.ColumnReference;
|
import org.hibernate.sql.ast.tree.expression.ColumnReference;
|
||||||
import org.hibernate.sql.ast.tree.from.NamedTableReference;
|
import org.hibernate.sql.ast.tree.from.NamedTableReference;
|
||||||
@ -40,6 +41,20 @@ public DeleteStatement(
|
|||||||
this.restriction = restriction;
|
this.restriction = restriction;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public DeleteStatement(
|
||||||
|
CteContainer cteContainer,
|
||||||
|
NamedTableReference targetTable,
|
||||||
|
Predicate restriction,
|
||||||
|
List<ColumnReference> returningColumns) {
|
||||||
|
this(
|
||||||
|
cteContainer.isWithRecursive(),
|
||||||
|
cteContainer.getCteStatements(),
|
||||||
|
targetTable,
|
||||||
|
restriction,
|
||||||
|
returningColumns
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
public DeleteStatement(
|
public DeleteStatement(
|
||||||
boolean withRecursive,
|
boolean withRecursive,
|
||||||
Map<String, CteStatement> cteStatements,
|
Map<String, CteStatement> cteStatements,
|
||||||
|
@ -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.sql.ast.tree.expression;
|
||||||
|
|
||||||
|
import org.hibernate.query.sqm.sql.SqmToSqlAstConverter;
|
||||||
|
import org.hibernate.sql.ast.tree.cte.CteContainer;
|
||||||
|
import org.hibernate.sql.ast.tree.select.QuerySpec;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Christian Beikov
|
||||||
|
*/
|
||||||
|
public interface QueryTransformer {
|
||||||
|
|
||||||
|
QuerySpec transform(
|
||||||
|
CteContainer cteContainer,
|
||||||
|
QuerySpec querySpec,
|
||||||
|
SqmToSqlAstConverter converter);
|
||||||
|
}
|
@ -14,6 +14,7 @@
|
|||||||
|
|
||||||
import org.hibernate.sql.ast.SqlAstWalker;
|
import org.hibernate.sql.ast.SqlAstWalker;
|
||||||
import org.hibernate.sql.ast.tree.AbstractMutationStatement;
|
import org.hibernate.sql.ast.tree.AbstractMutationStatement;
|
||||||
|
import org.hibernate.sql.ast.tree.cte.CteContainer;
|
||||||
import org.hibernate.sql.ast.tree.cte.CteStatement;
|
import org.hibernate.sql.ast.tree.cte.CteStatement;
|
||||||
import org.hibernate.sql.ast.tree.expression.ColumnReference;
|
import org.hibernate.sql.ast.tree.expression.ColumnReference;
|
||||||
import org.hibernate.sql.ast.tree.from.NamedTableReference;
|
import org.hibernate.sql.ast.tree.from.NamedTableReference;
|
||||||
@ -37,7 +38,18 @@ public InsertStatement(NamedTableReference targetTable, List<ColumnReference> re
|
|||||||
super( new LinkedHashMap<>(), targetTable, returningColumns );
|
super( new LinkedHashMap<>(), targetTable, returningColumns );
|
||||||
}
|
}
|
||||||
|
|
||||||
public InsertStatement(boolean withRecursive, Map<String, CteStatement> cteStatements, NamedTableReference targetTable, List<ColumnReference> returningColumns) {
|
public InsertStatement(
|
||||||
|
CteContainer cteContainer,
|
||||||
|
NamedTableReference targetTable,
|
||||||
|
List<ColumnReference> returningColumns) {
|
||||||
|
this( cteContainer.isWithRecursive(), cteContainer.getCteStatements(), targetTable, returningColumns );
|
||||||
|
}
|
||||||
|
|
||||||
|
public InsertStatement(
|
||||||
|
boolean withRecursive,
|
||||||
|
Map<String, CteStatement> cteStatements,
|
||||||
|
NamedTableReference targetTable,
|
||||||
|
List<ColumnReference> returningColumns) {
|
||||||
super( cteStatements, targetTable, returningColumns );
|
super( cteStatements, targetTable, returningColumns );
|
||||||
setWithRecursive( withRecursive );
|
setWithRecursive( withRecursive );
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
|
|
||||||
import org.hibernate.sql.ast.SqlAstWalker;
|
import org.hibernate.sql.ast.SqlAstWalker;
|
||||||
import org.hibernate.sql.ast.tree.AbstractStatement;
|
import org.hibernate.sql.ast.tree.AbstractStatement;
|
||||||
|
import org.hibernate.sql.ast.tree.cte.CteContainer;
|
||||||
import org.hibernate.sql.ast.tree.cte.CteStatement;
|
import org.hibernate.sql.ast.tree.cte.CteStatement;
|
||||||
import org.hibernate.sql.results.graph.DomainResult;
|
import org.hibernate.sql.results.graph.DomainResult;
|
||||||
|
|
||||||
@ -31,6 +32,13 @@ public SelectStatement(QueryPart queryPart, List<DomainResult<?>> domainResults)
|
|||||||
this( false, new LinkedHashMap<>(), queryPart, domainResults );
|
this( false, new LinkedHashMap<>(), queryPart, domainResults );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public SelectStatement(
|
||||||
|
CteContainer cteContainer,
|
||||||
|
QueryPart queryPart,
|
||||||
|
List<DomainResult<?>> domainResults) {
|
||||||
|
this( cteContainer.isWithRecursive(), cteContainer.getCteStatements(), queryPart, domainResults );
|
||||||
|
}
|
||||||
|
|
||||||
public SelectStatement(
|
public SelectStatement(
|
||||||
boolean withRecursive,
|
boolean withRecursive,
|
||||||
Map<String, CteStatement> cteStatements,
|
Map<String, CteStatement> cteStatements,
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
import org.hibernate.sql.ast.SqlAstWalker;
|
import org.hibernate.sql.ast.SqlAstWalker;
|
||||||
import org.hibernate.sql.ast.spi.SqlAstTreeHelper;
|
import org.hibernate.sql.ast.spi.SqlAstTreeHelper;
|
||||||
import org.hibernate.sql.ast.tree.AbstractMutationStatement;
|
import org.hibernate.sql.ast.tree.AbstractMutationStatement;
|
||||||
|
import org.hibernate.sql.ast.tree.cte.CteContainer;
|
||||||
import org.hibernate.sql.ast.tree.cte.CteStatement;
|
import org.hibernate.sql.ast.tree.cte.CteStatement;
|
||||||
import org.hibernate.sql.ast.tree.expression.ColumnReference;
|
import org.hibernate.sql.ast.tree.expression.ColumnReference;
|
||||||
import org.hibernate.sql.ast.tree.from.NamedTableReference;
|
import org.hibernate.sql.ast.tree.from.NamedTableReference;
|
||||||
@ -45,6 +46,22 @@ public UpdateStatement(
|
|||||||
this.restriction = restriction;
|
this.restriction = restriction;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public UpdateStatement(
|
||||||
|
CteContainer cteContainer,
|
||||||
|
NamedTableReference targetTable,
|
||||||
|
List<Assignment> assignments,
|
||||||
|
Predicate restriction,
|
||||||
|
List<ColumnReference> returningColumns) {
|
||||||
|
this(
|
||||||
|
cteContainer.isWithRecursive(),
|
||||||
|
cteContainer.getCteStatements(),
|
||||||
|
targetTable,
|
||||||
|
assignments,
|
||||||
|
restriction,
|
||||||
|
returningColumns
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
public UpdateStatement(
|
public UpdateStatement(
|
||||||
boolean withRecursive,
|
boolean withRecursive,
|
||||||
Map<String, CteStatement> cteStatements,
|
Map<String, CteStatement> cteStatements,
|
||||||
|
@ -20,7 +20,6 @@
|
|||||||
import org.hibernate.query.sqm.NodeBuilder;
|
import org.hibernate.query.sqm.NodeBuilder;
|
||||||
import org.hibernate.query.sqm.function.AbstractSqmFunctionDescriptor;
|
import org.hibernate.query.sqm.function.AbstractSqmFunctionDescriptor;
|
||||||
import org.hibernate.query.sqm.function.FunctionRenderingSupport;
|
import org.hibernate.query.sqm.function.FunctionRenderingSupport;
|
||||||
import org.hibernate.query.sqm.function.SelfRenderingFunctionSqlAstExpression;
|
|
||||||
import org.hibernate.query.sqm.function.SelfRenderingSqmFunction;
|
import org.hibernate.query.sqm.function.SelfRenderingSqmFunction;
|
||||||
import org.hibernate.query.sqm.function.SqmFunctionDescriptor;
|
import org.hibernate.query.sqm.function.SqmFunctionDescriptor;
|
||||||
import org.hibernate.query.sqm.produce.function.ArgumentsValidator;
|
import org.hibernate.query.sqm.produce.function.ArgumentsValidator;
|
||||||
@ -31,9 +30,9 @@
|
|||||||
import org.hibernate.query.sqm.sql.SqmToSqlAstConverter;
|
import org.hibernate.query.sqm.sql.SqmToSqlAstConverter;
|
||||||
import org.hibernate.query.sqm.tree.SqmCopyContext;
|
import org.hibernate.query.sqm.tree.SqmCopyContext;
|
||||||
import org.hibernate.query.sqm.tree.SqmTypedNode;
|
import org.hibernate.query.sqm.tree.SqmTypedNode;
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmAny;
|
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmLiteral;
|
import org.hibernate.query.sqm.tree.expression.SqmLiteral;
|
||||||
import org.hibernate.sql.ast.spi.SqlAstQueryPartProcessingState;
|
import org.hibernate.sql.ast.spi.SqlAstQueryPartProcessingState;
|
||||||
|
import org.hibernate.sql.ast.tree.expression.Expression;
|
||||||
import org.hibernate.sql.ast.tree.from.DelegatingTableGroup;
|
import org.hibernate.sql.ast.tree.from.DelegatingTableGroup;
|
||||||
import org.hibernate.sql.ast.tree.from.NamedTableReference;
|
import org.hibernate.sql.ast.tree.from.NamedTableReference;
|
||||||
import org.hibernate.sql.ast.tree.from.TableGroup;
|
import org.hibernate.sql.ast.tree.from.TableGroup;
|
||||||
@ -174,7 +173,7 @@ public OrderByFragmentSelfRenderingSqmFunction<T> copy(SqmCopyContext context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SelfRenderingFunctionSqlAstExpression convertToSqlAst(SqmToSqlAstConverter walker) {
|
public Expression convertToSqlAst(SqmToSqlAstConverter walker) {
|
||||||
final ReturnableType<?> resultType = resolveResultType(
|
final ReturnableType<?> resultType = resolveResultType(
|
||||||
walker.getCreationContext().getMappingMetamodel().getTypeConfiguration()
|
walker.getCreationContext().getMappingMetamodel().getTypeConfiguration()
|
||||||
);
|
);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user