Search in sources :

Example 1 with WindowFrameType

use of io.prestosql.spi.sql.expression.Types.WindowFrameType in project hetu-core by openlookeng.

the class QueryPlanner method window.

private PlanBuilder window(PlanBuilder inputSubPlan, List<FunctionCall> windowFunctions) {
    PlanBuilder subPlan = inputSubPlan;
    if (windowFunctions.isEmpty()) {
        return subPlan;
    }
    for (FunctionCall windowFunction : windowFunctions) {
        Window window = windowFunction.getWindow().get();
        // Extract frame
        WindowFrameType frameType = RANGE;
        FrameBoundType frameStartType = UNBOUNDED_PRECEDING;
        FrameBoundType frameEndType = 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(), planSymbolAllocator, 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
        LinkedHashMap<Symbol, SortOrder> orderings = new LinkedHashMap<>();
        for (SortItem item : getSortItemsFromOrderBy(window.getOrderBy())) {
            Symbol symbol = subPlan.translate(item.getSortKey());
            // don't override existing keys, i.e. when "ORDER BY a ASC, a DESC" is specified
            orderings.putIfAbsent(symbol, sortItemToSortOrder(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, 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 symbol, don't create another PlanNode
        if (rewritten instanceof SymbolReference) {
            if (needCoercion) {
                subPlan = explicitCoercionSymbols(subPlan, subPlan.getRoot().getOutputSymbols(), ImmutableList.of(windowFunction));
            }
            continue;
        }
        Type returnType = analysis.getType(windowFunction);
        Symbol newSymbol = planSymbolAllocator.newSymbol(rewritten, analysis.getType(windowFunction));
        outputTranslations.put(windowFunction, newSymbol);
        List<RowExpression> arguments = new ArrayList<>();
        for (int i = 0; i < ((FunctionCall) rewritten).getArguments().size(); i++) {
            arguments.add(castToRowExpression(((FunctionCall) rewritten).getArguments().get(i)));
        }
        WindowNode.Function function = new WindowNode.Function(call(windowFunction.getName().toString(), analysis.getFunctionHandle(windowFunction), returnType, ((FunctionCall) rewritten).getArguments().stream().map(OriginalExpressionUtils::castToRowExpression).collect(toImmutableList())), arguments, frame);
        List<Symbol> sourceSymbols = subPlan.getRoot().getOutputSymbols();
        ImmutableList.Builder<Symbol> orderBySymbols = ImmutableList.builder();
        orderBySymbols.addAll(orderings.keySet());
        Optional<OrderingScheme> orderingScheme = Optional.empty();
        if (!orderings.isEmpty()) {
            orderingScheme = Optional.of(new OrderingScheme(orderBySymbols.build(), orderings));
        }
        // create window node
        subPlan = new PlanBuilder(outputTranslations, new WindowNode(idAllocator.getNextId(), subPlan.getRoot(), new WindowNode.Specification(partitionBySymbols.build(), orderingScheme), ImmutableMap.of(newSymbol, function), Optional.empty(), ImmutableSet.of(), 0));
        if (needCoercion) {
            subPlan = explicitCoercionSymbols(subPlan, sourceSymbols, ImmutableList.of(windowFunction));
        }
    }
    return subPlan;
}
Also used : Cast(io.prestosql.sql.tree.Cast) WindowFrame(io.prestosql.sql.tree.WindowFrame) ImmutableList.toImmutableList(com.google.common.collect.ImmutableList.toImmutableList) ImmutableList(com.google.common.collect.ImmutableList) Symbol(io.prestosql.spi.plan.Symbol) SymbolUtils.toSymbolReference(io.prestosql.sql.planner.SymbolUtils.toSymbolReference) SymbolReference(io.prestosql.sql.tree.SymbolReference) ArrayList(java.util.ArrayList) FrameBoundType(io.prestosql.spi.sql.expression.Types.FrameBoundType) LinkedHashMap(java.util.LinkedHashMap) SortItem(io.prestosql.sql.tree.SortItem) WindowFrame(io.prestosql.sql.tree.WindowFrame) FunctionCall(io.prestosql.sql.tree.FunctionCall) Window(io.prestosql.sql.tree.Window) WindowFrameType(io.prestosql.spi.sql.expression.Types.WindowFrameType) WindowNode(io.prestosql.spi.plan.WindowNode) OrderingScheme(io.prestosql.spi.plan.OrderingScheme) SortOrder(io.prestosql.spi.block.SortOrder) OrderingSchemeUtils.sortItemToSortOrder(io.prestosql.sql.planner.OrderingSchemeUtils.sortItemToSortOrder) OriginalExpressionUtils.castToRowExpression(io.prestosql.sql.relational.OriginalExpressionUtils.castToRowExpression) RowExpression(io.prestosql.spi.relation.RowExpression) FrameBoundType(io.prestosql.spi.sql.expression.Types.FrameBoundType) Type(io.prestosql.spi.type.Type) WindowFrameType(io.prestosql.spi.sql.expression.Types.WindowFrameType) RelationType(io.prestosql.sql.analyzer.RelationType) OriginalExpressionUtils.castToRowExpression(io.prestosql.sql.relational.OriginalExpressionUtils.castToRowExpression) LambdaExpression(io.prestosql.sql.tree.LambdaExpression) Expression(io.prestosql.sql.tree.Expression) RowExpression(io.prestosql.spi.relation.RowExpression)

Aggregations

ImmutableList (com.google.common.collect.ImmutableList)1 ImmutableList.toImmutableList (com.google.common.collect.ImmutableList.toImmutableList)1 SortOrder (io.prestosql.spi.block.SortOrder)1 OrderingScheme (io.prestosql.spi.plan.OrderingScheme)1 Symbol (io.prestosql.spi.plan.Symbol)1 WindowNode (io.prestosql.spi.plan.WindowNode)1 RowExpression (io.prestosql.spi.relation.RowExpression)1 FrameBoundType (io.prestosql.spi.sql.expression.Types.FrameBoundType)1 WindowFrameType (io.prestosql.spi.sql.expression.Types.WindowFrameType)1 Type (io.prestosql.spi.type.Type)1 RelationType (io.prestosql.sql.analyzer.RelationType)1 OrderingSchemeUtils.sortItemToSortOrder (io.prestosql.sql.planner.OrderingSchemeUtils.sortItemToSortOrder)1 SymbolUtils.toSymbolReference (io.prestosql.sql.planner.SymbolUtils.toSymbolReference)1 OriginalExpressionUtils.castToRowExpression (io.prestosql.sql.relational.OriginalExpressionUtils.castToRowExpression)1 Cast (io.prestosql.sql.tree.Cast)1 Expression (io.prestosql.sql.tree.Expression)1 FunctionCall (io.prestosql.sql.tree.FunctionCall)1 LambdaExpression (io.prestosql.sql.tree.LambdaExpression)1 SortItem (io.prestosql.sql.tree.SortItem)1 SymbolReference (io.prestosql.sql.tree.SymbolReference)1