5252import com .google .common .collect .ImmutableMap ;
5353import java .util .Arrays ;
5454import java .util .Collections ;
55+ import java .util .HashMap ;
5556import java .util .List ;
57+ import java .util .Map ;
5658import java .util .stream .Collectors ;
5759import org .antlr .v4 .runtime .RuleContext ;
5860import org .apache .commons .lang3 .tuple .ImmutablePair ;
7981import org .opensearch .sql .ast .expression .When ;
8082import org .opensearch .sql .ast .expression .WindowFunction ;
8183import org .opensearch .sql .ast .tree .Sort .SortOption ;
84+ import org .opensearch .sql .catalog .model .auth .AuthenticationType ;
8285import org .opensearch .sql .common .utils .StringUtils ;
8386import org .opensearch .sql .exception .SemanticCheckException ;
8487import org .opensearch .sql .expression .function .BuiltinFunctionName ;
@@ -403,14 +406,11 @@ public UnresolvedExpression visitMultiFieldRelevanceFunction(
403406 MultiFieldRelevanceFunctionContext ctx ) {
404407 // To support alternate syntax for MULTI_MATCH like
405408 // 'MULTI_MATCH('query'='query_val', 'fields'='*fields_val')'
406- if ((StringUtils .unquoteText (ctx .multiFieldRelevanceFunctionName ().getText ().toUpperCase ())
407- .equals (BuiltinFunctionName .MULTI_MATCH .toString ())
408- || StringUtils .unquoteText (ctx .multiFieldRelevanceFunctionName ().getText ().toUpperCase ())
409- .equals (BuiltinFunctionName .MULTIMATCH .toString ())
410- || StringUtils .unquoteText (ctx .multiFieldRelevanceFunctionName ().getText ().toUpperCase ())
411- .equals (BuiltinFunctionName .MULTIMATCHQUERY .toString ()))
412- && ! ctx .getRuleContexts (OpenSearchSQLParser .AlternateMultiMatchQueryContext .class )
413- .isEmpty ()) {
409+ String funcName = StringUtils .unquoteText (ctx .multiFieldRelevanceFunctionName ().getText ());
410+ if ((funcName .equalsIgnoreCase (BuiltinFunctionName .MULTI_MATCH .toString ())
411+ || funcName .equalsIgnoreCase (BuiltinFunctionName .MULTIMATCH .toString ())
412+ || funcName .equalsIgnoreCase (BuiltinFunctionName .MULTIMATCHQUERY .toString ()))
413+ && ! ctx .getRuleContexts (OpenSearchSQLParser .AlternateMultiMatchQueryContext .class ).isEmpty ()) {
414414 return new Function (
415415 ctx .multiFieldRelevanceFunctionName ().getText ().toLowerCase (),
416416 alternateMultiMatchArguments (ctx ));
@@ -456,9 +456,13 @@ private QualifiedName visitIdentifiers(List<IdentContext> identifiers) {
456456
457457 private void fillRelevanceArgs (List <OpenSearchSQLParser .RelevanceArgContext > args ,
458458 ImmutableList .Builder <UnresolvedExpression > builder ) {
459- args .forEach (v -> builder .add (new UnresolvedArgument (
460- v .relevanceArgName ().getText ().toLowerCase (), new Literal (StringUtils .unquoteText (
461- v .relevanceArgValue ().getText ()), DataType .STRING ))));
459+ // To support old syntax we must support argument keys as quoted strings.
460+ args .forEach (v -> builder .add (v .relevanceArgName () != null
461+ ? new UnresolvedArgument (v .relevanceArgName ().getText ().toLowerCase (),
462+ new Literal (StringUtils .unquoteText (v .relevanceArgValue ().getText ()),
463+ DataType .STRING ))
464+ : new UnresolvedArgument (StringUtils .unquoteText (v .argName .getText ()).toLowerCase (),
465+ new Literal (StringUtils .unquoteText (v .argVal .getText ()), DataType .STRING ))));
462466 }
463467
464468 private List <UnresolvedExpression > noFieldRelevanceArguments (
@@ -516,13 +520,19 @@ private List<UnresolvedExpression> alternateMultiMatchArguments(
516520 // all the arguments are defaulted to string values
517521 // to skip environment resolving and function signature resolving
518522 ImmutableList .Builder <UnresolvedExpression > builder = ImmutableList .builder ();
519- ctx .getRuleContexts (OpenSearchSQLParser .AlternateMultiMatchFieldContext .class )
520- .stream ().findFirst ().ifPresent (
521- arg ->
522- builder .add (new UnresolvedArgument ("fields" ,
523- new RelevanceFieldList (
524- ImmutableMap .of (StringUtils .unquoteText (arg .argVal .getText ()), 1F ))))
525- );
523+ Map <String , Float > fieldAndWeightMap = new HashMap <>();
524+
525+ String [] fieldAndWeights = StringUtils .unquoteText (
526+ ctx .getRuleContexts (OpenSearchSQLParser .AlternateMultiMatchFieldContext .class )
527+ .stream ().findFirst ().get ().argVal .getText ()).split ("," );
528+
529+ for (var fieldAndWeight : fieldAndWeights ) {
530+ String [] splitFieldAndWeights = fieldAndWeight .split ("\\ ^" );
531+ fieldAndWeightMap .put (splitFieldAndWeights [0 ],
532+ splitFieldAndWeights .length > 1 ? Float .parseFloat (splitFieldAndWeights [1 ]) : 1F );
533+ }
534+ builder .add (new UnresolvedArgument ("fields" ,
535+ new RelevanceFieldList (fieldAndWeightMap )));
526536
527537 ctx .getRuleContexts (OpenSearchSQLParser .AlternateMultiMatchQueryContext .class )
528538 .stream ().findFirst ().ifPresent (
@@ -531,14 +541,7 @@ private List<UnresolvedExpression> alternateMultiMatchArguments(
531541 new Literal (StringUtils .unquoteText (arg .argVal .getText ()), DataType .STRING )))
532542 );
533543
534- // To support old syntax we must support argument keys as quoted strings.
535- ctx .getRuleContexts (OpenSearchSQLParser .AlternateMultiMatchOptionalArgContext .class )
536- .forEach (v -> builder .add (v .relevanceArg () != null
537- ? new UnresolvedArgument (v .relevanceArg ().relevanceArgName ().getText ().toLowerCase (),
538- new Literal (StringUtils .unquoteText (v .relevanceArg ().relevanceArgValue ().getText ()),
539- DataType .STRING ))
540- : new UnresolvedArgument (StringUtils .unquoteText (v .argName .getText ()).toLowerCase (),
541- new Literal (StringUtils .unquoteText (v .argVal .getText ()), DataType .STRING ))));
544+ fillRelevanceArgs (ctx .relevanceArg (), builder );
542545
543546 return builder .build ();
544547 }
0 commit comments