7272import org .elasticsearch .xpack .esql .plan .logical .TimeSeriesAggregate ;
7373import org .elasticsearch .xpack .esql .plan .logical .UnresolvedRelation ;
7474import org .elasticsearch .xpack .esql .plan .logical .inference .Completion ;
75+ import org .elasticsearch .xpack .esql .plan .logical .inference .InferencePlan ;
7576import org .elasticsearch .xpack .esql .plan .logical .inference .Rerank ;
7677import org .elasticsearch .xpack .esql .plan .logical .join .LookupJoin ;
7778import org .elasticsearch .xpack .esql .plan .logical .show .ShowInfo ;
@@ -759,16 +760,12 @@ public PlanFactory visitRerankCommand(EsqlBaseParser.RerankCommandContext ctx) {
759760
760761 if (queryText instanceof Literal queryTextLiteral && DataType .isString (queryText .dataType ())) {
761762 if (queryTextLiteral .value () == null ) {
762- throw new ParsingException (
763- source (ctx .queryText ),
764- "Query text cannot be null or undefined in RERANK" ,
765- ctx .queryText .getText ()
766- );
763+ throw new ParsingException (source (ctx .queryText ), "Query cannot be null or undefined in RERANK" , ctx .queryText .getText ());
767764 }
768765 } else {
769766 throw new ParsingException (
770767 source (ctx .queryText ),
771- "RERANK only support string as query text but [{}] cannot be used as string " ,
768+ "Query must be a valid string in RERANK, found [{}]" ,
772769 ctx .queryText .getText ()
773770 );
774771 }
@@ -790,26 +787,16 @@ private Rerank applyRerankOptions(Rerank rerank, EsqlBaseParser.CommandNamedPara
790787 Expression inferenceId = optionsMap .remove (Rerank .INFERENCE_ID_OPTION_NAME );
791788
792789 if (inferenceId != null ) {
793- if (inferenceId instanceof Literal inferenceIdLiteral && DataType .isString (inferenceId .dataType ())) {
794- if (inferenceIdLiteral .value () == null ) {
795- throw new ParsingException (
796- inferenceId .source (),
797- "[{}] option cannot be null or undefined in RERANK" ,
798- Rerank .INFERENCE_ID_OPTION_NAME
799- );
800- }
801- rerank = rerank .withInferenceId (inferenceId );
802- } else {
803- throw new ParsingException (
804- inferenceId .source (),
805- "Option [{}] only support string in RERANK but [{}] cannot be used as string" ,
806- Rerank .INFERENCE_ID_OPTION_NAME
807- );
808- }
790+ rerank = applyInferenceId (rerank , inferenceId );
809791 }
810792
811793 if (optionsMap .isEmpty () == false ) {
812- throw new ParsingException (source (ctx ), "Unknown option [{}] in RERANK command" , optionsMap .keySet ().stream ().findAny ().get ());
794+ throw new ParsingException (
795+ source (ctx ),
796+ "Inavalid option [{}] in RERANK, expected one of [{}]" ,
797+ optionsMap .keySet ().stream ().findAny ().get (),
798+ rerank .validOptionNames ()
799+ );
813800 }
814801
815802 return rerank ;
@@ -840,35 +827,37 @@ private Completion applyCompletionOptions(Completion completion, EsqlBaseParser.
840827
841828 Expression inferenceId = optionsMap .remove (Completion .INFERENCE_ID_OPTION_NAME );
842829 if (inferenceId != null ) {
843- if (inferenceId instanceof Literal inferenceIdLiteral && DataType .isString (inferenceId .dataType ())) {
844- if (inferenceIdLiteral .value () == null ) {
845- throw new ParsingException (
846- inferenceId .source (),
847- "[{}] option cannot be null or undefined in COMPLETION" ,
848- Completion .INFERENCE_ID_OPTION_NAME
849- );
850- }
851- completion = completion .withInferenceId (inferenceId );
852- } else {
853- throw new ParsingException (
854- inferenceId .source (),
855- "Option [{}] only support string in COMPLETION but [{}] cannot be used as string" ,
856- Completion .INFERENCE_ID_OPTION_NAME
857- );
858- }
830+ completion = applyInferenceId (completion , inferenceId );
859831 }
860832
861833 if (optionsMap .isEmpty () == false ) {
862834 throw new ParsingException (
863835 source (ctx ),
864- "Unknown option [{}] in Completion command" ,
865- optionsMap .keySet ().stream ().findAny ().get ()
836+ "Inavalid option [{}] in COMPLETION, expected one of [{}]" ,
837+ optionsMap .keySet ().stream ().findAny ().get (),
838+ completion .validOptionNames ()
866839 );
867840 }
868841
869842 return completion ;
870843 }
871844
845+ private <InferencePlanType extends InferencePlan <InferencePlanType >> InferencePlanType applyInferenceId (
846+ InferencePlanType inferencePlan ,
847+ Expression inferenceId
848+ ) {
849+ if ((inferenceId instanceof Literal && DataType .isString (inferenceId .dataType ())) == false ) {
850+ throw new ParsingException (
851+ inferenceId .source (),
852+ "Option [{}] must be a valid string, found [{}]" ,
853+ Completion .INFERENCE_ID_OPTION_NAME ,
854+ inferenceId .source ().text ()
855+ );
856+ }
857+
858+ return inferencePlan .withInferenceId (inferenceId );
859+ }
860+
872861 public PlanFactory visitSampleCommand (EsqlBaseParser .SampleCommandContext ctx ) {
873862 Source source = source (ctx );
874863 Object val = expression (ctx .probability ).fold (FoldContext .small () /* TODO remove me */ );
0 commit comments