blob: de3b778226f3c4b4eaf8884c469e398404d10165 [file] [log] [blame]
dan86fb6e12018-05-16 20:58:07 +00001/*
dan26522d12018-06-11 18:16:51 +00002** 2018 May 08
dan86fb6e12018-05-16 20:58:07 +00003**
4** The author disclaims copyright to this source code. In place of
5** a legal notice, here is a blessing:
6**
7** May you do good and not evil.
8** May you find forgiveness for yourself and forgive others.
9** May you share freely, never taking more than you give.
10**
11*************************************************************************
12*/
13#include "sqliteInt.h"
14
dandfa552f2018-06-02 21:04:28 +000015/*
dan73925692018-06-12 18:40:17 +000016** SELECT REWRITING
17**
18** Any SELECT statement that contains one or more window functions in
19** either the select list or ORDER BY clause (the only two places window
20** functions may be used) is transformed by function sqlite3WindowRewrite()
21** in order to support window function processing. For example, with the
22** schema:
23**
24** CREATE TABLE t1(a, b, c, d, e, f, g);
25**
26** the statement:
27**
28** SELECT a+1, max(b) OVER (PARTITION BY c ORDER BY d) FROM t1 ORDER BY e;
29**
30** is transformed to:
31**
32** SELECT a+1, max(b) OVER (PARTITION BY c ORDER BY d) FROM (
33** SELECT a, e, c, d, b FROM t1 ORDER BY c, d
34** ) ORDER BY e;
35**
36** The flattening optimization is disabled when processing this transformed
37** SELECT statement. This allows the implementation of the window function
38** (in this case max()) to process rows sorted in order of (c, d), which
39** makes things easier for obvious reasons. More generally:
40**
41** * FROM, WHERE, GROUP BY and HAVING clauses are all moved to
42** the sub-query.
43**
44** * ORDER BY, LIMIT and OFFSET remain part of the parent query.
45**
46** * Terminals from each of the expression trees that make up the
47** select-list and ORDER BY expressions in the parent query are
48** selected by the sub-query. For the purposes of the transformation,
49** terminals are column references and aggregate functions.
50**
51** If there is more than one window function in the SELECT that uses
52** the same window declaration (the OVER bit), then a single scan may
53** be used to process more than one window function. For example:
54**
55** SELECT max(b) OVER (PARTITION BY c ORDER BY d),
56** min(e) OVER (PARTITION BY c ORDER BY d)
57** FROM t1;
58**
59** is transformed in the same way as the example above. However:
60**
61** SELECT max(b) OVER (PARTITION BY c ORDER BY d),
62** min(e) OVER (PARTITION BY a ORDER BY b)
63** FROM t1;
64**
65** Must be transformed to:
66**
67** SELECT max(b) OVER (PARTITION BY c ORDER BY d) FROM (
68** SELECT e, min(e) OVER (PARTITION BY a ORDER BY b), c, d, b FROM
69** SELECT a, e, c, d, b FROM t1 ORDER BY a, b
70** ) ORDER BY c, d
71** ) ORDER BY e;
72**
73** so that both min() and max() may process rows in the order defined by
74** their respective window declarations.
75**
76** INTERFACE WITH SELECT.C
77**
78** When processing the rewritten SELECT statement, code in select.c calls
79** sqlite3WhereBegin() to begin iterating through the results of the
80** sub-query, which is always implemented as a co-routine. It then calls
81** sqlite3WindowCodeStep() to process rows and finish the scan by calling
82** sqlite3WhereEnd().
83**
84** sqlite3WindowCodeStep() generates VM code so that, for each row returned
85** by the sub-query a sub-routine (OP_Gosub) coded by select.c is invoked.
86** When the sub-routine is invoked:
87**
88** * The results of all window-functions for the row are stored
89** in the associated Window.regResult registers.
90**
91** * The required terminal values are stored in the current row of
92** temp table Window.iEphCsr.
93**
94** In some cases, depending on the window frame and the specific window
95** functions invoked, sqlite3WindowCodeStep() caches each entire partition
96** in a temp table before returning any rows. In other cases it does not.
97** This detail is encapsulated within this file, the code generated by
98** select.c is the same in either case.
99**
100** BUILT-IN WINDOW FUNCTIONS
101**
102** This implementation features the following built-in window functions:
103**
104** row_number()
105** rank()
106** dense_rank()
107** percent_rank()
108** cume_dist()
109** ntile(N)
110** lead(expr [, offset [, default]])
111** lag(expr [, offset [, default]])
112** first_value(expr)
113** last_value(expr)
114** nth_value(expr, N)
115**
116** These are the same built-in window functions supported by Postgres.
117** Although the behaviour of aggregate window functions (functions that
118** can be used as either aggregates or window funtions) allows them to
119** be implemented using an API, built-in window functions are much more
120** esoteric. Additionally, some window functions (e.g. nth_value())
121** may only be implemented by caching the entire partition in memory.
122** As such, some built-in window functions use the same API as aggregate
123** window functions and some are implemented directly using VDBE
124** instructions. Additionally, for those functions that use the API, the
125** window frame is sometimes modified before the SELECT statement is
126** rewritten. For example, regardless of the specified window frame, the
127** row_number() function always uses:
128**
129** ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
130**
131** See sqlite3WindowUpdate() for details.
danc0bb4452018-06-12 20:53:38 +0000132**
133** As well as some of the built-in window functions, aggregate window
134** functions min() and max() are implemented using VDBE instructions if
135** the start of the window frame is declared as anything other than
136** UNBOUNDED PRECEDING.
dan73925692018-06-12 18:40:17 +0000137*/
138
139/*
dandfa552f2018-06-02 21:04:28 +0000140** Implementation of built-in window function row_number(). Assumes that the
141** window frame has been coerced to:
142**
143** ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
144*/
145static void row_numberStepFunc(
146 sqlite3_context *pCtx,
147 int nArg,
148 sqlite3_value **apArg
149){
150 i64 *p = (i64*)sqlite3_aggregate_context(pCtx, sizeof(*p));
151 if( p ) (*p)++;
152}
dan2a11bb22018-06-11 20:50:25 +0000153static void row_numberInvFunc(
dandfa552f2018-06-02 21:04:28 +0000154 sqlite3_context *pCtx,
155 int nArg,
156 sqlite3_value **apArg
157){
158}
159static void row_numberValueFunc(sqlite3_context *pCtx){
160 i64 *p = (i64*)sqlite3_aggregate_context(pCtx, sizeof(*p));
161 sqlite3_result_int64(pCtx, (p ? *p : 0));
162}
163
164/*
dan2a11bb22018-06-11 20:50:25 +0000165** Context object type used by rank(), dense_rank(), percent_rank() and
166** cume_dist().
dandfa552f2018-06-02 21:04:28 +0000167*/
168struct CallCount {
169 i64 nValue;
170 i64 nStep;
171 i64 nTotal;
172};
173
174/*
175** Implementation of built-in window function dense_rank().
176*/
177static void dense_rankStepFunc(
178 sqlite3_context *pCtx,
179 int nArg,
180 sqlite3_value **apArg
181){
182 struct CallCount *p;
183 p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p));
184 if( p ) p->nStep = 1;
185}
dan2a11bb22018-06-11 20:50:25 +0000186static void dense_rankInvFunc(
dandfa552f2018-06-02 21:04:28 +0000187 sqlite3_context *pCtx,
188 int nArg,
189 sqlite3_value **apArg
190){
191}
192static void dense_rankValueFunc(sqlite3_context *pCtx){
193 struct CallCount *p;
194 p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p));
195 if( p ){
196 if( p->nStep ){
197 p->nValue++;
198 p->nStep = 0;
199 }
200 sqlite3_result_int64(pCtx, p->nValue);
201 }
202}
203
204/*
205** Implementation of built-in window function rank().
206*/
207static void rankStepFunc(
208 sqlite3_context *pCtx,
209 int nArg,
210 sqlite3_value **apArg
211){
212 struct CallCount *p;
213 p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p));
214 if( p ){
215 p->nStep++;
216 if( p->nValue==0 ){
217 p->nValue = p->nStep;
218 }
219 }
220}
dan2a11bb22018-06-11 20:50:25 +0000221static void rankInvFunc(
dandfa552f2018-06-02 21:04:28 +0000222 sqlite3_context *pCtx,
223 int nArg,
224 sqlite3_value **apArg
225){
226}
227static void rankValueFunc(sqlite3_context *pCtx){
228 struct CallCount *p;
229 p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p));
230 if( p ){
231 sqlite3_result_int64(pCtx, p->nValue);
232 p->nValue = 0;
233 }
234}
235
236/*
237** Implementation of built-in window function percent_rank().
238*/
239static void percent_rankStepFunc(
240 sqlite3_context *pCtx,
241 int nArg,
242 sqlite3_value **apArg
243){
244 struct CallCount *p;
245 assert( nArg==1 );
246
247 p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p));
248 if( p ){
249 if( p->nTotal==0 ){
250 p->nTotal = sqlite3_value_int64(apArg[0]);
251 }
252 p->nStep++;
253 if( p->nValue==0 ){
254 p->nValue = p->nStep;
255 }
256 }
257}
dan2a11bb22018-06-11 20:50:25 +0000258static void percent_rankInvFunc(
dandfa552f2018-06-02 21:04:28 +0000259 sqlite3_context *pCtx,
260 int nArg,
261 sqlite3_value **apArg
262){
263}
264static void percent_rankValueFunc(sqlite3_context *pCtx){
265 struct CallCount *p;
266 p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p));
267 if( p ){
268 if( p->nTotal>1 ){
269 double r = (double)(p->nValue-1) / (double)(p->nTotal-1);
270 sqlite3_result_double(pCtx, r);
271 }else{
272 sqlite3_result_double(pCtx, 100.0);
273 }
274 p->nValue = 0;
275 }
276}
277
danf1abe362018-06-04 08:22:09 +0000278static void cume_distStepFunc(
279 sqlite3_context *pCtx,
280 int nArg,
281 sqlite3_value **apArg
282){
283 struct CallCount *p;
284 assert( nArg==1 );
285
286 p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p));
287 if( p ){
288 if( p->nTotal==0 ){
289 p->nTotal = sqlite3_value_int64(apArg[0]);
290 }
291 p->nStep++;
292 }
293}
dan2a11bb22018-06-11 20:50:25 +0000294static void cume_distInvFunc(
danf1abe362018-06-04 08:22:09 +0000295 sqlite3_context *pCtx,
296 int nArg,
297 sqlite3_value **apArg
298){
299}
300static void cume_distValueFunc(sqlite3_context *pCtx){
301 struct CallCount *p;
302 p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p));
303 if( p ){
304 double r = (double)(p->nStep) / (double)(p->nTotal);
305 sqlite3_result_double(pCtx, r);
306 }
307}
308
dan2a11bb22018-06-11 20:50:25 +0000309/*
310** Context object for ntile() window function.
311*/
dan6bc5c9e2018-06-04 18:55:11 +0000312struct NtileCtx {
313 i64 nTotal; /* Total rows in partition */
314 i64 nParam; /* Parameter passed to ntile(N) */
315 i64 iRow; /* Current row */
316};
317
318/*
319** Implementation of ntile(). This assumes that the window frame has
320** been coerced to:
321**
322** ROWS UNBOUNDED PRECEDING AND CURRENT ROW
dan6bc5c9e2018-06-04 18:55:11 +0000323*/
324static void ntileStepFunc(
325 sqlite3_context *pCtx,
326 int nArg,
327 sqlite3_value **apArg
328){
329 struct NtileCtx *p;
330 assert( nArg==2 );
331 p = (struct NtileCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p));
332 if( p ){
333 if( p->nTotal==0 ){
334 p->nParam = sqlite3_value_int64(apArg[0]);
335 p->nTotal = sqlite3_value_int64(apArg[1]);
336 if( p->nParam<=0 ){
337 sqlite3_result_error(
338 pCtx, "argument of ntile must be a positive integer", -1
339 );
340 }
341 }
342 p->iRow++;
343 }
344}
dan2a11bb22018-06-11 20:50:25 +0000345static void ntileInvFunc(
dan6bc5c9e2018-06-04 18:55:11 +0000346 sqlite3_context *pCtx,
347 int nArg,
348 sqlite3_value **apArg
349){
350}
351static void ntileValueFunc(sqlite3_context *pCtx){
352 struct NtileCtx *p;
353 p = (struct NtileCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p));
354 if( p && p->nParam>0 ){
355 int nSize = (p->nTotal / p->nParam);
356 if( nSize==0 ){
357 sqlite3_result_int64(pCtx, p->iRow);
358 }else{
359 i64 nLarge = p->nTotal - p->nParam*nSize;
360 i64 iSmall = nLarge*(nSize+1);
361 i64 iRow = p->iRow-1;
362
363 assert( (nLarge*(nSize+1) + (p->nParam-nLarge)*nSize)==p->nTotal );
364
365 if( iRow<iSmall ){
366 sqlite3_result_int64(pCtx, 1 + iRow/(nSize+1));
367 }else{
368 sqlite3_result_int64(pCtx, 1 + nLarge + (iRow-iSmall)/nSize);
369 }
370 }
371 }
372}
373
dan2a11bb22018-06-11 20:50:25 +0000374/*
375** Context object for last_value() window function.
376*/
dan1c5ed622018-06-05 16:16:17 +0000377struct LastValueCtx {
378 sqlite3_value *pVal;
379 int nVal;
380};
381
382/*
383** Implementation of last_value().
384*/
385static void last_valueStepFunc(
386 sqlite3_context *pCtx,
387 int nArg,
388 sqlite3_value **apArg
389){
390 struct LastValueCtx *p;
391 p = (struct LastValueCtx *)sqlite3_aggregate_context(pCtx, sizeof(*p));
392 if( p ){
393 sqlite3_value_free(p->pVal);
394 p->pVal = sqlite3_value_dup(apArg[0]);
395 p->nVal++;
396 }
397}
dan2a11bb22018-06-11 20:50:25 +0000398static void last_valueInvFunc(
dan1c5ed622018-06-05 16:16:17 +0000399 sqlite3_context *pCtx,
400 int nArg,
401 sqlite3_value **apArg
402){
403 struct LastValueCtx *p;
404 p = (struct LastValueCtx *)sqlite3_aggregate_context(pCtx, sizeof(*p));
405 if( p ){
406 p->nVal--;
407 if( p->nVal==0 ){
408 sqlite3_value_free(p->pVal);
409 p->pVal = 0;
410 }
411 }
412}
413static void last_valueValueFunc(sqlite3_context *pCtx){
414 struct LastValueCtx *p;
415 p = (struct LastValueCtx *)sqlite3_aggregate_context(pCtx, sizeof(*p));
416 if( p && p->pVal ){
417 sqlite3_result_value(pCtx, p->pVal);
418 }
419}
420static void last_valueFinalizeFunc(sqlite3_context *pCtx){
421 struct LastValueCtx *p;
422 p = (struct LastValueCtx *)sqlite3_aggregate_context(pCtx, sizeof(*p));
423 if( p && p->pVal ){
424 sqlite3_result_value(pCtx, p->pVal);
425 sqlite3_value_free(p->pVal);
426 p->pVal = 0;
427 }
428}
429
dan2a11bb22018-06-11 20:50:25 +0000430/*
431** No-op implementations of nth_value(), first_value(), lead() and lag().
432** These are all implemented inline using VDBE instructions.
433*/
434static void nth_valueStepFunc(sqlite3_context *pCtx, int n, sqlite3_value **a){}
435static void nth_valueInvFunc(sqlite3_context *pCtx, int n, sqlite3_value **ap){}
436static void nth_valueValueFunc(sqlite3_context *pCtx){}
437static void first_valueStepFunc(sqlite3_context *p, int n, sqlite3_value **ap){}
438static void first_valueInvFunc(sqlite3_context *p, int n, sqlite3_value **ap){}
439static void first_valueValueFunc(sqlite3_context *pCtx){}
440static void leadStepFunc(sqlite3_context *pCtx, int n, sqlite3_value **ap){}
441static void leadInvFunc(sqlite3_context *pCtx, int n, sqlite3_value **ap){}
442static void leadValueFunc(sqlite3_context *pCtx){}
443static void lagStepFunc(sqlite3_context *pCtx, int n, sqlite3_value **ap){}
444static void lagInvFunc(sqlite3_context *pCtx, int n, sqlite3_value **ap){}
445static void lagValueFunc(sqlite3_context *pCtx){}
danfe4e25a2018-06-07 20:08:59 +0000446
dandfa552f2018-06-02 21:04:28 +0000447#define WINDOWFUNC(name,nArg,extra) { \
448 nArg, (SQLITE_UTF8|SQLITE_FUNC_WINDOW|extra), 0, 0, \
449 name ## StepFunc, name ## ValueFunc, name ## ValueFunc, \
dan2a11bb22018-06-11 20:50:25 +0000450 name ## InvFunc, #name \
dandfa552f2018-06-02 21:04:28 +0000451}
452
dan1c5ed622018-06-05 16:16:17 +0000453#define WINDOWFUNCF(name,nArg,extra) { \
454 nArg, (SQLITE_UTF8|SQLITE_FUNC_WINDOW|extra), 0, 0, \
455 name ## StepFunc, name ## FinalizeFunc, name ## ValueFunc, \
dan2a11bb22018-06-11 20:50:25 +0000456 name ## InvFunc, #name \
dan1c5ed622018-06-05 16:16:17 +0000457}
458
dandfa552f2018-06-02 21:04:28 +0000459/*
460** Register those built-in window functions that are not also aggregates.
461*/
462void sqlite3WindowFunctions(void){
463 static FuncDef aWindowFuncs[] = {
464 WINDOWFUNC(row_number, 0, 0),
465 WINDOWFUNC(dense_rank, 0, 0),
466 WINDOWFUNC(rank, 0, 0),
467 WINDOWFUNC(percent_rank, 0, SQLITE_FUNC_WINDOW_SIZE),
danf1abe362018-06-04 08:22:09 +0000468 WINDOWFUNC(cume_dist, 0, SQLITE_FUNC_WINDOW_SIZE),
dan6bc5c9e2018-06-04 18:55:11 +0000469 WINDOWFUNC(ntile, 1, SQLITE_FUNC_WINDOW_SIZE),
dan1c5ed622018-06-05 16:16:17 +0000470 WINDOWFUNCF(last_value, 1, 0),
dandfa552f2018-06-02 21:04:28 +0000471 WINDOWFUNC(nth_value, 2, 0),
dan7095c002018-06-07 17:45:22 +0000472 WINDOWFUNC(first_value, 1, 0),
danfe4e25a2018-06-07 20:08:59 +0000473 WINDOWFUNC(lead, 1, 0), WINDOWFUNC(lead, 2, 0), WINDOWFUNC(lead, 3, 0),
474 WINDOWFUNC(lag, 1, 0), WINDOWFUNC(lag, 2, 0), WINDOWFUNC(lag, 3, 0),
dandfa552f2018-06-02 21:04:28 +0000475 };
476 sqlite3InsertBuiltinFuncs(aWindowFuncs, ArraySize(aWindowFuncs));
477}
478
danc0bb4452018-06-12 20:53:38 +0000479/*
480** This function is called immediately after resolving the function name
481** for a window function within a SELECT statement. Argument pList is a
482** linked list of WINDOW definitions for the current SELECT statement.
483** Argument pFunc is the function definition just resolved and pWin
484** is the Window object representing the associated OVER clause. This
485** function updates the contents of pWin as follows:
486**
487** * If the OVER clause refered to a named window (as in "max(x) OVER win"),
488** search list pList for a matching WINDOW definition, and update pWin
489** accordingly. If no such WINDOW clause can be found, leave an error
490** in pParse.
491**
492** * If the function is a built-in window function that requires the
493** window to be coerced (see "BUILT-IN WINDOW FUNCTIONS" at the top
494** of this file), pWin is updated here.
495*/
dane3bf6322018-06-08 20:58:27 +0000496void sqlite3WindowUpdate(
497 Parse *pParse,
danc0bb4452018-06-12 20:53:38 +0000498 Window *pList, /* List of named windows for this SELECT */
499 Window *pWin, /* Window frame to update */
500 FuncDef *pFunc /* Window function definition */
dane3bf6322018-06-08 20:58:27 +0000501){
502 if( pWin->zName ){
503 Window *p;
504 for(p=pList; p; p=p->pNextWin){
505 if( sqlite3StrICmp(p->zName, pWin->zName)==0 ) break;
506 }
507 if( p==0 ){
508 sqlite3ErrorMsg(pParse, "no such window: %s", pWin->zName);
509 return;
510 }
511 pWin->pPartition = sqlite3ExprListDup(pParse->db, p->pPartition, 0);
512 pWin->pOrderBy = sqlite3ExprListDup(pParse->db, p->pOrderBy, 0);
513 pWin->pStart = sqlite3ExprDup(pParse->db, p->pStart, 0);
514 pWin->pEnd = sqlite3ExprDup(pParse->db, p->pEnd, 0);
515 pWin->eStart = p->eStart;
516 pWin->eEnd = p->eEnd;
517 }
dandfa552f2018-06-02 21:04:28 +0000518 if( pFunc->funcFlags & SQLITE_FUNC_WINDOW ){
519 sqlite3 *db = pParse->db;
dan8b985602018-06-09 17:43:45 +0000520 if( pWin->pFilter ){
521 sqlite3ErrorMsg(pParse,
522 "FILTER clause may only be used with aggregate window functions"
523 );
524 }else
dan6bc5c9e2018-06-04 18:55:11 +0000525 if( pFunc->xSFunc==row_numberStepFunc || pFunc->xSFunc==ntileStepFunc ){
dandfa552f2018-06-02 21:04:28 +0000526 sqlite3ExprDelete(db, pWin->pStart);
527 sqlite3ExprDelete(db, pWin->pEnd);
528 pWin->pStart = pWin->pEnd = 0;
529 pWin->eType = TK_ROWS;
530 pWin->eStart = TK_UNBOUNDED;
531 pWin->eEnd = TK_CURRENT;
dan8b985602018-06-09 17:43:45 +0000532 }else
dandfa552f2018-06-02 21:04:28 +0000533
534 if( pFunc->xSFunc==dense_rankStepFunc || pFunc->xSFunc==rankStepFunc
danf1abe362018-06-04 08:22:09 +0000535 || pFunc->xSFunc==percent_rankStepFunc || pFunc->xSFunc==cume_distStepFunc
dandfa552f2018-06-02 21:04:28 +0000536 ){
537 sqlite3ExprDelete(db, pWin->pStart);
538 sqlite3ExprDelete(db, pWin->pEnd);
539 pWin->pStart = pWin->pEnd = 0;
540 pWin->eType = TK_RANGE;
541 pWin->eStart = TK_UNBOUNDED;
542 pWin->eEnd = TK_CURRENT;
543 }
544 }
dan2a11bb22018-06-11 20:50:25 +0000545 pWin->pFunc = pFunc;
dandfa552f2018-06-02 21:04:28 +0000546}
547
danc0bb4452018-06-12 20:53:38 +0000548/*
549** Context object passed through sqlite3WalkExprList() to
550** selectWindowRewriteExprCb() by selectWindowRewriteEList().
551*/
dandfa552f2018-06-02 21:04:28 +0000552typedef struct WindowRewrite WindowRewrite;
553struct WindowRewrite {
554 Window *pWin;
555 ExprList *pSub;
556};
557
danc0bb4452018-06-12 20:53:38 +0000558/*
559** Callback function used by selectWindowRewriteEList(). If necessary,
560** this function appends to the output expression-list and updates
561** expression (*ppExpr) in place.
562*/
dandfa552f2018-06-02 21:04:28 +0000563static int selectWindowRewriteExprCb(Walker *pWalker, Expr *pExpr){
564 struct WindowRewrite *p = pWalker->u.pRewrite;
565 Parse *pParse = pWalker->pParse;
566
567 switch( pExpr->op ){
568
569 case TK_FUNCTION:
570 if( pExpr->pWin==0 ){
571 break;
572 }else{
573 Window *pWin;
574 for(pWin=p->pWin; pWin; pWin=pWin->pNextWin){
575 if( pExpr->pWin==pWin ){
dan2a11bb22018-06-11 20:50:25 +0000576 assert( pWin->pOwner==pExpr );
dandfa552f2018-06-02 21:04:28 +0000577 return WRC_Prune;
578 }
579 }
580 }
581 /* Fall through. */
582
dan73925692018-06-12 18:40:17 +0000583 case TK_AGG_FUNCTION:
dandfa552f2018-06-02 21:04:28 +0000584 case TK_COLUMN: {
585 Expr *pDup = sqlite3ExprDup(pParse->db, pExpr, 0);
586 p->pSub = sqlite3ExprListAppend(pParse, p->pSub, pDup);
587 if( p->pSub ){
588 assert( ExprHasProperty(pExpr, EP_Static)==0 );
589 ExprSetProperty(pExpr, EP_Static);
590 sqlite3ExprDelete(pParse->db, pExpr);
591 ExprClearProperty(pExpr, EP_Static);
592 memset(pExpr, 0, sizeof(Expr));
593
594 pExpr->op = TK_COLUMN;
595 pExpr->iColumn = p->pSub->nExpr-1;
596 pExpr->iTable = p->pWin->iEphCsr;
597 }
598
599 break;
600 }
601
602 default: /* no-op */
603 break;
604 }
605
606 return WRC_Continue;
607}
danc0bb4452018-06-12 20:53:38 +0000608static int selectWindowRewriteSelectCb(Walker *pWalker, Select *pSelect){
609 return WRC_Prune;
610}
dandfa552f2018-06-02 21:04:28 +0000611
danc0bb4452018-06-12 20:53:38 +0000612
613/*
614** Iterate through each expression in expression-list pEList. For each:
615**
616** * TK_COLUMN,
617** * aggregate function, or
618** * window function with a Window object that is not a member of the
619** linked list passed as the second argument (pWin)
620**
621** Append the node to output expression-list (*ppSub). And replace it
622** with a TK_COLUMN that reads the (N-1)th element of table
623** pWin->iEphCsr, where N is the number of elements in (*ppSub) after
624** appending the new one.
625*/
dandfa552f2018-06-02 21:04:28 +0000626static int selectWindowRewriteEList(
627 Parse *pParse,
628 Window *pWin,
629 ExprList *pEList, /* Rewrite expressions in this list */
630 ExprList **ppSub /* IN/OUT: Sub-select expression-list */
631){
632 Walker sWalker;
633 WindowRewrite sRewrite;
634 int rc;
635
636 memset(&sWalker, 0, sizeof(Walker));
637 memset(&sRewrite, 0, sizeof(WindowRewrite));
638
639 sRewrite.pSub = *ppSub;
640 sRewrite.pWin = pWin;
641
642 sWalker.pParse = pParse;
643 sWalker.xExprCallback = selectWindowRewriteExprCb;
644 sWalker.xSelectCallback = selectWindowRewriteSelectCb;
645 sWalker.u.pRewrite = &sRewrite;
646
647 rc = sqlite3WalkExprList(&sWalker, pEList);
648
649 *ppSub = sRewrite.pSub;
650 return rc;
651}
652
danc0bb4452018-06-12 20:53:38 +0000653/*
654** Append a copy of each expression in expression-list pAppend to
655** expression list pList. Return a pointer to the result list.
656*/
dandfa552f2018-06-02 21:04:28 +0000657static ExprList *exprListAppendList(
658 Parse *pParse, /* Parsing context */
659 ExprList *pList, /* List to which to append. Might be NULL */
660 ExprList *pAppend /* List of values to append. Might be NULL */
661){
662 if( pAppend ){
663 int i;
664 int nInit = pList ? pList->nExpr : 0;
665 for(i=0; i<pAppend->nExpr; i++){
666 Expr *pDup = sqlite3ExprDup(pParse->db, pAppend->a[i].pExpr, 0);
667 pList = sqlite3ExprListAppend(pParse, pList, pDup);
668 if( pList ) pList->a[nInit+i].sortOrder = pAppend->a[i].sortOrder;
669 }
670 }
671 return pList;
672}
673
674/*
675** If the SELECT statement passed as the second argument does not invoke
676** any SQL window functions, this function is a no-op. Otherwise, it
677** rewrites the SELECT statement so that window function xStep functions
danc0bb4452018-06-12 20:53:38 +0000678** are invoked in the correct order as described under "SELECT REWRITING"
679** at the top of this file.
dandfa552f2018-06-02 21:04:28 +0000680*/
681int sqlite3WindowRewrite(Parse *pParse, Select *p){
682 int rc = SQLITE_OK;
683 if( p->pWin ){
684 Vdbe *v = sqlite3GetVdbe(pParse);
685 int i;
686 sqlite3 *db = pParse->db;
687 Select *pSub = 0; /* The subquery */
688 SrcList *pSrc = p->pSrc;
689 Expr *pWhere = p->pWhere;
690 ExprList *pGroupBy = p->pGroupBy;
691 Expr *pHaving = p->pHaving;
692 ExprList *pSort = 0;
693
694 ExprList *pSublist = 0; /* Expression list for sub-query */
695 Window *pMWin = p->pWin; /* Master window object */
696 Window *pWin; /* Window object iterator */
697
698 p->pSrc = 0;
699 p->pWhere = 0;
700 p->pGroupBy = 0;
701 p->pHaving = 0;
702
703 /* Assign a cursor number for the ephemeral table used to buffer rows.
704 ** The OpenEphemeral instruction is coded later, after it is known how
705 ** many columns the table will have. */
706 pMWin->iEphCsr = pParse->nTab++;
707
708 rc = selectWindowRewriteEList(pParse, pMWin, p->pEList, &pSublist);
709 if( rc ) return rc;
710 rc = selectWindowRewriteEList(pParse, pMWin, p->pOrderBy, &pSublist);
711 if( rc ) return rc;
712 pMWin->nBufferCol = (pSublist ? pSublist->nExpr : 0);
713
714 /* Create the ORDER BY clause for the sub-select. This is the concatenation
715 ** of the window PARTITION and ORDER BY clauses. Append the same
716 ** expressions to the sub-select expression list. They are required to
717 ** figure out where boundaries for partitions and sets of peer rows. */
718 pSort = sqlite3ExprListDup(db, pMWin->pPartition, 0);
719 if( pMWin->pOrderBy ){
720 pSort = exprListAppendList(pParse, pSort, pMWin->pOrderBy);
721 }
722 pSublist = exprListAppendList(pParse, pSublist, pSort);
723
724 /* Append the arguments passed to each window function to the
725 ** sub-select expression list. Also allocate two registers for each
726 ** window function - one for the accumulator, another for interim
727 ** results. */
728 for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
729 pWin->iArgCol = (pSublist ? pSublist->nExpr : 0);
730 pSublist = exprListAppendList(pParse, pSublist, pWin->pOwner->x.pList);
dan8b985602018-06-09 17:43:45 +0000731 if( pWin->pFilter ){
732 Expr *pFilter = sqlite3ExprDup(db, pWin->pFilter, 0);
733 pSublist = sqlite3ExprListAppend(pParse, pSublist, pFilter);
734 }
dandfa552f2018-06-02 21:04:28 +0000735 pWin->regAccum = ++pParse->nMem;
736 pWin->regResult = ++pParse->nMem;
737 sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regAccum);
738 }
739
740 pSub = sqlite3SelectNew(
741 pParse, pSublist, pSrc, pWhere, pGroupBy, pHaving, pSort, 0, 0
742 );
743 p->pSrc = sqlite3SrcListAppend(db, 0, 0, 0);
744 if( p->pSrc ){
745 int iTab;
746 ExprList *pList = 0;
747 p->pSrc->a[0].pSelect = pSub;
748 sqlite3SrcListAssignCursors(pParse, p->pSrc);
749 if( sqlite3ExpandSubquery(pParse, &p->pSrc->a[0]) ){
750 rc = SQLITE_NOMEM;
751 }else{
752 pSub->selFlags |= SF_Expanded;
dan73925692018-06-12 18:40:17 +0000753 p->selFlags &= ~SF_Aggregate;
754 sqlite3SelectPrep(pParse, pSub, 0);
dandfa552f2018-06-02 21:04:28 +0000755 }
756 }
757
758 sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pMWin->iEphCsr, pSublist->nExpr);
759 }
760
761 return rc;
762}
763
danc0bb4452018-06-12 20:53:38 +0000764/*
765** Free the Window object passed as the second argument.
766*/
dan86fb6e12018-05-16 20:58:07 +0000767void sqlite3WindowDelete(sqlite3 *db, Window *p){
768 if( p ){
769 sqlite3ExprDelete(db, p->pFilter);
770 sqlite3ExprListDelete(db, p->pPartition);
771 sqlite3ExprListDelete(db, p->pOrderBy);
772 sqlite3ExprDelete(db, p->pEnd);
773 sqlite3ExprDelete(db, p->pStart);
dane3bf6322018-06-08 20:58:27 +0000774 sqlite3DbFree(db, p->zName);
dan86fb6e12018-05-16 20:58:07 +0000775 sqlite3DbFree(db, p);
776 }
777}
778
danc0bb4452018-06-12 20:53:38 +0000779/*
780** Free the linked list of Window objects starting at the second argument.
781*/
dane3bf6322018-06-08 20:58:27 +0000782void sqlite3WindowListDelete(sqlite3 *db, Window *p){
783 while( p ){
784 Window *pNext = p->pNextWin;
785 sqlite3WindowDelete(db, p);
786 p = pNext;
787 }
788}
789
danc0bb4452018-06-12 20:53:38 +0000790/*
791** Allocate and return a new Window object.
792*/
dan86fb6e12018-05-16 20:58:07 +0000793Window *sqlite3WindowAlloc(
794 Parse *pParse,
795 int eType,
danc3a20c12018-05-23 20:55:37 +0000796 int eStart, Expr *pStart,
797 int eEnd, Expr *pEnd
dan86fb6e12018-05-16 20:58:07 +0000798){
799 Window *pWin = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window));
800
801 if( pWin ){
802 pWin->eType = eType;
803 pWin->eStart = eStart;
804 pWin->eEnd = eEnd;
805 pWin->pEnd = pEnd;
806 pWin->pStart = pStart;
807 }else{
808 sqlite3ExprDelete(pParse->db, pEnd);
809 sqlite3ExprDelete(pParse->db, pStart);
810 }
811
812 return pWin;
813}
814
danc0bb4452018-06-12 20:53:38 +0000815/*
816** Attach window object pWin to expression p.
817*/
dan86fb6e12018-05-16 20:58:07 +0000818void sqlite3WindowAttach(Parse *pParse, Expr *p, Window *pWin){
819 if( p ){
820 p->pWin = pWin;
dan2a11bb22018-06-11 20:50:25 +0000821 if( pWin ) pWin->pOwner = p;
dan86fb6e12018-05-16 20:58:07 +0000822 }else{
823 sqlite3WindowDelete(pParse->db, pWin);
824 }
825}
dane2f781b2018-05-17 19:24:08 +0000826
827/*
828** Return 0 if the two window objects are identical, or non-zero otherwise.
829*/
830int sqlite3WindowCompare(Parse *pParse, Window *p1, Window *p2){
831 if( p1->eType!=p2->eType ) return 1;
832 if( p1->eStart!=p2->eStart ) return 1;
833 if( p1->eEnd!=p2->eEnd ) return 1;
834 if( sqlite3ExprCompare(pParse, p1->pStart, p2->pStart, -1) ) return 1;
835 if( sqlite3ExprCompare(pParse, p1->pEnd, p2->pEnd, -1) ) return 1;
836 if( sqlite3ExprListCompare(p1->pPartition, p2->pPartition, -1) ) return 1;
837 if( sqlite3ExprListCompare(p1->pOrderBy, p2->pOrderBy, -1) ) return 1;
838 return 0;
839}
840
danc9a86682018-05-30 20:44:58 +0000841static void windowAggInit(Parse *pParse, Window *pMWin){
842 Window *pWin;
843 for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
danec891fd2018-06-06 20:51:02 +0000844 Vdbe *v = sqlite3GetVdbe(pParse);
845 FuncDef *p = pWin->pFunc;
846 if( (p->funcFlags & SQLITE_FUNC_MINMAX) && pWin->eStart!=TK_UNBOUNDED ){
danc9a86682018-05-30 20:44:58 +0000847 ExprList *pList = pWin->pOwner->x.pList;
848 KeyInfo *pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pList, 0, 0);
danc9a86682018-05-30 20:44:58 +0000849 pWin->csrApp = pParse->nTab++;
850 pWin->regApp = pParse->nMem+1;
851 pParse->nMem += 3;
852 if( pKeyInfo && pWin->pFunc->zName[1]=='i' ){
853 assert( pKeyInfo->aSortOrder[0]==0 );
854 pKeyInfo->aSortOrder[0] = 1;
855 }
856 sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pWin->csrApp, 2);
857 sqlite3VdbeAppendP4(v, pKeyInfo, P4_KEYINFO);
858 sqlite3VdbeAddOp2(v, OP_Integer, 0, pWin->regApp+1);
859 }
dan7095c002018-06-07 17:45:22 +0000860 else if( p->xSFunc==nth_valueStepFunc || p->xSFunc==first_valueStepFunc ){
danec891fd2018-06-06 20:51:02 +0000861 /* Allocate two registers at pWin->regApp. These will be used to
862 ** store the start and end index of the current frame. */
863 assert( pMWin->iEphCsr );
864 pWin->regApp = pParse->nMem+1;
865 pWin->csrApp = pParse->nTab++;
866 pParse->nMem += 2;
danec891fd2018-06-06 20:51:02 +0000867 sqlite3VdbeAddOp2(v, OP_OpenDup, pWin->csrApp, pMWin->iEphCsr);
868 }
danfe4e25a2018-06-07 20:08:59 +0000869 else if( p->xSFunc==leadStepFunc || p->xSFunc==lagStepFunc ){
870 assert( pMWin->iEphCsr );
871 pWin->csrApp = pParse->nTab++;
872 sqlite3VdbeAddOp2(v, OP_OpenDup, pWin->csrApp, pMWin->iEphCsr);
873 }
danc9a86682018-05-30 20:44:58 +0000874 }
875}
876
danf9eae182018-05-21 19:45:11 +0000877void sqlite3WindowCodeInit(Parse *pParse, Window *pWin){
878 Vdbe *v = sqlite3GetVdbe(pParse);
879 int nPart = (pWin->pPartition ? pWin->pPartition->nExpr : 0);
880 nPart += (pWin->pOrderBy ? pWin->pOrderBy->nExpr : 0);
881 if( nPart ){
882 pWin->regPart = pParse->nMem+1;
883 pParse->nMem += nPart;
884 sqlite3VdbeAddOp3(v, OP_Null, 0, pWin->regPart, pWin->regPart+nPart-1);
885 }
danc9a86682018-05-30 20:44:58 +0000886 windowAggInit(pParse, pWin);
danf9eae182018-05-21 19:45:11 +0000887}
888
danc3a20c12018-05-23 20:55:37 +0000889static void windowCheckFrameValue(Parse *pParse, int reg, int bEnd){
890 static const char *azErr[] = {
891 "frame starting offset must be a non-negative integer",
892 "frame ending offset must be a non-negative integer"
893 };
894 Vdbe *v = sqlite3GetVdbe(pParse);
895 int regZero = ++pParse->nMem;
896
danc3a20c12018-05-23 20:55:37 +0000897 sqlite3VdbeAddOp2(v, OP_Integer, 0, regZero);
898 sqlite3VdbeAddOp2(v, OP_MustBeInt, reg, sqlite3VdbeCurrentAddr(v)+2);
899 sqlite3VdbeAddOp3(v, OP_Ge, regZero, sqlite3VdbeCurrentAddr(v)+2, reg);
900 sqlite3VdbeAddOp2(v, OP_Halt, SQLITE_ERROR, OE_Abort);
901 sqlite3VdbeAppendP4(v, (void*)azErr[bEnd], P4_STATIC);
902}
903
dan2a11bb22018-06-11 20:50:25 +0000904static int windowArgCount(Window *pWin){
905 ExprList *pList = pWin->pOwner->x.pList;
906 return (pList ? pList->nExpr : 0);
907}
908
danc9a86682018-05-30 20:44:58 +0000909/*
910** Generate VM code to invoke either xStep() (if bInverse is 0) or
911** xInverse (if bInverse is non-zero) for each window function in the
912** linked list starting at pMWin.
913*/
dan31f56392018-05-24 21:10:57 +0000914static void windowAggStep(
915 Parse *pParse,
916 Window *pMWin,
917 int csr,
918 int bInverse,
dandfa552f2018-06-02 21:04:28 +0000919 int reg,
920 int regPartSize /* Register containing size of partition */
dan31f56392018-05-24 21:10:57 +0000921){
922 Vdbe *v = sqlite3GetVdbe(pParse);
923 Window *pWin;
924 for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
dandfa552f2018-06-02 21:04:28 +0000925 int flags = pWin->pFunc->funcFlags;
danc9a86682018-05-30 20:44:58 +0000926 int regArg;
dan2a11bb22018-06-11 20:50:25 +0000927 int nArg = windowArgCount(pWin);
dandfa552f2018-06-02 21:04:28 +0000928
dan6bc5c9e2018-06-04 18:55:11 +0000929 if( csr>=0 ){
danc9a86682018-05-30 20:44:58 +0000930 int i;
dan2a11bb22018-06-11 20:50:25 +0000931 for(i=0; i<nArg; i++){
danc9a86682018-05-30 20:44:58 +0000932 sqlite3VdbeAddOp3(v, OP_Column, csr, pWin->iArgCol+i, reg+i);
933 }
934 regArg = reg;
dan6bc5c9e2018-06-04 18:55:11 +0000935 if( flags & SQLITE_FUNC_WINDOW_SIZE ){
936 if( nArg==0 ){
937 regArg = regPartSize;
938 }else{
939 sqlite3VdbeAddOp2(v, OP_SCopy, regPartSize, reg+nArg);
940 }
941 nArg++;
942 }
danc9a86682018-05-30 20:44:58 +0000943 }else{
dan6bc5c9e2018-06-04 18:55:11 +0000944 assert( !(flags & SQLITE_FUNC_WINDOW_SIZE) );
danc9a86682018-05-30 20:44:58 +0000945 regArg = reg + pWin->iArgCol;
dan31f56392018-05-24 21:10:57 +0000946 }
danc9a86682018-05-30 20:44:58 +0000947
danec891fd2018-06-06 20:51:02 +0000948 if( (pWin->pFunc->funcFlags & SQLITE_FUNC_MINMAX)
949 && pWin->eStart!=TK_UNBOUNDED
950 ){
danc9a86682018-05-30 20:44:58 +0000951 if( bInverse==0 ){
952 sqlite3VdbeAddOp2(v, OP_AddImm, pWin->regApp+1, 1);
953 sqlite3VdbeAddOp2(v, OP_SCopy, regArg, pWin->regApp);
954 sqlite3VdbeAddOp3(v, OP_MakeRecord, pWin->regApp, 2, pWin->regApp+2);
955 sqlite3VdbeAddOp2(v, OP_IdxInsert, pWin->csrApp, pWin->regApp+2);
956 }else{
957 sqlite3VdbeAddOp4Int(v, OP_SeekGE, pWin->csrApp, 0, regArg, 1);
958 sqlite3VdbeAddOp1(v, OP_Delete, pWin->csrApp);
959 sqlite3VdbeJumpHere(v, sqlite3VdbeCurrentAddr(v)-2);
960 }
danec891fd2018-06-06 20:51:02 +0000961 }else if( pWin->regApp ){
dan7095c002018-06-07 17:45:22 +0000962 assert( pWin->pFunc->xSFunc==nth_valueStepFunc
963 || pWin->pFunc->xSFunc==first_valueStepFunc
964 );
danec891fd2018-06-06 20:51:02 +0000965 assert( bInverse==0 || bInverse==1 );
966 sqlite3VdbeAddOp2(v, OP_AddImm, pWin->regApp+1-bInverse, 1);
danfe4e25a2018-06-07 20:08:59 +0000967 }else if( pWin->pFunc->xSFunc==leadStepFunc
968 || pWin->pFunc->xSFunc==lagStepFunc
969 ){
970 /* no-op */
danc9a86682018-05-30 20:44:58 +0000971 }else{
dan8b985602018-06-09 17:43:45 +0000972 int addrIf = 0;
973 if( pWin->pFilter ){
974 int regTmp;
dan2a11bb22018-06-11 20:50:25 +0000975 assert( nArg==pWin->pOwner->x.pList->nExpr );
dan8b985602018-06-09 17:43:45 +0000976 if( csr>0 ){
977 regTmp = sqlite3GetTempReg(pParse);
dan2a11bb22018-06-11 20:50:25 +0000978 sqlite3VdbeAddOp3(v, OP_Column, csr, pWin->iArgCol+nArg,regTmp);
dan8b985602018-06-09 17:43:45 +0000979 }else{
dan2a11bb22018-06-11 20:50:25 +0000980 regTmp = regArg + nArg;
dan8b985602018-06-09 17:43:45 +0000981 }
982 addrIf = sqlite3VdbeAddOp3(v, OP_IfNot, regTmp, 0, 1);
983 if( csr>0 ){
984 sqlite3ReleaseTempReg(pParse, regTmp);
985 }
986 }
danc9a86682018-05-30 20:44:58 +0000987 if( pWin->pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL ){
988 CollSeq *pColl;
dan8b985602018-06-09 17:43:45 +0000989 pColl = sqlite3ExprNNCollSeq(pParse, pWin->pOwner->x.pList->a[0].pExpr);
danc9a86682018-05-30 20:44:58 +0000990 sqlite3VdbeAddOp4(v, OP_CollSeq, 0,0,0, (const char*)pColl, P4_COLLSEQ);
991 }
992 sqlite3VdbeAddOp3(v, OP_AggStep0, bInverse, regArg, pWin->regAccum);
993 sqlite3VdbeAppendP4(v, pWin->pFunc, P4_FUNCDEF);
dandfa552f2018-06-02 21:04:28 +0000994 sqlite3VdbeChangeP5(v, (u8)nArg);
dan8b985602018-06-09 17:43:45 +0000995 if( addrIf ) sqlite3VdbeJumpHere(v, addrIf);
danc9a86682018-05-30 20:44:58 +0000996 }
dan31f56392018-05-24 21:10:57 +0000997 }
998}
999
dand6f784e2018-05-28 18:30:45 +00001000static void windowAggFinal(Parse *pParse, Window *pMWin, int bFinal){
1001 Vdbe *v = sqlite3GetVdbe(pParse);
1002 Window *pWin;
1003
1004 for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
danec891fd2018-06-06 20:51:02 +00001005 if( (pWin->pFunc->funcFlags & SQLITE_FUNC_MINMAX)
1006 && pWin->eStart!=TK_UNBOUNDED
1007 ){
dand6f784e2018-05-28 18:30:45 +00001008 sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regResult);
danc9a86682018-05-30 20:44:58 +00001009 sqlite3VdbeAddOp1(v, OP_Last, pWin->csrApp);
1010 sqlite3VdbeAddOp3(v, OP_Column, pWin->csrApp, 0, pWin->regResult);
1011 sqlite3VdbeJumpHere(v, sqlite3VdbeCurrentAddr(v)-2);
1012 if( bFinal ){
1013 sqlite3VdbeAddOp1(v, OP_ResetSorter, pWin->csrApp);
1014 }
danec891fd2018-06-06 20:51:02 +00001015 }else if( pWin->regApp ){
dand6f784e2018-05-28 18:30:45 +00001016 }else{
danc9a86682018-05-30 20:44:58 +00001017 if( bFinal==0 ){
1018 sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regResult);
1019 }
dan2a11bb22018-06-11 20:50:25 +00001020 sqlite3VdbeAddOp2(v, OP_AggFinal, pWin->regAccum, windowArgCount(pWin));
danc9a86682018-05-30 20:44:58 +00001021 sqlite3VdbeAppendP4(v, pWin->pFunc, P4_FUNCDEF);
1022 if( bFinal ){
1023 sqlite3VdbeAddOp2(v, OP_Copy, pWin->regAccum, pWin->regResult);
dan8b985602018-06-09 17:43:45 +00001024 sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regAccum);
danc9a86682018-05-30 20:44:58 +00001025 }else{
1026 sqlite3VdbeChangeP3(v, -1, pWin->regResult);
1027 }
dand6f784e2018-05-28 18:30:45 +00001028 }
1029 }
1030}
1031
danf690b572018-06-01 21:00:08 +00001032static void windowPartitionCache(
1033 Parse *pParse,
1034 Select *p,
1035 WhereInfo *pWInfo,
1036 int regFlushPart,
dandfa552f2018-06-02 21:04:28 +00001037 int lblFlushPart,
1038 int *pRegSize
danf690b572018-06-01 21:00:08 +00001039){
1040 Window *pMWin = p->pWin;
1041 Vdbe *v = sqlite3GetVdbe(pParse);
1042 Window *pWin;
1043 int iSubCsr = p->pSrc->a[0].iCursor;
1044 int nSub = p->pSrc->a[0].pTab->nCol;
1045 int k;
1046
1047 int reg = pParse->nMem+1;
1048 int regRecord = reg+nSub;
1049 int regRowid = regRecord+1;
1050
dandfa552f2018-06-02 21:04:28 +00001051 *pRegSize = regRowid;
danf690b572018-06-01 21:00:08 +00001052 pParse->nMem += nSub + 2;
1053
1054 /* Martial the row returned by the sub-select into an array of
1055 ** registers. */
1056 for(k=0; k<nSub; k++){
1057 sqlite3VdbeAddOp3(v, OP_Column, iSubCsr, k, reg+k);
1058 }
1059 sqlite3VdbeAddOp3(v, OP_MakeRecord, reg, nSub, regRecord);
1060
1061 /* Check if this is the start of a new partition. If so, call the
1062 ** flush_partition sub-routine. */
1063 if( pMWin->pPartition ){
1064 int addr;
1065 ExprList *pPart = pMWin->pPartition;
1066 int nPart = (pPart ? pPart->nExpr : 0);
1067 int regNewPart = reg + pMWin->nBufferCol;
1068 KeyInfo *pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pPart, 0, 0);
1069
1070 addr = sqlite3VdbeAddOp3(v, OP_Compare, regNewPart, pMWin->regPart,nPart);
1071 sqlite3VdbeAppendP4(v, (void*)pKeyInfo, P4_KEYINFO);
1072 sqlite3VdbeAddOp3(v, OP_Jump, addr+2, addr+4, addr+2);
1073 sqlite3VdbeAddOp3(v, OP_Copy, regNewPart, pMWin->regPart, nPart-1);
1074 sqlite3VdbeAddOp2(v, OP_Gosub, regFlushPart, lblFlushPart);
1075 }
1076
1077 /* Buffer the current row in the ephemeral table. */
1078 sqlite3VdbeAddOp2(v, OP_NewRowid, pMWin->iEphCsr, regRowid);
1079 sqlite3VdbeAddOp3(v, OP_Insert, pMWin->iEphCsr, regRecord, regRowid);
1080
1081 /* End of the input loop */
1082 sqlite3WhereEnd(pWInfo);
1083
1084 /* Invoke "flush_partition" to deal with the final (or only) partition */
1085 sqlite3VdbeAddOp2(v, OP_Gosub, regFlushPart, lblFlushPart);
1086}
dand6f784e2018-05-28 18:30:45 +00001087
danec891fd2018-06-06 20:51:02 +00001088static void windowReturnOneRow(
1089 Parse *pParse,
1090 Window *pMWin,
1091 int regGosub,
1092 int addrGosub
1093){
1094 Vdbe *v = sqlite3GetVdbe(pParse);
1095 Window *pWin;
1096 for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
1097 FuncDef *pFunc = pWin->pFunc;
dan7095c002018-06-07 17:45:22 +00001098 if( pFunc->xSFunc==nth_valueStepFunc
1099 || pFunc->xSFunc==first_valueStepFunc
1100 ){
danec891fd2018-06-06 20:51:02 +00001101 int csr = pWin->csrApp;
1102 int lbl = sqlite3VdbeMakeLabel(v);
1103 int tmpReg = sqlite3GetTempReg(pParse);
1104 sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regResult);
dan7095c002018-06-07 17:45:22 +00001105
1106 if( pFunc->xSFunc==nth_valueStepFunc ){
1107 sqlite3VdbeAddOp3(v, OP_Column, pWin->iEphCsr, pWin->iArgCol+1, tmpReg);
1108 }else{
1109 sqlite3VdbeAddOp2(v, OP_Integer, 1, tmpReg);
1110 }
danec891fd2018-06-06 20:51:02 +00001111 sqlite3VdbeAddOp3(v, OP_Add, tmpReg, pWin->regApp, tmpReg);
1112 sqlite3VdbeAddOp3(v, OP_Gt, pWin->regApp+1, lbl, tmpReg);
1113 sqlite3VdbeAddOp3(v, OP_SeekRowid, csr, lbl, tmpReg);
1114 sqlite3VdbeAddOp3(v, OP_Column, csr, pWin->iArgCol, pWin->regResult);
1115 sqlite3VdbeResolveLabel(v, lbl);
1116 sqlite3ReleaseTempReg(pParse, tmpReg);
1117 }
danfe4e25a2018-06-07 20:08:59 +00001118 else if( pFunc->xSFunc==leadStepFunc || pFunc->xSFunc==lagStepFunc ){
dan2a11bb22018-06-11 20:50:25 +00001119 int nArg = pWin->pOwner->x.pList->nExpr;
danfe4e25a2018-06-07 20:08:59 +00001120 int iEph = pWin->iEphCsr;
1121 int csr = pWin->csrApp;
1122 int lbl = sqlite3VdbeMakeLabel(v);
1123 int tmpReg = sqlite3GetTempReg(pParse);
1124
dan2a11bb22018-06-11 20:50:25 +00001125 if( nArg<3 ){
danfe4e25a2018-06-07 20:08:59 +00001126 sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regResult);
1127 }else{
1128 sqlite3VdbeAddOp3(v, OP_Column, iEph, pWin->iArgCol+2, pWin->regResult);
1129 }
1130 sqlite3VdbeAddOp2(v, OP_Rowid, iEph, tmpReg);
dan2a11bb22018-06-11 20:50:25 +00001131 if( nArg<2 ){
danfe4e25a2018-06-07 20:08:59 +00001132 int val = (pFunc->xSFunc==leadStepFunc ? 1 : -1);
1133 sqlite3VdbeAddOp2(v, OP_AddImm, tmpReg, val);
1134 }else{
1135 int op = (pFunc->xSFunc==leadStepFunc ? OP_Add : OP_Subtract);
1136 int tmpReg2 = sqlite3GetTempReg(pParse);
1137 sqlite3VdbeAddOp3(v, OP_Column, iEph, pWin->iArgCol+1, tmpReg2);
1138 sqlite3VdbeAddOp3(v, op, tmpReg2, tmpReg, tmpReg);
1139 sqlite3ReleaseTempReg(pParse, tmpReg2);
1140 }
1141
1142 sqlite3VdbeAddOp3(v, OP_SeekRowid, csr, lbl, tmpReg);
1143 sqlite3VdbeAddOp3(v, OP_Column, csr, pWin->iArgCol, pWin->regResult);
1144 sqlite3VdbeResolveLabel(v, lbl);
1145 sqlite3ReleaseTempReg(pParse, tmpReg);
1146 }
danec891fd2018-06-06 20:51:02 +00001147 }
1148 sqlite3VdbeAddOp2(v, OP_Gosub, regGosub, addrGosub);
1149}
1150
1151static void windowReturnRows(
1152 Parse *pParse,
1153 Window *pMWin,
1154 int regCtr,
1155 int bFinal,
1156 int regGosub,
1157 int addrGosub,
1158 int regInvArg,
1159 int regInvSize
1160){
1161 int addr;
1162 Vdbe *v = sqlite3GetVdbe(pParse);
1163 windowAggFinal(pParse, pMWin, 0);
1164 addr = sqlite3VdbeAddOp3(v, OP_IfPos, regCtr, sqlite3VdbeCurrentAddr(v)+2 ,1);
1165 sqlite3VdbeAddOp2(v, OP_Goto, 0, 0);
1166 windowReturnOneRow(pParse, pMWin, regGosub, addrGosub);
1167 if( regInvArg ){
1168 windowAggStep(pParse, pMWin, pMWin->iEphCsr, 1, regInvArg, regInvSize);
1169 }
1170 sqlite3VdbeAddOp2(v, OP_Next, pMWin->iEphCsr, addr);
1171 sqlite3VdbeJumpHere(v, addr+1); /* The OP_Goto */
1172}
1173
dan2e605682018-06-07 15:54:26 +00001174static int windowInitAccum(Parse *pParse, Window *pMWin){
1175 Vdbe *v = sqlite3GetVdbe(pParse);
1176 int regArg;
1177 int nArg = 0;
1178 Window *pWin;
1179 for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
1180 sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regAccum);
dan2a11bb22018-06-11 20:50:25 +00001181 nArg = MAX(nArg, windowArgCount(pWin));
dan7095c002018-06-07 17:45:22 +00001182 if( pWin->pFunc->xSFunc==nth_valueStepFunc
1183 || pWin->pFunc->xSFunc==first_valueStepFunc
1184 ){
dan2e605682018-06-07 15:54:26 +00001185 sqlite3VdbeAddOp2(v, OP_Integer, 0, pWin->regApp);
1186 sqlite3VdbeAddOp2(v, OP_Integer, 0, pWin->regApp+1);
1187 }
1188 }
1189 regArg = pParse->nMem+1;
1190 pParse->nMem += nArg;
1191 return regArg;
1192}
1193
1194
dan99652dd2018-05-24 17:49:14 +00001195/*
dan09590aa2018-05-25 20:30:17 +00001196** ROWS BETWEEN <expr1> PRECEDING AND <expr2> FOLLOWING
1197** ----------------------------------------------------
dan99652dd2018-05-24 17:49:14 +00001198**
dan09590aa2018-05-25 20:30:17 +00001199** Pseudo-code for the implementation of this window frame type is as
1200** follows. sqlite3WhereBegin() has already been called to generate the
1201** top of the main loop when this function is called.
1202**
1203** Each time the sub-routine at addrGosub is invoked, a single output
1204** row is generated based on the current row indicated by Window.iEphCsr.
1205**
1206** ...
1207** if( new partition ){
1208** Gosub flush_partition
1209** }
1210** Insert (record in eph-table)
1211** sqlite3WhereEnd()
1212** Gosub flush_partition
1213**
1214** flush_partition:
1215** Once {
1216** OpenDup (iEphCsr -> csrStart)
1217** OpenDup (iEphCsr -> csrEnd)
dan99652dd2018-05-24 17:49:14 +00001218** }
dan09590aa2018-05-25 20:30:17 +00001219** regStart = <expr1> // PRECEDING expression
1220** regEnd = <expr2> // FOLLOWING expression
1221** if( regStart<0 || regEnd<0 ){ error! }
1222** Rewind (csr,csrStart,csrEnd) // if EOF goto flush_partition_done
1223** Next(csrEnd) // if EOF skip Aggstep
1224** Aggstep (csrEnd)
1225** if( (regEnd--)<=0 ){
1226** AggFinal (xValue)
1227** Gosub addrGosub
1228** Next(csr) // if EOF goto flush_partition_done
1229** if( (regStart--)<=0 ){
1230** AggStep (csrStart, xInverse)
1231** Next(csrStart)
1232** }
1233** }
1234** flush_partition_done:
1235** ResetSorter (csr)
1236** Return
dan99652dd2018-05-24 17:49:14 +00001237**
dan09590aa2018-05-25 20:30:17 +00001238** ROWS BETWEEN <expr> PRECEDING AND CURRENT ROW
1239** ROWS BETWEEN CURRENT ROW AND <expr> FOLLOWING
1240** ROWS BETWEEN UNBOUNDED PRECEDING AND <expr> FOLLOWING
1241**
1242** These are similar to the above. For "CURRENT ROW", intialize the
1243** register to 0. For "UNBOUNDED PRECEDING" to infinity.
1244**
1245** ROWS BETWEEN <expr> PRECEDING AND UNBOUNDED FOLLOWING
1246** ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING
1247**
1248** Rewind (csr,csrStart,csrEnd) // if EOF goto flush_partition_done
1249** while( 1 ){
1250** Next(csrEnd) // Exit while(1) at EOF
1251** Aggstep (csrEnd)
1252** }
1253** while( 1 ){
dan99652dd2018-05-24 17:49:14 +00001254** AggFinal (xValue)
1255** Gosub addrGosub
dan09590aa2018-05-25 20:30:17 +00001256** Next(csr) // if EOF goto flush_partition_done
dan31f56392018-05-24 21:10:57 +00001257** if( (regStart--)<=0 ){
1258** AggStep (csrStart, xInverse)
1259** Next(csrStart)
dan99652dd2018-05-24 17:49:14 +00001260** }
1261** }
dan99652dd2018-05-24 17:49:14 +00001262**
dan09590aa2018-05-25 20:30:17 +00001263** For the "CURRENT ROW AND UNBOUNDED FOLLOWING" case, the final if()
1264** condition is always true (as if regStart were initialized to 0).
dan99652dd2018-05-24 17:49:14 +00001265**
dan09590aa2018-05-25 20:30:17 +00001266** RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING
1267**
1268** This is the only RANGE case handled by this routine. It modifies the
1269** second while( 1 ) loop in "ROWS BETWEEN CURRENT ... UNBOUNDED..." to
1270** be:
1271**
1272** while( 1 ){
1273** AggFinal (xValue)
1274** while( 1 ){
1275** regPeer++
1276** Gosub addrGosub
1277** Next(csr) // if EOF goto flush_partition_done
1278** if( new peer ) break;
1279** }
1280** while( (regPeer--)>0 ){
1281** AggStep (csrStart, xInverse)
1282** Next(csrStart)
1283** }
1284** }
dan99652dd2018-05-24 17:49:14 +00001285**
dan31f56392018-05-24 21:10:57 +00001286** ROWS BETWEEN <expr> FOLLOWING AND <expr> FOLLOWING
1287**
1288** regEnd = regEnd - regStart
1289** Rewind (csr,csrStart,csrEnd) // if EOF goto flush_partition_done
1290** Aggstep (csrEnd)
1291** Next(csrEnd) // if EOF fall-through
1292** if( (regEnd--)<=0 ){
dan31f56392018-05-24 21:10:57 +00001293** if( (regStart--)<=0 ){
1294** AggFinal (xValue)
1295** Gosub addrGosub
1296** Next(csr) // if EOF goto flush_partition_done
1297** }
dane105dd72018-05-25 09:29:11 +00001298** AggStep (csrStart, xInverse)
1299** Next (csrStart)
dan31f56392018-05-24 21:10:57 +00001300** }
1301**
1302** ROWS BETWEEN <expr> PRECEDING AND <expr> PRECEDING
1303**
1304** Replace the bit after "Rewind" in the above with:
1305**
1306** if( (regEnd--)<=0 ){
1307** AggStep (csrEnd)
1308** Next (csrEnd)
1309** }
1310** AggFinal (xValue)
1311** Gosub addrGosub
1312** Next(csr) // if EOF goto flush_partition_done
1313** if( (regStart--)<=0 ){
1314** AggStep (csr2, xInverse)
1315** Next (csr2)
1316** }
1317**
dan99652dd2018-05-24 17:49:14 +00001318*/
danc3a20c12018-05-23 20:55:37 +00001319static void windowCodeRowExprStep(
1320 Parse *pParse,
1321 Select *p,
1322 WhereInfo *pWInfo,
1323 int regGosub,
1324 int addrGosub
1325){
1326 Window *pMWin = p->pWin;
1327 Vdbe *v = sqlite3GetVdbe(pParse);
1328 Window *pWin;
1329 int k;
danc3a20c12018-05-23 20:55:37 +00001330 int nSub = p->pSrc->a[0].pTab->nCol;
1331 int regFlushPart; /* Register for "Gosub flush_partition" */
dan31f56392018-05-24 21:10:57 +00001332 int lblFlushPart; /* Label for "Gosub flush_partition" */
1333 int lblFlushDone; /* Label for "Gosub flush_partition_done" */
danc3a20c12018-05-23 20:55:37 +00001334
danf690b572018-06-01 21:00:08 +00001335 int regArg;
1336 int nArg;
danc3a20c12018-05-23 20:55:37 +00001337 int addr;
dan31f56392018-05-24 21:10:57 +00001338 int csrStart = pParse->nTab++;
1339 int csrEnd = pParse->nTab++;
1340 int regStart; /* Value of <expr> PRECEDING */
1341 int regEnd; /* Value of <expr> FOLLOWING */
danc3a20c12018-05-23 20:55:37 +00001342 int addrNext;
1343 int addrGoto;
dan31f56392018-05-24 21:10:57 +00001344 int addrTop;
danc3a20c12018-05-23 20:55:37 +00001345 int addrIfPos1;
1346 int addrIfPos2;
1347
dan09590aa2018-05-25 20:30:17 +00001348 int regPeer = 0; /* Number of peers in current group */
1349 int regPeerVal = 0; /* Array of values identifying peer group */
1350 int iPeer = 0; /* Column offset in eph-table of peer vals */
1351 int nPeerVal; /* Number of peer values */
dand6f784e2018-05-28 18:30:45 +00001352 int bRange = 0;
dandfa552f2018-06-02 21:04:28 +00001353 int regSize = 0;
dan09590aa2018-05-25 20:30:17 +00001354
dan99652dd2018-05-24 17:49:14 +00001355 assert( pMWin->eStart==TK_PRECEDING
1356 || pMWin->eStart==TK_CURRENT
dane105dd72018-05-25 09:29:11 +00001357 || pMWin->eStart==TK_FOLLOWING
dan99652dd2018-05-24 17:49:14 +00001358 || pMWin->eStart==TK_UNBOUNDED
1359 );
1360 assert( pMWin->eEnd==TK_FOLLOWING
1361 || pMWin->eEnd==TK_CURRENT
1362 || pMWin->eEnd==TK_UNBOUNDED
dan31f56392018-05-24 21:10:57 +00001363 || pMWin->eEnd==TK_PRECEDING
dan99652dd2018-05-24 17:49:14 +00001364 );
1365
dand6f784e2018-05-28 18:30:45 +00001366 if( pMWin->eType==TK_RANGE
1367 && pMWin->eStart==TK_CURRENT
1368 && pMWin->eEnd==TK_UNBOUNDED
1369 ){
1370 bRange = 1;
1371 }
1372
danc3a20c12018-05-23 20:55:37 +00001373 /* Allocate register and label for the "flush_partition" sub-routine. */
1374 regFlushPart = ++pParse->nMem;
dan31f56392018-05-24 21:10:57 +00001375 lblFlushPart = sqlite3VdbeMakeLabel(v);
1376 lblFlushDone = sqlite3VdbeMakeLabel(v);
danc3a20c12018-05-23 20:55:37 +00001377
dan31f56392018-05-24 21:10:57 +00001378 regStart = ++pParse->nMem;
1379 regEnd = ++pParse->nMem;
danc3a20c12018-05-23 20:55:37 +00001380
dandfa552f2018-06-02 21:04:28 +00001381 windowPartitionCache(pParse, p, pWInfo, regFlushPart, lblFlushPart, &regSize);
danc3a20c12018-05-23 20:55:37 +00001382
danc3a20c12018-05-23 20:55:37 +00001383 addrGoto = sqlite3VdbeAddOp0(v, OP_Goto);
1384
danc9a86682018-05-30 20:44:58 +00001385 /* Start of "flush_partition" */
dan31f56392018-05-24 21:10:57 +00001386 sqlite3VdbeResolveLabel(v, lblFlushPart);
danc3a20c12018-05-23 20:55:37 +00001387 sqlite3VdbeAddOp2(v, OP_Once, 0, sqlite3VdbeCurrentAddr(v)+3);
dan31f56392018-05-24 21:10:57 +00001388 sqlite3VdbeAddOp2(v, OP_OpenDup, csrStart, pMWin->iEphCsr);
1389 sqlite3VdbeAddOp2(v, OP_OpenDup, csrEnd, pMWin->iEphCsr);
danc3a20c12018-05-23 20:55:37 +00001390
dan31f56392018-05-24 21:10:57 +00001391 /* If either regStart or regEnd are not non-negative integers, throw
dan99652dd2018-05-24 17:49:14 +00001392 ** an exception. */
1393 if( pMWin->pStart ){
dan31f56392018-05-24 21:10:57 +00001394 sqlite3ExprCode(pParse, pMWin->pStart, regStart);
1395 windowCheckFrameValue(pParse, regStart, 0);
dan99652dd2018-05-24 17:49:14 +00001396 }
1397 if( pMWin->pEnd ){
dan31f56392018-05-24 21:10:57 +00001398 sqlite3ExprCode(pParse, pMWin->pEnd, regEnd);
1399 windowCheckFrameValue(pParse, regEnd, 1);
dan99652dd2018-05-24 17:49:14 +00001400 }
danc3a20c12018-05-23 20:55:37 +00001401
danc9a86682018-05-30 20:44:58 +00001402 /* If this is "ROWS <expr1> FOLLOWING AND ROWS <expr2> FOLLOWING", do:
1403 **
dan26522d12018-06-11 18:16:51 +00001404 ** if( regEnd<regStart ){
1405 ** // The frame always consists of 0 rows
1406 ** regStart = regSize;
1407 ** }
danc9a86682018-05-30 20:44:58 +00001408 ** regEnd = regEnd - regStart;
1409 */
1410 if( pMWin->pEnd && pMWin->pStart && pMWin->eStart==TK_FOLLOWING ){
1411 assert( pMWin->eEnd==TK_FOLLOWING );
dan26522d12018-06-11 18:16:51 +00001412 sqlite3VdbeAddOp3(v, OP_Ge, regStart, sqlite3VdbeCurrentAddr(v)+2, regEnd);
1413 sqlite3VdbeAddOp2(v, OP_Copy, regSize, regStart);
danc9a86682018-05-30 20:44:58 +00001414 sqlite3VdbeAddOp3(v, OP_Subtract, regStart, regEnd, regEnd);
1415 }
1416
dan26522d12018-06-11 18:16:51 +00001417 if( pMWin->pEnd && pMWin->pStart && pMWin->eEnd==TK_PRECEDING ){
1418 assert( pMWin->eStart==TK_PRECEDING );
1419 sqlite3VdbeAddOp3(v, OP_Le, regStart, sqlite3VdbeCurrentAddr(v)+3, regEnd);
1420 sqlite3VdbeAddOp2(v, OP_Copy, regSize, regStart);
1421 sqlite3VdbeAddOp2(v, OP_Copy, regSize, regEnd);
1422 }
1423
danc9a86682018-05-30 20:44:58 +00001424 /* Initialize the accumulator register for each window function to NULL */
dan2e605682018-06-07 15:54:26 +00001425 regArg = windowInitAccum(pParse, pMWin);
danc3a20c12018-05-23 20:55:37 +00001426
dan31f56392018-05-24 21:10:57 +00001427 sqlite3VdbeAddOp2(v, OP_Rewind, pMWin->iEphCsr, lblFlushDone);
1428 sqlite3VdbeAddOp2(v, OP_Rewind, csrStart, lblFlushDone);
danc3a20c12018-05-23 20:55:37 +00001429 sqlite3VdbeChangeP5(v, 1);
dan31f56392018-05-24 21:10:57 +00001430 sqlite3VdbeAddOp2(v, OP_Rewind, csrEnd, lblFlushDone);
danc3a20c12018-05-23 20:55:37 +00001431 sqlite3VdbeChangeP5(v, 1);
1432
1433 /* Invoke AggStep function for each window function using the row that
dan31f56392018-05-24 21:10:57 +00001434 ** csrEnd currently points to. Or, if csrEnd is already at EOF,
danc3a20c12018-05-23 20:55:37 +00001435 ** do nothing. */
dan31f56392018-05-24 21:10:57 +00001436 addrTop = sqlite3VdbeCurrentAddr(v);
1437 if( pMWin->eEnd==TK_PRECEDING ){
1438 addrIfPos1 = sqlite3VdbeAddOp3(v, OP_IfPos, regEnd, 0 , 1);
danc3a20c12018-05-23 20:55:37 +00001439 }
dan31f56392018-05-24 21:10:57 +00001440 sqlite3VdbeAddOp2(v, OP_Next, csrEnd, sqlite3VdbeCurrentAddr(v)+2);
1441 addr = sqlite3VdbeAddOp0(v, OP_Goto);
dandfa552f2018-06-02 21:04:28 +00001442 windowAggStep(pParse, pMWin, csrEnd, 0, regArg, regSize);
dan99652dd2018-05-24 17:49:14 +00001443 if( pMWin->eEnd==TK_UNBOUNDED ){
dan31f56392018-05-24 21:10:57 +00001444 sqlite3VdbeAddOp2(v, OP_Goto, 0, addrTop);
1445 sqlite3VdbeJumpHere(v, addr);
1446 addrTop = sqlite3VdbeCurrentAddr(v);
dan99652dd2018-05-24 17:49:14 +00001447 }else{
dan31f56392018-05-24 21:10:57 +00001448 sqlite3VdbeJumpHere(v, addr);
1449 if( pMWin->eEnd==TK_PRECEDING ){
1450 sqlite3VdbeJumpHere(v, addrIfPos1);
1451 }
dan99652dd2018-05-24 17:49:14 +00001452 }
danc3a20c12018-05-23 20:55:37 +00001453
dan99652dd2018-05-24 17:49:14 +00001454 if( pMWin->eEnd==TK_FOLLOWING ){
dan31f56392018-05-24 21:10:57 +00001455 addrIfPos1 = sqlite3VdbeAddOp3(v, OP_IfPos, regEnd, 0 , 1);
dan99652dd2018-05-24 17:49:14 +00001456 }
dane105dd72018-05-25 09:29:11 +00001457 if( pMWin->eStart==TK_FOLLOWING ){
1458 addrIfPos2 = sqlite3VdbeAddOp3(v, OP_IfPos, regStart, 0 , 1);
1459 }
dand6f784e2018-05-28 18:30:45 +00001460 if( bRange ){
dan09590aa2018-05-25 20:30:17 +00001461 assert( pMWin->eStart==TK_CURRENT && pMWin->pOrderBy );
1462 regPeer = ++pParse->nMem;
1463 regPeerVal = pParse->nMem+1;
1464 iPeer = pMWin->nBufferCol + (pMWin->pPartition?pMWin->pPartition->nExpr:0);
1465 nPeerVal = pMWin->pOrderBy->nExpr;
1466 pParse->nMem += (2 * nPeerVal);
1467 for(k=0; k<nPeerVal; k++){
1468 sqlite3VdbeAddOp3(v, OP_Column, pMWin->iEphCsr, iPeer+k, regPeerVal+k);
1469 }
1470 sqlite3VdbeAddOp2(v, OP_Integer, 0, regPeer);
1471 }
danec891fd2018-06-06 20:51:02 +00001472
dand6f784e2018-05-28 18:30:45 +00001473 windowAggFinal(pParse, pMWin, 0);
1474 if( bRange ){
dan09590aa2018-05-25 20:30:17 +00001475 sqlite3VdbeAddOp2(v, OP_AddImm, regPeer, 1);
1476 }
danec891fd2018-06-06 20:51:02 +00001477 windowReturnOneRow(pParse, pMWin, regGosub, addrGosub);
danc3a20c12018-05-23 20:55:37 +00001478 sqlite3VdbeAddOp2(v, OP_Next, pMWin->iEphCsr, sqlite3VdbeCurrentAddr(v)+2);
dan31f56392018-05-24 21:10:57 +00001479 sqlite3VdbeAddOp2(v, OP_Goto, 0, lblFlushDone);
dand6f784e2018-05-28 18:30:45 +00001480 if( bRange ){
dan09590aa2018-05-25 20:30:17 +00001481 KeyInfo *pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pMWin->pOrderBy,0,0);
1482 int addrJump = sqlite3VdbeCurrentAddr(v)-4;
1483 for(k=0; k<nPeerVal; k++){
1484 int iOut = regPeerVal + nPeerVal + k;
1485 sqlite3VdbeAddOp3(v, OP_Column, pMWin->iEphCsr, iPeer+k, iOut);
1486 }
1487 sqlite3VdbeAddOp3(v, OP_Compare, regPeerVal, regPeerVal+nPeerVal, nPeerVal);
1488 sqlite3VdbeAppendP4(v, (void*)pKeyInfo, P4_KEYINFO);
1489 addr = sqlite3VdbeCurrentAddr(v)+1;
1490 sqlite3VdbeAddOp3(v, OP_Jump, addr, addrJump, addr);
1491 }
dane105dd72018-05-25 09:29:11 +00001492 if( pMWin->eStart==TK_FOLLOWING ){
1493 sqlite3VdbeJumpHere(v, addrIfPos2);
1494 }
danc3a20c12018-05-23 20:55:37 +00001495
dane105dd72018-05-25 09:29:11 +00001496 if( pMWin->eStart==TK_CURRENT
1497 || pMWin->eStart==TK_PRECEDING
1498 || pMWin->eStart==TK_FOLLOWING
1499 ){
dan09590aa2018-05-25 20:30:17 +00001500 int addrJumpHere = 0;
dan99652dd2018-05-24 17:49:14 +00001501 if( pMWin->eStart==TK_PRECEDING ){
dan09590aa2018-05-25 20:30:17 +00001502 addrJumpHere = sqlite3VdbeAddOp3(v, OP_IfPos, regStart, 0 , 1);
1503 }
dand6f784e2018-05-28 18:30:45 +00001504 if( bRange ){
dan09590aa2018-05-25 20:30:17 +00001505 sqlite3VdbeAddOp3(v, OP_IfPos, regPeer, sqlite3VdbeCurrentAddr(v)+2, 1);
1506 addrJumpHere = sqlite3VdbeAddOp0(v, OP_Goto);
danc3a20c12018-05-23 20:55:37 +00001507 }
dan31f56392018-05-24 21:10:57 +00001508 sqlite3VdbeAddOp2(v, OP_Next, csrStart, sqlite3VdbeCurrentAddr(v)+1);
dandfa552f2018-06-02 21:04:28 +00001509 windowAggStep(pParse, pMWin, csrStart, 1, regArg, regSize);
dand6f784e2018-05-28 18:30:45 +00001510 if( bRange ){
dan09590aa2018-05-25 20:30:17 +00001511 sqlite3VdbeAddOp2(v, OP_Goto, 0, addrJumpHere-1);
1512 }
1513 if( addrJumpHere ){
1514 sqlite3VdbeJumpHere(v, addrJumpHere);
dan99652dd2018-05-24 17:49:14 +00001515 }
danc3a20c12018-05-23 20:55:37 +00001516 }
dan99652dd2018-05-24 17:49:14 +00001517 if( pMWin->eEnd==TK_FOLLOWING ){
1518 sqlite3VdbeJumpHere(v, addrIfPos1);
1519 }
dan31f56392018-05-24 21:10:57 +00001520 sqlite3VdbeAddOp2(v, OP_Goto, 0, addrTop);
danc3a20c12018-05-23 20:55:37 +00001521
1522 /* flush_partition_done: */
dan31f56392018-05-24 21:10:57 +00001523 sqlite3VdbeResolveLabel(v, lblFlushDone);
danc3a20c12018-05-23 20:55:37 +00001524 sqlite3VdbeAddOp1(v, OP_ResetSorter, pMWin->iEphCsr);
1525 sqlite3VdbeAddOp1(v, OP_Return, regFlushPart);
1526
1527 /* Jump to here to skip over flush_partition */
1528 sqlite3VdbeJumpHere(v, addrGoto);
1529}
1530
dan79d45442018-05-26 21:17:29 +00001531/*
1532** RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
1533**
danf690b572018-06-01 21:00:08 +00001534** flush_partition:
1535** Once {
1536** OpenDup (iEphCsr -> csrLead)
1537** }
1538** Integer ctr 0
1539** foreach row (csrLead){
1540** if( new peer ){
1541** AggFinal (xValue)
1542** for(i=0; i<ctr; i++){
1543** Gosub addrGosub
1544** Next iEphCsr
1545** }
1546** Integer ctr 0
1547** }
1548** AggStep (csrLead)
1549** Incr ctr
1550** }
1551**
1552** AggFinal (xFinalize)
1553** for(i=0; i<ctr; i++){
1554** Gosub addrGosub
1555** Next iEphCsr
1556** }
1557**
1558** ResetSorter (csr)
1559** Return
1560**
1561** ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
1562** RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
1563** RANGE BETWEEN CURRENT ROW AND CURRENT ROW
1564**
1565** TODO.
1566*/
1567static void windowCodeCacheStep(
1568 Parse *pParse,
1569 Select *p,
1570 WhereInfo *pWInfo,
1571 int regGosub,
1572 int addrGosub
1573){
1574 Window *pMWin = p->pWin;
1575 Vdbe *v = sqlite3GetVdbe(pParse);
1576 Window *pWin;
1577 int k;
1578 int addr;
1579 ExprList *pPart = pMWin->pPartition;
1580 ExprList *pOrderBy = pMWin->pOrderBy;
1581 int nPeer = pOrderBy->nExpr;
1582 int regNewPeer;
1583
1584 int addrGoto; /* Address of Goto used to jump flush_par.. */
1585 int addrRewind; /* Address of Rewind that starts loop */
1586 int regFlushPart;
1587 int lblFlushPart;
1588 int csrLead;
1589 int regCtr;
1590 int regArg; /* Register array to martial function args */
dandfa552f2018-06-02 21:04:28 +00001591 int regSize;
danf690b572018-06-01 21:00:08 +00001592 int nArg;
1593
1594 assert( (pMWin->eStart==TK_UNBOUNDED && pMWin->eEnd==TK_CURRENT)
danec891fd2018-06-06 20:51:02 +00001595 || (pMWin->eStart==TK_UNBOUNDED && pMWin->eEnd==TK_UNBOUNDED)
1596 || (pMWin->eStart==TK_CURRENT && pMWin->eEnd==TK_CURRENT)
danf690b572018-06-01 21:00:08 +00001597 );
1598
1599 regNewPeer = pParse->nMem+1;
1600 pParse->nMem += nPeer;
1601
1602 /* Allocate register and label for the "flush_partition" sub-routine. */
1603 regFlushPart = ++pParse->nMem;
1604 lblFlushPart = sqlite3VdbeMakeLabel(v);
1605
1606 csrLead = pParse->nTab++;
1607 regCtr = ++pParse->nMem;
1608
dandfa552f2018-06-02 21:04:28 +00001609 windowPartitionCache(pParse, p, pWInfo, regFlushPart, lblFlushPart, &regSize);
danf690b572018-06-01 21:00:08 +00001610 addrGoto = sqlite3VdbeAddOp0(v, OP_Goto);
1611
1612 /* Start of "flush_partition" */
1613 sqlite3VdbeResolveLabel(v, lblFlushPart);
1614 sqlite3VdbeAddOp2(v, OP_Once, 0, sqlite3VdbeCurrentAddr(v)+2);
1615 sqlite3VdbeAddOp2(v, OP_OpenDup, csrLead, pMWin->iEphCsr);
1616
1617 /* Initialize the accumulator register for each window function to NULL */
dan2e605682018-06-07 15:54:26 +00001618 regArg = windowInitAccum(pParse, pMWin);
danf690b572018-06-01 21:00:08 +00001619
1620 sqlite3VdbeAddOp2(v, OP_Integer, 0, regCtr);
1621 addrRewind = sqlite3VdbeAddOp1(v, OP_Rewind, csrLead);
1622 sqlite3VdbeAddOp1(v, OP_Rewind, pMWin->iEphCsr);
1623
danec891fd2018-06-06 20:51:02 +00001624 if( pOrderBy && pMWin->eEnd==TK_CURRENT ){
1625 int bCurrent = (pMWin->eEnd==TK_CURRENT && pMWin->eStart==TK_CURRENT);
1626 int addrJump = 0; /* Address of OP_Jump below */
1627 if( pMWin->eType==TK_RANGE ){
1628 int iOff = pMWin->nBufferCol + (pPart ? pPart->nExpr : 0);
1629 int regPeer = pMWin->regPart + (pPart ? pPart->nExpr : 0);
1630 KeyInfo *pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pOrderBy, 0, 0);
1631 for(k=0; k<nPeer; k++){
1632 sqlite3VdbeAddOp3(v, OP_Column, csrLead, iOff+k, regNewPeer+k);
1633 }
1634 addr = sqlite3VdbeAddOp3(v, OP_Compare, regNewPeer, regPeer, nPeer);
1635 sqlite3VdbeAppendP4(v, (void*)pKeyInfo, P4_KEYINFO);
1636 addrJump = sqlite3VdbeAddOp3(v, OP_Jump, addr+2, 0, addr+2);
1637 sqlite3VdbeAddOp3(v, OP_Copy, regNewPeer, regPeer, nPeer-1);
danf690b572018-06-01 21:00:08 +00001638 }
1639
danec891fd2018-06-06 20:51:02 +00001640 windowReturnRows(pParse, pMWin, regCtr, 0, regGosub, addrGosub,
1641 (bCurrent ? regArg : 0), (bCurrent ? regSize : 0)
1642 );
1643 if( addrJump ) sqlite3VdbeJumpHere(v, addrJump);
danf690b572018-06-01 21:00:08 +00001644 }
1645
dandfa552f2018-06-02 21:04:28 +00001646 windowAggStep(pParse, pMWin, csrLead, 0, regArg, regSize);
danf690b572018-06-01 21:00:08 +00001647 sqlite3VdbeAddOp2(v, OP_AddImm, regCtr, 1);
danf690b572018-06-01 21:00:08 +00001648 sqlite3VdbeAddOp2(v, OP_Next, csrLead, addrRewind+2);
1649
danec891fd2018-06-06 20:51:02 +00001650 windowReturnRows(pParse, pMWin, regCtr, 1, regGosub, addrGosub, 0, 0);
danf690b572018-06-01 21:00:08 +00001651
1652 sqlite3VdbeJumpHere(v, addrRewind);
1653 sqlite3VdbeJumpHere(v, addrRewind+1);
1654 sqlite3VdbeAddOp1(v, OP_ResetSorter, pMWin->iEphCsr);
1655 sqlite3VdbeAddOp1(v, OP_Return, regFlushPart);
1656
1657 /* Jump to here to skip over flush_partition */
1658 sqlite3VdbeJumpHere(v, addrGoto);
1659}
1660
1661
1662/*
1663** RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
1664**
dan79d45442018-05-26 21:17:29 +00001665** ...
1666** if( new partition ){
1667** AggFinal (xFinalize)
1668** Gosub addrGosub
1669** ResetSorter eph-table
1670** }
1671** else if( new peer ){
1672** AggFinal (xValue)
1673** Gosub addrGosub
1674** ResetSorter eph-table
1675** }
1676** AggStep
1677** Insert (record into eph-table)
1678** sqlite3WhereEnd()
1679** AggFinal (xFinalize)
1680** Gosub addrGosub
danf690b572018-06-01 21:00:08 +00001681**
1682** RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
1683**
1684** As above, except take no action for a "new peer". Invoke
1685** the sub-routine once only for each partition.
1686**
1687** RANGE BETWEEN CURRENT ROW AND CURRENT ROW
1688**
1689** As above, except that the "new peer" condition is handled in the
1690** same way as "new partition" (so there is no "else if" block).
1691**
1692** ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
1693**
1694** As above, except assume every row is a "new peer".
dan79d45442018-05-26 21:17:29 +00001695*/
danc3a20c12018-05-23 20:55:37 +00001696static void windowCodeDefaultStep(
1697 Parse *pParse,
1698 Select *p,
1699 WhereInfo *pWInfo,
1700 int regGosub,
1701 int addrGosub
1702){
1703 Window *pMWin = p->pWin;
1704 Vdbe *v = sqlite3GetVdbe(pParse);
1705 Window *pWin;
1706 int k;
1707 int iSubCsr = p->pSrc->a[0].iCursor;
1708 int nSub = p->pSrc->a[0].pTab->nCol;
1709 int reg = pParse->nMem+1;
1710 int regRecord = reg+nSub;
1711 int regRowid = regRecord+1;
1712 int addr;
dand6f784e2018-05-28 18:30:45 +00001713 ExprList *pPart = pMWin->pPartition;
1714 ExprList *pOrderBy = pMWin->pOrderBy;
danc3a20c12018-05-23 20:55:37 +00001715
dan79d45442018-05-26 21:17:29 +00001716 assert( pMWin->eType==TK_RANGE
1717 || (pMWin->eStart==TK_UNBOUNDED && pMWin->eEnd==TK_CURRENT)
1718 );
1719
dand6f784e2018-05-28 18:30:45 +00001720 assert( (pMWin->eStart==TK_UNBOUNDED && pMWin->eEnd==TK_CURRENT)
1721 || (pMWin->eStart==TK_UNBOUNDED && pMWin->eEnd==TK_UNBOUNDED)
1722 || (pMWin->eStart==TK_CURRENT && pMWin->eEnd==TK_CURRENT)
1723 || (pMWin->eStart==TK_CURRENT && pMWin->eEnd==TK_UNBOUNDED && !pOrderBy)
1724 );
1725
1726 if( pMWin->eEnd==TK_UNBOUNDED ){
1727 pOrderBy = 0;
1728 }
1729
danc3a20c12018-05-23 20:55:37 +00001730 pParse->nMem += nSub + 2;
1731
1732 /* Martial the row returned by the sub-select into an array of
1733 ** registers. */
1734 for(k=0; k<nSub; k++){
1735 sqlite3VdbeAddOp3(v, OP_Column, iSubCsr, k, reg+k);
1736 }
1737
1738 /* Check if this is the start of a new partition or peer group. */
dand6f784e2018-05-28 18:30:45 +00001739 if( pPart || pOrderBy ){
danc3a20c12018-05-23 20:55:37 +00001740 int nPart = (pPart ? pPart->nExpr : 0);
danc3a20c12018-05-23 20:55:37 +00001741 int addrGoto = 0;
1742 int addrJump = 0;
dand6f784e2018-05-28 18:30:45 +00001743 int nPeer = (pOrderBy ? pOrderBy->nExpr : 0);
danc3a20c12018-05-23 20:55:37 +00001744
1745 if( pPart ){
1746 int regNewPart = reg + pMWin->nBufferCol;
1747 KeyInfo *pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pPart, 0, 0);
1748 addr = sqlite3VdbeAddOp3(v, OP_Compare, regNewPart, pMWin->regPart,nPart);
1749 sqlite3VdbeAppendP4(v, (void*)pKeyInfo, P4_KEYINFO);
1750 addrJump = sqlite3VdbeAddOp3(v, OP_Jump, addr+2, 0, addr+2);
dand6f784e2018-05-28 18:30:45 +00001751 windowAggFinal(pParse, pMWin, 1);
danc3a20c12018-05-23 20:55:37 +00001752 if( pOrderBy ){
1753 addrGoto = sqlite3VdbeAddOp0(v, OP_Goto);
1754 }
1755 }
1756
1757 if( pOrderBy ){
1758 int regNewPeer = reg + pMWin->nBufferCol + nPart;
1759 int regPeer = pMWin->regPart + nPart;
1760
danc3a20c12018-05-23 20:55:37 +00001761 if( addrJump ) sqlite3VdbeJumpHere(v, addrJump);
dan79d45442018-05-26 21:17:29 +00001762 if( pMWin->eType==TK_RANGE ){
1763 KeyInfo *pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pOrderBy, 0, 0);
1764 addr = sqlite3VdbeAddOp3(v, OP_Compare, regNewPeer, regPeer, nPeer);
1765 sqlite3VdbeAppendP4(v, (void*)pKeyInfo, P4_KEYINFO);
1766 addrJump = sqlite3VdbeAddOp3(v, OP_Jump, addr+2, 0, addr+2);
1767 }else{
1768 addrJump = 0;
1769 }
dand6f784e2018-05-28 18:30:45 +00001770 windowAggFinal(pParse, pMWin, pMWin->eStart==TK_CURRENT);
danc3a20c12018-05-23 20:55:37 +00001771 if( addrGoto ) sqlite3VdbeJumpHere(v, addrGoto);
1772 }
1773
dandacf1de2018-06-08 16:11:55 +00001774 sqlite3VdbeAddOp2(v, OP_Rewind, pMWin->iEphCsr,sqlite3VdbeCurrentAddr(v)+3);
danc3a20c12018-05-23 20:55:37 +00001775 sqlite3VdbeAddOp2(v, OP_Gosub, regGosub, addrGosub);
dandacf1de2018-06-08 16:11:55 +00001776 sqlite3VdbeAddOp2(v, OP_Next, pMWin->iEphCsr, sqlite3VdbeCurrentAddr(v)-1);
1777
danc3a20c12018-05-23 20:55:37 +00001778 sqlite3VdbeAddOp1(v, OP_ResetSorter, pMWin->iEphCsr);
1779 sqlite3VdbeAddOp3(
1780 v, OP_Copy, reg+pMWin->nBufferCol, pMWin->regPart, nPart+nPeer-1
1781 );
1782
dan79d45442018-05-26 21:17:29 +00001783 if( addrJump ) sqlite3VdbeJumpHere(v, addrJump);
danc3a20c12018-05-23 20:55:37 +00001784 }
1785
1786 /* Invoke step function for window functions */
dandfa552f2018-06-02 21:04:28 +00001787 windowAggStep(pParse, pMWin, -1, 0, reg, 0);
danc3a20c12018-05-23 20:55:37 +00001788
1789 /* Buffer the current row in the ephemeral table. */
1790 if( pMWin->nBufferCol>0 ){
1791 sqlite3VdbeAddOp3(v, OP_MakeRecord, reg, pMWin->nBufferCol, regRecord);
1792 }else{
1793 sqlite3VdbeAddOp2(v, OP_Blob, 0, regRecord);
1794 sqlite3VdbeAppendP4(v, (void*)"", 0);
1795 }
1796 sqlite3VdbeAddOp2(v, OP_NewRowid, pMWin->iEphCsr, regRowid);
1797 sqlite3VdbeAddOp3(v, OP_Insert, pMWin->iEphCsr, regRecord, regRowid);
1798
1799 /* End the database scan loop. */
1800 sqlite3WhereEnd(pWInfo);
1801
dand6f784e2018-05-28 18:30:45 +00001802 windowAggFinal(pParse, pMWin, 1);
dandacf1de2018-06-08 16:11:55 +00001803 sqlite3VdbeAddOp2(v, OP_Rewind, pMWin->iEphCsr,sqlite3VdbeCurrentAddr(v)+3);
danc3a20c12018-05-23 20:55:37 +00001804 sqlite3VdbeAddOp2(v, OP_Gosub, regGosub, addrGosub);
dandacf1de2018-06-08 16:11:55 +00001805 sqlite3VdbeAddOp2(v, OP_Next, pMWin->iEphCsr, sqlite3VdbeCurrentAddr(v)-1);
danc3a20c12018-05-23 20:55:37 +00001806}
1807
dan2a11bb22018-06-11 20:50:25 +00001808Window *sqlite3WindowDup(sqlite3 *db, Expr *pOwner, Window *p){
dandacf1de2018-06-08 16:11:55 +00001809 Window *pNew = 0;
1810 if( p ){
1811 pNew = sqlite3DbMallocZero(db, sizeof(Window));
1812 if( pNew ){
1813 pNew->pFilter = sqlite3ExprDup(db, p->pFilter, 0);
1814 pNew->pPartition = sqlite3ExprListDup(db, p->pPartition, 0);
1815 pNew->pOrderBy = sqlite3ExprListDup(db, p->pOrderBy, 0);
1816 pNew->eType = p->eType;
1817 pNew->eEnd = p->eEnd;
1818 pNew->eStart = p->eStart;
1819 pNew->pStart = sqlite3ExprDup(db, pNew->pStart, 0);
1820 pNew->pEnd = sqlite3ExprDup(db, pNew->pEnd, 0);
dan2a11bb22018-06-11 20:50:25 +00001821 pNew->pOwner = pOwner;
dandacf1de2018-06-08 16:11:55 +00001822 }
1823 }
1824 return pNew;
1825}
danc3a20c12018-05-23 20:55:37 +00001826
danf9eae182018-05-21 19:45:11 +00001827/*
dan2a11bb22018-06-11 20:50:25 +00001828** sqlite3WhereBegin() has already been called for the SELECT statement
1829** passed as the second argument when this function is invoked. It generates
1830** code to populate the Window.regResult register for each window function and
1831** invoke the sub-routine at instruction addrGosub once for each row.
1832** This function calls sqlite3WhereEnd() before returning.
danf9eae182018-05-21 19:45:11 +00001833*/
1834void sqlite3WindowCodeStep(
dan2a11bb22018-06-11 20:50:25 +00001835 Parse *pParse, /* Parse context */
1836 Select *p, /* Rewritten SELECT statement */
1837 WhereInfo *pWInfo, /* Context returned by sqlite3WhereBegin() */
1838 int regGosub, /* Register for OP_Gosub */
1839 int addrGosub /* OP_Gosub here to return each row */
danf9eae182018-05-21 19:45:11 +00001840){
danf9eae182018-05-21 19:45:11 +00001841 Window *pMWin = p->pWin;
dandfa552f2018-06-02 21:04:28 +00001842 Window *pWin;
danf9eae182018-05-21 19:45:11 +00001843
dan2a11bb22018-06-11 20:50:25 +00001844 /* Call windowCodeRowExprStep() for all window modes *except*:
dan26522d12018-06-11 18:16:51 +00001845 **
1846 ** RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
1847 ** RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
1848 ** RANGE BETWEEN CURRENT ROW AND CURRENT ROW
1849 ** ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
1850 */
dan09590aa2018-05-25 20:30:17 +00001851 if( (pMWin->eType==TK_ROWS
dand6f784e2018-05-28 18:30:45 +00001852 && (pMWin->eStart!=TK_UNBOUNDED||pMWin->eEnd!=TK_CURRENT||!pMWin->pOrderBy))
1853 || (pMWin->eStart==TK_CURRENT&&pMWin->eEnd==TK_UNBOUNDED&&pMWin->pOrderBy)
dan09590aa2018-05-25 20:30:17 +00001854 ){
danc3a20c12018-05-23 20:55:37 +00001855 windowCodeRowExprStep(pParse, p, pWInfo, regGosub, addrGosub);
1856 return;
danf9eae182018-05-21 19:45:11 +00001857 }
1858
dan2a11bb22018-06-11 20:50:25 +00001859 /* Call windowCodeCacheStep() if there is a window function that requires
dan26522d12018-06-11 18:16:51 +00001860 ** that the entire partition be cached in a temp table before any rows
dan2a11bb22018-06-11 20:50:25 +00001861 ** are returned. */
dandfa552f2018-06-02 21:04:28 +00001862 for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
danec891fd2018-06-06 20:51:02 +00001863 FuncDef *pFunc = pWin->pFunc;
1864 if( (pFunc->funcFlags & SQLITE_FUNC_WINDOW_SIZE)
1865 || (pFunc->xSFunc==nth_valueStepFunc)
dan7095c002018-06-07 17:45:22 +00001866 || (pFunc->xSFunc==first_valueStepFunc)
danfe4e25a2018-06-07 20:08:59 +00001867 || (pFunc->xSFunc==leadStepFunc)
1868 || (pFunc->xSFunc==lagStepFunc)
danec891fd2018-06-06 20:51:02 +00001869 ){
dandfa552f2018-06-02 21:04:28 +00001870 windowCodeCacheStep(pParse, p, pWInfo, regGosub, addrGosub);
1871 return;
1872 }
danf690b572018-06-01 21:00:08 +00001873 }
danf690b572018-06-01 21:00:08 +00001874
dan2a11bb22018-06-11 20:50:25 +00001875 /* Otherwise, call windowCodeDefaultStep(). */
danc3a20c12018-05-23 20:55:37 +00001876 windowCodeDefaultStep(pParse, p, pWInfo, regGosub, addrGosub);
danf9eae182018-05-21 19:45:11 +00001877}
1878