Search in sources :

Example 1 with PatternRecognitionNode

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

the class PushDownProjectionsFromPatternRecognition method apply.

@Override
public Result apply(PatternRecognitionNode node, Captures captures, Context context) {
    Assignments.Builder assignments = Assignments.builder();
    Map<IrLabel, ExpressionAndValuePointers> rewrittenVariableDefinitions = rewriteVariableDefinitions(node.getVariableDefinitions(), assignments, context);
    Map<Symbol, Measure> rewrittenMeasureDefinitions = rewriteMeasureDefinitions(node.getMeasures(), assignments, context);
    if (assignments.build().isEmpty()) {
        return Result.empty();
    }
    assignments.putIdentities(node.getSource().getOutputSymbols());
    ProjectNode projectNode = new ProjectNode(context.getIdAllocator().getNextId(), node.getSource(), assignments.build());
    PatternRecognitionNode patternRecognitionNode = new PatternRecognitionNode(node.getId(), projectNode, node.getSpecification(), node.getHashSymbol(), node.getPrePartitionedInputs(), node.getPreSortedOrderPrefix(), node.getWindowFunctions(), rewrittenMeasureDefinitions, node.getCommonBaseFrame(), node.getRowsPerMatch(), node.getSkipToLabel(), node.getSkipToPosition(), node.isInitial(), node.getPattern(), node.getSubsets(), rewrittenVariableDefinitions);
    return Result.ofPlanNode(restrictOutputs(context.getIdAllocator(), patternRecognitionNode, ImmutableSet.copyOf(node.getOutputSymbols())).orElse(patternRecognitionNode));
}
Also used : IrLabel(io.trino.sql.planner.rowpattern.ir.IrLabel) PatternRecognitionNode(io.trino.sql.planner.plan.PatternRecognitionNode) Symbol(io.trino.sql.planner.Symbol) ExpressionAndValuePointers(io.trino.sql.planner.rowpattern.LogicalIndexExtractor.ExpressionAndValuePointers) Assignments(io.trino.sql.planner.plan.Assignments) Measure(io.trino.sql.planner.plan.PatternRecognitionNode.Measure) ProjectNode(io.trino.sql.planner.plan.ProjectNode)

Example 2 with PatternRecognitionNode

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

the class SymbolMapper method map.

public PatternRecognitionNode map(PatternRecognitionNode node, PlanNode source) {
    ImmutableMap.Builder<Symbol, WindowNode.Function> newFunctions = ImmutableMap.builder();
    node.getWindowFunctions().forEach((symbol, function) -> {
        List<Expression> newArguments = function.getArguments().stream().map(this::map).collect(toImmutableList());
        WindowNode.Frame newFrame = map(function.getFrame());
        newFunctions.put(map(symbol), new WindowNode.Function(function.getResolvedFunction(), newArguments, newFrame, function.isIgnoreNulls()));
    });
    ImmutableMap.Builder<Symbol, Measure> newMeasures = ImmutableMap.builder();
    node.getMeasures().forEach((symbol, measure) -> {
        ExpressionAndValuePointers newExpression = map(measure.getExpressionAndValuePointers());
        newMeasures.put(map(symbol), new Measure(newExpression, measure.getType()));
    });
    ImmutableMap.Builder<IrLabel, ExpressionAndValuePointers> newVariableDefinitions = ImmutableMap.builder();
    node.getVariableDefinitions().forEach((label, expression) -> newVariableDefinitions.put(label, map(expression)));
    return new PatternRecognitionNode(node.getId(), source, mapAndDistinct(node.getSpecification()), node.getHashSymbol().map(this::map), node.getPrePartitionedInputs().stream().map(this::map).collect(toImmutableSet()), node.getPreSortedOrderPrefix(), newFunctions.buildOrThrow(), newMeasures.buildOrThrow(), node.getCommonBaseFrame().map(this::map), node.getRowsPerMatch(), node.getSkipToLabel(), node.getSkipToPosition(), node.isInitial(), node.getPattern(), node.getSubsets(), newVariableDefinitions.buildOrThrow());
}
Also used : IrLabel(io.trino.sql.planner.rowpattern.ir.IrLabel) WindowNode(io.trino.sql.planner.plan.WindowNode) Symbol(io.trino.sql.planner.Symbol) ImmutableMap(com.google.common.collect.ImmutableMap) ImmutableMap.toImmutableMap(com.google.common.collect.ImmutableMap.toImmutableMap) Function(java.util.function.Function) PatternRecognitionNode(io.trino.sql.planner.plan.PatternRecognitionNode) Expression(io.trino.sql.tree.Expression) ExpressionAndValuePointers(io.trino.sql.planner.rowpattern.LogicalIndexExtractor.ExpressionAndValuePointers) Measure(io.trino.sql.planner.plan.PatternRecognitionNode.Measure)

Example 3 with PatternRecognitionNode

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

the class QueryPlanner method planPatternRecognition.

private PlanBuilder planPatternRecognition(PlanBuilder subPlan, FunctionCall windowFunction, ResolvedWindow window, PlanAndMappings coercions, Optional<Symbol> frameEndSymbol) {
    WindowNode.Specification specification = planWindowSpecification(window.getPartitionBy(), window.getOrderBy(), coercions::get);
    // in window frame with pattern recognition, the frame extent is specified as `ROWS BETWEEN CURRENT ROW AND ... `
    WindowFrame frame = window.getFrame().orElseThrow();
    FrameBound frameEnd = frame.getEnd().orElseThrow();
    WindowNode.Frame baseFrame = new WindowNode.Frame(WindowFrame.Type.ROWS, FrameBound.Type.CURRENT_ROW, Optional.empty(), Optional.empty(), frameEnd.getType(), frameEndSymbol, Optional.empty(), Optional.empty(), frameEnd.getValue());
    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()), baseFrame, nullTreatment == NullTreatment.IGNORE);
    PatternRecognitionComponents components = new RelationPlanner(analysis, symbolAllocator, idAllocator, lambdaDeclarationToSymbolMap, plannerContext, outerContext, session, recursiveSubqueries).planPatternRecognitionComponents(subPlan::rewrite, frame.getSubsets(), ImmutableList.of(), frame.getAfterMatchSkipTo(), frame.getPatternSearchMode(), frame.getPattern().orElseThrow(), frame.getVariableDefinitions());
    // create pattern recognition node
    return new PlanBuilder(subPlan.getTranslations().withAdditionalMappings(ImmutableMap.of(scopeAwareKey(windowFunction, analysis, subPlan.getScope()), newSymbol)), new PatternRecognitionNode(idAllocator.getNextId(), subPlan.getRoot(), specification, Optional.empty(), ImmutableSet.of(), 0, ImmutableMap.of(newSymbol, function), components.getMeasures(), Optional.of(baseFrame), RowsPerMatch.WINDOW, components.getSkipToLabel(), components.getSkipToPosition(), components.isInitial(), components.getPattern(), components.getSubsets(), components.getVariableDefinitions()));
}
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) PatternRecognitionNode(io.trino.sql.planner.plan.PatternRecognitionNode) WindowFrame(io.trino.sql.tree.WindowFrame) LambdaExpression(io.trino.sql.tree.LambdaExpression) PatternRecognitionComponents(io.trino.sql.planner.RelationPlanner.PatternRecognitionComponents)

Example 4 with PatternRecognitionNode

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

the class QueryPlanner method planPatternRecognition.

private PlanBuilder planPatternRecognition(PlanBuilder subPlan, WindowOperation windowMeasure, ResolvedWindow window, Optional<Symbol> frameEndSymbol) {
    WindowNode.Specification specification = planWindowSpecification(window.getPartitionBy(), window.getOrderBy(), subPlan::translate);
    // in window frame with pattern recognition, the frame extent is specified as `ROWS BETWEEN CURRENT ROW AND ... `
    WindowFrame frame = window.getFrame().orElseThrow();
    FrameBound frameEnd = frame.getEnd().orElseThrow();
    WindowNode.Frame baseFrame = new WindowNode.Frame(WindowFrame.Type.ROWS, FrameBound.Type.CURRENT_ROW, Optional.empty(), Optional.empty(), frameEnd.getType(), frameEndSymbol, Optional.empty(), Optional.empty(), frameEnd.getValue());
    PatternRecognitionComponents components = new RelationPlanner(analysis, symbolAllocator, idAllocator, lambdaDeclarationToSymbolMap, plannerContext, outerContext, session, recursiveSubqueries).planPatternRecognitionComponents(subPlan::rewrite, frame.getSubsets(), ImmutableList.of(analysis.getMeasureDefinition(windowMeasure)), frame.getAfterMatchSkipTo(), frame.getPatternSearchMode(), frame.getPattern().orElseThrow(), frame.getVariableDefinitions());
    Symbol measureSymbol = getOnlyElement(components.getMeasures().keySet());
    // create pattern recognition node
    return new PlanBuilder(subPlan.getTranslations().withAdditionalMappings(ImmutableMap.of(scopeAwareKey(windowMeasure, analysis, subPlan.getScope()), measureSymbol)), new PatternRecognitionNode(idAllocator.getNextId(), subPlan.getRoot(), specification, Optional.empty(), ImmutableSet.of(), 0, ImmutableMap.of(), components.getMeasures(), Optional.of(baseFrame), RowsPerMatch.WINDOW, components.getSkipToLabel(), components.getSkipToPosition(), components.isInitial(), components.getPattern(), components.getSubsets(), components.getVariableDefinitions()));
}
Also used : WindowNode(io.trino.sql.planner.plan.WindowNode) WindowFrame(io.trino.sql.tree.WindowFrame) PatternRecognitionNode(io.trino.sql.planner.plan.PatternRecognitionNode) WindowFrame(io.trino.sql.tree.WindowFrame) FrameBound(io.trino.sql.tree.FrameBound) PatternRecognitionComponents(io.trino.sql.planner.RelationPlanner.PatternRecognitionComponents) PlanBuilder.newPlanBuilder(io.trino.sql.planner.PlanBuilder.newPlanBuilder)

Example 5 with PatternRecognitionNode

use of io.trino.sql.planner.plan.PatternRecognitionNode 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

PatternRecognitionNode (io.trino.sql.planner.plan.PatternRecognitionNode)10 Symbol (io.trino.sql.planner.Symbol)6 Measure (io.trino.sql.planner.plan.PatternRecognitionNode.Measure)6 WindowNode (io.trino.sql.planner.plan.WindowNode)5 ExpressionAndValuePointers (io.trino.sql.planner.rowpattern.LogicalIndexExtractor.ExpressionAndValuePointers)5 IrLabel (io.trino.sql.planner.rowpattern.ir.IrLabel)5 Map (java.util.Map)5 ImmutableMap (com.google.common.collect.ImmutableMap)4 PlanNode (io.trino.sql.planner.plan.PlanNode)4 ImmutableMap.toImmutableMap (com.google.common.collect.ImmutableMap.toImmutableMap)3 ImmutableSet (com.google.common.collect.ImmutableSet)3 Assignments (io.trino.sql.planner.plan.Assignments)3 ProjectNode (io.trino.sql.planner.plan.ProjectNode)3 Function (io.trino.sql.planner.plan.WindowNode.Function)3 ImmutableList (com.google.common.collect.ImmutableList)2 Session (io.trino.Session)2 ResolvedFunction (io.trino.metadata.ResolvedFunction)2 Type (io.trino.spi.type.Type)2 PlanBuilder.newPlanBuilder (io.trino.sql.planner.PlanBuilder.newPlanBuilder)2 PatternRecognitionComponents (io.trino.sql.planner.RelationPlanner.PatternRecognitionComponents)2