Skip to content

Commit f262f89

Browse files
ezrahaleva-msftneildshealsur
authored
Query: Adds FIRST and LAST Scalar Expressions (#3629)
* Add FIRST and LAST objects and update visitors * add FIRST LAST evaluation and update offline engine visitors * Add FIRST and LAST to parser * update another visitor * Fix typo * fix typo * added new tests and baselines * cleaning * cleaning --------- Co-authored-by: neildsh <[email protected]> Co-authored-by: Matias Quaranta <[email protected]>
1 parent d6e04a9 commit f262f89

32 files changed

+1633
-741
lines changed

Microsoft.Azure.Cosmos/src/Query/Core/Parser/CstToAstVisitor.cs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -568,6 +568,16 @@ public override SqlObject VisitExistsScalarExpression([NotNull] sqlParser.Exists
568568
return SqlExistsScalarExpression.Create(subquery);
569569
}
570570

571+
public override SqlObject VisitFirstScalarExpression([NotNull] sqlParser.FirstScalarExpressionContext context)
572+
{
573+
Contract.Requires(context != null);
574+
// K_FIRST '(' sql_query ')'
575+
Contract.Requires(context.ChildCount == 4);
576+
577+
SqlQuery subquery = (SqlQuery)this.Visit(context.children[2]);
578+
return SqlFirstScalarExpression.Create(subquery);
579+
}
580+
571581
public override SqlObject VisitFunctionCallScalarExpression([NotNull] sqlParser.FunctionCallScalarExpressionContext context)
572582
{
573583
Contract.Requires(context != null);
@@ -627,6 +637,16 @@ public override SqlObject VisitIn_scalar_expression([NotNull] sqlParser.In_scala
627637
return SqlInScalarExpression.Create(needle, not, searchList.ToImmutableArray());
628638
}
629639

640+
public override SqlObject VisitLastScalarExpression([NotNull] sqlParser.LastScalarExpressionContext context)
641+
{
642+
Contract.Requires(context != null);
643+
// K_LAST '(' sql_query ')'
644+
Contract.Requires(context.ChildCount == 4);
645+
646+
SqlQuery subquery = (SqlQuery)this.Visit(context.children[2]);
647+
return SqlLastScalarExpression.Create(subquery);
648+
}
649+
630650
public override SqlObject VisitLike_scalar_expression([NotNull] sqlParser.Like_scalar_expressionContext context)
631651
{
632652
Contract.Requires(context != null);

Microsoft.Azure.Cosmos/src/Query/Core/Parser/IsqlListener.cs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -562,6 +562,18 @@ internal interface IsqlListener : IParseTreeListener {
562562
/// <param name="context">The parse tree.</param>
563563
void ExitObjectCreateScalarExpression([NotNull] sqlParser.ObjectCreateScalarExpressionContext context);
564564
/// <summary>
565+
/// Enter a parse tree produced by the <c>FirstScalarExpression</c>
566+
/// labeled alternative in <see cref="sqlParser.primary_expression"/>.
567+
/// </summary>
568+
/// <param name="context">The parse tree.</param>
569+
void EnterFirstScalarExpression([NotNull] sqlParser.FirstScalarExpressionContext context);
570+
/// <summary>
571+
/// Exit a parse tree produced by the <c>FirstScalarExpression</c>
572+
/// labeled alternative in <see cref="sqlParser.primary_expression"/>.
573+
/// </summary>
574+
/// <param name="context">The parse tree.</param>
575+
void ExitFirstScalarExpression([NotNull] sqlParser.FirstScalarExpressionContext context);
576+
/// <summary>
565577
/// Enter a parse tree produced by the <c>ArrayCreateScalarExpression</c>
566578
/// labeled alternative in <see cref="sqlParser.primary_expression"/>.
567579
/// </summary>
@@ -670,6 +682,18 @@ internal interface IsqlListener : IParseTreeListener {
670682
/// <param name="context">The parse tree.</param>
671683
void ExitArrayScalarExpression([NotNull] sqlParser.ArrayScalarExpressionContext context);
672684
/// <summary>
685+
/// Enter a parse tree produced by the <c>LastScalarExpression</c>
686+
/// labeled alternative in <see cref="sqlParser.primary_expression"/>.
687+
/// </summary>
688+
/// <param name="context">The parse tree.</param>
689+
void EnterLastScalarExpression([NotNull] sqlParser.LastScalarExpressionContext context);
690+
/// <summary>
691+
/// Exit a parse tree produced by the <c>LastScalarExpression</c>
692+
/// labeled alternative in <see cref="sqlParser.primary_expression"/>.
693+
/// </summary>
694+
/// <param name="context">The parse tree.</param>
695+
void ExitLastScalarExpression([NotNull] sqlParser.LastScalarExpressionContext context);
696+
/// <summary>
673697
/// Enter a parse tree produced by the <c>PropertyRefScalarExpressionRecursive</c>
674698
/// labeled alternative in <see cref="sqlParser.primary_expression"/>.
675699
/// </summary>

Microsoft.Azure.Cosmos/src/Query/Core/Parser/IsqlVisitor.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,13 @@ internal interface IsqlVisitor<Result> : IParseTreeVisitor<Result> {
347347
/// <return>The visitor result.</return>
348348
Result VisitObjectCreateScalarExpression([NotNull] sqlParser.ObjectCreateScalarExpressionContext context);
349349
/// <summary>
350+
/// Visit a parse tree produced by the <c>FirstScalarExpression</c>
351+
/// labeled alternative in <see cref="sqlParser.primary_expression"/>.
352+
/// </summary>
353+
/// <param name="context">The parse tree.</param>
354+
/// <return>The visitor result.</return>
355+
Result VisitFirstScalarExpression([NotNull] sqlParser.FirstScalarExpressionContext context);
356+
/// <summary>
350357
/// Visit a parse tree produced by the <c>ArrayCreateScalarExpression</c>
351358
/// labeled alternative in <see cref="sqlParser.primary_expression"/>.
352359
/// </summary>
@@ -410,6 +417,13 @@ internal interface IsqlVisitor<Result> : IParseTreeVisitor<Result> {
410417
/// <return>The visitor result.</return>
411418
Result VisitArrayScalarExpression([NotNull] sqlParser.ArrayScalarExpressionContext context);
412419
/// <summary>
420+
/// Visit a parse tree produced by the <c>LastScalarExpression</c>
421+
/// labeled alternative in <see cref="sqlParser.primary_expression"/>.
422+
/// </summary>
423+
/// <param name="context">The parse tree.</param>
424+
/// <return>The visitor result.</return>
425+
Result VisitLastScalarExpression([NotNull] sqlParser.LastScalarExpressionContext context);
426+
/// <summary>
413427
/// Visit a parse tree produced by the <c>PropertyRefScalarExpressionRecursive</c>
414428
/// labeled alternative in <see cref="sqlParser.primary_expression"/>.
415429
/// </summary>

Microsoft.Azure.Cosmos/src/Query/Core/Parser/sql.g4

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,8 @@ primary_expression
173173
| K_EXISTS '(' sql_query ')' #ExistsScalarExpression
174174
| K_ARRAY '(' sql_query ')' #ArrayScalarExpression
175175
| K_ALL '(' sql_query ')' #AllScalarExpression
176+
| K_FIRST '(' sql_query ')' #FirstScalarExpression
177+
| K_LAST '(' sql_query ')' #LastScalarExpression
176178
| function_call_scalar_expression #FunctionCallScalarExpression
177179
;
178180

@@ -191,6 +193,8 @@ object_property : STRING_LITERAL ':' scalar_expression ;
191193
identifier
192194
: LEX_IDENTIFIER
193195
| K_ALL
196+
| K_FIRST
197+
| K_LAST
194198
;
195199
/*--------------------------------------------------------------------------------*/
196200

@@ -208,11 +212,13 @@ K_DESC : D E S C;
208212
K_DISTINCT : D I S T I N C T;
209213
K_ESCAPE: E S C A P E;
210214
K_EXISTS : E X I S T S;
215+
K_FIRST : F I R S T;
211216
K_FALSE : 'false';
212217
K_FROM : F R O M;
213218
K_GROUP : G R O U P;
214219
K_IN : I N ;
215220
K_JOIN : J O I N;
221+
K_LAST : L A S T;
216222
K_LEFT : L E F T;
217223
K_LIKE : L I K E;
218224
K_LIMIT : L I M I T;

Microsoft.Azure.Cosmos/src/Query/Core/Parser/sqlBaseListener.cs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -666,6 +666,20 @@ public virtual void EnterObjectCreateScalarExpression([NotNull] sqlParser.Object
666666
/// <param name="context">The parse tree.</param>
667667
public virtual void ExitObjectCreateScalarExpression([NotNull] sqlParser.ObjectCreateScalarExpressionContext context) { }
668668
/// <summary>
669+
/// Enter a parse tree produced by the <c>FirstScalarExpression</c>
670+
/// labeled alternative in <see cref="sqlParser.primary_expression"/>.
671+
/// <para>The default implementation does nothing.</para>
672+
/// </summary>
673+
/// <param name="context">The parse tree.</param>
674+
public virtual void EnterFirstScalarExpression([NotNull] sqlParser.FirstScalarExpressionContext context) { }
675+
/// <summary>
676+
/// Exit a parse tree produced by the <c>FirstScalarExpression</c>
677+
/// labeled alternative in <see cref="sqlParser.primary_expression"/>.
678+
/// <para>The default implementation does nothing.</para>
679+
/// </summary>
680+
/// <param name="context">The parse tree.</param>
681+
public virtual void ExitFirstScalarExpression([NotNull] sqlParser.FirstScalarExpressionContext context) { }
682+
/// <summary>
669683
/// Enter a parse tree produced by the <c>ArrayCreateScalarExpression</c>
670684
/// labeled alternative in <see cref="sqlParser.primary_expression"/>.
671685
/// <para>The default implementation does nothing.</para>
@@ -792,6 +806,20 @@ public virtual void EnterArrayScalarExpression([NotNull] sqlParser.ArrayScalarEx
792806
/// <param name="context">The parse tree.</param>
793807
public virtual void ExitArrayScalarExpression([NotNull] sqlParser.ArrayScalarExpressionContext context) { }
794808
/// <summary>
809+
/// Enter a parse tree produced by the <c>LastScalarExpression</c>
810+
/// labeled alternative in <see cref="sqlParser.primary_expression"/>.
811+
/// <para>The default implementation does nothing.</para>
812+
/// </summary>
813+
/// <param name="context">The parse tree.</param>
814+
public virtual void EnterLastScalarExpression([NotNull] sqlParser.LastScalarExpressionContext context) { }
815+
/// <summary>
816+
/// Exit a parse tree produced by the <c>LastScalarExpression</c>
817+
/// labeled alternative in <see cref="sqlParser.primary_expression"/>.
818+
/// <para>The default implementation does nothing.</para>
819+
/// </summary>
820+
/// <param name="context">The parse tree.</param>
821+
public virtual void ExitLastScalarExpression([NotNull] sqlParser.LastScalarExpressionContext context) { }
822+
/// <summary>
795823
/// Enter a parse tree produced by the <c>PropertyRefScalarExpressionRecursive</c>
796824
/// labeled alternative in <see cref="sqlParser.primary_expression"/>.
797825
/// <para>The default implementation does nothing.</para>

Microsoft.Azure.Cosmos/src/Query/Core/Parser/sqlBaseVisitor.cs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -549,6 +549,17 @@ internal partial class sqlBaseVisitor<Result> : AbstractParseTreeVisitor<Result>
549549
/// <return>The visitor result.</return>
550550
public virtual Result VisitObjectCreateScalarExpression([NotNull] sqlParser.ObjectCreateScalarExpressionContext context) { return VisitChildren(context); }
551551
/// <summary>
552+
/// Visit a parse tree produced by the <c>FirstScalarExpression</c>
553+
/// labeled alternative in <see cref="sqlParser.primary_expression"/>.
554+
/// <para>
555+
/// The default implementation returns the result of calling <see cref="AbstractParseTreeVisitor{Result}.VisitChildren(IRuleNode)"/>
556+
/// on <paramref name="context"/>.
557+
/// </para>
558+
/// </summary>
559+
/// <param name="context">The parse tree.</param>
560+
/// <return>The visitor result.</return>
561+
public virtual Result VisitFirstScalarExpression([NotNull] sqlParser.FirstScalarExpressionContext context) { return VisitChildren(context); }
562+
/// <summary>
552563
/// Visit a parse tree produced by the <c>ArrayCreateScalarExpression</c>
553564
/// labeled alternative in <see cref="sqlParser.primary_expression"/>.
554565
/// <para>
@@ -648,6 +659,17 @@ internal partial class sqlBaseVisitor<Result> : AbstractParseTreeVisitor<Result>
648659
/// <return>The visitor result.</return>
649660
public virtual Result VisitArrayScalarExpression([NotNull] sqlParser.ArrayScalarExpressionContext context) { return VisitChildren(context); }
650661
/// <summary>
662+
/// Visit a parse tree produced by the <c>LastScalarExpression</c>
663+
/// labeled alternative in <see cref="sqlParser.primary_expression"/>.
664+
/// <para>
665+
/// The default implementation returns the result of calling <see cref="AbstractParseTreeVisitor{Result}.VisitChildren(IRuleNode)"/>
666+
/// on <paramref name="context"/>.
667+
/// </para>
668+
/// </summary>
669+
/// <param name="context">The parse tree.</param>
670+
/// <return>The visitor result.</return>
671+
public virtual Result VisitLastScalarExpression([NotNull] sqlParser.LastScalarExpressionContext context) { return VisitChildren(context); }
672+
/// <summary>
651673
/// Visit a parse tree produced by the <c>PropertyRefScalarExpressionRecursive</c>
652674
/// labeled alternative in <see cref="sqlParser.primary_expression"/>.
653675
/// <para>

0 commit comments

Comments
 (0)