Search in sources :

Example 11 with Ordering

use of com.facebook.presto.spi.plan.Ordering in project presto by prestodb.

the class TestEffectivePredicateExtractor method testSort.

@Test
public void testSort() {
    PlanNode node = new SortNode(Optional.empty(), newId(), filter(baseTableScan, and(equals(AV, BV), equals(BV, CV), lessThan(CV, bigintLiteral(10)))), new OrderingScheme(ImmutableList.of(new Ordering(AV, SortOrder.ASC_NULLS_LAST))), false);
    RowExpression effectivePredicate = effectivePredicateExtractor.extract(node);
    // Pass through
    assertEquals(normalizeConjuncts(effectivePredicate), normalizeConjuncts(equals(AV, BV), equals(BV, CV), lessThan(CV, bigintLiteral(10))));
}
Also used : OrderingScheme(com.facebook.presto.spi.plan.OrderingScheme) PlanNode(com.facebook.presto.spi.plan.PlanNode) SortNode(com.facebook.presto.sql.planner.plan.SortNode) Ordering(com.facebook.presto.spi.plan.Ordering) RowExpression(com.facebook.presto.spi.relation.RowExpression) Test(org.testng.annotations.Test)

Example 12 with Ordering

use of com.facebook.presto.spi.plan.Ordering in project presto by prestodb.

the class QueryPlanner method window.

private PlanBuilder window(PlanBuilder subPlan, List<FunctionCall> windowFunctions) {
    if (windowFunctions.isEmpty()) {
        return subPlan;
    }
    for (FunctionCall windowFunction : windowFunctions) {
        Window window = windowFunction.getWindow().get();
        // Extract frame
        WindowFrame.Type frameType = WindowFrame.Type.RANGE;
        FrameBound.Type frameStartType = FrameBound.Type.UNBOUNDED_PRECEDING;
        FrameBound.Type frameEndType = FrameBound.Type.CURRENT_ROW;
        Expression frameStart = null;
        Expression frameEnd = null;
        if (window.getFrame().isPresent()) {
            WindowFrame frame = window.getFrame().get();
            frameType = frame.getType();
            frameStartType = frame.getStart().getType();
            frameStart = frame.getStart().getValue().orElse(null);
            if (frame.getEnd().isPresent()) {
                frameEndType = frame.getEnd().get().getType();
                frameEnd = frame.getEnd().get().getValue().orElse(null);
            }
        }
        // Pre-project inputs
        ImmutableList.Builder<Expression> inputs = ImmutableList.<Expression>builder().addAll(windowFunction.getArguments()).addAll(window.getPartitionBy()).addAll(Iterables.transform(getSortItemsFromOrderBy(window.getOrderBy()), SortItem::getSortKey));
        if (frameStart != null) {
            inputs.add(frameStart);
        }
        if (frameEnd != null) {
            inputs.add(frameEnd);
        }
        subPlan = subPlan.appendProjections(inputs.build(), variableAllocator, idAllocator);
        // Rewrite PARTITION BY in terms of pre-projected inputs
        ImmutableList.Builder<VariableReferenceExpression> partitionByVariables = ImmutableList.builder();
        for (Expression expression : window.getPartitionBy()) {
            partitionByVariables.add(subPlan.translateToVariable(expression));
        }
        // Rewrite ORDER BY in terms of pre-projected inputs
        LinkedHashMap<VariableReferenceExpression, SortOrder> orderings = new LinkedHashMap<>();
        for (SortItem item : getSortItemsFromOrderBy(window.getOrderBy())) {
            VariableReferenceExpression variable = subPlan.translateToVariable(item.getSortKey());
            // don't override existing keys, i.e. when "ORDER BY a ASC, a DESC" is specified
            orderings.putIfAbsent(variable, toSortOrder(item));
        }
        // Rewrite frame bounds in terms of pre-projected inputs
        Optional<VariableReferenceExpression> frameStartVariable = Optional.empty();
        Optional<VariableReferenceExpression> frameEndVariable = Optional.empty();
        if (frameStart != null) {
            frameStartVariable = Optional.of(subPlan.translate(frameStart));
        }
        if (frameEnd != null) {
            frameEndVariable = Optional.of(subPlan.translate(frameEnd));
        }
        WindowNode.Frame frame = new WindowNode.Frame(toWindowType(frameType), toBoundType(frameStartType), frameStartVariable, toBoundType(frameEndType), frameEndVariable, Optional.ofNullable(frameStart).map(Expression::toString), Optional.ofNullable(frameEnd).map(Expression::toString));
        TranslationMap outputTranslations = subPlan.copyTranslations();
        // Rewrite function call in terms of pre-projected inputs
        Expression rewritten = subPlan.rewrite(windowFunction);
        boolean needCoercion = rewritten instanceof Cast;
        // Strip out the cast and add it back as a post-projection
        if (rewritten instanceof Cast) {
            rewritten = ((Cast) rewritten).getExpression();
        }
        // If refers to existing variable, don't create another PlanNode
        if (rewritten instanceof SymbolReference) {
            if (needCoercion) {
                subPlan = explicitCoercionVariables(subPlan, subPlan.getRoot().getOutputVariables(), ImmutableList.of(windowFunction));
            }
            continue;
        }
        Type returnType = analysis.getType(windowFunction);
        VariableReferenceExpression newVariable = variableAllocator.newVariable(rewritten, returnType);
        outputTranslations.put(windowFunction, newVariable);
        // TODO: replace arguments with RowExpression once we introduce subquery expression for RowExpression (#12745).
        // Wrap all arguments in CallExpression to be RawExpression.
        // The utility that work on the CallExpression should be aware of the RawExpression handling.
        // The interface will be dirty until we introduce subquery expression for RowExpression.
        // With subqueries, the translation from Expression to RowExpression can happen here.
        WindowNode.Function function = new WindowNode.Function(call(windowFunction.getName().toString(), analysis.getFunctionHandle(windowFunction), returnType, ((FunctionCall) rewritten).getArguments().stream().map(OriginalExpressionUtils::castToRowExpression).collect(toImmutableList())), frame, windowFunction.isIgnoreNulls());
        ImmutableList.Builder<VariableReferenceExpression> orderByVariables = ImmutableList.builder();
        orderByVariables.addAll(orderings.keySet());
        Optional<OrderingScheme> orderingScheme = Optional.empty();
        if (!orderings.isEmpty()) {
            orderingScheme = Optional.of(new OrderingScheme(orderByVariables.build().stream().map(variable -> new Ordering(variable, orderings.get(variable))).collect(toImmutableList())));
        }
        // create window node
        subPlan = new PlanBuilder(outputTranslations, new WindowNode(subPlan.getRoot().getSourceLocation(), idAllocator.getNextId(), subPlan.getRoot(), new WindowNode.Specification(partitionByVariables.build(), orderingScheme), ImmutableMap.of(newVariable, function), Optional.empty(), ImmutableSet.of(), 0));
        if (needCoercion) {
            subPlan = explicitCoercionVariables(subPlan, subPlan.getRoot().getOutputVariables(), ImmutableList.of(windowFunction));
        }
    }
    return subPlan;
}
Also used : Cast(com.facebook.presto.sql.tree.Cast) WindowFrame(com.facebook.presto.sql.tree.WindowFrame) ImmutableList.toImmutableList(com.google.common.collect.ImmutableList.toImmutableList) ImmutableList(com.google.common.collect.ImmutableList) SymbolReference(com.facebook.presto.sql.tree.SymbolReference) OriginalExpressionUtils.asSymbolReference(com.facebook.presto.sql.relational.OriginalExpressionUtils.asSymbolReference) LinkedHashMap(java.util.LinkedHashMap) SortItem(com.facebook.presto.sql.tree.SortItem) WindowFrame(com.facebook.presto.sql.tree.WindowFrame) Ordering(com.facebook.presto.spi.plan.Ordering) FunctionCall(com.facebook.presto.sql.tree.FunctionCall) Window(com.facebook.presto.sql.tree.Window) WindowNode(com.facebook.presto.sql.planner.plan.WindowNode) OrderingScheme(com.facebook.presto.spi.plan.OrderingScheme) PlannerUtils.toOrderingScheme(com.facebook.presto.sql.planner.PlannerUtils.toOrderingScheme) FrameBound(com.facebook.presto.sql.tree.FrameBound) SortOrder(com.facebook.presto.common.block.SortOrder) PlannerUtils.toSortOrder(com.facebook.presto.sql.planner.PlannerUtils.toSortOrder) WindowNodeUtil.toBoundType(com.facebook.presto.sql.planner.optimizations.WindowNodeUtil.toBoundType) WindowNodeUtil.toWindowType(com.facebook.presto.sql.planner.optimizations.WindowNodeUtil.toWindowType) Type(com.facebook.presto.common.type.Type) RelationType(com.facebook.presto.sql.analyzer.RelationType) VariableReferenceExpression(com.facebook.presto.spi.relation.VariableReferenceExpression) CallExpression(com.facebook.presto.spi.relation.CallExpression) LambdaExpression(com.facebook.presto.sql.tree.LambdaExpression) RowExpression(com.facebook.presto.spi.relation.RowExpression) Expression(com.facebook.presto.sql.tree.Expression) OriginalExpressionUtils.castToRowExpression(com.facebook.presto.sql.relational.OriginalExpressionUtils.castToRowExpression) VariableReferenceExpression(com.facebook.presto.spi.relation.VariableReferenceExpression)

Example 13 with Ordering

use of com.facebook.presto.spi.plan.Ordering in project presto by prestodb.

the class PlannerUtils method toOrderingScheme.

public static OrderingScheme toOrderingScheme(List<VariableReferenceExpression> orderingSymbols, List<SortOrder> sortOrders) {
    ImmutableList.Builder<Ordering> builder = ImmutableList.builder();
    // don't override existing keys, i.e. when "ORDER BY a ASC, a DESC" is specified
    Set<VariableReferenceExpression> keysSeen = new HashSet<>();
    forEachPair(orderingSymbols.stream(), sortOrders.stream(), (variable, sortOrder) -> {
        if (!keysSeen.contains(variable)) {
            keysSeen.add(variable);
            builder.add(new Ordering(variable, sortOrder));
        }
    });
    return new OrderingScheme(builder.build());
}
Also used : OrderingScheme(com.facebook.presto.spi.plan.OrderingScheme) ImmutableList.toImmutableList(com.google.common.collect.ImmutableList.toImmutableList) ImmutableList(com.google.common.collect.ImmutableList) VariableReferenceExpression(com.facebook.presto.spi.relation.VariableReferenceExpression) Ordering(com.facebook.presto.spi.plan.Ordering) HashSet(java.util.HashSet)

Example 14 with Ordering

use of com.facebook.presto.spi.plan.Ordering in project presto by prestodb.

the class TestPruneUnreferencedOutputs method windowNodePruning.

/**
 * Test that the unreferenced output pruning works correctly when WindowNode is pruned as no downstream operators are consuming the window function output
 */
@Test
public void windowNodePruning() {
    FunctionHandle functionHandle = createTestMetadataManager().getFunctionAndTypeManager().lookupFunction("rank", ImmutableList.of());
    CallExpression call = call("rank", functionHandle, BIGINT);
    WindowNode.Frame frame = new WindowNode.Frame(RANGE, UNBOUNDED_PRECEDING, Optional.empty(), UNBOUNDED_FOLLOWING, Optional.empty(), Optional.empty(), Optional.empty());
    assertRuleApplication().on(p -> p.output(ImmutableList.of("user_uuid"), ImmutableList.of(p.variable("user_uuid", VARCHAR)), p.project(Assignments.of(p.variable("user_uuid", VARCHAR), p.variable("user_uuid", VARCHAR)), p.window(new WindowNode.Specification(ImmutableList.of(p.variable("user_uuid", VARCHAR)), Optional.of(new OrderingScheme(ImmutableList.of(new Ordering(p.variable("expr"), SortOrder.ASC_NULLS_LAST), new Ordering(p.variable("random"), SortOrder.ASC_NULLS_LAST))))), ImmutableMap.of(p.variable("rank"), new WindowNode.Function(call, frame, false)), p.project(Assignments.builder().put(p.variable("user_uuid", VARCHAR), p.variable("user_uuid", VARCHAR)).put(p.variable("expr", BIGINT), p.variable("expr", BIGINT)).put(p.variable("random", BIGINT), p.rowExpression("random()")).build(), p.values(p.variable("user_uuid", VARCHAR), p.variable("expr", BIGINT))))))).matches(output(project(project(values("user_uuid")))));
}
Also used : BIGINT(com.facebook.presto.common.type.BigintType.BIGINT) PlanMatchPattern.project(com.facebook.presto.sql.planner.assertions.PlanMatchPattern.project) SortOrder(com.facebook.presto.common.block.SortOrder) WindowNode(com.facebook.presto.sql.planner.plan.WindowNode) ImmutableMap(com.google.common.collect.ImmutableMap) Ordering(com.facebook.presto.spi.plan.Ordering) VARCHAR(com.facebook.presto.common.type.VarcharType.VARCHAR) PlanMatchPattern.output(com.facebook.presto.sql.planner.assertions.PlanMatchPattern.output) Assignments(com.facebook.presto.spi.plan.Assignments) Test(org.testng.annotations.Test) Expressions.call(com.facebook.presto.sql.relational.Expressions.call) OptimizerAssert(com.facebook.presto.sql.planner.assertions.OptimizerAssert) RANGE(com.facebook.presto.sql.planner.plan.WindowNode.Frame.WindowType.RANGE) BaseRuleTest(com.facebook.presto.sql.planner.iterative.rule.test.BaseRuleTest) ImmutableList(com.google.common.collect.ImmutableList) MetadataManager.createTestMetadataManager(com.facebook.presto.metadata.MetadataManager.createTestMetadataManager) FunctionHandle(com.facebook.presto.spi.function.FunctionHandle) Optional(java.util.Optional) PlanMatchPattern.values(com.facebook.presto.sql.planner.assertions.PlanMatchPattern.values) CallExpression(com.facebook.presto.spi.relation.CallExpression) UNBOUNDED_PRECEDING(com.facebook.presto.sql.planner.plan.WindowNode.Frame.BoundType.UNBOUNDED_PRECEDING) OrderingScheme(com.facebook.presto.spi.plan.OrderingScheme) UNBOUNDED_FOLLOWING(com.facebook.presto.sql.planner.plan.WindowNode.Frame.BoundType.UNBOUNDED_FOLLOWING) RuleTester(com.facebook.presto.sql.planner.iterative.rule.test.RuleTester) WindowNode(com.facebook.presto.sql.planner.plan.WindowNode) OrderingScheme(com.facebook.presto.spi.plan.OrderingScheme) Ordering(com.facebook.presto.spi.plan.Ordering) FunctionHandle(com.facebook.presto.spi.function.FunctionHandle) CallExpression(com.facebook.presto.spi.relation.CallExpression) Test(org.testng.annotations.Test) BaseRuleTest(com.facebook.presto.sql.planner.iterative.rule.test.BaseRuleTest)

Example 15 with Ordering

use of com.facebook.presto.spi.plan.Ordering in project presto by prestodb.

the class TestPinotQueryGenerator method testAggregationWithOrderByPushDownInTopN.

@Test(expectedExceptions = NoSuchElementException.class)
public void testAggregationWithOrderByPushDownInTopN() {
    PlanBuilder planBuilder = createPlanBuilder(defaultSessionHolder);
    TableScanNode tableScanNode = tableScan(planBuilder, pinotTable, city, fare);
    AggregationNode agg = planBuilder.aggregation(aggBuilder -> aggBuilder.source(tableScanNode).singleGroupingSet(variable("city")).addAggregation(planBuilder.variable("agg"), getRowExpression("sum(fare)", defaultSessionHolder)));
    TopNNode topN = new TopNNode(Optional.empty(), planBuilder.getIdAllocator().getNextId(), agg, 50L, new OrderingScheme(ImmutableList.of(new Ordering(variable("city"), SortOrder.DESC_NULLS_FIRST))), TopNNode.Step.FINAL);
    testPinotQuery(pinotConfig, topN, "", defaultSessionHolder, ImmutableMap.of());
}
Also used : OrderingScheme(com.facebook.presto.spi.plan.OrderingScheme) TableScanNode(com.facebook.presto.spi.plan.TableScanNode) Ordering(com.facebook.presto.spi.plan.Ordering) AggregationNode(com.facebook.presto.spi.plan.AggregationNode) PlanBuilder(com.facebook.presto.sql.planner.iterative.rule.test.PlanBuilder) TopNNode(com.facebook.presto.spi.plan.TopNNode) Test(org.testng.annotations.Test)

Aggregations

Ordering (com.facebook.presto.spi.plan.Ordering)15 OrderingScheme (com.facebook.presto.spi.plan.OrderingScheme)15 Test (org.testng.annotations.Test)9 VariableReferenceExpression (com.facebook.presto.spi.relation.VariableReferenceExpression)8 SortOrder (com.facebook.presto.common.block.SortOrder)6 ImmutableList (com.google.common.collect.ImmutableList)6 AggregationNode (com.facebook.presto.spi.plan.AggregationNode)5 TopNNode (com.facebook.presto.spi.plan.TopNNode)5 RowExpression (com.facebook.presto.spi.relation.RowExpression)5 ImmutableList.toImmutableList (com.google.common.collect.ImmutableList.toImmutableList)5 PlanNode (com.facebook.presto.spi.plan.PlanNode)4 CallExpression (com.facebook.presto.spi.relation.CallExpression)4 WindowNode (com.facebook.presto.sql.planner.plan.WindowNode)4 PlanNodeId (com.facebook.presto.spi.plan.PlanNodeId)3 TableScanNode (com.facebook.presto.spi.plan.TableScanNode)3 SymbolReference (com.facebook.presto.sql.tree.SymbolReference)3 ImmutableMap (com.google.common.collect.ImmutableMap)3 PrestoWarning (com.facebook.presto.spi.PrestoWarning)2 FunctionHandle (com.facebook.presto.spi.function.FunctionHandle)2 PlanBuilder (com.facebook.presto.sql.planner.iterative.rule.test.PlanBuilder)2