|
@@ -10,6 +10,7 @@ package org.elasticsearch.xpack.esql.action;
|
|
|
import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest;
|
|
|
import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequestBuilder;
|
|
|
import org.elasticsearch.client.internal.Client;
|
|
|
+import org.elasticsearch.common.settings.Settings;
|
|
|
import org.elasticsearch.xpack.core.enrich.EnrichPolicy;
|
|
|
import org.elasticsearch.xpack.core.enrich.action.ExecuteEnrichPolicyAction;
|
|
|
import org.elasticsearch.xpack.core.enrich.action.PutEnrichPolicyAction;
|
|
@@ -289,6 +290,9 @@ public class CrossClusterLookupJoinIT extends AbstractCrossClusterTestCase {
|
|
|
populateLookupIndex(REMOTE_CLUSTER_1, "values_lookup", 10);
|
|
|
|
|
|
setSkipUnavailable(REMOTE_CLUSTER_1, true);
|
|
|
+
|
|
|
+ Exception ex;
|
|
|
+
|
|
|
try (
|
|
|
// Using local_tag as key which is not present in remote index
|
|
|
EsqlQueryResponse resp = runQuery(
|
|
@@ -362,10 +366,7 @@ public class CrossClusterLookupJoinIT extends AbstractCrossClusterTestCase {
|
|
|
}
|
|
|
|
|
|
// TODO: verify whether this should be an error or not when the key field is missing
|
|
|
- Exception ex = expectThrows(
|
|
|
- VerificationException.class,
|
|
|
- () -> runQuery("FROM c*:logs-* | LOOKUP JOIN values_lookup ON v", randomBoolean())
|
|
|
- );
|
|
|
+ ex = expectThrows(VerificationException.class, () -> runQuery("FROM c*:logs-* | LOOKUP JOIN values_lookup ON v", randomBoolean()));
|
|
|
assertThat(ex.getMessage(), containsString("Unknown column [v] in right side of join"));
|
|
|
|
|
|
ex = expectThrows(
|
|
@@ -374,6 +375,25 @@ public class CrossClusterLookupJoinIT extends AbstractCrossClusterTestCase {
|
|
|
);
|
|
|
assertThat(ex.getMessage(), containsString("Unknown column [local_tag] in right side of join"));
|
|
|
|
|
|
+ // Add KEEP clause to try and trick the field-caps result parser into returning empty mapping
|
|
|
+ ex = expectThrows(
|
|
|
+ VerificationException.class,
|
|
|
+ () -> runQuery("FROM logs-* | LOOKUP JOIN values_lookup ON v | KEEP v", randomBoolean())
|
|
|
+ );
|
|
|
+ assertThat(ex.getMessage(), containsString("Unknown column [v] in right side of join"));
|
|
|
+
|
|
|
+ ex = expectThrows(
|
|
|
+ VerificationException.class,
|
|
|
+ () -> runQuery("FROM logs-*,c*:logs-* | LOOKUP JOIN values_lookup ON v | KEEP v", randomBoolean())
|
|
|
+ );
|
|
|
+ assertThat(ex.getMessage(), containsString("Unknown column [v] in right side of join"));
|
|
|
+
|
|
|
+ ex = expectThrows(
|
|
|
+ VerificationException.class,
|
|
|
+ () -> runQuery("FROM c*:logs-* | LOOKUP JOIN values_lookup ON v | KEEP v", randomBoolean())
|
|
|
+ );
|
|
|
+ assertThat(ex.getMessage(), containsString("Unknown column [v] in right side of join"));
|
|
|
+
|
|
|
setSkipUnavailable(REMOTE_CLUSTER_1, false);
|
|
|
try (
|
|
|
// Using local_tag as key which is not present in remote index
|
|
@@ -393,6 +413,42 @@ public class CrossClusterLookupJoinIT extends AbstractCrossClusterTestCase {
|
|
|
// FIXME: verify whether we need to succeed or fail here
|
|
|
assertThat(remoteCluster.getStatus(), equalTo(EsqlExecutionInfo.Cluster.Status.SUCCESSFUL));
|
|
|
}
|
|
|
+
|
|
|
+ // Add KEEP clause to try and trick the field-caps result parser into returning empty mapping
|
|
|
+ ex = expectThrows(
|
|
|
+ VerificationException.class,
|
|
|
+ () -> runQuery("FROM c*:logs-* | LOOKUP JOIN values_lookup ON v | KEEP v", randomBoolean())
|
|
|
+ );
|
|
|
+ assertThat(ex.getMessage(), containsString("Unknown column [v] in right side of join"));
|
|
|
+
|
|
|
+ ex = expectThrows(
|
|
|
+ VerificationException.class,
|
|
|
+ () -> runQuery("FROM logs-*,c*:logs-* | LOOKUP JOIN values_lookup ON v | KEEP v", randomBoolean())
|
|
|
+ );
|
|
|
+ assertThat(ex.getMessage(), containsString("Unknown column [v] in right side of join"));
|
|
|
+ }
|
|
|
+
|
|
|
+ public void testLookupJoinEmptyIndex() throws IOException {
|
|
|
+ setupClusters(2);
|
|
|
+ populateEmptyIndices(LOCAL_CLUSTER, "values_lookup");
|
|
|
+ populateEmptyIndices(REMOTE_CLUSTER_1, "values_lookup");
|
|
|
+
|
|
|
+ // Should work the same with both settings
|
|
|
+ setSkipUnavailable(REMOTE_CLUSTER_1, randomBoolean());
|
|
|
+
|
|
|
+ Exception ex;
|
|
|
+ for (String index : List.of("values_lookup", "values_lookup_map", "values_lookup_map_lookup")) {
|
|
|
+ ex = expectThrows(
|
|
|
+ VerificationException.class,
|
|
|
+ () -> runQuery("FROM logs-* | LOOKUP JOIN " + index + " ON v | KEEP v", randomBoolean())
|
|
|
+ );
|
|
|
+ assertThat(ex.getMessage(), containsString("Unknown column [v] in right side of join"));
|
|
|
+ ex = expectThrows(
|
|
|
+ VerificationException.class,
|
|
|
+ () -> runQuery("FROM c*:logs-* | LOOKUP JOIN " + index + " ON v | KEEP v", randomBoolean())
|
|
|
+ );
|
|
|
+ assertThat(ex.getMessage(), containsString("Unknown column [v] in right side of join"));
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
public void testLookupJoinIndexMode() throws IOException {
|
|
@@ -528,4 +584,23 @@ public class CrossClusterLookupJoinIT extends AbstractCrossClusterTestCase {
|
|
|
assertAcked(client.admin().indices().aliases(indicesAliasesRequestBuilder.request()));
|
|
|
}
|
|
|
|
|
|
+ protected void populateEmptyIndices(String clusterAlias, String indexName) {
|
|
|
+ Client client = client(clusterAlias);
|
|
|
+ // Empty body
|
|
|
+ assertAcked(client.admin().indices().prepareCreate(indexName));
|
|
|
+ client.admin().indices().prepareRefresh(indexName).get();
|
|
|
+ // mappings + settings
|
|
|
+ assertAcked(
|
|
|
+ client.admin()
|
|
|
+ .indices()
|
|
|
+ .prepareCreate(indexName + "_map_lookup")
|
|
|
+ .setMapping()
|
|
|
+ .setSettings(Settings.builder().put("index.mode", "lookup"))
|
|
|
+ );
|
|
|
+ client.admin().indices().prepareRefresh(indexName + "_map_lookup").get();
|
|
|
+ // mappings only
|
|
|
+ assertAcked(client.admin().indices().prepareCreate(indexName + "_map").setMapping());
|
|
|
+ client.admin().indices().prepareRefresh(indexName + "_map").get();
|
|
|
+ }
|
|
|
+
|
|
|
}
|