Search in sources :

Example 6 with WindowNode

use of io.trino.sql.planner.plan.WindowNode in project trino by trinodb.

the class TestTypeValidator method testInvalidWindowFunctionSignature.

@Test
public void testInvalidWindowFunctionSignature() {
    Symbol windowSymbol = symbolAllocator.newSymbol("sum", BIGINT);
    ResolvedFunction resolvedFunction = functionResolution.resolveFunction(QualifiedName.of("sum"), fromTypes(DOUBLE));
    WindowNode.Frame frame = new WindowNode.Frame(WindowFrame.Type.RANGE, FrameBound.Type.UNBOUNDED_PRECEDING, Optional.empty(), Optional.empty(), FrameBound.Type.UNBOUNDED_FOLLOWING, Optional.empty(), Optional.empty(), Optional.empty(), Optional.empty());
    WindowNode.Function function = new WindowNode.Function(resolvedFunction, ImmutableList.of(columnC.toSymbolReference()), frame, false);
    WindowNode.Specification specification = new WindowNode.Specification(ImmutableList.of(), Optional.empty());
    PlanNode node = new WindowNode(newId(), baseTableScan, specification, ImmutableMap.of(windowSymbol, function), Optional.empty(), ImmutableSet.of(), 0);
    assertThatThrownBy(() -> assertTypesValid(node)).isInstanceOf(IllegalArgumentException.class).hasMessageMatching("type of symbol 'sum(_[0-9]+)?' is expected to be bigint, but the actual type is double");
}
Also used : WindowNode(io.trino.sql.planner.plan.WindowNode) ResolvedFunction(io.trino.metadata.ResolvedFunction) WindowFrame(io.trino.sql.tree.WindowFrame) PlanNode(io.trino.sql.planner.plan.PlanNode) ResolvedFunction(io.trino.metadata.ResolvedFunction) Test(org.testng.annotations.Test)

Example 7 with WindowNode

use of io.trino.sql.planner.plan.WindowNode in project trino by trinodb.

the class TestEffectivePredicateExtractor method testWindow.

@Test
public void testWindow() {
    PlanNode node = new WindowNode(newId(), filter(baseTableScan, and(equals(AE, BE), equals(BE, CE), lessThan(CE, bigintLiteral(10)))), new WindowNode.Specification(ImmutableList.of(A), Optional.of(new OrderingScheme(ImmutableList.of(A), ImmutableMap.of(A, SortOrder.ASC_NULLS_LAST)))), ImmutableMap.of(), Optional.empty(), ImmutableSet.of(), 0);
    Expression effectivePredicate = effectivePredicateExtractor.extract(SESSION, node, TypeProvider.empty(), typeAnalyzer);
    // Pass through
    assertEquals(normalizeConjuncts(effectivePredicate), normalizeConjuncts(equals(AE, BE), equals(BE, CE), lessThan(CE, bigintLiteral(10))));
}
Also used : WindowNode(io.trino.sql.planner.plan.WindowNode) PlanNode(io.trino.sql.planner.plan.PlanNode) InListExpression(io.trino.sql.tree.InListExpression) NotExpression(io.trino.sql.tree.NotExpression) ComparisonExpression(io.trino.sql.tree.ComparisonExpression) Expression(io.trino.sql.tree.Expression) Test(org.testng.annotations.Test)

Example 8 with WindowNode

use of io.trino.sql.planner.plan.WindowNode in project trino by trinodb.

the class TestPushdownLimitIntoWindow method testLimitWithPreSortedInputs.

@Test
public void testLimitWithPreSortedInputs() {
    // We can push Limit with pre-sorted inputs into WindowNode if ordering scheme is satisfied
    // We don't do it currently to avoid relying on LocalProperties outside of AddExchanges/AddLocalExchanges
    ResolvedFunction ranking = tester().getMetadata().resolveFunction(tester().getSession(), QualifiedName.of("row_number"), fromTypes());
    tester().assertThat(new PushdownLimitIntoWindow()).on(p -> {
        Symbol a = p.symbol("a");
        Symbol rowNumberSymbol = p.symbol("row_number_1");
        OrderingScheme orderingScheme = new OrderingScheme(ImmutableList.of(a), ImmutableMap.of(a, SortOrder.ASC_NULLS_FIRST));
        return p.limit(3, false, ImmutableList.of(a), p.window(new WindowNode.Specification(ImmutableList.of(), Optional.of(orderingScheme)), ImmutableMap.of(rowNumberSymbol, newWindowNodeFunction(ranking, a)), p.values(a)));
    }).doesNotFire();
}
Also used : Symbol(io.trino.sql.planner.Symbol) ImmutableMap(com.google.common.collect.ImmutableMap) BaseRuleTest(io.trino.sql.planner.iterative.rule.test.BaseRuleTest) PlanMatchPattern.topNRanking(io.trino.sql.planner.assertions.PlanMatchPattern.topNRanking) ResolvedFunction(io.trino.metadata.ResolvedFunction) TypeSignatureProvider.fromTypes(io.trino.sql.analyzer.TypeSignatureProvider.fromTypes) Test(org.testng.annotations.Test) PlanMatchPattern.values(io.trino.sql.planner.assertions.PlanMatchPattern.values) OrderingScheme(io.trino.sql.planner.OrderingScheme) DEFAULT_FRAME(io.trino.sql.planner.plan.WindowNode.Frame.DEFAULT_FRAME) SortOrder(io.trino.spi.connector.SortOrder) QualifiedName(io.trino.sql.tree.QualifiedName) PlanMatchPattern.limit(io.trino.sql.planner.assertions.PlanMatchPattern.limit) ImmutableList(com.google.common.collect.ImmutableList) Optional(java.util.Optional) WindowNode(io.trino.sql.planner.plan.WindowNode) OrderingScheme(io.trino.sql.planner.OrderingScheme) WindowNode(io.trino.sql.planner.plan.WindowNode) ResolvedFunction(io.trino.metadata.ResolvedFunction) Symbol(io.trino.sql.planner.Symbol) BaseRuleTest(io.trino.sql.planner.iterative.rule.test.BaseRuleTest) Test(org.testng.annotations.Test)

Example 9 with WindowNode

use of io.trino.sql.planner.plan.WindowNode in project trino by trinodb.

the class QueryPlanner method planWindow.

private PlanBuilder planWindow(PlanBuilder subPlan, FunctionCall windowFunction, ResolvedWindow window, PlanAndMappings coercions, Optional<Symbol> frameStartSymbol, Optional<Symbol> sortKeyCoercedForFrameStartComparison, Optional<Symbol> frameEndSymbol, Optional<Symbol> sortKeyCoercedForFrameEndComparison) {
    WindowFrame.Type frameType = WindowFrame.Type.RANGE;
    FrameBound.Type frameStartType = FrameBound.Type.UNBOUNDED_PRECEDING;
    FrameBound.Type frameEndType = FrameBound.Type.CURRENT_ROW;
    Optional<Expression> frameStartExpression = Optional.empty();
    Optional<Expression> frameEndExpression = Optional.empty();
    if (window.getFrame().isPresent()) {
        WindowFrame frame = window.getFrame().get();
        frameType = frame.getType();
        frameStartType = frame.getStart().getType();
        frameStartExpression = frame.getStart().getValue();
        if (frame.getEnd().isPresent()) {
            frameEndType = frame.getEnd().get().getType();
            frameEndExpression = frame.getEnd().get().getValue();
        }
    }
    WindowNode.Specification specification = planWindowSpecification(window.getPartitionBy(), window.getOrderBy(), coercions::get);
    // Rewrite frame bounds in terms of pre-projected inputs
    WindowNode.Frame frame = new WindowNode.Frame(frameType, frameStartType, frameStartSymbol, sortKeyCoercedForFrameStartComparison, frameEndType, frameEndSymbol, sortKeyCoercedForFrameEndComparison, frameStartExpression, frameEndExpression);
    Symbol newSymbol = symbolAllocator.newSymbol(windowFunction, analysis.getType(windowFunction));
    NullTreatment nullTreatment = windowFunction.getNullTreatment().orElse(NullTreatment.RESPECT);
    WindowNode.Function function = new WindowNode.Function(analysis.getResolvedFunction(windowFunction), windowFunction.getArguments().stream().map(argument -> {
        if (argument instanceof LambdaExpression) {
            return subPlan.rewrite(argument);
        }
        return coercions.get(argument).toSymbolReference();
    }).collect(toImmutableList()), frame, nullTreatment == NullTreatment.IGNORE);
    // create window node
    return new PlanBuilder(subPlan.getTranslations().withAdditionalMappings(ImmutableMap.of(scopeAwareKey(windowFunction, analysis, subPlan.getScope()), newSymbol)), new WindowNode(idAllocator.getNextId(), subPlan.getRoot(), specification, ImmutableMap.of(newSymbol, function), Optional.empty(), ImmutableSet.of(), 0));
}
Also used : WindowNode(io.trino.sql.planner.plan.WindowNode) WindowFrame(io.trino.sql.tree.WindowFrame) FrameBound(io.trino.sql.tree.FrameBound) PlanBuilder.newPlanBuilder(io.trino.sql.planner.PlanBuilder.newPlanBuilder) NullTreatment(io.trino.sql.tree.FunctionCall.NullTreatment) ResolvedFunction(io.trino.metadata.ResolvedFunction) Function(java.util.function.Function) WindowFrame(io.trino.sql.tree.WindowFrame) SelectExpression(io.trino.sql.analyzer.Analysis.SelectExpression) ComparisonExpression(io.trino.sql.tree.ComparisonExpression) IfExpression(io.trino.sql.tree.IfExpression) Expression(io.trino.sql.tree.Expression) LambdaExpression(io.trino.sql.tree.LambdaExpression) LambdaExpression(io.trino.sql.tree.LambdaExpression)

Example 10 with WindowNode

use of io.trino.sql.planner.plan.WindowNode in project trino by trinodb.

the class WindowFunctionMatcher method getAssignedSymbol.

@Override
public Optional<Symbol> getAssignedSymbol(PlanNode node, Session session, Metadata metadata, SymbolAliases symbolAliases) {
    Optional<Symbol> result = Optional.empty();
    Map<Symbol, Function> assignments;
    if (node instanceof WindowNode) {
        assignments = ((WindowNode) node).getWindowFunctions();
    } else if (node instanceof PatternRecognitionNode) {
        assignments = ((PatternRecognitionNode) node).getWindowFunctions();
    } else {
        return result;
    }
    FunctionCall expectedCall = callMaker.getExpectedValue(symbolAliases);
    Optional<WindowNode.Frame> expectedFrame = frameMaker.map(maker -> maker.getExpectedValue(symbolAliases));
    for (Map.Entry<Symbol, Function> assignment : assignments.entrySet()) {
        Function function = assignment.getValue();
        boolean signatureMatches = resolvedFunction.map(assignment.getValue().getResolvedFunction()::equals).orElse(true);
        if (signatureMatches && windowFunctionMatches(function, expectedCall, expectedFrame)) {
            checkState(result.isEmpty(), "Ambiguous function calls in %s", node);
            result = Optional.of(assignment.getKey());
        }
    }
    return result;
}
Also used : ResolvedFunction(io.trino.metadata.ResolvedFunction) Function(io.trino.sql.planner.plan.WindowNode.Function) WindowNode(io.trino.sql.planner.plan.WindowNode) PatternRecognitionNode(io.trino.sql.planner.plan.PatternRecognitionNode) Symbol(io.trino.sql.planner.Symbol) FunctionCall(io.trino.sql.tree.FunctionCall) Map(java.util.Map)

Aggregations

WindowNode (io.trino.sql.planner.plan.WindowNode)17 ResolvedFunction (io.trino.metadata.ResolvedFunction)9 Symbol (io.trino.sql.planner.Symbol)9 PlanNode (io.trino.sql.planner.plan.PlanNode)8 Expression (io.trino.sql.tree.Expression)6 WindowFrame (io.trino.sql.tree.WindowFrame)5 FilterNode (io.trino.sql.planner.plan.FilterNode)4 ComparisonExpression (io.trino.sql.tree.ComparisonExpression)4 Map (java.util.Map)4 Test (org.testng.annotations.Test)4 ImmutableList (com.google.common.collect.ImmutableList)3 ImmutableMap (com.google.common.collect.ImmutableMap)3 ImmutableSet.toImmutableSet (com.google.common.collect.ImmutableSet.toImmutableSet)3 Session (io.trino.Session)3 SortOrder (io.trino.spi.connector.SortOrder)3 Util.toTopNRankingType (io.trino.sql.planner.iterative.rule.Util.toTopNRankingType)3 ProjectNode (io.trino.sql.planner.plan.ProjectNode)3 Preconditions.checkState (com.google.common.base.Preconditions.checkState)2 ImmutableList.toImmutableList (com.google.common.collect.ImmutableList.toImmutableList)2 ImmutableMap.toImmutableMap (com.google.common.collect.ImmutableMap.toImmutableMap)2