Search in sources :

Example 6 with SortItem

use of io.trino.sql.tree.SortItem in project trino by trinodb.

the class TreePrinter method print.

public void print(Node root) {
    AstVisitor<Void, Integer> printer = new DefaultTraversalVisitor<Integer>() {

        @Override
        protected Void visitNode(Node node, Integer indentLevel) {
            throw new UnsupportedOperationException("not yet implemented: " + node);
        }

        @Override
        protected Void visitQuery(Query node, Integer indentLevel) {
            print(indentLevel, "Query ");
            indentLevel++;
            print(indentLevel, "QueryBody");
            process(node.getQueryBody(), indentLevel);
            if (node.getOrderBy().isPresent()) {
                print(indentLevel, "OrderBy");
                process(node.getOrderBy().get(), indentLevel + 1);
            }
            if (node.getLimit().isPresent()) {
                print(indentLevel, "Limit: " + node.getLimit().get());
            }
            return null;
        }

        @Override
        protected Void visitQuerySpecification(QuerySpecification node, Integer indentLevel) {
            print(indentLevel, "QuerySpecification ");
            indentLevel++;
            process(node.getSelect(), indentLevel);
            if (node.getFrom().isPresent()) {
                print(indentLevel, "From");
                process(node.getFrom().get(), indentLevel + 1);
            }
            if (node.getWhere().isPresent()) {
                print(indentLevel, "Where");
                process(node.getWhere().get(), indentLevel + 1);
            }
            if (node.getGroupBy().isPresent()) {
                String distinct = "";
                if (node.getGroupBy().get().isDistinct()) {
                    distinct = "[DISTINCT]";
                }
                print(indentLevel, "GroupBy" + distinct);
                for (GroupingElement groupingElement : node.getGroupBy().get().getGroupingElements()) {
                    print(indentLevel, "SimpleGroupBy");
                    if (groupingElement instanceof SimpleGroupBy) {
                        for (Expression column : groupingElement.getExpressions()) {
                            process(column, indentLevel + 1);
                        }
                    } else if (groupingElement instanceof GroupingSets) {
                        print(indentLevel + 1, "GroupingSets");
                        for (List<Expression> set : ((GroupingSets) groupingElement).getSets()) {
                            print(indentLevel + 2, "GroupingSet[");
                            for (Expression expression : set) {
                                process(expression, indentLevel + 3);
                            }
                            print(indentLevel + 2, "]");
                        }
                    } else if (groupingElement instanceof Cube) {
                        print(indentLevel + 1, "Cube");
                        for (Expression column : groupingElement.getExpressions()) {
                            process(column, indentLevel + 1);
                        }
                    } else if (groupingElement instanceof Rollup) {
                        print(indentLevel + 1, "Rollup");
                        for (Expression column : groupingElement.getExpressions()) {
                            process(column, indentLevel + 1);
                        }
                    }
                }
            }
            if (node.getHaving().isPresent()) {
                print(indentLevel, "Having");
                process(node.getHaving().get(), indentLevel + 1);
            }
            if (!node.getWindows().isEmpty()) {
                print(indentLevel, "Window");
                for (WindowDefinition windowDefinition : node.getWindows()) {
                    process(windowDefinition, indentLevel + 1);
                }
            }
            if (node.getOrderBy().isPresent()) {
                print(indentLevel, "OrderBy");
                process(node.getOrderBy().get(), indentLevel + 1);
            }
            if (node.getLimit().isPresent()) {
                print(indentLevel, "Limit: " + node.getLimit().get());
            }
            return null;
        }

        @Override
        protected Void visitOrderBy(OrderBy node, Integer indentLevel) {
            for (SortItem sortItem : node.getSortItems()) {
                process(sortItem, indentLevel);
            }
            return null;
        }

        @Override
        protected Void visitWindowDefinition(WindowDefinition node, Integer indentLevel) {
            print(indentLevel, "WindowDefinition[" + node.getName() + "]");
            process(node.getWindow(), indentLevel + 1);
            return null;
        }

        @Override
        protected Void visitWindowReference(WindowReference node, Integer indentLevel) {
            print(indentLevel, "WindowReference[" + node.getName() + "]");
            return null;
        }

        @Override
        public Void visitWindowSpecification(WindowSpecification node, Integer indentLevel) {
            if (node.getExistingWindowName().isPresent()) {
                print(indentLevel, "ExistingWindowName " + node.getExistingWindowName().get());
            }
            if (!node.getPartitionBy().isEmpty()) {
                print(indentLevel, "PartitionBy");
                for (Expression expression : node.getPartitionBy()) {
                    process(expression, indentLevel + 1);
                }
            }
            if (node.getOrderBy().isPresent()) {
                print(indentLevel, "OrderBy");
                process(node.getOrderBy().get(), indentLevel + 1);
            }
            if (node.getFrame().isPresent()) {
                print(indentLevel, "Frame");
                process(node.getFrame().get(), indentLevel + 1);
            }
            return null;
        }

        @Override
        protected Void visitSelect(Select node, Integer indentLevel) {
            String distinct = "";
            if (node.isDistinct()) {
                distinct = "[DISTINCT]";
            }
            print(indentLevel, "Select" + distinct);
            // visit children
            super.visitSelect(node, indentLevel + 1);
            return null;
        }

        @Override
        protected Void visitAllColumns(AllColumns node, Integer indent) {
            StringBuilder aliases = new StringBuilder();
            if (!node.getAliases().isEmpty()) {
                aliases.append(" [Aliases: ");
                Joiner.on(", ").appendTo(aliases, node.getAliases());
                aliases.append("]");
            }
            print(indent, "All columns" + aliases.toString());
            if (node.getTarget().isPresent()) {
                // visit child
                super.visitAllColumns(node, indent + 1);
            }
            return null;
        }

        @Override
        protected Void visitSingleColumn(SingleColumn node, Integer indent) {
            if (node.getAlias().isPresent()) {
                print(indent, "Alias: " + node.getAlias().get());
            }
            // visit children
            super.visitSingleColumn(node, indent + 1);
            return null;
        }

        @Override
        protected Void visitComparisonExpression(ComparisonExpression node, Integer indentLevel) {
            print(indentLevel, node.getOperator().toString());
            super.visitComparisonExpression(node, indentLevel + 1);
            return null;
        }

        @Override
        protected Void visitArithmeticBinary(ArithmeticBinaryExpression node, Integer indentLevel) {
            print(indentLevel, node.getOperator().toString());
            super.visitArithmeticBinary(node, indentLevel + 1);
            return null;
        }

        @Override
        protected Void visitLogicalExpression(LogicalExpression node, Integer indentLevel) {
            print(indentLevel, node.getOperator().toString());
            super.visitLogicalExpression(node, indentLevel + 1);
            return null;
        }

        @Override
        protected Void visitStringLiteral(StringLiteral node, Integer indentLevel) {
            print(indentLevel, "String[" + node.getValue() + "]");
            return null;
        }

        @Override
        protected Void visitBinaryLiteral(BinaryLiteral node, Integer indentLevel) {
            print(indentLevel, "Binary[" + node.toHexString() + "]");
            return null;
        }

        @Override
        protected Void visitBooleanLiteral(BooleanLiteral node, Integer indentLevel) {
            print(indentLevel, "Boolean[" + node.getValue() + "]");
            return null;
        }

        @Override
        protected Void visitLongLiteral(LongLiteral node, Integer indentLevel) {
            print(indentLevel, "Long[" + node.getValue() + "]");
            return null;
        }

        @Override
        protected Void visitLikePredicate(LikePredicate node, Integer indentLevel) {
            print(indentLevel, "LIKE");
            super.visitLikePredicate(node, indentLevel + 1);
            return null;
        }

        @Override
        protected Void visitIdentifier(Identifier node, Integer indentLevel) {
            QualifiedName resolved = resolvedNameReferences.get(node);
            String resolvedName = "";
            if (resolved != null) {
                resolvedName = "=>" + resolved.toString();
            }
            print(indentLevel, "Identifier[" + node.getValue() + resolvedName + "]");
            return null;
        }

        @Override
        protected Void visitDereferenceExpression(DereferenceExpression node, Integer indentLevel) {
            QualifiedName resolved = resolvedNameReferences.get(node);
            String resolvedName = "";
            if (resolved != null) {
                resolvedName = "=>" + resolved.toString();
            }
            print(indentLevel, "DereferenceExpression[" + node + resolvedName + "]");
            return null;
        }

        @Override
        protected Void visitFunctionCall(FunctionCall node, Integer indentLevel) {
            String name = Joiner.on('.').join(node.getName().getParts());
            print(indentLevel, "FunctionCall[" + name + "]");
            super.visitFunctionCall(node, indentLevel + 1);
            return null;
        }

        @Override
        protected Void visitTable(Table node, Integer indentLevel) {
            String name = Joiner.on('.').join(node.getName().getParts());
            print(indentLevel, "Table[" + name + "]");
            return null;
        }

        @Override
        protected Void visitValues(Values node, Integer indentLevel) {
            print(indentLevel, "Values");
            super.visitValues(node, indentLevel + 1);
            return null;
        }

        @Override
        protected Void visitRow(Row node, Integer indentLevel) {
            print(indentLevel, "Row");
            super.visitRow(node, indentLevel + 1);
            return null;
        }

        @Override
        protected Void visitAliasedRelation(AliasedRelation node, Integer indentLevel) {
            print(indentLevel, "Alias[" + node.getAlias() + "]");
            super.visitAliasedRelation(node, indentLevel + 1);
            return null;
        }

        @Override
        protected Void visitSampledRelation(SampledRelation node, Integer indentLevel) {
            print(indentLevel, "TABLESAMPLE[" + node.getType() + " (" + node.getSamplePercentage() + ")]");
            super.visitSampledRelation(node, indentLevel + 1);
            return null;
        }

        @Override
        protected Void visitTableSubquery(TableSubquery node, Integer indentLevel) {
            print(indentLevel, "SubQuery");
            super.visitTableSubquery(node, indentLevel + 1);
            return null;
        }

        @Override
        protected Void visitInPredicate(InPredicate node, Integer indentLevel) {
            print(indentLevel, "IN");
            super.visitInPredicate(node, indentLevel + 1);
            return null;
        }

        @Override
        protected Void visitSubqueryExpression(SubqueryExpression node, Integer indentLevel) {
            print(indentLevel, "SubQuery");
            super.visitSubqueryExpression(node, indentLevel + 1);
            return null;
        }
    };
    printer.process(root, 0);
}
Also used : ArithmeticBinaryExpression(io.trino.sql.tree.ArithmeticBinaryExpression) SimpleGroupBy(io.trino.sql.tree.SimpleGroupBy) Query(io.trino.sql.tree.Query) Rollup(io.trino.sql.tree.Rollup) BooleanLiteral(io.trino.sql.tree.BooleanLiteral) Node(io.trino.sql.tree.Node) Values(io.trino.sql.tree.Values) AllColumns(io.trino.sql.tree.AllColumns) WindowReference(io.trino.sql.tree.WindowReference) SubqueryExpression(io.trino.sql.tree.SubqueryExpression) QuerySpecification(io.trino.sql.tree.QuerySpecification) LogicalExpression(io.trino.sql.tree.LogicalExpression) SortItem(io.trino.sql.tree.SortItem) Identifier(io.trino.sql.tree.Identifier) List(java.util.List) FunctionCall(io.trino.sql.tree.FunctionCall) SampledRelation(io.trino.sql.tree.SampledRelation) GroupingSets(io.trino.sql.tree.GroupingSets) OrderBy(io.trino.sql.tree.OrderBy) DereferenceExpression(io.trino.sql.tree.DereferenceExpression) Table(io.trino.sql.tree.Table) LongLiteral(io.trino.sql.tree.LongLiteral) QualifiedName(io.trino.sql.tree.QualifiedName) WindowSpecification(io.trino.sql.tree.WindowSpecification) DefaultTraversalVisitor(io.trino.sql.tree.DefaultTraversalVisitor) SingleColumn(io.trino.sql.tree.SingleColumn) LikePredicate(io.trino.sql.tree.LikePredicate) TableSubquery(io.trino.sql.tree.TableSubquery) InPredicate(io.trino.sql.tree.InPredicate) GroupingElement(io.trino.sql.tree.GroupingElement) ComparisonExpression(io.trino.sql.tree.ComparisonExpression) BinaryLiteral(io.trino.sql.tree.BinaryLiteral) StringLiteral(io.trino.sql.tree.StringLiteral) SubqueryExpression(io.trino.sql.tree.SubqueryExpression) ArithmeticBinaryExpression(io.trino.sql.tree.ArithmeticBinaryExpression) ComparisonExpression(io.trino.sql.tree.ComparisonExpression) DereferenceExpression(io.trino.sql.tree.DereferenceExpression) LogicalExpression(io.trino.sql.tree.LogicalExpression) Expression(io.trino.sql.tree.Expression) Cube(io.trino.sql.tree.Cube) Select(io.trino.sql.tree.Select) Row(io.trino.sql.tree.Row) WindowDefinition(io.trino.sql.tree.WindowDefinition) AliasedRelation(io.trino.sql.tree.AliasedRelation)

Example 7 with SortItem

use of io.trino.sql.tree.SortItem in project trino by trinodb.

the class QueryPlanner method orderingScheme.

private Optional<OrderingScheme> orderingScheme(PlanBuilder subPlan, Optional<OrderBy> orderBy, List<Expression> orderByExpressions) {
    if (orderBy.isEmpty() || (isSkipRedundantSort(session)) && analysis.isOrderByRedundant(orderBy.get())) {
        return Optional.empty();
    }
    Iterator<SortItem> sortItems = orderBy.get().getSortItems().iterator();
    ImmutableList.Builder<Symbol> orderBySymbols = ImmutableList.builder();
    Map<Symbol, SortOrder> orderings = new HashMap<>();
    for (Expression fieldOrExpression : orderByExpressions) {
        Symbol symbol = subPlan.translate(fieldOrExpression);
        SortItem sortItem = sortItems.next();
        if (!orderings.containsKey(symbol)) {
            orderBySymbols.add(symbol);
            orderings.put(symbol, sortItemToSortOrder(sortItem));
        }
    }
    return Optional.of(new OrderingScheme(orderBySymbols.build(), orderings));
}
Also used : SortItem(io.trino.sql.tree.SortItem) LinkedHashMap(java.util.LinkedHashMap) HashMap(java.util.HashMap) 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) ImmutableList.toImmutableList(com.google.common.collect.ImmutableList.toImmutableList) ImmutableList(com.google.common.collect.ImmutableList) SortOrder(io.trino.spi.connector.SortOrder) OrderingScheme.sortItemToSortOrder(io.trino.sql.planner.OrderingScheme.sortItemToSortOrder)

Example 8 with SortItem

use of io.trino.sql.tree.SortItem in project trino by trinodb.

the class RelationPlanner method visitPatternRecognitionRelation.

@Override
protected RelationPlan visitPatternRecognitionRelation(PatternRecognitionRelation node, Void context) {
    RelationPlan subPlan = process(node.getInput(), context);
    // Pre-project inputs for PARTITION BY and ORDER BY
    List<Expression> inputs = ImmutableList.<Expression>builder().addAll(node.getPartitionBy()).addAll(getSortItemsFromOrderBy(node.getOrderBy()).stream().map(SortItem::getSortKey).collect(toImmutableList())).build();
    PlanBuilder planBuilder = newPlanBuilder(subPlan, analysis, lambdaDeclarationToSymbolMap);
    // no handleSubqueries because subqueries are not allowed here
    planBuilder = planBuilder.appendProjections(inputs, symbolAllocator, idAllocator);
    ImmutableList.Builder<Symbol> outputLayout = ImmutableList.builder();
    boolean oneRowOutput = node.getRowsPerMatch().isEmpty() || node.getRowsPerMatch().get().isOneRow();
    WindowNode.Specification specification = planWindowSpecification(node.getPartitionBy(), node.getOrderBy(), planBuilder::translate);
    outputLayout.addAll(specification.getPartitionBy());
    if (!oneRowOutput) {
        getSortItemsFromOrderBy(node.getOrderBy()).stream().map(SortItem::getSortKey).map(planBuilder::translate).forEach(outputLayout::add);
    }
    planBuilder = subqueryPlanner.handleSubqueries(planBuilder, extractPatternRecognitionExpressions(node.getVariableDefinitions(), node.getMeasures()), analysis.getSubqueries(node));
    PatternRecognitionComponents components = planPatternRecognitionComponents(planBuilder::rewrite, node.getSubsets(), node.getMeasures(), node.getAfterMatchSkipTo(), node.getPatternSearchMode(), node.getPattern(), node.getVariableDefinitions());
    outputLayout.addAll(components.getMeasureOutputs());
    if (!oneRowOutput) {
        Set<Symbol> inputSymbolsOnOutput = ImmutableSet.copyOf(outputLayout.build());
        subPlan.getFieldMappings().stream().filter(symbol -> !inputSymbolsOnOutput.contains(symbol)).forEach(outputLayout::add);
    }
    PatternRecognitionNode planNode = new PatternRecognitionNode(idAllocator.getNextId(), planBuilder.getRoot(), specification, Optional.empty(), ImmutableSet.of(), 0, ImmutableMap.of(), components.getMeasures(), Optional.empty(), node.getRowsPerMatch().orElse(ONE), components.getSkipToLabel(), components.getSkipToPosition(), components.isInitial(), components.getPattern(), components.getSubsets(), components.getVariableDefinitions());
    return new RelationPlan(planNode, analysis.getScope(node), outputLayout.build(), outerContext);
}
Also used : ListMultimap(com.google.common.collect.ListMultimap) SubsetDefinition(io.trino.sql.tree.SubsetDefinition) CorrelatedJoinNode(io.trino.sql.planner.plan.CorrelatedJoinNode) PlanNode(io.trino.sql.planner.plan.PlanNode) SetOperation(io.trino.sql.tree.SetOperation) Values(io.trino.sql.tree.Values) NOT_SUPPORTED(io.trino.spi.StandardErrorCode.NOT_SUPPORTED) AliasedRelation(io.trino.sql.tree.AliasedRelation) Node(io.trino.sql.tree.Node) ONE(io.trino.sql.tree.PatternRecognitionRelation.RowsPerMatch.ONE) Map(java.util.Map) RowPattern(io.trino.sql.tree.RowPattern) Union(io.trino.sql.tree.Union) SemanticExceptions.semanticException(io.trino.sql.analyzer.SemanticExceptions.semanticException) ENGLISH(java.util.Locale.ENGLISH) TableScanNode(io.trino.sql.planner.plan.TableScanNode) Identifier(io.trino.sql.tree.Identifier) Lateral(io.trino.sql.tree.Lateral) SampledRelation(io.trino.sql.tree.SampledRelation) ImmutableList.toImmutableList(com.google.common.collect.ImmutableList.toImmutableList) Assignments(io.trino.sql.planner.plan.Assignments) Join(io.trino.sql.tree.Join) Set(java.util.Set) PAST_LAST(io.trino.sql.tree.SkipTo.Position.PAST_LAST) SortItem(io.trino.sql.tree.SortItem) NodeUtils.getSortItemsFromOrderBy(io.trino.sql.NodeUtils.getSortItemsFromOrderBy) RelationType(io.trino.sql.analyzer.RelationType) IntersectNode(io.trino.sql.planner.plan.IntersectNode) ImmutableMap.toImmutableMap(com.google.common.collect.ImmutableMap.toImmutableMap) QueryPlanner.pruneInvisibleFields(io.trino.sql.planner.QueryPlanner.pruneInvisibleFields) PlanBuilder.newPlanBuilder(io.trino.sql.planner.PlanBuilder.newPlanBuilder) ImmutableListMultimap(com.google.common.collect.ImmutableListMultimap) IrRowPattern(io.trino.sql.planner.rowpattern.ir.IrRowPattern) ValuesNode(io.trino.sql.planner.plan.ValuesNode) TRUE(java.lang.Boolean.TRUE) Session(io.trino.Session) SkipTo(io.trino.sql.tree.SkipTo) TypeCoercion(io.trino.type.TypeCoercion) ArrayList(java.util.ArrayList) LinkedHashMap(java.util.LinkedHashMap) NodeRef(io.trino.sql.tree.NodeRef) INNER(io.trino.sql.tree.Join.Type.INNER) ColumnHandle(io.trino.spi.connector.ColumnHandle) AggregationNode(io.trino.sql.planner.plan.AggregationNode) ImmutableSet.toImmutableSet(com.google.common.collect.ImmutableSet.toImmutableSet) Query(io.trino.sql.tree.Query) ExpressionUtils(io.trino.sql.ExpressionUtils) Relation(io.trino.sql.tree.Relation) IrLabel(io.trino.sql.planner.rowpattern.ir.IrLabel) PatternRecognitionRelation(io.trino.sql.tree.PatternRecognitionRelation) Iterables.getOnlyElement(com.google.common.collect.Iterables.getOnlyElement) UnnestNode(io.trino.sql.planner.plan.UnnestNode) AggregationNode.singleGroupingSet(io.trino.sql.planner.plan.AggregationNode.singleGroupingSet) TableHandle(io.trino.metadata.TableHandle) ExceptNode(io.trino.sql.planner.plan.ExceptNode) RowPatternToIrRewriter(io.trino.sql.planner.rowpattern.RowPatternToIrRewriter) Table(io.trino.sql.tree.Table) SampleNode(io.trino.sql.planner.plan.SampleNode) MeasureDefinition(io.trino.sql.tree.MeasureDefinition) Intersect(io.trino.sql.tree.Intersect) Scope(io.trino.sql.analyzer.Scope) FilterNode(io.trino.sql.planner.plan.FilterNode) LambdaArgumentDeclaration(io.trino.sql.tree.LambdaArgumentDeclaration) Preconditions.checkArgument(com.google.common.base.Preconditions.checkArgument) IMPLICIT(io.trino.sql.tree.Join.Type.IMPLICIT) UnnestAnalysis(io.trino.sql.analyzer.Analysis.UnnestAnalysis) QueryPlanner.coerce(io.trino.sql.planner.QueryPlanner.coerce) TableSubquery(io.trino.sql.tree.TableSubquery) JoinNode(io.trino.sql.planner.plan.JoinNode) QueryPlanner.planWindowSpecification(io.trino.sql.planner.QueryPlanner.planWindowSpecification) QuerySpecification(io.trino.sql.tree.QuerySpecification) RowType(io.trino.spi.type.RowType) ImmutableSet(com.google.common.collect.ImmutableSet) QueryPlanner.coerceIfNecessary(io.trino.sql.planner.QueryPlanner.coerceIfNecessary) ImmutableMap(com.google.common.collect.ImmutableMap) TypeSignatureTranslator.toSqlType(io.trino.sql.analyzer.TypeSignatureTranslator.toSqlType) VariableDefinition(io.trino.sql.tree.VariableDefinition) PatternRecognitionNode(io.trino.sql.planner.plan.PatternRecognitionNode) ComparisonExpression(io.trino.sql.tree.ComparisonExpression) CROSS(io.trino.sql.tree.Join.Type.CROSS) INITIAL(io.trino.sql.tree.PatternSearchMode.Mode.INITIAL) CoalesceExpression(io.trino.sql.tree.CoalesceExpression) List(java.util.List) PatternSearchMode(io.trino.sql.tree.PatternSearchMode) NaturalJoin(io.trino.sql.tree.NaturalJoin) Optional(java.util.Optional) Expression(io.trino.sql.tree.Expression) WindowNode(io.trino.sql.planner.plan.WindowNode) PlannerContext(io.trino.sql.PlannerContext) Analysis(io.trino.sql.analyzer.Analysis) UnionNode(io.trino.sql.planner.plan.UnionNode) SubqueryExpression(io.trino.sql.tree.SubqueryExpression) Type(io.trino.spi.type.Type) Measure(io.trino.sql.planner.plan.PatternRecognitionNode.Measure) HashMap(java.util.HashMap) Unnest(io.trino.sql.tree.Unnest) Function(java.util.function.Function) Cast(io.trino.sql.tree.Cast) ImmutableList(com.google.common.collect.ImmutableList) Objects.requireNonNull(java.util.Objects.requireNonNull) Field(io.trino.sql.analyzer.Field) ProjectNode(io.trino.sql.planner.plan.ProjectNode) ExpressionAndValuePointers(io.trino.sql.planner.rowpattern.LogicalIndexExtractor.ExpressionAndValuePointers) AstVisitor(io.trino.sql.tree.AstVisitor) JoinUsing(io.trino.sql.tree.JoinUsing) Except(io.trino.sql.tree.Except) LogicalIndexExtractor(io.trino.sql.planner.rowpattern.LogicalIndexExtractor) TRUE_LITERAL(io.trino.sql.tree.BooleanLiteral.TRUE_LITERAL) QualifiedName(io.trino.sql.tree.QualifiedName) QueryPlanner.extractPatternRecognitionExpressions(io.trino.sql.planner.QueryPlanner.extractPatternRecognitionExpressions) Row(io.trino.sql.tree.Row) JoinCriteria(io.trino.sql.tree.JoinCriteria) WindowNode(io.trino.sql.planner.plan.WindowNode) ImmutableList.toImmutableList(com.google.common.collect.ImmutableList.toImmutableList) ImmutableList(com.google.common.collect.ImmutableList) PlanBuilder.newPlanBuilder(io.trino.sql.planner.PlanBuilder.newPlanBuilder) SortItem(io.trino.sql.tree.SortItem) PatternRecognitionNode(io.trino.sql.planner.plan.PatternRecognitionNode) ComparisonExpression(io.trino.sql.tree.ComparisonExpression) CoalesceExpression(io.trino.sql.tree.CoalesceExpression) Expression(io.trino.sql.tree.Expression) SubqueryExpression(io.trino.sql.tree.SubqueryExpression)

Example 9 with SortItem

use of io.trino.sql.tree.SortItem in project trino by trinodb.

the class QueryPlanner method aggregate.

private PlanBuilder aggregate(PlanBuilder subPlan, QuerySpecification node) {
    if (!analysis.isAggregation(node)) {
        return subPlan;
    }
    ImmutableList.Builder<Expression> inputBuilder = ImmutableList.builder();
    analysis.getAggregates(node).stream().map(FunctionCall::getArguments).flatMap(List::stream).filter(// lambda expression is generated at execution time
    expression -> !(expression instanceof LambdaExpression)).forEach(inputBuilder::add);
    analysis.getAggregates(node).stream().map(FunctionCall::getOrderBy).map(NodeUtils::getSortItemsFromOrderBy).flatMap(List::stream).map(SortItem::getSortKey).forEach(inputBuilder::add);
    // filter expressions need to be projected first
    analysis.getAggregates(node).stream().map(FunctionCall::getFilter).filter(Optional::isPresent).map(Optional::get).forEach(inputBuilder::add);
    GroupingSetAnalysis groupingSetAnalysis = analysis.getGroupingSets(node);
    inputBuilder.addAll(groupingSetAnalysis.getComplexExpressions());
    List<Expression> inputs = inputBuilder.build();
    subPlan = subqueryPlanner.handleSubqueries(subPlan, inputs, analysis.getSubqueries(node));
    subPlan = subPlan.appendProjections(inputs, symbolAllocator, idAllocator);
    // Add projection to coerce inputs to their site-specific types.
    // This is important because the same lexical expression may need to be coerced
    // in different ways if it's referenced by multiple arguments to the window function.
    // For example, given v::integer,
    // avg(v)
    // Needs to be rewritten as
    // avg(CAST(v AS double))
    PlanAndMappings coercions = coerce(subPlan, inputs, analysis, idAllocator, symbolAllocator, typeCoercion);
    subPlan = coercions.getSubPlan();
    GroupingSetsPlan groupingSets = planGroupingSets(subPlan, node, groupingSetAnalysis);
    subPlan = planAggregation(groupingSets.getSubPlan(), groupingSets.getGroupingSets(), groupingSets.getGroupIdSymbol(), analysis.getAggregates(node), coercions::get);
    return planGroupingOperations(subPlan, node, groupingSets.getGroupIdSymbol(), groupingSets.getColumnOnlyGroupingSets());
}
Also used : PatternRecognitionComponents(io.trino.sql.planner.RelationPlanner.PatternRecognitionComponents) Arrays(java.util.Arrays) TypeSignatureProvider.fromTypes(io.trino.sql.analyzer.TypeSignatureProvider.fromTypes) Delete(io.trino.sql.tree.Delete) PlanNode(io.trino.sql.planner.plan.PlanNode) Node(io.trino.sql.tree.Node) Offset(io.trino.sql.tree.Offset) PlanNodeId(io.trino.sql.planner.plan.PlanNodeId) LongLiteral(io.trino.sql.tree.LongLiteral) Map(java.util.Map) Union(io.trino.sql.tree.Union) FetchFirst(io.trino.sql.tree.FetchFirst) TableScanNode(io.trino.sql.planner.plan.TableScanNode) ImmutableList.toImmutableList(com.google.common.collect.ImmutableList.toImmutableList) Assignments(io.trino.sql.planner.plan.Assignments) Set(java.util.Set) TableSchema(io.trino.metadata.TableSchema) SortItem(io.trino.sql.tree.SortItem) NodeUtils.getSortItemsFromOrderBy(io.trino.sql.NodeUtils.getSortItemsFromOrderBy) DEFAULT_FRAME(io.trino.sql.planner.plan.WindowNode.Frame.DEFAULT_FRAME) RelationType(io.trino.sql.analyzer.RelationType) ImmutableMap.toImmutableMap(com.google.common.collect.ImmutableMap.toImmutableMap) AggregationNode.groupingSets(io.trino.sql.planner.plan.AggregationNode.groupingSets) DeleteTarget(io.trino.sql.planner.plan.TableWriterNode.DeleteTarget) PlanBuilder.newPlanBuilder(io.trino.sql.planner.PlanBuilder.newPlanBuilder) ImmutableListMultimap(com.google.common.collect.ImmutableListMultimap) DecimalLiteral(io.trino.sql.tree.DecimalLiteral) ValuesNode(io.trino.sql.planner.plan.ValuesNode) ExpressionAnalyzer.isNumericType(io.trino.sql.analyzer.ExpressionAnalyzer.isNumericType) Session(io.trino.Session) Iterables(com.google.common.collect.Iterables) LimitNode(io.trino.sql.planner.plan.LimitNode) TypeCoercion(io.trino.type.TypeCoercion) BOOLEAN(io.trino.spi.type.BooleanType.BOOLEAN) ArrayList(java.util.ArrayList) LinkedHashMap(java.util.LinkedHashMap) UpdateTarget(io.trino.sql.planner.plan.TableWriterNode.UpdateTarget) ScopeAware.scopeAwareKey(io.trino.sql.planner.ScopeAware.scopeAwareKey) VARCHAR(io.trino.spi.type.VarcharType.VARCHAR) NodeRef(io.trino.sql.tree.NodeRef) ColumnHandle(io.trino.spi.connector.ColumnHandle) AggregationNode(io.trino.sql.planner.plan.AggregationNode) ImmutableSet.toImmutableSet(com.google.common.collect.ImmutableSet.toImmutableSet) VARBINARY(io.trino.spi.type.VarbinaryType.VARBINARY) GroupingOperationRewriter.rewriteGroupingOperation(io.trino.sql.planner.GroupingOperationRewriter.rewriteGroupingOperation) NodeUtils(io.trino.sql.NodeUtils) INTERVAL_DAY_TIME(io.trino.type.IntervalDayTimeType.INTERVAL_DAY_TIME) Query(io.trino.sql.tree.Query) StringLiteral(io.trino.sql.tree.StringLiteral) Relation(io.trino.sql.tree.Relation) GroupingSetAnalysis(io.trino.sql.analyzer.Analysis.GroupingSetAnalysis) Iterables.getOnlyElement(com.google.common.collect.Iterables.getOnlyElement) SortOrder(io.trino.spi.connector.SortOrder) AggregationNode.singleGroupingSet(io.trino.sql.planner.plan.AggregationNode.singleGroupingSet) TableHandle(io.trino.metadata.TableHandle) Table(io.trino.sql.tree.Table) GroupIdNode(io.trino.sql.planner.plan.GroupIdNode) YEAR(io.trino.sql.tree.IntervalLiteral.IntervalField.YEAR) OffsetNode(io.trino.sql.planner.plan.OffsetNode) ROWS(io.trino.sql.tree.WindowFrame.Type.ROWS) NullTreatment(io.trino.sql.tree.FunctionCall.NullTreatment) DAY(io.trino.sql.tree.IntervalLiteral.IntervalField.DAY) MeasureDefinition(io.trino.sql.tree.MeasureDefinition) INTERVAL_YEAR_MONTH(io.trino.type.IntervalYearMonthType.INTERVAL_YEAR_MONTH) Aggregation(io.trino.sql.planner.plan.AggregationNode.Aggregation) FilterNode(io.trino.sql.planner.plan.FilterNode) LambdaArgumentDeclaration(io.trino.sql.tree.LambdaArgumentDeclaration) Preconditions.checkArgument(com.google.common.base.Preconditions.checkArgument) OrderingScheme.sortItemToSortOrder(io.trino.sql.planner.OrderingScheme.sortItemToSortOrder) SelectExpression(io.trino.sql.analyzer.Analysis.SelectExpression) GROUPS(io.trino.sql.tree.WindowFrame.Type.GROUPS) DeleteNode(io.trino.sql.planner.plan.DeleteNode) Update(io.trino.sql.tree.Update) FunctionCall(io.trino.sql.tree.FunctionCall) QuerySpecification(io.trino.sql.tree.QuerySpecification) ImmutableSet(com.google.common.collect.ImmutableSet) ImmutableMap(com.google.common.collect.ImmutableMap) ResolvedFunction(io.trino.metadata.ResolvedFunction) TypeSignatureTranslator.toSqlType(io.trino.sql.analyzer.TypeSignatureTranslator.toSqlType) IntervalLiteral(io.trino.sql.tree.IntervalLiteral) RANGE(io.trino.sql.tree.WindowFrame.Type.RANGE) VariableDefinition(io.trino.sql.tree.VariableDefinition) PatternRecognitionNode(io.trino.sql.planner.plan.PatternRecognitionNode) Collectors(java.util.stream.Collectors) Sets(com.google.common.collect.Sets) ComparisonExpression(io.trino.sql.tree.ComparisonExpression) String.format(java.lang.String.format) Preconditions.checkState(com.google.common.base.Preconditions.checkState) LESS_THAN_OR_EQUAL(io.trino.sql.tree.ComparisonExpression.Operator.LESS_THAN_OR_EQUAL) GenericLiteral(io.trino.sql.tree.GenericLiteral) SimplePlanRewriter(io.trino.sql.planner.plan.SimplePlanRewriter) List(java.util.List) POSITIVE(io.trino.sql.tree.IntervalLiteral.Sign.POSITIVE) IfExpression(io.trino.sql.tree.IfExpression) ColumnSchema(io.trino.spi.connector.ColumnSchema) BIGINT(io.trino.spi.type.BigintType.BIGINT) WindowFrame(io.trino.sql.tree.WindowFrame) Optional(java.util.Optional) Expression(io.trino.sql.tree.Expression) WindowNode(io.trino.sql.planner.plan.WindowNode) DecimalType(io.trino.spi.type.DecimalType) OrderBy(io.trino.sql.tree.OrderBy) PlannerContext(io.trino.sql.PlannerContext) Analysis(io.trino.sql.analyzer.Analysis) IntStream(java.util.stream.IntStream) FieldId(io.trino.sql.analyzer.FieldId) UnionNode(io.trino.sql.planner.plan.UnionNode) WindowOperation(io.trino.sql.tree.WindowOperation) Type(io.trino.spi.type.Type) LambdaExpression(io.trino.sql.tree.LambdaExpression) HashMap(java.util.HashMap) SystemSessionProperties.getMaxRecursionDepth(io.trino.SystemSessionProperties.getMaxRecursionDepth) SortNode(io.trino.sql.planner.plan.SortNode) Function(java.util.function.Function) Cast(io.trino.sql.tree.Cast) HashSet(java.util.HashSet) ImmutableList(com.google.common.collect.ImmutableList) Objects.requireNonNull(java.util.Objects.requireNonNull) GREATER_THAN_OR_EQUAL(io.trino.sql.tree.ComparisonExpression.Operator.GREATER_THAN_OR_EQUAL) ProjectNode(io.trino.sql.planner.plan.ProjectNode) ResolvedWindow(io.trino.sql.analyzer.Analysis.ResolvedWindow) RowsPerMatch(io.trino.sql.tree.PatternRecognitionRelation.RowsPerMatch) Iterator(java.util.Iterator) TRUE_LITERAL(io.trino.sql.tree.BooleanLiteral.TRUE_LITERAL) UpdateNode(io.trino.sql.planner.plan.UpdateNode) QualifiedName(io.trino.sql.tree.QualifiedName) SystemSessionProperties.isSkipRedundantSort(io.trino.SystemSessionProperties.isSkipRedundantSort) FrameBound(io.trino.sql.tree.FrameBound) Optional(java.util.Optional) ImmutableList.toImmutableList(com.google.common.collect.ImmutableList.toImmutableList) ImmutableList(com.google.common.collect.ImmutableList) GroupingSetAnalysis(io.trino.sql.analyzer.Analysis.GroupingSetAnalysis) 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) ImmutableList.toImmutableList(com.google.common.collect.ImmutableList.toImmutableList) ArrayList(java.util.ArrayList) List(java.util.List) ImmutableList(com.google.common.collect.ImmutableList) FunctionCall(io.trino.sql.tree.FunctionCall) LambdaExpression(io.trino.sql.tree.LambdaExpression)

Example 10 with SortItem

use of io.trino.sql.tree.SortItem in project trino by trinodb.

the class QueryPlanner method planWindowFunctions.

private PlanBuilder planWindowFunctions(Node node, PlanBuilder subPlan, List<FunctionCall> windowFunctions) {
    if (windowFunctions.isEmpty()) {
        return subPlan;
    }
    for (FunctionCall windowFunction : scopeAwareDistinct(subPlan, windowFunctions)) {
        checkArgument(windowFunction.getFilter().isEmpty(), "Window functions cannot have filter");
        ResolvedWindow window = analysis.getWindow(windowFunction);
        checkState(window != null, "no resolved window for: " + windowFunction);
        // Pre-project inputs.
        // Predefined window parts (specified in WINDOW clause) can only use source symbols, and no output symbols.
        // It matters in case when this window planning takes place in ORDER BY clause, where both source and output
        // symbols are visible.
        // This issue is solved by analyzing window definitions in the source scope. After analysis, the expressions
        // are recorded as belonging to the source scope, and consequentially source symbols will be used to plan them.
        ImmutableList.Builder<Expression> inputsBuilder = ImmutableList.<Expression>builder().addAll(windowFunction.getArguments().stream().filter(// lambda expression is generated at execution time
        argument -> !(argument instanceof LambdaExpression)).collect(Collectors.toList())).addAll(window.getPartitionBy()).addAll(getSortItemsFromOrderBy(window.getOrderBy()).stream().map(SortItem::getSortKey).iterator());
        if (window.getFrame().isPresent()) {
            WindowFrame frame = window.getFrame().get();
            frame.getStart().getValue().ifPresent(inputsBuilder::add);
            if (frame.getEnd().isPresent()) {
                frame.getEnd().get().getValue().ifPresent(inputsBuilder::add);
            }
        }
        List<Expression> inputs = inputsBuilder.build();
        subPlan = subqueryPlanner.handleSubqueries(subPlan, inputs, analysis.getSubqueries(node));
        subPlan = subPlan.appendProjections(inputs, symbolAllocator, idAllocator);
        // Add projection to coerce inputs to their site-specific types.
        // This is important because the same lexical expression may need to be coerced
        // in different ways if it's referenced by multiple arguments to the window function.
        // For example, given v::integer,
        // avg(v) OVER (ORDER BY v)
        // Needs to be rewritten as
        // avg(CAST(v AS double)) OVER (ORDER BY v)
        PlanAndMappings coercions = coerce(subPlan, inputs, analysis, idAllocator, symbolAllocator, typeCoercion);
        subPlan = coercions.getSubPlan();
        // For frame of type RANGE, append casts and functions necessary for frame bound calculations
        Optional<Symbol> frameStart = Optional.empty();
        Optional<Symbol> frameEnd = Optional.empty();
        Optional<Symbol> sortKeyCoercedForFrameStartComparison = Optional.empty();
        Optional<Symbol> sortKeyCoercedForFrameEndComparison = Optional.empty();
        if (window.getFrame().isPresent() && window.getFrame().get().getType() == RANGE) {
            Optional<Expression> startValue = window.getFrame().get().getStart().getValue();
            Optional<Expression> endValue = window.getFrame().get().getEnd().flatMap(FrameBound::getValue);
            // record sortKey coercions for reuse
            Map<Type, Symbol> sortKeyCoercions = new HashMap<>();
            // process frame start
            FrameBoundPlanAndSymbols plan = planFrameBound(subPlan, coercions, startValue, window, sortKeyCoercions);
            subPlan = plan.getSubPlan();
            frameStart = plan.getFrameBoundSymbol();
            sortKeyCoercedForFrameStartComparison = plan.getSortKeyCoercedForFrameBoundComparison();
            // process frame end
            plan = planFrameBound(subPlan, coercions, endValue, window, sortKeyCoercions);
            subPlan = plan.getSubPlan();
            frameEnd = plan.getFrameBoundSymbol();
            sortKeyCoercedForFrameEndComparison = plan.getSortKeyCoercedForFrameBoundComparison();
        } else if (window.getFrame().isPresent() && (window.getFrame().get().getType() == ROWS || window.getFrame().get().getType() == GROUPS)) {
            Optional<Expression> startValue = window.getFrame().get().getStart().getValue();
            Optional<Expression> endValue = window.getFrame().get().getEnd().flatMap(FrameBound::getValue);
            // process frame start
            FrameOffsetPlanAndSymbol plan = planFrameOffset(subPlan, startValue.map(coercions::get));
            subPlan = plan.getSubPlan();
            frameStart = plan.getFrameOffsetSymbol();
            // process frame end
            plan = planFrameOffset(subPlan, endValue.map(coercions::get));
            subPlan = plan.getSubPlan();
            frameEnd = plan.getFrameOffsetSymbol();
        } else if (window.getFrame().isPresent()) {
            throw new IllegalArgumentException("unexpected window frame type: " + window.getFrame().get().getType());
        }
        if (window.getFrame().isPresent() && window.getFrame().get().getPattern().isPresent()) {
            WindowFrame frame = window.getFrame().get();
            subPlan = subqueryPlanner.handleSubqueries(subPlan, extractPatternRecognitionExpressions(frame.getVariableDefinitions(), frame.getMeasures()), analysis.getSubqueries(node));
            subPlan = planPatternRecognition(subPlan, windowFunction, window, coercions, frameEnd);
        } else {
            subPlan = planWindow(subPlan, windowFunction, window, coercions, frameStart, sortKeyCoercedForFrameStartComparison, frameEnd, sortKeyCoercedForFrameEndComparison);
        }
    }
    return subPlan;
}
Also used : Optional(java.util.Optional) LinkedHashMap(java.util.LinkedHashMap) HashMap(java.util.HashMap) ImmutableList.toImmutableList(com.google.common.collect.ImmutableList.toImmutableList) ImmutableList(com.google.common.collect.ImmutableList) FrameBound(io.trino.sql.tree.FrameBound) SortItem(io.trino.sql.tree.SortItem) RelationType(io.trino.sql.analyzer.RelationType) ExpressionAnalyzer.isNumericType(io.trino.sql.analyzer.ExpressionAnalyzer.isNumericType) TypeSignatureTranslator.toSqlType(io.trino.sql.analyzer.TypeSignatureTranslator.toSqlType) DecimalType(io.trino.spi.type.DecimalType) Type(io.trino.spi.type.Type) 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) ResolvedWindow(io.trino.sql.analyzer.Analysis.ResolvedWindow) FunctionCall(io.trino.sql.tree.FunctionCall) LambdaExpression(io.trino.sql.tree.LambdaExpression)

Aggregations

SortItem (io.trino.sql.tree.SortItem)12 ComparisonExpression (io.trino.sql.tree.ComparisonExpression)8 Expression (io.trino.sql.tree.Expression)8 ImmutableList (com.google.common.collect.ImmutableList)7 FunctionCall (io.trino.sql.tree.FunctionCall)7 ImmutableList.toImmutableList (com.google.common.collect.ImmutableList.toImmutableList)6 SelectExpression (io.trino.sql.analyzer.Analysis.SelectExpression)5 IfExpression (io.trino.sql.tree.IfExpression)5 LambdaExpression (io.trino.sql.tree.LambdaExpression)5 OrderBy (io.trino.sql.tree.OrderBy)5 QualifiedName (io.trino.sql.tree.QualifiedName)5 QuerySpecification (io.trino.sql.tree.QuerySpecification)5 WindowFrame (io.trino.sql.tree.WindowFrame)5 LinkedHashMap (java.util.LinkedHashMap)5 QueryUtil.quotedIdentifier (io.trino.sql.QueryUtil.quotedIdentifier)4 Identifier (io.trino.sql.tree.Identifier)4 Query (io.trino.sql.tree.Query)4 Table (io.trino.sql.tree.Table)4 HashMap (java.util.HashMap)4 Test (org.junit.jupiter.api.Test)4