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 java.util.Collections; | |
10 | import java.util.Iterator; | |
11 | import java.util.List; | |
12 | import lombok.EqualsAndHashCode; | |
13 | import lombok.Getter; | |
14 | import lombok.ToString; | |
15 | import org.opensearch.sql.data.model.ExprValue; | |
16 | import org.opensearch.sql.expression.Expression; | |
17 | import org.opensearch.sql.expression.NamedExpression; | |
18 | import org.opensearch.sql.expression.aggregation.Aggregator; | |
19 | import org.opensearch.sql.expression.aggregation.NamedAggregator; | |
20 | import org.opensearch.sql.expression.span.SpanExpression; | |
21 | import org.opensearch.sql.planner.physical.collector.Collector; | |
22 | import org.opensearch.sql.storage.bindingtuple.BindingTuple; | |
23 | ||
24 | /** | |
25 | * Group the all the input {@link BindingTuple} by {@link AggregationOperator#groupByExprList}, | |
26 | * calculate the aggregation result by using {@link AggregationOperator#aggregatorList}. | |
27 | */ | |
28 | @EqualsAndHashCode(callSuper = false) | |
29 | @ToString | |
30 | public class AggregationOperator extends PhysicalPlan { | |
31 | @Getter | |
32 | private final PhysicalPlan input; | |
33 | @Getter | |
34 | private final List<NamedAggregator> aggregatorList; | |
35 | @Getter | |
36 | private final List<NamedExpression> groupByExprList; | |
37 | @Getter | |
38 | private final NamedExpression span; | |
39 | /** | |
40 | * {@link BindingTuple} Collector. | |
41 | */ | |
42 | @EqualsAndHashCode.Exclude | |
43 | private final Collector collector; | |
44 | @EqualsAndHashCode.Exclude | |
45 | private Iterator<ExprValue> iterator; | |
46 | ||
47 | /** | |
48 | * AggregationOperator Constructor. | |
49 | * | |
50 | * @param input Input {@link PhysicalPlan} | |
51 | * @param aggregatorList List of {@link Aggregator} | |
52 | * @param groupByExprList List of group by {@link Expression} | |
53 | */ | |
54 | public AggregationOperator(PhysicalPlan input, List<NamedAggregator> aggregatorList, | |
55 | List<NamedExpression> groupByExprList) { | |
56 | this.input = input; | |
57 | this.aggregatorList = aggregatorList; | |
58 | this.groupByExprList = groupByExprList; | |
59 |
1
1. <init> : negated conditional → KILLED |
if (hasSpan(groupByExprList)) { |
60 | // span expression is always the first expression in group list if exist. | |
61 | this.span = groupByExprList.get(0); | |
62 | this.collector = | |
63 | Collector.Builder.build( | |
64 | this.span, groupByExprList.subList(1, groupByExprList.size()), this.aggregatorList); | |
65 | ||
66 | } else { | |
67 | this.span = null; | |
68 | this.collector = | |
69 | Collector.Builder.build(this.span, this.groupByExprList, this.aggregatorList); | |
70 | } | |
71 | } | |
72 | ||
73 | @Override | |
74 | public <R, C> R accept(PhysicalPlanNodeVisitor<R, C> visitor, C context) { | |
75 |
1
1. accept : replaced return value with null for org/opensearch/sql/planner/physical/AggregationOperator::accept → KILLED |
return visitor.visitAggregation(this, context); |
76 | } | |
77 | ||
78 | @Override | |
79 | public List<PhysicalPlan> getChild() { | |
80 |
1
1. getChild : replaced return value with Collections.emptyList for org/opensearch/sql/planner/physical/AggregationOperator::getChild → KILLED |
return Collections.singletonList(input); |
81 | } | |
82 | ||
83 | ||
84 | @Override | |
85 | public boolean hasNext() { | |
86 |
2
1. hasNext : replaced boolean return with false for org/opensearch/sql/planner/physical/AggregationOperator::hasNext → KILLED 2. hasNext : replaced boolean return with true for org/opensearch/sql/planner/physical/AggregationOperator::hasNext → KILLED |
return iterator.hasNext(); |
87 | } | |
88 | ||
89 | @Override | |
90 | public ExprValue next() { | |
91 |
1
1. next : replaced return value with null for org/opensearch/sql/planner/physical/AggregationOperator::next → KILLED |
return iterator.next(); |
92 | } | |
93 | ||
94 | @Override | |
95 | public void open() { | |
96 |
1
1. open : removed call to org/opensearch/sql/planner/physical/PhysicalPlan::open → SURVIVED |
super.open(); |
97 |
1
1. open : negated conditional → KILLED |
while (input.hasNext()) { |
98 |
1
1. open : removed call to org/opensearch/sql/planner/physical/collector/Collector::collect → KILLED |
collector.collect(input.next().bindingTuples()); |
99 | } | |
100 | iterator = collector.results().iterator(); | |
101 | } | |
102 | ||
103 | private boolean hasSpan(List<NamedExpression> namedExpressionList) { | |
104 |
2
1. hasSpan : negated conditional → KILLED 2. hasSpan : replaced boolean return with true for org/opensearch/sql/planner/physical/AggregationOperator::hasSpan → KILLED |
return !namedExpressionList.isEmpty() |
105 |
1
1. hasSpan : negated conditional → KILLED |
&& namedExpressionList.get(0).getDelegated() instanceof SpanExpression; |
106 | } | |
107 | } | |
Mutations | ||
59 |
1.1 |
|
75 |
1.1 |
|
80 |
1.1 |
|
86 |
1.1 2.2 |
|
91 |
1.1 |
|
96 |
1.1 |
|
97 |
1.1 |
|
98 |
1.1 |
|
104 |
1.1 2.2 |
|
105 |
1.1 |