HighlightExpression.java

1
/*
2
 * Copyright OpenSearch Contributors
3
 * SPDX-License-Identifier: Apache-2.0
4
 */
5
6
package org.opensearch.sql.expression;
7
8
import java.util.LinkedHashMap;
9
import java.util.List;
10
import java.util.regex.Matcher;
11
import java.util.regex.Pattern;
12
import java.util.stream.Collectors;
13
import lombok.Getter;
14
import org.opensearch.sql.common.utils.StringUtils;
15
import org.opensearch.sql.data.model.ExprTupleValue;
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.expression.env.Environment;
21
import org.opensearch.sql.expression.function.BuiltinFunctionName;
22
23
/**
24
 * Highlight Expression.
25
 */
26
@Getter
27
public class HighlightExpression extends FunctionExpression {
28
  private final Expression highlightField;
29
  private final ExprType type;
30
31
  /**
32
   * HighlightExpression Constructor.
33
   * @param highlightField : Highlight field for expression.
34
   */
35
  public HighlightExpression(Expression highlightField) {
36
    super(BuiltinFunctionName.HIGHLIGHT.getName(), List.of(highlightField));
37
    this.highlightField = highlightField;
38 1 1. <init> : negated conditional → KILLED
    this.type = this.highlightField.toString().contains("*")
39
        ? ExprCoreType.STRUCT : ExprCoreType.ARRAY;
40
  }
41
42
  /**
43
   * Return collection value matching highlight field.
44
   * @param valueEnv : Dataset to parse value from.
45
   * @return : collection value of highlight fields.
46
   */
47
  @Override
48
  public ExprValue valueOf(Environment<Expression, ExprValue> valueEnv) {
49
    String refName = "_highlight";
50
    // Not a wilcard expression
51 1 1. valueOf : negated conditional → KILLED
    if (this.type == ExprCoreType.ARRAY) {
52
      refName += "." + StringUtils.unquoteText(getHighlightField().toString());
53
    }
54
    ExprValue value = valueEnv.resolve(DSL.ref(refName, ExprCoreType.STRING));
55
56
    // In the event of multiple returned highlights and wildcard being
57
    // used in conjunction with other highlight calls, we need to ensure
58
    // only wildcard regex matching is mapped to wildcard call.
59 2 1. valueOf : negated conditional → KILLED
2. valueOf : negated conditional → KILLED
    if (this.type == ExprCoreType.STRUCT && value.type() == ExprCoreType.STRUCT) {
60
      value = new ExprTupleValue(
61
          new LinkedHashMap<String, ExprValue>(value.tupleValue()
62
              .entrySet()
63
              .stream()
64 2 1. lambda$valueOf$0 : replaced boolean return with false for org/opensearch/sql/expression/HighlightExpression::lambda$valueOf$0 → KILLED
2. lambda$valueOf$0 : replaced boolean return with true for org/opensearch/sql/expression/HighlightExpression::lambda$valueOf$0 → KILLED
              .filter(s -> matchesHighlightRegex(s.getKey(),
65
                  StringUtils.unquoteText(highlightField.toString())))
66
              .collect(Collectors.toMap(
67 1 1. lambda$valueOf$1 : replaced return value with "" for org/opensearch/sql/expression/HighlightExpression::lambda$valueOf$1 → SURVIVED
                  e -> e.getKey(),
68 1 1. lambda$valueOf$2 : replaced return value with null for org/opensearch/sql/expression/HighlightExpression::lambda$valueOf$2 → KILLED
                  e -> e.getValue()))));
69 1 1. valueOf : negated conditional → KILLED
      if (value.tupleValue().isEmpty()) {
70
        value = ExprValueUtils.missingValue();
71
      }
72
    }
73
74 1 1. valueOf : replaced return value with null for org/opensearch/sql/expression/HighlightExpression::valueOf → KILLED
    return value;
75
  }
76
77
  /**
78
   * Get type for HighlightExpression.
79
   * @return : Expression type.
80
   */
81
  @Override
82
  public ExprType type() {
83 1 1. type : replaced return value with null for org/opensearch/sql/expression/HighlightExpression::type → KILLED
    return this.type;
84
  }
85
86
  @Override
87
  public <T, C> T accept(ExpressionNodeVisitor<T, C> visitor, C context) {
88 1 1. accept : replaced return value with null for org/opensearch/sql/expression/HighlightExpression::accept → KILLED
    return visitor.visitHighlight(this, context);
89
  }
90
91
  /**
92
   * Check if field matches the wildcard pattern used in highlight query.
93
   * @param field Highlight selected field for query
94
   * @param pattern Wildcard regex to match field against
95
   * @return True if field matches wildcard pattern
96
   */
97
  private boolean matchesHighlightRegex(String field, String pattern) {
98
    Pattern p = Pattern.compile(pattern.replace("*", ".*"));
99
    Matcher matcher = p.matcher(field);
100 2 1. matchesHighlightRegex : replaced boolean return with false for org/opensearch/sql/expression/HighlightExpression::matchesHighlightRegex → KILLED
2. matchesHighlightRegex : replaced boolean return with true for org/opensearch/sql/expression/HighlightExpression::matchesHighlightRegex → KILLED
    return matcher.matches();
101
  }
102
}

Mutations

38

1.1
Location : <init>
Killed by : org.opensearch.sql.expression.HighlightExpressionTest.[engine:junit-jupiter]/[class:org.opensearch.sql.expression.HighlightExpressionTest]/[method:single_highlight_test()]
negated conditional → KILLED

51

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

59

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

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

64

1.1
Location : lambda$valueOf$0
Killed by : org.opensearch.sql.expression.HighlightExpressionTest.[engine:junit-jupiter]/[class:org.opensearch.sql.expression.HighlightExpressionTest]/[method:highlight_all_test()]
replaced boolean return with false for org/opensearch/sql/expression/HighlightExpression::lambda$valueOf$0 → KILLED

2.2
Location : lambda$valueOf$0
Killed by : org.opensearch.sql.expression.HighlightExpressionTest.[engine:junit-jupiter]/[class:org.opensearch.sql.expression.HighlightExpressionTest]/[method:missing_highlight_wildcard_test()]
replaced boolean return with true for org/opensearch/sql/expression/HighlightExpression::lambda$valueOf$0 → KILLED

67

1.1
Location : lambda$valueOf$1
Killed by : none
replaced return value with "" for org/opensearch/sql/expression/HighlightExpression::lambda$valueOf$1 → SURVIVED

68

1.1
Location : lambda$valueOf$2
Killed by : org.opensearch.sql.expression.HighlightExpressionTest.[engine:junit-jupiter]/[class:org.opensearch.sql.expression.HighlightExpressionTest]/[method:highlight_all_test()]
replaced return value with null for org/opensearch/sql/expression/HighlightExpression::lambda$valueOf$2 → KILLED

69

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

74

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

83

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

88

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

100

1.1
Location : matchesHighlightRegex
Killed by : org.opensearch.sql.expression.HighlightExpressionTest.[engine:junit-jupiter]/[class:org.opensearch.sql.expression.HighlightExpressionTest]/[method:highlight_all_test()]
replaced boolean return with false for org/opensearch/sql/expression/HighlightExpression::matchesHighlightRegex → KILLED

2.2
Location : matchesHighlightRegex
Killed by : org.opensearch.sql.expression.HighlightExpressionTest.[engine:junit-jupiter]/[class:org.opensearch.sql.expression.HighlightExpressionTest]/[method:missing_highlight_wildcard_test()]
replaced boolean return with true for org/opensearch/sql/expression/HighlightExpression::matchesHighlightRegex → KILLED

Active mutators

Tests examined


Report generated by PIT 1.9.0