use of org.hibernate.query.sqm.tree.domain.SqmPolymorphicRootDescriptor in project hibernate-orm by hibernate.
the class SemanticQueryBuilder method visitUpdateStatement.
@Override
public SqmUpdateStatement<R> visitUpdateStatement(HqlParser.UpdateStatementContext ctx) {
final boolean versioned = !(ctx.getChild(1) instanceof HqlParser.TargetEntityContext);
final int dmlTargetIndex = versioned ? 2 : 1;
final HqlParser.TargetEntityContext dmlTargetContext = (HqlParser.TargetEntityContext) ctx.getChild(dmlTargetIndex);
final SqmRoot<R> root = visitTargetEntity(dmlTargetContext);
if (root.getReferencedPathSource() instanceof SqmPolymorphicRootDescriptor<?>) {
throw new SemanticException(String.format("Target type '%s' in update statement is not an entity", root.getReferencedPathSource().getHibernateEntityName()));
}
final SqmUpdateStatement<R> updateStatement = new SqmUpdateStatement<>(root, creationContext.getNodeBuilder());
parameterCollector = updateStatement;
final SqmDmlCreationProcessingState processingState = new SqmDmlCreationProcessingState(updateStatement, this);
processingStateStack.push(processingState);
processingState.getPathRegistry().register(root);
try {
updateStatement.versioned(versioned);
final HqlParser.SetClauseContext setClauseCtx = (HqlParser.SetClauseContext) ctx.getChild(dmlTargetIndex + 1);
for (ParseTree subCtx : setClauseCtx.children) {
if (subCtx instanceof HqlParser.AssignmentContext) {
final HqlParser.AssignmentContext assignmentContext = (HqlParser.AssignmentContext) subCtx;
updateStatement.applyAssignment(consumeDomainPath((HqlParser.SimplePathContext) assignmentContext.getChild(0)), (SqmExpression<?>) assignmentContext.getChild(2).accept(this));
}
}
if (dmlTargetIndex + 2 <= ctx.getChildCount()) {
updateStatement.applyPredicate(visitWhereClause((HqlParser.WhereClauseContext) ctx.getChild(dmlTargetIndex + 2)));
}
return updateStatement;
} finally {
processingStateStack.pop();
}
}
use of org.hibernate.query.sqm.tree.domain.SqmPolymorphicRootDescriptor in project hibernate-orm by hibernate.
the class SemanticQueryBuilder method visitInsertStatement.
@Override
public SqmInsertStatement<R> visitInsertStatement(HqlParser.InsertStatementContext ctx) {
final int dmlTargetIndex;
if (ctx.getChild(1) instanceof HqlParser.TargetEntityContext) {
dmlTargetIndex = 1;
} else {
dmlTargetIndex = 2;
}
final HqlParser.TargetEntityContext dmlTargetContext = (HqlParser.TargetEntityContext) ctx.getChild(dmlTargetIndex);
final HqlParser.TargetFieldsContext targetFieldsSpecContext = (HqlParser.TargetFieldsContext) ctx.getChild(dmlTargetIndex + 1);
final SqmRoot<R> root = visitTargetEntity(dmlTargetContext);
if (root.getReferencedPathSource() instanceof SqmPolymorphicRootDescriptor<?>) {
throw new SemanticException(String.format("Target type '%s' in insert statement is not an entity", root.getReferencedPathSource().getHibernateEntityName()));
}
final HqlParser.QueryExpressionContext queryExpressionContext = ctx.queryExpression();
if (queryExpressionContext != null) {
final SqmInsertSelectStatement<R> insertStatement = new SqmInsertSelectStatement<>(root, creationContext.getNodeBuilder());
parameterCollector = insertStatement;
final SqmDmlCreationProcessingState processingState = new SqmDmlCreationProcessingState(insertStatement, this);
processingStateStack.push(processingState);
try {
queryExpressionContext.accept(this);
final SqmCreationProcessingState stateFieldsProcessingState = new SqmCreationProcessingStateImpl(insertStatement, this);
stateFieldsProcessingState.getPathRegistry().register(root);
processingStateStack.push(stateFieldsProcessingState);
try {
for (HqlParser.SimplePathContext stateFieldCtx : targetFieldsSpecContext.simplePath()) {
final SqmPath<?> stateField = (SqmPath<?>) visitSimplePath(stateFieldCtx);
// todo : validate each resolved stateField...
insertStatement.addInsertTargetStateField(stateField);
}
} finally {
processingStateStack.pop();
}
return insertStatement;
} finally {
processingStateStack.pop();
}
} else {
final SqmInsertValuesStatement<R> insertStatement = new SqmInsertValuesStatement<>(root, creationContext.getNodeBuilder());
parameterCollector = insertStatement;
final SqmDmlCreationProcessingState processingState = new SqmDmlCreationProcessingState(insertStatement, this);
processingStateStack.push(processingState);
processingState.getPathRegistry().register(root);
try {
final HqlParser.ValuesListContext valuesListContext = ctx.valuesList();
for (int i = 1; i < valuesListContext.getChildCount(); i += 2) {
final ParseTree values = valuesListContext.getChild(i);
final SqmValues sqmValues = new SqmValues();
for (int j = 1; j < values.getChildCount(); j += 2) {
sqmValues.getExpressions().add((SqmExpression<?>) values.getChild(j).accept(this));
}
insertStatement.getValuesList().add(sqmValues);
}
for (HqlParser.SimplePathContext stateFieldCtx : targetFieldsSpecContext.simplePath()) {
final SqmPath<?> stateField = (SqmPath<?>) visitSimplePath(stateFieldCtx);
// todo : validate each resolved stateField...
insertStatement.addInsertTargetStateField(stateField);
}
return insertStatement;
} finally {
processingStateStack.pop();
}
}
}
use of org.hibernate.query.sqm.tree.domain.SqmPolymorphicRootDescriptor in project hibernate-orm by hibernate.
the class SemanticQueryBuilder method visitRootEntity.
@Override
@SuppressWarnings({ "rawtypes", "unchecked" })
public SqmRoot<?> visitRootEntity(HqlParser.RootEntityContext ctx) {
final HqlParser.EntityNameContext entityNameContext = (HqlParser.EntityNameContext) ctx.getChild(0);
final List<ParseTree> entityNameParseTreeChildren = entityNameContext.children;
final String name = getEntityName(entityNameContext);
log.debugf("Handling root path - %s", name);
final EntityDomainType entityDescriptor = getCreationContext().getJpaMetamodel().getHqlEntityReference(name);
final HqlParser.VariableContext identificationVariableDefContext;
if (ctx.getChildCount() > 1) {
identificationVariableDefContext = (HqlParser.VariableContext) ctx.getChild(1);
} else {
identificationVariableDefContext = null;
}
final String alias = applyJpaCompliance(visitVariable(identificationVariableDefContext));
final SqmCreationProcessingState processingState = processingStateStack.getCurrent();
final SqmPathRegistry pathRegistry = processingState.getPathRegistry();
if (entityDescriptor == null) {
final int size = entityNameParseTreeChildren.size();
// Handle the use of a correlation path in subqueries
if (processingStateStack.depth() > 1 && size > 2) {
final String parentAlias = entityNameParseTreeChildren.get(0).getText();
final AbstractSqmFrom<?, ?> correlation = processingState.getPathRegistry().findFromByAlias(parentAlias, true);
if (correlation instanceof SqmCorrelation<?, ?>) {
final DotIdentifierConsumer dotIdentifierConsumer = new QualifiedJoinPathConsumer(correlation, SqmJoinType.INNER, false, alias, this);
final int lastIdx = size - 1;
for (int i = 2; i != lastIdx; i += 2) {
dotIdentifierConsumer.consumeIdentifier(entityNameParseTreeChildren.get(i).getText(), false, false);
}
dotIdentifierConsumer.consumeIdentifier(entityNameParseTreeChildren.get(lastIdx).getText(), false, true);
return ((SqmCorrelation<?, ?>) correlation).getCorrelatedRoot();
}
throw new SemanticException("Could not resolve entity or correlation path '" + name + "'");
}
throw new UnknownEntityException("Could not resolve root entity '" + name + "'", name);
}
checkFQNEntityNameJpaComplianceViolationIfNeeded(name, entityDescriptor);
if (entityDescriptor instanceof SqmPolymorphicRootDescriptor) {
if (getCreationOptions().useStrictJpaCompliance()) {
throw new StrictJpaComplianceViolation("Encountered unmapped polymorphic reference [" + entityDescriptor.getHibernateEntityName() + "], but strict JPQL compliance was requested", StrictJpaComplianceViolation.Type.UNMAPPED_POLYMORPHISM);
}
if (processingStateStack.depth() > 1) {
throw new SemanticException("Illegal implicit-polymorphic domain path in subquery '" + entityDescriptor.getName() + "'");
}
}
final SqmRoot<?> sqmRoot = new SqmRoot<>(entityDescriptor, alias, true, creationContext.getNodeBuilder());
pathRegistry.register(sqmRoot);
return sqmRoot;
}
Aggregations