private Expression inlineReferences(Expression expression, Assignments assignments) { Function<Symbol, Expression> mapping = symbol -> { Expression result = assignments.get(symbol); if (result != null) { return result; } return symbol.toSymbolReference(); }; return inlineSymbols(mapping, expression); }
.filter(input -> child.getAssignments().get(input) instanceof Literal) .collect(toSet());
private boolean isInliningCandidate(Expression expression, ProjectNode node) { // TryExpressions should not be pushed down. However they are now being handled as lambda // passed to a FunctionCall now and should not affect predicate push down. So we want to make // sure the conjuncts are not TryExpressions. verify(AstUtils.preOrder(expression).noneMatch(TryExpression.class::isInstance)); // candidate symbols for inlining are // 1. references to simple constants // 2. references to complex expressions that appear only once // which come from the node, as opposed to an enclosing scope. Set<Symbol> childOutputSet = ImmutableSet.copyOf(node.getOutputSymbols()); Map<Symbol, Long> dependencies = SymbolsExtractor.extractAll(expression).stream() .filter(childOutputSet::contains) .collect(Collectors.groupingBy(Function.identity(), Collectors.counting())); return dependencies.entrySet().stream() .allMatch(entry -> entry.getValue() == 1 || node.getAssignments().get(entry.getKey()) instanceof Literal); }
private static boolean isCountOverConstant(AggregationNode.Aggregation aggregation, Assignments inputs) { Signature signature = aggregation.getSignature(); if (!signature.getName().equals("count") || signature.getArgumentTypes().size() != 1) { return false; } Expression argument = aggregation.getCall().getArguments().get(0); if (argument instanceof SymbolReference) { argument = inputs.get(Symbol.from(argument)); } return argument instanceof Literal && !(argument instanceof NullLiteral); } }
rewrittenProjections.add(symbolToInputRewriter.rewrite(assignments.get(symbol)));