Search in sources :

Example 21 with SortOrder

use of com.facebook.presto.common.block.SortOrder in project presto by prestodb.

the class TestWindowOperator method testRowNumberArbitraryWithSpill.

@Test
public void testRowNumberArbitraryWithSpill() {
    List<Page> input = rowPagesBuilder(BIGINT).row(1L).row(3L).row(5L).row(7L).pageBreak().row(2L).row(4L).row(6L).row(8L).build();
    WindowOperatorFactory operatorFactory = createFactoryUnbounded(ImmutableList.of(BIGINT), Ints.asList(0), ROW_NUMBER, Ints.asList(), Ints.asList(), ImmutableList.copyOf(new SortOrder[] {}), true);
    DriverContext driverContext = createDriverContext();
    MaterializedResult expected = resultBuilder(driverContext.getSession(), BIGINT, BIGINT).row(1L, 1L).row(2L, 2L).row(3L, 3L).row(4L, 4L).row(5L, 5L).row(6L, 6L).row(7L, 7L).row(8L, 8L).build();
    assertOperatorEquals(operatorFactory, driverContext, input, expected);
}
Also used : WindowOperatorFactory(com.facebook.presto.operator.WindowOperator.WindowOperatorFactory) SortOrder(com.facebook.presto.common.block.SortOrder) Page(com.facebook.presto.common.Page) OperatorAssertion.toMaterializedResult(com.facebook.presto.operator.OperatorAssertion.toMaterializedResult) MaterializedResult(com.facebook.presto.testing.MaterializedResult) Test(org.testng.annotations.Test)

Example 22 with SortOrder

use of com.facebook.presto.common.block.SortOrder in project presto by prestodb.

the class TestWindowOperator method testLeadPartition.

@Test(dataProvider = "spillEnabled")
public void testLeadPartition(boolean spillEnabled, boolean revokeMemoryWhenAddingPages, long memoryLimit) {
    List<Page> input = rowPagesBuilder(VARCHAR, VARCHAR, BIGINT, BIGINT, VARCHAR, BOOLEAN, VARCHAR).row("b", "A1", 1L, 1L, "D", true, "").row("a", "A2", 1L, 2L, "D", false, "").row("a", "B1", 2L, 2L, "D", true, "").pageBreak().row("b", "C1", 2L, 1L, "D", false, "").row("a", "C2", 3L, 2L, "D", true, "").row("c", "A3", 1L, 1L, "D", true, "").build();
    WindowOperatorFactory operatorFactory = createFactoryUnbounded(ImmutableList.of(VARCHAR, VARCHAR, BIGINT, BIGINT, VARCHAR, BOOLEAN, VARCHAR), Ints.asList(0, 1, 2, 5), LEAD, Ints.asList(0), Ints.asList(2), ImmutableList.copyOf(new SortOrder[] { SortOrder.ASC_NULLS_LAST }), spillEnabled);
    DriverContext driverContext = createDriverContext(memoryLimit);
    MaterializedResult expected = resultBuilder(driverContext.getSession(), VARCHAR, VARCHAR, BIGINT, BOOLEAN, VARCHAR).row("a", "A2", 1L, false, "C2").row("a", "B1", 2L, true, "D").row("a", "C2", 3L, true, "D").row("b", "A1", 1L, true, "C1").row("b", "C1", 2L, false, "D").row("c", "A3", 1L, true, "D").build();
    assertOperatorEquals(operatorFactory, driverContext, input, expected, revokeMemoryWhenAddingPages);
}
Also used : WindowOperatorFactory(com.facebook.presto.operator.WindowOperator.WindowOperatorFactory) SortOrder(com.facebook.presto.common.block.SortOrder) Page(com.facebook.presto.common.Page) OperatorAssertion.toMaterializedResult(com.facebook.presto.operator.OperatorAssertion.toMaterializedResult) MaterializedResult(com.facebook.presto.testing.MaterializedResult) Test(org.testng.annotations.Test)

Example 23 with SortOrder

use of com.facebook.presto.common.block.SortOrder in project presto by prestodb.

the class TestWindowOperator method testMultipleOutputPages.

@Test(dataProvider = "spillEnabled")
public void testMultipleOutputPages(boolean spillEnabled, boolean revokeMemoryWhenAddingPages, long memoryLimit) {
    // make operator produce multiple pages during finish phase
    int numberOfRows = 80_000;
    List<Page> input = rowPagesBuilder(BIGINT, DOUBLE).addSequencePage(numberOfRows, 0, 0).build();
    WindowOperatorFactory operatorFactory = createFactoryUnbounded(ImmutableList.of(BIGINT, DOUBLE), Ints.asList(1, 0), ROW_NUMBER, Ints.asList(), Ints.asList(0), ImmutableList.copyOf(new SortOrder[] { SortOrder.DESC_NULLS_FIRST }), spillEnabled);
    DriverContext driverContext = createDriverContext(memoryLimit);
    MaterializedResult.Builder expectedBuilder = resultBuilder(driverContext.getSession(), DOUBLE, BIGINT, BIGINT);
    for (int i = 0; i < numberOfRows; ++i) {
        expectedBuilder.row((double) numberOfRows - i - 1, (long) numberOfRows - i - 1, (long) i + 1);
    }
    MaterializedResult expected = expectedBuilder.build();
    List<Page> pages = toPages(operatorFactory, driverContext, input, revokeMemoryWhenAddingPages);
    assertGreaterThan(pages.size(), 1, "Expected more than one output page");
    MaterializedResult actual = toMaterializedResult(driverContext.getSession(), expected.getTypes(), pages);
    assertEquals(actual.getMaterializedRows(), expected.getMaterializedRows());
    assertTrue(spillEnabled == (spillerFactory.getSpillsCount() > 0), format("Spill state mismatch. Expected spill: %s, spill count: %s", spillEnabled, spillerFactory.getSpillsCount()));
}
Also used : WindowOperatorFactory(com.facebook.presto.operator.WindowOperator.WindowOperatorFactory) SortOrder(com.facebook.presto.common.block.SortOrder) Page(com.facebook.presto.common.Page) OperatorAssertion.toMaterializedResult(com.facebook.presto.operator.OperatorAssertion.toMaterializedResult) MaterializedResult(com.facebook.presto.testing.MaterializedResult) Test(org.testng.annotations.Test)

Example 24 with SortOrder

use of com.facebook.presto.common.block.SortOrder 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)

Aggregations

SortOrder (com.facebook.presto.common.block.SortOrder)24 Test (org.testng.annotations.Test)14 Page (com.facebook.presto.common.Page)12 WindowOperatorFactory (com.facebook.presto.operator.WindowOperator.WindowOperatorFactory)11 OperatorAssertion.toMaterializedResult (com.facebook.presto.operator.OperatorAssertion.toMaterializedResult)10 MaterializedResult (com.facebook.presto.testing.MaterializedResult)10 Type (com.facebook.presto.common.type.Type)8 OrderingScheme (com.facebook.presto.spi.plan.OrderingScheme)6 Ordering (com.facebook.presto.spi.plan.Ordering)5 VariableReferenceExpression (com.facebook.presto.spi.relation.VariableReferenceExpression)5 ImmutableList (com.google.common.collect.ImmutableList)5 ImmutableList.toImmutableList (com.google.common.collect.ImmutableList.toImmutableList)4 NotSupportedException (com.facebook.presto.common.NotSupportedException)3 Block (com.facebook.presto.common.block.Block)3 PrestoException (com.facebook.presto.spi.PrestoException)3 HashMap (java.util.HashMap)3 List (java.util.List)3 BytecodeBlock (com.facebook.presto.bytecode.BytecodeBlock)2 MethodDefinition (com.facebook.presto.bytecode.MethodDefinition)2 Parameter (com.facebook.presto.bytecode.Parameter)2