Search in sources :

Example 1 with SortItem

use of com.facebook.presto.sql.tree.SortItem in project presto by prestodb.

the class QueryPlanner method window.

private PlanBuilder window(PlanBuilder subPlan, QuerySpecification node) {
    List<FunctionCall> windowFunctions = ImmutableList.copyOf(analysis.getWindowFunctions(node));
    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(window.getOrderBy(), SortItem::getSortKey));
        if (frameStart != null) {
            inputs.add(frameStart);
        }
        if (frameEnd != null) {
            inputs.add(frameEnd);
        }
        subPlan = subPlan.appendProjections(inputs.build(), symbolAllocator, idAllocator);
        // Rewrite PARTITION BY in terms of pre-projected inputs
        ImmutableList.Builder<Symbol> partitionBySymbols = ImmutableList.builder();
        for (Expression expression : window.getPartitionBy()) {
            partitionBySymbols.add(subPlan.translate(expression));
        }
        // Rewrite ORDER BY in terms of pre-projected inputs
        Map<Symbol, SortOrder> orderings = new LinkedHashMap<>();
        for (SortItem item : window.getOrderBy()) {
            Symbol symbol = subPlan.translate(item.getSortKey());
            orderings.put(symbol, toSortOrder(item));
        }
        // Rewrite frame bounds in terms of pre-projected inputs
        Optional<Symbol> frameStartSymbol = Optional.empty();
        Optional<Symbol> frameEndSymbol = Optional.empty();
        if (frameStart != null) {
            frameStartSymbol = Optional.of(subPlan.translate(frameStart));
        }
        if (frameEnd != null) {
            frameEndSymbol = Optional.of(subPlan.translate(frameEnd));
        }
        WindowNode.Frame frame = new WindowNode.Frame(frameType, frameStartType, frameStartSymbol, frameEndType, frameEndSymbol);
        TranslationMap outputTranslations = subPlan.copyTranslations();
        // Rewrite function call in terms of pre-projected inputs
        Expression parametersReplaced = ExpressionTreeRewriter.rewriteWith(new ParameterRewriter(analysis.getParameters(), analysis), windowFunction);
        outputTranslations.addIntermediateMapping(windowFunction, parametersReplaced);
        Expression rewritten = subPlan.rewrite(parametersReplaced);
        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 symbol, don't create another PlanNode
        if (rewritten instanceof SymbolReference) {
            if (needCoercion) {
                subPlan = explicitCoercionSymbols(subPlan, subPlan.getRoot().getOutputSymbols(), ImmutableList.of(windowFunction));
            }
            continue;
        }
        Symbol newSymbol = symbolAllocator.newSymbol(rewritten, analysis.getType(windowFunction));
        outputTranslations.put(parametersReplaced, newSymbol);
        WindowNode.Function function = new WindowNode.Function((FunctionCall) rewritten, analysis.getFunctionSignature(windowFunction), frame);
        List<Symbol> sourceSymbols = subPlan.getRoot().getOutputSymbols();
        ImmutableList.Builder<Symbol> orderBySymbols = ImmutableList.builder();
        orderBySymbols.addAll(orderings.keySet());
        // create window node
        subPlan = new PlanBuilder(outputTranslations, new WindowNode(idAllocator.getNextId(), subPlan.getRoot(), new WindowNode.Specification(partitionBySymbols.build(), orderBySymbols.build(), orderings), ImmutableMap.of(newSymbol, function), Optional.empty(), ImmutableSet.of(), 0), analysis.getParameters());
        if (needCoercion) {
            subPlan = explicitCoercionSymbols(subPlan, sourceSymbols, ImmutableList.of(windowFunction));
        }
    }
    return subPlan;
}
Also used : Cast(com.facebook.presto.sql.tree.Cast) WindowFrame(com.facebook.presto.sql.tree.WindowFrame) ImmutableList(com.google.common.collect.ImmutableList) SymbolReference(com.facebook.presto.sql.tree.SymbolReference) LinkedHashMap(java.util.LinkedHashMap) IdentityLinkedHashMap(com.facebook.presto.util.maps.IdentityLinkedHashMap) SortItem(com.facebook.presto.sql.tree.SortItem) WindowFrame(com.facebook.presto.sql.tree.WindowFrame) FunctionCall(com.facebook.presto.sql.tree.FunctionCall) Window(com.facebook.presto.sql.tree.Window) WindowNode(com.facebook.presto.sql.planner.plan.WindowNode) FrameBound(com.facebook.presto.sql.tree.FrameBound) SortOrder(com.facebook.presto.spi.block.SortOrder) Expression(com.facebook.presto.sql.tree.Expression)

Example 2 with SortItem

use of com.facebook.presto.sql.tree.SortItem in project presto by prestodb.

the class QueryPlanner method sort.

private PlanBuilder sort(PlanBuilder subPlan, Optional<OrderBy> orderBy, Optional<String> limit, List<Expression> orderByExpressions) {
    if (!orderBy.isPresent()) {
        return subPlan;
    }
    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, toSortOrder(sortItem));
        }
    }
    PlanNode planNode;
    if (limit.isPresent() && !limit.get().equalsIgnoreCase("all")) {
        planNode = new TopNNode(idAllocator.getNextId(), subPlan.getRoot(), Long.parseLong(limit.get()), orderBySymbols.build(), orderings, false);
    } else {
        planNode = new SortNode(idAllocator.getNextId(), subPlan.getRoot(), orderBySymbols.build(), orderings);
    }
    return subPlan.withNewRoot(planNode);
}
Also used : SortItem(com.facebook.presto.sql.tree.SortItem) PlanNode(com.facebook.presto.sql.planner.plan.PlanNode) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) IdentityLinkedHashMap(com.facebook.presto.util.maps.IdentityLinkedHashMap) Expression(com.facebook.presto.sql.tree.Expression) SortNode(com.facebook.presto.sql.planner.plan.SortNode) ImmutableList(com.google.common.collect.ImmutableList) SortOrder(com.facebook.presto.spi.block.SortOrder) TopNNode(com.facebook.presto.sql.planner.plan.TopNNode)

Example 3 with SortItem

use of com.facebook.presto.sql.tree.SortItem in project presto by prestodb.

the class TestSqlParser method testShowPartitions.

@Test
public void testShowPartitions() {
    assertStatement("SHOW PARTITIONS FROM t", new ShowPartitions(QualifiedName.of("t"), Optional.empty(), ImmutableList.of(), Optional.empty()));
    assertStatement("SHOW PARTITIONS FROM t WHERE x = 1", new ShowPartitions(QualifiedName.of("t"), Optional.of(new ComparisonExpression(ComparisonExpressionType.EQUAL, new Identifier("x"), new LongLiteral("1"))), ImmutableList.of(), Optional.empty()));
    assertStatement("SHOW PARTITIONS FROM t WHERE x = 1 ORDER BY y", new ShowPartitions(QualifiedName.of("t"), Optional.of(new ComparisonExpression(ComparisonExpressionType.EQUAL, new Identifier("x"), new LongLiteral("1"))), ImmutableList.of(new SortItem(new Identifier("y"), SortItem.Ordering.ASCENDING, SortItem.NullOrdering.UNDEFINED)), Optional.empty()));
    assertStatement("SHOW PARTITIONS FROM t WHERE x = 1 ORDER BY y LIMIT 10", new ShowPartitions(QualifiedName.of("t"), Optional.of(new ComparisonExpression(ComparisonExpressionType.EQUAL, new Identifier("x"), new LongLiteral("1"))), ImmutableList.of(new SortItem(new Identifier("y"), SortItem.Ordering.ASCENDING, SortItem.NullOrdering.UNDEFINED)), Optional.of("10")));
    assertStatement("SHOW PARTITIONS FROM t WHERE x = 1 ORDER BY y LIMIT ALL", new ShowPartitions(QualifiedName.of("t"), Optional.of(new ComparisonExpression(ComparisonExpressionType.EQUAL, new Identifier("x"), new LongLiteral("1"))), ImmutableList.of(new SortItem(new Identifier("y"), SortItem.Ordering.ASCENDING, SortItem.NullOrdering.UNDEFINED)), Optional.of("ALL")));
}
Also used : QuantifiedComparisonExpression(com.facebook.presto.sql.tree.QuantifiedComparisonExpression) ComparisonExpression(com.facebook.presto.sql.tree.ComparisonExpression) SortItem(com.facebook.presto.sql.tree.SortItem) Identifier(com.facebook.presto.sql.tree.Identifier) ShowPartitions(com.facebook.presto.sql.tree.ShowPartitions) LongLiteral(com.facebook.presto.sql.tree.LongLiteral) Test(org.testng.annotations.Test)

Example 4 with SortItem

use of com.facebook.presto.sql.tree.SortItem in project presto by prestodb.

the class TreePrinter method print.

public void print(Node root) {
    AstVisitor<Void, Integer> printer = new DefaultTraversalVisitor<Void, 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 : ((SimpleGroupBy) groupingElement).getColumnExpressions()) {
                            process(column, indentLevel + 1);
                        }
                    } else if (groupingElement instanceof GroupingSets) {
                        print(indentLevel + 1, "GroupingSets");
                        for (Set<Expression> column : groupingElement.enumerateGroupingSets()) {
                            print(indentLevel + 2, "GroupingSet[");
                            for (Expression expression : column) {
                                process(expression, indentLevel + 3);
                            }
                            print(indentLevel + 2, "]");
                        }
                    } else if (groupingElement instanceof Cube) {
                        print(indentLevel + 1, "Cube");
                        for (QualifiedName column : ((Cube) groupingElement).getColumns()) {
                            print(indentLevel + 1, column.toString());
                        }
                    } else if (groupingElement instanceof Rollup) {
                        print(indentLevel + 1, "Rollup");
                        for (QualifiedName column : ((Rollup) groupingElement).getColumns()) {
                            print(indentLevel + 1, column.toString());
                        }
                    }
                }
            }
            if (node.getHaving().isPresent()) {
                print(indentLevel, "Having");
                process(node.getHaving().get(), 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;
        }

        protected Void visitOrderBy(OrderBy node, Integer indentLevel) {
            for (SortItem sortItem : node.getSortItems()) {
                process(sortItem, indentLevel);
            }
            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) {
            if (node.getPrefix().isPresent()) {
                print(indent, node.getPrefix() + ".*");
            } else {
                print(indent, "*");
            }
            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.getType().toString());
            super.visitComparisonExpression(node, indentLevel + 1);
            return null;
        }

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

        @Override
        protected Void visitLogicalBinaryExpression(LogicalBinaryExpression node, Integer indentLevel) {
            print(indentLevel, node.getType().toString());
            super.visitLogicalBinaryExpression(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.getName() + 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(com.facebook.presto.sql.tree.ArithmeticBinaryExpression) LogicalBinaryExpression(com.facebook.presto.sql.tree.LogicalBinaryExpression) SimpleGroupBy(com.facebook.presto.sql.tree.SimpleGroupBy) Set(java.util.Set) Query(com.facebook.presto.sql.tree.Query) Rollup(com.facebook.presto.sql.tree.Rollup) BooleanLiteral(com.facebook.presto.sql.tree.BooleanLiteral) Node(com.facebook.presto.sql.tree.Node) Values(com.facebook.presto.sql.tree.Values) AllColumns(com.facebook.presto.sql.tree.AllColumns) SubqueryExpression(com.facebook.presto.sql.tree.SubqueryExpression) QuerySpecification(com.facebook.presto.sql.tree.QuerySpecification) SortItem(com.facebook.presto.sql.tree.SortItem) Identifier(com.facebook.presto.sql.tree.Identifier) FunctionCall(com.facebook.presto.sql.tree.FunctionCall) SampledRelation(com.facebook.presto.sql.tree.SampledRelation) GroupingSets(com.facebook.presto.sql.tree.GroupingSets) OrderBy(com.facebook.presto.sql.tree.OrderBy) DereferenceExpression(com.facebook.presto.sql.tree.DereferenceExpression) Table(com.facebook.presto.sql.tree.Table) LongLiteral(com.facebook.presto.sql.tree.LongLiteral) QualifiedName(com.facebook.presto.sql.tree.QualifiedName) DefaultTraversalVisitor(com.facebook.presto.sql.tree.DefaultTraversalVisitor) SingleColumn(com.facebook.presto.sql.tree.SingleColumn) LikePredicate(com.facebook.presto.sql.tree.LikePredicate) TableSubquery(com.facebook.presto.sql.tree.TableSubquery) InPredicate(com.facebook.presto.sql.tree.InPredicate) GroupingElement(com.facebook.presto.sql.tree.GroupingElement) ComparisonExpression(com.facebook.presto.sql.tree.ComparisonExpression) BinaryLiteral(com.facebook.presto.sql.tree.BinaryLiteral) StringLiteral(com.facebook.presto.sql.tree.StringLiteral) SubqueryExpression(com.facebook.presto.sql.tree.SubqueryExpression) DereferenceExpression(com.facebook.presto.sql.tree.DereferenceExpression) ComparisonExpression(com.facebook.presto.sql.tree.ComparisonExpression) LogicalBinaryExpression(com.facebook.presto.sql.tree.LogicalBinaryExpression) Expression(com.facebook.presto.sql.tree.Expression) ArithmeticBinaryExpression(com.facebook.presto.sql.tree.ArithmeticBinaryExpression) Cube(com.facebook.presto.sql.tree.Cube) Select(com.facebook.presto.sql.tree.Select) Row(com.facebook.presto.sql.tree.Row) AliasedRelation(com.facebook.presto.sql.tree.AliasedRelation)

Aggregations

SortItem (com.facebook.presto.sql.tree.SortItem)4 Expression (com.facebook.presto.sql.tree.Expression)3 SortOrder (com.facebook.presto.spi.block.SortOrder)2 ComparisonExpression (com.facebook.presto.sql.tree.ComparisonExpression)2 FunctionCall (com.facebook.presto.sql.tree.FunctionCall)2 Identifier (com.facebook.presto.sql.tree.Identifier)2 LongLiteral (com.facebook.presto.sql.tree.LongLiteral)2 IdentityLinkedHashMap (com.facebook.presto.util.maps.IdentityLinkedHashMap)2 ImmutableList (com.google.common.collect.ImmutableList)2 LinkedHashMap (java.util.LinkedHashMap)2 PlanNode (com.facebook.presto.sql.planner.plan.PlanNode)1 SortNode (com.facebook.presto.sql.planner.plan.SortNode)1 TopNNode (com.facebook.presto.sql.planner.plan.TopNNode)1 WindowNode (com.facebook.presto.sql.planner.plan.WindowNode)1 AliasedRelation (com.facebook.presto.sql.tree.AliasedRelation)1 AllColumns (com.facebook.presto.sql.tree.AllColumns)1 ArithmeticBinaryExpression (com.facebook.presto.sql.tree.ArithmeticBinaryExpression)1 BinaryLiteral (com.facebook.presto.sql.tree.BinaryLiteral)1 BooleanLiteral (com.facebook.presto.sql.tree.BooleanLiteral)1 Cast (com.facebook.presto.sql.tree.Cast)1