ReferenceExpression.java

1
/*
2
 * Copyright OpenSearch Contributors
3
 * SPDX-License-Identifier: Apache-2.0
4
 */
5
6
7
package org.opensearch.sql.expression;
8
9
import static org.opensearch.sql.utils.ExpressionUtils.PATH_SEP;
10
11
import java.util.Arrays;
12
import java.util.List;
13
import lombok.EqualsAndHashCode;
14
import lombok.Getter;
15
import lombok.RequiredArgsConstructor;
16
import org.opensearch.sql.data.model.ExprTupleValue;
17
import org.opensearch.sql.data.model.ExprValue;
18
import org.opensearch.sql.data.type.ExprType;
19
import org.opensearch.sql.expression.env.Environment;
20
21
@EqualsAndHashCode
22
@RequiredArgsConstructor
23
public class ReferenceExpression implements Expression {
24
  @Getter
25
  private final String attr;
26
27
  @Getter
28
  private final List<String> paths;
29
30
  private final ExprType type;
31
32
  /**
33
   * Constructor of ReferenceExpression.
34
   * @param ref the field name. e.g. addr.state/addr.
35
   * @param type type.
36
   */
37
  public ReferenceExpression(String ref, ExprType type) {
38
    this.attr = ref;
39
    // Todo. the define of paths need to be redefined after adding multiple index/variable support.
40
    this.paths = Arrays.asList(ref.split("\\."));
41
    this.type = type;
42
  }
43
44
  @Override
45
  public ExprValue valueOf(Environment<Expression, ExprValue> env) {
46 1 1. valueOf : replaced return value with null for org/opensearch/sql/expression/ReferenceExpression::valueOf → KILLED
    return env.resolve(this);
47
  }
48
49
  @Override
50
  public ExprType type() {
51 1 1. type : replaced return value with null for org/opensearch/sql/expression/ReferenceExpression::type → KILLED
    return type;
52
  }
53
54
  @Override
55
  public <T, C> T accept(ExpressionNodeVisitor<T, C> visitor, C context) {
56 1 1. accept : replaced return value with null for org/opensearch/sql/expression/ReferenceExpression::accept → KILLED
    return visitor.visitReference(this, context);
57
  }
58
59
  @Override
60
  public String toString() {
61 1 1. toString : replaced return value with "" for org/opensearch/sql/expression/ReferenceExpression::toString → KILLED
    return attr;
62
  }
63
64
  /**
65
   * Resolve the ExprValue from {@link ExprTupleValue} using paths.
66
   * Considering the following sample data.
67
   * {
68
   *   "name": "bob smith"
69
   *   "project.year": 1990,
70
   *   "project": {
71
   *     "year": "2020"
72
   *   }
73
   *   "address": {
74
   *     "state": "WA",
75
   *     "city": "seattle",
76
   *     "project.year": 1990
77
   *   }
78
   *   "address.local": {
79
   *     "state": "WA",
80
   *   }
81
   * }
82
   * The paths could be
83
   * 1. top level, e.g. "name", which will be resolved as "bob smith"
84
   * 2. multiple paths, e.g. "name.address.state", which will be resolved as "WA"
85
   * 3. special case, the "." is the path separator, but it is possible that the path include
86
   * ".", for handling this use case, we define the resolve rule as bellow, e.g. "project.year" is
87
   * resolved as 1990 instead of 2020. Note. This logic only applied top level none object field.
88
   * e.g. "address.local.state" been resolved to Missing. but "address.project.year" could been
89
   * resolved as 1990.
90
   *
91
   * <p>Resolve Rule
92
   * 1. Resolve the full name by combine the paths("x"."y"."z") as whole ("x.y.z").
93
   * 2. Resolve the path recursively through ExprValue.
94
   *
95
   * @param value {@link ExprTupleValue}.
96
   * @return {@link ExprTupleValue}.
97
   */
98
  public ExprValue resolve(ExprTupleValue value) {
99 1 1. resolve : replaced return value with null for org/opensearch/sql/expression/ReferenceExpression::resolve → KILLED
    return resolve(value, paths);
100
  }
101
102
  private ExprValue resolve(ExprValue value, List<String> paths) {
103
    final ExprValue wholePathValue = value.keyValue(String.join(PATH_SEP, paths));
104 2 1. resolve : negated conditional → KILLED
2. resolve : negated conditional → KILLED
    if (!wholePathValue.isMissing() || paths.size() == 1) {
105 1 1. resolve : replaced return value with null for org/opensearch/sql/expression/ReferenceExpression::resolve → KILLED
      return wholePathValue;
106
    } else {
107 1 1. resolve : replaced return value with null for org/opensearch/sql/expression/ReferenceExpression::resolve → KILLED
      return resolve(value.keyValue(paths.get(0)), paths.subList(1, paths.size()));
108
    }
109
  }
110
}

Mutations

46

1.1
Location : valueOf
Killed by : org.opensearch.sql.expression.ReferenceExpressionTest.[engine:junit-jupiter]/[class:org.opensearch.sql.expression.ReferenceExpressionTest]/[method:resolve_value()]
replaced return value with null for org/opensearch/sql/expression/ReferenceExpression::valueOf → KILLED

51

1.1
Location : type
Killed by : org.opensearch.sql.expression.ReferenceExpressionTest.[engine:junit-jupiter]/[class:org.opensearch.sql.expression.ReferenceExpressionTest]/[method:resolve_type()]
replaced return value with null for org/opensearch/sql/expression/ReferenceExpression::type → KILLED

56

1.1
Location : accept
Killed by : org.opensearch.sql.planner.logical.LogicalSortTest.[engine:junit-jupiter]/[class:org.opensearch.sql.planner.logical.LogicalSortTest]/[method:analyze_sort_with_two_field_with_default_option()]
replaced return value with null for org/opensearch/sql/expression/ReferenceExpression::accept → KILLED

61

1.1
Location : toString
Killed by : org.opensearch.sql.planner.physical.RemoveOperatorTest.[engine:junit-jupiter]/[class:org.opensearch.sql.planner.physical.RemoveOperatorTest]/[method:invalid_to_retrieve_schema_from_remove()]
replaced return value with "" for org/opensearch/sql/expression/ReferenceExpression::toString → KILLED

99

1.1
Location : resolve
Killed by : org.opensearch.sql.expression.ReferenceExpressionTest.[engine:junit-jupiter]/[class:org.opensearch.sql.expression.ReferenceExpressionTest]/[method:one_path_value()]
replaced return value with null for org/opensearch/sql/expression/ReferenceExpression::resolve → KILLED

104

1.1
Location : resolve
Killed by : org.opensearch.sql.expression.ReferenceExpressionTest.[engine:junit-jupiter]/[class:org.opensearch.sql.expression.ReferenceExpressionTest]/[method:path_as_whole_has_highest_priority()]
negated conditional → KILLED

2.2
Location : resolve
Killed by : org.opensearch.sql.expression.ReferenceExpressionTest.[engine:junit-jupiter]/[class:org.opensearch.sql.expression.ReferenceExpressionTest]/[method:multiple_path_value()]
negated conditional → KILLED

105

1.1
Location : resolve
Killed by : org.opensearch.sql.expression.ReferenceExpressionTest.[engine:junit-jupiter]/[class:org.opensearch.sql.expression.ReferenceExpressionTest]/[method:one_path_value()]
replaced return value with null for org/opensearch/sql/expression/ReferenceExpression::resolve → KILLED

107

1.1
Location : resolve
Killed by : org.opensearch.sql.expression.ReferenceExpressionTest.[engine:junit-jupiter]/[class:org.opensearch.sql.expression.ReferenceExpressionTest]/[method:object_field_contain_dot()]
replaced return value with null for org/opensearch/sql/expression/ReferenceExpression::resolve → KILLED

Active mutators

Tests examined


Report generated by PIT 1.9.0