diff options
Diffstat (limited to 'config-model/src/main/java/com/yahoo/schema/expressiontransforms/BooleanExpressionTransformer.java')
-rw-r--r-- | config-model/src/main/java/com/yahoo/schema/expressiontransforms/BooleanExpressionTransformer.java | 32 |
1 files changed, 24 insertions, 8 deletions
diff --git a/config-model/src/main/java/com/yahoo/schema/expressiontransforms/BooleanExpressionTransformer.java b/config-model/src/main/java/com/yahoo/schema/expressiontransforms/BooleanExpressionTransformer.java index ad050d4ca63..49fb48225e7 100644 --- a/config-model/src/main/java/com/yahoo/schema/expressiontransforms/BooleanExpressionTransformer.java +++ b/config-model/src/main/java/com/yahoo/schema/expressiontransforms/BooleanExpressionTransformer.java @@ -36,12 +36,12 @@ public class BooleanExpressionTransformer extends ExpressionTransformer<Transfor node = transformChildren(composite, context); if (node instanceof OperationNode arithmetic) - node = transformBooleanArithmetics(arithmetic); + node = transformBooleanArithmetics(arithmetic, context); return node; } - private ExpressionNode transformBooleanArithmetics(OperationNode node) { + private ExpressionNode transformBooleanArithmetics(OperationNode node, TransformContext context) { Iterator<ExpressionNode> child = node.children().iterator(); // Transform in precedence order: @@ -51,24 +51,25 @@ public class BooleanExpressionTransformer extends ExpressionTransformer<Transfor Operator op = it.next(); if ( ! stack.isEmpty()) { while (stack.size() > 1 && ! op.hasPrecedenceOver(stack.peek().op)) { - popStack(stack); + popStack(stack, context); } } stack.push(new ChildNode(op, child.next())); } while (stack.size() > 1) - popStack(stack); + popStack(stack, context); return stack.getFirst().child; } - private void popStack(Deque<ChildNode> stack) { + private void popStack(Deque<ChildNode> stack, TransformContext context) { ChildNode rhs = stack.pop(); ChildNode lhs = stack.peek(); + boolean primitives = isDefinitelyPrimitive(lhs.child, context) && isDefinitelyPrimitive(rhs.child, context); ExpressionNode combination; - if (rhs.op == Operator.and) + if (primitives && rhs.op == Operator.and) combination = andByIfNode(lhs.child, rhs.child); - else if (rhs.op == Operator.or) + else if (primitives && rhs.op == Operator.or) combination = orByIfNode(lhs.child, rhs.child); else { combination = resolve(lhs, rhs); @@ -77,6 +78,22 @@ public class BooleanExpressionTransformer extends ExpressionTransformer<Transfor lhs.child = combination; } + private boolean isDefinitelyPrimitive(ExpressionNode node, TransformContext context) { + try { + return node.type(context.types()).rank() == 0; + } + catch (IllegalArgumentException e) { + // Types can only be reliably resolved top down, which has not done here. + // E.g + // function(nameArg) { + // attribute(nameArg) + // } + // is supported. + // So, we return false when something cannot be resolved. + return false; + } + } + private static OperationNode resolve(ChildNode left, ChildNode right) { if (! (left.child instanceof OperationNode) && ! (right.child instanceof OperationNode)) return new OperationNode(left.child, right.op, right.child); @@ -103,7 +120,6 @@ public class BooleanExpressionTransformer extends ExpressionTransformer<Transfor joinedChildren.add(node.child); } - private IfNode andByIfNode(ExpressionNode a, ExpressionNode b) { return new IfNode(a, b, new ConstantNode(new BooleanValue(false))); } |