瀏覽代碼

ESQL: Add invalid mappings tests with fields from plugins (#105544)

Andrei Stefan 1 年之前
父節點
當前提交
8b9c14f900

+ 4 - 0
x-pack/plugin/esql/qa/server/single-node/build.gradle

@@ -7,6 +7,10 @@ dependencies {
   javaRestTestImplementation project(xpackModule('esql:qa:testFixtures'))
   javaRestTestImplementation project(xpackModule('esql:qa:server'))
   yamlRestTestImplementation project(xpackModule('esql:qa:server'))
+  dependencies {
+    clusterPlugins project(':plugins:mapper-size')
+    clusterPlugins project(':plugins:mapper-murmur3')
+  }
 }
 
 restResources {

+ 7 - 0
x-pack/plugin/esql/qa/server/single-node/src/javaRestTest/java/org/elasticsearch/xpack/esql/qa/single_node/Clusters.java

@@ -8,15 +8,22 @@
 package org.elasticsearch.xpack.esql.qa.single_node;
 
 import org.elasticsearch.test.cluster.ElasticsearchCluster;
+import org.elasticsearch.test.cluster.local.LocalClusterConfigProvider;
 import org.elasticsearch.test.cluster.local.distribution.DistributionType;
 
 public class Clusters {
+
     public static ElasticsearchCluster testCluster() {
+        return testCluster(config -> {});
+    }
+
+    public static ElasticsearchCluster testCluster(LocalClusterConfigProvider configProvider) {
         return ElasticsearchCluster.local()
             .distribution(DistributionType.DEFAULT)
             .setting("xpack.security.enabled", "false")
             .setting("xpack.license.self_generated.type", "trial")
             .shared(true)
+            .apply(() -> configProvider)
             .build();
     }
 }

+ 105 - 1
x-pack/plugin/esql/qa/server/single-node/src/javaRestTest/java/org/elasticsearch/xpack/esql/qa/single_node/RestEsqlIT.java

@@ -18,6 +18,7 @@ import org.elasticsearch.common.settings.Settings;
 import org.elasticsearch.test.TestClustersThreadFilter;
 import org.elasticsearch.test.cluster.ElasticsearchCluster;
 import org.elasticsearch.xpack.esql.qa.rest.RestEsqlTestCase;
+import org.hamcrest.Matchers;
 import org.junit.Assert;
 import org.junit.ClassRule;
 
@@ -29,12 +30,15 @@ import java.util.Locale;
 import java.util.Map;
 
 import static org.hamcrest.Matchers.containsString;
+import static org.hamcrest.Matchers.equalTo;
 import static org.hamcrest.core.Is.is;
 
 @ThreadLeakFilters(filters = TestClustersThreadFilter.class)
 public class RestEsqlIT extends RestEsqlTestCase {
     @ClassRule
-    public static ElasticsearchCluster cluster = Clusters.testCluster();
+    public static ElasticsearchCluster cluster = Clusters.testCluster(
+        specBuilder -> specBuilder.plugin("mapper-size").plugin("mapper-murmur3")
+    );
 
     @Override
     protected String getTestRestCluster() {
@@ -100,4 +104,104 @@ public class RestEsqlIT extends RestEsqlTestCase {
         ResponseException re = expectThrows(ResponseException.class, () -> runEsqlSync(builder));
         assertThat(EntityUtils.toString(re.getResponse().getEntity()), containsString("[pragma] only allowed in snapshot builds"));
     }
+
+    public void testIncompatibleMappingsErrors() throws IOException {
+        // create first index
+        Request request = new Request("PUT", "/index1");
+        request.setJsonEntity("""
+            {
+               "mappings": {
+                 "_size": {
+                   "enabled": true
+                 },
+                 "properties": {
+                   "message": {
+                     "type": "keyword",
+                     "fields": {
+                       "hash": {
+                         "type": "murmur3"
+                       }
+                     }
+                   }
+                 }
+               }
+            }
+            """);
+        assertEquals(200, client().performRequest(request).getStatusLine().getStatusCode());
+
+        // create second index
+        request = new Request("PUT", "/index2");
+        request.setJsonEntity("""
+            {
+              "mappings": {
+                "properties": {
+                  "message": {
+                    "type": "long",
+                    "fields": {
+                      "hash": {
+                        "type": "integer"
+                      }
+                    }
+                  }
+                }
+              }
+            }
+            """);
+        assertEquals(200, client().performRequest(request).getStatusLine().getStatusCode());
+
+        // create alias
+        request = new Request("POST", "/_aliases");
+        request.setJsonEntity("""
+            {
+              "actions": [
+                {
+                  "add": {
+                    "index": "index1",
+                    "alias": "test_alias"
+                  }
+                },
+                {
+                  "add": {
+                    "index": "index2",
+                    "alias": "test_alias"
+                  }
+                }
+              ]
+            }
+            """);
+        assertEquals(200, client().performRequest(request).getStatusLine().getStatusCode());
+        assertException(
+            "from index1,index2 | stats count(message)",
+            "VerificationException",
+            "Cannot use field [message] due to ambiguities",
+            "incompatible types: [keyword] in [index1], [long] in [index2]"
+        );
+        assertException(
+            "from test_alias | where message is not null",
+            "VerificationException",
+            "Cannot use field [message] due to ambiguities",
+            "incompatible types: [keyword] in [index1], [long] in [index2]"
+        );
+        assertException("from test_alias | where _size is not null | limit 1", "Unknown column [_size]");
+        assertException(
+            "from test_alias | where message.hash is not null | limit 1",
+            "Cannot use field [message.hash] due to ambiguities",
+            "incompatible types: [integer] in [index2], [murmur3] in [index1]"
+        );
+        assertException(
+            "from index1 | where message.hash is not null | limit 1",
+            "Cannot use field [message.hash] with unsupported type [murmur3]"
+        );
+        // clean up
+        assertThat(deleteIndex("index1").isAcknowledged(), Matchers.is(true));
+        assertThat(deleteIndex("index2").isAcknowledged(), Matchers.is(true));
+    }
+
+    private void assertException(String query, String... errorMessages) throws IOException {
+        ResponseException re = expectThrows(ResponseException.class, () -> runEsqlSync(new RequestObjectBuilder().query(query)));
+        assertThat(re.getResponse().getStatusLine().getStatusCode(), equalTo(400));
+        for (var error : errorMessages) {
+            assertThat(re.getMessage(), containsString(error));
+        }
+    }
 }

+ 1 - 0
x-pack/plugin/esql/qa/server/single-node/src/yamlRestTest/java/org/elasticsearch/xpack/esql/qa/single_node/EsqlClientYamlIT.java

@@ -15,6 +15,7 @@ import org.elasticsearch.test.rest.yaml.ClientYamlTestCandidate;
  * Run the ESQL yaml tests against the synchronous API.
  */
 public class EsqlClientYamlIT extends AbstractEsqlClientYamlIT {
+
     public EsqlClientYamlIT(final ClientYamlTestCandidate testCandidate) {
         super(testCandidate);
     }

+ 1 - 2
x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/esql/50_index_patterns.yml

@@ -311,7 +311,6 @@ same_name_different_type:
               message:
                 type: long
 
-
   - do:
       bulk:
         index: test1
@@ -338,7 +337,7 @@ same_name_different_type:
         - "No limit defined, adding default limit of \\[.*\\]"
       esql.query:
         body:
-          query: 'from test1,test2  '
+          query: 'from test1,test2'
   - match: { columns.0.name: message }
   - match: { columns.0.type: unsupported }
   - length: { values: 4 }