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;
}
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(')');
}
}
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");
}
}
}
}
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;
}
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;
}
Aggregations