Skip to content

Commit b36d57f

Browse files
committed
Fix index lookup when field-caps returns empty mapping
1 parent 739ba25 commit b36d57f

File tree

2 files changed

+51
-4
lines changed

2 files changed

+51
-4
lines changed

x-pack/plugin/esql/src/internalClusterTest/java/org/elasticsearch/xpack/esql/action/CrossClusterLookupJoinIT.java

Lines changed: 46 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,9 @@ public void testLookupJoinMissingKey() throws IOException {
289289
populateLookupIndex(REMOTE_CLUSTER_1, "values_lookup", 10);
290290

291291
setSkipUnavailable(REMOTE_CLUSTER_1, true);
292+
293+
Exception ex;
294+
292295
try (
293296
// Using local_tag as key which is not present in remote index
294297
EsqlQueryResponse resp = runQuery(
@@ -362,10 +365,7 @@ public void testLookupJoinMissingKey() throws IOException {
362365
}
363366

364367
// TODO: verify whether this should be an error or not when the key field is missing
365-
Exception ex = expectThrows(
366-
VerificationException.class,
367-
() -> runQuery("FROM c*:logs-* | LOOKUP JOIN values_lookup ON v", randomBoolean())
368-
);
368+
ex = expectThrows(VerificationException.class, () -> runQuery("FROM c*:logs-* | LOOKUP JOIN values_lookup ON v", randomBoolean()));
369369
assertThat(ex.getMessage(), containsString("Unknown column [v] in right side of join"));
370370

371371
ex = expectThrows(
@@ -374,6 +374,34 @@ public void testLookupJoinMissingKey() throws IOException {
374374
);
375375
assertThat(ex.getMessage(), containsString("Unknown column [local_tag] in right side of join"));
376376

377+
// Add KEEP clause to try and trick the field-caps result parser
378+
ex = expectThrows(
379+
VerificationException.class,
380+
() -> runQuery("FROM logs-* | LOOKUP JOIN values_lookup ON v | KEEP v", randomBoolean())
381+
);
382+
assertThat(ex.getMessage(), containsString("Unknown column [v] in right side of join"));
383+
384+
ex = expectThrows(
385+
VerificationException.class,
386+
() -> runQuery("FROM logs-*,c*:logs-* | LOOKUP JOIN values_lookup ON v | KEEP v", randomBoolean())
387+
);
388+
// FIXME: strictly speaking this message is not correct, as the index is available, but the field is not
389+
assertThat(ex.getMessage(), containsString("lookup index [values_lookup] is not available"));
390+
391+
try (EsqlQueryResponse resp = runQuery("FROM c*:logs-* | LOOKUP JOIN values_lookup ON v | KEEP v", randomBoolean())) {
392+
List<List<Object>> values = getValuesList(resp);
393+
assertThat(values, hasSize(0));
394+
EsqlExecutionInfo executionInfo = resp.getExecutionInfo();
395+
assertThat(executionInfo.getClusters().size(), equalTo(1));
396+
assertTrue(executionInfo.isPartial());
397+
398+
var remoteCluster = executionInfo.getCluster(REMOTE_CLUSTER_1);
399+
assertThat(remoteCluster.getStatus(), equalTo(EsqlExecutionInfo.Cluster.Status.SKIPPED));
400+
assertThat(remoteCluster.getFailures().size(), equalTo(1));
401+
var failure = remoteCluster.getFailures().get(0);
402+
assertThat(failure.reason(), containsString("lookup index [values_lookup] is not available in remote cluster [cluster-a]"));
403+
}
404+
377405
setSkipUnavailable(REMOTE_CLUSTER_1, false);
378406
try (
379407
// Using local_tag as key which is not present in remote index
@@ -393,6 +421,20 @@ public void testLookupJoinMissingKey() throws IOException {
393421
// FIXME: verify whether we need to succeed or fail here
394422
assertThat(remoteCluster.getStatus(), equalTo(EsqlExecutionInfo.Cluster.Status.SUCCESSFUL));
395423
}
424+
425+
// Add KEEP clause to try and trick the field-caps result parser
426+
ex = expectThrows(
427+
VerificationException.class,
428+
() -> runQuery("FROM c*:logs-* | LOOKUP JOIN values_lookup ON v | KEEP v", randomBoolean())
429+
);
430+
assertThat(ex.getMessage(), containsString("lookup index [values_lookup] is not available in remote cluster [cluster-a]"));
431+
432+
ex = expectThrows(
433+
VerificationException.class,
434+
() -> runQuery("FROM logs-*,c*:logs-* | LOOKUP JOIN values_lookup ON v | KEEP v", randomBoolean())
435+
);
436+
assertThat(ex.getMessage(), containsString("lookup index [values_lookup] is not available in remote cluster [cluster-a]"));
437+
396438
}
397439

398440
public void testLookupJoinIndexMode() throws IOException {

x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/session/EsqlSession.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -504,6 +504,11 @@ private PreAnalysisResult receiveLookupIndexResolution(
504504
}
505505
if (executionInfo.getClusters().isEmpty() || executionInfo.isCrossClusterSearch() == false) {
506506
// Local only case, still do some checks, since we moved analysis checks here
507+
if (lookupIndexResolution.get().indexNameWithModes().isEmpty()) {
508+
// This is not OK, but we proceed with it as we do with invalid resolution, and it will fail on the verification
509+
// because lookup field will be missing.
510+
return result.addLookupIndexResolution(index, lookupIndexResolution);
511+
}
507512
if (lookupIndexResolution.get().indexNameWithModes().size() > 1) {
508513
throw new VerificationException(
509514
"Lookup Join requires a single lookup mode index; [" + index + "] resolves to multiple indices"

0 commit comments

Comments
 (0)