use of org.hibernate.sql.ast.tree.from.TableGroupJoin in project hibernate-orm by hibernate.
the class BaseSqmToSqlAstConverter method visitMapEntryFunction.
@Override
public Object visitMapEntryFunction(SqmMapEntryReference<?, ?> entryRef) {
final SqmPath<?> mapPath = entryRef.getMapPath();
prepareReusablePath(mapPath, () -> null);
final NavigablePath mapNavigablePath = mapPath.getNavigablePath();
final TableGroup tableGroup = getFromClauseAccess().resolveTableGroup(mapNavigablePath, (navigablePath) -> {
final TableGroup parentTableGroup = getFromClauseAccess().getTableGroup(mapNavigablePath.getParent());
final PluralAttributeMapping mapAttribute = (PluralAttributeMapping) parentTableGroup.getModelPart().findSubPart(mapNavigablePath.getLocalName(), null);
final TableGroupJoin tableGroupJoin = mapAttribute.createTableGroupJoin(mapNavigablePath, parentTableGroup, null, SqlAstJoinType.INNER, false, false, sqlAliasBaseManager, getSqlExpressionResolver(), this, creationContext);
parentTableGroup.addTableGroupJoin(tableGroupJoin);
return tableGroupJoin.getJoinedGroup();
});
final PluralAttributeMapping mapDescriptor = (PluralAttributeMapping) tableGroup.getModelPart();
final CollectionPart indexDescriptor = mapDescriptor.getIndexDescriptor();
final NavigablePath indexNavigablePath = mapNavigablePath.append(indexDescriptor.getPartName());
final DomainResult<Object> indexResult = indexDescriptor.createDomainResult(indexNavigablePath, tableGroup, null, this);
final CollectionPart valueDescriptor = mapDescriptor.getElementDescriptor();
final NavigablePath valueNavigablePath = mapNavigablePath.append(valueDescriptor.getPartName());
final DomainResult<Object> valueResult = valueDescriptor.createDomainResult(valueNavigablePath, tableGroup, null, this);
return new DomainResultProducer<Map.Entry<Object, Object>>() {
@Override
public DomainResult<Map.Entry<Object, Object>> createDomainResult(String resultVariable, DomainResultCreationState creationState) {
final JavaType<Map.Entry<Object, Object>> mapEntryDescriptor = getTypeConfiguration().getJavaTypeRegistry().resolveDescriptor(Map.Entry.class);
return new SqmMapEntryResult<>(indexResult, valueResult, resultVariable, mapEntryDescriptor);
}
@Override
public void applySqlSelections(DomainResultCreationState creationState) {
throw new UnsupportedOperationException();
}
};
}
use of org.hibernate.sql.ast.tree.from.TableGroupJoin in project hibernate-orm by hibernate.
the class BaseSqmToSqlAstConverter method consumeAttributeJoin.
private TableGroup consumeAttributeJoin(SqmAttributeJoin<?, ?> sqmJoin, TableGroup lhsTableGroup, TableGroup ownerTableGroup, boolean transitive) {
final SqmPathSource<?> pathSource = sqmJoin.getReferencedPathSource();
final SqmJoinType sqmJoinType = sqmJoin.getSqmJoinType();
final TableGroupJoin joinedTableGroupJoin;
final TableGroup joinedTableGroup;
final NavigablePath sqmJoinNavigablePath = sqmJoin.getNavigablePath();
final ModelPart modelPart = ownerTableGroup.getModelPart().findSubPart(pathSource.getPathName(), SqmMappingModelHelper.resolveExplicitTreatTarget(sqmJoin, this));
if (pathSource instanceof PluralPersistentAttribute) {
assert modelPart instanceof PluralAttributeMapping;
final PluralAttributeMapping pluralAttributeMapping = (PluralAttributeMapping) modelPart;
if (sqmJoin.isFetched()) {
containsCollectionFetches = true;
}
joinedTableGroupJoin = pluralAttributeMapping.createTableGroupJoin(sqmJoinNavigablePath, ownerTableGroup, sqmJoin.getExplicitAlias(), sqmJoinType.getCorrespondingSqlJoinType(), sqmJoin.isFetched(), sqmJoin.getJoinPredicate() != null, this);
joinedTableGroup = joinedTableGroupJoin.getJoinedGroup();
pluralAttributeMapping.applyBaseRestrictions((predicate) -> {
final PredicateCollector existing = collectionFilterPredicates.get(joinedTableGroup.getGroupAlias());
final PredicateCollector collector;
if (existing == null) {
collector = new PredicateCollector(predicate);
collectionFilterPredicates.put(joinedTableGroup.getGroupAlias(), collector);
} else {
collector = existing;
collector.applyPredicate(predicate);
}
}, joinedTableGroup, true, getLoadQueryInfluencers().getEnabledFilters(), null, this);
} else {
assert modelPart instanceof TableGroupJoinProducer;
joinedTableGroupJoin = ((TableGroupJoinProducer) modelPart).createTableGroupJoin(sqmJoinNavigablePath, ownerTableGroup, sqmJoin.getExplicitAlias(), sqmJoinType.getCorrespondingSqlJoinType(), sqmJoin.isFetched(), sqmJoin.getJoinPredicate() != null, this);
joinedTableGroup = joinedTableGroupJoin.getJoinedGroup();
// Left or inner singular attribute joins without a predicate can be safely optimized away
if (sqmJoin.getJoinPredicate() != null || sqmJoinType != SqmJoinType.INNER && sqmJoinType != SqmJoinType.LEFT) {
joinedTableGroup.getPrimaryTableReference();
}
}
lhsTableGroup.addTableGroupJoin(joinedTableGroupJoin);
getFromClauseIndex().register(sqmJoin, joinedTableGroup);
registerPluralTableGroupParts(joinedTableGroup);
// For joins we also need to register the table groups for the treats
if (joinedTableGroup instanceof PluralTableGroup) {
final PluralTableGroup pluralTableGroup = (PluralTableGroup) joinedTableGroup;
for (SqmFrom<?, ?> sqmTreat : sqmJoin.getSqmTreats()) {
if (pluralTableGroup.getElementTableGroup() != null) {
getFromClauseAccess().registerTableGroup(sqmTreat.getNavigablePath().append(CollectionPart.Nature.ELEMENT.getName()), pluralTableGroup.getElementTableGroup());
}
if (pluralTableGroup.getIndexTableGroup() != null) {
getFromClauseAccess().registerTableGroup(sqmTreat.getNavigablePath().append(CollectionPart.Nature.INDEX.getName()), pluralTableGroup.getIndexTableGroup());
}
}
} else {
for (SqmFrom<?, ?> sqmTreat : sqmJoin.getSqmTreats()) {
getFromClauseAccess().registerTableGroup(sqmTreat.getNavigablePath(), joinedTableGroup);
}
}
// add any additional join restrictions
if (sqmJoin.getJoinPredicate() != null) {
if (sqmJoin.isFetched()) {
QueryLogging.QUERY_MESSAGE_LOGGER.debugf("Join fetch [" + sqmJoinNavigablePath + "] is restricted");
}
final SqmJoin<?, ?> oldJoin = currentlyProcessingJoin;
currentlyProcessingJoin = sqmJoin;
joinedTableGroupJoin.applyPredicate(visitNestedTopLevelPredicate(sqmJoin.getJoinPredicate()));
currentlyProcessingJoin = oldJoin;
}
if (transitive) {
consumeExplicitJoins(sqmJoin, joinedTableGroup);
}
return joinedTableGroup;
}
use of org.hibernate.sql.ast.tree.from.TableGroupJoin in project hibernate-orm by hibernate.
the class CountFunction method hasNeighbouringJoinsAlteringNullability.
private Boolean hasNeighbouringJoinsAlteringNullability(TableGroup tableGroup, TableGroup targetTableGroup) {
if (tableGroup == targetTableGroup) {
return Boolean.FALSE;
}
final List<TableGroupJoin> tableGroupJoins = tableGroup.getTableGroupJoins();
int tableGroupIndex = -1;
for (int i = 0; i < tableGroupJoins.size(); i++) {
final TableGroupJoin tableGroupJoin = tableGroupJoins.get(i);
final Boolean result = hasNeighbouringJoinsAlteringNullability(tableGroupJoin.getJoinedGroup(), targetTableGroup);
if (result == Boolean.TRUE) {
return Boolean.TRUE;
} else if (result != null) {
tableGroupIndex = i;
break;
}
}
if (tableGroupIndex != -1) {
for (int i = 0; i < tableGroupJoins.size(); i++) {
if (i == tableGroupIndex) {
continue;
}
final TableGroupJoin tableGroupJoin = tableGroupJoins.get(i);
if (hasJoinsAlteringNullability(tableGroupJoin)) {
return Boolean.TRUE;
}
}
return Boolean.FALSE;
}
return null;
}
use of org.hibernate.sql.ast.tree.from.TableGroupJoin in project hibernate-orm by hibernate.
the class AbstractSqlAstTranslator method renderTableGroup.
protected void renderTableGroup(TableGroup tableGroup, Predicate predicate, List<TableGroupJoin> tableGroupJoinCollector) {
// Without reference joins or nested join groups, even a real table group does not need parenthesis
final boolean realTableGroup = tableGroup.isRealTableGroup() && (CollectionHelper.isNotEmpty(tableGroup.getTableReferenceJoins()) || hasNestedTableGroupsToRender(tableGroup.getNestedTableGroupJoins()));
if (realTableGroup) {
appendSql(OPEN_PARENTHESIS);
}
final LockMode effectiveLockMode = getEffectiveLockMode(tableGroup.getSourceAlias());
final boolean usesLockHint = renderPrimaryTableReference(tableGroup, effectiveLockMode);
final List<TableGroupJoin> tableGroupJoins;
if (realTableGroup) {
// For real table groups, we collect all normal table group joins within that table group
// The purpose of that is to render them in-order outside of the group/parenthesis
// This is necessary for at least Derby but is also a lot easier to read
renderTableReferenceJoins(tableGroup);
if (tableGroupJoinCollector == null) {
tableGroupJoins = new ArrayList<>();
processNestedTableGroupJoins(tableGroup, tableGroupJoins);
} else {
tableGroupJoins = null;
processNestedTableGroupJoins(tableGroup, tableGroupJoinCollector);
}
appendSql(CLOSE_PARENTHESIS);
} else {
tableGroupJoins = null;
}
if (predicate != null) {
appendSql(" on ");
predicate.accept(this);
}
if (tableGroup.isLateral() && !getDialect().supportsLateral()) {
final Predicate lateralEmulationPredicate = determineLateralEmulationPredicate(tableGroup);
if (lateralEmulationPredicate != null) {
if (predicate == null) {
appendSql(" on ");
} else {
appendSql(" and ");
}
lateralEmulationPredicate.accept(this);
}
}
if (!realTableGroup) {
renderTableReferenceJoins(tableGroup);
processNestedTableGroupJoins(tableGroup, tableGroupJoinCollector);
}
if (tableGroupJoinCollector != null) {
tableGroupJoinCollector.addAll(tableGroup.getTableGroupJoins());
} else {
if (tableGroupJoins != null) {
for (TableGroupJoin tableGroupJoin : tableGroupJoins) {
processTableGroupJoin(tableGroupJoin, null);
}
}
processTableGroupJoins(tableGroup);
}
ModelPartContainer modelPart = tableGroup.getModelPart();
if (modelPart instanceof AbstractEntityPersister) {
String[] querySpaces = (String[]) ((AbstractEntityPersister) modelPart).getQuerySpaces();
for (int i = 0; i < querySpaces.length; i++) {
registerAffectedTable(querySpaces[i]);
}
}
if (!usesLockHint && tableGroup.getSourceAlias() != null && LockMode.READ.lessThan(effectiveLockMode)) {
if (forUpdate == null) {
forUpdate = new ForUpdateClause(effectiveLockMode);
} else {
forUpdate.setLockMode(effectiveLockMode);
}
forUpdate.applyAliases(getDialect().getLockRowIdentifier(effectiveLockMode), tableGroup);
}
}
use of org.hibernate.sql.ast.tree.from.TableGroupJoin in project hibernate-orm by hibernate.
the class LoaderSelectBuilder method applyFiltering.
private void applyFiltering(QuerySpec querySpec, TableGroup tableGroup, PluralAttributeMapping pluralAttributeMapping, SqlAstCreationState astCreationState) {
pluralAttributeMapping.applyBaseRestrictions(querySpec::applyPredicate, tableGroup, true, loadQueryInfluencers.getEnabledFilters(), null, astCreationState);
pluralAttributeMapping.applyBaseManyToManyRestrictions((filterPredicate) -> {
final NavigablePath parentNavigablePath = tableGroup.getNavigablePath().getParent();
if (parentNavigablePath == null) {
querySpec.applyPredicate(filterPredicate);
} else {
final TableGroup parentTableGroup = astCreationState.getFromClauseAccess().getTableGroup(parentNavigablePath);
TableGroupJoin pluralTableGroupJoin = null;
for (TableGroupJoin nestedTableGroupJoin : parentTableGroup.getTableGroupJoins()) {
if (nestedTableGroupJoin.getNavigablePath() == tableGroup.getNavigablePath()) {
pluralTableGroupJoin = nestedTableGroupJoin;
break;
}
}
assert pluralTableGroupJoin != null;
pluralTableGroupJoin.applyPredicate(filterPredicate);
}
}, tableGroup, true, loadQueryInfluencers.getEnabledFilters(), null, astCreationState);
}
Aggregations