Search in sources :

Example 21 with PathExpression

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());
    }
}
Also used : ArrayList(java.util.ArrayList) PathElementExpression(com.blazebit.persistence.parser.expression.PathElementExpression) PathExpression(com.blazebit.persistence.parser.expression.PathExpression) PropertyExpression(com.blazebit.persistence.parser.expression.PropertyExpression)

Example 22 with PathExpression

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);
            }
        }
    }
}
Also used : ExtendedAttribute(com.blazebit.persistence.spi.ExtendedAttribute) ArrayList(java.util.ArrayList) PathElementExpression(com.blazebit.persistence.parser.expression.PathElementExpression) PathExpression(com.blazebit.persistence.parser.expression.PathExpression) PropertyExpression(com.blazebit.persistence.parser.expression.PropertyExpression) Map(java.util.Map)

Example 23 with PathExpression

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);
}
Also used : JoinNode(com.blazebit.persistence.impl.JoinNode) SubqueryBuilderListenerImpl(com.blazebit.persistence.impl.SubqueryBuilderListenerImpl) ResolvedExpression(com.blazebit.persistence.impl.ResolvedExpression) ArrayList(java.util.ArrayList) Subquery(com.blazebit.persistence.parser.expression.Subquery) SubqueryExpression(com.blazebit.persistence.parser.expression.SubqueryExpression) EntityType(javax.persistence.metamodel.EntityType) PathElementExpression(com.blazebit.persistence.parser.expression.PathElementExpression) PathExpression(com.blazebit.persistence.parser.expression.PathExpression) PropertyExpression(com.blazebit.persistence.parser.expression.PropertyExpression) SimplePathReference(com.blazebit.persistence.impl.SimplePathReference) ClauseType(com.blazebit.persistence.impl.ClauseType)

Example 24 with PathExpression

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);
}
Also used : PathExpression(com.blazebit.persistence.parser.expression.PathExpression)

Example 25 with PathExpression

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;
}
Also used : PathElementExpression(com.blazebit.persistence.parser.expression.PathElementExpression) PathExpression(com.blazebit.persistence.parser.expression.PathExpression) PropertyExpression(com.blazebit.persistence.parser.expression.PropertyExpression) Expression(com.blazebit.persistence.parser.expression.Expression) PathExpression(com.blazebit.persistence.parser.expression.PathExpression) PathElementExpression(com.blazebit.persistence.parser.expression.PathElementExpression) PropertyExpression(com.blazebit.persistence.parser.expression.PropertyExpression)

Aggregations

PathExpression (com.blazebit.persistence.parser.expression.PathExpression)55 PropertyExpression (com.blazebit.persistence.parser.expression.PropertyExpression)37 PathElementExpression (com.blazebit.persistence.parser.expression.PathElementExpression)29 Expression (com.blazebit.persistence.parser.expression.Expression)27 FunctionExpression (com.blazebit.persistence.parser.expression.FunctionExpression)26 SubqueryExpression (com.blazebit.persistence.parser.expression.SubqueryExpression)22 MapKeyExpression (com.blazebit.persistence.parser.expression.MapKeyExpression)21 ArrayExpression (com.blazebit.persistence.parser.expression.ArrayExpression)20 ParameterExpression (com.blazebit.persistence.parser.expression.ParameterExpression)19 ArrayList (java.util.ArrayList)17 ListIndexExpression (com.blazebit.persistence.parser.expression.ListIndexExpression)16 TreatExpression (com.blazebit.persistence.parser.expression.TreatExpression)16 MapValueExpression (com.blazebit.persistence.parser.expression.MapValueExpression)15 GeneralCaseExpression (com.blazebit.persistence.parser.expression.GeneralCaseExpression)11 MapEntryExpression (com.blazebit.persistence.parser.expression.MapEntryExpression)11 QualifiedExpression (com.blazebit.persistence.parser.expression.QualifiedExpression)10 ExtendedManagedType (com.blazebit.persistence.spi.ExtendedManagedType)10 EntityType (javax.persistence.metamodel.EntityType)10 PathReference (com.blazebit.persistence.parser.expression.PathReference)8 NullExpression (com.blazebit.persistence.parser.expression.NullExpression)7