1 | /* | |
2 | * Copyright OpenSearch Contributors | |
3 | * SPDX-License-Identifier: Apache-2.0 | |
4 | */ | |
5 | ||
6 | ||
7 | package org.opensearch.sql.planner.physical; | |
8 | ||
9 | import com.google.common.collect.ImmutableMap; | |
10 | import com.google.common.collect.Iterators; | |
11 | import com.google.common.collect.PeekingIterator; | |
12 | import java.util.Collections; | |
13 | import java.util.List; | |
14 | import lombok.EqualsAndHashCode; | |
15 | import lombok.Getter; | |
16 | import lombok.ToString; | |
17 | import org.opensearch.sql.data.model.ExprTupleValue; | |
18 | import org.opensearch.sql.data.model.ExprValue; | |
19 | import org.opensearch.sql.expression.NamedExpression; | |
20 | import org.opensearch.sql.expression.window.WindowDefinition; | |
21 | import org.opensearch.sql.expression.window.WindowFunctionExpression; | |
22 | import org.opensearch.sql.expression.window.frame.WindowFrame; | |
23 | ||
24 | /** | |
25 | * Physical operator for window function computation. | |
26 | */ | |
27 | @EqualsAndHashCode(callSuper = false) | |
28 | @ToString | |
29 | public class WindowOperator extends PhysicalPlan { | |
30 | @Getter | |
31 | private final PhysicalPlan input; | |
32 | ||
33 | @Getter | |
34 | private final NamedExpression windowFunction; | |
35 | ||
36 | @Getter | |
37 | private final WindowDefinition windowDefinition; | |
38 | ||
39 | @EqualsAndHashCode.Exclude | |
40 | @ToString.Exclude | |
41 | private final WindowFrame windowFrame; | |
42 | ||
43 | /** | |
44 | * Peeking iterator that can peek next element which is required | |
45 | * by window frame such as peer frame to prefetch all rows related | |
46 | * to same peer (of same sorting key). | |
47 | */ | |
48 | @EqualsAndHashCode.Exclude | |
49 | @ToString.Exclude | |
50 | private final PeekingIterator<ExprValue> peekingIterator; | |
51 | ||
52 | /** | |
53 | * Initialize window operator. | |
54 | * @param input child operator | |
55 | * @param windowFunction window function | |
56 | * @param windowDefinition window definition | |
57 | */ | |
58 | public WindowOperator(PhysicalPlan input, | |
59 | NamedExpression windowFunction, | |
60 | WindowDefinition windowDefinition) { | |
61 | this.input = input; | |
62 | this.windowFunction = windowFunction; | |
63 | this.windowDefinition = windowDefinition; | |
64 | this.windowFrame = createWindowFrame(); | |
65 | this.peekingIterator = Iterators.peekingIterator(input); | |
66 | } | |
67 | ||
68 | @Override | |
69 | public <R, C> R accept(PhysicalPlanNodeVisitor<R, C> visitor, C context) { | |
70 |
1
1. accept : replaced return value with null for org/opensearch/sql/planner/physical/WindowOperator::accept → KILLED |
return visitor.visitWindow(this, context); |
71 | } | |
72 | ||
73 | @Override | |
74 | public List<PhysicalPlan> getChild() { | |
75 |
1
1. getChild : replaced return value with Collections.emptyList for org/opensearch/sql/planner/physical/WindowOperator::getChild → KILLED |
return Collections.singletonList(input); |
76 | } | |
77 | ||
78 | @Override | |
79 | public boolean hasNext() { | |
80 |
3
1. hasNext : negated conditional → KILLED 2. hasNext : negated conditional → KILLED 3. hasNext : replaced boolean return with true for org/opensearch/sql/planner/physical/WindowOperator::hasNext → KILLED |
return peekingIterator.hasNext() || windowFrame.hasNext(); |
81 | } | |
82 | ||
83 | @Override | |
84 | public ExprValue next() { | |
85 |
1
1. next : removed call to org/opensearch/sql/expression/window/frame/WindowFrame::load → KILLED |
windowFrame.load(peekingIterator); |
86 |
1
1. next : replaced return value with null for org/opensearch/sql/planner/physical/WindowOperator::next → KILLED |
return enrichCurrentRowByWindowFunctionResult(); |
87 | } | |
88 | ||
89 | private WindowFrame createWindowFrame() { | |
90 |
1
1. createWindowFrame : replaced return value with null for org/opensearch/sql/planner/physical/WindowOperator::createWindowFrame → KILLED |
return ((WindowFunctionExpression) windowFunction.getDelegated()) |
91 | .createWindowFrame(windowDefinition); | |
92 | } | |
93 | ||
94 | private ExprValue enrichCurrentRowByWindowFunctionResult() { | |
95 | ImmutableMap.Builder<String, ExprValue> mapBuilder = new ImmutableMap.Builder<>(); | |
96 |
1
1. enrichCurrentRowByWindowFunctionResult : removed call to org/opensearch/sql/planner/physical/WindowOperator::preserveAllOriginalColumns → KILLED |
preserveAllOriginalColumns(mapBuilder); |
97 |
1
1. enrichCurrentRowByWindowFunctionResult : removed call to org/opensearch/sql/planner/physical/WindowOperator::addWindowFunctionResultColumn → KILLED |
addWindowFunctionResultColumn(mapBuilder); |
98 |
1
1. enrichCurrentRowByWindowFunctionResult : replaced return value with null for org/opensearch/sql/planner/physical/WindowOperator::enrichCurrentRowByWindowFunctionResult → KILLED |
return ExprTupleValue.fromExprValueMap(mapBuilder.build()); |
99 | } | |
100 | ||
101 | private void preserveAllOriginalColumns(ImmutableMap.Builder<String, ExprValue> mapBuilder) { | |
102 | ExprValue inputValue = windowFrame.current(); | |
103 |
1
1. preserveAllOriginalColumns : removed call to java/util/Map::forEach → KILLED |
inputValue.tupleValue().forEach(mapBuilder::put); |
104 | } | |
105 | ||
106 | private void addWindowFunctionResultColumn(ImmutableMap.Builder<String, ExprValue> mapBuilder) { | |
107 | ExprValue exprValue = windowFunction.valueOf(windowFrame); | |
108 | mapBuilder.put(windowFunction.getName(), exprValue); | |
109 | } | |
110 | ||
111 | } | |
Mutations | ||
70 |
1.1 |
|
75 |
1.1 |
|
80 |
1.1 2.2 3.3 |
|
85 |
1.1 |
|
86 |
1.1 |
|
90 |
1.1 |
|
96 |
1.1 |
|
97 |
1.1 |
|
98 |
1.1 |
|
103 |
1.1 |