use of com.facebook.presto.sql.tree.FunctionCall in project presto by prestodb.
the class AggregationFunctionMatcher method getAssignedSymbol.
@Override
public Optional<Symbol> getAssignedSymbol(PlanNode node, Session session, Metadata metadata, SymbolAliases symbolAliases) {
Optional<Symbol> result = Optional.empty();
if (!(node instanceof AggregationNode)) {
return result;
}
AggregationNode aggregationNode = (AggregationNode) node;
FunctionCall expectedCall = callMaker.getExpectedValue(symbolAliases);
for (Map.Entry<Symbol, FunctionCall> assignment : aggregationNode.getAggregations().entrySet()) {
if (expectedCall.equals(assignment.getValue())) {
checkState(!result.isPresent(), "Ambiguous function calls in %s", aggregationNode);
result = Optional.of(assignment.getKey());
}
}
return result;
}
use of com.facebook.presto.sql.tree.FunctionCall in project presto by prestodb.
the class TestCountConstantOptimizer method testCountConstantOptimizer.
@Test
public void testCountConstantOptimizer() throws Exception {
CountConstantOptimizer optimizer = new CountConstantOptimizer();
PlanNodeIdAllocator planNodeIdAllocator = new PlanNodeIdAllocator();
Symbol countAggregationSymbol = new Symbol("count");
Signature countAggregationSignature = new Signature("count", FunctionKind.AGGREGATE, parseTypeSignature(StandardTypes.BIGINT), parseTypeSignature(StandardTypes.BIGINT));
ImmutableMap<Symbol, FunctionCall> aggregations = ImmutableMap.of(countAggregationSymbol, new FunctionCall(QualifiedName.of("count"), ImmutableList.of(new SymbolReference("expr"))));
ImmutableMap<Symbol, Signature> functions = ImmutableMap.of(countAggregationSymbol, countAggregationSignature);
ValuesNode valuesNode = new ValuesNode(planNodeIdAllocator.getNextId(), ImmutableList.of(new Symbol("col")), ImmutableList.of(ImmutableList.of()));
AggregationNode eligiblePlan = new AggregationNode(planNodeIdAllocator.getNextId(), new ProjectNode(planNodeIdAllocator.getNextId(), valuesNode, Assignments.of(new Symbol("expr"), new LongLiteral("42"))), aggregations, functions, ImmutableMap.of(), ImmutableList.of(ImmutableList.of()), AggregationNode.Step.INTERMEDIATE, Optional.empty(), Optional.empty());
assertTrue(((AggregationNode) optimizer.optimize(eligiblePlan, TEST_SESSION, ImmutableMap.of(), new SymbolAllocator(), new PlanNodeIdAllocator())).getAggregations().get(countAggregationSymbol).getArguments().isEmpty());
AggregationNode ineligiblePlan = new AggregationNode(planNodeIdAllocator.getNextId(), new ProjectNode(planNodeIdAllocator.getNextId(), valuesNode, Assignments.of(new Symbol("expr"), new FunctionCall(QualifiedName.of("function"), ImmutableList.of(new Identifier("x"))))), aggregations, functions, ImmutableMap.of(), ImmutableList.of(ImmutableList.of()), AggregationNode.Step.INTERMEDIATE, Optional.empty(), Optional.empty());
assertFalse(((AggregationNode) optimizer.optimize(ineligiblePlan, TEST_SESSION, ImmutableMap.of(), new SymbolAllocator(), new PlanNodeIdAllocator())).getAggregations().get(countAggregationSymbol).getArguments().isEmpty());
}
use of com.facebook.presto.sql.tree.FunctionCall in project presto by prestodb.
the class DesugaringRewriter method rewriteAtTimeZone.
@Override
public Expression rewriteAtTimeZone(AtTimeZone node, Void context, ExpressionTreeRewriter<Void> treeRewriter) {
Expression value = treeRewriter.rewrite(node.getValue(), context);
Type type = expressionTypes.get(node.getValue());
if (type.equals(TIME)) {
value = new Cast(value, TIME_WITH_TIME_ZONE.getDisplayName());
} else if (type.equals(TIMESTAMP)) {
value = new Cast(value, TIMESTAMP_WITH_TIME_ZONE.getDisplayName());
}
return new FunctionCall(QualifiedName.of("at_timezone"), ImmutableList.of(value, treeRewriter.rewrite(node.getTimeZone(), context)));
}
use of com.facebook.presto.sql.tree.FunctionCall in project presto by prestodb.
the class SingleMarkDistinctToGroupBy method apply.
@Override
public Optional<PlanNode> apply(PlanNode node, Lookup lookup, PlanNodeIdAllocator idAllocator, SymbolAllocator symbolAllocator) {
if (!(node instanceof AggregationNode)) {
return Optional.empty();
}
AggregationNode parent = (AggregationNode) node;
PlanNode source = lookup.resolve(parent.getSource());
if (!(source instanceof MarkDistinctNode)) {
return Optional.empty();
}
MarkDistinctNode child = (MarkDistinctNode) source;
boolean hasFilters = parent.getAggregations().values().stream().map(FunctionCall::getFilter).anyMatch(Optional::isPresent);
if (hasFilters) {
return Optional.empty();
}
// optimize if and only if
// all aggregation functions have a single common distinct mask symbol
// AND all aggregation functions have mask
Set<Symbol> masks = ImmutableSet.copyOf(parent.getMasks().values());
if (masks.size() != 1 || parent.getMasks().size() != parent.getAggregations().size()) {
return Optional.empty();
}
Symbol mask = Iterables.getOnlyElement(masks);
if (!child.getMarkerSymbol().equals(mask)) {
return Optional.empty();
}
return Optional.of(new AggregationNode(idAllocator.getNextId(), new AggregationNode(idAllocator.getNextId(), child.getSource(), Collections.emptyMap(), ImmutableList.of(child.getDistinctSymbols()), SINGLE, child.getHashSymbol(), Optional.empty()), // remove DISTINCT flag from function calls
parent.getAssignments().entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, e -> removeDistinct(e.getValue()))), parent.getGroupingSets(), parent.getStep(), parent.getHashSymbol(), parent.getGroupIdSymbol()));
}
use of com.facebook.presto.sql.tree.FunctionCall in project presto by prestodb.
the class ImplementFilteredAggregations method apply.
@Override
public Optional<PlanNode> apply(PlanNode node, Lookup lookup, PlanNodeIdAllocator idAllocator, SymbolAllocator symbolAllocator) {
if (!(node instanceof AggregationNode)) {
return Optional.empty();
}
AggregationNode aggregation = (AggregationNode) node;
boolean hasFilters = aggregation.getAggregations().entrySet().stream().anyMatch(e -> e.getValue().getFilter().isPresent() && // can't handle filtered aggregations with DISTINCT (conservatively, if they have a mask)
!aggregation.getMasks().containsKey(e.getKey()));
if (!hasFilters) {
return Optional.empty();
}
Assignments.Builder newAssignments = Assignments.builder();
ImmutableMap.Builder<Symbol, Symbol> masks = ImmutableMap.<Symbol, Symbol>builder().putAll(aggregation.getMasks());
ImmutableMap.Builder<Symbol, FunctionCall> calls = ImmutableMap.builder();
for (Map.Entry<Symbol, FunctionCall> entry : aggregation.getAggregations().entrySet()) {
Symbol output = entry.getKey();
// strip the filters
FunctionCall call = entry.getValue();
calls.put(output, new FunctionCall(call.getName(), call.getWindow(), Optional.empty(), call.isDistinct(), call.getArguments()));
if (call.getFilter().isPresent()) {
Expression filter = entry.getValue().getFilter().get();
Symbol symbol = symbolAllocator.newSymbol(filter, BOOLEAN);
newAssignments.put(symbol, filter);
masks.put(output, symbol);
}
}
// identity projection for all existing inputs
newAssignments.putIdentities(aggregation.getSource().getOutputSymbols());
return Optional.of(new AggregationNode(idAllocator.getNextId(), new ProjectNode(idAllocator.getNextId(), aggregation.getSource(), newAssignments.build()), calls.build(), aggregation.getFunctions(), masks.build(), aggregation.getGroupingSets(), aggregation.getStep(), aggregation.getHashSymbol(), aggregation.getGroupIdSymbol()));
}
Aggregations