55 */
66package org .elasticsearch .xpack .sql .analysis .analyzer ;
77
8- import org .elasticsearch .xpack . sql . analysis . AnalysisException ;
8+ import org .elasticsearch .common . logging . LoggerMessageFormat ;
99import org .elasticsearch .xpack .sql .analysis .analyzer .Verifier .Failure ;
1010import org .elasticsearch .xpack .sql .analysis .index .IndexResolution ;
1111import org .elasticsearch .xpack .sql .capabilities .Resolvables ;
1616import org .elasticsearch .xpack .sql .expression .Expression ;
1717import org .elasticsearch .xpack .sql .expression .Expressions ;
1818import org .elasticsearch .xpack .sql .expression .FieldAttribute ;
19- import org .elasticsearch .xpack .sql .expression .Literal ;
19+ import org .elasticsearch .xpack .sql .expression .Foldables ;
2020import org .elasticsearch .xpack .sql .expression .NamedExpression ;
2121import org .elasticsearch .xpack .sql .expression .Order ;
2222import org .elasticsearch .xpack .sql .expression .SubQueryExpression ;
@@ -516,6 +516,7 @@ protected LogicalPlan rule(LogicalPlan plan) {
516516 int max = ordinalReference .size ();
517517
518518 for (Order order : orderBy .order ()) {
519+ Expression child = order .child ();
519520 Integer ordinal = findOrdinal (order .child ());
520521 if (ordinal != null ) {
521522 changed = true ;
@@ -524,7 +525,11 @@ protected LogicalPlan rule(LogicalPlan plan) {
524525 order .nullsPosition ()));
525526 }
526527 else {
527- throw new AnalysisException (order , "Invalid %d specified in OrderBy (valid range is [1, %d])" , ordinal , max );
528+ // report error
529+ String message = LoggerMessageFormat .format ("Invalid ordinal [{}] specified in [{}] (valid range is [1, {}])" ,
530+ ordinal , orderBy .sourceText (), max );
531+ UnresolvedAttribute ua = new UnresolvedAttribute (child .source (), orderBy .sourceText (), null , message );
532+ newOrder .add (new Order (order .source (), ua , order .direction (), order .nullsPosition ()));
528533 }
529534 }
530535 else {
@@ -551,17 +556,24 @@ protected LogicalPlan rule(LogicalPlan plan) {
551556 Integer ordinal = findOrdinal (exp );
552557 if (ordinal != null ) {
553558 changed = true ;
559+ String errorMessage = null ;
554560 if (ordinal > 0 && ordinal <= max ) {
555561 NamedExpression reference = aggregates .get (ordinal - 1 );
556562 if (containsAggregate (reference )) {
557- throw new AnalysisException (exp , "Group ordinal " + ordinal + " refers to an aggregate function "
558- + reference .nodeName () + " which is not compatible/allowed with GROUP BY" );
563+ errorMessage = LoggerMessageFormat .format (
564+ "Ordinal [{}] in [{}] refers to an invalid argument, aggregate function [{}]" ,
565+ ordinal , agg .sourceText (), reference .sourceText ());
566+
567+ } else {
568+ newGroupings .add (reference );
559569 }
560- newGroupings .add (reference );
561570 }
562571 else {
563- throw new AnalysisException (exp , "Invalid ordinal " + ordinal
564- + " specified in Aggregate (valid range is [1, " + max + "])" );
572+ errorMessage = LoggerMessageFormat .format ("Invalid ordinal [{}] specified in [{}] (valid range is [1, {}])" ,
573+ ordinal , agg .sourceText (), max );
574+ }
575+ if (errorMessage != null ) {
576+ newGroupings .add (new UnresolvedAttribute (exp .source (), agg .sourceText (), null , errorMessage ));
565577 }
566578 }
567579 else {
@@ -576,10 +588,9 @@ protected LogicalPlan rule(LogicalPlan plan) {
576588 }
577589
578590 private Integer findOrdinal (Expression expression ) {
579- if (expression instanceof Literal ) {
580- Literal l = (Literal ) expression ;
581- if (l .dataType ().isInteger ()) {
582- Object v = l .value ();
591+ if (expression .foldable ()) {
592+ if (expression .dataType ().isInteger ()) {
593+ Object v = Foldables .valueOf (expression );
583594 if (v instanceof Number ) {
584595 return Integer .valueOf (((Number ) v ).intValue ());
585596 }
0 commit comments