ProjectOperator.java

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.ImmutableMap.Builder;
11
import java.util.Collections;
12
import java.util.List;
13
import java.util.Optional;
14
import java.util.stream.Collectors;
15
import lombok.EqualsAndHashCode;
16
import lombok.Getter;
17
import lombok.RequiredArgsConstructor;
18
import lombok.ToString;
19
import org.opensearch.sql.data.model.ExprTupleValue;
20
import org.opensearch.sql.data.model.ExprValue;
21
import org.opensearch.sql.data.model.ExprValueUtils;
22
import org.opensearch.sql.executor.ExecutionEngine;
23
import org.opensearch.sql.expression.NamedExpression;
24
import org.opensearch.sql.expression.parse.ParseExpression;
25
26
/**
27
 * Project the fields specified in {@link ProjectOperator#projectList} from input.
28
 */
29
@ToString
30
@EqualsAndHashCode(callSuper = false)
31
@RequiredArgsConstructor
32
public class ProjectOperator extends PhysicalPlan {
33
  @Getter
34
  private final PhysicalPlan input;
35
  @Getter
36
  private final List<NamedExpression> projectList;
37
  @Getter
38
  private final List<NamedExpression> namedParseExpressions;
39
40
  @Override
41
  public <R, C> R accept(PhysicalPlanNodeVisitor<R, C> visitor, C context) {
42 1 1. accept : replaced return value with null for org/opensearch/sql/planner/physical/ProjectOperator::accept → KILLED
    return visitor.visitProject(this, context);
43
  }
44
45
  @Override
46
  public List<PhysicalPlan> getChild() {
47 1 1. getChild : replaced return value with Collections.emptyList for org/opensearch/sql/planner/physical/ProjectOperator::getChild → KILLED
    return Collections.singletonList(input);
48
  }
49
50
  @Override
51
  public boolean hasNext() {
52 2 1. hasNext : replaced boolean return with true for org/opensearch/sql/planner/physical/ProjectOperator::hasNext → TIMED_OUT
2. hasNext : replaced boolean return with false for org/opensearch/sql/planner/physical/ProjectOperator::hasNext → KILLED
    return input.hasNext();
53
  }
54
55
  @Override
56
  public ExprValue next() {
57
    ExprValue inputValue = input.next();
58
    ImmutableMap.Builder<String, ExprValue> mapBuilder = new Builder<>();
59
60
    // ParseExpression will always override NamedExpression when identifier conflicts
61
    // TODO needs a better implementation, see https://github.com/opensearch-project/sql/issues/458
62
    for (NamedExpression expr : projectList) {
63
      ExprValue exprValue = expr.valueOf(inputValue.bindingTuples());
64
      Optional<NamedExpression> optionalParseExpression = namedParseExpressions.stream()
65 2 1. lambda$next$0 : replaced boolean return with false for org/opensearch/sql/planner/physical/ProjectOperator::lambda$next$0 → KILLED
2. lambda$next$0 : replaced boolean return with true for org/opensearch/sql/planner/physical/ProjectOperator::lambda$next$0 → KILLED
          .filter(parseExpr -> parseExpr.getNameOrAlias().equals(expr.getNameOrAlias()))
66
          .findFirst();
67 1 1. next : negated conditional → KILLED
      if (optionalParseExpression.isEmpty()) {
68
        mapBuilder.put(expr.getNameOrAlias(), exprValue);
69
        continue;
70
      }
71
72
      NamedExpression parseExpression = optionalParseExpression.get();
73
      ExprValue sourceFieldValue = inputValue.bindingTuples()
74
          .resolve(((ParseExpression) parseExpression.getDelegated()).getSourceField());
75 1 1. next : negated conditional → KILLED
      if (sourceFieldValue.isMissing()) {
76
        // source field will be missing after stats command, read from inputValue if it exists
77
        // otherwise do nothing since it should not appear as a field
78
        ExprValue tupleValue =
79
            ExprValueUtils.getTupleValue(inputValue).get(parseExpression.getNameOrAlias());
80 1 1. next : negated conditional → KILLED
        if (tupleValue != null) {
81
          mapBuilder.put(parseExpression.getNameOrAlias(), tupleValue);
82
        }
83
      } else {
84
        ExprValue parsedValue = parseExpression.valueOf(inputValue.bindingTuples());
85
        mapBuilder.put(parseExpression.getNameOrAlias(), parsedValue);
86
      }
87
    }
88 1 1. next : replaced return value with null for org/opensearch/sql/planner/physical/ProjectOperator::next → KILLED
    return ExprTupleValue.fromExprValueMap(mapBuilder.build());
89
  }
90
91
  @Override
92
  public ExecutionEngine.Schema schema() {
93 1 1. schema : replaced return value with null for org/opensearch/sql/planner/physical/ProjectOperator::schema → KILLED
    return new ExecutionEngine.Schema(getProjectList().stream()
94 1 1. lambda$schema$1 : replaced return value with null for org/opensearch/sql/planner/physical/ProjectOperator::lambda$schema$1 → KILLED
        .map(expr -> new ExecutionEngine.Schema.Column(expr.getName(),
95
            expr.getAlias(), expr.type())).collect(Collectors.toList()));
96
  }
97
}

Mutations

42

1.1
Location : accept
Killed by : org.opensearch.sql.executor.ExplainTest.[engine:junit-jupiter]/[class:org.opensearch.sql.executor.ExplainTest]/[method:can_explain_project_filter_table_scan()]
replaced return value with null for org/opensearch/sql/planner/physical/ProjectOperator::accept → KILLED

47

1.1
Location : getChild
Killed by : org.opensearch.sql.executor.ExplainTest.[engine:junit-jupiter]/[class:org.opensearch.sql.executor.ExplainTest]/[method:can_explain_project_filter_table_scan()]
replaced return value with Collections.emptyList for org/opensearch/sql/planner/physical/ProjectOperator::getChild → KILLED

52

1.1
Location : hasNext
Killed by : org.opensearch.sql.planner.physical.ProjectOperatorTest.[engine:junit-jupiter]/[class:org.opensearch.sql.planner.physical.ProjectOperatorTest]/[method:project_one_field()]
replaced boolean return with false for org/opensearch/sql/planner/physical/ProjectOperator::hasNext → KILLED

2.2
Location : hasNext
Killed by : none
replaced boolean return with true for org/opensearch/sql/planner/physical/ProjectOperator::hasNext → TIMED_OUT

65

1.1
Location : lambda$next$0
Killed by : org.opensearch.sql.planner.physical.ProjectOperatorTest.[engine:junit-jupiter]/[class:org.opensearch.sql.planner.physical.ProjectOperatorTest]/[method:project_fields_with_parse_expressions()]
replaced boolean return with false for org/opensearch/sql/planner/physical/ProjectOperator::lambda$next$0 → KILLED

2.2
Location : lambda$next$0
Killed by : org.opensearch.sql.planner.physical.ProjectOperatorTest.[engine:junit-jupiter]/[class:org.opensearch.sql.planner.physical.ProjectOperatorTest]/[method:project_fields_with_unused_parse_expressions()]
replaced boolean return with true for org/opensearch/sql/planner/physical/ProjectOperator::lambda$next$0 → KILLED

67

1.1
Location : next
Killed by : org.opensearch.sql.planner.physical.ProjectOperatorTest.[engine:junit-jupiter]/[class:org.opensearch.sql.planner.physical.ProjectOperatorTest]/[method:project_one_field()]
negated conditional → KILLED

75

1.1
Location : next
Killed by : org.opensearch.sql.planner.physical.ProjectOperatorTest.[engine:junit-jupiter]/[class:org.opensearch.sql.planner.physical.ProjectOperatorTest]/[method:project_fields_with_parse_expressions()]
negated conditional → KILLED

80

1.1
Location : next
Killed by : org.opensearch.sql.planner.physical.ProjectOperatorTest.[engine:junit-jupiter]/[class:org.opensearch.sql.planner.physical.ProjectOperatorTest]/[method:project_parse_missing_will_fallback()]
negated conditional → KILLED

88

1.1
Location : next
Killed by : org.opensearch.sql.planner.physical.ProjectOperatorTest.[engine:junit-jupiter]/[class:org.opensearch.sql.planner.physical.ProjectOperatorTest]/[method:project_one_field()]
replaced return value with null for org/opensearch/sql/planner/physical/ProjectOperator::next → KILLED

93

1.1
Location : schema
Killed by : org.opensearch.sql.planner.physical.ProjectOperatorTest.[engine:junit-jupiter]/[class:org.opensearch.sql.planner.physical.ProjectOperatorTest]/[method:project_schema()]
replaced return value with null for org/opensearch/sql/planner/physical/ProjectOperator::schema → KILLED

94

1.1
Location : lambda$schema$1
Killed by : org.opensearch.sql.planner.physical.ProjectOperatorTest.[engine:junit-jupiter]/[class:org.opensearch.sql.planner.physical.ProjectOperatorTest]/[method:project_schema()]
replaced return value with null for org/opensearch/sql/planner/physical/ProjectOperator::lambda$schema$1 → KILLED

Active mutators

Tests examined


Report generated by PIT 1.9.0