use of org.hibernate.query.spi.NavigablePath in project hibernate-orm by hibernate.
the class DynamicFetchBuilderLegacy method buildFetch.
@Override
public Fetch buildFetch(FetchParent parent, NavigablePath fetchPath, JdbcValuesMetadata jdbcResultsMetadata, BiFunction<String, String, DynamicFetchBuilderLegacy> legacyFetchResolver, DomainResultCreationState domainResultCreationState) {
final DomainResultCreationStateImpl creationState = ResultsHelper.impl(domainResultCreationState);
final TableGroup ownerTableGroup = creationState.getFromClauseAccess().findByAlias(ownerTableAlias);
final AttributeMapping attributeMapping = parent.getReferencedMappingContainer().findContainingEntityMapping().findDeclaredAttributeMapping(fetchableName);
final TableGroup tableGroup;
if (attributeMapping instanceof TableGroupJoinProducer) {
final SqlAliasBase sqlAliasBase = new SqlAliasBaseConstant(tableAlias);
final TableGroupJoin tableGroupJoin = ((TableGroupJoinProducer) attributeMapping).createTableGroupJoin(fetchPath, ownerTableGroup, tableAlias, SqlAstJoinType.INNER, true, false, s -> sqlAliasBase, creationState.getSqlExpressionResolver(), creationState.getFromClauseAccess(), creationState.getCreationContext());
ownerTableGroup.addTableGroupJoin(tableGroupJoin);
creationState.getFromClauseAccess().registerTableGroup(fetchPath, tableGroup = tableGroupJoin.getJoinedGroup());
} else {
tableGroup = ownerTableGroup;
}
if (columnNames != null) {
final ForeignKeyDescriptor keyDescriptor;
if (attributeMapping instanceof PluralAttributeMapping) {
final PluralAttributeMapping pluralAttributeMapping = (PluralAttributeMapping) attributeMapping;
keyDescriptor = pluralAttributeMapping.getKeyDescriptor();
} else {
// Not sure if this fetch builder can also be used with other attribute mappings
assert attributeMapping instanceof ToOneAttributeMapping;
final ToOneAttributeMapping toOneAttributeMapping = (ToOneAttributeMapping) attributeMapping;
keyDescriptor = toOneAttributeMapping.getForeignKeyDescriptor();
}
if (!columnNames.isEmpty()) {
keyDescriptor.forEachSelectable((selectionIndex, selectableMapping) -> {
resolveSqlSelection(columnNames.get(selectionIndex), createColumnReferenceKey(tableGroup.resolveTableReference(selectableMapping.getContainingTableExpression()), selectableMapping.getSelectionExpression()), selectableMapping.getJdbcMapping(), jdbcResultsMetadata, domainResultCreationState);
});
}
// We process the fetch builder such that it contains a resultBuilderEntity before calling this method in ResultSetMappingProcessor
if (resultBuilderEntity != null) {
return resultBuilderEntity.buildFetch(parent, attributeMapping, jdbcResultsMetadata, creationState);
}
}
try {
final NavigablePath currentRelativePath = creationState.getCurrentRelativePath();
final String prefix;
if (currentRelativePath == null) {
prefix = "";
} else {
prefix = currentRelativePath.getFullPath().replace(ELEMENT_PREFIX, "").replace(INDEX_PREFIX, "") + ".";
}
creationState.pushExplicitFetchMementoResolver(relativePath -> {
if (relativePath.startsWith(prefix)) {
return findFetchBuilder(relativePath.substring(prefix.length()));
}
return null;
});
return parent.generateFetchableFetch(attributeMapping, parent.resolveNavigablePath(attributeMapping), FetchTiming.IMMEDIATE, true, null, domainResultCreationState);
} finally {
creationState.popExplicitFetchMementoResolver();
}
}
use of org.hibernate.query.spi.NavigablePath in project hibernate-orm by hibernate.
the class DynamicResultBuilderEntityStandard method buildResultOrFetch.
private <T> T buildResultOrFetch(Function<TableGroup, T> resultOrFetchBuilder, JdbcValuesMetadata jdbcResultsMetadata, DomainResultCreationState domainResultCreationState) {
final DomainResultCreationStateImpl creationState = impl(domainResultCreationState);
final FromClauseAccess fromClauseAccess = domainResultCreationState.getSqlAstCreationState().getFromClauseAccess();
final TableGroup tableGroup = fromClauseAccess.resolveTableGroup(navigablePath, np -> {
final TableReference tableReference = entityMapping.createPrimaryTableReference(new SqlAliasBaseConstant(tableAlias), creationState.getSqlExpressionResolver(), creationState.getCreationContext());
if (lockMode != null) {
domainResultCreationState.getSqlAstCreationState().registerLockMode(tableAlias, lockMode);
}
return new TableGroupImpl(navigablePath, tableAlias, tableReference, entityMapping);
});
final TableReference tableReference = tableGroup.getPrimaryTableReference();
final List<String> idColumnAliases;
final FetchBuilder idFetchBuilder;
if (this.idColumnNames != null) {
idColumnAliases = this.idColumnNames;
} else if ((idFetchBuilder = findIdFetchBuilder()) != null) {
idColumnAliases = ((DynamicFetchBuilder) idFetchBuilder).getColumnAliases();
} else {
idColumnAliases = null;
}
if (idColumnAliases != null) {
final EntityIdentifierMapping identifierMapping = entityMapping.getIdentifierMapping();
identifierMapping.forEachSelectable((selectionIndex, selectableMapping) -> {
resolveSqlSelection(idColumnAliases.get(selectionIndex), createColumnReferenceKey(tableReference, selectableMapping.getSelectionExpression()), selectableMapping.getJdbcMapping(), jdbcResultsMetadata, domainResultCreationState);
});
}
if (discriminatorColumnName != null) {
resolveSqlSelection(discriminatorColumnName, createColumnReferenceKey(tableReference, entityMapping.getDiscriminatorMapping().getSelectionExpression()), entityMapping.getDiscriminatorMapping().getJdbcMapping(), jdbcResultsMetadata, domainResultCreationState);
}
try {
final NavigablePath currentRelativePath = creationState.getCurrentRelativePath();
final String prefix;
if (currentRelativePath == null) {
prefix = "";
} else {
prefix = currentRelativePath.getFullPath().replace(ELEMENT_PREFIX, "").replace(INDEX_PREFIX, "") + ".";
}
creationState.pushExplicitFetchMementoResolver(relativePath -> {
if (relativePath.startsWith(prefix)) {
final int startIndex;
if (relativePath.regionMatches(prefix.length(), ELEMENT_PREFIX, 0, ELEMENT_PREFIX.length())) {
startIndex = prefix.length() + ELEMENT_PREFIX.length();
} else {
startIndex = prefix.length();
}
return findFetchBuilder(relativePath.substring(startIndex));
}
return null;
});
return resultOrFetchBuilder.apply(tableGroup);
} finally {
creationState.popExplicitFetchMementoResolver();
}
}
use of org.hibernate.query.spi.NavigablePath in project hibernate-orm by hibernate.
the class BaseSqmToSqlAstConverter method prepareForSelection.
private void prepareForSelection(SqmPath<?> selectionPath) {
final SqmPath<?> path;
// through a cardinality preserving mechanism in visitIndexAggregateFunction/visitElementAggregateFunction
if (selectionPath instanceof AbstractSqmSpecificPluralPartPath<?>) {
path = selectionPath.getLhs().getLhs();
} else {
path = selectionPath;
}
final FromClauseIndex fromClauseIndex = getFromClauseIndex();
final TableGroup tableGroup = fromClauseIndex.findTableGroup(path.getNavigablePath());
if (tableGroup == null) {
prepareReusablePath(path, () -> null);
final NavigablePath navigablePath;
if (CollectionPart.Nature.fromNameExact(path.getNavigablePath().getUnaliasedLocalName()) != null) {
navigablePath = path.getLhs().getLhs().getNavigablePath();
} else if (path instanceof SqmTreatedRoot<?, ?>) {
navigablePath = ((SqmTreatedRoot<?, ?>) path).getWrappedPath().getNavigablePath();
} else {
navigablePath = path.getLhs().getNavigablePath();
}
final TableGroup createdTableGroup = createTableGroup(fromClauseIndex.getTableGroup(navigablePath), path);
if (createdTableGroup != null) {
if (path instanceof SqmTreatedPath<?, ?>) {
fromClauseIndex.register(path, createdTableGroup);
}
if (path instanceof SqmFrom<?, ?>) {
registerTreatUsage((SqmFrom<?, ?>) path, createdTableGroup);
}
}
} else if (path instanceof SqmFrom<?, ?>) {
registerTreatUsage((SqmFrom<?, ?>) path, tableGroup);
}
}
use of org.hibernate.query.spi.NavigablePath in project hibernate-orm by hibernate.
the class BaseSqmToSqlAstConverter method visitInsertValuesStatement.
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Insert-values statement
@Override
public InsertStatement visitInsertValuesStatement(SqmInsertValuesStatement<?> sqmStatement) {
final CteContainer cteContainer = this.visitCteContainer(sqmStatement);
final String entityName = sqmStatement.getTarget().getEntityName();
final EntityPersister entityDescriptor = creationContext.getSessionFactory().getRuntimeMetamodels().getMappingMetamodel().getEntityDescriptor(entityName);
assert entityDescriptor != null;
pushProcessingState(new SqlAstProcessingStateImpl(null, this, getCurrentClauseStack()::getCurrent));
try {
final NavigablePath rootPath = sqmStatement.getTarget().getNavigablePath();
final TableGroup rootTableGroup = entityDescriptor.createRootTableGroup(true, rootPath, sqmStatement.getTarget().getExplicitAlias(), () -> predicate -> additionalRestrictions = SqlAstTreeHelper.combinePredicates(additionalRestrictions, predicate), this, getCreationContext());
if (!rootTableGroup.getTableReferenceJoins().isEmpty() || !rootTableGroup.getTableGroupJoins().isEmpty()) {
throw new HibernateException("Not expecting multiple table references for an SQM INSERT-SELECT");
}
getFromClauseAccess().registerTableGroup(rootPath, rootTableGroup);
final InsertStatement insertStatement = new InsertStatement(cteContainer, (NamedTableReference) rootTableGroup.getPrimaryTableReference(), Collections.emptyList());
final AdditionalInsertValues additionalInsertValues = visitInsertionTargetPaths((assigable, references) -> insertStatement.addTargetColumnReferences(references), sqmStatement, entityDescriptor, rootTableGroup);
if (!rootTableGroup.getTableReferenceJoins().isEmpty() || !rootTableGroup.getTableGroupJoins().isEmpty()) {
throw new SemanticException("Not expecting multiple table references for an SQM INSERT-SELECT");
}
for (SqmValues sqmValues : sqmStatement.getValuesList()) {
final Values values = visitValues(sqmValues);
additionalInsertValues.applyValues(values);
insertStatement.getValuesList().add(values);
}
return insertStatement;
} finally {
popProcessingStateStack();
}
}
use of org.hibernate.query.spi.NavigablePath in project hibernate-orm by hibernate.
the class BaseSqmToSqlAstConverter method consumeFromClauseCorrelatedRoot.
protected void consumeFromClauseCorrelatedRoot(SqmRoot<?> sqmRoot) {
log.tracef("Resolving SqmRoot [%s] to TableGroup", sqmRoot);
final FromClauseIndex fromClauseIndex = getFromClauseIndex();
if (fromClauseIndex.isResolved(sqmRoot)) {
log.tracef("Already resolved SqmRoot [%s] to TableGroup", sqmRoot);
}
final QuerySpec currentQuerySpec = currentQuerySpec();
final TableGroup tableGroup;
if (!sqmRoot.isCorrelated()) {
return;
}
final SessionFactoryImplementor sessionFactory = creationContext.getSessionFactory();
if (sqmRoot.containsOnlyInnerJoins()) {
// If we have just inner joins against a correlated root, we can render the joins as references
final SqmFrom<?, ?> from;
// It will always contain just a single correlated join though, which is what is actually correlated
if (sqmRoot instanceof SqmCorrelatedRootJoin<?>) {
assert sqmRoot.getSqmJoins().size() == 1;
assert sqmRoot.getSqmJoins().get(0).isCorrelated();
from = sqmRoot.getSqmJoins().get(0);
} else {
from = sqmRoot;
}
final TableGroup parentTableGroup = fromClauseIndex.findTableGroupOnParents(from.getCorrelationParent().getNavigablePath());
final SqlAliasBase sqlAliasBase = sqlAliasBaseManager.createSqlAliasBase(parentTableGroup.getGroupAlias());
if (parentTableGroup instanceof PluralTableGroup) {
final PluralTableGroup pluralTableGroup = (PluralTableGroup) parentTableGroup;
final CorrelatedPluralTableGroup correlatedPluralTableGroup = new CorrelatedPluralTableGroup(parentTableGroup, sqlAliasBase, currentQuerySpec, predicate -> additionalRestrictions = SqlAstTreeHelper.combinePredicates(additionalRestrictions, predicate), sessionFactory);
final TableGroup elementTableGroup = pluralTableGroup.getElementTableGroup();
if (elementTableGroup != null) {
final TableGroup correlatedElementTableGroup = new CorrelatedTableGroup(elementTableGroup, sqlAliasBase, currentQuerySpec, predicate -> additionalRestrictions = SqlAstTreeHelper.combinePredicates(additionalRestrictions, predicate), sessionFactory);
final TableGroupJoin tableGroupJoin = new TableGroupJoin(elementTableGroup.getNavigablePath(), SqlAstJoinType.INNER, correlatedElementTableGroup);
correlatedPluralTableGroup.registerElementTableGroup(tableGroupJoin);
}
final TableGroup indexTableGroup = pluralTableGroup.getIndexTableGroup();
if (indexTableGroup != null) {
final TableGroup correlatedIndexTableGroup = new CorrelatedTableGroup(indexTableGroup, sqlAliasBase, currentQuerySpec, predicate -> additionalRestrictions = SqlAstTreeHelper.combinePredicates(additionalRestrictions, predicate), sessionFactory);
final TableGroupJoin tableGroupJoin = new TableGroupJoin(indexTableGroup.getNavigablePath(), SqlAstJoinType.INNER, correlatedIndexTableGroup);
correlatedPluralTableGroup.registerIndexTableGroup(tableGroupJoin);
}
tableGroup = correlatedPluralTableGroup;
} else {
tableGroup = new CorrelatedTableGroup(parentTableGroup, sqlAliasBase, currentQuerySpec, predicate -> additionalRestrictions = SqlAstTreeHelper.combinePredicates(additionalRestrictions, predicate), sessionFactory);
}
fromClauseIndex.register(from, tableGroup);
registerPluralTableGroupParts(tableGroup);
log.tracef("Resolved SqmRoot [%s] to correlated TableGroup [%s]", sqmRoot, tableGroup);
consumeExplicitJoins(from, tableGroup);
return;
} else {
final EntityPersister entityDescriptor = resolveEntityPersister(sqmRoot.getReferencedPathSource());
final TableGroup parentTableGroup = fromClauseIndex.findTableGroupOnParents(sqmRoot.getCorrelationParent().getNavigablePath());
// If we have non-inner joins against a correlated root, we must render the root with a correlation predicate
tableGroup = entityDescriptor.createRootTableGroup(true, sqmRoot.getNavigablePath(), sqmRoot.getExplicitAlias(), () -> predicate -> {
}, this, creationContext);
final EntityIdentifierMapping identifierMapping = entityDescriptor.getIdentifierMapping();
final NavigablePath navigablePath = sqmRoot.getNavigablePath().append(identifierMapping.getNavigableRole().getNavigableName());
final int jdbcTypeCount = identifierMapping.getJdbcTypeCount();
if (jdbcTypeCount == 1) {
identifierMapping.forEachSelectable((index, selectable) -> additionalRestrictions = SqlAstTreeHelper.combinePredicates(additionalRestrictions, new ComparisonPredicate(new ColumnReference(parentTableGroup.resolveTableReference(navigablePath, selectable.getContainingTableExpression()), selectable, sessionFactory), ComparisonOperator.EQUAL, new ColumnReference(tableGroup.resolveTableReference(navigablePath, selectable.getContainingTableExpression()), selectable, sessionFactory))));
} else {
final List<Expression> lhs = new ArrayList<>(jdbcTypeCount);
final List<Expression> rhs = new ArrayList<>(jdbcTypeCount);
identifierMapping.forEachSelectable((index, selectable) -> {
lhs.add(new ColumnReference(parentTableGroup.resolveTableReference(navigablePath, selectable.getContainingTableExpression()), selectable, sessionFactory));
rhs.add(new ColumnReference(tableGroup.resolveTableReference(navigablePath, selectable.getContainingTableExpression()), selectable, sessionFactory));
});
additionalRestrictions = SqlAstTreeHelper.combinePredicates(additionalRestrictions, new ComparisonPredicate(new SqlTuple(lhs, identifierMapping), ComparisonOperator.EQUAL, new SqlTuple(rhs, identifierMapping)));
}
}
log.tracef("Resolved SqmRoot [%s] to new TableGroup [%s]", sqmRoot, tableGroup);
fromClauseIndex.register(sqmRoot, tableGroup);
currentQuerySpec.getFromClause().addRoot(tableGroup);
consumeJoins(sqmRoot, fromClauseIndex, tableGroup);
}
Aggregations