Aggregator.java

1
/*
2
 * Copyright OpenSearch Contributors
3
 * SPDX-License-Identifier: Apache-2.0
4
 */
5
6
7
package org.opensearch.sql.expression.aggregation;
8
9
import java.util.List;
10
import lombok.EqualsAndHashCode;
11
import lombok.Getter;
12
import lombok.RequiredArgsConstructor;
13
import lombok.Setter;
14
import lombok.experimental.Accessors;
15
import org.opensearch.sql.analysis.ExpressionAnalyzer;
16
import org.opensearch.sql.data.model.ExprValue;
17
import org.opensearch.sql.data.model.ExprValueUtils;
18
import org.opensearch.sql.data.type.ExprCoreType;
19
import org.opensearch.sql.data.type.ExprType;
20
import org.opensearch.sql.exception.ExpressionEvaluationException;
21
import org.opensearch.sql.expression.Expression;
22
import org.opensearch.sql.expression.ExpressionNodeVisitor;
23
import org.opensearch.sql.expression.env.Environment;
24
import org.opensearch.sql.expression.function.FunctionImplementation;
25
import org.opensearch.sql.expression.function.FunctionName;
26
import org.opensearch.sql.storage.bindingtuple.BindingTuple;
27
28
/**
29
 * Aggregator which will iterate on the {@link BindingTuple}s to aggregate the result.
30
 * The Aggregator is not well fit into Expression, because it has side effect.
31
 * But we still want to make it implement {@link Expression} interface to make
32
 * {@link ExpressionAnalyzer} easier.
33
 */
34
@EqualsAndHashCode
35
@RequiredArgsConstructor
36
public abstract class Aggregator<S extends AggregationState>
37
    implements FunctionImplementation, Expression {
38
  @Getter
39
  private final FunctionName functionName;
40
  @Getter
41
  private final List<Expression> arguments;
42
  protected final ExprCoreType returnType;
43
  @Setter
44
  @Getter
45
  @Accessors(fluent = true)
46
  protected Expression condition;
47
  @Setter
48
  @Getter
49
  @Accessors(fluent = true)
50
  protected Boolean distinct = false;
51
52
  /**
53
   * Create an {@link AggregationState} which will be used for aggregation.
54
   */
55
  public abstract S create();
56
57
  /**
58
   * Iterate on {@link ExprValue}.
59
   * @param value {@link ExprValue}
60
   * @param state {@link AggregationState}
61
   * @return {@link AggregationState}
62
   */
63
  protected abstract S iterate(ExprValue value, S state);
64
65
  /**
66
   * Let the aggregator iterate on the {@link BindingTuple}
67
   * To filter out ExprValues that are missing, null or cannot satisfy {@link #condition}
68
   * Before the specific aggregator iterating ExprValue in the tuple.
69
   *
70
   * @param tuple {@link BindingTuple}
71
   * @param state {@link AggregationState}
72
   * @return {@link AggregationState}
73
   */
74
  public S iterate(BindingTuple tuple, S state) {
75
    ExprValue value = getArguments().get(0).valueOf(tuple);
76 3 1. iterate : negated conditional → KILLED
2. iterate : negated conditional → KILLED
3. iterate : negated conditional → KILLED
    if (value.isNull() || value.isMissing() || !conditionValue(tuple)) {
77 1 1. iterate : replaced return value with null for org/opensearch/sql/expression/aggregation/Aggregator::iterate → SURVIVED
      return state;
78
    }
79 1 1. iterate : replaced return value with null for org/opensearch/sql/expression/aggregation/Aggregator::iterate → KILLED
    return iterate(value, state);
80
  }
81
82
  @Override
83
  public ExprValue valueOf(Environment<Expression, ExprValue> valueEnv) {
84
    throw new ExpressionEvaluationException(
85
        String.format("can't evaluate on aggregator: %s", functionName));
86
  }
87
88
  @Override
89
  public ExprType type() {
90 1 1. type : replaced return value with null for org/opensearch/sql/expression/aggregation/Aggregator::type → KILLED
    return returnType;
91
  }
92
93
  @Override
94
  public <T, C> T accept(ExpressionNodeVisitor<T, C> visitor, C context) {
95 1 1. accept : replaced return value with null for org/opensearch/sql/expression/aggregation/Aggregator::accept → KILLED
    return visitor.visitAggregator(this, context);
96
  }
97
98
  /**
99
   * Util method to get value of condition in aggregation filter.
100
   */
101
  public boolean conditionValue(BindingTuple tuple) {
102 1 1. conditionValue : negated conditional → KILLED
    if (condition == null) {
103 1 1. conditionValue : replaced boolean return with false for org/opensearch/sql/expression/aggregation/Aggregator::conditionValue → KILLED
      return true;
104
    }
105 2 1. conditionValue : replaced boolean return with false for org/opensearch/sql/expression/aggregation/Aggregator::conditionValue → KILLED
2. conditionValue : replaced boolean return with true for org/opensearch/sql/expression/aggregation/Aggregator::conditionValue → KILLED
    return ExprValueUtils.getBooleanValue(condition.valueOf(tuple));
106
  }
107
108
}

Mutations

76

1.1
Location : iterate
Killed by : org.opensearch.sql.expression.aggregation.SumAggregatorTest.[engine:junit-jupiter]/[class:org.opensearch.sql.expression.aggregation.SumAggregatorTest]/[method:sum_string_field_expression()]
negated conditional → KILLED

2.2
Location : iterate
Killed by : org.opensearch.sql.expression.aggregation.SumAggregatorTest.[engine:junit-jupiter]/[class:org.opensearch.sql.expression.aggregation.SumAggregatorTest]/[method:sum_string_field_expression()]
negated conditional → KILLED

3.3
Location : iterate
Killed by : org.opensearch.sql.expression.aggregation.SumAggregatorTest.[engine:junit-jupiter]/[class:org.opensearch.sql.expression.aggregation.SumAggregatorTest]/[method:sum_string_field_expression()]
negated conditional → KILLED

77

1.1
Location : iterate
Killed by : none
replaced return value with null for org/opensearch/sql/expression/aggregation/Aggregator::iterate → SURVIVED

79

1.1
Location : iterate
Killed by : org.opensearch.sql.expression.window.aggregation.AggregateWindowFunctionTest.[engine:junit-jupiter]/[class:org.opensearch.sql.expression.window.aggregation.AggregateWindowFunctionTest]/[method:should_accumulate_all_peer_values_and_not_reset_state_if_same_partition()]
replaced return value with null for org/opensearch/sql/expression/aggregation/Aggregator::iterate → KILLED

90

1.1
Location : type
Killed by : org.opensearch.sql.analysis.ExpressionReferenceOptimizerTest.[engine:junit-jupiter]/[class:org.opensearch.sql.analysis.ExpressionReferenceOptimizerTest]/[method:aggregation_expression_should_be_replaced()]
replaced return value with null for org/opensearch/sql/expression/aggregation/Aggregator::type → KILLED

95

1.1
Location : accept
Killed by : org.opensearch.sql.analysis.ExpressionReferenceOptimizerTest.[engine:junit-jupiter]/[class:org.opensearch.sql.analysis.ExpressionReferenceOptimizerTest]/[method:aggregation_expression_should_be_replaced()]
replaced return value with null for org/opensearch/sql/expression/aggregation/Aggregator::accept → KILLED

102

1.1
Location : conditionValue
Killed by : org.opensearch.sql.expression.aggregation.SumAggregatorTest.[engine:junit-jupiter]/[class:org.opensearch.sql.expression.aggregation.SumAggregatorTest]/[method:sum_string_field_expression()]
negated conditional → KILLED

103

1.1
Location : conditionValue
Killed by : org.opensearch.sql.expression.aggregation.SumAggregatorTest.[engine:junit-jupiter]/[class:org.opensearch.sql.expression.aggregation.SumAggregatorTest]/[method:sum_string_field_expression()]
replaced boolean return with false for org/opensearch/sql/expression/aggregation/Aggregator::conditionValue → KILLED

105

1.1
Location : conditionValue
Killed by : org.opensearch.sql.expression.aggregation.MaxAggregatorTest.[engine:junit-jupiter]/[class:org.opensearch.sql.expression.aggregation.MaxAggregatorTest]/[method:filtered_max()]
replaced boolean return with false for org/opensearch/sql/expression/aggregation/Aggregator::conditionValue → KILLED

2.2
Location : conditionValue
Killed by : org.opensearch.sql.expression.aggregation.MaxAggregatorTest.[engine:junit-jupiter]/[class:org.opensearch.sql.expression.aggregation.MaxAggregatorTest]/[method:filtered_max()]
replaced boolean return with true for org/opensearch/sql/expression/aggregation/Aggregator::conditionValue → KILLED

Active mutators

Tests examined


Report generated by PIT 1.9.0