From cc213ee57408ebf3c0a8190ac9e4fec46c9d8b03 Mon Sep 17 00:00:00 2001 From: "ievgen.degtiarenko" Date: Thu, 4 Sep 2025 10:40:32 +0200 Subject: [PATCH] Resolve main indices before lookup Lookup indices must be resolved for every remote cluster that is going to be queried. Today list of remotes is derived from the index expression. With CPS/flat expressions remotes should be derived from the resolved main indices. This change moves lookup index resolution after main index resolution so that it will be possible to use main index resolution when deriving lookup indices remotes. --- .../xpack/esql/session/EsqlSession.java | 31 +++++++++++++------ 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/session/EsqlSession.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/session/EsqlSession.java index 555fab6df0c47..3d0a4ab26b8d6 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/session/EsqlSession.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/session/EsqlSession.java @@ -78,6 +78,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; +import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; @@ -372,22 +373,34 @@ public void analyzedPlan( return; } - PreAnalyzer.PreAnalysis preAnalysis = preAnalyzer.preAnalyze(parsed); + var preAnalysis = preAnalyzer.preAnalyze(parsed); EsqlCCSUtils.initCrossClusterState(indicesExpressionGrouper, verifier.licenseState(), preAnalysis.indices, executionInfo); - var listener = SubscribableListener. // + SubscribableListener. // newForked(l -> enrichPolicyResolver.resolvePolicies(preAnalysis.enriches, executionInfo, l)) .andThenApply(enrichResolution -> FieldNameUtils.resolveFieldNames(parsed, enrichResolution)) - .andThen((l, preAnalysisResult) -> resolveInferences(parsed, preAnalysisResult, l)); - // first resolve the lookup indices, then the main indices - for (var index : preAnalysis.lookupIndices) { - listener = listener.andThen((l, preAnalysisResult) -> preAnalyzeLookupIndex(index, preAnalysisResult, executionInfo, l)); - } - listener.andThen((l, result) -> preAnalyzeMainIndices(preAnalysis, executionInfo, result, requestFilter, l)) - .andThen((l, result) -> analyzeWithRetry(parsed, requestFilter, preAnalysis, executionInfo, result, l)) + .andThen((l, r) -> resolveInferences(parsed, r, l)) + .andThen((l, r) -> preAnalyzeMainIndices(preAnalysis, executionInfo, r, requestFilter, l)) + .andThen((l, r) -> preAnalyzeLookupIndices(preAnalysis.lookupIndices.iterator(), r, executionInfo, l)) + .andThen((l, r) -> analyzeWithRetry(parsed, requestFilter, preAnalysis, executionInfo, r, l)) .addListener(logicalPlanListener); } + private void preAnalyzeLookupIndices( + Iterator lookupIndices, + PreAnalysisResult preAnalysisResult, + EsqlExecutionInfo executionInfo, + ActionListener listener + ) { + if (lookupIndices.hasNext()) { + preAnalyzeLookupIndex(lookupIndices.next(), preAnalysisResult, executionInfo, listener.delegateFailureAndWrap((l, r) -> { + preAnalyzeLookupIndices(lookupIndices, r, executionInfo, l); + })); + } else { + listener.onResponse(preAnalysisResult); + } + } + private void preAnalyzeLookupIndex( IndexPattern lookupIndexPattern, PreAnalysisResult result,