1212import org .elasticsearch .common .io .stream .NamedWriteableRegistry ;
1313import org .elasticsearch .common .io .stream .StreamInput ;
1414import org .elasticsearch .common .io .stream .StreamOutput ;
15+ import org .elasticsearch .common .io .stream .Writeable ;
1516import org .elasticsearch .compute .data .Block ;
1617import org .elasticsearch .compute .data .Page ;
1718import org .elasticsearch .compute .operator .AsyncOperator ;
2728import org .elasticsearch .xpack .esql .core .expression .NamedExpression ;
2829import org .elasticsearch .xpack .esql .core .tree .Source ;
2930import org .elasticsearch .xpack .esql .core .type .DataType ;
31+ import org .elasticsearch .xpack .esql .planner .Layout ;
3032
3133import java .io .IOException ;
3234import java .util .Iterator ;
3739
3840// TODO rename package
3941public final class LookupFromIndexOperator extends AsyncOperator <LookupFromIndexOperator .OngoingJoin > {
42+ public record MatchConfig (FieldAttribute .FieldName fieldName , int channel , DataType type ) implements Writeable {
43+ public MatchConfig (FieldAttribute match , Layout .ChannelAndType input ) {
44+ // TODO: Using exactAttribute was supposed to handle TEXT fields with KEYWORD subfields - but we don't allow these in lookup
45+ // indices, so the call to exactAttribute looks redundant now.
46+ this (match .exactAttribute ().fieldName (), input .channel (), input .type ());
47+ }
48+
49+ public MatchConfig (StreamInput in ) throws IOException {
50+ this (new FieldAttribute .FieldName (in .readString ()), in .readInt (), DataType .readFrom (in ));
51+ }
52+
53+ @ Override
54+ public void writeTo (StreamOutput out ) throws IOException {
55+ out .writeString (fieldName .string ());
56+ out .writeInt (channel );
57+ type .writeTo (out );
58+ }
59+
60+ }
61+
4062 public record Factory (
63+ List <MatchConfig > matchFields ,
4164 String sessionId ,
4265 CancellableTask parentTask ,
4366 int maxOutstandingRequests ,
44- int inputChannel ,
4567 Function <DriverContext , LookupFromIndexService > lookupService ,
46- DataType inputDataType ,
4768 String lookupIndexPattern ,
4869 String lookupIndex ,
49- FieldAttribute .FieldName matchField ,
5070 List <NamedExpression > loadFields ,
5171 Source source
5272 ) implements OperatorFactory {
5373 @ Override
5474 public String describe () {
55- return "LookupOperator[index="
56- + lookupIndex
57- + " input_type="
58- + inputDataType
59- + " match_field="
60- + matchField .string ()
61- + " load_fields="
62- + loadFields
63- + " inputChannel="
64- + inputChannel
65- + "]" ;
75+ StringBuilder stringBuilder = new StringBuilder ();
76+ stringBuilder .append ("LookupOperator[index=" ).append (lookupIndex ).append (" load_fields=" ).append (loadFields );
77+ for (MatchConfig matchField : matchFields ) {
78+ stringBuilder .append (" input_type=" )
79+ .append (matchField .type )
80+ .append (" match_field=" )
81+ .append (matchField .fieldName .string ())
82+ .append (" inputChannel=" )
83+ .append (matchField .channel );
84+ }
85+ stringBuilder .append ("]" );
86+ return stringBuilder .toString ();
6687 }
6788
6889 @ Override
6990 public Operator get (DriverContext driverContext ) {
7091 return new LookupFromIndexOperator (
92+ matchFields ,
7193 sessionId ,
7294 driverContext ,
7395 parentTask ,
7496 maxOutstandingRequests ,
75- inputChannel ,
7697 lookupService .apply (driverContext ),
77- inputDataType ,
7898 lookupIndexPattern ,
7999 lookupIndex ,
80- matchField .string (),
81100 loadFields ,
82101 source
83102 );
@@ -87,14 +106,12 @@ public Operator get(DriverContext driverContext) {
87106 private final LookupFromIndexService lookupService ;
88107 private final String sessionId ;
89108 private final CancellableTask parentTask ;
90- private final int inputChannel ;
91- private final DataType inputDataType ;
92109 private final String lookupIndexPattern ;
93110 private final String lookupIndex ;
94- private final String matchField ;
95111 private final List <NamedExpression > loadFields ;
96112 private final Source source ;
97113 private long totalTerms = 0L ;
114+ private List <MatchConfig > matchFields ;
98115 /**
99116 * Total number of pages emitted by this {@link Operator}.
100117 */
@@ -105,43 +122,47 @@ public Operator get(DriverContext driverContext) {
105122 private OngoingJoin ongoing = null ;
106123
107124 public LookupFromIndexOperator (
125+ List <MatchConfig > matchFields ,
108126 String sessionId ,
109127 DriverContext driverContext ,
110128 CancellableTask parentTask ,
111129 int maxOutstandingRequests ,
112- int inputChannel ,
113130 LookupFromIndexService lookupService ,
114- DataType inputDataType ,
115131 String lookupIndexPattern ,
116132 String lookupIndex ,
117- String matchField ,
118133 List <NamedExpression > loadFields ,
119134 Source source
120135 ) {
121136 super (driverContext , lookupService .getThreadContext (), maxOutstandingRequests );
137+ this .matchFields = matchFields ;
122138 this .sessionId = sessionId ;
123139 this .parentTask = parentTask ;
124- this .inputChannel = inputChannel ;
125140 this .lookupService = lookupService ;
126- this .inputDataType = inputDataType ;
127141 this .lookupIndexPattern = lookupIndexPattern ;
128142 this .lookupIndex = lookupIndex ;
129- this .matchField = matchField ;
130143 this .loadFields = loadFields ;
131144 this .source = source ;
132145 }
133146
134147 @ Override
135148 protected void performAsync (Page inputPage , ActionListener <OngoingJoin > listener ) {
136- final Block inputBlock = inputPage .getBlock (inputChannel );
137- totalTerms += inputBlock .getTotalValueCount ();
149+ // what is happening here?
150+ // should I be getting multiple bloks, and send them using the LookupFromIndexService.Request
151+ // is the totalTerms supposed to be the total number of terms in all blocks?
152+ Block [] inputBlockArray = new Block [matchFields .size ()];
153+ for (int i = 0 ; i < matchFields .size (); i ++) {
154+ MatchConfig matchField = matchFields .get (i );
155+ int inputChannel = matchField .channel ;
156+ final Block inputBlock = inputPage .getBlock (inputChannel );
157+ totalTerms += inputBlock .getTotalValueCount ();
158+ inputBlockArray [i ] = inputBlock ;
159+ }
138160 LookupFromIndexService .Request request = new LookupFromIndexService .Request (
139161 sessionId ,
140162 lookupIndex ,
141163 lookupIndexPattern ,
142- inputDataType ,
143- matchField ,
144- new Page (inputBlock ),
164+ matchFields ,
165+ new Page (inputBlockArray ),
145166 loadFields ,
146167 source
147168 );
@@ -190,17 +211,18 @@ protected void releaseFetchedOnAnyThread(OngoingJoin ongoingJoin) {
190211
191212 @ Override
192213 public String toString () {
193- return "LookupOperator[index="
194- + lookupIndex
195- + " input_type="
196- + inputDataType
197- + " match_field="
198- + matchField
199- + " load_fields="
200- + loadFields
201- + " inputChannel="
202- + inputChannel
203- + "]" ;
214+ StringBuilder stringBuilder = new StringBuilder ();
215+ stringBuilder .append ("LookupOperator[index=" ).append (lookupIndex ).append (" load_fields=" ).append (loadFields );
216+ for (MatchConfig matchField : matchFields ) {
217+ stringBuilder .append (" input_type=" )
218+ .append (matchField .type )
219+ .append (" match_field=" )
220+ .append (matchField .fieldName .string ())
221+ .append (" inputChannel=" )
222+ .append (matchField .channel );
223+ }
224+ stringBuilder .append ("]" );
225+ return stringBuilder .toString ();
204226 }
205227
206228 @ Override
0 commit comments