88package org .elasticsearch .xpack .esql .action ;
99
1010import org .elasticsearch .common .settings .Settings ;
11- import org .elasticsearch .common .util .Maps ;
1211import org .elasticsearch .core .TimeValue ;
1312import org .elasticsearch .index .query .AbstractQueryBuilder ;
1413import org .elasticsearch .xcontent .ObjectParser ;
@@ -90,19 +89,6 @@ String fields() {
9089 private static final ObjectParser <EsqlQueryRequest , Void > SYNC_PARSER = objectParserSync (EsqlQueryRequest ::syncEsqlQueryRequest );
9190 private static final ObjectParser <EsqlQueryRequest , Void > ASYNC_PARSER = objectParserAsync (EsqlQueryRequest ::asyncEsqlQueryRequest );
9291
93- private enum ParamParsingKey {
94- VALUE ,
95- KIND
96- }
97-
98- private static final Map <String , ParamParsingKey > paramParsingKeys = Maps .newMapWithExpectedSize (ParamParsingKey .values ().length );
99-
100- static {
101- for (ParamParsingKey e : ParamParsingKey .values ()) {
102- paramParsingKeys .put (e .name (), e );
103- }
104- }
105-
10692 /** Parses a synchronous request. */
10793 static EsqlQueryRequest parseSync (XContentParser parser ) {
10894 return SYNC_PARSER .apply (parser , null );
@@ -180,25 +166,21 @@ private static QueryParams parseParams(XContentParser p) throws IOException {
180166 );
181167 }
182168 for (Map .Entry <String , Object > entry : param .fields .entrySet ()) {
183- ParserUtils .ParamClassification classification ;
169+ ParserUtils .ParamClassification classification = null ;
170+ paramValue = null ;
184171 String paramName = entry .getKey ();
185172 checkParamNameValidity (paramName , errors , loc );
186173
187- if (EsqlCapabilities .Cap .NAMED_PARAMETER_FOR_FIELD_AND_FUNCTION_NAMES .isEnabled ()
188- && entry .getValue () instanceof Map <?, ?> values ) {// parameter specified as key:value pairs
189- Map <ParamParsingKey , Object > paramElements = Maps .newMapWithExpectedSize (2 );
190- for (Object keyName : values .keySet ()) {
191- ParamParsingKey paramType = checkParamValueKeysValidity (keyName .toString (), errors , loc );
192- if (paramType != null ) {
193- paramElements .put (paramType , values .get (keyName ));
174+ if (EsqlCapabilities .Cap .NAMED_PARAMETER_FOR_FIELD_AND_FUNCTION_NAMES_SIMPLIFIED_SYNTAX .isEnabled ()
175+ && entry .getValue () instanceof Map <?, ?> value ) {// parameter specified as a key:value pair
176+ checkParamValueSize (paramName , value , loc , errors );
177+ for (Object keyName : value .keySet ()) {
178+ classification = getParamClassification (keyName .toString (), errors , loc );
179+ if (classification != null ) {
180+ paramValue = value .get (keyName );
181+ checkParamValueValidity (classification , paramValue , loc , errors );
194182 }
195183 }
196- paramValue = paramElements .get (ParamParsingKey .VALUE );
197- if (paramValue == null && values .size () > 1 ) { // require non-null value for identifier and pattern
198- errors .add (new XContentParseException (loc , "[" + entry + "] does not have a value specified" ));
199- }
200-
201- classification = getClassificationForParam (paramElements , loc , errors );
202184 } else {// parameter specifies as a value only
203185 paramValue = entry .getValue ();
204186 classification = VALUE ;
@@ -280,51 +262,67 @@ private static void checkParamNameValidity(String name, List<XContentParseExcept
280262 }
281263 }
282264
283- private static ParamParsingKey checkParamValueKeysValidity (
265+ private static void checkParamValueSize (
266+ String paramName ,
267+ Map <?, ?> paramValue ,
268+ XContentLocation loc ,
269+ List <XContentParseException > errors
270+ ) {
271+ if (paramValue .size () == 1 ) {
272+ return ;
273+ }
274+ String errorMessage ;
275+ if (paramValue .isEmpty ()) {
276+ errorMessage = " has no valid param attribute" ;
277+ } else {
278+ errorMessage = " has multiple param attributes ["
279+ + paramValue .keySet ().stream ().map (Object ::toString ).collect (Collectors .joining (", " ))
280+ + "]" ;
281+ }
282+ errors .add (
283+ new XContentParseException (
284+ loc ,
285+ "["
286+ + paramName
287+ + "]"
288+ + errorMessage
289+ + ", only one of "
290+ + Arrays .stream (ParserUtils .ParamClassification .values ())
291+ .map (ParserUtils .ParamClassification ::name )
292+ .collect (Collectors .joining (", " ))
293+ + " can be defined in a param"
294+ )
295+ );
296+ }
297+
298+ private static ParserUtils .ParamClassification getParamClassification (
284299 String paramKeyName ,
285300 List <XContentParseException > errors ,
286301 XContentLocation loc
287302 ) {
288- ParamParsingKey paramType = paramParsingKeys .get (paramKeyName .toUpperCase (Locale .ROOT ));
303+ ParserUtils . ParamClassification paramType = paramClassifications .get (paramKeyName .toUpperCase (Locale .ROOT ));
289304 if (paramType == null ) {
290305 errors .add (
291306 new XContentParseException (
292307 loc ,
293308 "["
294309 + paramKeyName
295310 + "] is not a valid param attribute, a valid attribute is any of "
296- + Arrays .stream (ParamParsingKey .values ()).map (ParamParsingKey ::name ).collect (Collectors .joining (", " ))
311+ + Arrays .stream (ParserUtils .ParamClassification .values ())
312+ .map (ParserUtils .ParamClassification ::name )
313+ .collect (Collectors .joining (", " ))
297314 )
298315 );
299316 }
300317 return paramType ;
301318 }
302319
303- private static ParserUtils .ParamClassification getClassificationForParam (
304- Map <ParamParsingKey , Object > paramElements ,
320+ private static void checkParamValueValidity (
321+ ParserUtils .ParamClassification classification ,
322+ Object value ,
305323 XContentLocation loc ,
306324 List <XContentParseException > errors
307325 ) {
308- Object value = paramElements .get (ParamParsingKey .VALUE );
309- Object kind = paramElements .get (ParamParsingKey .KIND );
310- ParserUtils .ParamClassification classification = VALUE ;
311- if (kind != null ) {
312- classification = paramClassifications .get (kind .toString ().toUpperCase (Locale .ROOT ));
313- if (classification == null ) {
314- errors .add (
315- new XContentParseException (
316- loc ,
317- "["
318- + kind
319- + "] is not a valid param kind, a valid kind is any of "
320- + Arrays .stream (ParserUtils .ParamClassification .values ())
321- .map (ParserUtils .ParamClassification ::name )
322- .collect (Collectors .joining (", " ))
323- )
324- );
325- }
326- }
327-
328326 // If a param is an "identifier" or a "pattern", validate it is a string.
329327 // If a param is a "pattern", validate it contains *.
330328 if (classification == IDENTIFIER || classification == PATTERN ) {
@@ -345,6 +343,5 @@ private static ParserUtils.ParamClassification getClassificationForParam(
345343 );
346344 }
347345 }
348- return classification ;
349346 }
350347}
0 commit comments