use of com.blazebit.persistence.parser.expression.PathExpression in project blaze-persistence by Blazebit.
the class JoinManager method generateAndApplyOnPredicate.
private void generateAndApplyOnPredicate(JoinNode joinNode, ArrayExpression arrayExpr) {
PathExpression joinAliasPathExpression = new PathExpression(new PropertyExpression(joinNode.getAlias()));
arrayExpr.getIndex().accept(new AliasReplacementVisitor(joinAliasPathExpression, ArrayExpression.ELEMENT_NAME));
Predicate filterPredicate = getArrayExpressionPredicate(joinNode, arrayExpr);
// Array expression predicates get a different root, normal expressions not
ClauseType fromClause = joinVisitor.getFromClause();
JoinNode currentJoinNode = joinVisitor.getCurrentJoinNode();
CompoundPredicate currentPred = joinNode.getOnPredicate();
boolean newPredicate = false;
if (currentPred != null) {
// Only add the predicate if it isn't contained yet
if (!findPredicate(currentPred, filterPredicate, joinNode.getAlias())) {
currentPred.getChildren().add(filterPredicate);
newPredicate = true;
}
} else {
CompoundPredicate onAndPredicate = new CompoundPredicate(CompoundPredicate.BooleanOperator.AND);
onAndPredicate.getChildren().add(filterPredicate);
joinNode.setOnPredicate(onAndPredicate);
newPredicate = true;
}
try {
joinVisitor.setFromClause(ClauseType.JOIN);
joinVisitor.setCurrentJoinNode(joinNode);
if (arrayExpr.getIndex() instanceof Predicate) {
JoinNode oldRootNode = rootNode;
try {
rootNode = joinNode;
joinNode.accept(joinVisitor);
} finally {
rootNode = oldRootNode;
}
} else {
arrayExpr.getIndex().accept(joinVisitor);
}
} finally {
joinVisitor.setFromClause(fromClause);
joinVisitor.setCurrentJoinNode(currentJoinNode);
}
if (newPredicate) {
joinNode.registerDependencies();
joinNode.updateClauseDependencies(ClauseType.JOIN, new LinkedHashSet<JoinNode>());
}
}
use of com.blazebit.persistence.parser.expression.PathExpression in project blaze-persistence by Blazebit.
the class JoinManager method join.
JoinNode join(Expression expr, String alias, JoinType type, boolean fetch, boolean defaultJoin, String deReferenceFunction) {
PathElementExpression elementExpr;
String treatType = null;
JoinResult result;
JoinNode current;
if (type == JoinType.FULL) {
hasFullJoin = true;
}
if (expr instanceof PathExpression) {
PathExpression pathExpression = (PathExpression) expr;
if (isExternal(pathExpression) || isJoinableSelectAlias(pathExpression, false, false)) {
throw new IllegalArgumentException("No external path or select alias allowed in join path");
}
List<PathElementExpression> pathElements = pathExpression.getExpressions();
elementExpr = pathElements.get(pathElements.size() - 1);
result = implicitJoin(null, pathExpression, null, null, null, new HashSet<String>(), 0, pathElements.size() - 1, false, true, true, false);
current = result.baseNode;
} else if (expr instanceof QualifiedExpression) {
elementExpr = (PathElementExpression) expr;
result = null;
current = null;
} else if (expr instanceof TreatExpression) {
TreatExpression treatExpression = (TreatExpression) expr;
if (isExternal(treatExpression)) {
throw new IllegalArgumentException("No external path or select alias allowed in join path");
}
Expression expression = treatExpression.getExpression();
if (expression instanceof PathExpression) {
PathExpression pathExpression = (PathExpression) expression;
List<PathElementExpression> pathElements = pathExpression.getExpressions();
elementExpr = pathElements.get(pathElements.size() - 1);
result = implicitJoin(null, pathExpression, null, null, null, new HashSet<String>(), 0, pathElements.size() - 1, false, true, true, false);
current = result.baseNode;
treatType = treatExpression.getType();
} else {
throw new IllegalArgumentException("Unexpected expression type[" + expression.getClass().getSimpleName() + "] in treat expression: " + treatExpression);
}
} else {
throw new IllegalArgumentException("Join path [" + expr + "] is not a path");
}
if (elementExpr instanceof ArrayExpression) {
ArrayExpression arrayExpr = (ArrayExpression) elementExpr;
implicitJoinIndex(arrayExpr);
if (arrayExpr.getBase() instanceof PropertyExpression) {
List<String> resultFields = result.addToList(new ArrayList<String>());
current = current == null ? getRootNodeOrFail("Could not join path [", expr, "] because it did not use an absolute path but multiple root nodes are available!") : current;
resultFields.add(arrayExpr.getBase().toString());
result = createOrUpdateNode(current, resultFields, treatType, alias, type, null, false, defaultJoin, true, true);
} else {
Class<?> entityClass = ((EntityLiteral) arrayExpr.getBase()).getValue();
joinOn(null, rootNodes.get(0).getAlias(), entityClass, alias, JoinType.LEFT, false).end();
result = new JoinResult(((JoinAliasInfo) aliasManager.getAliasInfo(alias)).getJoinNode());
}
generateAndApplyOnPredicate(result.baseNode, arrayExpr);
} else if (elementExpr instanceof MapKeyExpression) {
MapKeyExpression mapKeyExpression = (MapKeyExpression) elementExpr;
boolean fromSubquery = false;
boolean fromSelectAlias = false;
boolean joinRequired = true;
current = joinMapKey(mapKeyExpression, alias, null, new HashSet<String>(), fromSubquery, fromSelectAlias, joinRequired, fetch, false, defaultJoin);
result = new JoinResult(current);
} else {
List<String> joinRelationAttributes = result.addToList(new ArrayList<String>());
joinRelationAttributes.add(elementExpr.toString());
current = current == null ? getRootNodeOrFail("Could not join path [", expr, "] because it did not use an absolute path but multiple root nodes are available!") : current;
result = createOrUpdateNode(current, joinRelationAttributes, treatType, alias, type, null, false, defaultJoin, true, true);
}
result.baseNode.setDeReferenceFunction(deReferenceFunction);
if (fetch) {
fetchPath(result.baseNode);
}
return result.baseNode;
}
use of com.blazebit.persistence.parser.expression.PathExpression in project blaze-persistence by Blazebit.
the class JoinManager method getArrayExpressionPredicate.
private Predicate getArrayExpressionPredicate(JoinNode joinNode, ArrayExpression arrayExpr) {
if (arrayExpr.getIndex() instanceof Predicate) {
return (Predicate) arrayExpr.getIndex();
} else {
PathExpression keyPath = new PathExpression(new ArrayList<PathElementExpression>(), true);
keyPath.getExpressions().add(new PropertyExpression(joinNode.getAliasInfo().getAlias()));
keyPath.setPathReference(new SimplePathReference(joinNode, null, joinNode.getNodeType()));
Attribute<?, ?> arrayBaseAttribute = joinNode.getParentTreeNode().getAttribute();
Expression keyExpression;
if (arrayBaseAttribute instanceof ListAttribute<?, ?>) {
keyExpression = new ListIndexExpression(keyPath);
} else {
keyExpression = new MapKeyExpression(keyPath);
}
return new EqPredicate(keyExpression, arrayExpr.getIndex());
}
}
use of com.blazebit.persistence.parser.expression.PathExpression in project blaze-persistence by Blazebit.
the class JoinManager method getJoinableSelectAlias.
public Expression getJoinableSelectAlias(PathExpression pathExpr, boolean fromSelect, boolean fromSubquery) {
// We can skip this check if the first element is not a simple property
if (!(pathExpr.getExpressions().get(0) instanceof PropertyExpression)) {
return null;
}
boolean singlePathElement = pathExpr.getExpressions().size() == 1;
String startAlias = pathExpr.getExpressions().get(0).toString();
AliasInfo aliasInfo = aliasManager.getAliasInfo(startAlias);
if (aliasInfo == null) {
return null;
}
if (aliasInfo instanceof SelectInfo) {
// select alias
if (!singlePathElement) {
throw new IllegalStateException("Path starting with select alias not allowed");
}
// might be joinable
Expression expression = ((SelectInfo) aliasInfo).getExpression();
// If the expression the alias refers to and the expression are the same, we are resolving an ambiguous alias expression
if (expression == pathExpr) {
return null;
}
return expression;
}
return null;
}
use of com.blazebit.persistence.parser.expression.PathExpression in project blaze-persistence by Blazebit.
the class JoinNode method createExpression.
public Expression createExpression(String field, boolean asPath) {
List<PathElementExpression> pathElements = new ArrayList<>();
if (qualificationExpression != null) {
List<PathElementExpression> pathElementExpressions = new ArrayList<>(1);
pathElementExpressions.add(new PropertyExpression(parent.getAlias()));
PathExpression path = new PathExpression(pathElementExpressions);
if ("KEY".equalsIgnoreCase(qualificationExpression)) {
pathElements.add(new MapKeyExpression(path));
} else if ("INDEX".equalsIgnoreCase(qualificationExpression)) {
pathElements.add(new ListIndexExpression(path));
} else if ("ENTRY".equalsIgnoreCase(qualificationExpression)) {
pathElements.add(new MapEntryExpression(path));
}
} else {
pathElements.add(new PropertyExpression(aliasInfo.getAlias()));
}
if (field != null) {
for (String fieldPart : field.split("\\.")) {
pathElements.add(new PropertyExpression(fieldPart));
}
}
if (!asPath && valuesTypeName != null) {
return new FunctionExpression("FUNCTION", Arrays.asList(new StringLiteral("TREAT_" + valuesTypeName.toUpperCase()), new PathExpression(pathElements)));
} else {
return new PathExpression(pathElements);
}
}
Aggregations