Browse Source

ES|QL: remove dead code for LIKE operator (#115037) (#115192)

Luigi Dell'Aquila 1 year ago
parent
commit
b769c5eddd

+ 0 - 46
x-pack/plugin/esql-core/src/main/java/org/elasticsearch/xpack/esql/core/expression/predicate/regex/Like.java

@@ -1,46 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License
- * 2.0; you may not use this file except in compliance with the Elastic License
- * 2.0.
- */
-package org.elasticsearch.xpack.esql.core.expression.predicate.regex;
-
-import org.elasticsearch.common.io.stream.StreamOutput;
-import org.elasticsearch.xpack.esql.core.expression.Expression;
-import org.elasticsearch.xpack.esql.core.tree.NodeInfo;
-import org.elasticsearch.xpack.esql.core.tree.Source;
-
-import java.io.IOException;
-
-public class Like extends RegexMatch<LikePattern> {
-
-    public Like(Source source, Expression left, LikePattern pattern) {
-        this(source, left, pattern, false);
-    }
-
-    @Override
-    public void writeTo(StreamOutput out) throws IOException {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public String getWriteableName() {
-        throw new UnsupportedOperationException();
-    }
-
-    public Like(Source source, Expression left, LikePattern pattern, boolean caseInsensitive) {
-        super(source, left, pattern, caseInsensitive);
-    }
-
-    @Override
-    protected NodeInfo<Like> info() {
-        return NodeInfo.create(this, Like::new, field(), pattern(), caseInsensitive());
-    }
-
-    @Override
-    protected Like replaceChild(Expression newLeft) {
-        return new Like(source(), newLeft, pattern(), caseInsensitive());
-    }
-
-}

+ 0 - 95
x-pack/plugin/esql-core/src/main/java/org/elasticsearch/xpack/esql/core/expression/predicate/regex/LikePattern.java

@@ -1,95 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License
- * 2.0; you may not use this file except in compliance with the Elastic License
- * 2.0.
- */
-package org.elasticsearch.xpack.esql.core.expression.predicate.regex;
-
-import org.apache.lucene.index.Term;
-import org.apache.lucene.search.WildcardQuery;
-import org.apache.lucene.util.automaton.Automaton;
-import org.apache.lucene.util.automaton.MinimizationOperations;
-import org.apache.lucene.util.automaton.Operations;
-import org.elasticsearch.xpack.esql.core.util.StringUtils;
-
-import java.util.Objects;
-
-/**
- * A SQL 'like' pattern.
- * Similar to basic regex, supporting '_' instead of '?' and '%' instead of '*'.
- * <p>
- * Allows escaping based on a regular char.
- *
- * To prevent conflicts with ES, the string and char must be validated to not contain '*'.
- */
-public class LikePattern extends AbstractStringPattern {
-
-    private final String pattern;
-    private final char escape;
-
-    private final String regex;
-    private final String wildcard;
-    private final String indexNameWildcard;
-
-    public LikePattern(String pattern, char escape) {
-        this.pattern = pattern;
-        this.escape = escape;
-        // early initialization to force string validation
-        this.regex = StringUtils.likeToJavaPattern(pattern, escape);
-        this.wildcard = StringUtils.likeToLuceneWildcard(pattern, escape);
-        this.indexNameWildcard = StringUtils.likeToIndexWildcard(pattern, escape);
-    }
-
-    public String pattern() {
-        return pattern;
-    }
-
-    public char escape() {
-        return escape;
-    }
-
-    @Override
-    public Automaton createAutomaton() {
-        Automaton automaton = WildcardQuery.toAutomaton(new Term(null, wildcard));
-        return MinimizationOperations.minimize(automaton, Operations.DEFAULT_DETERMINIZE_WORK_LIMIT);
-    }
-
-    @Override
-    public String asJavaRegex() {
-        return regex;
-    }
-
-    /**
-     * Returns the pattern in (Lucene) wildcard format.
-     */
-    public String asLuceneWildcard() {
-        return wildcard;
-    }
-
-    /**
-     * Returns the pattern in (IndexNameExpressionResolver) wildcard format.
-     */
-    public String asIndexNameWildcard() {
-        return indexNameWildcard;
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(pattern, escape);
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-
-        if (obj == null || getClass() != obj.getClass()) {
-            return false;
-        }
-
-        LikePattern other = (LikePattern) obj;
-        return Objects.equals(pattern, other.pattern) && escape == other.escape;
-    }
-}

+ 0 - 4
x-pack/plugin/esql-core/src/main/java/org/elasticsearch/xpack/esql/core/planner/ExpressionTranslators.java

@@ -19,7 +19,6 @@ import org.elasticsearch.xpack.esql.core.expression.predicate.logical.Not;
 import org.elasticsearch.xpack.esql.core.expression.predicate.logical.Or;
 import org.elasticsearch.xpack.esql.core.expression.predicate.nulls.IsNotNull;
 import org.elasticsearch.xpack.esql.core.expression.predicate.nulls.IsNull;
-import org.elasticsearch.xpack.esql.core.expression.predicate.regex.Like;
 import org.elasticsearch.xpack.esql.core.expression.predicate.regex.RLike;
 import org.elasticsearch.xpack.esql.core.expression.predicate.regex.RegexMatch;
 import org.elasticsearch.xpack.esql.core.expression.predicate.regex.WildcardLike;
@@ -66,9 +65,6 @@ public final class ExpressionTranslators {
         }
 
         private static Query translateField(RegexMatch e, String targetFieldName) {
-            if (e instanceof Like l) {
-                return new WildcardQuery(e.source(), targetFieldName, l.pattern().asLuceneWildcard(), l.caseInsensitive());
-            }
             if (e instanceof WildcardLike l) {
                 return new WildcardQuery(e.source(), targetFieldName, l.pattern().asLuceneWildcard(), l.caseInsensitive());
             }

+ 49 - 49
x-pack/plugin/esql-core/src/test/java/org/elasticsearch/xpack/esql/core/expression/predicate/regex/StringPatternTests.java

@@ -12,78 +12,78 @@ import org.elasticsearch.xpack.esql.core.util.StringUtils;
 
 public class StringPatternTests extends ESTestCase {
 
-    private LikePattern like(String pattern, char escape) {
-        return new LikePattern(pattern, escape);
+    private WildcardPattern like(String pattern) {
+        return new WildcardPattern(pattern);
     }
 
     private RLikePattern rlike(String pattern) {
         return new RLikePattern(pattern);
     }
 
-    private boolean matchesAll(String pattern, char escape) {
-        return like(pattern, escape).matchesAll();
+    private boolean likeMatchesAll(String pattern) {
+        return like(pattern).matchesAll();
     }
 
-    private boolean exactMatch(String pattern, char escape) {
-        String escaped = pattern.replace(Character.toString(escape), StringUtils.EMPTY);
-        return escaped.equals(like(pattern, escape).exactMatch());
+    private boolean likeExactMatch(String pattern) {
+        String escaped = pattern.replace("\\", StringUtils.EMPTY);
+        return escaped.equals(like(pattern).exactMatch());
     }
 
-    private boolean matchesAll(String pattern) {
+    private boolean rlikeMatchesAll(String pattern) {
         return rlike(pattern).matchesAll();
     }
 
-    private boolean exactMatch(String pattern) {
+    private boolean rlikeExactMatch(String pattern) {
         return pattern.equals(rlike(pattern).exactMatch());
     }
 
-    public void testWildcardMatchAll() throws Exception {
-        assertTrue(matchesAll("%", '0'));
-        assertTrue(matchesAll("%%", '0'));
+    public void testWildcardMatchAll() {
+        assertTrue(likeMatchesAll("*"));
+        assertTrue(likeMatchesAll("**"));
 
-        assertFalse(matchesAll("a%", '0'));
-        assertFalse(matchesAll("%_", '0'));
-        assertFalse(matchesAll("%_%_%", '0'));
-        assertFalse(matchesAll("_%", '0'));
-        assertFalse(matchesAll("0%", '0'));
+        assertFalse(likeMatchesAll("a*"));
+        assertFalse(likeMatchesAll("*?"));
+        assertFalse(likeMatchesAll("*?*?*"));
+        assertFalse(likeMatchesAll("?*"));
+        assertFalse(likeMatchesAll("\\*"));
     }
 
-    public void testRegexMatchAll() throws Exception {
-        assertTrue(matchesAll(".*"));
-        assertTrue(matchesAll(".*.*"));
-        assertTrue(matchesAll(".*.?"));
-        assertTrue(matchesAll(".?.*"));
-        assertTrue(matchesAll(".*.?.*"));
+    public void testRegexMatchAll() {
+        assertTrue(rlikeMatchesAll(".*"));
+        assertTrue(rlikeMatchesAll(".*.*"));
+        assertTrue(rlikeMatchesAll(".*.?"));
+        assertTrue(rlikeMatchesAll(".?.*"));
+        assertTrue(rlikeMatchesAll(".*.?.*"));
 
-        assertFalse(matchesAll("..*"));
-        assertFalse(matchesAll("ab."));
-        assertFalse(matchesAll("..?"));
+        assertFalse(rlikeMatchesAll("..*"));
+        assertFalse(rlikeMatchesAll("ab."));
+        assertFalse(rlikeMatchesAll("..?"));
     }
 
-    public void testWildcardExactMatch() throws Exception {
-        assertTrue(exactMatch("0%", '0'));
-        assertTrue(exactMatch("0_", '0'));
-        assertTrue(exactMatch("123", '0'));
-        assertTrue(exactMatch("1230_", '0'));
-        assertTrue(exactMatch("1230_321", '0'));
-
-        assertFalse(exactMatch("%", '0'));
-        assertFalse(exactMatch("%%", '0'));
-        assertFalse(exactMatch("a%", '0'));
-        assertFalse(exactMatch("a_", '0'));
+    public void testWildcardExactMatch() {
+        assertTrue(likeExactMatch("\\*"));
+        assertTrue(likeExactMatch("\\?"));
+        assertTrue(likeExactMatch("123"));
+        assertTrue(likeExactMatch("123\\?"));
+        assertTrue(likeExactMatch("123\\?321"));
+
+        assertFalse(likeExactMatch("*"));
+        assertFalse(likeExactMatch("**"));
+        assertFalse(likeExactMatch("a*"));
+        assertFalse(likeExactMatch("a?"));
     }
 
-    public void testRegexExactMatch() throws Exception {
-        assertFalse(exactMatch(".*"));
-        assertFalse(exactMatch(".*.*"));
-        assertFalse(exactMatch(".*.?"));
-        assertFalse(exactMatch(".?.*"));
-        assertFalse(exactMatch(".*.?.*"));
-        assertFalse(exactMatch("..*"));
-        assertFalse(exactMatch("ab."));
-        assertFalse(exactMatch("..?"));
-
-        assertTrue(exactMatch("abc"));
-        assertTrue(exactMatch("12345"));
+    public void testRegexExactMatch() {
+        assertFalse(rlikeExactMatch(".*"));
+        assertFalse(rlikeExactMatch(".*.*"));
+        assertFalse(rlikeExactMatch(".*.?"));
+        assertFalse(rlikeExactMatch(".?.*"));
+        assertFalse(rlikeExactMatch(".*.?.*"));
+        assertFalse(rlikeExactMatch("..*"));
+        assertFalse(rlikeExactMatch("ab."));
+        assertFalse(rlikeExactMatch("..?"));
+
+        assertTrue(rlikeExactMatch("abc"));
+        assertTrue(rlikeExactMatch("12345"));
     }
 }

+ 0 - 3
x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/rules/logical/ConstantFoldingTests.java

@@ -17,8 +17,6 @@ import org.elasticsearch.xpack.esql.core.expression.predicate.BinaryOperator;
 import org.elasticsearch.xpack.esql.core.expression.predicate.logical.And;
 import org.elasticsearch.xpack.esql.core.expression.predicate.logical.Not;
 import org.elasticsearch.xpack.esql.core.expression.predicate.logical.Or;
-import org.elasticsearch.xpack.esql.core.expression.predicate.regex.Like;
-import org.elasticsearch.xpack.esql.core.expression.predicate.regex.LikePattern;
 import org.elasticsearch.xpack.esql.core.expression.predicate.regex.RLike;
 import org.elasticsearch.xpack.esql.core.expression.predicate.regex.RLikePattern;
 import org.elasticsearch.xpack.esql.core.expression.predicate.regex.WildcardLike;
@@ -101,7 +99,6 @@ public class ConstantFoldingTests extends ESTestCase {
     }
 
     public void testConstantFoldingLikes() {
-        assertEquals(TRUE, new ConstantFolding().rule(new Like(EMPTY, of("test_emp"), new LikePattern("test%", (char) 0))).canonical());
         assertEquals(TRUE, new ConstantFolding().rule(new WildcardLike(EMPTY, of("test_emp"), new WildcardPattern("test*"))).canonical());
         assertEquals(TRUE, new ConstantFolding().rule(new RLike(EMPTY, of("test_emp"), new RLikePattern("test.emp"))).canonical());
     }

+ 5 - 31
x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/rules/logical/ReplaceRegexMatchTests.java

@@ -11,8 +11,6 @@ import org.elasticsearch.test.ESTestCase;
 import org.elasticsearch.xpack.esql.core.expression.Expression;
 import org.elasticsearch.xpack.esql.core.expression.FieldAttribute;
 import org.elasticsearch.xpack.esql.core.expression.predicate.nulls.IsNotNull;
-import org.elasticsearch.xpack.esql.core.expression.predicate.regex.Like;
-import org.elasticsearch.xpack.esql.core.expression.predicate.regex.LikePattern;
 import org.elasticsearch.xpack.esql.core.expression.predicate.regex.RLike;
 import org.elasticsearch.xpack.esql.core.expression.predicate.regex.RLikePattern;
 import org.elasticsearch.xpack.esql.core.expression.predicate.regex.WildcardLike;
@@ -26,18 +24,6 @@ import static org.elasticsearch.xpack.esql.core.tree.Source.EMPTY;
 
 public class ReplaceRegexMatchTests extends ESTestCase {
 
-    public void testMatchAllLikeToExist() {
-        for (String s : asList("%", "%%", "%%%")) {
-            LikePattern pattern = new LikePattern(s, (char) 0);
-            FieldAttribute fa = getFieldAttribute();
-            Like l = new Like(EMPTY, fa, pattern);
-            Expression e = new ReplaceRegexMatch().rule(l);
-            assertEquals(IsNotNull.class, e.getClass());
-            IsNotNull inn = (IsNotNull) e;
-            assertEquals(fa, inn.field());
-        }
-    }
-
     public void testMatchAllWildcardLikeToExist() {
         for (String s : asList("*", "**", "***")) {
             WildcardPattern pattern = new WildcardPattern(s);
@@ -60,31 +46,19 @@ public class ReplaceRegexMatchTests extends ESTestCase {
         assertEquals(fa, inn.field());
     }
 
-    public void testExactMatchLike() {
-        for (String s : asList("ab", "ab0%", "ab0_c")) {
-            LikePattern pattern = new LikePattern(s, '0');
+    public void testExactMatchWildcardLike() {
+        for (String s : asList("ab", "ab\\*", "ab\\?c")) {
+            WildcardPattern pattern = new WildcardPattern(s);
             FieldAttribute fa = getFieldAttribute();
-            Like l = new Like(EMPTY, fa, pattern);
+            WildcardLike l = new WildcardLike(EMPTY, fa, pattern);
             Expression e = new ReplaceRegexMatch().rule(l);
             assertEquals(Equals.class, e.getClass());
             Equals eq = (Equals) e;
             assertEquals(fa, eq.left());
-            assertEquals(s.replace("0", StringUtils.EMPTY), eq.right().fold());
+            assertEquals(s.replace("\\", StringUtils.EMPTY), eq.right().fold());
         }
     }
 
-    public void testExactMatchWildcardLike() {
-        String s = "ab";
-        WildcardPattern pattern = new WildcardPattern(s);
-        FieldAttribute fa = getFieldAttribute();
-        WildcardLike l = new WildcardLike(EMPTY, fa, pattern);
-        Expression e = new ReplaceRegexMatch().rule(l);
-        assertEquals(Equals.class, e.getClass());
-        Equals eq = (Equals) e;
-        assertEquals(fa, eq.left());
-        assertEquals(s, eq.right().fold());
-    }
-
     public void testExactMatchRLike() {
         RLikePattern pattern = new RLikePattern("abc");
         FieldAttribute fa = getFieldAttribute();

+ 0 - 8
x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/tree/EsqlNodeSubclassTests.java

@@ -28,8 +28,6 @@ import org.elasticsearch.xpack.esql.core.expression.UnresolvedAttributeTests;
 import org.elasticsearch.xpack.esql.core.expression.UnresolvedNamedExpression;
 import org.elasticsearch.xpack.esql.core.expression.function.Function;
 import org.elasticsearch.xpack.esql.core.expression.predicate.fulltext.FullTextPredicate;
-import org.elasticsearch.xpack.esql.core.expression.predicate.regex.Like;
-import org.elasticsearch.xpack.esql.core.expression.predicate.regex.LikePattern;
 import org.elasticsearch.xpack.esql.core.tree.AbstractNodeTestCase;
 import org.elasticsearch.xpack.esql.core.tree.Node;
 import org.elasticsearch.xpack.esql.core.tree.NodeInfo;
@@ -422,12 +420,6 @@ public class EsqlNodeSubclassTests<T extends B, B extends Node<B>> extends NodeS
                 }
                 return b.toString();
             }
-        } else if (toBuildClass == Like.class) {
-
-            if (argClass == LikePattern.class) {
-                return new LikePattern(randomAlphaOfLength(16), randomFrom('\\', '|', '/', '`'));
-            }
-
         } else if (argClass == Dissect.Parser.class) {
             // Dissect.Parser is a record / final, cannot be mocked
             String pattern = randomDissectPattern();