private static SimpleConditionList contains(Criteria criteria, FunctionCallNode call, SimpleOperator operator) { ResourceId field = parseFieldId(call.getArgument(0)); List<SimpleCondition> conditions = new ArrayList<>(); for (int i = 1; i < call.getArguments().size(); i++) { conditions.add(new SimpleCondition(field, operator, parseEnum(call.getArgument(i)))); } return new SimpleConditionList(criteria, conditions); }
private static void findBinaryTree(FormulaNode node, List<FormulaNode> list, FormulaFunction operator) { // Unwrap group expressions ((A)) node = simplify(node); if(isBinaryOperation(node, operator)) { // If this expression is in the form A && B, then descend // recursively FunctionCallNode callNode = (FunctionCallNode) node; findBinaryTree(callNode.getArgument(0), list, operator); findBinaryTree(callNode.getArgument(1), list, operator); } else { // If not a conjunction, then add this node to the list list.add(node); } }
private static boolean filterContainsPartner(String filter, ResourceId partnerFormId, ResourceId partnerId) { FormulaNode filterFormula = FormulaParser.parse(filter); SymbolNode expectedPartnerForm = new SymbolNode(partnerFormId); ConstantNode expectedPartnerRecord = new ConstantNode(partnerId.asString()); if (!(filterFormula instanceof FunctionCallNode)) { return false; } if (!(((FunctionCallNode) filterFormula).getFunction() instanceof EqualFunction)) { return false; } if (((FunctionCallNode) filterFormula).getArgumentCount() != 2) { return false; } FunctionCallNode equalFunctionCall = (FunctionCallNode) filterFormula; if (!(equalFunctionCall.getArgument(0 ) instanceof SymbolNode)) { return false; } if (!(equalFunctionCall.getArgument(1) instanceof ConstantNode)) { return false; } SymbolNode partnerFormNode = (SymbolNode) equalFunctionCall.getArgument(0); ConstantNode partnerFieldNode = (ConstantNode) equalFunctionCall.getArgument(1); if (!partnerFormNode.equals(expectedPartnerForm)) { return false; } if (!partnerFieldNode.equals(expectedPartnerRecord)) { return false; } return true; }
private static SimpleCondition parseCondition(FormulaNode node) { if(node instanceof GroupNode) { return parseCondition(((GroupNode) node).getExpr()); } else if(node instanceof FunctionCallNode) { FunctionCallNode callNode = ((FunctionCallNode) node); if(callNode.getFunction() == NotFunction.INSTANCE) { return parseCondition(callNode.getArgument(0)).negate(); } else if(callNode.getArguments().size() == 2) { return parseBinary(((FunctionCallNode) node)); } else { throw new UnsupportedOperationException("function: " + ((FunctionCallNode) node).getFunction()); } } else if(node instanceof CompoundExpr) { return parseEnumCondition((CompoundExpr) node); } else { throw new UnsupportedOperationException("cannot handle expression: " + node); } }
private boolean parseComparison(FormulaNode node, Multimap<Integer, FilterConfig> result) { if(!(node instanceof FunctionCallNode)) { return false; } // Check that this is a binary FunctionCallNode callNode = (FunctionCallNode) node; if(callNode.getArgumentCount() != 2) { return false; } // Does this comparison involve one of our fields? Integer columnIndex = findColumnIndex(callNode.getArgument(0)); if(columnIndex == null) { return false; } // Is it compared with a constant value? FieldValue value = parseLiteral(callNode.getArgument(1)); if(value == null) { return false; } FilterConfig config; if(value instanceof Quantity) { config = numericFilter(callNode, (Quantity) value); } else if(value instanceof LocalDate) { config = dateFilter(callNode, (LocalDate) value); } else { return false; } result.put(columnIndex, config); return true; }
private static SimpleCondition parseBinary(FunctionCallNode call) { ResourceId fieldId = parseFieldId(call.getArgument(0)); SimpleOperator op = parseOp(call.getFunction()); FieldValue fieldValue = parseFieldValue(call.getArgument(1)); return new SimpleCondition(fieldId, op, fieldValue); }
@Override public Slot<ColumnView> visitFunctionCall(final FunctionCallNode call) { if(call.getFunction() instanceof ColumnFunction) { if(call.getArguments().isEmpty()) { return createNullaryFunctionCall(call); } else { return createFunctionCall(call); } } else if(call.getFunction() instanceof BoundingBoxFunction) { FormulaNode geometry = call.getArgument(0); Collection<NodeMatch> nodes; if(geometry instanceof SymbolNode) { nodes = resolver.resolveSymbol(((SymbolNode) geometry)); } else if(geometry instanceof CompoundExpr) { nodes = resolver.resolveCompoundExpr((CompoundExpr) geometry); } else { throw new QuerySyntaxException("Function " + call.getFunction().getId() + " can only be applied" + " to an argument of type GeoArea."); } return addColumn(nodes.stream().map(n -> n.withComponent(call.getFunction().getId())).collect(Collectors.toList())); } else { throw new UnsupportedOperationException("TODO: " + call.getFunction().getId()); } }
return false; FormulaNode isNumberArgument = Formulas.simplify(isNumberCall.getArgument(0)); if(!(isNumberArgument instanceof FunctionCallNode)) { return false; return false; FieldValue substring = parseLiteral(searchCall.getArgument(0)); if(!(substring instanceof HasStringValue)) { return false; FormulaNode columnExpr = searchCall.getArgument(1); Integer columnIndex = columnMap.get(columnExpr); if(columnIndex == -1) {
/** * If this node is a literal value, for example "abc" or 42.0 or * DATE(2017, 1, 1), then return its value. Otherwise return {@code null}. */ private FieldValue parseLiteral(FormulaNode node) { if(node instanceof ConstantNode) { return ((ConstantNode) node).getValue(); } else if(node instanceof FunctionCallNode) { FunctionCallNode callNode = (FunctionCallNode) node; if(callNode.getFunction() == DateFunction.INSTANCE) { FieldValue year = parseLiteral(callNode.getArgument(0)); FieldValue month = parseLiteral(callNode.getArgument(1)); FieldValue day = parseLiteral(callNode.getArgument(2)); if(year != null && month != null || day != null) { return DateFunction.apply(year, month, day); } } } return null; }
private static void parse(List<SimpleCondition> conditions, Set<Criteria> criteria, FormulaNode node) { if(node instanceof GroupNode) { parse(conditions, criteria, ((GroupNode) node).getExpr()); return; } if(node instanceof FunctionCallNode) { FunctionCallNode call = (FunctionCallNode) node; if (call.getFunction() == AndFunction.INSTANCE) { criteria.add(Criteria.ALL_TRUE); parse(conditions, criteria, call.getArgument(0)); parse(conditions, criteria, call.getArgument(1)); return; } else if (call.getFunction() == OrFunction.INSTANCE) { criteria.add(Criteria.ANY_TRUE); parse(conditions, criteria, call.getArgument(0)); parse(conditions, criteria, call.getArgument(1)); return; } } conditions.add(parseCondition(node)); }
@Test public void symbolSourceRefs() { FunctionCallNode call = (FunctionCallNode) FormulaParser.parse("[A] + [B]"); assertThat(call.getSourceRange(), equalTo(new SourceRange(new SourcePos(0, 0), new SourcePos(0, 9)))); assertThat(call.getArgument(1).getSourceRange(), equalTo(new SourceRange(new SourcePos(0, 6), new SourcePos(0, 9)))); }