use of com.blazebit.persistence.parser.expression.PathExpression in project blaze-persistence by Blazebit.
the class BaseFinalSetOperationBuilderImpl method isNullable.
private boolean isNullable(AbstractCommonQueryBuilder<?, ?, ?, ?, ?> queryBuilder, String expression) {
if (queryBuilder instanceof BaseFinalSetOperationBuilderImpl<?, ?, ?>) {
SetOperationManager setOpManager = ((BaseFinalSetOperationBuilderImpl<?, ?, ?>) queryBuilder).setOperationManager;
if (isNullable(setOpManager.getStartQueryBuilder(), expression)) {
return true;
}
for (AbstractCommonQueryBuilder<?, ?, ?, ?, ?> setOp : setOpManager.getSetOperations()) {
if (isNullable(setOp, expression)) {
return true;
}
}
return false;
}
AliasInfo aliasInfo = queryBuilder.aliasManager.getAliasInfo(expression);
if (aliasInfo == null) {
List<SelectInfo> selectInfos = queryBuilder.selectManager.getSelectInfos();
if (selectInfos.size() > 1) {
throw new IllegalArgumentException("Can't order by an attribute when having multiple select items! Use a select alias!");
}
JoinNode rootNode;
if (selectInfos.isEmpty()) {
rootNode = queryBuilder.joinManager.getRootNodeOrFail("Can't order by an attribute when having multiple query roots! Use a select alias!");
} else {
if (!(selectInfos.get(0).get() instanceof PathExpression)) {
throw new IllegalArgumentException("Can't order by an attribute when the select item is a complex expression! Use a select alias!");
}
rootNode = (JoinNode) ((PathExpression) selectInfos.get(0).get()).getBaseNode();
}
if (JpaMetamodelUtils.getAttribute(rootNode.getManagedType(), expression) == null) {
throw new IllegalArgumentException("The attribute '" + expression + "' does not exist on the type '" + rootNode.getJavaType().getName() + "'! Did you maybe forget to use a select alias?");
}
List<PathElementExpression> path = new ArrayList<>(2);
path.add(new PropertyExpression(rootNode.getAlias()));
path.add(new PropertyExpression(expression));
return joinManager.hasFullJoin() || ExpressionUtils.isNullable(getMetamodel(), queryBuilder.functionalDependencyAnalyzerVisitor.getConstantifiedJoinNodeAttributeCollector(), new PathExpression(path, new SimplePathReference(rootNode, expression, null), false, false));
} else {
return joinManager.hasFullJoin() || ExpressionUtils.isNullable(getMetamodel(), queryBuilder.functionalDependencyAnalyzerVisitor.getConstantifiedJoinNodeAttributeCollector(), ((SelectInfo) aliasInfo).getExpression());
}
}
use of com.blazebit.persistence.parser.expression.PathExpression in project blaze-persistence by Blazebit.
the class EntitySelectResolveVisitor method visit.
@Override
public void visit(PathExpression expression) {
if (expression.getField() == null) {
/**
* We need to resolve entity selects because hibernate will
* select every entity attribute. Since we need every select in
* the group by (because of DB2) we need to resolve such entity
* selects here
*/
rootNode = ((JoinNode) expression.getBaseNode());
if (rootNode == null) {
// This is an alias expression to a complex expression
return;
}
EntityType<?> entityType = m.getEntity(rootNode.getJavaType());
if (entityType == null) {
// ignore if the expression is not an entity
return;
}
// TODO: a polymorphic query will fail because we don't collect subtype properties
ExtendedManagedType<?> extendedManagedType = m.getManagedType(ExtendedManagedType.class, entityType);
Set<String> attributePaths;
if (rootNode.getValuesIdNames() != null && !rootNode.getValuesIdNames().isEmpty()) {
attributePaths = rootNode.getValuesIdNames();
} else {
attributePaths = Collections.emptySet();
}
Map<String, ExtendedAttribute<?, ?>> ownedSingularAttributes = (Map<String, ExtendedAttribute<?, ?>>) (Map) extendedManagedType.getOwnedSingularAttributes();
Collection<String> propertyPaths = JpaUtils.getEmbeddedPropertyPaths(ownedSingularAttributes, null, jpaProvider.needsElementCollectionIdCutoff(), true);
for (String propertyPath : propertyPaths) {
// Skip if the attribute is not in the desired attribute paths
if (!attributePaths.isEmpty() && !attributePaths.contains(propertyPath)) {
continue;
}
ExtendedAttribute<?, ?> extendedAttribute = ownedSingularAttributes.get(propertyPath);
Attribute<?, ?> attr = extendedAttribute.getAttribute();
boolean resolve = false;
if (JpaMetamodelUtils.isAssociation(attr) && !attr.isCollection()) {
resolve = true;
} else if (ExpressionUtils.getFetchType(attr) == FetchType.EAGER) {
if (attr.getPersistentAttributeType() == Attribute.PersistentAttributeType.ELEMENT_COLLECTION) {
throw new UnsupportedOperationException("Eager element collections are not supported");
}
resolve = true;
}
if (resolve) {
List<PathElementExpression> paths = new ArrayList<>(expression.getExpressions().size() + 1);
paths.addAll(expression.getExpressions());
for (Attribute<?, ?> attribute : extendedAttribute.getAttributePath()) {
paths.add(new PropertyExpression(attribute.getName()));
}
PathExpression attrPath = new PathExpression(paths);
attrPath.setPathReference(new SimplePathReference(rootNode, propertyPath, m.type(extendedAttribute.getElementClass())));
pathExpressions.add(attrPath);
}
}
}
}
use of com.blazebit.persistence.parser.expression.PathExpression in project blaze-persistence by Blazebit.
the class SizeTransformationVisitor method generateSubquery.
private SubqueryExpression generateSubquery(PathExpression sizeArg) {
JoinNode sizeArgJoin = (JoinNode) sizeArg.getBaseNode();
final Type<?> nodeType = sizeArgJoin.getNodeType();
if (!(nodeType instanceof EntityType<?>)) {
throw new IllegalArgumentException("Size on a collection owned by a non-entity type is not supported yet: " + sizeArg);
}
final EntityType<?> startType = (EntityType<?>) nodeType;
Subquery countSubquery = (Subquery) subqueryInitFactory.createSubqueryInitiator(null, new SubqueryBuilderListenerImpl<>(), false, getClause()).from(sizeArg.getPathReference().toString()).select("COUNT(*)");
for (SingularAttribute<?, ?> idAttribute : JpaMetamodelUtils.getIdAttributes(startType)) {
String groupByExprString = sizeArgJoin.getAlias() + "." + idAttribute.getName();
ResolvedExpression groupByExpr = new ResolvedExpression(groupByExprString, null);
Set<ClauseType> clauseTypes = subqueryGroupBys.get(groupByExpr);
if (clauseTypes == null) {
List<PathElementExpression> pathElementExpressions = new ArrayList<>(2);
pathElementExpressions.add(new PropertyExpression(sizeArgJoin.getAlias()));
pathElementExpressions.add(new PropertyExpression(idAttribute.getName()));
PathExpression pathExpression = new PathExpression(pathElementExpressions);
pathExpression.setPathReference(new SimplePathReference(sizeArgJoin, idAttribute.getName(), metamodel.type(JpaMetamodelUtils.resolveFieldClass(startType.getJavaType(), idAttribute))));
groupByExpr = new ResolvedExpression(groupByExprString, pathExpression);
subqueryGroupBys.put(groupByExpr, EnumSet.of(clause));
} else {
clauseTypes.add(clause);
}
}
return new SubqueryExpression(countSubquery);
}
use of com.blazebit.persistence.parser.expression.PathExpression in project blaze-persistence by Blazebit.
the class PathTargetResolvingExpressionVisitor method visit.
@Override
public void visit(TreatExpression expression) {
boolean handled = false;
if (expression.getExpression() instanceof PathExpression) {
PathExpression treatPath = (PathExpression) expression.getExpression();
if (treatPath.getExpressions().size() == 1 && rootTypes.containsKey(treatPath.getExpressions().get(0).toString())) {
// When we encounter a naked root treat like "TREAT(alias AS Subtype)" we always skip it
handled = true;
}
}
if (!handled) {
expression.getExpression().accept(this);
}
EntityType<?> type = metamodel.getEntity(expression.getType());
// TODO: should we check if the type is actually a sub- or super type?
currentPosition.setCurrentType(type);
currentPosition.setValueType(type);
}
use of com.blazebit.persistence.parser.expression.PathExpression in project blaze-persistence by Blazebit.
the class AliasReplacementVisitor method visit.
@Override
public Expression visit(PathExpression expression) {
List<PathElementExpression> expressions = expression.getExpressions();
int size = expressions.size();
if (size == 1) {
PathElementExpression elementExpression = expressions.get(0);
if (elementExpression instanceof PropertyExpression) {
if (alias.equals(((PropertyExpression) elementExpression).getProperty())) {
Expression newExpression = substitute.copy(ExpressionCopyContext.EMPTY);
if (newExpression instanceof PathExpression) {
PathExpression newPathExpression = (PathExpression) newExpression;
newPathExpression.setUsedInCollectionFunction(expression.isUsedInCollectionFunction());
newPathExpression.setCollectionQualifiedPath(expression.isCollectionQualifiedPath());
}
return newExpression;
}
}
} else {
PathExpression leftMost = ExpressionUtils.getLeftMostPathExpression(expression);
if (leftMost.getExpressions().get(0) instanceof PropertyExpression && alias.equals(((PropertyExpression) leftMost.getExpressions().get(0)).getProperty())) {
if (substitute instanceof PathExpression) {
leftMost.getExpressions().remove(0);
leftMost.getExpressions().addAll(0, ((PathExpression) substitute).getExpressions());
} else {
leftMost.getExpressions().set(0, (PathElementExpression) substitute);
}
}
}
return expression;
}
Aggregations