Search in sources :

Example 11 with PathExpression

use of com.blazebit.persistence.parser.expression.PathExpression in project blaze-persistence by Blazebit.

the class ResolvingQueryGenerator method visit.

@Override
public void visit(InPredicate predicate) {
    boolean quantifiedPredicate = this.quantifiedPredicate;
    this.quantifiedPredicate = true;
    if (predicate.getRight().size() == 1 && jpaProvider.needsAssociationToIdRewriteInOnClause() && clauseType == ClauseType.JOIN) {
        Expression right = predicate.getRight().get(0);
        if (right instanceof ParameterExpression) {
            ParameterExpression parameterExpression = (ParameterExpression) right;
            @SuppressWarnings("unchecked") Type<?> associationType = getAssociationType(predicate.getLeft(), right);
            // If the association type is a entity type, we transform it
            if (associationType instanceof EntityType<?>) {
                renderEquality(predicate.getLeft(), right, predicate.isNegated(), PredicateQuantifier.ONE);
            } else {
                super.visit(predicate);
            }
        } else if (right instanceof PathExpression) {
            renderEquality(predicate.getLeft(), right, predicate.isNegated(), PredicateQuantifier.ONE);
        } else {
            super.visit(predicate);
        }
    } else {
        super.visit(predicate);
    }
    this.quantifiedPredicate = quantifiedPredicate;
}
Also used : EntityType(javax.persistence.metamodel.EntityType) PathExpression(com.blazebit.persistence.parser.expression.PathExpression) ListIndexExpression(com.blazebit.persistence.parser.expression.ListIndexExpression) Expression(com.blazebit.persistence.parser.expression.Expression) QualifiedExpression(com.blazebit.persistence.parser.expression.QualifiedExpression) TreatExpression(com.blazebit.persistence.parser.expression.TreatExpression) ParameterExpression(com.blazebit.persistence.parser.expression.ParameterExpression) ArithmeticExpression(com.blazebit.persistence.parser.expression.ArithmeticExpression) PathExpression(com.blazebit.persistence.parser.expression.PathExpression) AggregateExpression(com.blazebit.persistence.parser.expression.AggregateExpression) ArrayExpression(com.blazebit.persistence.parser.expression.ArrayExpression) FunctionExpression(com.blazebit.persistence.parser.expression.FunctionExpression) SubqueryExpression(com.blazebit.persistence.parser.expression.SubqueryExpression) MapValueExpression(com.blazebit.persistence.parser.expression.MapValueExpression) NullExpression(com.blazebit.persistence.parser.expression.NullExpression) MapKeyExpression(com.blazebit.persistence.parser.expression.MapKeyExpression) ParameterExpression(com.blazebit.persistence.parser.expression.ParameterExpression)

Example 12 with PathExpression

use of com.blazebit.persistence.parser.expression.PathExpression in project blaze-persistence by Blazebit.

the class ResolvingQueryGenerator method visit.

@Override
public void visit(MapKeyExpression expression) {
    PathExpression path = expression.getPath();
    String deReferenceFunction = null;
    if (!externalRepresentation && path.getPathReference() != null && (deReferenceFunction = ((JoinNode) path.getPathReference().getBaseNode()).getDeReferenceFunction()) != null) {
        sb.append(deReferenceFunction);
    }
    sb.append("KEY(");
    path.accept(this);
    sb.append(')');
    if (deReferenceFunction != null) {
        sb.append(')');
    }
}
Also used : PathExpression(com.blazebit.persistence.parser.expression.PathExpression)

Example 13 with PathExpression

use of com.blazebit.persistence.parser.expression.PathExpression in project blaze-persistence by Blazebit.

the class ResolvingQueryGenerator method visit.

@Override
public void visit(PathExpression expression) {
    if (resolveSelectAliases && expression.getExpressions().size() == 1) {
        AliasInfo aliasInfo;
        String potentialAlias = expression.getExpressions().get(0).toString();
        try {
            if (currentlyResolvingAliases.add(potentialAlias) && (aliasInfo = aliasManager.getAliasInfo(potentialAlias)) != null) {
                if (aliasInfo instanceof SelectInfo) {
                    SelectInfo selectAliasInfo = (SelectInfo) aliasInfo;
                    if (selectAliasInfo.getExpression() instanceof PathExpression) {
                        PathExpression aliasedExpression = (PathExpression) selectAliasInfo.getExpression();
                        boolean collectionKeyPath = aliasedExpression.isCollectionQualifiedPath();
                        boolean usedInCollectionFunction = aliasedExpression.isUsedInCollectionFunction();
                        aliasedExpression.setCollectionQualifiedPath(expression.isCollectionQualifiedPath());
                        aliasedExpression.setUsedInCollectionFunction(expression.isUsedInCollectionFunction());
                        try {
                            selectAliasInfo.getExpression().accept(this);
                        } finally {
                            aliasedExpression.setCollectionQualifiedPath(collectionKeyPath);
                            aliasedExpression.setUsedInCollectionFunction(usedInCollectionFunction);
                        }
                    } else {
                        selectAliasInfo.getExpression().accept(this);
                    }
                    return;
                }
            }
        } finally {
            currentlyResolvingAliases.remove(potentialAlias);
        }
    }
    JoinNode baseNode;
    String field;
    if ((baseNode = (JoinNode) expression.getBaseNode()) == null) {
        super.visit(expression);
    } else {
        String collectionValueFunction = jpaProvider.getCollectionValueFunction();
        if ((field = expression.getField()) == null) {
            if (expression.isUsedInCollectionFunction() || renderAbsolutePath(expression)) {
                super.visit(expression);
            } else {
                // NOTE: Hibernate uses the column from a join table if VALUE is used which is wrong, so drop the VALUE here
                boolean valueFunction = collectionValueFunction != null && needsValueFunction(expression, baseNode, field);
                if (valueFunction) {
                    sb.append(collectionValueFunction);
                    sb.append('(');
                }
                if (aliasPrefix != null) {
                    sb.append(aliasPrefix);
                }
                baseNode.appendAlias(sb, externalRepresentation);
                if (valueFunction) {
                    sb.append(')');
                }
            }
        } else {
            List<JoinNode> treatedJoinNodes = baseNode.getJoinNodesForTreatConstraint();
            Type<?> baseNodeType = baseNode.getBaseType();
            boolean addTypeCaseWhen = false;
            if (!treatedJoinNodes.isEmpty() && baseNodeType instanceof EntityType<?> && baseNode.getTreatType() != null && (jpaProvider.supportsSubtypePropertyResolving() || !jpaProvider.supportsRootTreat())) {
                ExtendedManagedType<?> extendedManagedType = entityMetamodel.getManagedType(ExtendedManagedType.class, baseNode.getTreatType().getName());
                ExtendedAttribute<?, ?> extendedAttribute = extendedManagedType.getAttributes().get(field);
                if (extendedAttribute.isColumnShared()) {
                    // To disambiguate shared column access, we also must use the type constraint
                    addTypeCaseWhen = jpaProvider.needsTypeConstraintForColumnSharing();
                } else {
                    // If the attribute is declared by an entity sub-type of the treat target type, we don't need the case when
                    ExtendedAttribute<?, ?> baseTypeAttribute = (ExtendedAttribute<?, ?>) entityMetamodel.getManagedType(ExtendedManagedType.class, ((EntityType<?>) baseNode.getBaseType()).getName()).getAttributes().get(field);
                    addTypeCaseWhen = baseTypeAttribute != null && !baseNode.getTreatType().getJavaType().isAssignableFrom(baseTypeAttribute.getAttributePath().get(0).getDeclaringType().getJavaType());
                }
            }
            if (addTypeCaseWhen) {
                sb.append("CASE WHEN ");
                boolean first = true;
                for (int i = 0; i < treatedJoinNodes.size(); i++) {
                    JoinNode treatedJoinNode = treatedJoinNodes.get(i);
                    // we skip the type constraint as that is already applied through the join
                    if (jpaProvider.supportsTreatJoin() && treatedJoinNode.isTreatJoinNode()) {
                        continue;
                    }
                    if (first) {
                        first = false;
                    } else {
                        sb.append(" AND ");
                    }
                    sb.append("TYPE(");
                    treatedJoinNode.appendAlias(sb, externalRepresentation);
                    sb.append(") IN (");
                    for (EntityType<?> entitySubtype : entityMetamodel.getEntitySubtypes(treatedJoinNode.getTreatType())) {
                        sb.append(entitySubtype.getName());
                        sb.append(", ");
                    }
                    sb.setLength(sb.length() - 2);
                    sb.append(')');
                }
                if (first) {
                    sb.setLength(sb.length() - "CASE WHEN ".length());
                    addTypeCaseWhen = false;
                } else {
                    sb.append(" THEN ");
                }
            }
            boolean valueFunction = collectionValueFunction != null && needsValueFunction(expression, baseNode, field);
            // NOTE: There is no need to check for whether the JPA provider support implicit downcasting here
            // If it didn't, the query building would have already failed before. Here we just decide whether to render the treat or not
            boolean renderTreat = jpaProvider.supportsRootTreat();
            if (valueFunction) {
                sb.append(collectionValueFunction);
                sb.append('(');
                if (aliasPrefix != null) {
                    sb.append(aliasPrefix);
                }
                baseNode.appendAlias(sb, renderTreat, externalRepresentation);
                sb.append(')');
                sb.append(".").append(field);
            } else {
                if (aliasPrefix != null) {
                    sb.append(aliasPrefix);
                }
                baseNode.appendDeReference(sb, field, renderTreat, externalRepresentation, jpaProvider.needsElementCollectionIdCutoff());
            }
            if (addTypeCaseWhen) {
                if (jpaProvider.needsCaseWhenElseBranch()) {
                    sb.append(" ELSE NULL");
                }
                sb.append(" END");
            }
        }
    }
}
Also used : ExtendedAttribute(com.blazebit.persistence.spi.ExtendedAttribute) ExtendedManagedType(com.blazebit.persistence.spi.ExtendedManagedType) EntityType(javax.persistence.metamodel.EntityType) PathExpression(com.blazebit.persistence.parser.expression.PathExpression)

Example 14 with PathExpression

use of com.blazebit.persistence.parser.expression.PathExpression in project blaze-persistence by Blazebit.

the class SplittingVisitor method visit.

@Override
public Expression visit(MapKeyExpression expression) {
    if (expression == expressionToSplit) {
        List<PathElementExpression> expressions = new ArrayList<>(2);
        expressions.add(expression);
        for (String subAttributePart : subAttribute.split("\\.")) {
            expressions.add(new PropertyExpression(subAttributePart));
        }
        JoinNode node = ((JoinNode) expression.getPath().getBaseNode()).getKeyJoinNode();
        String field = subAttribute;
        Class<?> fieldClass = jpaProvider.getJpaMetamodelAccessor().getAttributePath(metamodel, node.getManagedType(), field).getAttributeClass();
        Type<?> fieldType = metamodel.type(fieldClass);
        return new PathExpression(expressions, new SimplePathReference(node, field, fieldType), false, false);
    }
    return expression;
}
Also used : PathElementExpression(com.blazebit.persistence.parser.expression.PathElementExpression) PathExpression(com.blazebit.persistence.parser.expression.PathExpression) ArrayList(java.util.ArrayList) PropertyExpression(com.blazebit.persistence.parser.expression.PropertyExpression)

Example 15 with PathExpression

use of com.blazebit.persistence.parser.expression.PathExpression in project blaze-persistence by Blazebit.

the class JpqlMacroAwareExpressionFactory method createJoinPathExpression.

@Override
public Expression createJoinPathExpression(String expression, MacroConfiguration macroConfiguration, Set<String> usedMacros) {
    Expression pathExpression = createPathExpression(expression, macroConfiguration, usedMacros);
    if (pathExpression instanceof PathExpression) {
        List<PathElementExpression> expressions = ((PathExpression) pathExpression).getExpressions();
        PathElementExpression first;
        if (expressions.size() > 1 || (first = expressions.get(0)) instanceof PropertyExpression || first instanceof ArrayExpression) {
            return pathExpression;
        }
        return first;
    }
    return pathExpression;
}
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) ArrayExpression(com.blazebit.persistence.parser.expression.ArrayExpression) PathElementExpression(com.blazebit.persistence.parser.expression.PathElementExpression) ArrayExpression(com.blazebit.persistence.parser.expression.ArrayExpression) 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