use of org.hibernate.query.sqm.tree.domain.SqmPath in project hibernate-orm by hibernate.
the class ASTParserLoadingTest method verifyAnimalZooSelection.
private static void verifyAnimalZooSelection(Query q) {
final SqmSelectStatement<?> sqmStatement = (SqmSelectStatement<?>) q.unwrap(QuerySqmImpl.class).getSqmStatement();
final SqmSelection<?> sqmSelection = sqmStatement.getQuerySpec().getSelectClause().getSelections().get(0);
assertThat(sqmSelection.getSelectableNode(), instanceOf(SqmPath.class));
final SqmPath<?> selectedPath = (SqmPath<?>) sqmSelection.getSelectableNode();
assertThat(selectedPath.getReferencedPathSource(), instanceOf(EntitySqmPathSource.class));
final EntitySqmPathSource selectedAttr = (EntitySqmPathSource) selectedPath.getReferencedPathSource();
assertThat(selectedAttr.getPathName(), is("zoo"));
assertThat(selectedAttr.getSqmPathType(), instanceOf(EntityDomainType.class));
final EntityDomainType<?> zooType = (EntityDomainType<?>) selectedAttr.getSqmPathType();
assertThat(zooType.getHibernateEntityName(), is(Zoo.class.getName()));
}
use of org.hibernate.query.sqm.tree.domain.SqmPath 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().getJdbcMapping(), entityDescriptor.getVersionJavaType());
}
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);
}
use of org.hibernate.query.sqm.tree.domain.SqmPath in project hibernate-orm by hibernate.
the class BaseSqmToSqlAstConverter method determineValueMapping.
protected MappingModelExpressible<?> determineValueMapping(SqmParameter<?> sqmParameter) {
log.debugf("Determining mapping-model type for SqmParameter : %s", sqmParameter);
final QueryParameterImplementor<?> queryParameter = domainParameterXref.getQueryParameter(sqmParameter);
final QueryParameterBinding<?> binding = domainParameterBindings.getBinding(queryParameter);
BindableType<?> paramType = binding.getBindType();
if (paramType == null) {
paramType = queryParameter.getHibernateType();
if (paramType == null) {
paramType = sqmParameter.getAnticipatedType();
}
}
if (paramType == null) {
final MappingModelExpressible<?> inferredValueMapping = getInferredValueMapping();
if (inferredValueMapping != null) {
return inferredValueMapping;
}
// Default to the Object type
return basicType(Object.class);
} else if (paramType instanceof MappingModelExpressible<?>) {
final MappingModelExpressible<?> paramModelType = (MappingModelExpressible<?>) paramType;
final MappingModelExpressible<?> inferredValueMapping = getInferredValueMapping();
// Prefer the model part type instead of the bind type if possible as the model part type contains size information
if (inferredValueMapping instanceof ModelPart) {
final JdbcMapping paramJdbcMapping = paramModelType.getJdbcMappings().get(0);
final JdbcMapping inferredJdbcMapping = inferredValueMapping.getJdbcMappings().get(0);
// If the bind type has a different JDBC type, we prefer that
if (paramJdbcMapping.getJdbcType() == inferredJdbcMapping.getJdbcType()) {
return inferredValueMapping;
}
}
return paramModelType;
} else if (sqmParameter.getAnticipatedType() == null) {
// this should indicate the condition that the user query did not define an
// explicit type in regard to this parameter. Here we should prefer the
// inferrable type and fallback to resolving the binding type
final MappingModelExpressible<?> inferredValueMapping = getInferredValueMapping();
if (inferredValueMapping != null) {
return inferredValueMapping;
}
} else if (paramType instanceof EntityDomainType) {
// In JPA Criteria, it is possible to define a parameter of an entity type,
// but that should infer the mapping type from context,
// otherwise this would default to binding the PK which might be wrong
final MappingModelExpressible<?> inferredValueMapping = getInferredValueMapping();
if (inferredValueMapping != null) {
return inferredValueMapping;
}
}
final SqmExpressible<?> paramSqmType = paramType.resolveExpressible(creationContext.getSessionFactory());
if (paramSqmType instanceof SqmPath) {
final SqmPath<?> sqmPath = (SqmPath<?>) paramSqmType;
final NavigablePath navigablePath = sqmPath.getNavigablePath();
if (navigablePath.getParent() != null) {
final TableGroup tableGroup = getFromClauseAccess().getTableGroup(navigablePath.getParent());
return tableGroup.getModelPart().findSubPart(navigablePath.getLocalName(), null);
}
return getFromClauseAccess().getTableGroup(navigablePath).getModelPart();
}
if (paramSqmType instanceof BasicValuedMapping) {
return (BasicValuedMapping) paramSqmType;
}
if (paramSqmType instanceof CompositeSqmPathSource) {
// Try to infer the value mapping since the other side apparently is a path source
final MappingModelExpressible<?> inferredValueMapping = getInferredValueMapping();
if (inferredValueMapping != null) {
return inferredValueMapping;
}
throw new NotYetImplementedFor6Exception("Support for embedded-valued parameters not yet implemented");
}
if (paramSqmType instanceof SqmPathSource<?> || paramSqmType instanceof BasicDomainType<?>) {
// Try to infer the value mapping since the other side apparently is a path source
final MappingModelExpressible<?> inferredValueMapping = getInferredValueMapping();
if (inferredValueMapping != null) {
return inferredValueMapping;
}
return getTypeConfiguration().getBasicTypeForJavaType(paramSqmType.getExpressibleJavaType().getJavaTypeClass());
}
throw new ConversionException("Could not determine ValueMapping for SqmParameter: " + sqmParameter);
}
use of org.hibernate.query.sqm.tree.domain.SqmPath in project hibernate-orm by hibernate.
the class BaseSqmToSqlAstConverter method visitNestedTopLevelPredicate.
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Predicates
@Override
public Predicate visitNestedTopLevelPredicate(SqmPredicate predicate) {
final Map<SqmPath<?>, Set<String>> originalConjunctTableGroupTreatUsages;
if (conjunctTreatUsages.isEmpty()) {
originalConjunctTableGroupTreatUsages = null;
} else {
originalConjunctTableGroupTreatUsages = new IdentityHashMap<>(conjunctTreatUsages);
}
conjunctTreatUsages.clear();
final Predicate result = (Predicate) predicate.accept(this);
final Predicate finalPredicate = SqlAstTreeHelper.combinePredicates(result, consumeConjunctTreatTypeRestrictions());
if (originalConjunctTableGroupTreatUsages != null) {
conjunctTreatUsages.putAll(originalConjunctTableGroupTreatUsages);
}
return finalPredicate;
}
use of org.hibernate.query.sqm.tree.domain.SqmPath in project hibernate-orm by hibernate.
the class BaseSqmToSqlAstConverter method determineValueMapping.
private MappingModelExpressible<?> determineValueMapping(SqmExpression<?> sqmExpression, FromClauseIndex fromClauseIndex) {
if (sqmExpression instanceof SqmParameter) {
return determineValueMapping((SqmParameter<?>) sqmExpression);
} else if (sqmExpression instanceof SqmPath) {
log.debugf("Determining mapping-model type for SqmPath : %s ", sqmExpression);
final MappingMetamodel domainModel = creationContext.getSessionFactory().getRuntimeMetamodels().getMappingMetamodel();
return SqmMappingModelHelper.resolveMappingModelExpressible(sqmExpression, domainModel, fromClauseIndex::findTableGroup);
} else // The model type of an enum literal is always inferred
if (sqmExpression instanceof SqmEnumLiteral<?>) {
final MappingModelExpressible<?> mappingModelExpressible = resolveInferredType();
if (mappingModelExpressible != null) {
return mappingModelExpressible;
}
} else if (sqmExpression instanceof SqmSubQuery<?>) {
final SqmSubQuery<?> subQuery = (SqmSubQuery<?>) sqmExpression;
final SqmSelectClause selectClause = subQuery.getQuerySpec().getSelectClause();
if (selectClause.getSelections().size() == 1) {
final SqmSelection<?> subQuerySelection = selectClause.getSelections().get(0);
final SqmSelectableNode<?> selectableNode = subQuerySelection.getSelectableNode();
if (selectableNode instanceof SqmExpression<?>) {
return determineValueMapping((SqmExpression<?>) selectableNode, fromClauseIndex);
}
final SqmExpressible<?> selectionNodeType = subQuerySelection.getNodeType();
if (selectionNodeType != null) {
final MappingMetamodel domainModel = creationContext.getSessionFactory().getRuntimeMetamodels().getMappingMetamodel();
final MappingModelExpressible<?> expressible = domainModel.resolveMappingExpressible(selectionNodeType, this::findTableGroupByPath);
if (expressible != null) {
return expressible;
}
try {
final MappingModelExpressible<?> mappingModelExpressible = resolveInferredType();
if (mappingModelExpressible != null) {
return mappingModelExpressible;
}
} catch (Exception ignore) {
return null;
}
}
}
}
log.debugf("Determining mapping-model type for generalized SqmExpression : %s", sqmExpression);
final SqmExpressible<?> nodeType = sqmExpression.getNodeType();
if (nodeType == null) {
// We can't determine the type of the expression
return null;
}
final MappingMetamodel domainModel = creationContext.getSessionFactory().getRuntimeMetamodels().getMappingMetamodel();
final MappingModelExpressible<?> valueMapping = domainModel.resolveMappingExpressible(nodeType, fromClauseIndex::getTableGroup);
if (valueMapping == null) {
final MappingModelExpressible<?> mappingModelExpressible = resolveInferredType();
if (mappingModelExpressible != null) {
return mappingModelExpressible;
}
}
if (valueMapping == null) {
// For literals it is totally possible that we can't figure out a mapping type
if (sqmExpression instanceof SqmLiteral<?>) {
return null;
}
throw new ConversionException("Could not determine ValueMapping for SqmExpression: " + sqmExpression);
}
return valueMapping;
}
Aggregations