6868import static org .elasticsearch .index .query .MatchQueryBuilder .ZERO_TERMS_QUERY_FIELD ;
6969import static org .elasticsearch .xpack .esql .core .expression .TypeResolutions .ParamOrdinal .FIRST ;
7070import static org .elasticsearch .xpack .esql .core .expression .TypeResolutions .ParamOrdinal .SECOND ;
71+ import static org .elasticsearch .xpack .esql .core .expression .TypeResolutions .ParamOrdinal .THIRD ;
7172import static org .elasticsearch .xpack .esql .core .expression .TypeResolutions .isFoldable ;
7273import static org .elasticsearch .xpack .esql .core .expression .TypeResolutions .isMapExpression ;
7374import static org .elasticsearch .xpack .esql .core .expression .TypeResolutions .isNotNull ;
@@ -277,8 +278,12 @@ public String getWriteableName() {
277278 }
278279
279280 @ Override
280- protected TypeResolution resolveNonQueryParamTypes () {
281- TypeResolution resolution = isNotNull (field , sourceText (), FIRST ).and (
281+ protected TypeResolution resolveParams () {
282+ return resolveField ().and (resolveQuery ()).and (resolveOptions ()).and (checkParamCompatibility ());
283+ }
284+
285+ private TypeResolution resolveField () {
286+ return isNotNull (field , sourceText (), FIRST ).and (
282287 isType (
283288 field ,
284289 FIELD_DATA_TYPES ::contains ,
@@ -287,14 +292,16 @@ protected TypeResolution resolveNonQueryParamTypes() {
287292 "keyword, text, boolean, date, date_nanos, double, integer, ip, long, unsigned_long, version"
288293 )
289294 );
290- if (resolution .unresolved ()) {
291- return resolution ;
292- }
295+ }
293296
294- // TODO Extract common logic for validating options
297+ private TypeResolution resolveOptions () {
295298 if (options () != null && EsqlCapabilities .Cap .MATCH_FUNCTION_OPTIONS .isEnabled ()) {
299+ TypeResolution resolution = isNotNull (options (), sourceText (), THIRD );
300+ if (resolution .unresolved ()) {
301+ return resolution ;
302+ }
296303 // MapExpression does not have a DataType associated with it
297- resolution = isMapExpression (options (), sourceText (), SECOND );
304+ resolution = isMapExpression (options (), sourceText (), THIRD );
298305 if (resolution .unresolved ()) {
299306 return resolution ;
300307 }
@@ -308,6 +315,16 @@ protected TypeResolution resolveNonQueryParamTypes() {
308315 return TypeResolution .TYPE_RESOLVED ;
309316 }
310317
318+ private TypeResolution resolveQuery () {
319+ return isType (
320+ query (),
321+ QUERY_DATA_TYPES ::contains ,
322+ sourceText (),
323+ queryParamOrdinal (),
324+ "keyword, boolean, date, date_nanos, double, integer, ip, long, unsigned_long, version"
325+ ).and (isNotNullAndFoldable (query (), sourceText (), SECOND ));
326+ }
327+
311328 private Map <String , Object > parseOptions () throws InvalidArgumentException {
312329 Map <String , Object > matchOptions = new HashMap <>();
313330 // Match is lenient by default to avoid failing on incompatible types
@@ -347,19 +364,7 @@ private Map<String, Object> parseOptions() throws InvalidArgumentException {
347364 return matchOptions ;
348365 }
349366
350- @ Override
351- protected TypeResolution resolveQueryParamType () {
352- return isType (
353- query (),
354- QUERY_DATA_TYPES ::contains ,
355- sourceText (),
356- queryParamOrdinal (),
357- "keyword, boolean, date, date_nanos, double, integer, ip, long, unsigned_long, version"
358- ).and (isNotNullAndFoldable (query (), sourceText (), queryParamOrdinal ()));
359- }
360-
361- @ Override
362- protected TypeResolution checkParamCompatibility () {
367+ private TypeResolution checkParamCompatibility () {
363368 DataType fieldType = field ().dataType ();
364369 DataType queryType = query ().dataType ();
365370
0 commit comments