Skip to content

Commit

Permalink
Fix like expression (#381)
Browse files Browse the repository at this point in the history
Signed-off-by: Francesco Guardiani <francescoguard@gmail.com>
  • Loading branch information
slinkydeveloper committed May 3, 2021
1 parent 0a1a03d commit 9d45943
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,7 @@ public LikeExpression(Interval expressionInterval, String expressionText, Expres
super(expressionInterval, expressionText);
this.internal = internal;
// Converting to regex is not the most performant impl, but it works
this.pattern = Pattern.compile("^" +
pattern.replaceAll("(?<!\\\\)\\%", ".*")
.replaceAll("(?<!\\\\)\\_", ".")
.replaceAll("\\\\\\%", "%")
.replaceAll("\\\\_", "_") + "$"
);
this.pattern = convertLikePatternToRegex(pattern);
}

@Override
Expand All @@ -35,4 +30,38 @@ public Object evaluate(EvaluationRuntime runtime, CloudEvent event, ExceptionThr

return pattern.matcher(value).matches();
}

private Pattern convertLikePatternToRegex(String pattern) {
StringBuilder builder = new StringBuilder();
builder.append("^\\Q");

for (int i = 0; i < pattern.length(); i++) {
if (pattern.charAt(i) == '\\' && i < pattern.length() - 1) {
if (pattern.charAt(i + 1) == '%') {
// \% case
builder.append('%');
i++;
continue;
} else if (pattern.charAt(i + 1) == '_') {
// \_ case
builder.append('_');
i++;
continue;
}
}
if (pattern.charAt(i) == '_') {
// replace with .
builder.append("\\E.\\Q");
} else if (pattern.charAt(i) == '%') {
// replace with .*
builder.append("\\E.*\\Q");
} else {
builder.append(pattern.charAt(i));
}
}

builder.append("\\E$");

return Pattern.compile(builder.toString());
}
}
17 changes: 16 additions & 1 deletion sql/src/test/resources/tck/like_expression.yaml
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
name: Like expression
tests:
- name: Exact match
- name: Exact match (1)
expression: "'abc' LIKE 'abc'"
result: true
- name: Exact match (2)
expression: "'ab\\c' LIKE 'ab\\c'"
result: true
- name: Exact match (negate)
expression: "'abc' NOT LIKE 'abc'"
result: false
Expand All @@ -25,6 +28,12 @@ tests:
- name: Percentage operator (6)
expression: "'' LIKE 'abc'"
result: false
- name: Percentage operator (7)
expression: "'.ab.cde.' LIKE '.%.%.'"
result: true
- name: Percentage operator (8)
expression: "'ab.cde' LIKE '.%.%.'"
result: false

- name: Underscore operator (1)
expression: "'abc' LIKE 'a_b_c'"
Expand All @@ -41,6 +50,12 @@ tests:
- name: Underscore operator (5)
expression: "'azbzc' LIKE 'a_b_c'"
result: true
- name: Underscore operator (6)
expression: "'.a.b.' LIKE '._._.'"
result: true
- name: Underscore operator (7)
expression: "'abcd.' LIKE '._._.'"
result: false

- name: Escaped underscore wildcards (1)
expression: "'a_b_c' LIKE 'a\\_b\\_c'"
Expand Down

0 comments on commit 9d45943

Please sign in to comment.