@Override protected Boolean visitIfExpression(IfExpression node, Void context) { ImmutableList.Builder<Expression> expressions = ImmutableList.<Expression>builder() .add(node.getCondition()) .add(node.getTrueValue()); if (node.getFalseValue().isPresent()) { expressions.add(node.getFalseValue().get()); } return expressions.build().stream().allMatch(expression -> process(expression, context)); }
@Override protected Boolean visitCoalesceExpression(CoalesceExpression node, Void context) { return node.getOperands().stream().allMatch(expression -> process(expression, context)); }
@Override public Boolean visitRow(Row node, final Void context) { return node.getItems().stream() .allMatch(item -> process(item, context)); }
@Override public Boolean visitParameter(Parameter node, Void context) { if (analysis.isDescribe()) { return true; } List<Expression> parameters = analysis.getParameters(); checkArgument(node.getPosition() < parameters.size(), "Invalid parameter number %s, max values is %s", node.getPosition(), parameters.size() - 1); return process(parameters.get(node.getPosition()), context); }
@Override protected Boolean visitNotExpression(NotExpression node, Void context) { return process(node.getValue(), context); }
@Override protected Boolean visitLambdaExpression(LambdaExpression node, Void context) { return process(node.getBody(), context); }
@Override protected Boolean visitInListExpression(InListExpression node, Void context) { return node.getValues().stream().allMatch(expression -> process(expression, context)); }
@Override protected Boolean visitArrayConstructor(ArrayConstructor node, Void context) { return node.getValues().stream().allMatch(expression -> process(expression, context)); }
@Override protected Boolean visitDereferenceExpression(DereferenceExpression node, Void context) { if (columnReferences.containsKey(NodeRef.<Expression>of(node))) { return isGroupingKey(node); } // Allow SELECT col1.f1 FROM table1 GROUP BY col1 return process(node.getBase(), context); }
@Override protected Boolean visitExists(ExistsPredicate node, Void context) { checkState(node.getSubquery() instanceof SubqueryExpression); return process(node.getSubquery(), context); }
@Override protected Boolean visitTryExpression(TryExpression node, Void context) { return process(node.getInnerExpression(), context); }
@Override protected Boolean visitSearchedCaseExpression(SearchedCaseExpression node, Void context) { for (WhenClause whenClause : node.getWhenClauses()) { if (!process(whenClause.getOperand(), context) || !process(whenClause.getResult(), context)) { return false; } } return !node.getDefaultValue().isPresent() || process(node.getDefaultValue().get(), context); }
@Override protected Boolean visitExtract(Extract node, Void context) { return process(node.getExpression(), context); }
private void analyze(Expression expression) { Visitor visitor = new Visitor(); if (!visitor.process(expression, null)) { throw new SemanticException(MUST_BE_AGGREGATE_OR_GROUP_BY, expression, "'%s' must be an aggregate expression or appear in GROUP BY clause", expression); } }