use of org.hibernate.sql.ast.tree.expression.ColumnReference in project hibernate-orm by hibernate.
the class BaseSqmToSqlAstConverter method createCorrelatedAggregateSubQuery.
protected Expression createCorrelatedAggregateSubQuery(AbstractSqmSpecificPluralPartPath<?> pluralPartPath, boolean index, String function) {
prepareReusablePath(pluralPartPath.getLhs(), () -> null);
final PluralAttributeMapping pluralAttributeMapping = (PluralAttributeMapping) determineValueMapping(pluralPartPath.getPluralDomainPath());
final FromClauseAccess parentFromClauseAccess = getFromClauseAccess();
final QuerySpec subQuerySpec = new QuerySpec(false);
pushProcessingState(new SqlAstQueryPartProcessingStateImpl(subQuerySpec, getCurrentProcessingState(), this, currentClauseStack::getCurrent, false));
try {
final TableGroup tableGroup = pluralAttributeMapping.createRootTableGroup(true, pluralPartPath.getNavigablePath(), null, () -> subQuerySpec::applyPredicate, this, creationContext);
pluralAttributeMapping.applyBaseRestrictions(subQuerySpec::applyPredicate, tableGroup, true, getLoadQueryInfluencers().getEnabledFilters(), null, this);
getFromClauseAccess().registerTableGroup(pluralPartPath.getNavigablePath(), tableGroup);
registerPluralTableGroupParts(tableGroup);
subQuerySpec.getFromClause().addRoot(tableGroup);
final AbstractSqmSelfRenderingFunctionDescriptor functionDescriptor = (AbstractSqmSelfRenderingFunctionDescriptor) creationContext.getSessionFactory().getQueryEngine().getSqmFunctionRegistry().findFunctionDescriptor(function);
final CollectionPart collectionPart = index ? pluralAttributeMapping.getIndexDescriptor() : pluralAttributeMapping.getElementDescriptor();
final ModelPart modelPart;
if (collectionPart instanceof EntityAssociationMapping) {
modelPart = ((EntityAssociationMapping) collectionPart).getKeyTargetMatchPart();
} else {
modelPart = collectionPart;
}
final List<Expression> arguments = new ArrayList<>(1);
final NavigablePath navigablePath = pluralPartPath.getNavigablePath();
final int jdbcTypeCount = modelPart.getJdbcTypeCount();
final List<Expression> tupleElements;
if (jdbcTypeCount == 1) {
tupleElements = arguments;
} else {
tupleElements = new ArrayList<>(jdbcTypeCount);
}
modelPart.forEachSelectable((selectionIndex, selectionMapping) -> tupleElements.add(new ColumnReference(tableGroup.resolveTableReference(navigablePath, selectionMapping.getContainingTableExpression()), selectionMapping, creationContext.getSessionFactory())));
if (jdbcTypeCount != 1) {
arguments.add(new SqlTuple(tupleElements, modelPart));
}
final Expression expression = new SelfRenderingAggregateFunctionSqlAstExpression(functionDescriptor.getName(), functionDescriptor, arguments, null, (ReturnableType<?>) functionDescriptor.getReturnTypeResolver().resolveFunctionReturnType(() -> null, arguments).getJdbcMapping(), modelPart);
subQuerySpec.getSelectClause().addSqlSelection(new SqlSelectionImpl(1, 0, expression));
NavigablePath parent = pluralPartPath.getPluralDomainPath().getNavigablePath().getParent();
subQuerySpec.applyPredicate(pluralAttributeMapping.getKeyDescriptor().generateJoinPredicate(parentFromClauseAccess.findTableGroup(parent), tableGroup, getSqlExpressionResolver(), creationContext));
} finally {
popProcessingStateStack();
}
return subQuerySpec;
}
use of org.hibernate.sql.ast.tree.expression.ColumnReference in project hibernate-orm by hibernate.
the class BaseSqmToSqlAstConverter method visitFkExpression.
@Override
public Object visitFkExpression(SqmFkExpression<?> fkExpression) {
final EntityValuedPathInterpretation<?> toOneInterpretation = (EntityValuedPathInterpretation<?>) visitEntityValuedPath(fkExpression.getToOnePath());
assert toOneInterpretation.getExpressionType() instanceof ToOneAttributeMapping;
final ToOneAttributeMapping toOneMapping = (ToOneAttributeMapping) toOneInterpretation.getExpressionType();
final ForeignKeyDescriptor fkDescriptor = toOneMapping.getForeignKeyDescriptor();
final TableGroup tableGroup = toOneInterpretation.getTableGroup();
final TableReference tableReference = tableGroup.resolveTableReference(fkDescriptor.getKeyTable());
final ModelPart fkKeyPart = fkDescriptor.getKeyPart();
if (fkKeyPart instanceof BasicValuedModelPart) {
final BasicValuedModelPart basicFkPart = (BasicValuedModelPart) fkKeyPart;
return getSqlExpressionResolver().resolveSqlExpression(createColumnReferenceKey(tableReference, basicFkPart.getSelectionExpression()), (sqlAstProcessingState) -> new ColumnReference(tableReference, basicFkPart, creationContext.getSessionFactory()));
} else {
assert fkKeyPart instanceof EmbeddableValuedModelPart;
final EmbeddableValuedModelPart compositeFkPart = (EmbeddableValuedModelPart) fkKeyPart;
final List<JdbcMapping> jdbcMappings = compositeFkPart.getJdbcMappings();
final List<Expression> tupleElements = new ArrayList<>(jdbcMappings.size());
compositeFkPart.forEachSelectable((position, selectable) -> {
tupleElements.add(getSqlExpressionResolver().resolveSqlExpression(createColumnReferenceKey(tableReference, selectable.getSelectionExpression()), (sqlAstProcessingState) -> new ColumnReference(tableReference, selectable, creationContext.getSessionFactory())));
});
return new SqlTuple(tupleElements, compositeFkPart);
}
}
use of org.hibernate.sql.ast.tree.expression.ColumnReference in project hibernate-orm by hibernate.
the class BaseSqmToSqlAstConverter method visitSetClause.
@Override
public List<Assignment> visitSetClause(SqmSetClause setClause) {
final List<Assignment> assignments = new ArrayList<>(setClause.getAssignments().size());
for (SqmAssignment<?> sqmAssignment : setClause.getAssignments()) {
final List<ColumnReference> targetColumnReferences = new ArrayList<>();
pushProcessingState(new SqlAstProcessingStateImpl(getCurrentProcessingState(), this, getCurrentClauseStack()::getCurrent) {
@Override
public Expression resolveSqlExpression(String key, Function<SqlAstProcessingState, Expression> creator) {
final Expression expression = getParentState().getSqlExpressionResolver().resolveSqlExpression(key, creator);
assert expression instanceof ColumnReference;
targetColumnReferences.add((ColumnReference) expression);
return expression;
}
}, getFromClauseIndex());
final SqmPathInterpretation<?> assignedPathInterpretation;
try {
assignedPathInterpretation = (SqmPathInterpretation<?>) sqmAssignment.getTargetPath().accept(this);
} finally {
popProcessingStateStack();
}
inferrableTypeAccessStack.push(assignedPathInterpretation::getExpressionType);
// final List<ColumnReference> valueColumnReferences = new ArrayList<>();
pushProcessingState(new SqlAstProcessingStateImpl(getCurrentProcessingState(), this, getCurrentClauseStack()::getCurrent) {
@Override
public Expression resolveSqlExpression(String key, Function<SqlAstProcessingState, Expression> creator) {
final Expression expression = getParentState().getSqlExpressionResolver().resolveSqlExpression(key, creator);
assert expression instanceof ColumnReference;
// valueColumnReferences.add( (ColumnReference) expression );
return expression;
}
}, getFromClauseIndex());
try {
final SqmExpression<?> assignmentValue = sqmAssignment.getValue();
final SqmParameter<?> assignmentValueParameter = getSqmParameter(assignmentValue);
if (assignmentValueParameter != null) {
consumeSqmParameter(assignmentValueParameter, assignedPathInterpretation.getExpressionType(), (index, jdbcParameter) -> assignments.add(new Assignment(targetColumnReferences.get(index), jdbcParameter)));
} else {
final Expression valueExpression = (Expression) assignmentValue.accept(this);
final int valueExprJdbcCount = getKeyExpressible(valueExpression.getExpressionType()).getJdbcTypeCount();
final int assignedPathJdbcCount = getKeyExpressible(assignedPathInterpretation.getExpressionType()).getJdbcTypeCount();
if (valueExprJdbcCount != assignedPathJdbcCount) {
SqlTreeCreationLogger.LOGGER.debugf("JDBC type count does not match in UPDATE assignment between the assigned-path and the assigned-value; " + "this will likely lead to problems executing the query");
}
assert assignedPathJdbcCount == valueExprJdbcCount;
for (ColumnReference columnReference : targetColumnReferences) {
assignments.add(new Assignment(columnReference, valueExpression));
}
}
} finally {
popProcessingStateStack();
inferrableTypeAccessStack.pop();
}
}
return assignments;
}
use of org.hibernate.sql.ast.tree.expression.ColumnReference in project hibernate-orm by hibernate.
the class BaseSqmToSqlAstConverter method addVersionedAssignment.
public void addVersionedAssignment(Consumer<Assignment> assignmentConsumer, SqmUpdateStatement<?> sqmStatement) {
if (!sqmStatement.isVersioned()) {
return;
}
final EntityPersister persister = creationContext.getSessionFactory().getRuntimeMetamodels().getMappingMetamodel().findEntityDescriptor(sqmStatement.getTarget().getEntityName());
if (!persister.isVersioned()) {
throw new SemanticException("increment option specified for update of non-versioned entity");
}
final BasicType<?> versionType = persister.getVersionType();
if (versionType instanceof UserVersionType) {
throw new SemanticException("user-defined version types not supported for increment option");
}
final EntityVersionMapping versionMapping = persister.getVersionMapping();
final List<ColumnReference> targetColumnReferences = BasicValuedPathInterpretation.from((SqmBasicValuedSimplePath<?>) sqmStatement.getRoot().get(versionMapping.getPartName()), this, this, jpaQueryComplianceEnabled).getColumnReferences();
assert targetColumnReferences.size() == 1;
final ColumnReference versionColumn = targetColumnReferences.get(0);
final Expression value;
if (versionMapping.getJdbcMapping().getJdbcType().isTemporal()) {
value = new VersionTypeSeedParameterSpecification(versionMapping);
} else {
value = new BinaryArithmeticExpression(versionColumn, ADD, new QueryLiteral<>(1, versionType), versionType);
}
assignmentConsumer.accept(new Assignment(versionColumn, value));
}
use of org.hibernate.sql.ast.tree.expression.ColumnReference in project hibernate-orm by hibernate.
the class BaseSqmToSqlAstConverter method visitInsertionTargetPaths.
public AdditionalInsertValues visitInsertionTargetPaths(BiConsumer<Assignable, List<ColumnReference>> targetColumnReferenceConsumer, SqmInsertStatement<?> sqmStatement, EntityPersister entityDescriptor, TableGroup rootTableGroup) {
final List<SqmPath<?>> targetPaths = sqmStatement.getInsertionTargetPaths();
final EntityDiscriminatorMapping discriminatorMapping = entityDescriptor.getDiscriminatorMapping();
IdentifierGenerator identifierGenerator = entityDescriptor.getIdentifierGenerator();
Expression versionExpression = null;
Expression discriminatorExpression = null;
BasicEntityIdentifierMapping identifierMapping = null;
// We use the id property name to null the identifier generator variable if the target paths contain the id
final String identifierPropertyName;
if (identifierGenerator != null) {
identifierPropertyName = entityDescriptor.getIdentifierPropertyName();
} else {
identifierPropertyName = null;
}
final String versionAttributeName;
boolean needsVersionInsert;
if (entityDescriptor.isVersioned()) {
versionAttributeName = entityDescriptor.getVersionMapping().getVersionAttribute().getAttributeName();
needsVersionInsert = true;
} else {
versionAttributeName = null;
needsVersionInsert = false;
}
// Go through all target paths and remember if the target paths contain the version or id attributes
for (int i = 0; i < targetPaths.size(); i++) {
final SqmPath<?> path = targetPaths.get(i);
final String localName = path.getNavigablePath().getLocalName();
if (localName.equals(identifierPropertyName)) {
identifierGenerator = null;
} else if (localName.equals(versionAttributeName)) {
needsVersionInsert = false;
}
final Assignable assignable = (Assignable) path.accept(this);
targetColumnReferenceConsumer.accept(assignable, assignable.getColumnReferences());
}
if (needsVersionInsert) {
final BasicValuedPathInterpretation<?> versionPath = BasicValuedPathInterpretation.from((SqmBasicValuedSimplePath<?>) sqmStatement.getTarget().get(versionAttributeName), this, this, jpaQueryComplianceEnabled);
final List<ColumnReference> targetColumnReferences = versionPath.getColumnReferences();
assert targetColumnReferences.size() == 1;
targetColumnReferenceConsumer.accept(versionPath, targetColumnReferences);
versionExpression = new VersionTypeSeedParameterSpecification(entityDescriptor.getVersionMapping());
}
if (discriminatorMapping != null && discriminatorMapping.isPhysical()) {
final BasicValuedPathInterpretation<?> discriminatorPath = new BasicValuedPathInterpretation<>(new ColumnReference(rootTableGroup.resolveTableReference(discriminatorMapping.getContainingTableExpression()), discriminatorMapping, getCreationContext().getSessionFactory()), rootTableGroup.getNavigablePath().append(discriminatorMapping.getPartName()), discriminatorMapping, rootTableGroup);
targetColumnReferenceConsumer.accept(discriminatorPath, discriminatorPath.getColumnReferences());
discriminatorExpression = new QueryLiteral<>(entityDescriptor.getDiscriminatorValue(), discriminatorMapping);
}
// This uses identity generation, so we don't need to list the column
if (identifierGenerator instanceof PostInsertIdentifierGenerator || identifierGenerator instanceof CompositeNestedGeneratedValueGenerator) {
identifierGenerator = null;
} else if (identifierGenerator != null) {
identifierMapping = (BasicEntityIdentifierMapping) entityDescriptor.getIdentifierMapping();
final BasicValuedPathInterpretation<?> identifierPath = new BasicValuedPathInterpretation<>(new ColumnReference(rootTableGroup.resolveTableReference(identifierMapping.getContainingTableExpression()), identifierMapping, getCreationContext().getSessionFactory()), rootTableGroup.getNavigablePath().append(identifierMapping.getPartName()), identifierMapping, rootTableGroup);
targetColumnReferenceConsumer.accept(identifierPath, identifierPath.getColumnReferences());
}
return new AdditionalInsertValues(versionExpression, discriminatorExpression, identifierGenerator, identifierMapping);
}
Aggregations