aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/parse.y21
-rw-r--r--src/sqliteInt.h2
-rw-r--r--src/window.c4
3 files changed, 20 insertions, 7 deletions
diff --git a/src/parse.y b/src/parse.y
index f8701534e..dcbc31319 100644
--- a/src/parse.y
+++ b/src/parse.y
@@ -1688,13 +1688,13 @@ window(A) ::= nm(W) frame_opt(Z). {
}
frame_opt(A) ::= . {
- A = sqlite3WindowAlloc(pParse, 0, TK_UNBOUNDED, 0, TK_CURRENT, 0);
+ A = sqlite3WindowAlloc(pParse, 0, TK_UNBOUNDED, 0, TK_CURRENT, 0, 0);
}
-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) frame_bound_s(Y) frame_exclude_opt(Z). {
+ A = sqlite3WindowAlloc(pParse, X, Y.eType, Y.pExpr, TK_CURRENT, 0, 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);
+frame_opt(A) ::= range_or_rows(X) BETWEEN frame_bound_s(Y) AND frame_bound_e(Z) frame_exclude_opt(W). {
+ A = sqlite3WindowAlloc(pParse, X, Y.eType, Y.pExpr, Z.eType, Z.pExpr, W);
}
range_or_rows(A) ::= RANGE. { A = TK_RANGE; }
@@ -1711,6 +1711,17 @@ 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; }
+%type frame_exclude_opt {u8}
+frame_exclude_opt(A) ::= . { A = TK_NO; }
+frame_exclude_opt(A) ::= EXCLUDE frame_exclude(X). { A = X; }
+
+%type frame_exclude {u8}
+frame_exclude(A) ::= NO OTHERS. { A = 0; }
+frame_exclude(A) ::= CURRENT ROW. { A = TK_CURRENT; }
+frame_exclude(A) ::= GROUP. { A = TK_GROUP; }
+frame_exclude(A) ::= TIES. { A = TK_TIES; }
+
+
%type window_clause {Window*}
%destructor window_clause {sqlite3WindowListDelete(pParse->db, $$);}
window_clause(A) ::= WINDOW windowdefn_list(B). { A = B; }
diff --git a/src/sqliteInt.h b/src/sqliteInt.h
index 8c878228e..3bd02f138 100644
--- a/src/sqliteInt.h
+++ b/src/sqliteInt.h
@@ -3585,7 +3585,7 @@ struct Window {
#ifndef SQLITE_OMIT_WINDOWFUNC
void sqlite3WindowDelete(sqlite3*, Window*);
void sqlite3WindowListDelete(sqlite3 *db, Window *p);
-Window *sqlite3WindowAlloc(Parse*, int, int, Expr*, int , Expr*);
+Window *sqlite3WindowAlloc(Parse*, int, int, Expr*, int , Expr*, u8);
void sqlite3WindowAttach(Parse*, Expr*, Window*);
int sqlite3WindowCompare(Parse*, Window*, Window*);
void sqlite3WindowCodeInit(Parse*, Window*);
diff --git a/src/window.c b/src/window.c
index c17ea1dbb..83635edac 100644
--- a/src/window.c
+++ b/src/window.c
@@ -994,7 +994,8 @@ Window *sqlite3WindowAlloc(
int eStart, /* Start type: CURRENT, PRECEDING, FOLLOWING, UNBOUNDED */
Expr *pStart, /* Start window size if TK_PRECEDING or FOLLOWING */
int eEnd, /* End type: CURRENT, FOLLOWING, TK_UNBOUNDED, PRECEDING */
- Expr *pEnd /* End window size if TK_FOLLOWING or PRECEDING */
+ Expr *pEnd, /* End window size if TK_FOLLOWING or PRECEDING */
+ u8 eExclude /* EXCLUDE clause */
){
Window *pWin = 0;
int bImplicitFrame = 0;
@@ -1039,6 +1040,7 @@ Window *sqlite3WindowAlloc(
pWin->eType = eType;
pWin->eStart = eStart;
pWin->eEnd = eEnd;
+ pWin->eExclude = eExclude;
pWin->bImplicitFrame = bImplicitFrame;
pWin->pEnd = sqlite3WindowOffsetExpr(pParse, pEnd);
pWin->pStart = sqlite3WindowOffsetExpr(pParse, pStart);