1414import org .elasticsearch .compute .data .BlockFactory ;
1515import org .elasticsearch .compute .data .ElementType ;
1616import org .elasticsearch .core .Tuple ;
17+ import org .elasticsearch .index .IndexMode ;
1718import org .elasticsearch .index .mapper .MappedFieldType ;
1819import org .elasticsearch .index .query .QueryBuilder ;
1920import org .elasticsearch .index .query .SearchExecutionContext ;
2021import org .elasticsearch .xpack .esql .EsqlIllegalArgumentException ;
2122import org .elasticsearch .xpack .esql .core .expression .AttributeSet ;
2223import org .elasticsearch .xpack .esql .core .expression .Expression ;
2324import org .elasticsearch .xpack .esql .core .expression .FoldContext ;
24- import org .elasticsearch .xpack .esql .core .tree .Node ;
2525import org .elasticsearch .xpack .esql .core .tree .Source ;
2626import org .elasticsearch .xpack .esql .core .type .DataType ;
2727import org .elasticsearch .xpack .esql .core .util .Holder ;
3333import org .elasticsearch .xpack .esql .optimizer .LocalPhysicalPlanOptimizer ;
3434import org .elasticsearch .xpack .esql .plan .logical .EsRelation ;
3535import org .elasticsearch .xpack .esql .plan .logical .Filter ;
36- import org .elasticsearch .xpack .esql .plan .logical .join .Join ;
3736import org .elasticsearch .xpack .esql .plan .physical .AggregateExec ;
3837import org .elasticsearch .xpack .esql .plan .physical .EsSourceExec ;
3938import org .elasticsearch .xpack .esql .plan .physical .EstimatesRowSize ;
4039import org .elasticsearch .xpack .esql .plan .physical .ExchangeExec ;
4140import org .elasticsearch .xpack .esql .plan .physical .ExchangeSinkExec ;
4241import org .elasticsearch .xpack .esql .plan .physical .ExchangeSourceExec ;
4342import org .elasticsearch .xpack .esql .plan .physical .FragmentExec ;
44- import org .elasticsearch .xpack .esql .plan .physical .LookupJoinExec ;
4543import org .elasticsearch .xpack .esql .plan .physical .PhysicalPlan ;
4644import org .elasticsearch .xpack .esql .planner .mapper .LocalMapper ;
4745import org .elasticsearch .xpack .esql .planner .mapper .Mapper ;
5048import org .elasticsearch .xpack .esql .stats .SearchStats ;
5149
5250import java .util .ArrayList ;
53- import java .util .Collection ;
5451import java .util .LinkedHashSet ;
5552import java .util .List ;
5653import java .util .Set ;
5754import java .util .function .Consumer ;
58- import java .util .function .Function ;
5955
6056import static java .util .Arrays .asList ;
6157import static org .elasticsearch .index .mapper .MappedFieldType .FieldExtractPreference .DOC_VALUES ;
@@ -110,7 +106,7 @@ public static Set<String> planConcreteIndices(PhysicalPlan plan) {
110106 return Set .of ();
111107 }
112108 var indices = new LinkedHashSet <String >();
113- forEachFromRelation (plan , relation -> indices .addAll (relation .concreteIndices ()));
109+ forEachRelation (plan , relation -> indices .addAll (relation .concreteIndices ()));
114110 return indices ;
115111 }
116112
@@ -122,42 +118,16 @@ public static String[] planOriginalIndices(PhysicalPlan plan) {
122118 return Strings .EMPTY_ARRAY ;
123119 }
124120 var indices = new LinkedHashSet <String >();
125- forEachFromRelation (plan , relation -> indices .addAll (asList (Strings .commaDelimitedListToStringArray (relation .indexPattern ()))));
121+ forEachRelation (plan , relation -> indices .addAll (asList (Strings .commaDelimitedListToStringArray (relation .indexPattern ()))));
126122 return indices .toArray (String []::new );
127123 }
128124
129- /**
130- * Iterates over the plan and applies the action to each {@link EsRelation} node.
131- * <p>
132- * This method ignores the right side of joins.
133- * </p>
134- */
135- private static void forEachFromRelation (PhysicalPlan plan , Consumer <EsRelation > action ) {
136- // Take the non-join-side fragments
137- forEachUpWithChildren (plan , FragmentExec .class , fragment -> {
138- // Take the non-join-side relations
139- forEachUpWithChildren (
140- fragment .fragment (),
141- EsRelation .class ,
142- action ,
143- node -> node instanceof Join join ? List .of (join .left ()) : node .children ()
144- );
145- }, node -> node instanceof LookupJoinExec join ? List .of (join .left ()) : node .children ());
146- }
147-
148- /**
149- * Similar to {@link Node#forEachUp(Class, Consumer)}, but with a custom callback to get the node children.
150- */
151- private static <T extends Node <T >, E extends T > void forEachUpWithChildren (
152- T node ,
153- Class <E > typeToken ,
154- Consumer <? super E > action ,
155- Function <? super T , Collection <T >> childrenGetter
156- ) {
157- childrenGetter .apply (node ).forEach (c -> forEachUpWithChildren (c , typeToken , action , childrenGetter ));
158- if (typeToken .isInstance (node )) {
159- action .accept (typeToken .cast (node ));
160- }
125+ private static void forEachRelation (PhysicalPlan plan , Consumer <EsRelation > action ) {
126+ plan .forEachDown (FragmentExec .class , f -> f .fragment ().forEachDown (EsRelation .class , r -> {
127+ if (r .indexMode () != IndexMode .LOOKUP ) {
128+ action .accept (r );
129+ }
130+ }));
161131 }
162132
163133 public static PhysicalPlan localPlan (
0 commit comments