Browse Source

SQL: Use underlying exact field for LIKE/RLIKE (#39443)

Previously, if a text field had an underlying keyword field
the latter was not used instead of the text leading to wrong
results returned by queries filtering with LIKE/RLIKE.

Fixes: #39442
Marios Trivyzas 6 năm trước cách đây
mục cha
commit
2a5d0a3f6a

+ 2 - 0
x-pack/plugin/sql/qa/src/main/resources/docs.csv-spec

@@ -2353,6 +2353,7 @@ SELECT * FROM (SELECT first_name, last_name FROM emp WHERE last_name NOT LIKE '%
   first_name   |   last_name
 ---------------+---------------
 Anneke         |Preusig
+Alejandro      |McAlpine
 Anoosh         |Peyn
 Arumugam       |Ossenbruggen
 // end::limitationSubSelect
@@ -2365,6 +2366,7 @@ SELECT first_name, last_name FROM emp WHERE last_name NOT LIKE '%a%' AND first_n
   first_name   |   last_name
 ---------------+---------------
 Anneke         |Preusig
+Alejandro      |McAlpine
 Anoosh         |Peyn
 Arumugam       |Ossenbruggen
 ;

+ 1 - 1
x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/planner/QueryTranslator.java

@@ -483,7 +483,7 @@ final class QueryTranslator {
             if (e.field() instanceof FieldAttribute) {
                 FieldAttribute fa = (FieldAttribute) e.field();
                 inexact = fa.isInexact();
-                target = nameOf(inexact ? fa : fa.exactAttribute());
+                target = nameOf(inexact ? fa.exactAttribute() : fa);
             } else {
                 throw new SqlIllegalArgumentException("Scalar function ({}) not allowed (yet) as arguments for LIKE",
                         Expressions.name(e.field()));

+ 14 - 0
x-pack/plugin/sql/src/test/java/org/elasticsearch/xpack/sql/planner/QueryTranslatorTests.java

@@ -39,6 +39,7 @@ import org.elasticsearch.xpack.sql.querydsl.agg.GroupByDateHistogram;
 import org.elasticsearch.xpack.sql.querydsl.query.ExistsQuery;
 import org.elasticsearch.xpack.sql.querydsl.query.NotQuery;
 import org.elasticsearch.xpack.sql.querydsl.query.Query;
+import org.elasticsearch.xpack.sql.querydsl.query.QueryStringQuery;
 import org.elasticsearch.xpack.sql.querydsl.query.RangeQuery;
 import org.elasticsearch.xpack.sql.querydsl.query.ScriptQuery;
 import org.elasticsearch.xpack.sql.querydsl.query.TermQuery;
@@ -184,6 +185,19 @@ public class QueryTranslatorTests extends ESTestCase {
         assertEquals("date", rq.field());
         assertEquals(DateUtils.asDateTime("1969-05-13T12:34:56Z"), rq.lower());
     }
+
+    public void testLikeOnInexact() {
+        LogicalPlan p = plan("SELECT * FROM test WHERE some.string LIKE '%a%'");
+        assertTrue(p instanceof Project);
+        p = ((Project) p).child();
+        assertTrue(p instanceof Filter);
+        Expression condition = ((Filter) p).condition();
+        QueryTranslation qt = QueryTranslator.toQuery(condition, false);
+        assertEquals(QueryStringQuery.class, qt.query.getClass());
+        QueryStringQuery qsq = ((QueryStringQuery) qt.query);
+        assertEquals(1, qsq.fields().size());
+        assertEquals("some.string.typical", qsq.fields().keySet().iterator().next());
+    }
     
     public void testLikeConstructsNotSupported() {
         LogicalPlan p = plan("SELECT LTRIM(keyword) lt FROM test WHERE LTRIM(keyword) LIKE '%a%'");