blob: c43e3f11f158469c4c860df89df03111dc17a04a [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
dan67a9b8e2018-06-22 20:51:35 +000015#ifndef SQLITE_OMIT_WINDOWFUNC
16
dandfa552f2018-06-02 21:04:28 +000017/*
dan73925692018-06-12 18:40:17 +000018** SELECT REWRITING
19**
20** Any SELECT statement that contains one or more window functions in
21** either the select list or ORDER BY clause (the only two places window
22** functions may be used) is transformed by function sqlite3WindowRewrite()
23** in order to support window function processing. For example, with the
24** schema:
25**
26** CREATE TABLE t1(a, b, c, d, e, f, g);
27**
28** the statement:
29**
30** SELECT a+1, max(b) OVER (PARTITION BY c ORDER BY d) FROM t1 ORDER BY e;
31**
32** is transformed to:
33**
34** SELECT a+1, max(b) OVER (PARTITION BY c ORDER BY d) FROM (
35** SELECT a, e, c, d, b FROM t1 ORDER BY c, d
36** ) ORDER BY e;
37**
38** The flattening optimization is disabled when processing this transformed
39** SELECT statement. This allows the implementation of the window function
40** (in this case max()) to process rows sorted in order of (c, d), which
41** makes things easier for obvious reasons. More generally:
42**
43** * FROM, WHERE, GROUP BY and HAVING clauses are all moved to
44** the sub-query.
45**
46** * ORDER BY, LIMIT and OFFSET remain part of the parent query.
47**
48** * Terminals from each of the expression trees that make up the
49** select-list and ORDER BY expressions in the parent query are
50** selected by the sub-query. For the purposes of the transformation,
51** terminals are column references and aggregate functions.
52**
53** If there is more than one window function in the SELECT that uses
54** the same window declaration (the OVER bit), then a single scan may
55** be used to process more than one window function. For example:
56**
57** SELECT max(b) OVER (PARTITION BY c ORDER BY d),
58** min(e) OVER (PARTITION BY c ORDER BY d)
59** FROM t1;
60**
61** is transformed in the same way as the example above. However:
62**
63** SELECT max(b) OVER (PARTITION BY c ORDER BY d),
64** min(e) OVER (PARTITION BY a ORDER BY b)
65** FROM t1;
66**
67** Must be transformed to:
68**
69** SELECT max(b) OVER (PARTITION BY c ORDER BY d) FROM (
70** SELECT e, min(e) OVER (PARTITION BY a ORDER BY b), c, d, b FROM
71** SELECT a, e, c, d, b FROM t1 ORDER BY a, b
72** ) ORDER BY c, d
73** ) ORDER BY e;
74**
75** so that both min() and max() may process rows in the order defined by
76** their respective window declarations.
77**
78** INTERFACE WITH SELECT.C
79**
80** When processing the rewritten SELECT statement, code in select.c calls
81** sqlite3WhereBegin() to begin iterating through the results of the
82** sub-query, which is always implemented as a co-routine. It then calls
83** sqlite3WindowCodeStep() to process rows and finish the scan by calling
84** sqlite3WhereEnd().
85**
86** sqlite3WindowCodeStep() generates VM code so that, for each row returned
87** by the sub-query a sub-routine (OP_Gosub) coded by select.c is invoked.
88** When the sub-routine is invoked:
89**
90** * The results of all window-functions for the row are stored
91** in the associated Window.regResult registers.
92**
93** * The required terminal values are stored in the current row of
94** temp table Window.iEphCsr.
95**
96** In some cases, depending on the window frame and the specific window
97** functions invoked, sqlite3WindowCodeStep() caches each entire partition
98** in a temp table before returning any rows. In other cases it does not.
99** This detail is encapsulated within this file, the code generated by
100** select.c is the same in either case.
101**
102** BUILT-IN WINDOW FUNCTIONS
103**
104** This implementation features the following built-in window functions:
105**
106** row_number()
107** rank()
108** dense_rank()
109** percent_rank()
110** cume_dist()
111** ntile(N)
112** lead(expr [, offset [, default]])
113** lag(expr [, offset [, default]])
114** first_value(expr)
115** last_value(expr)
116** nth_value(expr, N)
117**
118** These are the same built-in window functions supported by Postgres.
119** Although the behaviour of aggregate window functions (functions that
120** can be used as either aggregates or window funtions) allows them to
121** be implemented using an API, built-in window functions are much more
122** esoteric. Additionally, some window functions (e.g. nth_value())
123** may only be implemented by caching the entire partition in memory.
124** As such, some built-in window functions use the same API as aggregate
125** window functions and some are implemented directly using VDBE
126** instructions. Additionally, for those functions that use the API, the
127** window frame is sometimes modified before the SELECT statement is
128** rewritten. For example, regardless of the specified window frame, the
129** row_number() function always uses:
130**
131** ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
132**
133** See sqlite3WindowUpdate() for details.
danc0bb4452018-06-12 20:53:38 +0000134**
135** As well as some of the built-in window functions, aggregate window
136** functions min() and max() are implemented using VDBE instructions if
137** the start of the window frame is declared as anything other than
138** UNBOUNDED PRECEDING.
dan73925692018-06-12 18:40:17 +0000139*/
140
141/*
dandfa552f2018-06-02 21:04:28 +0000142** Implementation of built-in window function row_number(). Assumes that the
143** window frame has been coerced to:
144**
145** ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
146*/
147static void row_numberStepFunc(
148 sqlite3_context *pCtx,
149 int nArg,
150 sqlite3_value **apArg
151){
152 i64 *p = (i64*)sqlite3_aggregate_context(pCtx, sizeof(*p));
drh5d6374f2018-07-10 23:31:17 +0000153 if( p ) (*p)++;
drhc7bf5712018-07-09 22:49:01 +0000154 UNUSED_PARAMETER(nArg);
155 UNUSED_PARAMETER(apArg);
dandfa552f2018-06-02 21:04:28 +0000156}
dandfa552f2018-06-02 21:04:28 +0000157static void row_numberValueFunc(sqlite3_context *pCtx){
158 i64 *p = (i64*)sqlite3_aggregate_context(pCtx, sizeof(*p));
159 sqlite3_result_int64(pCtx, (p ? *p : 0));
160}
161
162/*
dan2a11bb22018-06-11 20:50:25 +0000163** Context object type used by rank(), dense_rank(), percent_rank() and
164** cume_dist().
dandfa552f2018-06-02 21:04:28 +0000165*/
166struct CallCount {
167 i64 nValue;
168 i64 nStep;
169 i64 nTotal;
170};
171
172/*
dan9c277582018-06-20 09:23:49 +0000173** Implementation of built-in window function dense_rank(). Assumes that
174** the window frame has been set to:
175**
176** RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
dandfa552f2018-06-02 21:04:28 +0000177*/
178static void dense_rankStepFunc(
179 sqlite3_context *pCtx,
180 int nArg,
181 sqlite3_value **apArg
182){
183 struct CallCount *p;
184 p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p));
drh5d6374f2018-07-10 23:31:17 +0000185 if( p ) p->nStep = 1;
drhc7bf5712018-07-09 22:49:01 +0000186 UNUSED_PARAMETER(nArg);
187 UNUSED_PARAMETER(apArg);
dandfa552f2018-06-02 21:04:28 +0000188}
dandfa552f2018-06-02 21:04:28 +0000189static void dense_rankValueFunc(sqlite3_context *pCtx){
190 struct CallCount *p;
191 p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p));
192 if( p ){
193 if( p->nStep ){
194 p->nValue++;
195 p->nStep = 0;
196 }
197 sqlite3_result_int64(pCtx, p->nValue);
198 }
199}
200
201/*
dan9c277582018-06-20 09:23:49 +0000202** Implementation of built-in window function rank(). Assumes that
203** the window frame has been set to:
204**
205** RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
dandfa552f2018-06-02 21:04:28 +0000206*/
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));
drh5d6374f2018-07-10 23:31:17 +0000214 if( p ){
dandfa552f2018-06-02 21:04:28 +0000215 p->nStep++;
216 if( p->nValue==0 ){
217 p->nValue = p->nStep;
218 }
219 }
drhc7bf5712018-07-09 22:49:01 +0000220 UNUSED_PARAMETER(nArg);
221 UNUSED_PARAMETER(apArg);
dandfa552f2018-06-02 21:04:28 +0000222}
dandfa552f2018-06-02 21:04:28 +0000223static void rankValueFunc(sqlite3_context *pCtx){
224 struct CallCount *p;
225 p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p));
226 if( p ){
227 sqlite3_result_int64(pCtx, p->nValue);
228 p->nValue = 0;
229 }
230}
231
232/*
dan9c277582018-06-20 09:23:49 +0000233** Implementation of built-in window function percent_rank(). Assumes that
234** the window frame has been set to:
235**
236** RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
dandfa552f2018-06-02 21:04:28 +0000237*/
238static void percent_rankStepFunc(
239 sqlite3_context *pCtx,
240 int nArg,
241 sqlite3_value **apArg
242){
243 struct CallCount *p;
drhc7bf5712018-07-09 22:49:01 +0000244 UNUSED_PARAMETER(nArg); assert( nArg==1 );
dandfa552f2018-06-02 21:04:28 +0000245
246 p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p));
drh5d6374f2018-07-10 23:31:17 +0000247 if( p ){
dandfa552f2018-06-02 21:04:28 +0000248 if( p->nTotal==0 ){
249 p->nTotal = sqlite3_value_int64(apArg[0]);
250 }
251 p->nStep++;
252 if( p->nValue==0 ){
253 p->nValue = p->nStep;
254 }
255 }
256}
dandfa552f2018-06-02 21:04:28 +0000257static void percent_rankValueFunc(sqlite3_context *pCtx){
258 struct CallCount *p;
259 p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p));
260 if( p ){
261 if( p->nTotal>1 ){
262 double r = (double)(p->nValue-1) / (double)(p->nTotal-1);
263 sqlite3_result_double(pCtx, r);
264 }else{
danb7306f62018-06-21 19:20:39 +0000265 sqlite3_result_double(pCtx, 0.0);
dandfa552f2018-06-02 21:04:28 +0000266 }
267 p->nValue = 0;
268 }
269}
270
dan9c277582018-06-20 09:23:49 +0000271/*
272** Implementation of built-in window function cume_dist(). Assumes that
273** the window frame has been set to:
274**
275** RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
276*/
danf1abe362018-06-04 08:22:09 +0000277static void cume_distStepFunc(
278 sqlite3_context *pCtx,
279 int nArg,
280 sqlite3_value **apArg
281){
282 struct CallCount *p;
drhc7bf5712018-07-09 22:49:01 +0000283 assert( nArg==1 ); UNUSED_PARAMETER(nArg);
danf1abe362018-06-04 08:22:09 +0000284
285 p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p));
drh5d6374f2018-07-10 23:31:17 +0000286 if( p ){
danf1abe362018-06-04 08:22:09 +0000287 if( p->nTotal==0 ){
288 p->nTotal = sqlite3_value_int64(apArg[0]);
289 }
290 p->nStep++;
291 }
292}
danf1abe362018-06-04 08:22:09 +0000293static void cume_distValueFunc(sqlite3_context *pCtx){
294 struct CallCount *p;
295 p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p));
dan660af932018-06-18 16:55:22 +0000296 if( p && p->nTotal ){
danf1abe362018-06-04 08:22:09 +0000297 double r = (double)(p->nStep) / (double)(p->nTotal);
298 sqlite3_result_double(pCtx, r);
299 }
300}
301
dan2a11bb22018-06-11 20:50:25 +0000302/*
303** Context object for ntile() window function.
304*/
dan6bc5c9e2018-06-04 18:55:11 +0000305struct NtileCtx {
306 i64 nTotal; /* Total rows in partition */
307 i64 nParam; /* Parameter passed to ntile(N) */
308 i64 iRow; /* Current row */
309};
310
311/*
312** Implementation of ntile(). This assumes that the window frame has
313** been coerced to:
314**
315** ROWS UNBOUNDED PRECEDING AND CURRENT ROW
dan6bc5c9e2018-06-04 18:55:11 +0000316*/
317static void ntileStepFunc(
318 sqlite3_context *pCtx,
319 int nArg,
320 sqlite3_value **apArg
321){
322 struct NtileCtx *p;
drhc7bf5712018-07-09 22:49:01 +0000323 assert( nArg==2 ); UNUSED_PARAMETER(nArg);
dan6bc5c9e2018-06-04 18:55:11 +0000324 p = (struct NtileCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p));
drh5d6374f2018-07-10 23:31:17 +0000325 if( p ){
dan6bc5c9e2018-06-04 18:55:11 +0000326 if( p->nTotal==0 ){
327 p->nParam = sqlite3_value_int64(apArg[0]);
328 p->nTotal = sqlite3_value_int64(apArg[1]);
329 if( p->nParam<=0 ){
330 sqlite3_result_error(
331 pCtx, "argument of ntile must be a positive integer", -1
332 );
333 }
334 }
335 p->iRow++;
336 }
337}
dan6bc5c9e2018-06-04 18:55:11 +0000338static void ntileValueFunc(sqlite3_context *pCtx){
339 struct NtileCtx *p;
340 p = (struct NtileCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p));
341 if( p && p->nParam>0 ){
342 int nSize = (p->nTotal / p->nParam);
343 if( nSize==0 ){
344 sqlite3_result_int64(pCtx, p->iRow);
345 }else{
346 i64 nLarge = p->nTotal - p->nParam*nSize;
347 i64 iSmall = nLarge*(nSize+1);
348 i64 iRow = p->iRow-1;
349
350 assert( (nLarge*(nSize+1) + (p->nParam-nLarge)*nSize)==p->nTotal );
351
352 if( iRow<iSmall ){
353 sqlite3_result_int64(pCtx, 1 + iRow/(nSize+1));
354 }else{
355 sqlite3_result_int64(pCtx, 1 + nLarge + (iRow-iSmall)/nSize);
356 }
357 }
358 }
359}
360
dan2a11bb22018-06-11 20:50:25 +0000361/*
362** Context object for last_value() window function.
363*/
dan1c5ed622018-06-05 16:16:17 +0000364struct LastValueCtx {
365 sqlite3_value *pVal;
366 int nVal;
367};
368
369/*
370** Implementation of last_value().
371*/
372static void last_valueStepFunc(
373 sqlite3_context *pCtx,
374 int nArg,
375 sqlite3_value **apArg
376){
377 struct LastValueCtx *p;
drhc7bf5712018-07-09 22:49:01 +0000378 UNUSED_PARAMETER(nArg);
dan9c277582018-06-20 09:23:49 +0000379 p = (struct LastValueCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p));
dan1c5ed622018-06-05 16:16:17 +0000380 if( p ){
381 sqlite3_value_free(p->pVal);
382 p->pVal = sqlite3_value_dup(apArg[0]);
dan6fde1792018-06-15 19:01:35 +0000383 if( p->pVal==0 ){
384 sqlite3_result_error_nomem(pCtx);
385 }else{
386 p->nVal++;
387 }
dan1c5ed622018-06-05 16:16:17 +0000388 }
389}
dan2a11bb22018-06-11 20:50:25 +0000390static void last_valueInvFunc(
dan1c5ed622018-06-05 16:16:17 +0000391 sqlite3_context *pCtx,
392 int nArg,
393 sqlite3_value **apArg
394){
395 struct LastValueCtx *p;
drhc7bf5712018-07-09 22:49:01 +0000396 UNUSED_PARAMETER(nArg);
397 UNUSED_PARAMETER(apArg);
dan9c277582018-06-20 09:23:49 +0000398 p = (struct LastValueCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p));
399 if( ALWAYS(p) ){
dan1c5ed622018-06-05 16:16:17 +0000400 p->nVal--;
401 if( p->nVal==0 ){
402 sqlite3_value_free(p->pVal);
403 p->pVal = 0;
404 }
405 }
406}
407static void last_valueValueFunc(sqlite3_context *pCtx){
408 struct LastValueCtx *p;
dan9c277582018-06-20 09:23:49 +0000409 p = (struct LastValueCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p));
dan1c5ed622018-06-05 16:16:17 +0000410 if( p && p->pVal ){
411 sqlite3_result_value(pCtx, p->pVal);
412 }
413}
414static void last_valueFinalizeFunc(sqlite3_context *pCtx){
415 struct LastValueCtx *p;
dan9c277582018-06-20 09:23:49 +0000416 p = (struct LastValueCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p));
dan1c5ed622018-06-05 16:16:17 +0000417 if( p && p->pVal ){
418 sqlite3_result_value(pCtx, p->pVal);
419 sqlite3_value_free(p->pVal);
420 p->pVal = 0;
421 }
422}
423
dan2a11bb22018-06-11 20:50:25 +0000424/*
drh19dc4d42018-07-08 01:02:26 +0000425** Static names for the built-in window function names. These static
426** names are used, rather than string literals, so that FuncDef objects
427** can be associated with a particular window function by direct
428** comparison of the zName pointer. Example:
429**
430** if( pFuncDef->zName==row_valueName ){ ... }
dan2a11bb22018-06-11 20:50:25 +0000431*/
drh19dc4d42018-07-08 01:02:26 +0000432static const char row_numberName[] = "row_number";
433static const char dense_rankName[] = "dense_rank";
434static const char rankName[] = "rank";
435static const char percent_rankName[] = "percent_rank";
436static const char cume_distName[] = "cume_dist";
437static const char ntileName[] = "ntile";
438static const char last_valueName[] = "last_value";
439static const char nth_valueName[] = "nth_value";
440static const char first_valueName[] = "first_value";
441static const char leadName[] = "lead";
442static const char lagName[] = "lag";
danfe4e25a2018-06-07 20:08:59 +0000443
drh19dc4d42018-07-08 01:02:26 +0000444/*
445** No-op implementations of xStep() and xFinalize(). Used as place-holders
446** for built-in window functions that never call those interfaces.
447**
448** The noopValueFunc() is called but is expected to do nothing. The
449** noopStepFunc() is never called, and so it is marked with NO_TEST to
450** let the test coverage routine know not to expect this function to be
451** invoked.
452*/
453static void noopStepFunc( /*NO_TEST*/
454 sqlite3_context *p, /*NO_TEST*/
455 int n, /*NO_TEST*/
456 sqlite3_value **a /*NO_TEST*/
457){ /*NO_TEST*/
drhc7bf5712018-07-09 22:49:01 +0000458 UNUSED_PARAMETER(p); /*NO_TEST*/
459 UNUSED_PARAMETER(n); /*NO_TEST*/
460 UNUSED_PARAMETER(a); /*NO_TEST*/
drh19dc4d42018-07-08 01:02:26 +0000461 assert(0); /*NO_TEST*/
462} /*NO_TEST*/
drhc7bf5712018-07-09 22:49:01 +0000463static void noopValueFunc(sqlite3_context *p){ UNUSED_PARAMETER(p); /*no-op*/ }
dandfa552f2018-06-02 21:04:28 +0000464
drh19dc4d42018-07-08 01:02:26 +0000465/* Window functions that use all window interfaces: xStep, xFinal,
466** xValue, and xInverse */
467#define WINDOWFUNCALL(name,nArg,extra) { \
dan1c5ed622018-06-05 16:16:17 +0000468 nArg, (SQLITE_UTF8|SQLITE_FUNC_WINDOW|extra), 0, 0, \
469 name ## StepFunc, name ## FinalizeFunc, name ## ValueFunc, \
drhc7bf5712018-07-09 22:49:01 +0000470 name ## InvFunc, name ## Name, {0} \
dan1c5ed622018-06-05 16:16:17 +0000471}
472
drh19dc4d42018-07-08 01:02:26 +0000473/* Window functions that are implemented using bytecode and thus have
474** no-op routines for their methods */
475#define WINDOWFUNCNOOP(name,nArg,extra) { \
476 nArg, (SQLITE_UTF8|SQLITE_FUNC_WINDOW|extra), 0, 0, \
477 noopStepFunc, noopValueFunc, noopValueFunc, \
drhc7bf5712018-07-09 22:49:01 +0000478 noopStepFunc, name ## Name, {0} \
drh19dc4d42018-07-08 01:02:26 +0000479}
480
481/* Window functions that use all window interfaces: xStep, the
482** same routine for xFinalize and xValue and which never call
483** xInverse. */
484#define WINDOWFUNCX(name,nArg,extra) { \
485 nArg, (SQLITE_UTF8|SQLITE_FUNC_WINDOW|extra), 0, 0, \
486 name ## StepFunc, name ## ValueFunc, name ## ValueFunc, \
drhc7bf5712018-07-09 22:49:01 +0000487 noopStepFunc, name ## Name, {0} \
drh19dc4d42018-07-08 01:02:26 +0000488}
489
490
dandfa552f2018-06-02 21:04:28 +0000491/*
492** Register those built-in window functions that are not also aggregates.
493*/
494void sqlite3WindowFunctions(void){
495 static FuncDef aWindowFuncs[] = {
drh19dc4d42018-07-08 01:02:26 +0000496 WINDOWFUNCX(row_number, 0, 0),
497 WINDOWFUNCX(dense_rank, 0, 0),
498 WINDOWFUNCX(rank, 0, 0),
499 WINDOWFUNCX(percent_rank, 0, SQLITE_FUNC_WINDOW_SIZE),
500 WINDOWFUNCX(cume_dist, 0, SQLITE_FUNC_WINDOW_SIZE),
501 WINDOWFUNCX(ntile, 1, SQLITE_FUNC_WINDOW_SIZE),
502 WINDOWFUNCALL(last_value, 1, 0),
503 WINDOWFUNCNOOP(nth_value, 2, 0),
504 WINDOWFUNCNOOP(first_value, 1, 0),
505 WINDOWFUNCNOOP(lead, 1, 0),
506 WINDOWFUNCNOOP(lead, 2, 0),
507 WINDOWFUNCNOOP(lead, 3, 0),
508 WINDOWFUNCNOOP(lag, 1, 0),
509 WINDOWFUNCNOOP(lag, 2, 0),
510 WINDOWFUNCNOOP(lag, 3, 0),
dandfa552f2018-06-02 21:04:28 +0000511 };
512 sqlite3InsertBuiltinFuncs(aWindowFuncs, ArraySize(aWindowFuncs));
513}
514
dane7c9ca42019-02-16 17:27:51 +0000515static Window *windowFind(Parse *pParse, Window *pList, const char *zName){
516 Window *p;
517 for(p=pList; p; p=p->pNextWin){
518 if( sqlite3StrICmp(p->zName, zName)==0 ) break;
519 }
520 if( p==0 ){
521 sqlite3ErrorMsg(pParse, "no such window: %s", zName);
522 }
523 return p;
524}
525
danc0bb4452018-06-12 20:53:38 +0000526/*
527** This function is called immediately after resolving the function name
528** for a window function within a SELECT statement. Argument pList is a
529** linked list of WINDOW definitions for the current SELECT statement.
530** Argument pFunc is the function definition just resolved and pWin
531** is the Window object representing the associated OVER clause. This
532** function updates the contents of pWin as follows:
533**
534** * If the OVER clause refered to a named window (as in "max(x) OVER win"),
535** search list pList for a matching WINDOW definition, and update pWin
536** accordingly. If no such WINDOW clause can be found, leave an error
537** in pParse.
538**
539** * If the function is a built-in window function that requires the
540** window to be coerced (see "BUILT-IN WINDOW FUNCTIONS" at the top
541** of this file), pWin is updated here.
542*/
dane3bf6322018-06-08 20:58:27 +0000543void sqlite3WindowUpdate(
544 Parse *pParse,
danc0bb4452018-06-12 20:53:38 +0000545 Window *pList, /* List of named windows for this SELECT */
546 Window *pWin, /* Window frame to update */
547 FuncDef *pFunc /* Window function definition */
dane3bf6322018-06-08 20:58:27 +0000548){
danc95f38d2018-06-18 20:34:43 +0000549 if( pWin->zName && pWin->eType==0 ){
dane7c9ca42019-02-16 17:27:51 +0000550 Window *p = windowFind(pParse, pList, pWin->zName);
551 if( p==0 ) return;
dane3bf6322018-06-08 20:58:27 +0000552 pWin->pPartition = sqlite3ExprListDup(pParse->db, p->pPartition, 0);
553 pWin->pOrderBy = sqlite3ExprListDup(pParse->db, p->pOrderBy, 0);
554 pWin->pStart = sqlite3ExprDup(pParse->db, p->pStart, 0);
555 pWin->pEnd = sqlite3ExprDup(pParse->db, p->pEnd, 0);
556 pWin->eStart = p->eStart;
557 pWin->eEnd = p->eEnd;
danc95f38d2018-06-18 20:34:43 +0000558 pWin->eType = p->eType;
dane7c9ca42019-02-16 17:27:51 +0000559 }else{
560 sqlite3WindowChain(pParse, pWin, pList);
dane3bf6322018-06-08 20:58:27 +0000561 }
dan72b9fdc2019-03-09 20:49:17 +0000562 if( (pWin->eType==TK_RANGE)
563 && (pWin->pStart || pWin->pEnd)
564 && (pWin->pOrderBy==0 || pWin->pOrderBy->nExpr!=1)
565 ){
566 sqlite3ErrorMsg(pParse,
567 "RANGE with offset PRECEDING/FOLLOWING requires one ORDER BY expression"
568 );
569 }else
dandfa552f2018-06-02 21:04:28 +0000570 if( pFunc->funcFlags & SQLITE_FUNC_WINDOW ){
571 sqlite3 *db = pParse->db;
dan8b985602018-06-09 17:43:45 +0000572 if( pWin->pFilter ){
573 sqlite3ErrorMsg(pParse,
574 "FILTER clause may only be used with aggregate window functions"
575 );
576 }else
drh19dc4d42018-07-08 01:02:26 +0000577 if( pFunc->zName==row_numberName || pFunc->zName==ntileName ){
dandfa552f2018-06-02 21:04:28 +0000578 sqlite3ExprDelete(db, pWin->pStart);
579 sqlite3ExprDelete(db, pWin->pEnd);
580 pWin->pStart = pWin->pEnd = 0;
581 pWin->eType = TK_ROWS;
582 pWin->eStart = TK_UNBOUNDED;
583 pWin->eEnd = TK_CURRENT;
dan8b985602018-06-09 17:43:45 +0000584 }else
dandfa552f2018-06-02 21:04:28 +0000585
drh19dc4d42018-07-08 01:02:26 +0000586 if( pFunc->zName==dense_rankName || pFunc->zName==rankName
587 || pFunc->zName==percent_rankName || pFunc->zName==cume_distName
dandfa552f2018-06-02 21:04:28 +0000588 ){
589 sqlite3ExprDelete(db, pWin->pStart);
590 sqlite3ExprDelete(db, pWin->pEnd);
591 pWin->pStart = pWin->pEnd = 0;
592 pWin->eType = TK_RANGE;
593 pWin->eStart = TK_UNBOUNDED;
594 pWin->eEnd = TK_CURRENT;
595 }
596 }
dan2a11bb22018-06-11 20:50:25 +0000597 pWin->pFunc = pFunc;
dandfa552f2018-06-02 21:04:28 +0000598}
599
danc0bb4452018-06-12 20:53:38 +0000600/*
601** Context object passed through sqlite3WalkExprList() to
602** selectWindowRewriteExprCb() by selectWindowRewriteEList().
603*/
dandfa552f2018-06-02 21:04:28 +0000604typedef struct WindowRewrite WindowRewrite;
605struct WindowRewrite {
606 Window *pWin;
danb556f262018-07-10 17:26:12 +0000607 SrcList *pSrc;
dandfa552f2018-06-02 21:04:28 +0000608 ExprList *pSub;
danb556f262018-07-10 17:26:12 +0000609 Select *pSubSelect; /* Current sub-select, if any */
dandfa552f2018-06-02 21:04:28 +0000610};
611
danc0bb4452018-06-12 20:53:38 +0000612/*
613** Callback function used by selectWindowRewriteEList(). If necessary,
614** this function appends to the output expression-list and updates
615** expression (*ppExpr) in place.
616*/
dandfa552f2018-06-02 21:04:28 +0000617static int selectWindowRewriteExprCb(Walker *pWalker, Expr *pExpr){
618 struct WindowRewrite *p = pWalker->u.pRewrite;
619 Parse *pParse = pWalker->pParse;
620
danb556f262018-07-10 17:26:12 +0000621 /* If this function is being called from within a scalar sub-select
622 ** that used by the SELECT statement being processed, only process
623 ** TK_COLUMN expressions that refer to it (the outer SELECT). Do
624 ** not process aggregates or window functions at all, as they belong
625 ** to the scalar sub-select. */
626 if( p->pSubSelect ){
627 if( pExpr->op!=TK_COLUMN ){
628 return WRC_Continue;
629 }else{
630 int nSrc = p->pSrc->nSrc;
631 int i;
632 for(i=0; i<nSrc; i++){
633 if( pExpr->iTable==p->pSrc->a[i].iCursor ) break;
634 }
635 if( i==nSrc ) return WRC_Continue;
636 }
637 }
638
dandfa552f2018-06-02 21:04:28 +0000639 switch( pExpr->op ){
640
641 case TK_FUNCTION:
drheda079c2018-09-20 19:02:15 +0000642 if( !ExprHasProperty(pExpr, EP_WinFunc) ){
dandfa552f2018-06-02 21:04:28 +0000643 break;
644 }else{
645 Window *pWin;
646 for(pWin=p->pWin; pWin; pWin=pWin->pNextWin){
drheda079c2018-09-20 19:02:15 +0000647 if( pExpr->y.pWin==pWin ){
dan2a11bb22018-06-11 20:50:25 +0000648 assert( pWin->pOwner==pExpr );
dandfa552f2018-06-02 21:04:28 +0000649 return WRC_Prune;
650 }
651 }
652 }
653 /* Fall through. */
654
dan73925692018-06-12 18:40:17 +0000655 case TK_AGG_FUNCTION:
dandfa552f2018-06-02 21:04:28 +0000656 case TK_COLUMN: {
657 Expr *pDup = sqlite3ExprDup(pParse->db, pExpr, 0);
658 p->pSub = sqlite3ExprListAppend(pParse, p->pSub, pDup);
659 if( p->pSub ){
660 assert( ExprHasProperty(pExpr, EP_Static)==0 );
661 ExprSetProperty(pExpr, EP_Static);
662 sqlite3ExprDelete(pParse->db, pExpr);
663 ExprClearProperty(pExpr, EP_Static);
664 memset(pExpr, 0, sizeof(Expr));
665
666 pExpr->op = TK_COLUMN;
667 pExpr->iColumn = p->pSub->nExpr-1;
668 pExpr->iTable = p->pWin->iEphCsr;
669 }
670
671 break;
672 }
673
674 default: /* no-op */
675 break;
676 }
677
678 return WRC_Continue;
679}
danc0bb4452018-06-12 20:53:38 +0000680static int selectWindowRewriteSelectCb(Walker *pWalker, Select *pSelect){
danb556f262018-07-10 17:26:12 +0000681 struct WindowRewrite *p = pWalker->u.pRewrite;
682 Select *pSave = p->pSubSelect;
683 if( pSave==pSelect ){
684 return WRC_Continue;
685 }else{
686 p->pSubSelect = pSelect;
687 sqlite3WalkSelect(pWalker, pSelect);
688 p->pSubSelect = pSave;
689 }
danc0bb4452018-06-12 20:53:38 +0000690 return WRC_Prune;
691}
dandfa552f2018-06-02 21:04:28 +0000692
danc0bb4452018-06-12 20:53:38 +0000693
694/*
695** Iterate through each expression in expression-list pEList. For each:
696**
697** * TK_COLUMN,
698** * aggregate function, or
699** * window function with a Window object that is not a member of the
danb556f262018-07-10 17:26:12 +0000700** Window list passed as the second argument (pWin).
danc0bb4452018-06-12 20:53:38 +0000701**
702** Append the node to output expression-list (*ppSub). And replace it
703** with a TK_COLUMN that reads the (N-1)th element of table
704** pWin->iEphCsr, where N is the number of elements in (*ppSub) after
705** appending the new one.
706*/
dan13b08bb2018-06-15 20:46:12 +0000707static void selectWindowRewriteEList(
dandfa552f2018-06-02 21:04:28 +0000708 Parse *pParse,
709 Window *pWin,
danb556f262018-07-10 17:26:12 +0000710 SrcList *pSrc,
dandfa552f2018-06-02 21:04:28 +0000711 ExprList *pEList, /* Rewrite expressions in this list */
712 ExprList **ppSub /* IN/OUT: Sub-select expression-list */
713){
714 Walker sWalker;
715 WindowRewrite sRewrite;
dandfa552f2018-06-02 21:04:28 +0000716
717 memset(&sWalker, 0, sizeof(Walker));
718 memset(&sRewrite, 0, sizeof(WindowRewrite));
719
720 sRewrite.pSub = *ppSub;
721 sRewrite.pWin = pWin;
danb556f262018-07-10 17:26:12 +0000722 sRewrite.pSrc = pSrc;
dandfa552f2018-06-02 21:04:28 +0000723
724 sWalker.pParse = pParse;
725 sWalker.xExprCallback = selectWindowRewriteExprCb;
726 sWalker.xSelectCallback = selectWindowRewriteSelectCb;
727 sWalker.u.pRewrite = &sRewrite;
728
dan13b08bb2018-06-15 20:46:12 +0000729 (void)sqlite3WalkExprList(&sWalker, pEList);
dandfa552f2018-06-02 21:04:28 +0000730
731 *ppSub = sRewrite.pSub;
dandfa552f2018-06-02 21:04:28 +0000732}
733
danc0bb4452018-06-12 20:53:38 +0000734/*
735** Append a copy of each expression in expression-list pAppend to
736** expression list pList. Return a pointer to the result list.
737*/
dandfa552f2018-06-02 21:04:28 +0000738static ExprList *exprListAppendList(
739 Parse *pParse, /* Parsing context */
740 ExprList *pList, /* List to which to append. Might be NULL */
741 ExprList *pAppend /* List of values to append. Might be NULL */
742){
743 if( pAppend ){
744 int i;
745 int nInit = pList ? pList->nExpr : 0;
746 for(i=0; i<pAppend->nExpr; i++){
747 Expr *pDup = sqlite3ExprDup(pParse->db, pAppend->a[i].pExpr, 0);
748 pList = sqlite3ExprListAppend(pParse, pList, pDup);
749 if( pList ) pList->a[nInit+i].sortOrder = pAppend->a[i].sortOrder;
750 }
751 }
752 return pList;
753}
754
755/*
756** If the SELECT statement passed as the second argument does not invoke
757** any SQL window functions, this function is a no-op. Otherwise, it
758** rewrites the SELECT statement so that window function xStep functions
danc0bb4452018-06-12 20:53:38 +0000759** are invoked in the correct order as described under "SELECT REWRITING"
760** at the top of this file.
dandfa552f2018-06-02 21:04:28 +0000761*/
762int sqlite3WindowRewrite(Parse *pParse, Select *p){
763 int rc = SQLITE_OK;
dan0f5f5402018-10-23 13:48:19 +0000764 if( p->pWin && p->pPrior==0 ){
dandfa552f2018-06-02 21:04:28 +0000765 Vdbe *v = sqlite3GetVdbe(pParse);
dandfa552f2018-06-02 21:04:28 +0000766 sqlite3 *db = pParse->db;
767 Select *pSub = 0; /* The subquery */
768 SrcList *pSrc = p->pSrc;
769 Expr *pWhere = p->pWhere;
770 ExprList *pGroupBy = p->pGroupBy;
771 Expr *pHaving = p->pHaving;
772 ExprList *pSort = 0;
773
774 ExprList *pSublist = 0; /* Expression list for sub-query */
775 Window *pMWin = p->pWin; /* Master window object */
776 Window *pWin; /* Window object iterator */
777
778 p->pSrc = 0;
779 p->pWhere = 0;
780 p->pGroupBy = 0;
781 p->pHaving = 0;
782
danf02cdd32018-06-27 19:48:50 +0000783 /* Create the ORDER BY clause for the sub-select. This is the concatenation
784 ** of the window PARTITION and ORDER BY clauses. Then, if this makes it
785 ** redundant, remove the ORDER BY from the parent SELECT. */
786 pSort = sqlite3ExprListDup(db, pMWin->pPartition, 0);
787 pSort = exprListAppendList(pParse, pSort, pMWin->pOrderBy);
788 if( pSort && p->pOrderBy ){
789 if( sqlite3ExprListCompare(pSort, p->pOrderBy, -1)==0 ){
790 sqlite3ExprListDelete(db, p->pOrderBy);
791 p->pOrderBy = 0;
792 }
793 }
794
dandfa552f2018-06-02 21:04:28 +0000795 /* Assign a cursor number for the ephemeral table used to buffer rows.
796 ** The OpenEphemeral instruction is coded later, after it is known how
797 ** many columns the table will have. */
798 pMWin->iEphCsr = pParse->nTab++;
dan680f6e82019-03-04 21:07:11 +0000799 pParse->nTab += 3;
dandfa552f2018-06-02 21:04:28 +0000800
danb556f262018-07-10 17:26:12 +0000801 selectWindowRewriteEList(pParse, pMWin, pSrc, p->pEList, &pSublist);
802 selectWindowRewriteEList(pParse, pMWin, pSrc, p->pOrderBy, &pSublist);
dandfa552f2018-06-02 21:04:28 +0000803 pMWin->nBufferCol = (pSublist ? pSublist->nExpr : 0);
804
danf02cdd32018-06-27 19:48:50 +0000805 /* Append the PARTITION BY and ORDER BY expressions to the to the
806 ** sub-select expression list. They are required to figure out where
807 ** boundaries for partitions and sets of peer rows lie. */
808 pSublist = exprListAppendList(pParse, pSublist, pMWin->pPartition);
809 pSublist = exprListAppendList(pParse, pSublist, pMWin->pOrderBy);
dandfa552f2018-06-02 21:04:28 +0000810
811 /* Append the arguments passed to each window function to the
812 ** sub-select expression list. Also allocate two registers for each
813 ** window function - one for the accumulator, another for interim
814 ** results. */
815 for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
816 pWin->iArgCol = (pSublist ? pSublist->nExpr : 0);
817 pSublist = exprListAppendList(pParse, pSublist, pWin->pOwner->x.pList);
dan8b985602018-06-09 17:43:45 +0000818 if( pWin->pFilter ){
819 Expr *pFilter = sqlite3ExprDup(db, pWin->pFilter, 0);
820 pSublist = sqlite3ExprListAppend(pParse, pSublist, pFilter);
821 }
dandfa552f2018-06-02 21:04:28 +0000822 pWin->regAccum = ++pParse->nMem;
823 pWin->regResult = ++pParse->nMem;
824 sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regAccum);
825 }
826
dan9c277582018-06-20 09:23:49 +0000827 /* If there is no ORDER BY or PARTITION BY clause, and the window
828 ** function accepts zero arguments, and there are no other columns
829 ** selected (e.g. "SELECT row_number() OVER () FROM t1"), it is possible
830 ** that pSublist is still NULL here. Add a constant expression here to
831 ** keep everything legal in this case.
832 */
833 if( pSublist==0 ){
834 pSublist = sqlite3ExprListAppend(pParse, 0,
835 sqlite3ExprAlloc(db, TK_INTEGER, &sqlite3IntTokens[0], 0)
836 );
837 }
838
dandfa552f2018-06-02 21:04:28 +0000839 pSub = sqlite3SelectNew(
840 pParse, pSublist, pSrc, pWhere, pGroupBy, pHaving, pSort, 0, 0
841 );
drh29c992c2019-01-17 15:40:41 +0000842 p->pSrc = sqlite3SrcListAppend(pParse, 0, 0, 0);
dandfa552f2018-06-02 21:04:28 +0000843 if( p->pSrc ){
dandfa552f2018-06-02 21:04:28 +0000844 p->pSrc->a[0].pSelect = pSub;
845 sqlite3SrcListAssignCursors(pParse, p->pSrc);
846 if( sqlite3ExpandSubquery(pParse, &p->pSrc->a[0]) ){
847 rc = SQLITE_NOMEM;
848 }else{
849 pSub->selFlags |= SF_Expanded;
dan73925692018-06-12 18:40:17 +0000850 p->selFlags &= ~SF_Aggregate;
851 sqlite3SelectPrep(pParse, pSub, 0);
dandfa552f2018-06-02 21:04:28 +0000852 }
dandfa552f2018-06-02 21:04:28 +0000853
dan6fde1792018-06-15 19:01:35 +0000854 sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pMWin->iEphCsr, pSublist->nExpr);
dan680f6e82019-03-04 21:07:11 +0000855 sqlite3VdbeAddOp2(v, OP_OpenDup, pMWin->iEphCsr+1, pMWin->iEphCsr);
856 sqlite3VdbeAddOp2(v, OP_OpenDup, pMWin->iEphCsr+2, pMWin->iEphCsr);
857 sqlite3VdbeAddOp2(v, OP_OpenDup, pMWin->iEphCsr+3, pMWin->iEphCsr);
dan6fde1792018-06-15 19:01:35 +0000858 }else{
859 sqlite3SelectDelete(db, pSub);
860 }
861 if( db->mallocFailed ) rc = SQLITE_NOMEM;
dandfa552f2018-06-02 21:04:28 +0000862 }
863
864 return rc;
865}
866
danc0bb4452018-06-12 20:53:38 +0000867/*
868** Free the Window object passed as the second argument.
869*/
dan86fb6e12018-05-16 20:58:07 +0000870void sqlite3WindowDelete(sqlite3 *db, Window *p){
871 if( p ){
872 sqlite3ExprDelete(db, p->pFilter);
873 sqlite3ExprListDelete(db, p->pPartition);
874 sqlite3ExprListDelete(db, p->pOrderBy);
875 sqlite3ExprDelete(db, p->pEnd);
876 sqlite3ExprDelete(db, p->pStart);
dane3bf6322018-06-08 20:58:27 +0000877 sqlite3DbFree(db, p->zName);
dane7c9ca42019-02-16 17:27:51 +0000878 sqlite3DbFree(db, p->zBase);
dan86fb6e12018-05-16 20:58:07 +0000879 sqlite3DbFree(db, p);
880 }
881}
882
danc0bb4452018-06-12 20:53:38 +0000883/*
884** Free the linked list of Window objects starting at the second argument.
885*/
dane3bf6322018-06-08 20:58:27 +0000886void sqlite3WindowListDelete(sqlite3 *db, Window *p){
887 while( p ){
888 Window *pNext = p->pNextWin;
889 sqlite3WindowDelete(db, p);
890 p = pNext;
891 }
892}
893
danc0bb4452018-06-12 20:53:38 +0000894/*
drhe4984a22018-07-06 17:19:20 +0000895** The argument expression is an PRECEDING or FOLLOWING offset. The
896** value should be a non-negative integer. If the value is not a
897** constant, change it to NULL. The fact that it is then a non-negative
898** integer will be caught later. But it is important not to leave
899** variable values in the expression tree.
900*/
901static Expr *sqlite3WindowOffsetExpr(Parse *pParse, Expr *pExpr){
902 if( 0==sqlite3ExprIsConstant(pExpr) ){
danfb8ac322019-01-16 12:05:22 +0000903 if( IN_RENAME_OBJECT ) sqlite3RenameExprUnmap(pParse, pExpr);
drhe4984a22018-07-06 17:19:20 +0000904 sqlite3ExprDelete(pParse->db, pExpr);
905 pExpr = sqlite3ExprAlloc(pParse->db, TK_NULL, 0, 0);
906 }
907 return pExpr;
908}
909
910/*
911** Allocate and return a new Window object describing a Window Definition.
danc0bb4452018-06-12 20:53:38 +0000912*/
dan86fb6e12018-05-16 20:58:07 +0000913Window *sqlite3WindowAlloc(
drhe4984a22018-07-06 17:19:20 +0000914 Parse *pParse, /* Parsing context */
915 int eType, /* Frame type. TK_RANGE or TK_ROWS */
916 int eStart, /* Start type: CURRENT, PRECEDING, FOLLOWING, UNBOUNDED */
917 Expr *pStart, /* Start window size if TK_PRECEDING or FOLLOWING */
918 int eEnd, /* End type: CURRENT, FOLLOWING, TK_UNBOUNDED, PRECEDING */
919 Expr *pEnd /* End window size if TK_FOLLOWING or PRECEDING */
dan86fb6e12018-05-16 20:58:07 +0000920){
dan7a606e12018-07-05 18:34:53 +0000921 Window *pWin = 0;
dane7c9ca42019-02-16 17:27:51 +0000922 int bImplicitFrame = 0;
dan7a606e12018-07-05 18:34:53 +0000923
drhe4984a22018-07-06 17:19:20 +0000924 /* Parser assures the following: */
dan6c75b392019-03-08 20:02:52 +0000925 assert( eType==0 || eType==TK_RANGE || eType==TK_ROWS || eType==TK_GROUPS );
drhe4984a22018-07-06 17:19:20 +0000926 assert( eStart==TK_CURRENT || eStart==TK_PRECEDING
927 || eStart==TK_UNBOUNDED || eStart==TK_FOLLOWING );
928 assert( eEnd==TK_CURRENT || eEnd==TK_FOLLOWING
929 || eEnd==TK_UNBOUNDED || eEnd==TK_PRECEDING );
930 assert( (eStart==TK_PRECEDING || eStart==TK_FOLLOWING)==(pStart!=0) );
931 assert( (eEnd==TK_FOLLOWING || eEnd==TK_PRECEDING)==(pEnd!=0) );
932
dane7c9ca42019-02-16 17:27:51 +0000933 if( eType==0 ){
934 bImplicitFrame = 1;
935 eType = TK_RANGE;
936 }
drhe4984a22018-07-06 17:19:20 +0000937
drhe4984a22018-07-06 17:19:20 +0000938 /* Additionally, the
dan5d764ac2018-07-06 14:15:49 +0000939 ** starting boundary type may not occur earlier in the following list than
940 ** the ending boundary type:
941 **
942 ** UNBOUNDED PRECEDING
943 ** <expr> PRECEDING
944 ** CURRENT ROW
945 ** <expr> FOLLOWING
946 ** UNBOUNDED FOLLOWING
947 **
948 ** The parser ensures that "UNBOUNDED PRECEDING" cannot be used as an ending
949 ** boundary, and than "UNBOUNDED FOLLOWING" cannot be used as a starting
950 ** frame boundary.
951 */
drhe4984a22018-07-06 17:19:20 +0000952 if( (eStart==TK_CURRENT && eEnd==TK_PRECEDING)
dan5d764ac2018-07-06 14:15:49 +0000953 || (eStart==TK_FOLLOWING && (eEnd==TK_PRECEDING || eEnd==TK_CURRENT))
954 ){
dan72b9fdc2019-03-09 20:49:17 +0000955 sqlite3ErrorMsg(pParse, "unsupported frame specification");
drhe4984a22018-07-06 17:19:20 +0000956 goto windowAllocErr;
dan7a606e12018-07-05 18:34:53 +0000957 }
dan86fb6e12018-05-16 20:58:07 +0000958
drhe4984a22018-07-06 17:19:20 +0000959 pWin = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window));
960 if( pWin==0 ) goto windowAllocErr;
961 pWin->eType = eType;
962 pWin->eStart = eStart;
963 pWin->eEnd = eEnd;
dane7c9ca42019-02-16 17:27:51 +0000964 pWin->bImplicitFrame = bImplicitFrame;
drhe4984a22018-07-06 17:19:20 +0000965 pWin->pEnd = sqlite3WindowOffsetExpr(pParse, pEnd);
966 pWin->pStart = sqlite3WindowOffsetExpr(pParse, pStart);
dan86fb6e12018-05-16 20:58:07 +0000967 return pWin;
drhe4984a22018-07-06 17:19:20 +0000968
969windowAllocErr:
970 sqlite3ExprDelete(pParse->db, pEnd);
971 sqlite3ExprDelete(pParse->db, pStart);
972 return 0;
dan86fb6e12018-05-16 20:58:07 +0000973}
974
danc0bb4452018-06-12 20:53:38 +0000975/*
dane7c9ca42019-02-16 17:27:51 +0000976** Attach PARTITION and ORDER BY clauses pPartition and pOrderBy to window
977** pWin. Also, if parameter pBase is not NULL, set pWin->zBase to the
978** equivalent nul-terminated string.
979*/
980Window *sqlite3WindowAssemble(
981 Parse *pParse,
982 Window *pWin,
983 ExprList *pPartition,
984 ExprList *pOrderBy,
985 Token *pBase
986){
987 if( pWin ){
988 pWin->pPartition = pPartition;
989 pWin->pOrderBy = pOrderBy;
990 if( pBase ){
991 pWin->zBase = sqlite3DbStrNDup(pParse->db, pBase->z, pBase->n);
992 }
993 }else{
994 sqlite3ExprListDelete(pParse->db, pPartition);
995 sqlite3ExprListDelete(pParse->db, pOrderBy);
996 }
997 return pWin;
998}
999
1000/*
1001** Window *pWin has just been created from a WINDOW clause. Tokne pBase
1002** is the base window. Earlier windows from the same WINDOW clause are
1003** stored in the linked list starting at pWin->pNextWin. This function
1004** either updates *pWin according to the base specification, or else
1005** leaves an error in pParse.
1006*/
1007void sqlite3WindowChain(Parse *pParse, Window *pWin, Window *pList){
1008 if( pWin->zBase ){
1009 sqlite3 *db = pParse->db;
1010 Window *pExist = windowFind(pParse, pList, pWin->zBase);
1011 if( pExist ){
1012 const char *zErr = 0;
1013 /* Check for errors */
1014 if( pWin->pPartition ){
1015 zErr = "PARTITION clause";
1016 }else if( pExist->pOrderBy && pWin->pOrderBy ){
1017 zErr = "ORDER BY clause";
1018 }else if( pExist->bImplicitFrame==0 ){
1019 zErr = "frame specification";
1020 }
1021 if( zErr ){
1022 sqlite3ErrorMsg(pParse,
1023 "cannot override %s of window: %s", zErr, pWin->zBase
1024 );
1025 }else{
1026 pWin->pPartition = sqlite3ExprListDup(db, pExist->pPartition, 0);
1027 if( pExist->pOrderBy ){
1028 assert( pWin->pOrderBy==0 );
1029 pWin->pOrderBy = sqlite3ExprListDup(db, pExist->pOrderBy, 0);
1030 }
1031 sqlite3DbFree(db, pWin->zBase);
1032 pWin->zBase = 0;
1033 }
1034 }
1035 }
1036}
1037
1038/*
danc0bb4452018-06-12 20:53:38 +00001039** Attach window object pWin to expression p.
1040*/
dan86fb6e12018-05-16 20:58:07 +00001041void sqlite3WindowAttach(Parse *pParse, Expr *p, Window *pWin){
1042 if( p ){
drheda079c2018-09-20 19:02:15 +00001043 assert( p->op==TK_FUNCTION );
drh954733b2018-07-27 23:33:16 +00001044 /* This routine is only called for the parser. If pWin was not
1045 ** allocated due to an OOM, then the parser would fail before ever
1046 ** invoking this routine */
1047 if( ALWAYS(pWin) ){
drheda079c2018-09-20 19:02:15 +00001048 p->y.pWin = pWin;
1049 ExprSetProperty(p, EP_WinFunc);
dane33f6e72018-07-06 07:42:42 +00001050 pWin->pOwner = p;
1051 if( p->flags & EP_Distinct ){
drhe4984a22018-07-06 17:19:20 +00001052 sqlite3ErrorMsg(pParse,
1053 "DISTINCT is not supported for window functions");
dane33f6e72018-07-06 07:42:42 +00001054 }
1055 }
dan86fb6e12018-05-16 20:58:07 +00001056 }else{
1057 sqlite3WindowDelete(pParse->db, pWin);
1058 }
1059}
dane2f781b2018-05-17 19:24:08 +00001060
1061/*
1062** Return 0 if the two window objects are identical, or non-zero otherwise.
dan13078ca2018-06-13 20:29:38 +00001063** Identical window objects can be processed in a single scan.
dane2f781b2018-05-17 19:24:08 +00001064*/
1065int sqlite3WindowCompare(Parse *pParse, Window *p1, Window *p2){
1066 if( p1->eType!=p2->eType ) return 1;
1067 if( p1->eStart!=p2->eStart ) return 1;
1068 if( p1->eEnd!=p2->eEnd ) return 1;
1069 if( sqlite3ExprCompare(pParse, p1->pStart, p2->pStart, -1) ) return 1;
1070 if( sqlite3ExprCompare(pParse, p1->pEnd, p2->pEnd, -1) ) return 1;
1071 if( sqlite3ExprListCompare(p1->pPartition, p2->pPartition, -1) ) return 1;
1072 if( sqlite3ExprListCompare(p1->pOrderBy, p2->pOrderBy, -1) ) return 1;
1073 return 0;
1074}
1075
dan13078ca2018-06-13 20:29:38 +00001076
1077/*
1078** This is called by code in select.c before it calls sqlite3WhereBegin()
1079** to begin iterating through the sub-query results. It is used to allocate
1080** and initialize registers and cursors used by sqlite3WindowCodeStep().
1081*/
1082void sqlite3WindowCodeInit(Parse *pParse, Window *pMWin){
danc9a86682018-05-30 20:44:58 +00001083 Window *pWin;
dan13078ca2018-06-13 20:29:38 +00001084 Vdbe *v = sqlite3GetVdbe(pParse);
1085 int nPart = (pMWin->pPartition ? pMWin->pPartition->nExpr : 0);
1086 nPart += (pMWin->pOrderBy ? pMWin->pOrderBy->nExpr : 0);
1087 if( nPart ){
1088 pMWin->regPart = pParse->nMem+1;
1089 pParse->nMem += nPart;
1090 sqlite3VdbeAddOp3(v, OP_Null, 0, pMWin->regPart, pMWin->regPart+nPart-1);
1091 }
1092
dan680f6e82019-03-04 21:07:11 +00001093 pMWin->regFirst = ++pParse->nMem;
1094 sqlite3VdbeAddOp2(v, OP_Integer, 1, pMWin->regFirst);
danb33487b2019-03-06 17:12:32 +00001095 pMWin->regSize = ++pParse->nMem;
1096 sqlite3VdbeAddOp2(v, OP_Integer, 0, pMWin->regSize);
dan680f6e82019-03-04 21:07:11 +00001097
danc9a86682018-05-30 20:44:58 +00001098 for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
danec891fd2018-06-06 20:51:02 +00001099 FuncDef *p = pWin->pFunc;
1100 if( (p->funcFlags & SQLITE_FUNC_MINMAX) && pWin->eStart!=TK_UNBOUNDED ){
dan9a947222018-06-14 19:06:36 +00001101 /* The inline versions of min() and max() require a single ephemeral
1102 ** table and 3 registers. The registers are used as follows:
1103 **
1104 ** regApp+0: slot to copy min()/max() argument to for MakeRecord
1105 ** regApp+1: integer value used to ensure keys are unique
1106 ** regApp+2: output of MakeRecord
1107 */
danc9a86682018-05-30 20:44:58 +00001108 ExprList *pList = pWin->pOwner->x.pList;
1109 KeyInfo *pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pList, 0, 0);
danc9a86682018-05-30 20:44:58 +00001110 pWin->csrApp = pParse->nTab++;
1111 pWin->regApp = pParse->nMem+1;
1112 pParse->nMem += 3;
1113 if( pKeyInfo && pWin->pFunc->zName[1]=='i' ){
1114 assert( pKeyInfo->aSortOrder[0]==0 );
1115 pKeyInfo->aSortOrder[0] = 1;
1116 }
1117 sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pWin->csrApp, 2);
1118 sqlite3VdbeAppendP4(v, pKeyInfo, P4_KEYINFO);
1119 sqlite3VdbeAddOp2(v, OP_Integer, 0, pWin->regApp+1);
1120 }
drh19dc4d42018-07-08 01:02:26 +00001121 else if( p->zName==nth_valueName || p->zName==first_valueName ){
danec891fd2018-06-06 20:51:02 +00001122 /* Allocate two registers at pWin->regApp. These will be used to
1123 ** store the start and end index of the current frame. */
1124 assert( pMWin->iEphCsr );
1125 pWin->regApp = pParse->nMem+1;
1126 pWin->csrApp = pParse->nTab++;
1127 pParse->nMem += 2;
danec891fd2018-06-06 20:51:02 +00001128 sqlite3VdbeAddOp2(v, OP_OpenDup, pWin->csrApp, pMWin->iEphCsr);
1129 }
drh19dc4d42018-07-08 01:02:26 +00001130 else if( p->zName==leadName || p->zName==lagName ){
danfe4e25a2018-06-07 20:08:59 +00001131 assert( pMWin->iEphCsr );
1132 pWin->csrApp = pParse->nTab++;
1133 sqlite3VdbeAddOp2(v, OP_OpenDup, pWin->csrApp, pMWin->iEphCsr);
1134 }
danc9a86682018-05-30 20:44:58 +00001135 }
1136}
1137
dan13078ca2018-06-13 20:29:38 +00001138/*
dana1a7e112018-07-09 13:31:18 +00001139** A "PRECEDING <expr>" (eCond==0) or "FOLLOWING <expr>" (eCond==1) or the
1140** value of the second argument to nth_value() (eCond==2) has just been
1141** evaluated and the result left in register reg. This function generates VM
1142** code to check that the value is a non-negative integer and throws an
1143** exception if it is not.
dan13078ca2018-06-13 20:29:38 +00001144*/
dana1a7e112018-07-09 13:31:18 +00001145static void windowCheckIntValue(Parse *pParse, int reg, int eCond){
danc3a20c12018-05-23 20:55:37 +00001146 static const char *azErr[] = {
1147 "frame starting offset must be a non-negative integer",
dana1a7e112018-07-09 13:31:18 +00001148 "frame ending offset must be a non-negative integer",
1149 "second argument to nth_value must be a positive integer"
danc3a20c12018-05-23 20:55:37 +00001150 };
dana1a7e112018-07-09 13:31:18 +00001151 static int aOp[] = { OP_Ge, OP_Ge, OP_Gt };
danc3a20c12018-05-23 20:55:37 +00001152 Vdbe *v = sqlite3GetVdbe(pParse);
dan13078ca2018-06-13 20:29:38 +00001153 int regZero = sqlite3GetTempReg(pParse);
dana1a7e112018-07-09 13:31:18 +00001154 assert( eCond==0 || eCond==1 || eCond==2 );
danc3a20c12018-05-23 20:55:37 +00001155 sqlite3VdbeAddOp2(v, OP_Integer, 0, regZero);
1156 sqlite3VdbeAddOp2(v, OP_MustBeInt, reg, sqlite3VdbeCurrentAddr(v)+2);
drh0b3b0dd2018-07-10 05:11:03 +00001157 VdbeCoverageIf(v, eCond==0);
1158 VdbeCoverageIf(v, eCond==1);
1159 VdbeCoverageIf(v, eCond==2);
dana1a7e112018-07-09 13:31:18 +00001160 sqlite3VdbeAddOp3(v, aOp[eCond], regZero, sqlite3VdbeCurrentAddr(v)+2, reg);
drh6ccbd272018-07-10 17:10:44 +00001161 VdbeCoverageNeverNullIf(v, eCond==0);
1162 VdbeCoverageNeverNullIf(v, eCond==1);
1163 VdbeCoverageNeverNullIf(v, eCond==2);
drh211a0852019-01-27 02:41:34 +00001164 sqlite3MayAbort(pParse);
danc3a20c12018-05-23 20:55:37 +00001165 sqlite3VdbeAddOp2(v, OP_Halt, SQLITE_ERROR, OE_Abort);
dana1a7e112018-07-09 13:31:18 +00001166 sqlite3VdbeAppendP4(v, (void*)azErr[eCond], P4_STATIC);
dan13078ca2018-06-13 20:29:38 +00001167 sqlite3ReleaseTempReg(pParse, regZero);
danc3a20c12018-05-23 20:55:37 +00001168}
1169
dan13078ca2018-06-13 20:29:38 +00001170/*
1171** Return the number of arguments passed to the window-function associated
1172** with the object passed as the only argument to this function.
1173*/
dan2a11bb22018-06-11 20:50:25 +00001174static int windowArgCount(Window *pWin){
1175 ExprList *pList = pWin->pOwner->x.pList;
1176 return (pList ? pList->nExpr : 0);
1177}
1178
danc9a86682018-05-30 20:44:58 +00001179/*
1180** Generate VM code to invoke either xStep() (if bInverse is 0) or
1181** xInverse (if bInverse is non-zero) for each window function in the
dan13078ca2018-06-13 20:29:38 +00001182** linked list starting at pMWin. Or, for built-in window functions
1183** that do not use the standard function API, generate the required
1184** inline VM code.
1185**
1186** If argument csr is greater than or equal to 0, then argument reg is
1187** the first register in an array of registers guaranteed to be large
1188** enough to hold the array of arguments for each function. In this case
1189** the arguments are extracted from the current row of csr into the
drh8f26da62018-07-05 21:22:57 +00001190** array of registers before invoking OP_AggStep or OP_AggInverse
dan13078ca2018-06-13 20:29:38 +00001191**
1192** Or, if csr is less than zero, then the array of registers at reg is
1193** already populated with all columns from the current row of the sub-query.
1194**
1195** If argument regPartSize is non-zero, then it is a register containing the
1196** number of rows in the current partition.
danc9a86682018-05-30 20:44:58 +00001197*/
dan31f56392018-05-24 21:10:57 +00001198static void windowAggStep(
1199 Parse *pParse,
dan13078ca2018-06-13 20:29:38 +00001200 Window *pMWin, /* Linked list of window functions */
1201 int csr, /* Read arguments from this cursor */
1202 int bInverse, /* True to invoke xInverse instead of xStep */
1203 int reg, /* Array of registers */
dandfa552f2018-06-02 21:04:28 +00001204 int regPartSize /* Register containing size of partition */
dan31f56392018-05-24 21:10:57 +00001205){
1206 Vdbe *v = sqlite3GetVdbe(pParse);
1207 Window *pWin;
1208 for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
dandfa552f2018-06-02 21:04:28 +00001209 int flags = pWin->pFunc->funcFlags;
danc9a86682018-05-30 20:44:58 +00001210 int regArg;
dan2a11bb22018-06-11 20:50:25 +00001211 int nArg = windowArgCount(pWin);
dandfa552f2018-06-02 21:04:28 +00001212
dan6bc5c9e2018-06-04 18:55:11 +00001213 if( csr>=0 ){
danc9a86682018-05-30 20:44:58 +00001214 int i;
dan2a11bb22018-06-11 20:50:25 +00001215 for(i=0; i<nArg; i++){
danc9a86682018-05-30 20:44:58 +00001216 sqlite3VdbeAddOp3(v, OP_Column, csr, pWin->iArgCol+i, reg+i);
1217 }
1218 regArg = reg;
dan6bc5c9e2018-06-04 18:55:11 +00001219 if( flags & SQLITE_FUNC_WINDOW_SIZE ){
1220 if( nArg==0 ){
1221 regArg = regPartSize;
1222 }else{
1223 sqlite3VdbeAddOp2(v, OP_SCopy, regPartSize, reg+nArg);
1224 }
1225 nArg++;
1226 }
danc9a86682018-05-30 20:44:58 +00001227 }else{
dan6bc5c9e2018-06-04 18:55:11 +00001228 assert( !(flags & SQLITE_FUNC_WINDOW_SIZE) );
danc9a86682018-05-30 20:44:58 +00001229 regArg = reg + pWin->iArgCol;
dan31f56392018-05-24 21:10:57 +00001230 }
danc9a86682018-05-30 20:44:58 +00001231
danec891fd2018-06-06 20:51:02 +00001232 if( (pWin->pFunc->funcFlags & SQLITE_FUNC_MINMAX)
1233 && pWin->eStart!=TK_UNBOUNDED
1234 ){
dand4fc49f2018-07-07 17:30:44 +00001235 int addrIsNull = sqlite3VdbeAddOp1(v, OP_IsNull, regArg);
1236 VdbeCoverage(v);
danc9a86682018-05-30 20:44:58 +00001237 if( bInverse==0 ){
1238 sqlite3VdbeAddOp2(v, OP_AddImm, pWin->regApp+1, 1);
1239 sqlite3VdbeAddOp2(v, OP_SCopy, regArg, pWin->regApp);
1240 sqlite3VdbeAddOp3(v, OP_MakeRecord, pWin->regApp, 2, pWin->regApp+2);
1241 sqlite3VdbeAddOp2(v, OP_IdxInsert, pWin->csrApp, pWin->regApp+2);
1242 }else{
1243 sqlite3VdbeAddOp4Int(v, OP_SeekGE, pWin->csrApp, 0, regArg, 1);
drh93419162018-07-11 03:27:52 +00001244 VdbeCoverageNeverTaken(v);
danc9a86682018-05-30 20:44:58 +00001245 sqlite3VdbeAddOp1(v, OP_Delete, pWin->csrApp);
1246 sqlite3VdbeJumpHere(v, sqlite3VdbeCurrentAddr(v)-2);
1247 }
dand4fc49f2018-07-07 17:30:44 +00001248 sqlite3VdbeJumpHere(v, addrIsNull);
danec891fd2018-06-06 20:51:02 +00001249 }else if( pWin->regApp ){
drh19dc4d42018-07-08 01:02:26 +00001250 assert( pWin->pFunc->zName==nth_valueName
1251 || pWin->pFunc->zName==first_valueName
dan7095c002018-06-07 17:45:22 +00001252 );
danec891fd2018-06-06 20:51:02 +00001253 assert( bInverse==0 || bInverse==1 );
1254 sqlite3VdbeAddOp2(v, OP_AddImm, pWin->regApp+1-bInverse, 1);
drh19dc4d42018-07-08 01:02:26 +00001255 }else if( pWin->pFunc->zName==leadName
1256 || pWin->pFunc->zName==lagName
danfe4e25a2018-06-07 20:08:59 +00001257 ){
1258 /* no-op */
danc9a86682018-05-30 20:44:58 +00001259 }else{
dan8b985602018-06-09 17:43:45 +00001260 int addrIf = 0;
1261 if( pWin->pFilter ){
1262 int regTmp;
danf5e8e312018-07-09 06:51:36 +00001263 assert( nArg==0 || nArg==pWin->pOwner->x.pList->nExpr );
1264 assert( nArg || pWin->pOwner->x.pList==0 );
dan8b985602018-06-09 17:43:45 +00001265 if( csr>0 ){
1266 regTmp = sqlite3GetTempReg(pParse);
dan2a11bb22018-06-11 20:50:25 +00001267 sqlite3VdbeAddOp3(v, OP_Column, csr, pWin->iArgCol+nArg,regTmp);
dan8b985602018-06-09 17:43:45 +00001268 }else{
dan2a11bb22018-06-11 20:50:25 +00001269 regTmp = regArg + nArg;
dan8b985602018-06-09 17:43:45 +00001270 }
1271 addrIf = sqlite3VdbeAddOp3(v, OP_IfNot, regTmp, 0, 1);
dan01e12292018-06-27 20:24:59 +00001272 VdbeCoverage(v);
dan8b985602018-06-09 17:43:45 +00001273 if( csr>0 ){
1274 sqlite3ReleaseTempReg(pParse, regTmp);
1275 }
1276 }
danc9a86682018-05-30 20:44:58 +00001277 if( pWin->pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL ){
1278 CollSeq *pColl;
danf5e8e312018-07-09 06:51:36 +00001279 assert( nArg>0 );
dan8b985602018-06-09 17:43:45 +00001280 pColl = sqlite3ExprNNCollSeq(pParse, pWin->pOwner->x.pList->a[0].pExpr);
danc9a86682018-05-30 20:44:58 +00001281 sqlite3VdbeAddOp4(v, OP_CollSeq, 0,0,0, (const char*)pColl, P4_COLLSEQ);
1282 }
drh8f26da62018-07-05 21:22:57 +00001283 sqlite3VdbeAddOp3(v, bInverse? OP_AggInverse : OP_AggStep,
1284 bInverse, regArg, pWin->regAccum);
danc9a86682018-05-30 20:44:58 +00001285 sqlite3VdbeAppendP4(v, pWin->pFunc, P4_FUNCDEF);
dandfa552f2018-06-02 21:04:28 +00001286 sqlite3VdbeChangeP5(v, (u8)nArg);
dan8b985602018-06-09 17:43:45 +00001287 if( addrIf ) sqlite3VdbeJumpHere(v, addrIf);
danc9a86682018-05-30 20:44:58 +00001288 }
dan31f56392018-05-24 21:10:57 +00001289 }
1290}
1291
dan13078ca2018-06-13 20:29:38 +00001292/*
1293** Generate VM code to invoke either xValue() (bFinal==0) or xFinalize()
1294** (bFinal==1) for each window function in the linked list starting at
1295** pMWin. Or, for built-in window-functions that do not use the standard
1296** API, generate the equivalent VM code.
1297*/
dand6f784e2018-05-28 18:30:45 +00001298static void windowAggFinal(Parse *pParse, Window *pMWin, int bFinal){
1299 Vdbe *v = sqlite3GetVdbe(pParse);
1300 Window *pWin;
1301
1302 for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
danec891fd2018-06-06 20:51:02 +00001303 if( (pWin->pFunc->funcFlags & SQLITE_FUNC_MINMAX)
1304 && pWin->eStart!=TK_UNBOUNDED
1305 ){
dand6f784e2018-05-28 18:30:45 +00001306 sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regResult);
danc9a86682018-05-30 20:44:58 +00001307 sqlite3VdbeAddOp1(v, OP_Last, pWin->csrApp);
dan01e12292018-06-27 20:24:59 +00001308 VdbeCoverage(v);
danc9a86682018-05-30 20:44:58 +00001309 sqlite3VdbeAddOp3(v, OP_Column, pWin->csrApp, 0, pWin->regResult);
1310 sqlite3VdbeJumpHere(v, sqlite3VdbeCurrentAddr(v)-2);
1311 if( bFinal ){
1312 sqlite3VdbeAddOp1(v, OP_ResetSorter, pWin->csrApp);
1313 }
danec891fd2018-06-06 20:51:02 +00001314 }else if( pWin->regApp ){
dand6f784e2018-05-28 18:30:45 +00001315 }else{
danc9a86682018-05-30 20:44:58 +00001316 if( bFinal ){
drh8f26da62018-07-05 21:22:57 +00001317 sqlite3VdbeAddOp2(v, OP_AggFinal, pWin->regAccum, windowArgCount(pWin));
1318 sqlite3VdbeAppendP4(v, pWin->pFunc, P4_FUNCDEF);
danc9a86682018-05-30 20:44:58 +00001319 sqlite3VdbeAddOp2(v, OP_Copy, pWin->regAccum, pWin->regResult);
dan8b985602018-06-09 17:43:45 +00001320 sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regAccum);
danc9a86682018-05-30 20:44:58 +00001321 }else{
drh8f26da62018-07-05 21:22:57 +00001322 sqlite3VdbeAddOp3(v, OP_AggValue, pWin->regAccum, windowArgCount(pWin),
1323 pWin->regResult);
1324 sqlite3VdbeAppendP4(v, pWin->pFunc, P4_FUNCDEF);
danc9a86682018-05-30 20:44:58 +00001325 }
dand6f784e2018-05-28 18:30:45 +00001326 }
1327 }
1328}
1329
dan13078ca2018-06-13 20:29:38 +00001330/*
dan13078ca2018-06-13 20:29:38 +00001331** Invoke the sub-routine at regGosub (generated by code in select.c) to
1332** return the current row of Window.iEphCsr. If all window functions are
1333** aggregate window functions that use the standard API, a single
1334** OP_Gosub instruction is all that this routine generates. Extra VM code
1335** for per-row processing is only generated for the following built-in window
1336** functions:
1337**
1338** nth_value()
1339** first_value()
1340** lag()
1341** lead()
1342*/
danec891fd2018-06-06 20:51:02 +00001343static void windowReturnOneRow(
1344 Parse *pParse,
1345 Window *pMWin,
1346 int regGosub,
1347 int addrGosub
1348){
1349 Vdbe *v = sqlite3GetVdbe(pParse);
1350 Window *pWin;
1351 for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
1352 FuncDef *pFunc = pWin->pFunc;
drh19dc4d42018-07-08 01:02:26 +00001353 if( pFunc->zName==nth_valueName
1354 || pFunc->zName==first_valueName
dan7095c002018-06-07 17:45:22 +00001355 ){
danec891fd2018-06-06 20:51:02 +00001356 int csr = pWin->csrApp;
drhec4ccdb2018-12-29 02:26:59 +00001357 int lbl = sqlite3VdbeMakeLabel(pParse);
danec891fd2018-06-06 20:51:02 +00001358 int tmpReg = sqlite3GetTempReg(pParse);
1359 sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regResult);
dan7095c002018-06-07 17:45:22 +00001360
drh19dc4d42018-07-08 01:02:26 +00001361 if( pFunc->zName==nth_valueName ){
dan6fde1792018-06-15 19:01:35 +00001362 sqlite3VdbeAddOp3(v, OP_Column, pMWin->iEphCsr, pWin->iArgCol+1,tmpReg);
dana1a7e112018-07-09 13:31:18 +00001363 windowCheckIntValue(pParse, tmpReg, 2);
dan7095c002018-06-07 17:45:22 +00001364 }else{
1365 sqlite3VdbeAddOp2(v, OP_Integer, 1, tmpReg);
1366 }
danec891fd2018-06-06 20:51:02 +00001367 sqlite3VdbeAddOp3(v, OP_Add, tmpReg, pWin->regApp, tmpReg);
1368 sqlite3VdbeAddOp3(v, OP_Gt, pWin->regApp+1, lbl, tmpReg);
drh6ccbd272018-07-10 17:10:44 +00001369 VdbeCoverageNeverNull(v);
drh93419162018-07-11 03:27:52 +00001370 sqlite3VdbeAddOp3(v, OP_SeekRowid, csr, 0, tmpReg);
1371 VdbeCoverageNeverTaken(v);
danec891fd2018-06-06 20:51:02 +00001372 sqlite3VdbeAddOp3(v, OP_Column, csr, pWin->iArgCol, pWin->regResult);
1373 sqlite3VdbeResolveLabel(v, lbl);
1374 sqlite3ReleaseTempReg(pParse, tmpReg);
1375 }
drh19dc4d42018-07-08 01:02:26 +00001376 else if( pFunc->zName==leadName || pFunc->zName==lagName ){
dan2a11bb22018-06-11 20:50:25 +00001377 int nArg = pWin->pOwner->x.pList->nExpr;
danfe4e25a2018-06-07 20:08:59 +00001378 int csr = pWin->csrApp;
drhec4ccdb2018-12-29 02:26:59 +00001379 int lbl = sqlite3VdbeMakeLabel(pParse);
danfe4e25a2018-06-07 20:08:59 +00001380 int tmpReg = sqlite3GetTempReg(pParse);
dan680f6e82019-03-04 21:07:11 +00001381 int iEph = pMWin->iEphCsr;
danfe4e25a2018-06-07 20:08:59 +00001382
dan2a11bb22018-06-11 20:50:25 +00001383 if( nArg<3 ){
danfe4e25a2018-06-07 20:08:59 +00001384 sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regResult);
1385 }else{
1386 sqlite3VdbeAddOp3(v, OP_Column, iEph, pWin->iArgCol+2, pWin->regResult);
1387 }
1388 sqlite3VdbeAddOp2(v, OP_Rowid, iEph, tmpReg);
dan2a11bb22018-06-11 20:50:25 +00001389 if( nArg<2 ){
drh19dc4d42018-07-08 01:02:26 +00001390 int val = (pFunc->zName==leadName ? 1 : -1);
danfe4e25a2018-06-07 20:08:59 +00001391 sqlite3VdbeAddOp2(v, OP_AddImm, tmpReg, val);
1392 }else{
drh19dc4d42018-07-08 01:02:26 +00001393 int op = (pFunc->zName==leadName ? OP_Add : OP_Subtract);
danfe4e25a2018-06-07 20:08:59 +00001394 int tmpReg2 = sqlite3GetTempReg(pParse);
1395 sqlite3VdbeAddOp3(v, OP_Column, iEph, pWin->iArgCol+1, tmpReg2);
1396 sqlite3VdbeAddOp3(v, op, tmpReg2, tmpReg, tmpReg);
1397 sqlite3ReleaseTempReg(pParse, tmpReg2);
1398 }
1399
1400 sqlite3VdbeAddOp3(v, OP_SeekRowid, csr, lbl, tmpReg);
dan01e12292018-06-27 20:24:59 +00001401 VdbeCoverage(v);
danfe4e25a2018-06-07 20:08:59 +00001402 sqlite3VdbeAddOp3(v, OP_Column, csr, pWin->iArgCol, pWin->regResult);
1403 sqlite3VdbeResolveLabel(v, lbl);
1404 sqlite3ReleaseTempReg(pParse, tmpReg);
1405 }
danec891fd2018-06-06 20:51:02 +00001406 }
1407 sqlite3VdbeAddOp2(v, OP_Gosub, regGosub, addrGosub);
1408}
1409
dan13078ca2018-06-13 20:29:38 +00001410/*
dan54a9ab32018-06-14 14:27:05 +00001411** Generate code to set the accumulator register for each window function
1412** in the linked list passed as the second argument to NULL. And perform
1413** any equivalent initialization required by any built-in window functions
1414** in the list.
1415*/
dan2e605682018-06-07 15:54:26 +00001416static int windowInitAccum(Parse *pParse, Window *pMWin){
1417 Vdbe *v = sqlite3GetVdbe(pParse);
1418 int regArg;
1419 int nArg = 0;
1420 Window *pWin;
1421 for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
dan9a947222018-06-14 19:06:36 +00001422 FuncDef *pFunc = pWin->pFunc;
dan2e605682018-06-07 15:54:26 +00001423 sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regAccum);
dan2a11bb22018-06-11 20:50:25 +00001424 nArg = MAX(nArg, windowArgCount(pWin));
drh19dc4d42018-07-08 01:02:26 +00001425 if( pFunc->zName==nth_valueName
1426 || pFunc->zName==first_valueName
dan7095c002018-06-07 17:45:22 +00001427 ){
dan2e605682018-06-07 15:54:26 +00001428 sqlite3VdbeAddOp2(v, OP_Integer, 0, pWin->regApp);
1429 sqlite3VdbeAddOp2(v, OP_Integer, 0, pWin->regApp+1);
1430 }
dan9a947222018-06-14 19:06:36 +00001431
1432 if( (pFunc->funcFlags & SQLITE_FUNC_MINMAX) && pWin->csrApp ){
1433 assert( pWin->eStart!=TK_UNBOUNDED );
1434 sqlite3VdbeAddOp1(v, OP_ResetSorter, pWin->csrApp);
1435 sqlite3VdbeAddOp2(v, OP_Integer, 0, pWin->regApp+1);
1436 }
dan2e605682018-06-07 15:54:26 +00001437 }
1438 regArg = pParse->nMem+1;
1439 pParse->nMem += nArg;
1440 return regArg;
1441}
1442
danb33487b2019-03-06 17:12:32 +00001443/*
dan00267b82019-03-06 21:04:11 +00001444** Return true if the entire partition should be cached in the ephemeral
1445** table before processing any rows.
danb33487b2019-03-06 17:12:32 +00001446*/
1447static int windowCachePartition(Window *pMWin){
1448 Window *pWin;
1449 for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
1450 FuncDef *pFunc = pWin->pFunc;
1451 if( (pFunc->funcFlags & SQLITE_FUNC_WINDOW_SIZE)
1452 || (pFunc->zName==nth_valueName)
1453 || (pFunc->zName==first_valueName)
1454 || (pFunc->zName==leadName)
1455 || (pFunc->zName==lagName)
1456 ){
1457 return 1;
1458 }
1459 }
1460 return 0;
1461}
1462
dan6c75b392019-03-08 20:02:52 +00001463/*
1464** regOld and regNew are each the first register in an array of size
1465** pOrderBy->nExpr. This function generates code to compare the two
1466** arrays of registers using the collation sequences and other comparison
1467** parameters specified by pOrderBy.
1468**
1469** If the two arrays are not equal, the contents of regNew is copied to
1470** regOld and control falls through. Otherwise, if the contents of the arrays
1471** are equal, an OP_Goto is executed. The address of the OP_Goto is returned.
1472*/
1473static int windowIfNewPeer(
1474 Parse *pParse,
1475 ExprList *pOrderBy,
1476 int regNew, /* First in array of new values */
1477 int regOld /* First in array of old values */
1478){
1479 Vdbe *v = sqlite3GetVdbe(pParse);
1480 int addr;
1481 if( pOrderBy ){
1482 int nVal = pOrderBy->nExpr;
1483 KeyInfo *pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pOrderBy, 0, 0);
1484 sqlite3VdbeAddOp3(v, OP_Compare, regOld, regNew, nVal);
1485 sqlite3VdbeAppendP4(v, (void*)pKeyInfo, P4_KEYINFO);
1486 addr = sqlite3VdbeAddOp3(
1487 v, OP_Jump, sqlite3VdbeCurrentAddr(v)+1, 0, sqlite3VdbeCurrentAddr(v)+1
dan72b9fdc2019-03-09 20:49:17 +00001488 );
dan6c75b392019-03-08 20:02:52 +00001489 VdbeCoverageEqNe(v);
1490 sqlite3VdbeAddOp3(v, OP_Copy, regNew, regOld, nVal-1);
1491 }else{
1492 addr = sqlite3VdbeAddOp0(v, OP_Goto);
1493 }
1494 return addr;
1495}
1496
dan00267b82019-03-06 21:04:11 +00001497typedef struct WindowCodeArg WindowCodeArg;
dan6c75b392019-03-08 20:02:52 +00001498typedef struct WindowCsrAndReg WindowCsrAndReg;
1499struct WindowCsrAndReg {
1500 int csr;
1501 int reg;
1502};
dan00267b82019-03-06 21:04:11 +00001503struct WindowCodeArg {
1504 Parse *pParse;
1505 Window *pMWin;
1506 Vdbe *pVdbe;
1507 int regGosub;
1508 int addrGosub;
1509 int regArg;
dan6c75b392019-03-08 20:02:52 +00001510
1511 WindowCsrAndReg start;
1512 WindowCsrAndReg current;
1513 WindowCsrAndReg end;
dan00267b82019-03-06 21:04:11 +00001514};
1515
1516#define WINDOW_RETURN_ROW 1
1517#define WINDOW_AGGINVERSE 2
1518#define WINDOW_AGGSTEP 3
1519
dan6c75b392019-03-08 20:02:52 +00001520/*
1521** Generate VM code to read the window frames peer values from cursor csr into
1522** an array of registers starting at reg.
1523*/
1524static void windowReadPeerValues(
1525 WindowCodeArg *p,
1526 int csr,
1527 int reg
1528){
1529 Window *pMWin = p->pMWin;
1530 ExprList *pOrderBy = pMWin->pOrderBy;
1531 if( pOrderBy ){
1532 Vdbe *v = sqlite3GetVdbe(p->pParse);
1533 ExprList *pPart = pMWin->pPartition;
1534 int iColOff = pMWin->nBufferCol + (pPart ? pPart->nExpr : 0);
1535 int i;
1536 for(i=0; i<pOrderBy->nExpr; i++){
1537 sqlite3VdbeAddOp3(v, OP_Column, csr, iColOff+i, reg+i);
1538 }
1539 }
1540}
1541
dan72b9fdc2019-03-09 20:49:17 +00001542/*
1543** This function is called as part of generating VM programs for RANGE
1544** offset PRECEDING/FOLLOWING frame boundaries. It generates code equivalent
1545** to:
1546**
1547** if( csr1.peerVal + regVal >= csr2.peerVal ) goto lbl;
1548** if( csr1.rowid >= csr2.rowid ) goto lbl;
1549*/
1550static void windowCodeRangeTest(
1551 WindowCodeArg *p,
1552 int op, /* OP_Ge or OP_Gt */
1553 int csr1,
1554 int regVal,
1555 int csr2,
1556 int lbl
1557){
1558 Parse *pParse = p->pParse;
1559 Vdbe *v = sqlite3GetVdbe(pParse);
1560 int reg1 = sqlite3GetTempReg(pParse);
1561 int reg2 = sqlite3GetTempReg(pParse);
1562 windowReadPeerValues(p, csr1, reg1);
1563 windowReadPeerValues(p, csr2, reg2);
1564 sqlite3VdbeAddOp3(v, OP_Add, reg1, regVal, reg1);
1565 sqlite3VdbeAddOp3(v, op, reg2, lbl, reg1);
1566 sqlite3VdbeAddOp2(v, OP_Rowid, csr1, reg1);
1567 sqlite3VdbeAddOp2(v, OP_Rowid, csr2, reg2);
1568 sqlite3VdbeAddOp3(v, OP_Gt, reg2, lbl, reg1);
1569 sqlite3ReleaseTempReg(pParse, reg1);
1570 sqlite3ReleaseTempReg(pParse, reg2);
1571
1572 assert( op==OP_Ge || op==OP_Gt || op==OP_Lt || op==OP_Le );
1573}
1574
dan00267b82019-03-06 21:04:11 +00001575static int windowCodeOp(
1576 WindowCodeArg *p,
1577 int op,
dan00267b82019-03-06 21:04:11 +00001578 int regCountdown,
1579 int jumpOnEof
1580){
dan6c75b392019-03-08 20:02:52 +00001581 int csr, reg;
1582 Parse *pParse = p->pParse;
dan54975cd2019-03-07 20:47:46 +00001583 Window *pMWin = p->pMWin;
dan00267b82019-03-06 21:04:11 +00001584 int ret = 0;
1585 Vdbe *v = p->pVdbe;
1586 int addrIf = 0;
dan6c75b392019-03-08 20:02:52 +00001587 int addrContinue = 0;
1588 int addrGoto = 0;
1589 int bPeer = (pMWin->eType!=TK_ROWS);
dan00267b82019-03-06 21:04:11 +00001590
dan72b9fdc2019-03-09 20:49:17 +00001591 int lblDone = sqlite3VdbeMakeLabel(pParse);
1592 int addrNextRange = 0;
1593
dan54975cd2019-03-07 20:47:46 +00001594 /* Special case - WINDOW_AGGINVERSE is always a no-op if the frame
1595 ** starts with UNBOUNDED PRECEDING. */
1596 if( op==WINDOW_AGGINVERSE && pMWin->eStart==TK_UNBOUNDED ){
1597 assert( regCountdown==0 && jumpOnEof==0 );
1598 return 0;
1599 }
1600
dan00267b82019-03-06 21:04:11 +00001601 if( regCountdown>0 ){
dan72b9fdc2019-03-09 20:49:17 +00001602 if( pMWin->eType==TK_RANGE ){
1603 addrNextRange = sqlite3VdbeCurrentAddr(v);
1604
1605 switch( op ){
1606 case WINDOW_RETURN_ROW: {
1607 assert( 0 );
1608 break;
1609 }
1610
1611 case WINDOW_AGGINVERSE: {
1612 if( pMWin->eStart==TK_FOLLOWING ){
1613 windowCodeRangeTest(
1614 p, OP_Le, p->current.csr, regCountdown, p->start.csr, lblDone
1615 );
1616 }else{
1617 windowCodeRangeTest(
1618 p, OP_Ge, p->start.csr, regCountdown, p->current.csr, lblDone
1619 );
1620 }
1621 break;
1622 }
1623
1624 case WINDOW_AGGSTEP: {
1625 windowCodeRangeTest(
1626 p, OP_Gt, p->end.csr, regCountdown, p->current.csr, lblDone
1627 );
1628 break;
1629 }
1630 }
1631
1632 }else{
1633 addrIf = sqlite3VdbeAddOp3(v, OP_IfPos, regCountdown, 0, 1);
1634 }
dan00267b82019-03-06 21:04:11 +00001635 }
1636
dan6c75b392019-03-08 20:02:52 +00001637 if( op==WINDOW_RETURN_ROW ){
1638 windowAggFinal(pParse, pMWin, 0);
1639 }
1640 addrContinue = sqlite3VdbeCurrentAddr(v);
dan00267b82019-03-06 21:04:11 +00001641 switch( op ){
1642 case WINDOW_RETURN_ROW:
dan6c75b392019-03-08 20:02:52 +00001643 csr = p->current.csr;
1644 reg = p->current.reg;
1645 windowReturnOneRow(pParse, pMWin, p->regGosub, p->addrGosub);
dan00267b82019-03-06 21:04:11 +00001646 break;
1647
1648 case WINDOW_AGGINVERSE:
dan6c75b392019-03-08 20:02:52 +00001649 csr = p->start.csr;
1650 reg = p->start.reg;
1651 windowAggStep(pParse, pMWin, csr, 1, p->regArg, pMWin->regSize);
dan00267b82019-03-06 21:04:11 +00001652 break;
1653
1654 case WINDOW_AGGSTEP:
dan6c75b392019-03-08 20:02:52 +00001655 csr = p->end.csr;
1656 reg = p->end.reg;
1657 windowAggStep(pParse, pMWin, csr, 0, p->regArg, pMWin->regSize);
dan00267b82019-03-06 21:04:11 +00001658 break;
1659 }
1660
danc8137502019-03-07 19:26:17 +00001661 if( jumpOnEof ){
1662 sqlite3VdbeAddOp2(v, OP_Next, csr, sqlite3VdbeCurrentAddr(v)+2);
1663 ret = sqlite3VdbeAddOp0(v, OP_Goto);
1664 }else{
dan6c75b392019-03-08 20:02:52 +00001665 sqlite3VdbeAddOp2(v, OP_Next, csr, sqlite3VdbeCurrentAddr(v)+1+bPeer);
1666 if( bPeer ){
1667 addrGoto = sqlite3VdbeAddOp0(v, OP_Goto);
1668 }
dan00267b82019-03-06 21:04:11 +00001669 }
danc8137502019-03-07 19:26:17 +00001670
dan6c75b392019-03-08 20:02:52 +00001671 if( bPeer ){
1672 int addr;
1673 int nReg = (pMWin->pOrderBy ? pMWin->pOrderBy->nExpr : 0);
1674 int regTmp = (nReg ? sqlite3GetTempRange(pParse, nReg) : 0);
1675 windowReadPeerValues(p, csr, regTmp);
1676 addr = windowIfNewPeer(pParse, pMWin->pOrderBy, regTmp, reg);
1677 sqlite3VdbeChangeP2(v, addr, addrContinue);
1678 sqlite3ReleaseTempRange(pParse, regTmp, nReg);
dan00267b82019-03-06 21:04:11 +00001679 }
dan6c75b392019-03-08 20:02:52 +00001680
dan72b9fdc2019-03-09 20:49:17 +00001681 if( addrNextRange ){
1682 sqlite3VdbeAddOp2(v, OP_Goto, 0, addrNextRange);
1683 }
1684 sqlite3VdbeResolveLabel(v, lblDone);
dan6c75b392019-03-08 20:02:52 +00001685 if( addrGoto ) sqlite3VdbeJumpHere(v, addrGoto);
1686 if( addrIf ) sqlite3VdbeJumpHere(v, addrIf);
dan00267b82019-03-06 21:04:11 +00001687 return ret;
1688}
1689
dan00267b82019-03-06 21:04:11 +00001690/*
1691** This function - windowCodeStep() - generates the VM code that reads data
1692** from the sub-select and returns rows to the consumer. For the simplest
1693** case:
1694**
1695** ROWS BETWEEN <expr1> PRECEDING AND <expr2> FOLLOWING
1696**
1697** The VM code generated is equivalent in spirit to the following:
1698**
1699** while( !eof ){
1700** if( new partition ){
1701** Gosub flush
1702** }
1703** Insert new row into eph table.
1704**
1705** if( first row of partition ){
1706** Rewind(csrEnd, skipNext=1)
dan6c75b392019-03-08 20:02:52 +00001707** Rewind(start.csr, skipNext=1)
dan00267b82019-03-06 21:04:11 +00001708** Rewind(csrCurrent, skipNext=1)
1709**
1710** regEnd = <expr2> // FOLLOWING expression
1711** regStart = <expr1> // PRECEDING expression
1712** }else{
1713** if( (regEnd--)<=0 ){
1714** Next(csrCurrent)
1715** Return one row.
1716** if( (regStart--)<0 ){
dan6c75b392019-03-08 20:02:52 +00001717** Next(start.csr)
1718** AggInverse(start.csr)
dan00267b82019-03-06 21:04:11 +00001719** }
1720** }
1721** }
1722**
1723** Next(csrEnd)
1724** AggStep(csrEnd)
1725** }
1726** flush:
1727** while( 1 ){
1728** Next(csrCurrent)
1729** if( eof ) break
1730** Return one row.
1731** if( (regStart--)<0 ){
dan6c75b392019-03-08 20:02:52 +00001732** Next(start.csr)
1733** AggInverse(start.csr)
dan00267b82019-03-06 21:04:11 +00001734** }
1735** }
1736** Empty eph table.
1737**
1738** More generally, the pattern used for all window types is:
1739**
1740** while( !eof ){
1741** if( new partition ){
1742** Gosub flush
1743** }
1744** Insert new row into eph table.
1745** if( first row of partition ){
1746** FIRST_ROW_CODE
1747** }else{
1748** SECOND_ROW_CODE
1749** }
1750** ALL_ROW_CODE
1751** }
1752** flush:
1753** FLUSH_CODE
1754** Empty eph table.
1755**
1756*/
dan680f6e82019-03-04 21:07:11 +00001757static void windowCodeStep(
1758 Parse *pParse,
1759 Select *p,
1760 WhereInfo *pWInfo,
1761 int regGosub,
1762 int addrGosub
1763){
1764 Window *pMWin = p->pWin;
dan6c75b392019-03-08 20:02:52 +00001765 ExprList *pOrderBy = pMWin->pOrderBy;
dan680f6e82019-03-04 21:07:11 +00001766 Vdbe *v = sqlite3GetVdbe(pParse);
1767 int regFlushPart; /* Register for "Gosub flush_partition" */
1768
1769 int regArg;
dan6c75b392019-03-08 20:02:52 +00001770 int csrWrite = pMWin->iEphCsr+1;
dan680f6e82019-03-04 21:07:11 +00001771
dan00267b82019-03-06 21:04:11 +00001772 int iSubCsr = p->pSrc->a[0].iCursor; /* Cursor of sub-select */
1773 int nSub = p->pSrc->a[0].pTab->nCol; /* Number of cols returned by sub */
1774 int iCol; /* To iterate through sub cols */
dan680f6e82019-03-04 21:07:11 +00001775
1776 int addrGoto;
1777 int addrIf;
dan680f6e82019-03-04 21:07:11 +00001778 int addrGosubFlush;
1779 int addrInteger;
danb33487b2019-03-06 17:12:32 +00001780 int addrCacheRewind;
1781 int addrCacheNext;
danb25a2142019-03-05 19:29:36 +00001782
1783 int addrShortcut = 0;
danc8137502019-03-07 19:26:17 +00001784 int addrEmpty = 0;
dan6c75b392019-03-08 20:02:52 +00001785 int addrPeerJump = 0;
dan680f6e82019-03-04 21:07:11 +00001786
danb33487b2019-03-06 17:12:32 +00001787 int bCache = windowCachePartition(pMWin);
1788
dan54975cd2019-03-07 20:47:46 +00001789 int regStart = 0; /* Value of <expr> PRECEDING */
1790 int regEnd = 0; /* Value of <expr> FOLLOWING */
1791
dan680f6e82019-03-04 21:07:11 +00001792 int reg = pParse->nMem+1;
1793 int regRecord = reg+nSub;
1794 int regRowid = regRecord+1;
dan6c75b392019-03-08 20:02:52 +00001795 int regPeer = 0;
1796 int regNewPeer = 0;
dan00267b82019-03-06 21:04:11 +00001797 WindowCodeArg s;
dan680f6e82019-03-04 21:07:11 +00001798
dan72b9fdc2019-03-09 20:49:17 +00001799 assert( pMWin->eStart==TK_PRECEDING || pMWin->eStart==TK_CURRENT
1800 || pMWin->eStart==TK_FOLLOWING || pMWin->eStart==TK_UNBOUNDED
1801 );
1802 assert( pMWin->eEnd==TK_FOLLOWING || pMWin->eEnd==TK_CURRENT
1803 || pMWin->eEnd==TK_UNBOUNDED || pMWin->eEnd==TK_PRECEDING
1804 );
1805
dan00267b82019-03-06 21:04:11 +00001806 memset(&s, 0, sizeof(WindowCodeArg));
1807 s.pParse = pParse;
1808 s.pMWin = pMWin;
1809 s.pVdbe = v;
1810 s.regGosub = regGosub;
1811 s.addrGosub = addrGosub;
dan6c75b392019-03-08 20:02:52 +00001812 s.current.csr = pMWin->iEphCsr;
1813 s.start.csr = s.current.csr+2;
1814 s.end.csr = s.current.csr+3;
danb33487b2019-03-06 17:12:32 +00001815
dan680f6e82019-03-04 21:07:11 +00001816 pParse->nMem += 1 + nSub + 1;
1817
1818 regFlushPart = ++pParse->nMem;
dan54975cd2019-03-07 20:47:46 +00001819
1820 if( pMWin->eStart==TK_PRECEDING || pMWin->eStart==TK_FOLLOWING ){
1821 regStart = ++pParse->nMem;
1822 }
1823 if( pMWin->eEnd==TK_PRECEDING || pMWin->eEnd==TK_FOLLOWING ){
1824 regEnd = ++pParse->nMem;
1825 }
dan680f6e82019-03-04 21:07:11 +00001826
dan72b9fdc2019-03-09 20:49:17 +00001827 /* If this is not a "ROWS BETWEEN ..." frame, then allocate arrays of
1828 ** registers to store a copies of the ORDER BY expressions for the
1829 ** main loop, and for each cursor (start, current and end). */
dan6c75b392019-03-08 20:02:52 +00001830 if( pMWin->eType!=TK_ROWS ){
1831 int nPeer = (pOrderBy ? pOrderBy->nExpr : 0);
1832 regNewPeer = reg + pMWin->nBufferCol;
1833 if( pMWin->pPartition ) regNewPeer += pMWin->pPartition->nExpr;
1834
1835 regPeer = pParse->nMem+1; pParse->nMem += nPeer;
1836 s.start.reg = pParse->nMem+1; pParse->nMem += nPeer;
1837 s.current.reg = pParse->nMem+1; pParse->nMem += nPeer;
1838 s.end.reg = pParse->nMem+1; pParse->nMem += nPeer;
1839 }
1840
dan680f6e82019-03-04 21:07:11 +00001841 /* Load the column values for the row returned by the sub-select
1842 ** into an array of registers starting at reg. Assemble them into
1843 ** a record in register regRecord. TODO: An optimization here? */
dan00267b82019-03-06 21:04:11 +00001844 for(iCol=0; iCol<nSub; iCol++){
1845 sqlite3VdbeAddOp3(v, OP_Column, iSubCsr, iCol, reg+iCol);
dan680f6e82019-03-04 21:07:11 +00001846 }
1847 sqlite3VdbeAddOp3(v, OP_MakeRecord, reg, nSub, regRecord);
1848
danb33487b2019-03-06 17:12:32 +00001849 /* An input row has just been read into an array of registers starting
1850 ** at reg. If the window has a PARTITION clause, this block generates
1851 ** VM code to check if the input row is the start of a new partition.
1852 ** If so, it does an OP_Gosub to an address to be filled in later. The
1853 ** address of the OP_Gosub is stored in local variable addrGosubFlush.
1854 */
dan680f6e82019-03-04 21:07:11 +00001855 if( pMWin->pPartition ){
1856 int addr;
1857 ExprList *pPart = pMWin->pPartition;
1858 int nPart = pPart->nExpr;
1859 int regNewPart = reg + pMWin->nBufferCol;
1860 KeyInfo *pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pPart, 0, 0);
1861
dan680f6e82019-03-04 21:07:11 +00001862 addr = sqlite3VdbeAddOp3(v, OP_Compare, regNewPart, pMWin->regPart, nPart);
1863 sqlite3VdbeAppendP4(v, (void*)pKeyInfo, P4_KEYINFO);
danb33487b2019-03-06 17:12:32 +00001864 sqlite3VdbeAddOp3(v, OP_Jump, addr+2, addr+4, addr+2);
dan680f6e82019-03-04 21:07:11 +00001865 VdbeCoverageEqNe(v);
1866 addrGosubFlush = sqlite3VdbeAddOp1(v, OP_Gosub, regFlushPart);
1867 VdbeComment((v, "call flush_partition"));
danb33487b2019-03-06 17:12:32 +00001868 sqlite3VdbeAddOp3(v, OP_Copy, regNewPart, pMWin->regPart, nPart-1);
dan680f6e82019-03-04 21:07:11 +00001869 }
1870
1871 /* Insert the new row into the ephemeral table */
1872 sqlite3VdbeAddOp2(v, OP_NewRowid, csrWrite, regRowid);
1873 sqlite3VdbeAddOp3(v, OP_Insert, csrWrite, regRecord, regRowid);
danb33487b2019-03-06 17:12:32 +00001874 sqlite3VdbeAddOp2(v, OP_AddImm, pMWin->regSize, 1);
dan680f6e82019-03-04 21:07:11 +00001875
danb33487b2019-03-06 17:12:32 +00001876 if( bCache ){
1877 sqlite3VdbeAddOp2(v, OP_Integer, 0, pMWin->regFirst);
1878 sqlite3WhereEnd(pWInfo);
1879 addrInteger = sqlite3VdbeAddOp2(v, OP_Integer, 0, regFlushPart);
1880 if( pMWin->pPartition ){
1881 sqlite3VdbeJumpHere(v, addrGosubFlush);
1882 }
1883 addrCacheRewind = sqlite3VdbeAddOp1(v, OP_Rewind, csrWrite);
1884 }else{
1885 addrIf = sqlite3VdbeAddOp1(v, OP_IfNot, pMWin->regFirst);
dan680f6e82019-03-04 21:07:11 +00001886 }
danb25a2142019-03-05 19:29:36 +00001887
danb33487b2019-03-06 17:12:32 +00001888 /* This block is run for the first row of each partition */
dan00267b82019-03-06 21:04:11 +00001889 s.regArg = regArg = windowInitAccum(pParse, pMWin);
dan680f6e82019-03-04 21:07:11 +00001890
dan54975cd2019-03-07 20:47:46 +00001891 if( regStart ){
1892 sqlite3ExprCode(pParse, pMWin->pStart, regStart);
1893 windowCheckIntValue(pParse, regStart, 0);
1894 }
1895 if( regEnd ){
1896 sqlite3ExprCode(pParse, pMWin->pEnd, regEnd);
1897 windowCheckIntValue(pParse, regEnd, 1);
1898 }
danb25a2142019-03-05 19:29:36 +00001899
dan54975cd2019-03-07 20:47:46 +00001900 if( pMWin->eStart==pMWin->eEnd && regStart && regEnd ){
danb25a2142019-03-05 19:29:36 +00001901 int op = ((pMWin->eStart==TK_FOLLOWING) ? OP_Ge : OP_Le);
1902 int addrGe = sqlite3VdbeAddOp3(v, op, regStart, 0, regEnd);
1903 windowAggFinal(pParse, pMWin, 0);
danb33487b2019-03-06 17:12:32 +00001904 if( bCache ){
1905 sqlite3VdbeAddOp2(v, OP_Rowid, csrWrite, regRowid);
dan6c75b392019-03-08 20:02:52 +00001906 sqlite3VdbeAddOp3(v, OP_NotExists, s.current.csr, 0, regRowid);
danb33487b2019-03-06 17:12:32 +00001907 windowReturnOneRow(pParse, pMWin, regGosub, addrGosub);
1908 sqlite3VdbeAddOp2(v, OP_Next, csrWrite, addrCacheRewind+1);
1909 }else{
dan6c75b392019-03-08 20:02:52 +00001910 sqlite3VdbeAddOp2(v, OP_Rewind, s.current.csr, 1);
danb33487b2019-03-06 17:12:32 +00001911 windowReturnOneRow(pParse, pMWin, regGosub, addrGosub);
dan6c75b392019-03-08 20:02:52 +00001912 sqlite3VdbeAddOp1(v, OP_ResetSorter, s.current.csr);
danb33487b2019-03-06 17:12:32 +00001913 }
danb25a2142019-03-05 19:29:36 +00001914 addrShortcut = sqlite3VdbeAddOp0(v, OP_Goto);
1915 sqlite3VdbeJumpHere(v, addrGe);
1916 }
dan72b9fdc2019-03-09 20:49:17 +00001917 if( pMWin->eStart==TK_FOLLOWING && pMWin->eType!=TK_RANGE && regEnd ){
dan54975cd2019-03-07 20:47:46 +00001918 assert( pMWin->eEnd==TK_FOLLOWING );
danb25a2142019-03-05 19:29:36 +00001919 sqlite3VdbeAddOp3(v, OP_Subtract, regStart, regEnd, regStart);
1920 }
1921
dan54975cd2019-03-07 20:47:46 +00001922 if( pMWin->eStart!=TK_UNBOUNDED ){
dan6c75b392019-03-08 20:02:52 +00001923 sqlite3VdbeAddOp2(v, OP_Rewind, s.start.csr, 1);
dan54975cd2019-03-07 20:47:46 +00001924 }
dan6c75b392019-03-08 20:02:52 +00001925 sqlite3VdbeAddOp2(v, OP_Rewind, s.current.csr, 1);
1926 sqlite3VdbeAddOp2(v, OP_Rewind, s.end.csr, 1);
1927 if( regPeer && pOrderBy ){
1928 if( bCache ){
1929 windowReadPeerValues(&s, csrWrite, regPeer);
1930 }else{
1931 sqlite3VdbeAddOp3(v, OP_Copy, regNewPeer, regPeer, pOrderBy->nExpr-1);
1932 }
1933 sqlite3VdbeAddOp3(v, OP_Copy, regPeer, s.start.reg, pOrderBy->nExpr-1);
1934 sqlite3VdbeAddOp3(v, OP_Copy, regPeer, s.current.reg, pOrderBy->nExpr-1);
1935 sqlite3VdbeAddOp3(v, OP_Copy, regPeer, s.end.reg, pOrderBy->nExpr-1);
1936 }
danb25a2142019-03-05 19:29:36 +00001937
1938 sqlite3VdbeAddOp2(v, OP_Integer, 0, pMWin->regFirst);
dan680f6e82019-03-04 21:07:11 +00001939 addrGoto = sqlite3VdbeAddOp0(v, OP_Goto);
1940
dan00267b82019-03-06 21:04:11 +00001941 /* Begin generating SECOND_ROW_CODE */
1942 VdbeModuleComment((pParse->pVdbe, "Begin windowCodeStep.SECOND_ROW_CODE"));
danb33487b2019-03-06 17:12:32 +00001943 if( bCache ){
1944 addrCacheNext = sqlite3VdbeCurrentAddr(v);
dan6c75b392019-03-08 20:02:52 +00001945 if( pMWin->eType!=TK_ROWS ){
1946 windowReadPeerValues(&s, csrWrite, regNewPeer);
1947 }
danb33487b2019-03-06 17:12:32 +00001948 }else{
1949 sqlite3VdbeJumpHere(v, addrIf);
1950 }
dan6c75b392019-03-08 20:02:52 +00001951 if( regPeer ){
1952 addrPeerJump = windowIfNewPeer(pParse, pOrderBy, regNewPeer, regPeer);
1953 }
danb25a2142019-03-05 19:29:36 +00001954 if( pMWin->eStart==TK_FOLLOWING ){
dan6c75b392019-03-08 20:02:52 +00001955 windowCodeOp(&s, WINDOW_AGGSTEP, 0, 0);
dan54975cd2019-03-07 20:47:46 +00001956 if( pMWin->eEnd!=TK_UNBOUNDED ){
dan72b9fdc2019-03-09 20:49:17 +00001957 if( pMWin->eType==TK_RANGE ){
1958 int lbl = sqlite3VdbeMakeLabel(pParse);
1959 int addrNext = sqlite3VdbeCurrentAddr(v);
1960 windowCodeRangeTest(&s, OP_Ge, s.current.csr, regEnd, s.end.csr, lbl);
1961 windowCodeOp(&s, WINDOW_AGGINVERSE, regStart, 0);
1962 windowCodeOp(&s, WINDOW_RETURN_ROW, 0, 0);
1963 sqlite3VdbeAddOp2(v, OP_Goto, 0, addrNext);
1964 sqlite3VdbeResolveLabel(v, lbl);
1965 }else{
1966 windowCodeOp(&s, WINDOW_RETURN_ROW, regEnd, 0);
1967 windowCodeOp(&s, WINDOW_AGGINVERSE, regStart, 0);
1968 }
dan54975cd2019-03-07 20:47:46 +00001969 }
danb25a2142019-03-05 19:29:36 +00001970 }else
1971 if( pMWin->eEnd==TK_PRECEDING ){
dan6c75b392019-03-08 20:02:52 +00001972 windowCodeOp(&s, WINDOW_AGGSTEP, regEnd, 0);
1973 windowCodeOp(&s, WINDOW_RETURN_ROW, 0, 0);
1974 windowCodeOp(&s, WINDOW_AGGINVERSE, regStart, 0);
danb25a2142019-03-05 19:29:36 +00001975 }else{
danc8137502019-03-07 19:26:17 +00001976 int addr;
dan6c75b392019-03-08 20:02:52 +00001977 windowCodeOp(&s, WINDOW_AGGSTEP, 0, 0);
dan54975cd2019-03-07 20:47:46 +00001978 if( pMWin->eEnd!=TK_UNBOUNDED ){
dan72b9fdc2019-03-09 20:49:17 +00001979 if( pMWin->eType==TK_RANGE ){
1980 int lbl;
1981 addr = sqlite3VdbeCurrentAddr(v);
1982 if( regEnd ){
1983 lbl = sqlite3VdbeMakeLabel(pParse);
1984 windowCodeRangeTest(&s, OP_Ge, s.current.csr, regEnd, s.end.csr, lbl);
1985 }
1986 windowCodeOp(&s, WINDOW_RETURN_ROW, 0, 0);
1987 windowCodeOp(&s, WINDOW_AGGINVERSE, regStart, 0);
1988 if( regEnd ){
1989 sqlite3VdbeAddOp2(v, OP_Goto, 0, addr);
1990 sqlite3VdbeResolveLabel(v, lbl);
1991 }
1992 }else{
1993 if( regEnd ) addr = sqlite3VdbeAddOp3(v, OP_IfPos, regEnd, 0, 1);
1994 windowCodeOp(&s, WINDOW_RETURN_ROW, 0, 0);
1995 windowCodeOp(&s, WINDOW_AGGINVERSE, regStart, 0);
1996 if( regEnd ) sqlite3VdbeJumpHere(v, addr);
1997 }
dan54975cd2019-03-07 20:47:46 +00001998 }
danb25a2142019-03-05 19:29:36 +00001999 }
dan6c75b392019-03-08 20:02:52 +00002000 if( addrPeerJump ){
2001 sqlite3VdbeJumpHere(v, addrPeerJump);
2002 }
dan00267b82019-03-06 21:04:11 +00002003 VdbeModuleComment((pParse->pVdbe, "End windowCodeStep.SECOND_ROW_CODE"));
dan680f6e82019-03-04 21:07:11 +00002004
dan680f6e82019-03-04 21:07:11 +00002005 /* End of the main input loop */
danc8137502019-03-07 19:26:17 +00002006 sqlite3VdbeJumpHere(v, addrGoto);
danb33487b2019-03-06 17:12:32 +00002007 if( bCache ){
2008 sqlite3VdbeAddOp2(v, OP_Next, csrWrite, addrCacheNext);
2009 sqlite3VdbeJumpHere(v, addrCacheRewind);
2010 }else{
2011 if( addrShortcut>0 ) sqlite3VdbeJumpHere(v, addrShortcut);
2012 sqlite3WhereEnd(pWInfo);
2013 }
dan680f6e82019-03-04 21:07:11 +00002014
2015 /* Fall through */
danb33487b2019-03-06 17:12:32 +00002016 if( pMWin->pPartition && bCache==0 ){
dan680f6e82019-03-04 21:07:11 +00002017 addrInteger = sqlite3VdbeAddOp2(v, OP_Integer, 0, regFlushPart);
2018 sqlite3VdbeJumpHere(v, addrGosubFlush);
2019 }
2020
danc8137502019-03-07 19:26:17 +00002021 VdbeModuleComment((pParse->pVdbe, "Begin windowCodeStep.FLUSH_CODE"));
2022 addrEmpty = sqlite3VdbeAddOp1(v, OP_Rewind, csrWrite);
dan00267b82019-03-06 21:04:11 +00002023 if( pMWin->eEnd==TK_PRECEDING ){
dan6c75b392019-03-08 20:02:52 +00002024 windowCodeOp(&s, WINDOW_AGGSTEP, regEnd, 0);
2025 windowCodeOp(&s, WINDOW_RETURN_ROW, 0, 0);
danc8137502019-03-07 19:26:17 +00002026 }else if( pMWin->eStart==TK_FOLLOWING ){
2027 int addrStart;
2028 int addrBreak1;
2029 int addrBreak2;
2030 int addrBreak3;
dan6c75b392019-03-08 20:02:52 +00002031 windowCodeOp(&s, WINDOW_AGGSTEP, 0, 0);
dan72b9fdc2019-03-09 20:49:17 +00002032 if( pMWin->eType==TK_RANGE ){
2033 addrStart = sqlite3VdbeCurrentAddr(v);
2034 addrBreak2 = windowCodeOp(&s, WINDOW_AGGINVERSE, regStart, 1);
2035 addrBreak1 = windowCodeOp(&s, WINDOW_RETURN_ROW, 0, 1);
2036 }else
dan54975cd2019-03-07 20:47:46 +00002037 if( pMWin->eEnd==TK_UNBOUNDED ){
2038 addrStart = sqlite3VdbeCurrentAddr(v);
dan6c75b392019-03-08 20:02:52 +00002039 addrBreak1 = windowCodeOp(&s, WINDOW_RETURN_ROW, regStart, 1);
2040 addrBreak2 = windowCodeOp(&s, WINDOW_AGGINVERSE, 0, 1);
dan54975cd2019-03-07 20:47:46 +00002041 }else{
2042 assert( pMWin->eEnd==TK_FOLLOWING );
2043 addrStart = sqlite3VdbeCurrentAddr(v);
dan6c75b392019-03-08 20:02:52 +00002044 addrBreak1 = windowCodeOp(&s, WINDOW_RETURN_ROW, regEnd, 1);
2045 addrBreak2 = windowCodeOp(&s, WINDOW_AGGINVERSE, regStart, 1);
dan54975cd2019-03-07 20:47:46 +00002046 }
danc8137502019-03-07 19:26:17 +00002047 sqlite3VdbeAddOp2(v, OP_Goto, 0, addrStart);
2048 sqlite3VdbeJumpHere(v, addrBreak2);
2049 addrStart = sqlite3VdbeCurrentAddr(v);
dan6c75b392019-03-08 20:02:52 +00002050 addrBreak3 = windowCodeOp(&s, WINDOW_RETURN_ROW, 0, 1);
danc8137502019-03-07 19:26:17 +00002051 sqlite3VdbeAddOp2(v, OP_Goto, 0, addrStart);
2052 sqlite3VdbeJumpHere(v, addrBreak1);
2053 sqlite3VdbeJumpHere(v, addrBreak3);
danb25a2142019-03-05 19:29:36 +00002054 }else{
dan00267b82019-03-06 21:04:11 +00002055 int addrBreak;
danc8137502019-03-07 19:26:17 +00002056 int addrStart;
dan6c75b392019-03-08 20:02:52 +00002057 windowCodeOp(&s, WINDOW_AGGSTEP, 0, 0);
danc8137502019-03-07 19:26:17 +00002058 addrStart = sqlite3VdbeCurrentAddr(v);
dan6c75b392019-03-08 20:02:52 +00002059 addrBreak = windowCodeOp(&s, WINDOW_RETURN_ROW, 0, 1);
2060 windowCodeOp(&s, WINDOW_AGGINVERSE, regStart, 0);
dan00267b82019-03-06 21:04:11 +00002061 sqlite3VdbeAddOp2(v, OP_Goto, 0, addrStart);
2062 sqlite3VdbeJumpHere(v, addrBreak);
danb25a2142019-03-05 19:29:36 +00002063 }
2064
danc8137502019-03-07 19:26:17 +00002065 sqlite3VdbeJumpHere(v, addrEmpty);
2066
danb33487b2019-03-06 17:12:32 +00002067 if( bCache && addrShortcut>0 ) sqlite3VdbeJumpHere(v, addrShortcut);
dan6c75b392019-03-08 20:02:52 +00002068 sqlite3VdbeAddOp1(v, OP_ResetSorter, s.current.csr);
danb33487b2019-03-06 17:12:32 +00002069 sqlite3VdbeAddOp2(v, OP_Integer, 0, pMWin->regSize);
2070 if( bCache==0 ) sqlite3VdbeAddOp2(v, OP_Integer, 1, pMWin->regFirst);
dan00267b82019-03-06 21:04:11 +00002071 VdbeModuleComment((pParse->pVdbe, "End windowCodeStep.FLUSH_CODE"));
dan680f6e82019-03-04 21:07:11 +00002072 if( pMWin->pPartition ){
2073 sqlite3VdbeChangeP1(v, addrInteger, sqlite3VdbeCurrentAddr(v));
2074 sqlite3VdbeAddOp1(v, OP_Return, regFlushPart);
2075 }
2076}
2077
danc3a20c12018-05-23 20:55:37 +00002078
dan13078ca2018-06-13 20:29:38 +00002079/*
2080** Allocate and return a duplicate of the Window object indicated by the
2081** third argument. Set the Window.pOwner field of the new object to
2082** pOwner.
2083*/
dan2a11bb22018-06-11 20:50:25 +00002084Window *sqlite3WindowDup(sqlite3 *db, Expr *pOwner, Window *p){
dandacf1de2018-06-08 16:11:55 +00002085 Window *pNew = 0;
drheda079c2018-09-20 19:02:15 +00002086 if( ALWAYS(p) ){
dandacf1de2018-06-08 16:11:55 +00002087 pNew = sqlite3DbMallocZero(db, sizeof(Window));
2088 if( pNew ){
danc95f38d2018-06-18 20:34:43 +00002089 pNew->zName = sqlite3DbStrDup(db, p->zName);
dandacf1de2018-06-08 16:11:55 +00002090 pNew->pFilter = sqlite3ExprDup(db, p->pFilter, 0);
drha8389972018-12-06 22:04:19 +00002091 pNew->pFunc = p->pFunc;
dandacf1de2018-06-08 16:11:55 +00002092 pNew->pPartition = sqlite3ExprListDup(db, p->pPartition, 0);
2093 pNew->pOrderBy = sqlite3ExprListDup(db, p->pOrderBy, 0);
2094 pNew->eType = p->eType;
2095 pNew->eEnd = p->eEnd;
2096 pNew->eStart = p->eStart;
dan303451a2018-06-14 20:52:08 +00002097 pNew->pStart = sqlite3ExprDup(db, p->pStart, 0);
2098 pNew->pEnd = sqlite3ExprDup(db, p->pEnd, 0);
dan2a11bb22018-06-11 20:50:25 +00002099 pNew->pOwner = pOwner;
dandacf1de2018-06-08 16:11:55 +00002100 }
2101 }
2102 return pNew;
2103}
danc3a20c12018-05-23 20:55:37 +00002104
danf9eae182018-05-21 19:45:11 +00002105/*
danc95f38d2018-06-18 20:34:43 +00002106** Return a copy of the linked list of Window objects passed as the
2107** second argument.
2108*/
2109Window *sqlite3WindowListDup(sqlite3 *db, Window *p){
2110 Window *pWin;
2111 Window *pRet = 0;
2112 Window **pp = &pRet;
2113
2114 for(pWin=p; pWin; pWin=pWin->pNextWin){
2115 *pp = sqlite3WindowDup(db, 0, pWin);
2116 if( *pp==0 ) break;
2117 pp = &((*pp)->pNextWin);
2118 }
2119
2120 return pRet;
2121}
2122
2123/*
dan2a11bb22018-06-11 20:50:25 +00002124** sqlite3WhereBegin() has already been called for the SELECT statement
2125** passed as the second argument when this function is invoked. It generates
2126** code to populate the Window.regResult register for each window function and
2127** invoke the sub-routine at instruction addrGosub once for each row.
2128** This function calls sqlite3WhereEnd() before returning.
danf9eae182018-05-21 19:45:11 +00002129*/
2130void sqlite3WindowCodeStep(
dan2a11bb22018-06-11 20:50:25 +00002131 Parse *pParse, /* Parse context */
2132 Select *p, /* Rewritten SELECT statement */
2133 WhereInfo *pWInfo, /* Context returned by sqlite3WhereBegin() */
2134 int regGosub, /* Register for OP_Gosub */
2135 int addrGosub /* OP_Gosub here to return each row */
danf9eae182018-05-21 19:45:11 +00002136){
dan6c75b392019-03-08 20:02:52 +00002137 VdbeModuleComment((pParse->pVdbe, "Begin windowCodeStep()"));
2138 windowCodeStep(pParse, p, pWInfo, regGosub, addrGosub);
2139 VdbeModuleComment((pParse->pVdbe, "End windowCodeStep()"));
danf9eae182018-05-21 19:45:11 +00002140}
2141
dan67a9b8e2018-06-22 20:51:35 +00002142#endif /* SQLITE_OMIT_WINDOWFUNC */