Prevent "UNBOUNDED FOLLOWING" from being used as the starting boundary of a

window-frame. And "UNBOUNDED PRECEDING" from being used as the ending
boundary.

FossilOrigin-Name: e51fdf66a24c27ba6491391fffcc88fc5ca2ae79cfc4ab769a149b19c394e308
This commit is contained in:
dan
2018-07-06 13:48:09 +00:00
parent cf0343b699
commit 287fa17b78
4 changed files with 35 additions and 12 deletions
+12 -4
View File
@@ -1641,6 +1641,10 @@ sqlite3WindowDelete(pParse->db, $$);}
%type frame_bound {struct FrameBound}
%destructor frame_bound {sqlite3ExprDelete(pParse->db, $$.pExpr);}
%type frame_bound_s {struct FrameBound}
%destructor frame_bound_s {sqlite3ExprDelete(pParse->db, $$.pExpr);}
%type frame_bound_e {struct FrameBound}
%destructor frame_bound_e {sqlite3ExprDelete(pParse->db, $$.pExpr);}
window_or_nm(A) ::= window(Z). {A = Z;}
window_or_nm(A) ::= nm(Z). {
@@ -1664,21 +1668,25 @@ part_opt(A) ::= . { A = 0; }
frame_opt(A) ::= . {
A = sqlite3WindowAlloc(pParse, TK_RANGE, TK_UNBOUNDED, 0, TK_CURRENT, 0);
}
frame_opt(A) ::= range_or_rows(X) frame_bound(Y). {
frame_opt(A) ::= range_or_rows(X) frame_bound_s(Y). {
A = sqlite3WindowAlloc(pParse, X, Y.eType, Y.pExpr, TK_CURRENT, 0);
}
frame_opt(A) ::= range_or_rows(X) BETWEEN frame_bound(Y) AND frame_bound(Z). {
frame_opt(A) ::= range_or_rows(X) BETWEEN frame_bound_s(Y) AND frame_bound_e(Z). {
A = sqlite3WindowAlloc(pParse, X, Y.eType, Y.pExpr, Z.eType, Z.pExpr);
}
range_or_rows(A) ::= RANGE. { A = TK_RANGE; }
range_or_rows(A) ::= ROWS. { A = TK_ROWS; }
frame_bound(A) ::= UNBOUNDED PRECEDING. { A.eType = TK_UNBOUNDED; A.pExpr = 0; }
frame_bound_s(A) ::= frame_bound(X). { A = X; }
frame_bound_s(A) ::= UNBOUNDED PRECEDING. {A.eType = TK_UNBOUNDED; A.pExpr = 0;}
frame_bound_e(A) ::= frame_bound(X). { A = X; }
frame_bound_e(A) ::= UNBOUNDED FOLLOWING. {A.eType = TK_UNBOUNDED; A.pExpr = 0;}
frame_bound(A) ::= expr(X) PRECEDING. { A.eType = TK_PRECEDING; A.pExpr = X; }
frame_bound(A) ::= CURRENT ROW. { A.eType = TK_CURRENT ; A.pExpr = 0; }
frame_bound(A) ::= expr(X) FOLLOWING. { A.eType = TK_FOLLOWING; A.pExpr = X; }
frame_bound(A) ::= UNBOUNDED FOLLOWING. { A.eType = TK_UNBOUNDED; A.pExpr = 0; }
%type windowdefn_opt {Window*}
%destructor windowdefn_opt {sqlite3WindowDelete(pParse->db, $$);}