xref: /sqlite-3.40.0/src/window.c (revision 3b01dd0f)
186fb6e17Sdan /*
226522d1cSdan ** 2018 May 08
386fb6e17Sdan **
486fb6e17Sdan ** The author disclaims copyright to this source code.  In place of
586fb6e17Sdan ** a legal notice, here is a blessing:
686fb6e17Sdan **
786fb6e17Sdan **    May you do good and not evil.
886fb6e17Sdan **    May you find forgiveness for yourself and forgive others.
986fb6e17Sdan **    May you share freely, never taking more than you give.
1086fb6e17Sdan **
1186fb6e17Sdan *************************************************************************
1286fb6e17Sdan */
1386fb6e17Sdan #include "sqliteInt.h"
1486fb6e17Sdan 
1567a9b8edSdan #ifndef SQLITE_OMIT_WINDOWFUNC
1667a9b8edSdan 
17dfa552f4Sdan /*
187392569fSdan ** SELECT REWRITING
197392569fSdan **
207392569fSdan **   Any SELECT statement that contains one or more window functions in
217392569fSdan **   either the select list or ORDER BY clause (the only two places window
227392569fSdan **   functions may be used) is transformed by function sqlite3WindowRewrite()
237392569fSdan **   in order to support window function processing. For example, with the
247392569fSdan **   schema:
257392569fSdan **
267392569fSdan **     CREATE TABLE t1(a, b, c, d, e, f, g);
277392569fSdan **
287392569fSdan **   the statement:
297392569fSdan **
307392569fSdan **     SELECT a+1, max(b) OVER (PARTITION BY c ORDER BY d) FROM t1 ORDER BY e;
317392569fSdan **
327392569fSdan **   is transformed to:
337392569fSdan **
347392569fSdan **     SELECT a+1, max(b) OVER (PARTITION BY c ORDER BY d) FROM (
357392569fSdan **         SELECT a, e, c, d, b FROM t1 ORDER BY c, d
367392569fSdan **     ) ORDER BY e;
377392569fSdan **
387392569fSdan **   The flattening optimization is disabled when processing this transformed
397392569fSdan **   SELECT statement. This allows the implementation of the window function
407392569fSdan **   (in this case max()) to process rows sorted in order of (c, d), which
417392569fSdan **   makes things easier for obvious reasons. More generally:
427392569fSdan **
437392569fSdan **     * FROM, WHERE, GROUP BY and HAVING clauses are all moved to
447392569fSdan **       the sub-query.
457392569fSdan **
467392569fSdan **     * ORDER BY, LIMIT and OFFSET remain part of the parent query.
477392569fSdan **
487392569fSdan **     * Terminals from each of the expression trees that make up the
497392569fSdan **       select-list and ORDER BY expressions in the parent query are
507392569fSdan **       selected by the sub-query. For the purposes of the transformation,
517392569fSdan **       terminals are column references and aggregate functions.
527392569fSdan **
537392569fSdan **   If there is more than one window function in the SELECT that uses
547392569fSdan **   the same window declaration (the OVER bit), then a single scan may
557392569fSdan **   be used to process more than one window function. For example:
567392569fSdan **
577392569fSdan **     SELECT max(b) OVER (PARTITION BY c ORDER BY d),
587392569fSdan **            min(e) OVER (PARTITION BY c ORDER BY d)
597392569fSdan **     FROM t1;
607392569fSdan **
617392569fSdan **   is transformed in the same way as the example above. However:
627392569fSdan **
637392569fSdan **     SELECT max(b) OVER (PARTITION BY c ORDER BY d),
647392569fSdan **            min(e) OVER (PARTITION BY a ORDER BY b)
657392569fSdan **     FROM t1;
667392569fSdan **
677392569fSdan **   Must be transformed to:
687392569fSdan **
697392569fSdan **     SELECT max(b) OVER (PARTITION BY c ORDER BY d) FROM (
707392569fSdan **         SELECT e, min(e) OVER (PARTITION BY a ORDER BY b), c, d, b FROM
717392569fSdan **           SELECT a, e, c, d, b FROM t1 ORDER BY a, b
727392569fSdan **         ) ORDER BY c, d
737392569fSdan **     ) ORDER BY e;
747392569fSdan **
757392569fSdan **   so that both min() and max() may process rows in the order defined by
767392569fSdan **   their respective window declarations.
777392569fSdan **
787392569fSdan ** INTERFACE WITH SELECT.C
797392569fSdan **
807392569fSdan **   When processing the rewritten SELECT statement, code in select.c calls
817392569fSdan **   sqlite3WhereBegin() to begin iterating through the results of the
827392569fSdan **   sub-query, which is always implemented as a co-routine. It then calls
837392569fSdan **   sqlite3WindowCodeStep() to process rows and finish the scan by calling
847392569fSdan **   sqlite3WhereEnd().
857392569fSdan **
867392569fSdan **   sqlite3WindowCodeStep() generates VM code so that, for each row returned
877392569fSdan **   by the sub-query a sub-routine (OP_Gosub) coded by select.c is invoked.
887392569fSdan **   When the sub-routine is invoked:
897392569fSdan **
907392569fSdan **     * The results of all window-functions for the row are stored
917392569fSdan **       in the associated Window.regResult registers.
927392569fSdan **
937392569fSdan **     * The required terminal values are stored in the current row of
947392569fSdan **       temp table Window.iEphCsr.
957392569fSdan **
967392569fSdan **   In some cases, depending on the window frame and the specific window
977392569fSdan **   functions invoked, sqlite3WindowCodeStep() caches each entire partition
987392569fSdan **   in a temp table before returning any rows. In other cases it does not.
997392569fSdan **   This detail is encapsulated within this file, the code generated by
1007392569fSdan **   select.c is the same in either case.
1017392569fSdan **
1027392569fSdan ** BUILT-IN WINDOW FUNCTIONS
1037392569fSdan **
1047392569fSdan **   This implementation features the following built-in window functions:
1057392569fSdan **
1067392569fSdan **     row_number()
1077392569fSdan **     rank()
1087392569fSdan **     dense_rank()
1097392569fSdan **     percent_rank()
1107392569fSdan **     cume_dist()
1117392569fSdan **     ntile(N)
1127392569fSdan **     lead(expr [, offset [, default]])
1137392569fSdan **     lag(expr [, offset [, default]])
1147392569fSdan **     first_value(expr)
1157392569fSdan **     last_value(expr)
1167392569fSdan **     nth_value(expr, N)
1177392569fSdan **
1187392569fSdan **   These are the same built-in window functions supported by Postgres.
1197392569fSdan **   Although the behaviour of aggregate window functions (functions that
1207392569fSdan **   can be used as either aggregates or window funtions) allows them to
1217392569fSdan **   be implemented using an API, built-in window functions are much more
1227392569fSdan **   esoteric. Additionally, some window functions (e.g. nth_value())
1237392569fSdan **   may only be implemented by caching the entire partition in memory.
1247392569fSdan **   As such, some built-in window functions use the same API as aggregate
1257392569fSdan **   window functions and some are implemented directly using VDBE
1267392569fSdan **   instructions. Additionally, for those functions that use the API, the
1277392569fSdan **   window frame is sometimes modified before the SELECT statement is
1287392569fSdan **   rewritten. For example, regardless of the specified window frame, the
1297392569fSdan **   row_number() function always uses:
1307392569fSdan **
1317392569fSdan **     ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
1327392569fSdan **
1337392569fSdan **   See sqlite3WindowUpdate() for details.
134c0bb4459Sdan **
135c0bb4459Sdan **   As well as some of the built-in window functions, aggregate window
136c0bb4459Sdan **   functions min() and max() are implemented using VDBE instructions if
137c0bb4459Sdan **   the start of the window frame is declared as anything other than
138c0bb4459Sdan **   UNBOUNDED PRECEDING.
1397392569fSdan */
1407392569fSdan 
1417392569fSdan /*
142dfa552f4Sdan ** Implementation of built-in window function row_number(). Assumes that the
143dfa552f4Sdan ** window frame has been coerced to:
144dfa552f4Sdan **
145dfa552f4Sdan **   ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
146dfa552f4Sdan */
row_numberStepFunc(sqlite3_context * pCtx,int nArg,sqlite3_value ** apArg)147dfa552f4Sdan static void row_numberStepFunc(
148dfa552f4Sdan   sqlite3_context *pCtx,
149dfa552f4Sdan   int nArg,
150dfa552f4Sdan   sqlite3_value **apArg
151dfa552f4Sdan ){
152dfa552f4Sdan   i64 *p = (i64*)sqlite3_aggregate_context(pCtx, sizeof(*p));
1535d6374faSdrh   if( p ) (*p)++;
154c7bf5716Sdrh   UNUSED_PARAMETER(nArg);
155c7bf5716Sdrh   UNUSED_PARAMETER(apArg);
156dfa552f4Sdan }
row_numberValueFunc(sqlite3_context * pCtx)157dfa552f4Sdan static void row_numberValueFunc(sqlite3_context *pCtx){
158dfa552f4Sdan   i64 *p = (i64*)sqlite3_aggregate_context(pCtx, sizeof(*p));
159dfa552f4Sdan   sqlite3_result_int64(pCtx, (p ? *p : 0));
160dfa552f4Sdan }
161dfa552f4Sdan 
162dfa552f4Sdan /*
1632a11bb23Sdan ** Context object type used by rank(), dense_rank(), percent_rank() and
1642a11bb23Sdan ** cume_dist().
165dfa552f4Sdan */
166dfa552f4Sdan struct CallCount {
167dfa552f4Sdan   i64 nValue;
168dfa552f4Sdan   i64 nStep;
169dfa552f4Sdan   i64 nTotal;
170dfa552f4Sdan };
171dfa552f4Sdan 
172dfa552f4Sdan /*
1739c27758eSdan ** Implementation of built-in window function dense_rank(). Assumes that
1749c27758eSdan ** the window frame has been set to:
1759c27758eSdan **
1769c27758eSdan **   RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
177dfa552f4Sdan */
dense_rankStepFunc(sqlite3_context * pCtx,int nArg,sqlite3_value ** apArg)178dfa552f4Sdan static void dense_rankStepFunc(
179dfa552f4Sdan   sqlite3_context *pCtx,
180dfa552f4Sdan   int nArg,
181dfa552f4Sdan   sqlite3_value **apArg
182dfa552f4Sdan ){
183dfa552f4Sdan   struct CallCount *p;
184dfa552f4Sdan   p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p));
1855d6374faSdrh   if( p ) p->nStep = 1;
186c7bf5716Sdrh   UNUSED_PARAMETER(nArg);
187c7bf5716Sdrh   UNUSED_PARAMETER(apArg);
188dfa552f4Sdan }
dense_rankValueFunc(sqlite3_context * pCtx)189dfa552f4Sdan static void dense_rankValueFunc(sqlite3_context *pCtx){
190dfa552f4Sdan   struct CallCount *p;
191dfa552f4Sdan   p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p));
192dfa552f4Sdan   if( p ){
193dfa552f4Sdan     if( p->nStep ){
194dfa552f4Sdan       p->nValue++;
195dfa552f4Sdan       p->nStep = 0;
196dfa552f4Sdan     }
197dfa552f4Sdan     sqlite3_result_int64(pCtx, p->nValue);
198dfa552f4Sdan   }
199dfa552f4Sdan }
200dfa552f4Sdan 
201dfa552f4Sdan /*
202a0f6b833Sdan ** Implementation of built-in window function nth_value(). This
203a0f6b833Sdan ** implementation is used in "slow mode" only - when the EXCLUDE clause
204a0f6b833Sdan ** is not set to the default value "NO OTHERS".
205a0f6b833Sdan */
206a0f6b833Sdan struct NthValueCtx {
207a0f6b833Sdan   i64 nStep;
208a0f6b833Sdan   sqlite3_value *pValue;
209a0f6b833Sdan };
nth_valueStepFunc(sqlite3_context * pCtx,int nArg,sqlite3_value ** apArg)210a0f6b833Sdan static void nth_valueStepFunc(
211a0f6b833Sdan   sqlite3_context *pCtx,
212a0f6b833Sdan   int nArg,
213a0f6b833Sdan   sqlite3_value **apArg
214a0f6b833Sdan ){
215a0f6b833Sdan   struct NthValueCtx *p;
216a0f6b833Sdan   p = (struct NthValueCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p));
217a0f6b833Sdan   if( p ){
218108e6b2cSdan     i64 iVal;
219108e6b2cSdan     switch( sqlite3_value_numeric_type(apArg[1]) ){
220108e6b2cSdan       case SQLITE_INTEGER:
221108e6b2cSdan         iVal = sqlite3_value_int64(apArg[1]);
222108e6b2cSdan         break;
223108e6b2cSdan       case SQLITE_FLOAT: {
224108e6b2cSdan         double fVal = sqlite3_value_double(apArg[1]);
225108e6b2cSdan         if( ((i64)fVal)!=fVal ) goto error_out;
226108e6b2cSdan         iVal = (i64)fVal;
227108e6b2cSdan         break;
228108e6b2cSdan       }
229108e6b2cSdan       default:
230108e6b2cSdan         goto error_out;
231108e6b2cSdan     }
232108e6b2cSdan     if( iVal<=0 ) goto error_out;
233108e6b2cSdan 
234a0f6b833Sdan     p->nStep++;
235a0f6b833Sdan     if( iVal==p->nStep ){
236a0f6b833Sdan       p->pValue = sqlite3_value_dup(apArg[0]);
237108e6b2cSdan       if( !p->pValue ){
238108e6b2cSdan         sqlite3_result_error_nomem(pCtx);
239108e6b2cSdan       }
240a0f6b833Sdan     }
241a0f6b833Sdan   }
242a0f6b833Sdan   UNUSED_PARAMETER(nArg);
243a0f6b833Sdan   UNUSED_PARAMETER(apArg);
244108e6b2cSdan   return;
245108e6b2cSdan 
246108e6b2cSdan  error_out:
247108e6b2cSdan   sqlite3_result_error(
248108e6b2cSdan       pCtx, "second argument to nth_value must be a positive integer", -1
249108e6b2cSdan   );
250a0f6b833Sdan }
nth_valueFinalizeFunc(sqlite3_context * pCtx)251a0f6b833Sdan static void nth_valueFinalizeFunc(sqlite3_context *pCtx){
252a0f6b833Sdan   struct NthValueCtx *p;
2530525b6f4Sdan   p = (struct NthValueCtx*)sqlite3_aggregate_context(pCtx, 0);
254a0f6b833Sdan   if( p && p->pValue ){
255a0f6b833Sdan     sqlite3_result_value(pCtx, p->pValue);
256a0f6b833Sdan     sqlite3_value_free(p->pValue);
257a0f6b833Sdan     p->pValue = 0;
258a0f6b833Sdan   }
259a0f6b833Sdan }
260a0f6b833Sdan #define nth_valueInvFunc noopStepFunc
2610525b6f4Sdan #define nth_valueValueFunc noopValueFunc
262a0f6b833Sdan 
first_valueStepFunc(sqlite3_context * pCtx,int nArg,sqlite3_value ** apArg)263c782a81aSdan static void first_valueStepFunc(
264c782a81aSdan   sqlite3_context *pCtx,
265c782a81aSdan   int nArg,
266c782a81aSdan   sqlite3_value **apArg
267c782a81aSdan ){
268c782a81aSdan   struct NthValueCtx *p;
269c782a81aSdan   p = (struct NthValueCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p));
270c782a81aSdan   if( p && p->pValue==0 ){
271c782a81aSdan     p->pValue = sqlite3_value_dup(apArg[0]);
272108e6b2cSdan     if( !p->pValue ){
273108e6b2cSdan       sqlite3_result_error_nomem(pCtx);
274108e6b2cSdan     }
275c782a81aSdan   }
276c782a81aSdan   UNUSED_PARAMETER(nArg);
277c782a81aSdan   UNUSED_PARAMETER(apArg);
278c782a81aSdan }
first_valueFinalizeFunc(sqlite3_context * pCtx)279c782a81aSdan static void first_valueFinalizeFunc(sqlite3_context *pCtx){
280c782a81aSdan   struct NthValueCtx *p;
281c782a81aSdan   p = (struct NthValueCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p));
282c782a81aSdan   if( p && p->pValue ){
283c782a81aSdan     sqlite3_result_value(pCtx, p->pValue);
284c782a81aSdan     sqlite3_value_free(p->pValue);
285c782a81aSdan     p->pValue = 0;
286c782a81aSdan   }
287c782a81aSdan }
288c782a81aSdan #define first_valueInvFunc noopStepFunc
2890525b6f4Sdan #define first_valueValueFunc noopValueFunc
290c782a81aSdan 
291a0f6b833Sdan /*
2929c27758eSdan ** Implementation of built-in window function rank(). Assumes that
2939c27758eSdan ** the window frame has been set to:
2949c27758eSdan **
2959c27758eSdan **   RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
296dfa552f4Sdan */
rankStepFunc(sqlite3_context * pCtx,int nArg,sqlite3_value ** apArg)297dfa552f4Sdan static void rankStepFunc(
298dfa552f4Sdan   sqlite3_context *pCtx,
299dfa552f4Sdan   int nArg,
300dfa552f4Sdan   sqlite3_value **apArg
301dfa552f4Sdan ){
302dfa552f4Sdan   struct CallCount *p;
303dfa552f4Sdan   p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p));
3045d6374faSdrh   if( p ){
305dfa552f4Sdan     p->nStep++;
306dfa552f4Sdan     if( p->nValue==0 ){
307dfa552f4Sdan       p->nValue = p->nStep;
308dfa552f4Sdan     }
309dfa552f4Sdan   }
310c7bf5716Sdrh   UNUSED_PARAMETER(nArg);
311c7bf5716Sdrh   UNUSED_PARAMETER(apArg);
312dfa552f4Sdan }
rankValueFunc(sqlite3_context * pCtx)313dfa552f4Sdan static void rankValueFunc(sqlite3_context *pCtx){
314dfa552f4Sdan   struct CallCount *p;
315dfa552f4Sdan   p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p));
316dfa552f4Sdan   if( p ){
317dfa552f4Sdan     sqlite3_result_int64(pCtx, p->nValue);
318dfa552f4Sdan     p->nValue = 0;
319dfa552f4Sdan   }
320dfa552f4Sdan }
321dfa552f4Sdan 
322dfa552f4Sdan /*
3239c27758eSdan ** Implementation of built-in window function percent_rank(). Assumes that
3249c27758eSdan ** the window frame has been set to:
3259c27758eSdan **
326cc7a850fSdan **   GROUPS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING
327dfa552f4Sdan */
percent_rankStepFunc(sqlite3_context * pCtx,int nArg,sqlite3_value ** apArg)328dfa552f4Sdan static void percent_rankStepFunc(
329dfa552f4Sdan   sqlite3_context *pCtx,
330dfa552f4Sdan   int nArg,
331dfa552f4Sdan   sqlite3_value **apArg
332dfa552f4Sdan ){
333dfa552f4Sdan   struct CallCount *p;
334cc7a850fSdan   UNUSED_PARAMETER(nArg); assert( nArg==0 );
335d4a591ddSdrh   UNUSED_PARAMETER(apArg);
336dfa552f4Sdan   p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p));
3375d6374faSdrh   if( p ){
338cc7a850fSdan     p->nTotal++;
339dfa552f4Sdan   }
340cc7a850fSdan }
percent_rankInvFunc(sqlite3_context * pCtx,int nArg,sqlite3_value ** apArg)341cc7a850fSdan static void percent_rankInvFunc(
342cc7a850fSdan   sqlite3_context *pCtx,
343cc7a850fSdan   int nArg,
344cc7a850fSdan   sqlite3_value **apArg
345cc7a850fSdan ){
346cc7a850fSdan   struct CallCount *p;
347cc7a850fSdan   UNUSED_PARAMETER(nArg); assert( nArg==0 );
348d4a591ddSdrh   UNUSED_PARAMETER(apArg);
349cc7a850fSdan   p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p));
350dfa552f4Sdan   p->nStep++;
351dfa552f4Sdan }
percent_rankValueFunc(sqlite3_context * pCtx)352dfa552f4Sdan static void percent_rankValueFunc(sqlite3_context *pCtx){
353dfa552f4Sdan   struct CallCount *p;
354dfa552f4Sdan   p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p));
355dfa552f4Sdan   if( p ){
356cc7a850fSdan     p->nValue = p->nStep;
357dfa552f4Sdan     if( p->nTotal>1 ){
358cc7a850fSdan       double r = (double)p->nValue / (double)(p->nTotal-1);
359dfa552f4Sdan       sqlite3_result_double(pCtx, r);
360dfa552f4Sdan     }else{
361b7306f6fSdan       sqlite3_result_double(pCtx, 0.0);
362dfa552f4Sdan     }
363dfa552f4Sdan   }
364dfa552f4Sdan }
365cc7a850fSdan #define percent_rankFinalizeFunc percent_rankValueFunc
366dfa552f4Sdan 
3679c27758eSdan /*
3689c27758eSdan ** Implementation of built-in window function cume_dist(). Assumes that
3699c27758eSdan ** the window frame has been set to:
3709c27758eSdan **
371cc7a850fSdan **   GROUPS BETWEEN 1 FOLLOWING AND UNBOUNDED FOLLOWING
3729c27758eSdan */
cume_distStepFunc(sqlite3_context * pCtx,int nArg,sqlite3_value ** apArg)373f1abe368Sdan static void cume_distStepFunc(
374f1abe368Sdan   sqlite3_context *pCtx,
375f1abe368Sdan   int nArg,
376f1abe368Sdan   sqlite3_value **apArg
377f1abe368Sdan ){
378f1abe368Sdan   struct CallCount *p;
379cc7a850fSdan   UNUSED_PARAMETER(nArg); assert( nArg==0 );
380d4a591ddSdrh   UNUSED_PARAMETER(apArg);
381f1abe368Sdan   p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p));
3825d6374faSdrh   if( p ){
383cc7a850fSdan     p->nTotal++;
384f1abe368Sdan   }
385cc7a850fSdan }
cume_distInvFunc(sqlite3_context * pCtx,int nArg,sqlite3_value ** apArg)386cc7a850fSdan static void cume_distInvFunc(
387cc7a850fSdan   sqlite3_context *pCtx,
388cc7a850fSdan   int nArg,
389cc7a850fSdan   sqlite3_value **apArg
390cc7a850fSdan ){
391cc7a850fSdan   struct CallCount *p;
392cc7a850fSdan   UNUSED_PARAMETER(nArg); assert( nArg==0 );
393d4a591ddSdrh   UNUSED_PARAMETER(apArg);
394cc7a850fSdan   p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p));
395f1abe368Sdan   p->nStep++;
396f1abe368Sdan }
cume_distValueFunc(sqlite3_context * pCtx)397f1abe368Sdan static void cume_distValueFunc(sqlite3_context *pCtx){
398f1abe368Sdan   struct CallCount *p;
3990525b6f4Sdan   p = (struct CallCount*)sqlite3_aggregate_context(pCtx, 0);
4000525b6f4Sdan   if( p ){
401f1abe368Sdan     double r = (double)(p->nStep) / (double)(p->nTotal);
402f1abe368Sdan     sqlite3_result_double(pCtx, r);
403f1abe368Sdan   }
404f1abe368Sdan }
405cc7a850fSdan #define cume_distFinalizeFunc cume_distValueFunc
406f1abe368Sdan 
4072a11bb23Sdan /*
4082a11bb23Sdan ** Context object for ntile() window function.
4092a11bb23Sdan */
4106bc5c9e7Sdan struct NtileCtx {
4116bc5c9e7Sdan   i64 nTotal;                     /* Total rows in partition */
4126bc5c9e7Sdan   i64 nParam;                     /* Parameter passed to ntile(N) */
4136bc5c9e7Sdan   i64 iRow;                       /* Current row */
4146bc5c9e7Sdan };
4156bc5c9e7Sdan 
4166bc5c9e7Sdan /*
4176bc5c9e7Sdan ** Implementation of ntile(). This assumes that the window frame has
4186bc5c9e7Sdan ** been coerced to:
4196bc5c9e7Sdan **
420cc7a850fSdan **   ROWS CURRENT ROW AND UNBOUNDED FOLLOWING
4216bc5c9e7Sdan */
ntileStepFunc(sqlite3_context * pCtx,int nArg,sqlite3_value ** apArg)4226bc5c9e7Sdan static void ntileStepFunc(
4236bc5c9e7Sdan   sqlite3_context *pCtx,
4246bc5c9e7Sdan   int nArg,
4256bc5c9e7Sdan   sqlite3_value **apArg
4266bc5c9e7Sdan ){
4276bc5c9e7Sdan   struct NtileCtx *p;
428cc7a850fSdan   assert( nArg==1 ); UNUSED_PARAMETER(nArg);
4296bc5c9e7Sdan   p = (struct NtileCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p));
4305d6374faSdrh   if( p ){
4316bc5c9e7Sdan     if( p->nTotal==0 ){
4326bc5c9e7Sdan       p->nParam = sqlite3_value_int64(apArg[0]);
4336bc5c9e7Sdan       if( p->nParam<=0 ){
4346bc5c9e7Sdan         sqlite3_result_error(
4356bc5c9e7Sdan             pCtx, "argument of ntile must be a positive integer", -1
4366bc5c9e7Sdan         );
4376bc5c9e7Sdan       }
4386bc5c9e7Sdan     }
439cc7a850fSdan     p->nTotal++;
4406bc5c9e7Sdan   }
4416bc5c9e7Sdan }
ntileInvFunc(sqlite3_context * pCtx,int nArg,sqlite3_value ** apArg)442cc7a850fSdan static void ntileInvFunc(
443cc7a850fSdan   sqlite3_context *pCtx,
444cc7a850fSdan   int nArg,
445cc7a850fSdan   sqlite3_value **apArg
446cc7a850fSdan ){
447cc7a850fSdan   struct NtileCtx *p;
448cc7a850fSdan   assert( nArg==1 ); UNUSED_PARAMETER(nArg);
449d4a591ddSdrh   UNUSED_PARAMETER(apArg);
450cc7a850fSdan   p = (struct NtileCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p));
451cc7a850fSdan   p->iRow++;
452cc7a850fSdan }
ntileValueFunc(sqlite3_context * pCtx)4536bc5c9e7Sdan static void ntileValueFunc(sqlite3_context *pCtx){
4546bc5c9e7Sdan   struct NtileCtx *p;
4556bc5c9e7Sdan   p = (struct NtileCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p));
4566bc5c9e7Sdan   if( p && p->nParam>0 ){
4576bc5c9e7Sdan     int nSize = (p->nTotal / p->nParam);
4586bc5c9e7Sdan     if( nSize==0 ){
459cc7a850fSdan       sqlite3_result_int64(pCtx, p->iRow+1);
4606bc5c9e7Sdan     }else{
4616bc5c9e7Sdan       i64 nLarge = p->nTotal - p->nParam*nSize;
4626bc5c9e7Sdan       i64 iSmall = nLarge*(nSize+1);
463cc7a850fSdan       i64 iRow = p->iRow;
4646bc5c9e7Sdan 
4656bc5c9e7Sdan       assert( (nLarge*(nSize+1) + (p->nParam-nLarge)*nSize)==p->nTotal );
4666bc5c9e7Sdan 
4676bc5c9e7Sdan       if( iRow<iSmall ){
4686bc5c9e7Sdan         sqlite3_result_int64(pCtx, 1 + iRow/(nSize+1));
4696bc5c9e7Sdan       }else{
4706bc5c9e7Sdan         sqlite3_result_int64(pCtx, 1 + nLarge + (iRow-iSmall)/nSize);
4716bc5c9e7Sdan       }
4726bc5c9e7Sdan     }
4736bc5c9e7Sdan   }
4746bc5c9e7Sdan }
475cc7a850fSdan #define ntileFinalizeFunc ntileValueFunc
4766bc5c9e7Sdan 
4772a11bb23Sdan /*
4782a11bb23Sdan ** Context object for last_value() window function.
4792a11bb23Sdan */
4801c5ed624Sdan struct LastValueCtx {
4811c5ed624Sdan   sqlite3_value *pVal;
4821c5ed624Sdan   int nVal;
4831c5ed624Sdan };
4841c5ed624Sdan 
4851c5ed624Sdan /*
4861c5ed624Sdan ** Implementation of last_value().
4871c5ed624Sdan */
last_valueStepFunc(sqlite3_context * pCtx,int nArg,sqlite3_value ** apArg)4881c5ed624Sdan static void last_valueStepFunc(
4891c5ed624Sdan   sqlite3_context *pCtx,
4901c5ed624Sdan   int nArg,
4911c5ed624Sdan   sqlite3_value **apArg
4921c5ed624Sdan ){
4931c5ed624Sdan   struct LastValueCtx *p;
494c7bf5716Sdrh   UNUSED_PARAMETER(nArg);
4951c5ed624Sdan   p = (struct LastValueCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p));
4961c5ed624Sdan   if( p ){
4971c5ed624Sdan     sqlite3_value_free(p->pVal);
4981c5ed624Sdan     p->pVal = sqlite3_value_dup(apArg[0]);
4996fde1799Sdan     if( p->pVal==0 ){
5006fde1799Sdan       sqlite3_result_error_nomem(pCtx);
5016fde1799Sdan     }else{
5021c5ed624Sdan       p->nVal++;
5031c5ed624Sdan     }
5041c5ed624Sdan   }
5056fde1799Sdan }
last_valueInvFunc(sqlite3_context * pCtx,int nArg,sqlite3_value ** apArg)5062a11bb23Sdan static void last_valueInvFunc(
5071c5ed624Sdan   sqlite3_context *pCtx,
5081c5ed624Sdan   int nArg,
5091c5ed624Sdan   sqlite3_value **apArg
5101c5ed624Sdan ){
5111c5ed624Sdan   struct LastValueCtx *p;
512c7bf5716Sdrh   UNUSED_PARAMETER(nArg);
513c7bf5716Sdrh   UNUSED_PARAMETER(apArg);
5141c5ed624Sdan   p = (struct LastValueCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p));
5159c27758eSdan   if( ALWAYS(p) ){
5161c5ed624Sdan     p->nVal--;
5171c5ed624Sdan     if( p->nVal==0 ){
5181c5ed624Sdan       sqlite3_value_free(p->pVal);
5191c5ed624Sdan       p->pVal = 0;
5201c5ed624Sdan     }
5211c5ed624Sdan   }
5221c5ed624Sdan }
last_valueValueFunc(sqlite3_context * pCtx)5231c5ed624Sdan static void last_valueValueFunc(sqlite3_context *pCtx){
5241c5ed624Sdan   struct LastValueCtx *p;
5250525b6f4Sdan   p = (struct LastValueCtx*)sqlite3_aggregate_context(pCtx, 0);
5261c5ed624Sdan   if( p && p->pVal ){
5271c5ed624Sdan     sqlite3_result_value(pCtx, p->pVal);
5281c5ed624Sdan   }
5291c5ed624Sdan }
last_valueFinalizeFunc(sqlite3_context * pCtx)5301c5ed624Sdan static void last_valueFinalizeFunc(sqlite3_context *pCtx){
5311c5ed624Sdan   struct LastValueCtx *p;
5321c5ed624Sdan   p = (struct LastValueCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p));
5331c5ed624Sdan   if( p && p->pVal ){
5341c5ed624Sdan     sqlite3_result_value(pCtx, p->pVal);
5351c5ed624Sdan     sqlite3_value_free(p->pVal);
5361c5ed624Sdan     p->pVal = 0;
5371c5ed624Sdan   }
5381c5ed624Sdan }
5391c5ed624Sdan 
5402a11bb23Sdan /*
54119dc4d40Sdrh ** Static names for the built-in window function names.  These static
54219dc4d40Sdrh ** names are used, rather than string literals, so that FuncDef objects
54319dc4d40Sdrh ** can be associated with a particular window function by direct
54419dc4d40Sdrh ** comparison of the zName pointer.  Example:
54519dc4d40Sdrh **
54619dc4d40Sdrh **       if( pFuncDef->zName==row_valueName ){ ... }
5472a11bb23Sdan */
54819dc4d40Sdrh static const char row_numberName[] =   "row_number";
54919dc4d40Sdrh static const char dense_rankName[] =   "dense_rank";
55019dc4d40Sdrh static const char rankName[] =         "rank";
55119dc4d40Sdrh static const char percent_rankName[] = "percent_rank";
55219dc4d40Sdrh static const char cume_distName[] =    "cume_dist";
55319dc4d40Sdrh static const char ntileName[] =        "ntile";
55419dc4d40Sdrh static const char last_valueName[] =   "last_value";
55519dc4d40Sdrh static const char nth_valueName[] =    "nth_value";
55619dc4d40Sdrh static const char first_valueName[] =  "first_value";
55719dc4d40Sdrh static const char leadName[] =         "lead";
55819dc4d40Sdrh static const char lagName[] =          "lag";
559fe4e25a0Sdan 
56019dc4d40Sdrh /*
56119dc4d40Sdrh ** No-op implementations of xStep() and xFinalize().  Used as place-holders
56219dc4d40Sdrh ** for built-in window functions that never call those interfaces.
56319dc4d40Sdrh **
56419dc4d40Sdrh ** The noopValueFunc() is called but is expected to do nothing.  The
56519dc4d40Sdrh ** noopStepFunc() is never called, and so it is marked with NO_TEST to
56619dc4d40Sdrh ** let the test coverage routine know not to expect this function to be
56719dc4d40Sdrh ** invoked.
56819dc4d40Sdrh */
noopStepFunc(sqlite3_context * p,int n,sqlite3_value ** a)56919dc4d40Sdrh static void noopStepFunc(    /*NO_TEST*/
57019dc4d40Sdrh   sqlite3_context *p,        /*NO_TEST*/
57119dc4d40Sdrh   int n,                     /*NO_TEST*/
57219dc4d40Sdrh   sqlite3_value **a          /*NO_TEST*/
57319dc4d40Sdrh ){                           /*NO_TEST*/
574c7bf5716Sdrh   UNUSED_PARAMETER(p);       /*NO_TEST*/
575c7bf5716Sdrh   UNUSED_PARAMETER(n);       /*NO_TEST*/
576c7bf5716Sdrh   UNUSED_PARAMETER(a);       /*NO_TEST*/
57719dc4d40Sdrh   assert(0);                 /*NO_TEST*/
57819dc4d40Sdrh }                            /*NO_TEST*/
noopValueFunc(sqlite3_context * p)579c7bf5716Sdrh static void noopValueFunc(sqlite3_context *p){ UNUSED_PARAMETER(p); /*no-op*/ }
580dfa552f4Sdan 
58119dc4d40Sdrh /* Window functions that use all window interfaces: xStep, xFinal,
58219dc4d40Sdrh ** xValue, and xInverse */
58319dc4d40Sdrh #define WINDOWFUNCALL(name,nArg,extra) {                                   \
584f9751074Sdrh   nArg, (SQLITE_FUNC_BUILTIN|SQLITE_UTF8|SQLITE_FUNC_WINDOW|extra), 0, 0,  \
5851c5ed624Sdan   name ## StepFunc, name ## FinalizeFunc, name ## ValueFunc,               \
586c7bf5716Sdrh   name ## InvFunc, name ## Name, {0}                                       \
5871c5ed624Sdan }
5881c5ed624Sdan 
58919dc4d40Sdrh /* Window functions that are implemented using bytecode and thus have
59019dc4d40Sdrh ** no-op routines for their methods */
59119dc4d40Sdrh #define WINDOWFUNCNOOP(name,nArg,extra) {                                  \
592f9751074Sdrh   nArg, (SQLITE_FUNC_BUILTIN|SQLITE_UTF8|SQLITE_FUNC_WINDOW|extra), 0, 0,  \
59319dc4d40Sdrh   noopStepFunc, noopValueFunc, noopValueFunc,                              \
594c7bf5716Sdrh   noopStepFunc, name ## Name, {0}                                          \
59519dc4d40Sdrh }
59619dc4d40Sdrh 
59719dc4d40Sdrh /* Window functions that use all window interfaces: xStep, the
59819dc4d40Sdrh ** same routine for xFinalize and xValue and which never call
59919dc4d40Sdrh ** xInverse. */
60019dc4d40Sdrh #define WINDOWFUNCX(name,nArg,extra) {                                     \
601f9751074Sdrh   nArg, (SQLITE_FUNC_BUILTIN|SQLITE_UTF8|SQLITE_FUNC_WINDOW|extra), 0, 0,  \
60219dc4d40Sdrh   name ## StepFunc, name ## ValueFunc, name ## ValueFunc,                  \
603c7bf5716Sdrh   noopStepFunc, name ## Name, {0}                                          \
60419dc4d40Sdrh }
60519dc4d40Sdrh 
60619dc4d40Sdrh 
607dfa552f4Sdan /*
608dfa552f4Sdan ** Register those built-in window functions that are not also aggregates.
609dfa552f4Sdan */
sqlite3WindowFunctions(void)610dfa552f4Sdan void sqlite3WindowFunctions(void){
611dfa552f4Sdan   static FuncDef aWindowFuncs[] = {
61219dc4d40Sdrh     WINDOWFUNCX(row_number, 0, 0),
61319dc4d40Sdrh     WINDOWFUNCX(dense_rank, 0, 0),
61419dc4d40Sdrh     WINDOWFUNCX(rank, 0, 0),
615cc7a850fSdan     WINDOWFUNCALL(percent_rank, 0, 0),
616cc7a850fSdan     WINDOWFUNCALL(cume_dist, 0, 0),
617cc7a850fSdan     WINDOWFUNCALL(ntile, 1, 0),
61819dc4d40Sdrh     WINDOWFUNCALL(last_value, 1, 0),
619a0f6b833Sdan     WINDOWFUNCALL(nth_value, 2, 0),
620c782a81aSdan     WINDOWFUNCALL(first_value, 1, 0),
62119dc4d40Sdrh     WINDOWFUNCNOOP(lead, 1, 0),
62219dc4d40Sdrh     WINDOWFUNCNOOP(lead, 2, 0),
62319dc4d40Sdrh     WINDOWFUNCNOOP(lead, 3, 0),
62419dc4d40Sdrh     WINDOWFUNCNOOP(lag, 1, 0),
62519dc4d40Sdrh     WINDOWFUNCNOOP(lag, 2, 0),
62619dc4d40Sdrh     WINDOWFUNCNOOP(lag, 3, 0),
627dfa552f4Sdan   };
628dfa552f4Sdan   sqlite3InsertBuiltinFuncs(aWindowFuncs, ArraySize(aWindowFuncs));
629dfa552f4Sdan }
630dfa552f4Sdan 
windowFind(Parse * pParse,Window * pList,const char * zName)631e7c9ca41Sdan static Window *windowFind(Parse *pParse, Window *pList, const char *zName){
632e7c9ca41Sdan   Window *p;
633e7c9ca41Sdan   for(p=pList; p; p=p->pNextWin){
634e7c9ca41Sdan     if( sqlite3StrICmp(p->zName, zName)==0 ) break;
635e7c9ca41Sdan   }
636e7c9ca41Sdan   if( p==0 ){
637e7c9ca41Sdan     sqlite3ErrorMsg(pParse, "no such window: %s", zName);
638e7c9ca41Sdan   }
639e7c9ca41Sdan   return p;
640e7c9ca41Sdan }
641e7c9ca41Sdan 
642c0bb4459Sdan /*
643c0bb4459Sdan ** This function is called immediately after resolving the function name
644c0bb4459Sdan ** for a window function within a SELECT statement. Argument pList is a
645c0bb4459Sdan ** linked list of WINDOW definitions for the current SELECT statement.
646c0bb4459Sdan ** Argument pFunc is the function definition just resolved and pWin
647c0bb4459Sdan ** is the Window object representing the associated OVER clause. This
648c0bb4459Sdan ** function updates the contents of pWin as follows:
649c0bb4459Sdan **
650c0bb4459Sdan **   * If the OVER clause refered to a named window (as in "max(x) OVER win"),
651c0bb4459Sdan **     search list pList for a matching WINDOW definition, and update pWin
652c0bb4459Sdan **     accordingly. If no such WINDOW clause can be found, leave an error
653c0bb4459Sdan **     in pParse.
654c0bb4459Sdan **
655c0bb4459Sdan **   * If the function is a built-in window function that requires the
656c0bb4459Sdan **     window to be coerced (see "BUILT-IN WINDOW FUNCTIONS" at the top
657c0bb4459Sdan **     of this file), pWin is updated here.
658c0bb4459Sdan */
sqlite3WindowUpdate(Parse * pParse,Window * pList,Window * pWin,FuncDef * pFunc)659e3bf632cSdan void sqlite3WindowUpdate(
660e3bf632cSdan   Parse *pParse,
661c0bb4459Sdan   Window *pList,                  /* List of named windows for this SELECT */
662c0bb4459Sdan   Window *pWin,                   /* Window frame to update */
663c0bb4459Sdan   FuncDef *pFunc                  /* Window function definition */
664e3bf632cSdan ){
665fc15f4c5Sdrh   if( pWin->zName && pWin->eFrmType==0 ){
666e7c9ca41Sdan     Window *p = windowFind(pParse, pList, pWin->zName);
667e7c9ca41Sdan     if( p==0 ) return;
668e3bf632cSdan     pWin->pPartition = sqlite3ExprListDup(pParse->db, p->pPartition, 0);
669e3bf632cSdan     pWin->pOrderBy = sqlite3ExprListDup(pParse->db, p->pOrderBy, 0);
670e3bf632cSdan     pWin->pStart = sqlite3ExprDup(pParse->db, p->pStart, 0);
671e3bf632cSdan     pWin->pEnd = sqlite3ExprDup(pParse->db, p->pEnd, 0);
672e3bf632cSdan     pWin->eStart = p->eStart;
673e3bf632cSdan     pWin->eEnd = p->eEnd;
674fc15f4c5Sdrh     pWin->eFrmType = p->eFrmType;
675c782a81aSdan     pWin->eExclude = p->eExclude;
676e7c9ca41Sdan   }else{
677e7c9ca41Sdan     sqlite3WindowChain(pParse, pWin, pList);
678e3bf632cSdan   }
679fc15f4c5Sdrh   if( (pWin->eFrmType==TK_RANGE)
68072b9fdcfSdan    && (pWin->pStart || pWin->pEnd)
68172b9fdcfSdan    && (pWin->pOrderBy==0 || pWin->pOrderBy->nExpr!=1)
68272b9fdcfSdan   ){
68372b9fdcfSdan     sqlite3ErrorMsg(pParse,
68472b9fdcfSdan       "RANGE with offset PRECEDING/FOLLOWING requires one ORDER BY expression"
68572b9fdcfSdan     );
68672b9fdcfSdan   }else
687dfa552f4Sdan   if( pFunc->funcFlags & SQLITE_FUNC_WINDOW ){
688dfa552f4Sdan     sqlite3 *db = pParse->db;
6898b98560dSdan     if( pWin->pFilter ){
6908b98560dSdan       sqlite3ErrorMsg(pParse,
6918b98560dSdan           "FILTER clause may only be used with aggregate window functions"
6928b98560dSdan       );
693cc7a850fSdan     }else{
694cc7a850fSdan       struct WindowUpdate {
695cc7a850fSdan         const char *zFunc;
696fc15f4c5Sdrh         int eFrmType;
697cc7a850fSdan         int eStart;
698cc7a850fSdan         int eEnd;
699cc7a850fSdan       } aUp[] = {
700cc7a850fSdan         { row_numberName,   TK_ROWS,   TK_UNBOUNDED, TK_CURRENT },
701cc7a850fSdan         { dense_rankName,   TK_RANGE,  TK_UNBOUNDED, TK_CURRENT },
702cc7a850fSdan         { rankName,         TK_RANGE,  TK_UNBOUNDED, TK_CURRENT },
703cc7a850fSdan         { percent_rankName, TK_GROUPS, TK_CURRENT,   TK_UNBOUNDED },
704cc7a850fSdan         { cume_distName,    TK_GROUPS, TK_FOLLOWING, TK_UNBOUNDED },
705cc7a850fSdan         { ntileName,        TK_ROWS,   TK_CURRENT,   TK_UNBOUNDED },
706cc7a850fSdan         { leadName,         TK_ROWS,   TK_UNBOUNDED, TK_UNBOUNDED },
707b560a719Sdan         { lagName,          TK_ROWS,   TK_UNBOUNDED, TK_CURRENT },
708cc7a850fSdan       };
709cc7a850fSdan       int i;
710cc7a850fSdan       for(i=0; i<ArraySize(aUp); i++){
711cc7a850fSdan         if( pFunc->zName==aUp[i].zFunc ){
712dfa552f4Sdan           sqlite3ExprDelete(db, pWin->pStart);
713dfa552f4Sdan           sqlite3ExprDelete(db, pWin->pEnd);
714cc7a850fSdan           pWin->pEnd = pWin->pStart = 0;
715fc15f4c5Sdrh           pWin->eFrmType = aUp[i].eFrmType;
716cc7a850fSdan           pWin->eStart = aUp[i].eStart;
717cc7a850fSdan           pWin->eEnd = aUp[i].eEnd;
718a0f6b833Sdan           pWin->eExclude = 0;
719cc7a850fSdan           if( pWin->eStart==TK_FOLLOWING ){
720cc7a850fSdan             pWin->pStart = sqlite3Expr(db, TK_INTEGER, "1");
721cc7a850fSdan           }
722cc7a850fSdan           break;
723cc7a850fSdan         }
724cc7a850fSdan       }
725dfa552f4Sdan     }
726dfa552f4Sdan   }
727105dcaa5Sdrh   pWin->pWFunc = pFunc;
728dfa552f4Sdan }
729dfa552f4Sdan 
730c0bb4459Sdan /*
731c0bb4459Sdan ** Context object passed through sqlite3WalkExprList() to
732c0bb4459Sdan ** selectWindowRewriteExprCb() by selectWindowRewriteEList().
733c0bb4459Sdan */
734dfa552f4Sdan typedef struct WindowRewrite WindowRewrite;
735dfa552f4Sdan struct WindowRewrite {
736dfa552f4Sdan   Window *pWin;
737b556f261Sdan   SrcList *pSrc;
738dfa552f4Sdan   ExprList *pSub;
73962742fd2Sdan   Table *pTab;
740b556f261Sdan   Select *pSubSelect;             /* Current sub-select, if any */
741dfa552f4Sdan };
742dfa552f4Sdan 
743c0bb4459Sdan /*
744c0bb4459Sdan ** Callback function used by selectWindowRewriteEList(). If necessary,
745c0bb4459Sdan ** this function appends to the output expression-list and updates
746c0bb4459Sdan ** expression (*ppExpr) in place.
747c0bb4459Sdan */
selectWindowRewriteExprCb(Walker * pWalker,Expr * pExpr)748dfa552f4Sdan static int selectWindowRewriteExprCb(Walker *pWalker, Expr *pExpr){
749dfa552f4Sdan   struct WindowRewrite *p = pWalker->u.pRewrite;
750dfa552f4Sdan   Parse *pParse = pWalker->pParse;
75155f66b34Sdrh   assert( p!=0 );
75255f66b34Sdrh   assert( p->pWin!=0 );
753dfa552f4Sdan 
754b556f261Sdan   /* If this function is being called from within a scalar sub-select
755b556f261Sdan   ** that used by the SELECT statement being processed, only process
756b556f261Sdan   ** TK_COLUMN expressions that refer to it (the outer SELECT). Do
757b556f261Sdan   ** not process aggregates or window functions at all, as they belong
758b556f261Sdan   ** to the scalar sub-select.  */
759b556f261Sdan   if( p->pSubSelect ){
760b556f261Sdan     if( pExpr->op!=TK_COLUMN ){
761b556f261Sdan       return WRC_Continue;
762b556f261Sdan     }else{
763b556f261Sdan       int nSrc = p->pSrc->nSrc;
764b556f261Sdan       int i;
765b556f261Sdan       for(i=0; i<nSrc; i++){
766b556f261Sdan         if( pExpr->iTable==p->pSrc->a[i].iCursor ) break;
767b556f261Sdan       }
768b556f261Sdan       if( i==nSrc ) return WRC_Continue;
769b556f261Sdan     }
770b556f261Sdan   }
771b556f261Sdan 
772dfa552f4Sdan   switch( pExpr->op ){
773dfa552f4Sdan 
774dfa552f4Sdan     case TK_FUNCTION:
775eda079cdSdrh       if( !ExprHasProperty(pExpr, EP_WinFunc) ){
776dfa552f4Sdan         break;
777dfa552f4Sdan       }else{
778dfa552f4Sdan         Window *pWin;
779dfa552f4Sdan         for(pWin=p->pWin; pWin; pWin=pWin->pNextWin){
780eda079cdSdrh           if( pExpr->y.pWin==pWin ){
7812a11bb23Sdan             assert( pWin->pOwner==pExpr );
782dfa552f4Sdan             return WRC_Prune;
783dfa552f4Sdan           }
784dfa552f4Sdan         }
785dfa552f4Sdan       }
78608b92086Sdrh       /* no break */ deliberate_fall_through
787dfa552f4Sdan 
7887392569fSdan     case TK_AGG_FUNCTION:
789dfa552f4Sdan     case TK_COLUMN: {
79062be2dc7Sdan       int iCol = -1;
791d22ecfd3Sdrh       if( pParse->db->mallocFailed ) return WRC_Abort;
79262be2dc7Sdan       if( p->pSub ){
79362be2dc7Sdan         int i;
79462be2dc7Sdan         for(i=0; i<p->pSub->nExpr; i++){
79562be2dc7Sdan           if( 0==sqlite3ExprCompare(0, p->pSub->a[i].pExpr, pExpr, -1) ){
79662be2dc7Sdan             iCol = i;
79762be2dc7Sdan             break;
79862be2dc7Sdan           }
79962be2dc7Sdan         }
80062be2dc7Sdan       }
80162be2dc7Sdan       if( iCol<0 ){
802dfa552f4Sdan         Expr *pDup = sqlite3ExprDup(pParse->db, pExpr, 0);
80343170437Sdan         if( pDup && pDup->op==TK_AGG_FUNCTION ) pDup->op = TK_FUNCTION;
804dfa552f4Sdan         p->pSub = sqlite3ExprListAppend(pParse, p->pSub, pDup);
80562be2dc7Sdan       }
806dfa552f4Sdan       if( p->pSub ){
80727da907fSdan         int f = pExpr->flags & EP_Collate;
808dfa552f4Sdan         assert( ExprHasProperty(pExpr, EP_Static)==0 );
809dfa552f4Sdan         ExprSetProperty(pExpr, EP_Static);
810dfa552f4Sdan         sqlite3ExprDelete(pParse->db, pExpr);
811dfa552f4Sdan         ExprClearProperty(pExpr, EP_Static);
812dfa552f4Sdan         memset(pExpr, 0, sizeof(Expr));
813dfa552f4Sdan 
814dfa552f4Sdan         pExpr->op = TK_COLUMN;
81562be2dc7Sdan         pExpr->iColumn = (iCol<0 ? p->pSub->nExpr-1: iCol);
816dfa552f4Sdan         pExpr->iTable = p->pWin->iEphCsr;
81762742fd2Sdan         pExpr->y.pTab = p->pTab;
81827da907fSdan         pExpr->flags = f;
819dfa552f4Sdan       }
820a2f142d0Sdrh       if( pParse->db->mallocFailed ) return WRC_Abort;
821dfa552f4Sdan       break;
822dfa552f4Sdan     }
823dfa552f4Sdan 
824dfa552f4Sdan     default: /* no-op */
825dfa552f4Sdan       break;
826dfa552f4Sdan   }
827dfa552f4Sdan 
828dfa552f4Sdan   return WRC_Continue;
829dfa552f4Sdan }
selectWindowRewriteSelectCb(Walker * pWalker,Select * pSelect)830c0bb4459Sdan static int selectWindowRewriteSelectCb(Walker *pWalker, Select *pSelect){
831b556f261Sdan   struct WindowRewrite *p = pWalker->u.pRewrite;
832b556f261Sdan   Select *pSave = p->pSubSelect;
833b556f261Sdan   if( pSave==pSelect ){
834b556f261Sdan     return WRC_Continue;
835b556f261Sdan   }else{
836b556f261Sdan     p->pSubSelect = pSelect;
837b556f261Sdan     sqlite3WalkSelect(pWalker, pSelect);
838b556f261Sdan     p->pSubSelect = pSave;
839b556f261Sdan   }
840c0bb4459Sdan   return WRC_Prune;
841c0bb4459Sdan }
842dfa552f4Sdan 
843c0bb4459Sdan 
844c0bb4459Sdan /*
845c0bb4459Sdan ** Iterate through each expression in expression-list pEList. For each:
846c0bb4459Sdan **
847c0bb4459Sdan **   * TK_COLUMN,
848c0bb4459Sdan **   * aggregate function, or
849c0bb4459Sdan **   * window function with a Window object that is not a member of the
850b556f261Sdan **     Window list passed as the second argument (pWin).
851c0bb4459Sdan **
852c0bb4459Sdan ** Append the node to output expression-list (*ppSub). And replace it
853c0bb4459Sdan ** with a TK_COLUMN that reads the (N-1)th element of table
854c0bb4459Sdan ** pWin->iEphCsr, where N is the number of elements in (*ppSub) after
855c0bb4459Sdan ** appending the new one.
856c0bb4459Sdan */
selectWindowRewriteEList(Parse * pParse,Window * pWin,SrcList * pSrc,ExprList * pEList,Table * pTab,ExprList ** ppSub)85713b08bb6Sdan static void selectWindowRewriteEList(
858dfa552f4Sdan   Parse *pParse,
859dfa552f4Sdan   Window *pWin,
860b556f261Sdan   SrcList *pSrc,
861dfa552f4Sdan   ExprList *pEList,               /* Rewrite expressions in this list */
86262742fd2Sdan   Table *pTab,
863dfa552f4Sdan   ExprList **ppSub                /* IN/OUT: Sub-select expression-list */
864dfa552f4Sdan ){
865dfa552f4Sdan   Walker sWalker;
866dfa552f4Sdan   WindowRewrite sRewrite;
867dfa552f4Sdan 
86855f66b34Sdrh   assert( pWin!=0 );
869dfa552f4Sdan   memset(&sWalker, 0, sizeof(Walker));
870dfa552f4Sdan   memset(&sRewrite, 0, sizeof(WindowRewrite));
871dfa552f4Sdan 
872dfa552f4Sdan   sRewrite.pSub = *ppSub;
873dfa552f4Sdan   sRewrite.pWin = pWin;
874b556f261Sdan   sRewrite.pSrc = pSrc;
87562742fd2Sdan   sRewrite.pTab = pTab;
876dfa552f4Sdan 
877dfa552f4Sdan   sWalker.pParse = pParse;
878dfa552f4Sdan   sWalker.xExprCallback = selectWindowRewriteExprCb;
879dfa552f4Sdan   sWalker.xSelectCallback = selectWindowRewriteSelectCb;
880dfa552f4Sdan   sWalker.u.pRewrite = &sRewrite;
881dfa552f4Sdan 
88213b08bb6Sdan   (void)sqlite3WalkExprList(&sWalker, pEList);
883dfa552f4Sdan 
884dfa552f4Sdan   *ppSub = sRewrite.pSub;
885dfa552f4Sdan }
886dfa552f4Sdan 
887c0bb4459Sdan /*
888c0bb4459Sdan ** Append a copy of each expression in expression-list pAppend to
889c0bb4459Sdan ** expression list pList. Return a pointer to the result list.
890c0bb4459Sdan */
exprListAppendList(Parse * pParse,ExprList * pList,ExprList * pAppend,int bIntToNull)891dfa552f4Sdan static ExprList *exprListAppendList(
892dfa552f4Sdan   Parse *pParse,          /* Parsing context */
893dfa552f4Sdan   ExprList *pList,        /* List to which to append. Might be NULL */
89408f6de7fSdan   ExprList *pAppend,      /* List of values to append. Might be NULL */
89508f6de7fSdan   int bIntToNull
896dfa552f4Sdan ){
897dfa552f4Sdan   if( pAppend ){
898dfa552f4Sdan     int i;
899dfa552f4Sdan     int nInit = pList ? pList->nExpr : 0;
900dfa552f4Sdan     for(i=0; i<pAppend->nExpr; i++){
90157f90189Sdrh       sqlite3 *db = pParse->db;
90257f90189Sdrh       Expr *pDup = sqlite3ExprDup(db, pAppend->a[i].pExpr, 0);
9034c4a2572Sdrh       if( db->mallocFailed ){
9044c4a2572Sdrh         sqlite3ExprDelete(db, pDup);
9054c4a2572Sdrh         break;
9064c4a2572Sdrh       }
9074c4a2572Sdrh       if( bIntToNull ){
908efa78884Sdan         int iDummy;
909efa78884Sdan         Expr *pSub;
910a261c02dSdan         pSub = sqlite3ExprSkipCollateAndLikely(pDup);
911efa78884Sdan         if( sqlite3ExprIsInteger(pSub, &iDummy) ){
912efa78884Sdan           pSub->op = TK_NULL;
913efa78884Sdan           pSub->flags &= ~(EP_IntValue|EP_IsTrue|EP_IsFalse);
914efa78884Sdan           pSub->u.zToken = 0;
915efa78884Sdan         }
91608f6de7fSdan       }
917dfa552f4Sdan       pList = sqlite3ExprListAppend(pParse, pList, pDup);
918d88fd539Sdrh       if( pList ) pList->a[nInit+i].fg.sortFlags = pAppend->a[i].fg.sortFlags;
919dfa552f4Sdan     }
920dfa552f4Sdan   }
921dfa552f4Sdan   return pList;
922dfa552f4Sdan }
923dfa552f4Sdan 
924dfa552f4Sdan /*
925c37577bbSdrh ** When rewriting a query, if the new subquery in the FROM clause
926c37577bbSdrh ** contains TK_AGG_FUNCTION nodes that refer to an outer query,
927c37577bbSdrh ** then we have to increase the Expr->op2 values of those nodes
928c37577bbSdrh ** due to the extra subquery layer that was added.
929c37577bbSdrh **
930c37577bbSdrh ** See also the incrAggDepth() routine in resolve.c
931c37577bbSdrh */
sqlite3WindowExtraAggFuncDepth(Walker * pWalker,Expr * pExpr)932c37577bbSdrh static int sqlite3WindowExtraAggFuncDepth(Walker *pWalker, Expr *pExpr){
933c37577bbSdrh   if( pExpr->op==TK_AGG_FUNCTION
934c37577bbSdrh    && pExpr->op2>=pWalker->walkerDepth
935c37577bbSdrh   ){
936c37577bbSdrh     pExpr->op2++;
937c37577bbSdrh   }
938c37577bbSdrh   return WRC_Continue;
939c37577bbSdrh }
940c37577bbSdrh 
disallowAggregatesInOrderByCb(Walker * pWalker,Expr * pExpr)9414752bbd8Sdrh static int disallowAggregatesInOrderByCb(Walker *pWalker, Expr *pExpr){
9424752bbd8Sdrh   if( pExpr->op==TK_AGG_FUNCTION && pExpr->pAggInfo==0 ){
943f9751074Sdrh     assert( !ExprHasProperty(pExpr, EP_IntValue) );
9444752bbd8Sdrh      sqlite3ErrorMsg(pWalker->pParse,
9454752bbd8Sdrh          "misuse of aggregate: %s()", pExpr->u.zToken);
9464752bbd8Sdrh   }
9474752bbd8Sdrh   return WRC_Continue;
9484752bbd8Sdrh }
9494752bbd8Sdrh 
950c37577bbSdrh /*
951dfa552f4Sdan ** If the SELECT statement passed as the second argument does not invoke
952dfa552f4Sdan ** any SQL window functions, this function is a no-op. Otherwise, it
953dfa552f4Sdan ** rewrites the SELECT statement so that window function xStep functions
954c0bb4459Sdan ** are invoked in the correct order as described under "SELECT REWRITING"
955c0bb4459Sdan ** at the top of this file.
956dfa552f4Sdan */
sqlite3WindowRewrite(Parse * pParse,Select * p)957dfa552f4Sdan int sqlite3WindowRewrite(Parse *pParse, Select *p){
958dfa552f4Sdan   int rc = SQLITE_OK;
9595e121a50Sdrh   if( p->pWin
9605e121a50Sdrh    && p->pPrior==0
9615e121a50Sdrh    && ALWAYS((p->selFlags & SF_WinRewrite)==0)
962fde30432Sdrh    && ALWAYS(!IN_RENAME_OBJECT)
9635e121a50Sdrh   ){
964dfa552f4Sdan     Vdbe *v = sqlite3GetVdbe(pParse);
965dfa552f4Sdan     sqlite3 *db = pParse->db;
966dfa552f4Sdan     Select *pSub = 0;             /* The subquery */
967dfa552f4Sdan     SrcList *pSrc = p->pSrc;
968dfa552f4Sdan     Expr *pWhere = p->pWhere;
969dfa552f4Sdan     ExprList *pGroupBy = p->pGroupBy;
970dfa552f4Sdan     Expr *pHaving = p->pHaving;
971dfa552f4Sdan     ExprList *pSort = 0;
972dfa552f4Sdan 
973dfa552f4Sdan     ExprList *pSublist = 0;       /* Expression list for sub-query */
974067b92baSdrh     Window *pMWin = p->pWin;      /* Main window object */
975dfa552f4Sdan     Window *pWin;                 /* Window object iterator */
97662742fd2Sdan     Table *pTab;
97789636628Sdrh     Walker w;
97889636628Sdrh 
979553948e5Sdan     u32 selFlags = p->selFlags;
98062742fd2Sdan 
98162742fd2Sdan     pTab = sqlite3DbMallocZero(db, sizeof(Table));
98262742fd2Sdan     if( pTab==0 ){
9838654186bSdrh       return sqlite3ErrorToParser(db, SQLITE_NOMEM);
98462742fd2Sdan     }
98589636628Sdrh     sqlite3AggInfoPersistWalkerInit(&w, pParse);
98689636628Sdrh     sqlite3WalkSelect(&w, p);
9874752bbd8Sdrh     if( (p->selFlags & SF_Aggregate)==0 ){
9884752bbd8Sdrh       w.xExprCallback = disallowAggregatesInOrderByCb;
9893d691fd9Sdan       w.xSelectCallback = 0;
9904752bbd8Sdrh       sqlite3WalkExprList(&w, p->pOrderBy);
9914752bbd8Sdrh     }
992dfa552f4Sdan 
993dfa552f4Sdan     p->pSrc = 0;
994dfa552f4Sdan     p->pWhere = 0;
995dfa552f4Sdan     p->pGroupBy = 0;
996dfa552f4Sdan     p->pHaving = 0;
99762742fd2Sdan     p->selFlags &= ~SF_Aggregate;
998ba01634cSdrh     p->selFlags |= SF_WinRewrite;
999dfa552f4Sdan 
1000f02cdd37Sdan     /* Create the ORDER BY clause for the sub-select. This is the concatenation
1001f02cdd37Sdan     ** of the window PARTITION and ORDER BY clauses. Then, if this makes it
1002f02cdd37Sdan     ** redundant, remove the ORDER BY from the parent SELECT.  */
1003d8d2fb92Sdan     pSort = exprListAppendList(pParse, 0, pMWin->pPartition, 1);
100408f6de7fSdan     pSort = exprListAppendList(pParse, pSort, pMWin->pOrderBy, 1);
10050e3c50c5Sdan     if( pSort && p->pOrderBy && p->pOrderBy->nExpr<=pSort->nExpr ){
10060e3c50c5Sdan       int nSave = pSort->nExpr;
10070e3c50c5Sdan       pSort->nExpr = p->pOrderBy->nExpr;
1008f02cdd37Sdan       if( sqlite3ExprListCompare(pSort, p->pOrderBy, -1)==0 ){
1009f02cdd37Sdan         sqlite3ExprListDelete(db, p->pOrderBy);
1010f02cdd37Sdan         p->pOrderBy = 0;
1011f02cdd37Sdan       }
10120e3c50c5Sdan       pSort->nExpr = nSave;
1013f02cdd37Sdan     }
1014f02cdd37Sdan 
1015dfa552f4Sdan     /* Assign a cursor number for the ephemeral table used to buffer rows.
1016dfa552f4Sdan     ** The OpenEphemeral instruction is coded later, after it is known how
1017dfa552f4Sdan     ** many columns the table will have.  */
1018dfa552f4Sdan     pMWin->iEphCsr = pParse->nTab++;
1019680f6e8eSdan     pParse->nTab += 3;
1020dfa552f4Sdan 
102162742fd2Sdan     selectWindowRewriteEList(pParse, pMWin, pSrc, p->pEList, pTab, &pSublist);
102262742fd2Sdan     selectWindowRewriteEList(pParse, pMWin, pSrc, p->pOrderBy, pTab, &pSublist);
1023dfa552f4Sdan     pMWin->nBufferCol = (pSublist ? pSublist->nExpr : 0);
1024dfa552f4Sdan 
1025f02cdd37Sdan     /* Append the PARTITION BY and ORDER BY expressions to the to the
1026f02cdd37Sdan     ** sub-select expression list. They are required to figure out where
1027f02cdd37Sdan     ** boundaries for partitions and sets of peer rows lie.  */
102808f6de7fSdan     pSublist = exprListAppendList(pParse, pSublist, pMWin->pPartition, 0);
102908f6de7fSdan     pSublist = exprListAppendList(pParse, pSublist, pMWin->pOrderBy, 0);
1030dfa552f4Sdan 
1031dfa552f4Sdan     /* Append the arguments passed to each window function to the
1032dfa552f4Sdan     ** sub-select expression list. Also allocate two registers for each
1033dfa552f4Sdan     ** window function - one for the accumulator, another for interim
1034dfa552f4Sdan     ** results.  */
1035dfa552f4Sdan     for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
1036a4eeccdfSdrh       ExprList *pArgs;
1037a4eeccdfSdrh       assert( ExprUseXList(pWin->pOwner) );
10385e121a50Sdrh       assert( pWin->pWFunc!=0 );
1039a4eeccdfSdrh       pArgs = pWin->pOwner->x.pList;
1040105dcaa5Sdrh       if( pWin->pWFunc->funcFlags & SQLITE_FUNC_SUBTYPE ){
1041e2ba6df9Sdan         selectWindowRewriteEList(pParse, pMWin, pSrc, pArgs, pTab, &pSublist);
1042dfa552f4Sdan         pWin->iArgCol = (pSublist ? pSublist->nExpr : 0);
1043e2ba6df9Sdan         pWin->bExprArgs = 1;
1044e2ba6df9Sdan       }else{
1045e2ba6df9Sdan         pWin->iArgCol = (pSublist ? pSublist->nExpr : 0);
1046e2ba6df9Sdan         pSublist = exprListAppendList(pParse, pSublist, pArgs, 0);
1047e2ba6df9Sdan       }
10488b98560dSdan       if( pWin->pFilter ){
10498b98560dSdan         Expr *pFilter = sqlite3ExprDup(db, pWin->pFilter, 0);
10508b98560dSdan         pSublist = sqlite3ExprListAppend(pParse, pSublist, pFilter);
10518b98560dSdan       }
1052dfa552f4Sdan       pWin->regAccum = ++pParse->nMem;
1053dfa552f4Sdan       pWin->regResult = ++pParse->nMem;
1054dfa552f4Sdan       sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regAccum);
1055dfa552f4Sdan     }
1056dfa552f4Sdan 
10579c27758eSdan     /* If there is no ORDER BY or PARTITION BY clause, and the window
10589c27758eSdan     ** function accepts zero arguments, and there are no other columns
10599c27758eSdan     ** selected (e.g. "SELECT row_number() OVER () FROM t1"), it is possible
10609c27758eSdan     ** that pSublist is still NULL here. Add a constant expression here to
10619c27758eSdan     ** keep everything legal in this case.
10629c27758eSdan     */
10639c27758eSdan     if( pSublist==0 ){
10649c27758eSdan       pSublist = sqlite3ExprListAppend(pParse, 0,
10655776ee5cSdrh         sqlite3Expr(db, TK_INTEGER, "0")
10669c27758eSdan       );
10679c27758eSdan     }
10689c27758eSdan 
1069dfa552f4Sdan     pSub = sqlite3SelectNew(
1070dfa552f4Sdan         pParse, pSublist, pSrc, pWhere, pGroupBy, pHaving, pSort, 0, 0
1071dfa552f4Sdan     );
10729216de8aSdrh     SELECTTRACE(1,pParse,pSub,
10739216de8aSdrh        ("New window-function subquery in FROM clause of (%u/%p)\n",
10749216de8aSdrh        p->selId, p));
107529c992cbSdrh     p->pSrc = sqlite3SrcListAppend(pParse, 0, 0, 0);
107682456a66Sdrh     assert( pSub!=0 || p->pSrc==0 ); /* Due to db->mallocFailed test inside
107782456a66Sdrh                                      ** of sqlite3DbMallocRawNN() called from
107882456a66Sdrh                                      ** sqlite3SrcListAppend() */
1079dfa552f4Sdan     if( p->pSrc ){
108062742fd2Sdan       Table *pTab2;
1081dfa552f4Sdan       p->pSrc->a[0].pSelect = pSub;
1082dfa552f4Sdan       sqlite3SrcListAssignCursors(pParse, p->pSrc);
1083bb301231Sdrh       pSub->selFlags |= SF_Expanded|SF_OrderByReqd;
108496fb16eeSdrh       pTab2 = sqlite3ResultSetOfSelect(pParse, pSub, SQLITE_AFF_NONE);
1085553948e5Sdan       pSub->selFlags |= (selFlags & SF_Aggregate);
108662742fd2Sdan       if( pTab2==0 ){
1087a9ebfe20Sdrh         /* Might actually be some other kind of error, but in that case
1088a9ebfe20Sdrh         ** pParse->nErr will be set, so if SQLITE_NOMEM is set, we will get
1089a9ebfe20Sdrh         ** the correct error message regardless. */
1090dfa552f4Sdan         rc = SQLITE_NOMEM;
1091dfa552f4Sdan       }else{
109262742fd2Sdan         memcpy(pTab, pTab2, sizeof(Table));
109362742fd2Sdan         pTab->tabFlags |= TF_Ephemeral;
109462742fd2Sdan         p->pSrc->a[0].pTab = pTab;
109562742fd2Sdan         pTab = pTab2;
1096c37577bbSdrh         memset(&w, 0, sizeof(w));
1097c37577bbSdrh         w.xExprCallback = sqlite3WindowExtraAggFuncDepth;
1098c37577bbSdrh         w.xSelectCallback = sqlite3WalkerDepthIncrease;
1099c37577bbSdrh         w.xSelectCallback2 = sqlite3WalkerDepthDecrease;
1100c37577bbSdrh         sqlite3WalkSelect(&w, pSub);
1101dfa552f4Sdan       }
11026fde1799Sdan     }else{
11036fde1799Sdan       sqlite3SelectDelete(db, pSub);
11046fde1799Sdan     }
11056fde1799Sdan     if( db->mallocFailed ) rc = SQLITE_NOMEM;
11066d64b4a0Sdrh 
11076d64b4a0Sdrh     /* Defer deleting the temporary table pTab because if an error occurred,
11086d64b4a0Sdrh     ** there could still be references to that table embedded in the
11096d64b4a0Sdrh     ** result-set or ORDER BY clause of the SELECT statement p.  */
11106d64b4a0Sdrh     sqlite3ParserAddCleanup(pParse, sqlite3DbFree, pTab);
1111dfa552f4Sdan   }
1112dfa552f4Sdan 
11131da88b5cSdrh   assert( rc==SQLITE_OK || pParse->nErr!=0 );
1114dfa552f4Sdan   return rc;
1115dfa552f4Sdan }
1116dfa552f4Sdan 
1117c0bb4459Sdan /*
1118e2094572Sdrh ** Unlink the Window object from the Select to which it is attached,
1119e2094572Sdrh ** if it is attached.
1120e2094572Sdrh */
sqlite3WindowUnlinkFromSelect(Window * p)1121e2094572Sdrh void sqlite3WindowUnlinkFromSelect(Window *p){
1122e2094572Sdrh   if( p->ppThis ){
1123e2094572Sdrh     *p->ppThis = p->pNextWin;
1124e2094572Sdrh     if( p->pNextWin ) p->pNextWin->ppThis = p->ppThis;
1125e2094572Sdrh     p->ppThis = 0;
1126e2094572Sdrh   }
1127e2094572Sdrh }
1128e2094572Sdrh 
1129e2094572Sdrh /*
1130c0bb4459Sdan ** Free the Window object passed as the second argument.
1131c0bb4459Sdan */
sqlite3WindowDelete(sqlite3 * db,Window * p)113286fb6e17Sdan void sqlite3WindowDelete(sqlite3 *db, Window *p){
113386fb6e17Sdan   if( p ){
1134e2094572Sdrh     sqlite3WindowUnlinkFromSelect(p);
113586fb6e17Sdan     sqlite3ExprDelete(db, p->pFilter);
113686fb6e17Sdan     sqlite3ExprListDelete(db, p->pPartition);
113786fb6e17Sdan     sqlite3ExprListDelete(db, p->pOrderBy);
113886fb6e17Sdan     sqlite3ExprDelete(db, p->pEnd);
113986fb6e17Sdan     sqlite3ExprDelete(db, p->pStart);
1140e3bf632cSdan     sqlite3DbFree(db, p->zName);
1141e7c9ca41Sdan     sqlite3DbFree(db, p->zBase);
114286fb6e17Sdan     sqlite3DbFree(db, p);
114386fb6e17Sdan   }
114486fb6e17Sdan }
114586fb6e17Sdan 
1146c0bb4459Sdan /*
1147c0bb4459Sdan ** Free the linked list of Window objects starting at the second argument.
1148c0bb4459Sdan */
sqlite3WindowListDelete(sqlite3 * db,Window * p)1149e3bf632cSdan void sqlite3WindowListDelete(sqlite3 *db, Window *p){
1150e3bf632cSdan   while( p ){
1151e3bf632cSdan     Window *pNext = p->pNextWin;
1152e3bf632cSdan     sqlite3WindowDelete(db, p);
1153e3bf632cSdan     p = pNext;
1154e3bf632cSdan   }
1155e3bf632cSdan }
1156e3bf632cSdan 
1157c0bb4459Sdan /*
1158e4984a2bSdrh ** The argument expression is an PRECEDING or FOLLOWING offset.  The
1159e4984a2bSdrh ** value should be a non-negative integer.  If the value is not a
1160e4984a2bSdrh ** constant, change it to NULL.  The fact that it is then a non-negative
1161e4984a2bSdrh ** integer will be caught later.  But it is important not to leave
1162e4984a2bSdrh ** variable values in the expression tree.
1163e4984a2bSdrh */
sqlite3WindowOffsetExpr(Parse * pParse,Expr * pExpr)1164e4984a2bSdrh static Expr *sqlite3WindowOffsetExpr(Parse *pParse, Expr *pExpr){
1165e4984a2bSdrh   if( 0==sqlite3ExprIsConstant(pExpr) ){
1166fb8ac325Sdan     if( IN_RENAME_OBJECT ) sqlite3RenameExprUnmap(pParse, pExpr);
1167e4984a2bSdrh     sqlite3ExprDelete(pParse->db, pExpr);
1168e4984a2bSdrh     pExpr = sqlite3ExprAlloc(pParse->db, TK_NULL, 0, 0);
1169e4984a2bSdrh   }
1170e4984a2bSdrh   return pExpr;
1171e4984a2bSdrh }
1172e4984a2bSdrh 
1173e4984a2bSdrh /*
1174e4984a2bSdrh ** Allocate and return a new Window object describing a Window Definition.
1175c0bb4459Sdan */
sqlite3WindowAlloc(Parse * pParse,int eType,int eStart,Expr * pStart,int eEnd,Expr * pEnd,u8 eExclude)117686fb6e17Sdan Window *sqlite3WindowAlloc(
1177e4984a2bSdrh   Parse *pParse,    /* Parsing context */
1178fc15f4c5Sdrh   int eType,        /* Frame type. TK_RANGE, TK_ROWS, TK_GROUPS, or 0 */
1179e4984a2bSdrh   int eStart,       /* Start type: CURRENT, PRECEDING, FOLLOWING, UNBOUNDED */
1180e4984a2bSdrh   Expr *pStart,     /* Start window size if TK_PRECEDING or FOLLOWING */
1181e4984a2bSdrh   int eEnd,         /* End type: CURRENT, FOLLOWING, TK_UNBOUNDED, PRECEDING */
1182d35300f9Sdan   Expr *pEnd,       /* End window size if TK_FOLLOWING or PRECEDING */
1183d35300f9Sdan   u8 eExclude       /* EXCLUDE clause */
118486fb6e17Sdan ){
11857a606e1aSdan   Window *pWin = 0;
1186e7c9ca41Sdan   int bImplicitFrame = 0;
11877a606e1aSdan 
1188e4984a2bSdrh   /* Parser assures the following: */
11896c75b396Sdan   assert( eType==0 || eType==TK_RANGE || eType==TK_ROWS || eType==TK_GROUPS );
1190e4984a2bSdrh   assert( eStart==TK_CURRENT || eStart==TK_PRECEDING
1191e4984a2bSdrh            || eStart==TK_UNBOUNDED || eStart==TK_FOLLOWING );
1192e4984a2bSdrh   assert( eEnd==TK_CURRENT || eEnd==TK_FOLLOWING
1193e4984a2bSdrh            || eEnd==TK_UNBOUNDED || eEnd==TK_PRECEDING );
1194e4984a2bSdrh   assert( (eStart==TK_PRECEDING || eStart==TK_FOLLOWING)==(pStart!=0) );
1195e4984a2bSdrh   assert( (eEnd==TK_FOLLOWING || eEnd==TK_PRECEDING)==(pEnd!=0) );
1196e4984a2bSdrh 
1197e7c9ca41Sdan   if( eType==0 ){
1198e7c9ca41Sdan     bImplicitFrame = 1;
1199e7c9ca41Sdan     eType = TK_RANGE;
1200e7c9ca41Sdan   }
1201e4984a2bSdrh 
1202e4984a2bSdrh   /* Additionally, the
12035d764ac9Sdan   ** starting boundary type may not occur earlier in the following list than
12045d764ac9Sdan   ** the ending boundary type:
12055d764ac9Sdan   **
12065d764ac9Sdan   **   UNBOUNDED PRECEDING
12075d764ac9Sdan   **   <expr> PRECEDING
12085d764ac9Sdan   **   CURRENT ROW
12095d764ac9Sdan   **   <expr> FOLLOWING
12105d764ac9Sdan   **   UNBOUNDED FOLLOWING
12115d764ac9Sdan   **
12125d764ac9Sdan   ** The parser ensures that "UNBOUNDED PRECEDING" cannot be used as an ending
12135d764ac9Sdan   ** boundary, and than "UNBOUNDED FOLLOWING" cannot be used as a starting
12145d764ac9Sdan   ** frame boundary.
12155d764ac9Sdan   */
1216e4984a2bSdrh   if( (eStart==TK_CURRENT && eEnd==TK_PRECEDING)
12175d764ac9Sdan    || (eStart==TK_FOLLOWING && (eEnd==TK_PRECEDING || eEnd==TK_CURRENT))
12185d764ac9Sdan   ){
121972b9fdcfSdan     sqlite3ErrorMsg(pParse, "unsupported frame specification");
1220e4984a2bSdrh     goto windowAllocErr;
12217a606e1aSdan   }
122286fb6e17Sdan 
1223e4984a2bSdrh   pWin = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window));
1224e4984a2bSdrh   if( pWin==0 ) goto windowAllocErr;
1225fc15f4c5Sdrh   pWin->eFrmType = eType;
122686fb6e17Sdan   pWin->eStart = eStart;
122786fb6e17Sdan   pWin->eEnd = eEnd;
122894809086Sdrh   if( eExclude==0 && OptimizationDisabled(pParse->db, SQLITE_WindowFunc) ){
1229108e6b2cSdan     eExclude = TK_NO;
1230108e6b2cSdan   }
1231d35300f9Sdan   pWin->eExclude = eExclude;
1232e7c9ca41Sdan   pWin->bImplicitFrame = bImplicitFrame;
1233e4984a2bSdrh   pWin->pEnd = sqlite3WindowOffsetExpr(pParse, pEnd);
1234e4984a2bSdrh   pWin->pStart = sqlite3WindowOffsetExpr(pParse, pStart);
1235e4984a2bSdrh   return pWin;
1236e4984a2bSdrh 
1237e4984a2bSdrh windowAllocErr:
123886fb6e17Sdan   sqlite3ExprDelete(pParse->db, pEnd);
123986fb6e17Sdan   sqlite3ExprDelete(pParse->db, pStart);
1240e4984a2bSdrh   return 0;
124186fb6e17Sdan }
124286fb6e17Sdan 
1243c0bb4459Sdan /*
1244e7c9ca41Sdan ** Attach PARTITION and ORDER BY clauses pPartition and pOrderBy to window
1245e7c9ca41Sdan ** pWin. Also, if parameter pBase is not NULL, set pWin->zBase to the
1246e7c9ca41Sdan ** equivalent nul-terminated string.
1247e7c9ca41Sdan */
sqlite3WindowAssemble(Parse * pParse,Window * pWin,ExprList * pPartition,ExprList * pOrderBy,Token * pBase)1248e7c9ca41Sdan Window *sqlite3WindowAssemble(
1249e7c9ca41Sdan   Parse *pParse,
1250e7c9ca41Sdan   Window *pWin,
1251e7c9ca41Sdan   ExprList *pPartition,
1252e7c9ca41Sdan   ExprList *pOrderBy,
1253e7c9ca41Sdan   Token *pBase
1254e7c9ca41Sdan ){
1255e7c9ca41Sdan   if( pWin ){
1256e7c9ca41Sdan     pWin->pPartition = pPartition;
1257e7c9ca41Sdan     pWin->pOrderBy = pOrderBy;
1258e7c9ca41Sdan     if( pBase ){
1259e7c9ca41Sdan       pWin->zBase = sqlite3DbStrNDup(pParse->db, pBase->z, pBase->n);
1260e7c9ca41Sdan     }
1261e7c9ca41Sdan   }else{
1262e7c9ca41Sdan     sqlite3ExprListDelete(pParse->db, pPartition);
1263e7c9ca41Sdan     sqlite3ExprListDelete(pParse->db, pOrderBy);
1264e7c9ca41Sdan   }
1265e7c9ca41Sdan   return pWin;
1266e7c9ca41Sdan }
1267e7c9ca41Sdan 
1268e7c9ca41Sdan /*
1269e7c9ca41Sdan ** Window *pWin has just been created from a WINDOW clause. Tokne pBase
1270e7c9ca41Sdan ** is the base window. Earlier windows from the same WINDOW clause are
1271e7c9ca41Sdan ** stored in the linked list starting at pWin->pNextWin. This function
1272e7c9ca41Sdan ** either updates *pWin according to the base specification, or else
1273e7c9ca41Sdan ** leaves an error in pParse.
1274e7c9ca41Sdan */
sqlite3WindowChain(Parse * pParse,Window * pWin,Window * pList)1275e7c9ca41Sdan void sqlite3WindowChain(Parse *pParse, Window *pWin, Window *pList){
1276e7c9ca41Sdan   if( pWin->zBase ){
1277e7c9ca41Sdan     sqlite3 *db = pParse->db;
1278e7c9ca41Sdan     Window *pExist = windowFind(pParse, pList, pWin->zBase);
1279e7c9ca41Sdan     if( pExist ){
1280e7c9ca41Sdan       const char *zErr = 0;
1281e7c9ca41Sdan       /* Check for errors */
1282e7c9ca41Sdan       if( pWin->pPartition ){
1283e7c9ca41Sdan         zErr = "PARTITION clause";
1284e7c9ca41Sdan       }else if( pExist->pOrderBy && pWin->pOrderBy ){
1285e7c9ca41Sdan         zErr = "ORDER BY clause";
1286e7c9ca41Sdan       }else if( pExist->bImplicitFrame==0 ){
1287e7c9ca41Sdan         zErr = "frame specification";
1288e7c9ca41Sdan       }
1289e7c9ca41Sdan       if( zErr ){
1290e7c9ca41Sdan         sqlite3ErrorMsg(pParse,
1291e7c9ca41Sdan             "cannot override %s of window: %s", zErr, pWin->zBase
1292e7c9ca41Sdan         );
1293e7c9ca41Sdan       }else{
1294e7c9ca41Sdan         pWin->pPartition = sqlite3ExprListDup(db, pExist->pPartition, 0);
1295e7c9ca41Sdan         if( pExist->pOrderBy ){
1296e7c9ca41Sdan           assert( pWin->pOrderBy==0 );
1297e7c9ca41Sdan           pWin->pOrderBy = sqlite3ExprListDup(db, pExist->pOrderBy, 0);
1298e7c9ca41Sdan         }
1299e7c9ca41Sdan         sqlite3DbFree(db, pWin->zBase);
1300e7c9ca41Sdan         pWin->zBase = 0;
1301e7c9ca41Sdan       }
1302e7c9ca41Sdan     }
1303e7c9ca41Sdan   }
1304e7c9ca41Sdan }
1305e7c9ca41Sdan 
1306e7c9ca41Sdan /*
1307c0bb4459Sdan ** Attach window object pWin to expression p.
1308c0bb4459Sdan */
sqlite3WindowAttach(Parse * pParse,Expr * p,Window * pWin)13094f9adee2Sdan void sqlite3WindowAttach(Parse *pParse, Expr *p, Window *pWin){
131086fb6e17Sdan   if( p ){
1311eda079cdSdrh     assert( p->op==TK_FUNCTION );
13124f9adee2Sdan     assert( pWin );
1313eda079cdSdrh     p->y.pWin = pWin;
1314eda079cdSdrh     ExprSetProperty(p, EP_WinFunc);
1315e33f6e7cSdan     pWin->pOwner = p;
13164f9adee2Sdan     if( (p->flags & EP_Distinct) && pWin->eFrmType!=TK_FILTER ){
1317e4984a2bSdrh       sqlite3ErrorMsg(pParse,
13184f9adee2Sdan           "DISTINCT is not supported for window functions"
13194f9adee2Sdan       );
1320e33f6e7cSdan     }
132186fb6e17Sdan   }else{
132286fb6e17Sdan     sqlite3WindowDelete(pParse->db, pWin);
132386fb6e17Sdan   }
132486fb6e17Sdan }
1325e2f781b9Sdan 
1326e2f781b9Sdan /*
1327a3fcc000Sdan ** Possibly link window pWin into the list at pSel->pWin (window functions
1328a3fcc000Sdan ** to be processed as part of SELECT statement pSel). The window is linked
1329a3fcc000Sdan ** in if either (a) there are no other windows already linked to this
1330a3fcc000Sdan ** SELECT, or (b) the windows already linked use a compatible window frame.
1331a3fcc000Sdan */
sqlite3WindowLink(Select * pSel,Window * pWin)1332a3fcc000Sdan void sqlite3WindowLink(Select *pSel, Window *pWin){
1333903fdd48Sdan   if( pSel ){
1334903fdd48Sdan     if( 0==pSel->pWin || 0==sqlite3WindowCompare(0, pSel->pWin, pWin, 0) ){
1335a3fcc000Sdan       pWin->pNextWin = pSel->pWin;
1336a3fcc000Sdan       if( pSel->pWin ){
1337a3fcc000Sdan         pSel->pWin->ppThis = &pWin->pNextWin;
1338a3fcc000Sdan       }
1339a3fcc000Sdan       pSel->pWin = pWin;
1340a3fcc000Sdan       pWin->ppThis = &pSel->pWin;
1341903fdd48Sdan     }else{
1342903fdd48Sdan       if( sqlite3ExprListCompare(pWin->pPartition, pSel->pWin->pPartition,-1) ){
1343903fdd48Sdan         pSel->selFlags |= SF_MultiPart;
1344903fdd48Sdan       }
1345903fdd48Sdan     }
1346a3fcc000Sdan   }
1347a3fcc000Sdan }
1348a3fcc000Sdan 
1349a3fcc000Sdan /*
1350fbb6e9ffSdan ** Return 0 if the two window objects are identical, 1 if they are
1351fbb6e9ffSdan ** different, or 2 if it cannot be determined if the objects are identical
1352fbb6e9ffSdan ** or not. Identical window objects can be processed in a single scan.
1353e2f781b9Sdan */
sqlite3WindowCompare(const Parse * pParse,const Window * p1,const Window * p2,int bFilter)13541580d50bSdrh int sqlite3WindowCompare(
13551580d50bSdrh   const Parse *pParse,
13561580d50bSdrh   const Window *p1,
13571580d50bSdrh   const Window *p2,
13581580d50bSdrh   int bFilter
13591580d50bSdrh ){
1360fbb6e9ffSdan   int res;
1361a2f142d0Sdrh   if( NEVER(p1==0) || NEVER(p2==0) ) return 1;
1362fc15f4c5Sdrh   if( p1->eFrmType!=p2->eFrmType ) return 1;
1363e2f781b9Sdan   if( p1->eStart!=p2->eStart ) return 1;
1364e2f781b9Sdan   if( p1->eEnd!=p2->eEnd ) return 1;
1365a0f6b833Sdan   if( p1->eExclude!=p2->eExclude ) return 1;
1366e2f781b9Sdan   if( sqlite3ExprCompare(pParse, p1->pStart, p2->pStart, -1) ) return 1;
1367e2f781b9Sdan   if( sqlite3ExprCompare(pParse, p1->pEnd, p2->pEnd, -1) ) return 1;
1368fbb6e9ffSdan   if( (res = sqlite3ExprListCompare(p1->pPartition, p2->pPartition, -1)) ){
1369fbb6e9ffSdan     return res;
1370fbb6e9ffSdan   }
1371fbb6e9ffSdan   if( (res = sqlite3ExprListCompare(p1->pOrderBy, p2->pOrderBy, -1)) ){
1372fbb6e9ffSdan     return res;
1373fbb6e9ffSdan   }
13744f9adee2Sdan   if( bFilter ){
1375fbb6e9ffSdan     if( (res = sqlite3ExprCompare(pParse, p1->pFilter, p2->pFilter, -1)) ){
1376fbb6e9ffSdan       return res;
1377fbb6e9ffSdan     }
13784f9adee2Sdan   }
1379e2f781b9Sdan   return 0;
1380e2f781b9Sdan }
1381e2f781b9Sdan 
138213078caaSdan 
138313078caaSdan /*
138413078caaSdan ** This is called by code in select.c before it calls sqlite3WhereBegin()
138513078caaSdan ** to begin iterating through the sub-query results. It is used to allocate
138613078caaSdan ** and initialize registers and cursors used by sqlite3WindowCodeStep().
138713078caaSdan */
sqlite3WindowCodeInit(Parse * pParse,Select * pSelect)13884ea562eeSdan void sqlite3WindowCodeInit(Parse *pParse, Select *pSelect){
13894ea562eeSdan   int nEphExpr = pSelect->pSrc->a[0].pSelect->pEList->nExpr;
13904ea562eeSdan   Window *pMWin = pSelect->pWin;
1391c9a8668aSdan   Window *pWin;
1392ec891fd4Sdan   Vdbe *v = sqlite3GetVdbe(pParse);
1393b6f2deacSdan 
13944ea562eeSdan   sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pMWin->iEphCsr, nEphExpr);
13954ea562eeSdan   sqlite3VdbeAddOp2(v, OP_OpenDup, pMWin->iEphCsr+1, pMWin->iEphCsr);
13964ea562eeSdan   sqlite3VdbeAddOp2(v, OP_OpenDup, pMWin->iEphCsr+2, pMWin->iEphCsr);
13974ea562eeSdan   sqlite3VdbeAddOp2(v, OP_OpenDup, pMWin->iEphCsr+3, pMWin->iEphCsr);
13984ea562eeSdan 
1399b6f2deacSdan   /* Allocate registers to use for PARTITION BY values, if any. Initialize
1400b6f2deacSdan   ** said registers to NULL.  */
1401b6f2deacSdan   if( pMWin->pPartition ){
1402b6f2deacSdan     int nExpr = pMWin->pPartition->nExpr;
140313078caaSdan     pMWin->regPart = pParse->nMem+1;
1404b6f2deacSdan     pParse->nMem += nExpr;
1405b6f2deacSdan     sqlite3VdbeAddOp3(v, OP_Null, 0, pMWin->regPart, pMWin->regPart+nExpr-1);
140613078caaSdan   }
140713078caaSdan 
1408bf84515aSdan   pMWin->regOne = ++pParse->nMem;
1409bf84515aSdan   sqlite3VdbeAddOp2(v, OP_Integer, 1, pMWin->regOne);
1410680f6e8eSdan 
1411a0f6b833Sdan   if( pMWin->eExclude ){
1412a0f6b833Sdan     pMWin->regStartRowid = ++pParse->nMem;
1413a0f6b833Sdan     pMWin->regEndRowid = ++pParse->nMem;
1414a0f6b833Sdan     pMWin->csrApp = pParse->nTab++;
1415a0f6b833Sdan     sqlite3VdbeAddOp2(v, OP_Integer, 1, pMWin->regStartRowid);
1416a0f6b833Sdan     sqlite3VdbeAddOp2(v, OP_Integer, 0, pMWin->regEndRowid);
1417a0f6b833Sdan     sqlite3VdbeAddOp2(v, OP_OpenDup, pMWin->csrApp, pMWin->iEphCsr);
1418a0f6b833Sdan     return;
1419a0f6b833Sdan   }
1420a0f6b833Sdan 
142113078caaSdan   for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
1422105dcaa5Sdrh     FuncDef *p = pWin->pWFunc;
1423ec891fd4Sdan     if( (p->funcFlags & SQLITE_FUNC_MINMAX) && pWin->eStart!=TK_UNBOUNDED ){
14249a94722dSdan       /* The inline versions of min() and max() require a single ephemeral
14259a94722dSdan       ** table and 3 registers. The registers are used as follows:
14269a94722dSdan       **
14279a94722dSdan       **   regApp+0: slot to copy min()/max() argument to for MakeRecord
14289a94722dSdan       **   regApp+1: integer value used to ensure keys are unique
14299a94722dSdan       **   regApp+2: output of MakeRecord
14309a94722dSdan       */
1431a4eeccdfSdrh       ExprList *pList;
1432a4eeccdfSdrh       KeyInfo *pKeyInfo;
1433a4eeccdfSdrh       assert( ExprUseXList(pWin->pOwner) );
1434a4eeccdfSdrh       pList = pWin->pOwner->x.pList;
1435a4eeccdfSdrh       pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pList, 0, 0);
1436c9a8668aSdan       pWin->csrApp = pParse->nTab++;
1437c9a8668aSdan       pWin->regApp = pParse->nMem+1;
1438c9a8668aSdan       pParse->nMem += 3;
1439105dcaa5Sdrh       if( pKeyInfo && pWin->pWFunc->zName[1]=='i' ){
14406e11892dSdan         assert( pKeyInfo->aSortFlags[0]==0 );
14416e11892dSdan         pKeyInfo->aSortFlags[0] = KEYINFO_ORDER_DESC;
1442c9a8668aSdan       }
1443c9a8668aSdan       sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pWin->csrApp, 2);
1444c9a8668aSdan       sqlite3VdbeAppendP4(v, pKeyInfo, P4_KEYINFO);
1445c9a8668aSdan       sqlite3VdbeAddOp2(v, OP_Integer, 0, pWin->regApp+1);
1446c9a8668aSdan     }
144719dc4d40Sdrh     else if( p->zName==nth_valueName || p->zName==first_valueName ){
1448ec891fd4Sdan       /* Allocate two registers at pWin->regApp. These will be used to
1449ec891fd4Sdan       ** store the start and end index of the current frame.  */
1450ec891fd4Sdan       pWin->regApp = pParse->nMem+1;
1451ec891fd4Sdan       pWin->csrApp = pParse->nTab++;
1452ec891fd4Sdan       pParse->nMem += 2;
1453ec891fd4Sdan       sqlite3VdbeAddOp2(v, OP_OpenDup, pWin->csrApp, pMWin->iEphCsr);
1454ec891fd4Sdan     }
145519dc4d40Sdrh     else if( p->zName==leadName || p->zName==lagName ){
1456fe4e25a0Sdan       pWin->csrApp = pParse->nTab++;
1457fe4e25a0Sdan       sqlite3VdbeAddOp2(v, OP_OpenDup, pWin->csrApp, pMWin->iEphCsr);
1458fe4e25a0Sdan     }
1459c9a8668aSdan   }
1460c9a8668aSdan }
1461c9a8668aSdan 
1462bb407278Sdan #define WINDOW_STARTING_INT  0
1463bb407278Sdan #define WINDOW_ENDING_INT    1
1464bb407278Sdan #define WINDOW_NTH_VALUE_INT 2
1465bb407278Sdan #define WINDOW_STARTING_NUM  3
1466bb407278Sdan #define WINDOW_ENDING_NUM    4
1467bb407278Sdan 
146813078caaSdan /*
1469a1a7e112Sdan ** A "PRECEDING <expr>" (eCond==0) or "FOLLOWING <expr>" (eCond==1) or the
1470a1a7e112Sdan ** value of the second argument to nth_value() (eCond==2) has just been
1471a1a7e112Sdan ** evaluated and the result left in register reg. This function generates VM
1472a1a7e112Sdan ** code to check that the value is a non-negative integer and throws an
1473a1a7e112Sdan ** exception if it is not.
147413078caaSdan */
windowCheckValue(Parse * pParse,int reg,int eCond)1475bb407278Sdan static void windowCheckValue(Parse *pParse, int reg, int eCond){
1476c3a20c19Sdan   static const char *azErr[] = {
1477c3a20c19Sdan     "frame starting offset must be a non-negative integer",
1478a1a7e112Sdan     "frame ending offset must be a non-negative integer",
1479bb407278Sdan     "second argument to nth_value must be a positive integer",
1480bb407278Sdan     "frame starting offset must be a non-negative number",
1481bb407278Sdan     "frame ending offset must be a non-negative number",
1482c3a20c19Sdan   };
1483bb407278Sdan   static int aOp[] = { OP_Ge, OP_Ge, OP_Gt, OP_Ge, OP_Ge };
1484c3a20c19Sdan   Vdbe *v = sqlite3GetVdbe(pParse);
148513078caaSdan   int regZero = sqlite3GetTempReg(pParse);
1486bb407278Sdan   assert( eCond>=0 && eCond<ArraySize(azErr) );
1487c3a20c19Sdan   sqlite3VdbeAddOp2(v, OP_Integer, 0, regZero);
1488e5166e07Sdan   if( eCond>=WINDOW_STARTING_NUM ){
1489e5166e07Sdan     int regString = sqlite3GetTempReg(pParse);
1490e5166e07Sdan     sqlite3VdbeAddOp4(v, OP_String8, 0, regString, 0, "", P4_STATIC);
1491e5166e07Sdan     sqlite3VdbeAddOp3(v, OP_Ge, regString, sqlite3VdbeCurrentAddr(v)+2, reg);
149221826f44Sdrh     sqlite3VdbeChangeP5(v, SQLITE_AFF_NUMERIC|SQLITE_JUMPIFNULL);
14936f88359dSdrh     VdbeCoverage(v);
14946f88359dSdrh     assert( eCond==3 || eCond==4 );
14956f88359dSdrh     VdbeCoverageIf(v, eCond==3);
14966f88359dSdrh     VdbeCoverageIf(v, eCond==4);
1497e5166e07Sdan   }else{
1498c3a20c19Sdan     sqlite3VdbeAddOp2(v, OP_MustBeInt, reg, sqlite3VdbeCurrentAddr(v)+2);
14996f88359dSdrh     VdbeCoverage(v);
15006f88359dSdrh     assert( eCond==0 || eCond==1 || eCond==2 );
15010b3b0dd1Sdrh     VdbeCoverageIf(v, eCond==0);
15020b3b0dd1Sdrh     VdbeCoverageIf(v, eCond==1);
15030b3b0dd1Sdrh     VdbeCoverageIf(v, eCond==2);
15046f88359dSdrh   }
1505a1a7e112Sdan   sqlite3VdbeAddOp3(v, aOp[eCond], regZero, sqlite3VdbeCurrentAddr(v)+2, reg);
1506b03786adSdan   sqlite3VdbeChangeP5(v, SQLITE_AFF_NUMERIC);
150721826f44Sdrh   VdbeCoverageNeverNullIf(v, eCond==0); /* NULL case captured by */
150821826f44Sdrh   VdbeCoverageNeverNullIf(v, eCond==1); /*   the OP_MustBeInt */
150921826f44Sdrh   VdbeCoverageNeverNullIf(v, eCond==2);
151021826f44Sdrh   VdbeCoverageNeverNullIf(v, eCond==3); /* NULL case caught by */
151121826f44Sdrh   VdbeCoverageNeverNullIf(v, eCond==4); /*   the OP_Ge */
1512211a0857Sdrh   sqlite3MayAbort(pParse);
1513c3a20c19Sdan   sqlite3VdbeAddOp2(v, OP_Halt, SQLITE_ERROR, OE_Abort);
1514a1a7e112Sdan   sqlite3VdbeAppendP4(v, (void*)azErr[eCond], P4_STATIC);
151513078caaSdan   sqlite3ReleaseTempReg(pParse, regZero);
1516c3a20c19Sdan }
1517c3a20c19Sdan 
151813078caaSdan /*
151913078caaSdan ** Return the number of arguments passed to the window-function associated
152013078caaSdan ** with the object passed as the only argument to this function.
152113078caaSdan */
windowArgCount(Window * pWin)15222a11bb23Sdan static int windowArgCount(Window *pWin){
1523a4eeccdfSdrh   const ExprList *pList;
1524a4eeccdfSdrh   assert( ExprUseXList(pWin->pOwner) );
1525a4eeccdfSdrh   pList = pWin->pOwner->x.pList;
15262a11bb23Sdan   return (pList ? pList->nExpr : 0);
15272a11bb23Sdan }
15282a11bb23Sdan 
1529c782a81aSdan typedef struct WindowCodeArg WindowCodeArg;
1530c782a81aSdan typedef struct WindowCsrAndReg WindowCsrAndReg;
15311cac1766Sdan 
15321cac1766Sdan /*
15331cac1766Sdan ** See comments above struct WindowCodeArg.
15341cac1766Sdan */
1535c782a81aSdan struct WindowCsrAndReg {
15361cac1766Sdan   int csr;                        /* Cursor number */
15371cac1766Sdan   int reg;                        /* First in array of peer values */
1538c782a81aSdan };
1539c782a81aSdan 
15401cac1766Sdan /*
15411cac1766Sdan ** A single instance of this structure is allocated on the stack by
15421cac1766Sdan ** sqlite3WindowCodeStep() and a pointer to it passed to the various helper
15431cac1766Sdan ** routines. This is to reduce the number of arguments required by each
15441cac1766Sdan ** helper function.
15451cac1766Sdan **
15461cac1766Sdan ** regArg:
15471cac1766Sdan **   Each window function requires an accumulator register (just as an
15481cac1766Sdan **   ordinary aggregate function does). This variable is set to the first
15491cac1766Sdan **   in an array of accumulator registers - one for each window function
15501cac1766Sdan **   in the WindowCodeArg.pMWin list.
15511cac1766Sdan **
15521cac1766Sdan ** eDelete:
15531cac1766Sdan **   The window functions implementation sometimes caches the input rows
15541cac1766Sdan **   that it processes in a temporary table. If it is not zero, this
15551cac1766Sdan **   variable indicates when rows may be removed from the temp table (in
15561cac1766Sdan **   order to reduce memory requirements - it would always be safe just
15571cac1766Sdan **   to leave them there). Possible values for eDelete are:
15581cac1766Sdan **
15591cac1766Sdan **      WINDOW_RETURN_ROW:
15601cac1766Sdan **        An input row can be discarded after it is returned to the caller.
15611cac1766Sdan **
15621cac1766Sdan **      WINDOW_AGGINVERSE:
15631cac1766Sdan **        An input row can be discarded after the window functions xInverse()
15641cac1766Sdan **        callbacks have been invoked in it.
15651cac1766Sdan **
15661cac1766Sdan **      WINDOW_AGGSTEP:
15671cac1766Sdan **        An input row can be discarded after the window functions xStep()
15681cac1766Sdan **        callbacks have been invoked in it.
15691cac1766Sdan **
15701cac1766Sdan ** start,current,end
15711cac1766Sdan **   Consider a window-frame similar to the following:
15721cac1766Sdan **
15731cac1766Sdan **     (ORDER BY a, b GROUPS BETWEEN 2 PRECEDING AND 2 FOLLOWING)
15741cac1766Sdan **
15751cac1766Sdan **   The windows functions implmentation caches the input rows in a temp
15761cac1766Sdan **   table, sorted by "a, b" (it actually populates the cache lazily, and
15771cac1766Sdan **   aggressively removes rows once they are no longer required, but that's
15781cac1766Sdan **   a mere detail). It keeps three cursors open on the temp table. One
15791cac1766Sdan **   (current) that points to the next row to return to the query engine
15801cac1766Sdan **   once its window function values have been calculated. Another (end)
15811cac1766Sdan **   points to the next row to call the xStep() method of each window function
15821cac1766Sdan **   on (so that it is 2 groups ahead of current). And a third (start) that
15831cac1766Sdan **   points to the next row to call the xInverse() method of each window
15841cac1766Sdan **   function on.
15851cac1766Sdan **
15861cac1766Sdan **   Each cursor (start, current and end) consists of a VDBE cursor
15871cac1766Sdan **   (WindowCsrAndReg.csr) and an array of registers (starting at
15881cac1766Sdan **   WindowCodeArg.reg) that always contains a copy of the peer values
15891cac1766Sdan **   read from the corresponding cursor.
15901cac1766Sdan **
15911cac1766Sdan **   Depending on the window-frame in question, all three cursors may not
15921cac1766Sdan **   be required. In this case both WindowCodeArg.csr and reg are set to
15931cac1766Sdan **   0.
15941cac1766Sdan */
1595c782a81aSdan struct WindowCodeArg {
15961cac1766Sdan   Parse *pParse;             /* Parse context */
15971cac1766Sdan   Window *pMWin;             /* First in list of functions being processed */
15981cac1766Sdan   Vdbe *pVdbe;               /* VDBE object */
15991cac1766Sdan   int addrGosub;             /* OP_Gosub to this address to return one row */
16001cac1766Sdan   int regGosub;              /* Register used with OP_Gosub(addrGosub) */
16011cac1766Sdan   int regArg;                /* First in array of accumulator registers */
16021cac1766Sdan   int eDelete;               /* See above */
1603113a33c5Sdrh   int regRowid;
1604c782a81aSdan 
1605c782a81aSdan   WindowCsrAndReg start;
1606c782a81aSdan   WindowCsrAndReg current;
1607c782a81aSdan   WindowCsrAndReg end;
1608c782a81aSdan };
1609c782a81aSdan 
1610c782a81aSdan /*
1611c782a81aSdan ** Generate VM code to read the window frames peer values from cursor csr into
1612c782a81aSdan ** an array of registers starting at reg.
1613c782a81aSdan */
windowReadPeerValues(WindowCodeArg * p,int csr,int reg)1614c782a81aSdan static void windowReadPeerValues(
1615c782a81aSdan   WindowCodeArg *p,
1616c782a81aSdan   int csr,
1617c782a81aSdan   int reg
1618c782a81aSdan ){
1619c782a81aSdan   Window *pMWin = p->pMWin;
1620c782a81aSdan   ExprList *pOrderBy = pMWin->pOrderBy;
1621c782a81aSdan   if( pOrderBy ){
1622c782a81aSdan     Vdbe *v = sqlite3GetVdbe(p->pParse);
1623c782a81aSdan     ExprList *pPart = pMWin->pPartition;
1624c782a81aSdan     int iColOff = pMWin->nBufferCol + (pPart ? pPart->nExpr : 0);
1625c782a81aSdan     int i;
1626c782a81aSdan     for(i=0; i<pOrderBy->nExpr; i++){
1627c782a81aSdan       sqlite3VdbeAddOp3(v, OP_Column, csr, iColOff+i, reg+i);
1628c782a81aSdan     }
1629c782a81aSdan   }
1630c782a81aSdan }
1631c782a81aSdan 
163213078caaSdan /*
163337d296a7Sdan ** Generate VM code to invoke either xStep() (if bInverse is 0) or
163437d296a7Sdan ** xInverse (if bInverse is non-zero) for each window function in the
163537d296a7Sdan ** linked list starting at pMWin. Or, for built-in window functions
163637d296a7Sdan ** that do not use the standard function API, generate the required
163737d296a7Sdan ** inline VM code.
163837d296a7Sdan **
163937d296a7Sdan ** If argument csr is greater than or equal to 0, then argument reg is
164037d296a7Sdan ** the first register in an array of registers guaranteed to be large
164137d296a7Sdan ** enough to hold the array of arguments for each function. In this case
164237d296a7Sdan ** the arguments are extracted from the current row of csr into the
164337d296a7Sdan ** array of registers before invoking OP_AggStep or OP_AggInverse
164437d296a7Sdan **
164537d296a7Sdan ** Or, if csr is less than zero, then the array of registers at reg is
164637d296a7Sdan ** already populated with all columns from the current row of the sub-query.
164737d296a7Sdan **
164837d296a7Sdan ** If argument regPartSize is non-zero, then it is a register containing the
164937d296a7Sdan ** number of rows in the current partition.
165037d296a7Sdan */
windowAggStep(WindowCodeArg * p,Window * pMWin,int csr,int bInverse,int reg)165137d296a7Sdan static void windowAggStep(
165237d296a7Sdan   WindowCodeArg *p,
165337d296a7Sdan   Window *pMWin,                  /* Linked list of window functions */
165437d296a7Sdan   int csr,                        /* Read arguments from this cursor */
165537d296a7Sdan   int bInverse,                   /* True to invoke xInverse instead of xStep */
165637d296a7Sdan   int reg                         /* Array of registers */
165737d296a7Sdan ){
165837d296a7Sdan   Parse *pParse = p->pParse;
165937d296a7Sdan   Vdbe *v = sqlite3GetVdbe(pParse);
166037d296a7Sdan   Window *pWin;
166137d296a7Sdan   for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
1662105dcaa5Sdrh     FuncDef *pFunc = pWin->pWFunc;
166337d296a7Sdan     int regArg;
166437d296a7Sdan     int nArg = pWin->bExprArgs ? 0 : windowArgCount(pWin);
166537d296a7Sdan     int i;
166637d296a7Sdan 
166737d296a7Sdan     assert( bInverse==0 || pWin->eStart!=TK_UNBOUNDED );
166837d296a7Sdan 
1669c5b35ae5Sdrh     /* All OVER clauses in the same window function aggregate step must
1670c5b35ae5Sdrh     ** be the same. */
1671fbb6e9ffSdan     assert( pWin==pMWin || sqlite3WindowCompare(pParse,pWin,pMWin,0)!=1 );
1672c5b35ae5Sdrh 
167337d296a7Sdan     for(i=0; i<nArg; i++){
167437d296a7Sdan       if( i!=1 || pFunc->zName!=nth_valueName ){
167537d296a7Sdan         sqlite3VdbeAddOp3(v, OP_Column, csr, pWin->iArgCol+i, reg+i);
167637d296a7Sdan       }else{
167737d296a7Sdan         sqlite3VdbeAddOp3(v, OP_Column, pMWin->iEphCsr, pWin->iArgCol+i, reg+i);
167837d296a7Sdan       }
167937d296a7Sdan     }
168037d296a7Sdan     regArg = reg;
168137d296a7Sdan 
168237d296a7Sdan     if( pMWin->regStartRowid==0
168337d296a7Sdan      && (pFunc->funcFlags & SQLITE_FUNC_MINMAX)
168437d296a7Sdan      && (pWin->eStart!=TK_UNBOUNDED)
168537d296a7Sdan     ){
168637d296a7Sdan       int addrIsNull = sqlite3VdbeAddOp1(v, OP_IsNull, regArg);
168737d296a7Sdan       VdbeCoverage(v);
168837d296a7Sdan       if( bInverse==0 ){
168937d296a7Sdan         sqlite3VdbeAddOp2(v, OP_AddImm, pWin->regApp+1, 1);
169037d296a7Sdan         sqlite3VdbeAddOp2(v, OP_SCopy, regArg, pWin->regApp);
169137d296a7Sdan         sqlite3VdbeAddOp3(v, OP_MakeRecord, pWin->regApp, 2, pWin->regApp+2);
169237d296a7Sdan         sqlite3VdbeAddOp2(v, OP_IdxInsert, pWin->csrApp, pWin->regApp+2);
169337d296a7Sdan       }else{
169437d296a7Sdan         sqlite3VdbeAddOp4Int(v, OP_SeekGE, pWin->csrApp, 0, regArg, 1);
169537d296a7Sdan         VdbeCoverageNeverTaken(v);
169637d296a7Sdan         sqlite3VdbeAddOp1(v, OP_Delete, pWin->csrApp);
169737d296a7Sdan         sqlite3VdbeJumpHere(v, sqlite3VdbeCurrentAddr(v)-2);
169837d296a7Sdan       }
169937d296a7Sdan       sqlite3VdbeJumpHere(v, addrIsNull);
170037d296a7Sdan     }else if( pWin->regApp ){
170137d296a7Sdan       assert( pFunc->zName==nth_valueName
170237d296a7Sdan            || pFunc->zName==first_valueName
170337d296a7Sdan       );
170437d296a7Sdan       assert( bInverse==0 || bInverse==1 );
170537d296a7Sdan       sqlite3VdbeAddOp2(v, OP_AddImm, pWin->regApp+1-bInverse, 1);
170637d296a7Sdan     }else if( pFunc->xSFunc!=noopStepFunc ){
170737d296a7Sdan       int addrIf = 0;
170837d296a7Sdan       if( pWin->pFilter ){
170937d296a7Sdan         int regTmp;
1710a4eeccdfSdrh         assert( ExprUseXList(pWin->pOwner) );
171137d296a7Sdan         assert( pWin->bExprArgs || !nArg ||nArg==pWin->pOwner->x.pList->nExpr );
171237d296a7Sdan         assert( pWin->bExprArgs || nArg  ||pWin->pOwner->x.pList==0 );
171337d296a7Sdan         regTmp = sqlite3GetTempReg(pParse);
171437d296a7Sdan         sqlite3VdbeAddOp3(v, OP_Column, csr, pWin->iArgCol+nArg,regTmp);
171537d296a7Sdan         addrIf = sqlite3VdbeAddOp3(v, OP_IfNot, regTmp, 0, 1);
171637d296a7Sdan         VdbeCoverage(v);
171737d296a7Sdan         sqlite3ReleaseTempReg(pParse, regTmp);
171837d296a7Sdan       }
171937d296a7Sdan 
172037d296a7Sdan       if( pWin->bExprArgs ){
17215a9fd231Sdan         int iOp = sqlite3VdbeCurrentAddr(v);
17225a9fd231Sdan         int iEnd;
172337d296a7Sdan 
1724a4eeccdfSdrh         assert( ExprUseXList(pWin->pOwner) );
172537d296a7Sdan         nArg = pWin->pOwner->x.pList->nExpr;
172637d296a7Sdan         regArg = sqlite3GetTempRange(pParse, nArg);
172737d296a7Sdan         sqlite3ExprCodeExprList(pParse, pWin->pOwner->x.pList, regArg, 0, 0);
172837d296a7Sdan 
17295a9fd231Sdan         for(iEnd=sqlite3VdbeCurrentAddr(v); iOp<iEnd; iOp++){
17305a9fd231Sdan           VdbeOp *pOp = sqlite3VdbeGetOp(v, iOp);
173141150bf3Sdan           if( pOp->opcode==OP_Column && pOp->p1==pMWin->iEphCsr ){
173237d296a7Sdan             pOp->p1 = csr;
173337d296a7Sdan           }
173437d296a7Sdan         }
173537d296a7Sdan       }
173637d296a7Sdan       if( pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL ){
173737d296a7Sdan         CollSeq *pColl;
173837d296a7Sdan         assert( nArg>0 );
1739a4eeccdfSdrh         assert( ExprUseXList(pWin->pOwner) );
174037d296a7Sdan         pColl = sqlite3ExprNNCollSeq(pParse, pWin->pOwner->x.pList->a[0].pExpr);
174137d296a7Sdan         sqlite3VdbeAddOp4(v, OP_CollSeq, 0,0,0, (const char*)pColl, P4_COLLSEQ);
174237d296a7Sdan       }
174337d296a7Sdan       sqlite3VdbeAddOp3(v, bInverse? OP_AggInverse : OP_AggStep,
174437d296a7Sdan                         bInverse, regArg, pWin->regAccum);
174537d296a7Sdan       sqlite3VdbeAppendP4(v, pFunc, P4_FUNCDEF);
174637d296a7Sdan       sqlite3VdbeChangeP5(v, (u8)nArg);
174737d296a7Sdan       if( pWin->bExprArgs ){
174837d296a7Sdan         sqlite3ReleaseTempRange(pParse, regArg, nArg);
174937d296a7Sdan       }
175037d296a7Sdan       if( addrIf ) sqlite3VdbeJumpHere(v, addrIf);
175137d296a7Sdan     }
175237d296a7Sdan   }
175337d296a7Sdan }
175437d296a7Sdan 
175537d296a7Sdan /*
175637d296a7Sdan ** Values that may be passed as the second argument to windowCodeOp().
175737d296a7Sdan */
175837d296a7Sdan #define WINDOW_RETURN_ROW 1
175937d296a7Sdan #define WINDOW_AGGINVERSE 2
176037d296a7Sdan #define WINDOW_AGGSTEP    3
176137d296a7Sdan 
176237d296a7Sdan /*
1763a0f6b833Sdan ** Generate VM code to invoke either xValue() (bFin==0) or xFinalize()
1764a0f6b833Sdan ** (bFin==1) for each window function in the linked list starting at
176513078caaSdan ** pMWin. Or, for built-in window-functions that do not use the standard
176613078caaSdan ** API, generate the equivalent VM code.
176713078caaSdan */
windowAggFinal(WindowCodeArg * p,int bFin)1768c782a81aSdan static void windowAggFinal(WindowCodeArg *p, int bFin){
1769c782a81aSdan   Parse *pParse = p->pParse;
1770c782a81aSdan   Window *pMWin = p->pMWin;
1771d6f784efSdan   Vdbe *v = sqlite3GetVdbe(pParse);
1772d6f784efSdan   Window *pWin;
1773d6f784efSdan 
1774a0f6b833Sdan   for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
1775a0f6b833Sdan     if( pMWin->regStartRowid==0
1776105dcaa5Sdrh      && (pWin->pWFunc->funcFlags & SQLITE_FUNC_MINMAX)
1777a0f6b833Sdan      && (pWin->eStart!=TK_UNBOUNDED)
1778ec891fd4Sdan     ){
1779c9a8668aSdan       sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regResult);
1780c9a8668aSdan       sqlite3VdbeAddOp1(v, OP_Last, pWin->csrApp);
178101e12290Sdan       VdbeCoverage(v);
1782c9a8668aSdan       sqlite3VdbeAddOp3(v, OP_Column, pWin->csrApp, 0, pWin->regResult);
1783c9a8668aSdan       sqlite3VdbeJumpHere(v, sqlite3VdbeCurrentAddr(v)-2);
1784ec891fd4Sdan     }else if( pWin->regApp ){
1785a0f6b833Sdan       assert( pMWin->regStartRowid==0 );
1786c9a8668aSdan     }else{
1787a0f6b833Sdan       int nArg = windowArgCount(pWin);
1788a0f6b833Sdan       if( bFin ){
1789a0f6b833Sdan         sqlite3VdbeAddOp2(v, OP_AggFinal, pWin->regAccum, nArg);
1790105dcaa5Sdrh         sqlite3VdbeAppendP4(v, pWin->pWFunc, P4_FUNCDEF);
1791d6f784efSdan         sqlite3VdbeAddOp2(v, OP_Copy, pWin->regAccum, pWin->regResult);
17928b98560dSdan         sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regAccum);
1793d6f784efSdan       }else{
1794a0f6b833Sdan         sqlite3VdbeAddOp3(v, OP_AggValue,pWin->regAccum,nArg,pWin->regResult);
1795105dcaa5Sdrh         sqlite3VdbeAppendP4(v, pWin->pWFunc, P4_FUNCDEF);
1796d6f784efSdan       }
1797d6f784efSdan     }
1798d6f784efSdan   }
1799c9a8668aSdan }
1800d6f784efSdan 
18010525b6f4Sdan /*
18020525b6f4Sdan ** Generate code to calculate the current values of all window functions in the
18030525b6f4Sdan ** p->pMWin list by doing a full scan of the current window frame. Store the
18040525b6f4Sdan ** results in the Window.regResult registers, ready to return the upper
18050525b6f4Sdan ** layer.
18060525b6f4Sdan */
windowFullScan(WindowCodeArg * p)1807c782a81aSdan static void windowFullScan(WindowCodeArg *p){
1808c782a81aSdan   Window *pWin;
1809c782a81aSdan   Parse *pParse = p->pParse;
1810c782a81aSdan   Window *pMWin = p->pMWin;
1811c782a81aSdan   Vdbe *v = p->pVdbe;
1812c782a81aSdan 
1813c782a81aSdan   int regCRowid = 0;              /* Current rowid value */
1814c782a81aSdan   int regCPeer = 0;               /* Current peer values */
1815c782a81aSdan   int regRowid = 0;               /* AggStep rowid value */
1816c782a81aSdan   int regPeer = 0;                /* AggStep peer values */
1817c782a81aSdan 
1818c782a81aSdan   int nPeer;
1819c782a81aSdan   int lblNext;
1820c782a81aSdan   int lblBrk;
1821c782a81aSdan   int addrNext;
182255f66b34Sdrh   int csr;
1823c782a81aSdan 
182437d296a7Sdan   VdbeModuleComment((v, "windowFullScan begin"));
182537d296a7Sdan 
182655f66b34Sdrh   assert( pMWin!=0 );
182755f66b34Sdrh   csr = pMWin->csrApp;
1828c782a81aSdan   nPeer = (pMWin->pOrderBy ? pMWin->pOrderBy->nExpr : 0);
1829c782a81aSdan 
1830c782a81aSdan   lblNext = sqlite3VdbeMakeLabel(pParse);
1831c782a81aSdan   lblBrk = sqlite3VdbeMakeLabel(pParse);
1832c782a81aSdan 
1833c782a81aSdan   regCRowid = sqlite3GetTempReg(pParse);
1834c782a81aSdan   regRowid = sqlite3GetTempReg(pParse);
1835c782a81aSdan   if( nPeer ){
1836c782a81aSdan     regCPeer = sqlite3GetTempRange(pParse, nPeer);
1837c782a81aSdan     regPeer = sqlite3GetTempRange(pParse, nPeer);
1838c782a81aSdan   }
1839c782a81aSdan 
1840c782a81aSdan   sqlite3VdbeAddOp2(v, OP_Rowid, pMWin->iEphCsr, regCRowid);
1841c782a81aSdan   windowReadPeerValues(p, pMWin->iEphCsr, regCPeer);
1842c782a81aSdan 
1843c782a81aSdan   for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
1844c782a81aSdan     sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regAccum);
1845c782a81aSdan   }
1846c782a81aSdan 
1847c782a81aSdan   sqlite3VdbeAddOp3(v, OP_SeekGE, csr, lblBrk, pMWin->regStartRowid);
18481d4b25faSdan   VdbeCoverage(v);
1849c782a81aSdan   addrNext = sqlite3VdbeCurrentAddr(v);
1850c782a81aSdan   sqlite3VdbeAddOp2(v, OP_Rowid, csr, regRowid);
1851c782a81aSdan   sqlite3VdbeAddOp3(v, OP_Gt, pMWin->regEndRowid, lblBrk, regRowid);
18521d4b25faSdan   VdbeCoverageNeverNull(v);
1853108e6b2cSdan 
1854c782a81aSdan   if( pMWin->eExclude==TK_CURRENT ){
1855c782a81aSdan     sqlite3VdbeAddOp3(v, OP_Eq, regCRowid, lblNext, regRowid);
185683c5bb99Sdrh     VdbeCoverageNeverNull(v);
1857c782a81aSdan   }else if( pMWin->eExclude!=TK_NO ){
1858c782a81aSdan     int addr;
1859108e6b2cSdan     int addrEq = 0;
18606603342fSdan     KeyInfo *pKeyInfo = 0;
1861108e6b2cSdan 
18626603342fSdan     if( pMWin->pOrderBy ){
1863108e6b2cSdan       pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pMWin->pOrderBy, 0, 0);
1864c782a81aSdan     }
18656603342fSdan     if( pMWin->eExclude==TK_TIES ){
18666603342fSdan       addrEq = sqlite3VdbeAddOp3(v, OP_Eq, regCRowid, 0, regRowid);
186783c5bb99Sdrh       VdbeCoverageNeverNull(v);
18686603342fSdan     }
18696603342fSdan     if( pKeyInfo ){
1870c782a81aSdan       windowReadPeerValues(p, csr, regPeer);
1871c782a81aSdan       sqlite3VdbeAddOp3(v, OP_Compare, regPeer, regCPeer, nPeer);
1872c782a81aSdan       sqlite3VdbeAppendP4(v, (void*)pKeyInfo, P4_KEYINFO);
1873c782a81aSdan       addr = sqlite3VdbeCurrentAddr(v)+1;
1874c782a81aSdan       sqlite3VdbeAddOp3(v, OP_Jump, addr, lblNext, addr);
1875c782a81aSdan       VdbeCoverageEqNe(v);
18766603342fSdan     }else{
18776603342fSdan       sqlite3VdbeAddOp2(v, OP_Goto, 0, lblNext);
18786603342fSdan     }
1879c782a81aSdan     if( addrEq ) sqlite3VdbeJumpHere(v, addrEq);
1880c782a81aSdan   }
1881c782a81aSdan 
188237d296a7Sdan   windowAggStep(p, pMWin, csr, 0, p->regArg);
1883c782a81aSdan 
1884c782a81aSdan   sqlite3VdbeResolveLabel(v, lblNext);
1885c782a81aSdan   sqlite3VdbeAddOp2(v, OP_Next, csr, addrNext);
18861d4b25faSdan   VdbeCoverage(v);
1887c782a81aSdan   sqlite3VdbeJumpHere(v, addrNext-1);
1888c782a81aSdan   sqlite3VdbeJumpHere(v, addrNext+1);
1889c782a81aSdan   sqlite3ReleaseTempReg(pParse, regRowid);
1890c782a81aSdan   sqlite3ReleaseTempReg(pParse, regCRowid);
1891c782a81aSdan   if( nPeer ){
1892c782a81aSdan     sqlite3ReleaseTempRange(pParse, regPeer, nPeer);
1893c782a81aSdan     sqlite3ReleaseTempRange(pParse, regCPeer, nPeer);
1894c782a81aSdan   }
1895c782a81aSdan 
1896c782a81aSdan   windowAggFinal(p, 1);
189737d296a7Sdan   VdbeModuleComment((v, "windowFullScan end"));
1898c782a81aSdan }
1899c782a81aSdan 
190013078caaSdan /*
190113078caaSdan ** Invoke the sub-routine at regGosub (generated by code in select.c) to
190213078caaSdan ** return the current row of Window.iEphCsr. If all window functions are
190313078caaSdan ** aggregate window functions that use the standard API, a single
190413078caaSdan ** OP_Gosub instruction is all that this routine generates. Extra VM code
190513078caaSdan ** for per-row processing is only generated for the following built-in window
190613078caaSdan ** functions:
190713078caaSdan **
190813078caaSdan **   nth_value()
190913078caaSdan **   first_value()
191013078caaSdan **   lag()
191113078caaSdan **   lead()
191213078caaSdan */
windowReturnOneRow(WindowCodeArg * p)1913c782a81aSdan static void windowReturnOneRow(WindowCodeArg *p){
1914c782a81aSdan   Window *pMWin = p->pMWin;
1915c782a81aSdan   Vdbe *v = p->pVdbe;
1916c782a81aSdan 
1917c782a81aSdan   if( pMWin->regStartRowid ){
1918c782a81aSdan     windowFullScan(p);
1919c782a81aSdan   }else{
1920c782a81aSdan     Parse *pParse = p->pParse;
1921ec891fd4Sdan     Window *pWin;
1922c782a81aSdan 
1923ec891fd4Sdan     for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
1924105dcaa5Sdrh       FuncDef *pFunc = pWin->pWFunc;
1925a4eeccdfSdrh       assert( ExprUseXList(pWin->pOwner) );
192619dc4d40Sdrh       if( pFunc->zName==nth_valueName
192719dc4d40Sdrh        || pFunc->zName==first_valueName
19287095c002Sdan       ){
1929c782a81aSdan         int csr = pWin->csrApp;
1930ec4ccdbcSdrh         int lbl = sqlite3VdbeMakeLabel(pParse);
1931ec891fd4Sdan         int tmpReg = sqlite3GetTempReg(pParse);
1932ec891fd4Sdan         sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regResult);
19337095c002Sdan 
193419dc4d40Sdrh         if( pFunc->zName==nth_valueName ){
19356fde1799Sdan           sqlite3VdbeAddOp3(v, OP_Column,pMWin->iEphCsr,pWin->iArgCol+1,tmpReg);
1936bb407278Sdan           windowCheckValue(pParse, tmpReg, 2);
19377095c002Sdan         }else{
19387095c002Sdan           sqlite3VdbeAddOp2(v, OP_Integer, 1, tmpReg);
19397095c002Sdan         }
1940ec891fd4Sdan         sqlite3VdbeAddOp3(v, OP_Add, tmpReg, pWin->regApp, tmpReg);
1941ec891fd4Sdan         sqlite3VdbeAddOp3(v, OP_Gt, pWin->regApp+1, lbl, tmpReg);
19426ccbd278Sdrh         VdbeCoverageNeverNull(v);
19439341916eSdrh         sqlite3VdbeAddOp3(v, OP_SeekRowid, csr, 0, tmpReg);
19449341916eSdrh         VdbeCoverageNeverTaken(v);
1945ec891fd4Sdan         sqlite3VdbeAddOp3(v, OP_Column, csr, pWin->iArgCol, pWin->regResult);
1946ec891fd4Sdan         sqlite3VdbeResolveLabel(v, lbl);
1947ec891fd4Sdan         sqlite3ReleaseTempReg(pParse, tmpReg);
1948ec891fd4Sdan       }
194919dc4d40Sdrh       else if( pFunc->zName==leadName || pFunc->zName==lagName ){
19502a11bb23Sdan         int nArg = pWin->pOwner->x.pList->nExpr;
1951fe4e25a0Sdan         int csr = pWin->csrApp;
1952ec4ccdbcSdrh         int lbl = sqlite3VdbeMakeLabel(pParse);
1953fe4e25a0Sdan         int tmpReg = sqlite3GetTempReg(pParse);
1954680f6e8eSdan         int iEph = pMWin->iEphCsr;
1955fe4e25a0Sdan 
19562a11bb23Sdan         if( nArg<3 ){
1957fe4e25a0Sdan           sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regResult);
1958fe4e25a0Sdan         }else{
1959fe4e25a0Sdan           sqlite3VdbeAddOp3(v, OP_Column, iEph,pWin->iArgCol+2,pWin->regResult);
1960fe4e25a0Sdan         }
1961fe4e25a0Sdan         sqlite3VdbeAddOp2(v, OP_Rowid, iEph, tmpReg);
19622a11bb23Sdan         if( nArg<2 ){
196319dc4d40Sdrh           int val = (pFunc->zName==leadName ? 1 : -1);
1964fe4e25a0Sdan           sqlite3VdbeAddOp2(v, OP_AddImm, tmpReg, val);
1965fe4e25a0Sdan         }else{
196619dc4d40Sdrh           int op = (pFunc->zName==leadName ? OP_Add : OP_Subtract);
1967fe4e25a0Sdan           int tmpReg2 = sqlite3GetTempReg(pParse);
1968fe4e25a0Sdan           sqlite3VdbeAddOp3(v, OP_Column, iEph, pWin->iArgCol+1, tmpReg2);
1969fe4e25a0Sdan           sqlite3VdbeAddOp3(v, op, tmpReg2, tmpReg, tmpReg);
1970fe4e25a0Sdan           sqlite3ReleaseTempReg(pParse, tmpReg2);
1971fe4e25a0Sdan         }
1972fe4e25a0Sdan 
1973fe4e25a0Sdan         sqlite3VdbeAddOp3(v, OP_SeekRowid, csr, lbl, tmpReg);
197401e12290Sdan         VdbeCoverage(v);
1975fe4e25a0Sdan         sqlite3VdbeAddOp3(v, OP_Column, csr, pWin->iArgCol, pWin->regResult);
1976fe4e25a0Sdan         sqlite3VdbeResolveLabel(v, lbl);
1977fe4e25a0Sdan         sqlite3ReleaseTempReg(pParse, tmpReg);
1978fe4e25a0Sdan       }
1979ec891fd4Sdan     }
1980c782a81aSdan   }
1981c782a81aSdan   sqlite3VdbeAddOp2(v, OP_Gosub, p->regGosub, p->addrGosub);
1982ec891fd4Sdan }
1983ec891fd4Sdan 
198413078caaSdan /*
198554a9ab3fSdan ** Generate code to set the accumulator register for each window function
198654a9ab3fSdan ** in the linked list passed as the second argument to NULL. And perform
198754a9ab3fSdan ** any equivalent initialization required by any built-in window functions
198854a9ab3fSdan ** in the list.
198954a9ab3fSdan */
windowInitAccum(Parse * pParse,Window * pMWin)19902e60568fSdan static int windowInitAccum(Parse *pParse, Window *pMWin){
19912e60568fSdan   Vdbe *v = sqlite3GetVdbe(pParse);
19922e60568fSdan   int regArg;
19932e60568fSdan   int nArg = 0;
19942e60568fSdan   Window *pWin;
19952e60568fSdan   for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
1996105dcaa5Sdrh     FuncDef *pFunc = pWin->pWFunc;
19970a21ea99Sdan     assert( pWin->regAccum );
19982e60568fSdan     sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regAccum);
19992a11bb23Sdan     nArg = MAX(nArg, windowArgCount(pWin));
2000108e6b2cSdan     if( pMWin->regStartRowid==0 ){
2001a0f6b833Sdan       if( pFunc->zName==nth_valueName || pFunc->zName==first_valueName ){
20022e60568fSdan         sqlite3VdbeAddOp2(v, OP_Integer, 0, pWin->regApp);
20032e60568fSdan         sqlite3VdbeAddOp2(v, OP_Integer, 0, pWin->regApp+1);
20042e60568fSdan       }
20059a94722dSdan 
20069a94722dSdan       if( (pFunc->funcFlags & SQLITE_FUNC_MINMAX) && pWin->csrApp ){
20079a94722dSdan         assert( pWin->eStart!=TK_UNBOUNDED );
20089a94722dSdan         sqlite3VdbeAddOp1(v, OP_ResetSorter, pWin->csrApp);
20099a94722dSdan         sqlite3VdbeAddOp2(v, OP_Integer, 0, pWin->regApp+1);
20109a94722dSdan       }
20112e60568fSdan     }
2012a0f6b833Sdan   }
20132e60568fSdan   regArg = pParse->nMem+1;
20142e60568fSdan   pParse->nMem += nArg;
20152e60568fSdan   return regArg;
20162e60568fSdan }
20172e60568fSdan 
2018b33487b0Sdan /*
2019cc7a850fSdan ** Return true if the current frame should be cached in the ephemeral table,
2020cc7a850fSdan ** even if there are no xInverse() calls required.
2021b33487b0Sdan */
windowCacheFrame(Window * pMWin)2022cc7a850fSdan static int windowCacheFrame(Window *pMWin){
2023b33487b0Sdan   Window *pWin;
2024a0f6b833Sdan   if( pMWin->regStartRowid ) return 1;
2025b33487b0Sdan   for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
2026105dcaa5Sdrh     FuncDef *pFunc = pWin->pWFunc;
2027cc7a850fSdan     if( (pFunc->zName==nth_valueName)
2028b33487b0Sdan      || (pFunc->zName==first_valueName)
2029b560a719Sdan      || (pFunc->zName==leadName)
2030b33487b0Sdan      || (pFunc->zName==lagName)
2031b33487b0Sdan     ){
2032b33487b0Sdan       return 1;
2033b33487b0Sdan     }
2034b33487b0Sdan   }
2035b33487b0Sdan   return 0;
2036b33487b0Sdan }
2037b33487b0Sdan 
20386c75b396Sdan /*
20396c75b396Sdan ** regOld and regNew are each the first register in an array of size
20406c75b396Sdan ** pOrderBy->nExpr. This function generates code to compare the two
20416c75b396Sdan ** arrays of registers using the collation sequences and other comparison
20426c75b396Sdan ** parameters specified by pOrderBy.
20436c75b396Sdan **
20446c75b396Sdan ** If the two arrays are not equal, the contents of regNew is copied to
20456c75b396Sdan ** regOld and control falls through. Otherwise, if the contents of the arrays
20466c75b396Sdan ** are equal, an OP_Goto is executed. The address of the OP_Goto is returned.
20476c75b396Sdan */
windowIfNewPeer(Parse * pParse,ExprList * pOrderBy,int regNew,int regOld,int addr)2048935d9d82Sdan static void windowIfNewPeer(
20496c75b396Sdan   Parse *pParse,
20506c75b396Sdan   ExprList *pOrderBy,
20516c75b396Sdan   int regNew,                     /* First in array of new values */
2052935d9d82Sdan   int regOld,                     /* First in array of old values */
2053935d9d82Sdan   int addr                        /* Jump here */
20546c75b396Sdan ){
20556c75b396Sdan   Vdbe *v = sqlite3GetVdbe(pParse);
20566c75b396Sdan   if( pOrderBy ){
20576c75b396Sdan     int nVal = pOrderBy->nExpr;
20586c75b396Sdan     KeyInfo *pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pOrderBy, 0, 0);
20596c75b396Sdan     sqlite3VdbeAddOp3(v, OP_Compare, regOld, regNew, nVal);
20606c75b396Sdan     sqlite3VdbeAppendP4(v, (void*)pKeyInfo, P4_KEYINFO);
2061935d9d82Sdan     sqlite3VdbeAddOp3(v, OP_Jump,
2062935d9d82Sdan       sqlite3VdbeCurrentAddr(v)+1, addr, sqlite3VdbeCurrentAddr(v)+1
20636c75b396Sdan     );
20646c75b396Sdan     VdbeCoverageEqNe(v);
20656c75b396Sdan     sqlite3VdbeAddOp3(v, OP_Copy, regNew, regOld, nVal-1);
20666c75b396Sdan   }else{
2067935d9d82Sdan     sqlite3VdbeAddOp2(v, OP_Goto, 0, addr);
20686c75b396Sdan   }
20696c75b396Sdan }
20706c75b396Sdan 
207172b9fdcfSdan /*
207272b9fdcfSdan ** This function is called as part of generating VM programs for RANGE
20731e7cb19bSdan ** offset PRECEDING/FOLLOWING frame boundaries. Assuming "ASC" order for
20748b47f520Sdan ** the ORDER BY term in the window, and that argument op is OP_Ge, it generates
20758b47f520Sdan ** code equivalent to:
207672b9fdcfSdan **
207772b9fdcfSdan **   if( csr1.peerVal + regVal >= csr2.peerVal ) goto lbl;
20781e7cb19bSdan **
20798b47f520Sdan ** The value of parameter op may also be OP_Gt or OP_Le. In these cases the
20808b47f520Sdan ** operator in the above pseudo-code is replaced with ">" or "<=", respectively.
20818b47f520Sdan **
20828b47f520Sdan ** If the sort-order for the ORDER BY term in the window is DESC, then the
20838b47f520Sdan ** comparison is reversed. Instead of adding regVal to csr1.peerVal, it is
20848b47f520Sdan ** subtracted. And the comparison operator is inverted to - ">=" becomes "<=",
20858b47f520Sdan ** ">" becomes "<", and so on. So, with DESC sort order, if the argument op
20868b47f520Sdan ** is OP_Ge, the generated code is equivalent to:
20878b47f520Sdan **
20888b47f520Sdan **   if( csr1.peerVal - regVal <= csr2.peerVal ) goto lbl;
20898b47f520Sdan **
20908b47f520Sdan ** A special type of arithmetic is used such that if csr1.peerVal is not
20916b6ec407Sdan ** a numeric type (real or integer), then the result of the addition
20928b47f520Sdan ** or subtraction is a a copy of csr1.peerVal.
209372b9fdcfSdan */
windowCodeRangeTest(WindowCodeArg * p,int op,int csr1,int regVal,int csr2,int lbl)209472b9fdcfSdan static void windowCodeRangeTest(
209572b9fdcfSdan   WindowCodeArg *p,
2096f76ccb7dSdrh   int op,                         /* OP_Ge, OP_Gt, or OP_Le */
20978b47f520Sdan   int csr1,                       /* Cursor number for cursor 1 */
20988b47f520Sdan   int regVal,                     /* Register containing non-negative number */
20998b47f520Sdan   int csr2,                       /* Cursor number for cursor 2 */
21001cac1766Sdan   int lbl                         /* Jump destination if condition is true */
210172b9fdcfSdan ){
210272b9fdcfSdan   Parse *pParse = p->pParse;
210372b9fdcfSdan   Vdbe *v = sqlite3GetVdbe(pParse);
21041cac1766Sdan   ExprList *pOrderBy = p->pMWin->pOrderBy;  /* ORDER BY clause for window */
21051cac1766Sdan   int reg1 = sqlite3GetTempReg(pParse);     /* Reg. for csr1.peerVal+regVal */
21061cac1766Sdan   int reg2 = sqlite3GetTempReg(pParse);     /* Reg. for csr2.peerVal */
21071cac1766Sdan   int regString = ++pParse->nMem;           /* Reg. for constant value '' */
21088b47f520Sdan   int arith = OP_Add;                       /* OP_Add or OP_Subtract */
21098b47f520Sdan   int addrGe;                               /* Jump destination */
21106b6ec407Sdan   int addrDone = sqlite3VdbeMakeLabel(pParse);   /* Address past OP_Ge */
21117f8653a2Sdan   CollSeq *pColl;
211271fddaf1Sdan 
21136b6ec407Sdan   /* Read the peer-value from each cursor into a register */
21146b6ec407Sdan   windowReadPeerValues(p, csr1, reg1);
21156b6ec407Sdan   windowReadPeerValues(p, csr2, reg2);
21166b6ec407Sdan 
211771fddaf1Sdan   assert( op==OP_Ge || op==OP_Gt || op==OP_Le );
2118ae8e45cbSdan   assert( pOrderBy && pOrderBy->nExpr==1 );
2119d88fd539Sdrh   if( pOrderBy->a[0].fg.sortFlags & KEYINFO_ORDER_DESC ){
212071fddaf1Sdan     switch( op ){
212171fddaf1Sdan       case OP_Ge: op = OP_Le; break;
212271fddaf1Sdan       case OP_Gt: op = OP_Lt; break;
212371fddaf1Sdan       default: assert( op==OP_Le ); op = OP_Ge; break;
212471fddaf1Sdan     }
212571fddaf1Sdan     arith = OP_Subtract;
212671fddaf1Sdan   }
212771fddaf1Sdan 
21288b47f520Sdan   VdbeModuleComment((v, "CodeRangeTest: if( R%d %s R%d %s R%d ) goto lbl",
21298b47f520Sdan       reg1, (arith==OP_Add ? "+" : "-"), regVal,
21308b47f520Sdan       ((op==OP_Ge) ? ">=" : (op==OP_Le) ? "<=" : (op==OP_Gt) ? ">" : "<"), reg2
21318b47f520Sdan   ));
21328b47f520Sdan 
21338b47f520Sdan   /* If the BIGNULL flag is set for the ORDER BY, then it is required to
21348b47f520Sdan   ** consider NULL values to be larger than all other values, instead of
21358b47f520Sdan   ** the usual smaller. The VDBE opcodes OP_Ge and so on do not handle this
21368b47f520Sdan   ** (and adding that capability causes a performance regression), so
21378b47f520Sdan   ** instead if the BIGNULL flag is set then cases where either reg1 or
21388b47f520Sdan   ** reg2 are NULL are handled separately in the following block. The code
21398b47f520Sdan   ** generated is equivalent to:
21408b47f520Sdan   **
21418b47f520Sdan   **   if( reg1 IS NULL ){
21429889ede2Sdan   **     if( op==OP_Ge ) goto lbl;
21439889ede2Sdan   **     if( op==OP_Gt && reg2 IS NOT NULL ) goto lbl;
21448b47f520Sdan   **     if( op==OP_Le && reg2 IS NULL ) goto lbl;
21458b47f520Sdan   **   }else if( reg2 IS NULL ){
21468b47f520Sdan   **     if( op==OP_Le ) goto lbl;
21478b47f520Sdan   **   }
21488b47f520Sdan   **
21498b47f520Sdan   ** Additionally, if either reg1 or reg2 are NULL but the jump to lbl is
21508b47f520Sdan   ** not taken, control jumps over the comparison operator coded below this
21518b47f520Sdan   ** block.  */
2152d88fd539Sdrh   if( pOrderBy->a[0].fg.sortFlags & KEYINFO_ORDER_BIGNULL ){
21538b47f520Sdan     /* This block runs if reg1 contains a NULL. */
21548b47f520Sdan     int addr = sqlite3VdbeAddOp1(v, OP_NotNull, reg1); VdbeCoverage(v);
2155ae8e45cbSdan     switch( op ){
21568b47f520Sdan       case OP_Ge:
21578b47f520Sdan         sqlite3VdbeAddOp2(v, OP_Goto, 0, lbl);
21588b47f520Sdan         break;
2159f236b21fSdan       case OP_Gt:
2160db3a32edSdrh         sqlite3VdbeAddOp2(v, OP_NotNull, reg2, lbl);
2161db3a32edSdrh         VdbeCoverage(v);
2162f236b21fSdan         break;
2163db3a32edSdrh       case OP_Le:
2164db3a32edSdrh         sqlite3VdbeAddOp2(v, OP_IsNull, reg2, lbl);
2165db3a32edSdrh         VdbeCoverage(v);
2166f236b21fSdan         break;
2167db3a32edSdrh       default: assert( op==OP_Lt ); /* no-op */ break;
2168ae8e45cbSdan     }
21696b6ec407Sdan     sqlite3VdbeAddOp2(v, OP_Goto, 0, addrDone);
21708b47f520Sdan 
21718b47f520Sdan     /* This block runs if reg1 is not NULL, but reg2 is. */
2172ae8e45cbSdan     sqlite3VdbeJumpHere(v, addr);
2173058e9950Sdrh     sqlite3VdbeAddOp2(v, OP_IsNull, reg2,
2174058e9950Sdrh                       (op==OP_Gt || op==OP_Ge) ? addrDone : lbl);
2175*3b01dd0fSdrh     VdbeCoverage(v);
2176ae8e45cbSdan   }
21778b47f520Sdan 
21786b6ec407Sdan   /* Register reg1 currently contains csr1.peerVal (the peer-value from csr1).
21796b6ec407Sdan   ** This block adds (or subtracts for DESC) the numeric value in regVal
21806b6ec407Sdan   ** from it. Or, if reg1 is not numeric (it is a NULL, a text value or a blob),
21816b6ec407Sdan   ** then leave reg1 as it is. In pseudo-code, this is implemented as:
21826b6ec407Sdan   **
21836b6ec407Sdan   **   if( reg1>='' ) goto addrGe;
21846b6ec407Sdan   **   reg1 = reg1 +/- regVal
21856b6ec407Sdan   **   addrGe:
21866b6ec407Sdan   **
21876b6ec407Sdan   ** Since all strings and blobs are greater-than-or-equal-to an empty string,
21886b6ec407Sdan   ** the add/subtract is skipped for these, as required. If reg1 is a NULL,
21896b6ec407Sdan   ** then the arithmetic is performed, but since adding or subtracting from
21906b6ec407Sdan   ** NULL is always NULL anyway, this case is handled as required too.  */
21916b6ec407Sdan   sqlite3VdbeAddOp4(v, OP_String8, 0, regString, 0, "", P4_STATIC);
21926b6ec407Sdan   addrGe = sqlite3VdbeAddOp3(v, OP_Ge, regString, 0, reg1);
21936b6ec407Sdan   VdbeCoverage(v);
21946b6ec407Sdan   if( (op==OP_Ge && arith==OP_Add) || (op==OP_Le && arith==OP_Subtract) ){
21956b6ec407Sdan     sqlite3VdbeAddOp3(v, op, reg2, lbl, reg1); VdbeCoverage(v);
21966b6ec407Sdan   }
21976b6ec407Sdan   sqlite3VdbeAddOp3(v, arith, regVal, reg1, reg1);
21986b6ec407Sdan   sqlite3VdbeJumpHere(v, addrGe);
21996b6ec407Sdan 
22008b47f520Sdan   /* Compare registers reg2 and reg1, taking the jump if required. Note that
22018b47f520Sdan   ** control skips over this test if the BIGNULL flag is set and either
22028b47f520Sdan   ** reg1 or reg2 contain a NULL value.  */
22036f88359dSdrh   sqlite3VdbeAddOp3(v, op, reg2, lbl, reg1); VdbeCoverage(v);
22047f8653a2Sdan   pColl = sqlite3ExprNNCollSeq(pParse, pOrderBy->a[0].pExpr);
22057f8653a2Sdan   sqlite3VdbeAppendP4(v, (void*)pColl, P4_COLLSEQ);
2206bdabe742Sdan   sqlite3VdbeChangeP5(v, SQLITE_NULLEQ);
22076b6ec407Sdan   sqlite3VdbeResolveLabel(v, addrDone);
22088b47f520Sdan 
22096f88359dSdrh   assert( op==OP_Ge || op==OP_Gt || op==OP_Lt || op==OP_Le );
22106f88359dSdrh   testcase(op==OP_Ge); VdbeCoverageIf(v, op==OP_Ge);
22116f88359dSdrh   testcase(op==OP_Lt); VdbeCoverageIf(v, op==OP_Lt);
22126f88359dSdrh   testcase(op==OP_Le); VdbeCoverageIf(v, op==OP_Le);
22136f88359dSdrh   testcase(op==OP_Gt); VdbeCoverageIf(v, op==OP_Gt);
221472b9fdcfSdan   sqlite3ReleaseTempReg(pParse, reg1);
221572b9fdcfSdan   sqlite3ReleaseTempReg(pParse, reg2);
22168b47f520Sdan 
22178b47f520Sdan   VdbeModuleComment((v, "CodeRangeTest: end"));
221872b9fdcfSdan }
221972b9fdcfSdan 
22200525b6f4Sdan /*
22210525b6f4Sdan ** Helper function for sqlite3WindowCodeStep(). Each call to this function
22220525b6f4Sdan ** generates VM code for a single RETURN_ROW, AGGSTEP or AGGINVERSE
22230525b6f4Sdan ** operation. Refer to the header comment for sqlite3WindowCodeStep() for
22240525b6f4Sdan ** details.
22250525b6f4Sdan */
windowCodeOp(WindowCodeArg * p,int op,int regCountdown,int jumpOnEof)222600267b8aSdan static int windowCodeOp(
22270525b6f4Sdan  WindowCodeArg *p,                /* Context object */
22280525b6f4Sdan  int op,                          /* WINDOW_RETURN_ROW, AGGSTEP or AGGINVERSE */
22290525b6f4Sdan  int regCountdown,                /* Register for OP_IfPos countdown */
22300525b6f4Sdan  int jumpOnEof                    /* Jump here if stepped cursor reaches EOF */
223100267b8aSdan ){
22326c75b396Sdan   int csr, reg;
22336c75b396Sdan   Parse *pParse = p->pParse;
223454975cdfSdan   Window *pMWin = p->pMWin;
223500267b8aSdan   int ret = 0;
223600267b8aSdan   Vdbe *v = p->pVdbe;
22376c75b396Sdan   int addrContinue = 0;
2238fc15f4c5Sdrh   int bPeer = (pMWin->eFrmType!=TK_ROWS);
223900267b8aSdan 
224072b9fdcfSdan   int lblDone = sqlite3VdbeMakeLabel(pParse);
224172b9fdcfSdan   int addrNextRange = 0;
224272b9fdcfSdan 
224354975cdfSdan   /* Special case - WINDOW_AGGINVERSE is always a no-op if the frame
224454975cdfSdan   ** starts with UNBOUNDED PRECEDING. */
224554975cdfSdan   if( op==WINDOW_AGGINVERSE && pMWin->eStart==TK_UNBOUNDED ){
224654975cdfSdan     assert( regCountdown==0 && jumpOnEof==0 );
224754975cdfSdan     return 0;
224854975cdfSdan   }
224954975cdfSdan 
225000267b8aSdan   if( regCountdown>0 ){
2251fc15f4c5Sdrh     if( pMWin->eFrmType==TK_RANGE ){
225272b9fdcfSdan       addrNextRange = sqlite3VdbeCurrentAddr(v);
22530525b6f4Sdan       assert( op==WINDOW_AGGINVERSE || op==WINDOW_AGGSTEP );
22540525b6f4Sdan       if( op==WINDOW_AGGINVERSE ){
225572b9fdcfSdan         if( pMWin->eStart==TK_FOLLOWING ){
225672b9fdcfSdan           windowCodeRangeTest(
225772b9fdcfSdan               p, OP_Le, p->current.csr, regCountdown, p->start.csr, lblDone
225872b9fdcfSdan           );
225972b9fdcfSdan         }else{
226072b9fdcfSdan           windowCodeRangeTest(
226172b9fdcfSdan               p, OP_Ge, p->start.csr, regCountdown, p->current.csr, lblDone
226272b9fdcfSdan           );
226372b9fdcfSdan         }
22640525b6f4Sdan       }else{
226572b9fdcfSdan         windowCodeRangeTest(
226672b9fdcfSdan             p, OP_Gt, p->end.csr, regCountdown, p->current.csr, lblDone
226772b9fdcfSdan         );
226872b9fdcfSdan       }
226972b9fdcfSdan     }else{
227037d296a7Sdan       sqlite3VdbeAddOp3(v, OP_IfPos, regCountdown, lblDone, 1);
22711d4b25faSdan       VdbeCoverage(v);
227200267b8aSdan     }
227372b9fdcfSdan   }
227400267b8aSdan 
22750525b6f4Sdan   if( op==WINDOW_RETURN_ROW && pMWin->regStartRowid==0 ){
2276c782a81aSdan     windowAggFinal(p, 0);
22776c75b396Sdan   }
22786c75b396Sdan   addrContinue = sqlite3VdbeCurrentAddr(v);
2279e7579a53Sdan 
2280e7579a53Sdan   /* If this is a (RANGE BETWEEN a FOLLOWING AND b FOLLOWING) or
2281e7579a53Sdan   ** (RANGE BETWEEN b PRECEDING AND a PRECEDING) frame, ensure the
2282e7579a53Sdan   ** start cursor does not advance past the end cursor within the
2283113a33c5Sdrh   ** temporary table. It otherwise might, if (a>b). Also ensure that,
2284113a33c5Sdrh   ** if the input cursor is still finding new rows, that the end
2285113a33c5Sdrh   ** cursor does not go past it to EOF. */
2286e7579a53Sdan   if( pMWin->eStart==pMWin->eEnd && regCountdown
2287113a33c5Sdrh    && pMWin->eFrmType==TK_RANGE
2288e7579a53Sdan   ){
2289e7579a53Sdan     int regRowid1 = sqlite3GetTempReg(pParse);
2290e7579a53Sdan     int regRowid2 = sqlite3GetTempReg(pParse);
2291113a33c5Sdrh     if( op==WINDOW_AGGINVERSE ){
2292e7579a53Sdan       sqlite3VdbeAddOp2(v, OP_Rowid, p->start.csr, regRowid1);
2293e7579a53Sdan       sqlite3VdbeAddOp2(v, OP_Rowid, p->end.csr, regRowid2);
2294e7579a53Sdan       sqlite3VdbeAddOp3(v, OP_Ge, regRowid2, lblDone, regRowid1);
2295b19131a8Sdrh       VdbeCoverage(v);
2296113a33c5Sdrh     }else if( p->regRowid ){
2297113a33c5Sdrh       sqlite3VdbeAddOp2(v, OP_Rowid, p->end.csr, regRowid1);
2298113a33c5Sdrh       sqlite3VdbeAddOp3(v, OP_Ge, p->regRowid, lblDone, regRowid1);
229979f313f1Sdrh       VdbeCoverageNeverNull(v);
2300113a33c5Sdrh     }
2301e7579a53Sdan     sqlite3ReleaseTempReg(pParse, regRowid1);
2302e7579a53Sdan     sqlite3ReleaseTempReg(pParse, regRowid2);
2303e7579a53Sdan     assert( pMWin->eStart==TK_PRECEDING || pMWin->eStart==TK_FOLLOWING );
2304e7579a53Sdan   }
2305e7579a53Sdan 
230600267b8aSdan   switch( op ){
230700267b8aSdan     case WINDOW_RETURN_ROW:
23086c75b396Sdan       csr = p->current.csr;
23096c75b396Sdan       reg = p->current.reg;
2310c782a81aSdan       windowReturnOneRow(p);
231100267b8aSdan       break;
231200267b8aSdan 
231300267b8aSdan     case WINDOW_AGGINVERSE:
23146c75b396Sdan       csr = p->start.csr;
23156c75b396Sdan       reg = p->start.reg;
2316a0f6b833Sdan       if( pMWin->regStartRowid ){
2317a0f6b833Sdan         assert( pMWin->regEndRowid );
2318a0f6b833Sdan         sqlite3VdbeAddOp2(v, OP_AddImm, pMWin->regStartRowid, 1);
2319a0f6b833Sdan       }else{
232037d296a7Sdan         windowAggStep(p, pMWin, csr, 1, p->regArg);
2321a0f6b833Sdan       }
232200267b8aSdan       break;
232300267b8aSdan 
23240525b6f4Sdan     default:
23250525b6f4Sdan       assert( op==WINDOW_AGGSTEP );
23266c75b396Sdan       csr = p->end.csr;
23276c75b396Sdan       reg = p->end.reg;
2328a0f6b833Sdan       if( pMWin->regStartRowid ){
2329a0f6b833Sdan         assert( pMWin->regEndRowid );
2330a0f6b833Sdan         sqlite3VdbeAddOp2(v, OP_AddImm, pMWin->regEndRowid, 1);
2331a0f6b833Sdan       }else{
233237d296a7Sdan         windowAggStep(p, pMWin, csr, 0, p->regArg);
2333a0f6b833Sdan       }
233400267b8aSdan       break;
233500267b8aSdan   }
233600267b8aSdan 
2337b560a719Sdan   if( op==p->eDelete ){
2338b560a719Sdan     sqlite3VdbeAddOp1(v, OP_Delete, csr);
2339b560a719Sdan     sqlite3VdbeChangeP5(v, OPFLAG_SAVEPOSITION);
2340b560a719Sdan   }
2341b560a719Sdan 
2342c813750bSdan   if( jumpOnEof ){
2343c813750bSdan     sqlite3VdbeAddOp2(v, OP_Next, csr, sqlite3VdbeCurrentAddr(v)+2);
23441d4b25faSdan     VdbeCoverage(v);
2345c813750bSdan     ret = sqlite3VdbeAddOp0(v, OP_Goto);
2346c813750bSdan   }else{
23476c75b396Sdan     sqlite3VdbeAddOp2(v, OP_Next, csr, sqlite3VdbeCurrentAddr(v)+1+bPeer);
23481d4b25faSdan     VdbeCoverage(v);
23496c75b396Sdan     if( bPeer ){
235037d296a7Sdan       sqlite3VdbeAddOp2(v, OP_Goto, 0, lblDone);
23516c75b396Sdan     }
235200267b8aSdan   }
2353c813750bSdan 
23546c75b396Sdan   if( bPeer ){
23556c75b396Sdan     int nReg = (pMWin->pOrderBy ? pMWin->pOrderBy->nExpr : 0);
2356e7579a53Sdan     int regTmp = (nReg ? sqlite3GetTempRange(pParse, nReg) : 0);
23576c75b396Sdan     windowReadPeerValues(p, csr, regTmp);
2358935d9d82Sdan     windowIfNewPeer(pParse, pMWin->pOrderBy, regTmp, reg, addrContinue);
23596c75b396Sdan     sqlite3ReleaseTempRange(pParse, regTmp, nReg);
236000267b8aSdan   }
23616c75b396Sdan 
236272b9fdcfSdan   if( addrNextRange ){
236372b9fdcfSdan     sqlite3VdbeAddOp2(v, OP_Goto, 0, addrNextRange);
236472b9fdcfSdan   }
236572b9fdcfSdan   sqlite3VdbeResolveLabel(v, lblDone);
236600267b8aSdan   return ret;
236700267b8aSdan }
236800267b8aSdan 
2369a786e453Sdan 
237000267b8aSdan /*
2371a786e453Sdan ** Allocate and return a duplicate of the Window object indicated by the
2372a786e453Sdan ** third argument. Set the Window.pOwner field of the new object to
2373a786e453Sdan ** pOwner.
2374a786e453Sdan */
sqlite3WindowDup(sqlite3 * db,Expr * pOwner,Window * p)2375a786e453Sdan Window *sqlite3WindowDup(sqlite3 *db, Expr *pOwner, Window *p){
2376a786e453Sdan   Window *pNew = 0;
2377a786e453Sdan   if( ALWAYS(p) ){
2378a786e453Sdan     pNew = sqlite3DbMallocZero(db, sizeof(Window));
2379a786e453Sdan     if( pNew ){
2380a786e453Sdan       pNew->zName = sqlite3DbStrDup(db, p->zName);
2381b42eb357Sdan       pNew->zBase = sqlite3DbStrDup(db, p->zBase);
2382a786e453Sdan       pNew->pFilter = sqlite3ExprDup(db, p->pFilter, 0);
2383105dcaa5Sdrh       pNew->pWFunc = p->pWFunc;
2384a786e453Sdan       pNew->pPartition = sqlite3ExprListDup(db, p->pPartition, 0);
2385a786e453Sdan       pNew->pOrderBy = sqlite3ExprListDup(db, p->pOrderBy, 0);
2386fc15f4c5Sdrh       pNew->eFrmType = p->eFrmType;
2387a786e453Sdan       pNew->eEnd = p->eEnd;
2388a786e453Sdan       pNew->eStart = p->eStart;
2389c782a81aSdan       pNew->eExclude = p->eExclude;
2390b555b080Sdrh       pNew->regResult = p->regResult;
23910a21ea99Sdan       pNew->regAccum = p->regAccum;
23920a21ea99Sdan       pNew->iArgCol = p->iArgCol;
23930a21ea99Sdan       pNew->iEphCsr = p->iEphCsr;
23940a21ea99Sdan       pNew->bExprArgs = p->bExprArgs;
2395a786e453Sdan       pNew->pStart = sqlite3ExprDup(db, p->pStart, 0);
2396a786e453Sdan       pNew->pEnd = sqlite3ExprDup(db, p->pEnd, 0);
2397a786e453Sdan       pNew->pOwner = pOwner;
2398b42eb357Sdan       pNew->bImplicitFrame = p->bImplicitFrame;
2399a786e453Sdan     }
2400a786e453Sdan   }
2401a786e453Sdan   return pNew;
2402a786e453Sdan }
2403a786e453Sdan 
2404a786e453Sdan /*
2405a786e453Sdan ** Return a copy of the linked list of Window objects passed as the
2406a786e453Sdan ** second argument.
2407a786e453Sdan */
sqlite3WindowListDup(sqlite3 * db,Window * p)2408a786e453Sdan Window *sqlite3WindowListDup(sqlite3 *db, Window *p){
2409a786e453Sdan   Window *pWin;
2410a786e453Sdan   Window *pRet = 0;
2411a786e453Sdan   Window **pp = &pRet;
2412a786e453Sdan 
2413a786e453Sdan   for(pWin=p; pWin; pWin=pWin->pNextWin){
2414a786e453Sdan     *pp = sqlite3WindowDup(db, 0, pWin);
2415a786e453Sdan     if( *pp==0 ) break;
2416a786e453Sdan     pp = &((*pp)->pNextWin);
2417a786e453Sdan   }
2418a786e453Sdan 
2419a786e453Sdan   return pRet;
2420a786e453Sdan }
2421a786e453Sdan 
2422a786e453Sdan /*
2423725b1cfcSdan ** Return true if it can be determined at compile time that expression
2424725b1cfcSdan ** pExpr evaluates to a value that, when cast to an integer, is greater
2425725b1cfcSdan ** than zero. False otherwise.
2426725b1cfcSdan **
2427725b1cfcSdan ** If an OOM error occurs, this function sets the Parse.db.mallocFailed
2428725b1cfcSdan ** flag and returns zero.
2429725b1cfcSdan */
windowExprGtZero(Parse * pParse,Expr * pExpr)2430725b1cfcSdan static int windowExprGtZero(Parse *pParse, Expr *pExpr){
2431725b1cfcSdan   int ret = 0;
2432725b1cfcSdan   sqlite3 *db = pParse->db;
2433725b1cfcSdan   sqlite3_value *pVal = 0;
2434725b1cfcSdan   sqlite3ValueFromExpr(db, pExpr, db->enc, SQLITE_AFF_NUMERIC, &pVal);
2435725b1cfcSdan   if( pVal && sqlite3_value_int(pVal)>0 ){
2436725b1cfcSdan     ret = 1;
2437725b1cfcSdan   }
2438725b1cfcSdan   sqlite3ValueFree(pVal);
2439725b1cfcSdan   return ret;
2440725b1cfcSdan }
2441725b1cfcSdan 
2442725b1cfcSdan /*
2443a786e453Sdan ** sqlite3WhereBegin() has already been called for the SELECT statement
2444a786e453Sdan ** passed as the second argument when this function is invoked. It generates
2445a786e453Sdan ** code to populate the Window.regResult register for each window function
2446a786e453Sdan ** and invoke the sub-routine at instruction addrGosub once for each row.
2447a786e453Sdan ** sqlite3WhereEnd() is always called before returning.
2448a786e453Sdan **
2449a786e453Sdan ** This function handles several different types of window frames, which
2450a786e453Sdan ** require slightly different processing. The following pseudo code is
2451a786e453Sdan ** used to implement window frames of the form:
245200267b8aSdan **
245300267b8aSdan **   ROWS BETWEEN <expr1> PRECEDING AND <expr2> FOLLOWING
245400267b8aSdan **
2455a786e453Sdan ** Other window frame types use variants of the following:
245600267b8aSdan **
2457a786e453Sdan **     ... loop started by sqlite3WhereBegin() ...
245800267b8aSdan **       if( new partition ){
245900267b8aSdan **         Gosub flush
246000267b8aSdan **       }
246100267b8aSdan **       Insert new row into eph table.
246200267b8aSdan **
246300267b8aSdan **       if( first row of partition ){
2464a786e453Sdan **         // Rewind three cursors, all open on the eph table.
2465a786e453Sdan **         Rewind(csrEnd);
2466a786e453Sdan **         Rewind(csrStart);
2467a786e453Sdan **         Rewind(csrCurrent);
246800267b8aSdan **
246900267b8aSdan **         regEnd = <expr2>          // FOLLOWING expression
247000267b8aSdan **         regStart = <expr1>        // PRECEDING expression
247100267b8aSdan **       }else{
2472a786e453Sdan **         // First time this branch is taken, the eph table contains two
2473a786e453Sdan **         // rows. The first row in the partition, which all three cursors
2474a786e453Sdan **         // currently point to, and the following row.
2475a786e453Sdan **         AGGSTEP
247600267b8aSdan **         if( (regEnd--)<=0 ){
2477a786e453Sdan **           RETURN_ROW
2478a786e453Sdan **           if( (regStart--)<=0 ){
2479a786e453Sdan **             AGGINVERSE
248000267b8aSdan **           }
248100267b8aSdan **         }
248200267b8aSdan **       }
248300267b8aSdan **     }
248400267b8aSdan **     flush:
2485a786e453Sdan **       AGGSTEP
248600267b8aSdan **       while( 1 ){
2487a786e453Sdan **         RETURN ROW
2488a786e453Sdan **         if( csrCurrent is EOF ) break;
2489a786e453Sdan **         if( (regStart--)<=0 ){
2490a786e453Sdan **           AggInverse(csrStart)
2491a786e453Sdan **           Next(csrStart)
249200267b8aSdan **         }
249300267b8aSdan **       }
249400267b8aSdan **
2495a786e453Sdan ** The pseudo-code above uses the following shorthand:
249600267b8aSdan **
2497a786e453Sdan **   AGGSTEP:    invoke the aggregate xStep() function for each window function
2498a786e453Sdan **               with arguments read from the current row of cursor csrEnd, then
2499a786e453Sdan **               step cursor csrEnd forward one row (i.e. sqlite3BtreeNext()).
2500a786e453Sdan **
2501a786e453Sdan **   RETURN_ROW: return a row to the caller based on the contents of the
2502a786e453Sdan **               current row of csrCurrent and the current state of all
2503a786e453Sdan **               aggregates. Then step cursor csrCurrent forward one row.
2504a786e453Sdan **
2505a786e453Sdan **   AGGINVERSE: invoke the aggregate xInverse() function for each window
2506a786e453Sdan **               functions with arguments read from the current row of cursor
2507a786e453Sdan **               csrStart. Then step csrStart forward one row.
2508a786e453Sdan **
2509a786e453Sdan ** There are two other ROWS window frames that are handled significantly
2510a786e453Sdan ** differently from the above - "BETWEEN <expr> PRECEDING AND <expr> PRECEDING"
2511a786e453Sdan ** and "BETWEEN <expr> FOLLOWING AND <expr> FOLLOWING". These are special
2512a786e453Sdan ** cases because they change the order in which the three cursors (csrStart,
2513a786e453Sdan ** csrCurrent and csrEnd) iterate through the ephemeral table. Cases that
2514a786e453Sdan ** use UNBOUNDED or CURRENT ROW are much simpler variations on one of these
2515a786e453Sdan ** three.
2516a786e453Sdan **
2517a786e453Sdan **   ROWS BETWEEN <expr1> PRECEDING AND <expr2> PRECEDING
2518a786e453Sdan **
2519a786e453Sdan **     ... loop started by sqlite3WhereBegin() ...
252000267b8aSdan **       if( new partition ){
252100267b8aSdan **         Gosub flush
252200267b8aSdan **       }
252300267b8aSdan **       Insert new row into eph table.
252400267b8aSdan **       if( first row of partition ){
2525935d9d82Sdan **         Rewind(csrEnd) ; Rewind(csrStart) ; Rewind(csrCurrent)
2526a786e453Sdan **         regEnd = <expr2>
2527a786e453Sdan **         regStart = <expr1>
252800267b8aSdan **       }else{
2529a786e453Sdan **         if( (regEnd--)<=0 ){
2530a786e453Sdan **           AGGSTEP
253100267b8aSdan **         }
2532a786e453Sdan **         RETURN_ROW
2533a786e453Sdan **         if( (regStart--)<=0 ){
2534a786e453Sdan **           AGGINVERSE
2535a786e453Sdan **         }
2536a786e453Sdan **       }
253700267b8aSdan **     }
253800267b8aSdan **     flush:
2539a786e453Sdan **       if( (regEnd--)<=0 ){
2540a786e453Sdan **         AGGSTEP
2541a786e453Sdan **       }
2542a786e453Sdan **       RETURN_ROW
2543a786e453Sdan **
2544a786e453Sdan **
2545a786e453Sdan **   ROWS BETWEEN <expr1> FOLLOWING AND <expr2> FOLLOWING
2546a786e453Sdan **
2547a786e453Sdan **     ... loop started by sqlite3WhereBegin() ...
2548a786e453Sdan **     if( new partition ){
2549a786e453Sdan **       Gosub flush
2550a786e453Sdan **     }
2551a786e453Sdan **     Insert new row into eph table.
2552a786e453Sdan **     if( first row of partition ){
2553935d9d82Sdan **       Rewind(csrEnd) ; Rewind(csrStart) ; Rewind(csrCurrent)
2554a786e453Sdan **       regEnd = <expr2>
2555a786e453Sdan **       regStart = regEnd - <expr1>
2556a786e453Sdan **     }else{
2557a786e453Sdan **       AGGSTEP
2558a786e453Sdan **       if( (regEnd--)<=0 ){
2559a786e453Sdan **         RETURN_ROW
2560a786e453Sdan **       }
2561a786e453Sdan **       if( (regStart--)<=0 ){
2562a786e453Sdan **         AGGINVERSE
2563a786e453Sdan **       }
2564a786e453Sdan **     }
2565a786e453Sdan **   }
2566a786e453Sdan **   flush:
2567a786e453Sdan **     AGGSTEP
2568a786e453Sdan **     while( 1 ){
2569a786e453Sdan **       if( (regEnd--)<=0 ){
2570a786e453Sdan **         RETURN_ROW
2571a786e453Sdan **         if( eof ) break;
2572a786e453Sdan **       }
2573a786e453Sdan **       if( (regStart--)<=0 ){
2574a786e453Sdan **         AGGINVERSE
2575a786e453Sdan **         if( eof ) break
2576a786e453Sdan **       }
2577a786e453Sdan **     }
2578a786e453Sdan **     while( !eof csrCurrent ){
2579a786e453Sdan **       RETURN_ROW
2580a786e453Sdan **     }
2581a786e453Sdan **
2582a786e453Sdan ** For the most part, the patterns above are adapted to support UNBOUNDED by
2583a786e453Sdan ** assuming that it is equivalent to "infinity PRECEDING/FOLLOWING" and
2584a786e453Sdan ** CURRENT ROW by assuming that it is equivilent to "0 PRECEDING/FOLLOWING".
2585a786e453Sdan ** This is optimized of course - branches that will never be taken and
2586a786e453Sdan ** conditions that are always true are omitted from the VM code. The only
2587a786e453Sdan ** exceptional case is:
2588a786e453Sdan **
2589a786e453Sdan **   ROWS BETWEEN <expr1> FOLLOWING AND UNBOUNDED FOLLOWING
2590a786e453Sdan **
2591a786e453Sdan **     ... loop started by sqlite3WhereBegin() ...
2592a786e453Sdan **     if( new partition ){
2593a786e453Sdan **       Gosub flush
2594a786e453Sdan **     }
2595a786e453Sdan **     Insert new row into eph table.
2596a786e453Sdan **     if( first row of partition ){
2597935d9d82Sdan **       Rewind(csrEnd) ; Rewind(csrStart) ; Rewind(csrCurrent)
2598a786e453Sdan **       regStart = <expr1>
2599a786e453Sdan **     }else{
2600a786e453Sdan **       AGGSTEP
2601a786e453Sdan **     }
2602a786e453Sdan **   }
2603a786e453Sdan **   flush:
2604a786e453Sdan **     AGGSTEP
2605a786e453Sdan **     while( 1 ){
2606a786e453Sdan **       if( (regStart--)<=0 ){
2607a786e453Sdan **         AGGINVERSE
2608a786e453Sdan **         if( eof ) break
2609a786e453Sdan **       }
2610a786e453Sdan **       RETURN_ROW
2611a786e453Sdan **     }
2612a786e453Sdan **     while( !eof csrCurrent ){
2613a786e453Sdan **       RETURN_ROW
2614a786e453Sdan **     }
2615935d9d82Sdan **
2616935d9d82Sdan ** Also requiring special handling are the cases:
2617935d9d82Sdan **
2618935d9d82Sdan **   ROWS BETWEEN <expr1> PRECEDING AND <expr2> PRECEDING
2619935d9d82Sdan **   ROWS BETWEEN <expr1> FOLLOWING AND <expr2> FOLLOWING
2620935d9d82Sdan **
2621935d9d82Sdan ** when (expr1 < expr2). This is detected at runtime, not by this function.
2622935d9d82Sdan ** To handle this case, the pseudo-code programs depicted above are modified
2623935d9d82Sdan ** slightly to be:
2624935d9d82Sdan **
2625935d9d82Sdan **     ... loop started by sqlite3WhereBegin() ...
2626935d9d82Sdan **     if( new partition ){
2627935d9d82Sdan **       Gosub flush
2628935d9d82Sdan **     }
2629935d9d82Sdan **     Insert new row into eph table.
2630935d9d82Sdan **     if( first row of partition ){
2631935d9d82Sdan **       Rewind(csrEnd) ; Rewind(csrStart) ; Rewind(csrCurrent)
2632935d9d82Sdan **       regEnd = <expr2>
2633935d9d82Sdan **       regStart = <expr1>
2634935d9d82Sdan **       if( regEnd < regStart ){
2635935d9d82Sdan **         RETURN_ROW
2636935d9d82Sdan **         delete eph table contents
2637935d9d82Sdan **         continue
2638935d9d82Sdan **       }
2639935d9d82Sdan **     ...
2640935d9d82Sdan **
2641935d9d82Sdan ** The new "continue" statement in the above jumps to the next iteration
2642935d9d82Sdan ** of the outer loop - the one started by sqlite3WhereBegin().
2643935d9d82Sdan **
2644935d9d82Sdan ** The various GROUPS cases are implemented using the same patterns as
2645935d9d82Sdan ** ROWS. The VM code is modified slightly so that:
2646935d9d82Sdan **
2647935d9d82Sdan **   1. The else branch in the main loop is only taken if the row just
2648935d9d82Sdan **      added to the ephemeral table is the start of a new group. In
2649935d9d82Sdan **      other words, it becomes:
2650935d9d82Sdan **
2651935d9d82Sdan **         ... loop started by sqlite3WhereBegin() ...
2652935d9d82Sdan **         if( new partition ){
2653935d9d82Sdan **           Gosub flush
2654935d9d82Sdan **         }
2655935d9d82Sdan **         Insert new row into eph table.
2656935d9d82Sdan **         if( first row of partition ){
2657935d9d82Sdan **           Rewind(csrEnd) ; Rewind(csrStart) ; Rewind(csrCurrent)
2658935d9d82Sdan **           regEnd = <expr2>
2659935d9d82Sdan **           regStart = <expr1>
2660935d9d82Sdan **         }else if( new group ){
2661935d9d82Sdan **           ...
2662935d9d82Sdan **         }
2663935d9d82Sdan **       }
2664935d9d82Sdan **
2665935d9d82Sdan **   2. Instead of processing a single row, each RETURN_ROW, AGGSTEP or
2666935d9d82Sdan **      AGGINVERSE step processes the current row of the relevant cursor and
2667935d9d82Sdan **      all subsequent rows belonging to the same group.
2668935d9d82Sdan **
2669935d9d82Sdan ** RANGE window frames are a little different again. As for GROUPS, the
2670935d9d82Sdan ** main loop runs once per group only. And RETURN_ROW, AGGSTEP and AGGINVERSE
2671935d9d82Sdan ** deal in groups instead of rows. As for ROWS and GROUPS, there are three
2672935d9d82Sdan ** basic cases:
2673935d9d82Sdan **
2674935d9d82Sdan **   RANGE BETWEEN <expr1> PRECEDING AND <expr2> FOLLOWING
2675935d9d82Sdan **
2676935d9d82Sdan **     ... loop started by sqlite3WhereBegin() ...
2677935d9d82Sdan **       if( new partition ){
2678935d9d82Sdan **         Gosub flush
2679935d9d82Sdan **       }
2680935d9d82Sdan **       Insert new row into eph table.
2681935d9d82Sdan **       if( first row of partition ){
2682935d9d82Sdan **         Rewind(csrEnd) ; Rewind(csrStart) ; Rewind(csrCurrent)
2683935d9d82Sdan **         regEnd = <expr2>
2684935d9d82Sdan **         regStart = <expr1>
2685935d9d82Sdan **       }else{
2686935d9d82Sdan **         AGGSTEP
2687935d9d82Sdan **         while( (csrCurrent.key + regEnd) < csrEnd.key ){
2688935d9d82Sdan **           RETURN_ROW
2689935d9d82Sdan **           while( csrStart.key + regStart) < csrCurrent.key ){
2690935d9d82Sdan **             AGGINVERSE
2691935d9d82Sdan **           }
2692935d9d82Sdan **         }
2693935d9d82Sdan **       }
2694935d9d82Sdan **     }
2695935d9d82Sdan **     flush:
2696935d9d82Sdan **       AGGSTEP
2697935d9d82Sdan **       while( 1 ){
2698935d9d82Sdan **         RETURN ROW
2699935d9d82Sdan **         if( csrCurrent is EOF ) break;
2700935d9d82Sdan **           while( csrStart.key + regStart) < csrCurrent.key ){
2701935d9d82Sdan **             AGGINVERSE
2702935d9d82Sdan **           }
2703935d9d82Sdan **         }
2704935d9d82Sdan **       }
2705935d9d82Sdan **
2706935d9d82Sdan ** In the above notation, "csr.key" means the current value of the ORDER BY
2707935d9d82Sdan ** expression (there is only ever 1 for a RANGE that uses an <expr> FOLLOWING
2708935d9d82Sdan ** or <expr PRECEDING) read from cursor csr.
2709935d9d82Sdan **
2710935d9d82Sdan **   RANGE BETWEEN <expr1> PRECEDING AND <expr2> PRECEDING
2711935d9d82Sdan **
2712935d9d82Sdan **     ... loop started by sqlite3WhereBegin() ...
2713935d9d82Sdan **       if( new partition ){
2714935d9d82Sdan **         Gosub flush
2715935d9d82Sdan **       }
2716935d9d82Sdan **       Insert new row into eph table.
2717935d9d82Sdan **       if( first row of partition ){
2718935d9d82Sdan **         Rewind(csrEnd) ; Rewind(csrStart) ; Rewind(csrCurrent)
2719935d9d82Sdan **         regEnd = <expr2>
2720935d9d82Sdan **         regStart = <expr1>
2721935d9d82Sdan **       }else{
272237d296a7Sdan **         while( (csrEnd.key + regEnd) <= csrCurrent.key ){
2723935d9d82Sdan **           AGGSTEP
2724935d9d82Sdan **         }
2725935d9d82Sdan **         while( (csrStart.key + regStart) < csrCurrent.key ){
2726935d9d82Sdan **           AGGINVERSE
2727935d9d82Sdan **         }
2728e7579a53Sdan **         RETURN_ROW
2729935d9d82Sdan **       }
2730935d9d82Sdan **     }
2731935d9d82Sdan **     flush:
2732935d9d82Sdan **       while( (csrEnd.key + regEnd) <= csrCurrent.key ){
2733935d9d82Sdan **         AGGSTEP
2734935d9d82Sdan **       }
27353f49c321Sdan **       while( (csrStart.key + regStart) < csrCurrent.key ){
27363f49c321Sdan **         AGGINVERSE
27373f49c321Sdan **       }
2738e7579a53Sdan **       RETURN_ROW
2739935d9d82Sdan **
2740935d9d82Sdan **   RANGE BETWEEN <expr1> FOLLOWING AND <expr2> FOLLOWING
2741935d9d82Sdan **
2742935d9d82Sdan **     ... loop started by sqlite3WhereBegin() ...
2743935d9d82Sdan **       if( new partition ){
2744935d9d82Sdan **         Gosub flush
2745935d9d82Sdan **       }
2746935d9d82Sdan **       Insert new row into eph table.
2747935d9d82Sdan **       if( first row of partition ){
2748935d9d82Sdan **         Rewind(csrEnd) ; Rewind(csrStart) ; Rewind(csrCurrent)
2749935d9d82Sdan **         regEnd = <expr2>
2750935d9d82Sdan **         regStart = <expr1>
2751935d9d82Sdan **       }else{
2752935d9d82Sdan **         AGGSTEP
2753935d9d82Sdan **         while( (csrCurrent.key + regEnd) < csrEnd.key ){
2754935d9d82Sdan **           while( (csrCurrent.key + regStart) > csrStart.key ){
2755935d9d82Sdan **             AGGINVERSE
2756935d9d82Sdan **           }
2757935d9d82Sdan **           RETURN_ROW
2758935d9d82Sdan **         }
2759935d9d82Sdan **       }
2760935d9d82Sdan **     }
2761935d9d82Sdan **     flush:
2762935d9d82Sdan **       AGGSTEP
2763935d9d82Sdan **       while( 1 ){
2764935d9d82Sdan **         while( (csrCurrent.key + regStart) > csrStart.key ){
2765935d9d82Sdan **           AGGINVERSE
2766935d9d82Sdan **           if( eof ) break "while( 1 )" loop.
2767935d9d82Sdan **         }
2768935d9d82Sdan **         RETURN_ROW
2769935d9d82Sdan **       }
2770935d9d82Sdan **       while( !eof csrCurrent ){
2771935d9d82Sdan **         RETURN_ROW
2772935d9d82Sdan **       }
2773935d9d82Sdan **
2774b6f2deacSdan ** The text above leaves out many details. Refer to the code and comments
2775b6f2deacSdan ** below for a more complete picture.
277600267b8aSdan */
sqlite3WindowCodeStep(Parse * pParse,Select * p,WhereInfo * pWInfo,int regGosub,int addrGosub)2777a786e453Sdan void sqlite3WindowCodeStep(
2778a786e453Sdan   Parse *pParse,                  /* Parse context */
2779a786e453Sdan   Select *p,                      /* Rewritten SELECT statement */
2780a786e453Sdan   WhereInfo *pWInfo,              /* Context returned by sqlite3WhereBegin() */
2781a786e453Sdan   int regGosub,                   /* Register for OP_Gosub */
2782a786e453Sdan   int addrGosub                   /* OP_Gosub here to return each row */
2783680f6e8eSdan ){
2784680f6e8eSdan   Window *pMWin = p->pWin;
27856c75b396Sdan   ExprList *pOrderBy = pMWin->pOrderBy;
2786680f6e8eSdan   Vdbe *v = sqlite3GetVdbe(pParse);
2787a786e453Sdan   int csrWrite;                   /* Cursor used to write to eph. table */
2788a786e453Sdan   int csrInput = p->pSrc->a[0].iCursor;     /* Cursor of sub-select */
2789a786e453Sdan   int nInput = p->pSrc->a[0].pTab->nCol;    /* Number of cols returned by sub */
2790a786e453Sdan   int iInput;                               /* To iterate through sub cols */
2791bf84515aSdan   int addrNe;                     /* Address of OP_Ne */
2792d4a591ddSdrh   int addrGosubFlush = 0;         /* Address of OP_Gosub to flush: */
2793d4a591ddSdrh   int addrInteger = 0;            /* Address of OP_Integer */
2794d446165fSdan   int addrEmpty;                  /* Address of OP_Rewind in flush: */
2795a786e453Sdan   int regNew;                     /* Array of registers holding new input row */
2796a786e453Sdan   int regRecord;                  /* regNew array in record form */
2797a786e453Sdan   int regNewPeer = 0;             /* Peer values for new row (part of regNew) */
2798a786e453Sdan   int regPeer = 0;                /* Peer values for current row */
2799d446165fSdan   int regFlushPart = 0;           /* Register for "Gosub flush_partition" */
2800a786e453Sdan   WindowCodeArg s;                /* Context object for sub-routines */
2801935d9d82Sdan   int lblWhereEnd;                /* Label just before sqlite3WhereEnd() code */
2802e7579a53Sdan   int regStart = 0;               /* Value of <expr> PRECEDING */
2803e7579a53Sdan   int regEnd = 0;                 /* Value of <expr> FOLLOWING */
2804680f6e8eSdan 
280572b9fdcfSdan   assert( pMWin->eStart==TK_PRECEDING || pMWin->eStart==TK_CURRENT
280672b9fdcfSdan        || pMWin->eStart==TK_FOLLOWING || pMWin->eStart==TK_UNBOUNDED
280772b9fdcfSdan   );
280872b9fdcfSdan   assert( pMWin->eEnd==TK_FOLLOWING || pMWin->eEnd==TK_CURRENT
280972b9fdcfSdan        || pMWin->eEnd==TK_UNBOUNDED || pMWin->eEnd==TK_PRECEDING
281072b9fdcfSdan   );
2811108e6b2cSdan   assert( pMWin->eExclude==0 || pMWin->eExclude==TK_CURRENT
2812108e6b2cSdan        || pMWin->eExclude==TK_GROUP || pMWin->eExclude==TK_TIES
2813108e6b2cSdan        || pMWin->eExclude==TK_NO
2814108e6b2cSdan   );
281572b9fdcfSdan 
2816935d9d82Sdan   lblWhereEnd = sqlite3VdbeMakeLabel(pParse);
2817a786e453Sdan 
2818a786e453Sdan   /* Fill in the context object */
281900267b8aSdan   memset(&s, 0, sizeof(WindowCodeArg));
282000267b8aSdan   s.pParse = pParse;
282100267b8aSdan   s.pMWin = pMWin;
282200267b8aSdan   s.pVdbe = v;
282300267b8aSdan   s.regGosub = regGosub;
282400267b8aSdan   s.addrGosub = addrGosub;
28256c75b396Sdan   s.current.csr = pMWin->iEphCsr;
2826a786e453Sdan   csrWrite = s.current.csr+1;
28276c75b396Sdan   s.start.csr = s.current.csr+2;
28286c75b396Sdan   s.end.csr = s.current.csr+3;
2829b33487b0Sdan 
2830b560a719Sdan   /* Figure out when rows may be deleted from the ephemeral table. There
2831b560a719Sdan   ** are four options - they may never be deleted (eDelete==0), they may
2832b560a719Sdan   ** be deleted as soon as they are no longer part of the window frame
2833b560a719Sdan   ** (eDelete==WINDOW_AGGINVERSE), they may be deleted as after the row
2834b560a719Sdan   ** has been returned to the caller (WINDOW_RETURN_ROW), or they may
2835b560a719Sdan   ** be deleted after they enter the frame (WINDOW_AGGSTEP). */
2836b560a719Sdan   switch( pMWin->eStart ){
2837725b1cfcSdan     case TK_FOLLOWING:
2838fc15f4c5Sdrh       if( pMWin->eFrmType!=TK_RANGE
2839fc15f4c5Sdrh        && windowExprGtZero(pParse, pMWin->pStart)
2840fc15f4c5Sdrh       ){
2841b560a719Sdan         s.eDelete = WINDOW_RETURN_ROW;
2842b560a719Sdan       }
2843b560a719Sdan       break;
2844b560a719Sdan     case TK_UNBOUNDED:
2845b560a719Sdan       if( windowCacheFrame(pMWin)==0 ){
2846b560a719Sdan         if( pMWin->eEnd==TK_PRECEDING ){
2847fc15f4c5Sdrh           if( pMWin->eFrmType!=TK_RANGE
2848fc15f4c5Sdrh            && windowExprGtZero(pParse, pMWin->pEnd)
2849fc15f4c5Sdrh           ){
2850b560a719Sdan             s.eDelete = WINDOW_AGGSTEP;
2851725b1cfcSdan           }
2852b560a719Sdan         }else{
2853b560a719Sdan           s.eDelete = WINDOW_RETURN_ROW;
2854b560a719Sdan         }
2855b560a719Sdan       }
2856b560a719Sdan       break;
2857b560a719Sdan     default:
2858b560a719Sdan       s.eDelete = WINDOW_AGGINVERSE;
2859b560a719Sdan       break;
2860b560a719Sdan   }
2861b560a719Sdan 
2862d446165fSdan   /* Allocate registers for the array of values from the sub-query, the
2863d446165fSdan   ** samve values in record form, and the rowid used to insert said record
2864d446165fSdan   ** into the ephemeral table.  */
2865a786e453Sdan   regNew = pParse->nMem+1;
2866a786e453Sdan   pParse->nMem += nInput;
2867a786e453Sdan   regRecord = ++pParse->nMem;
2868113a33c5Sdrh   s.regRowid = ++pParse->nMem;
286954975cdfSdan 
2870a786e453Sdan   /* If the window frame contains an "<expr> PRECEDING" or "<expr> FOLLOWING"
2871a786e453Sdan   ** clause, allocate registers to store the results of evaluating each
2872a786e453Sdan   ** <expr>.  */
287354975cdfSdan   if( pMWin->eStart==TK_PRECEDING || pMWin->eStart==TK_FOLLOWING ){
2874e7579a53Sdan     regStart = ++pParse->nMem;
287554975cdfSdan   }
287654975cdfSdan   if( pMWin->eEnd==TK_PRECEDING || pMWin->eEnd==TK_FOLLOWING ){
2877e7579a53Sdan     regEnd = ++pParse->nMem;
287854975cdfSdan   }
2879680f6e8eSdan 
288072b9fdcfSdan   /* If this is not a "ROWS BETWEEN ..." frame, then allocate arrays of
2881a786e453Sdan   ** registers to store copies of the ORDER BY expressions (peer values)
2882a786e453Sdan   ** for the main loop, and for each cursor (start, current and end). */
2883fc15f4c5Sdrh   if( pMWin->eFrmType!=TK_ROWS ){
28846c75b396Sdan     int nPeer = (pOrderBy ? pOrderBy->nExpr : 0);
2885a786e453Sdan     regNewPeer = regNew + pMWin->nBufferCol;
28866c75b396Sdan     if( pMWin->pPartition ) regNewPeer += pMWin->pPartition->nExpr;
28876c75b396Sdan     regPeer = pParse->nMem+1;       pParse->nMem += nPeer;
28886c75b396Sdan     s.start.reg = pParse->nMem+1;   pParse->nMem += nPeer;
28896c75b396Sdan     s.current.reg = pParse->nMem+1; pParse->nMem += nPeer;
28906c75b396Sdan     s.end.reg = pParse->nMem+1;     pParse->nMem += nPeer;
28916c75b396Sdan   }
28926c75b396Sdan 
2893680f6e8eSdan   /* Load the column values for the row returned by the sub-select
2894a786e453Sdan   ** into an array of registers starting at regNew. Assemble them into
2895a786e453Sdan   ** a record in register regRecord. */
2896a786e453Sdan   for(iInput=0; iInput<nInput; iInput++){
2897a786e453Sdan     sqlite3VdbeAddOp3(v, OP_Column, csrInput, iInput, regNew+iInput);
2898680f6e8eSdan   }
2899a786e453Sdan   sqlite3VdbeAddOp3(v, OP_MakeRecord, regNew, nInput, regRecord);
2900680f6e8eSdan 
2901b33487b0Sdan   /* An input row has just been read into an array of registers starting
2902a786e453Sdan   ** at regNew. If the window has a PARTITION clause, this block generates
2903b33487b0Sdan   ** VM code to check if the input row is the start of a new partition.
2904b33487b0Sdan   ** If so, it does an OP_Gosub to an address to be filled in later. The
2905a786e453Sdan   ** address of the OP_Gosub is stored in local variable addrGosubFlush. */
2906680f6e8eSdan   if( pMWin->pPartition ){
2907680f6e8eSdan     int addr;
2908680f6e8eSdan     ExprList *pPart = pMWin->pPartition;
2909680f6e8eSdan     int nPart = pPart->nExpr;
2910a786e453Sdan     int regNewPart = regNew + pMWin->nBufferCol;
2911680f6e8eSdan     KeyInfo *pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pPart, 0, 0);
2912680f6e8eSdan 
2913d446165fSdan     regFlushPart = ++pParse->nMem;
2914680f6e8eSdan     addr = sqlite3VdbeAddOp3(v, OP_Compare, regNewPart, pMWin->regPart, nPart);
2915680f6e8eSdan     sqlite3VdbeAppendP4(v, (void*)pKeyInfo, P4_KEYINFO);
2916b33487b0Sdan     sqlite3VdbeAddOp3(v, OP_Jump, addr+2, addr+4, addr+2);
2917680f6e8eSdan     VdbeCoverageEqNe(v);
2918680f6e8eSdan     addrGosubFlush = sqlite3VdbeAddOp1(v, OP_Gosub, regFlushPart);
2919680f6e8eSdan     VdbeComment((v, "call flush_partition"));
2920b33487b0Sdan     sqlite3VdbeAddOp3(v, OP_Copy, regNewPart, pMWin->regPart, nPart-1);
2921680f6e8eSdan   }
2922680f6e8eSdan 
2923680f6e8eSdan   /* Insert the new row into the ephemeral table */
2924113a33c5Sdrh   sqlite3VdbeAddOp2(v, OP_NewRowid, csrWrite, s.regRowid);
2925113a33c5Sdrh   sqlite3VdbeAddOp3(v, OP_Insert, csrWrite, regRecord, s.regRowid);
2926113a33c5Sdrh   addrNe = sqlite3VdbeAddOp3(v, OP_Ne, pMWin->regOne, 0, s.regRowid);
292783c5bb99Sdrh   VdbeCoverageNeverNull(v);
2928b25a214dSdan 
2929b33487b0Sdan   /* This block is run for the first row of each partition */
2930a786e453Sdan   s.regArg = windowInitAccum(pParse, pMWin);
2931680f6e8eSdan 
2932e7579a53Sdan   if( regStart ){
2933e7579a53Sdan     sqlite3ExprCode(pParse, pMWin->pStart, regStart);
2934e7579a53Sdan     windowCheckValue(pParse, regStart, 0 + (pMWin->eFrmType==TK_RANGE?3:0));
293554975cdfSdan   }
2936e7579a53Sdan   if( regEnd ){
2937e7579a53Sdan     sqlite3ExprCode(pParse, pMWin->pEnd, regEnd);
2938e7579a53Sdan     windowCheckValue(pParse, regEnd, 1 + (pMWin->eFrmType==TK_RANGE?3:0));
293954975cdfSdan   }
2940b25a214dSdan 
2941e7579a53Sdan   if( pMWin->eFrmType!=TK_RANGE && pMWin->eStart==pMWin->eEnd && regStart ){
2942b25a214dSdan     int op = ((pMWin->eStart==TK_FOLLOWING) ? OP_Ge : OP_Le);
2943e7579a53Sdan     int addrGe = sqlite3VdbeAddOp3(v, op, regStart, 0, regEnd);
2944495ed62eSdrh     VdbeCoverageNeverNullIf(v, op==OP_Ge); /* NeverNull because bound <expr> */
2945495ed62eSdrh     VdbeCoverageNeverNullIf(v, op==OP_Le); /*   values previously checked */
2946c782a81aSdan     windowAggFinal(&s, 0);
29476c75b396Sdan     sqlite3VdbeAddOp2(v, OP_Rewind, s.current.csr, 1);
29481d4b25faSdan     VdbeCoverageNeverTaken(v);
2949c782a81aSdan     windowReturnOneRow(&s);
29506c75b396Sdan     sqlite3VdbeAddOp1(v, OP_ResetSorter, s.current.csr);
2951935d9d82Sdan     sqlite3VdbeAddOp2(v, OP_Goto, 0, lblWhereEnd);
2952b25a214dSdan     sqlite3VdbeJumpHere(v, addrGe);
2953b25a214dSdan   }
2954e7579a53Sdan   if( pMWin->eStart==TK_FOLLOWING && pMWin->eFrmType!=TK_RANGE && regEnd ){
295554975cdfSdan     assert( pMWin->eEnd==TK_FOLLOWING );
2956e7579a53Sdan     sqlite3VdbeAddOp3(v, OP_Subtract, regStart, regEnd, regStart);
2957b25a214dSdan   }
2958b25a214dSdan 
295954975cdfSdan   if( pMWin->eStart!=TK_UNBOUNDED ){
29606c75b396Sdan     sqlite3VdbeAddOp2(v, OP_Rewind, s.start.csr, 1);
29611d4b25faSdan     VdbeCoverageNeverTaken(v);
296254975cdfSdan   }
29636c75b396Sdan   sqlite3VdbeAddOp2(v, OP_Rewind, s.current.csr, 1);
29641d4b25faSdan   VdbeCoverageNeverTaken(v);
29656c75b396Sdan   sqlite3VdbeAddOp2(v, OP_Rewind, s.end.csr, 1);
29661d4b25faSdan   VdbeCoverageNeverTaken(v);
29676c75b396Sdan   if( regPeer && pOrderBy ){
29686c75b396Sdan     sqlite3VdbeAddOp3(v, OP_Copy, regNewPeer, regPeer, pOrderBy->nExpr-1);
29696c75b396Sdan     sqlite3VdbeAddOp3(v, OP_Copy, regPeer, s.start.reg, pOrderBy->nExpr-1);
29706c75b396Sdan     sqlite3VdbeAddOp3(v, OP_Copy, regPeer, s.current.reg, pOrderBy->nExpr-1);
29716c75b396Sdan     sqlite3VdbeAddOp3(v, OP_Copy, regPeer, s.end.reg, pOrderBy->nExpr-1);
29726c75b396Sdan   }
2973b25a214dSdan 
2974935d9d82Sdan   sqlite3VdbeAddOp2(v, OP_Goto, 0, lblWhereEnd);
2975680f6e8eSdan 
2976bf84515aSdan   sqlite3VdbeJumpHere(v, addrNe);
29773f49c321Sdan 
29783f49c321Sdan   /* Beginning of the block executed for the second and subsequent rows. */
29796c75b396Sdan   if( regPeer ){
2980935d9d82Sdan     windowIfNewPeer(pParse, pOrderBy, regNewPeer, regPeer, lblWhereEnd);
29816c75b396Sdan   }
2982b25a214dSdan   if( pMWin->eStart==TK_FOLLOWING ){
29836c75b396Sdan     windowCodeOp(&s, WINDOW_AGGSTEP, 0, 0);
298454975cdfSdan     if( pMWin->eEnd!=TK_UNBOUNDED ){
2985fc15f4c5Sdrh       if( pMWin->eFrmType==TK_RANGE ){
298672b9fdcfSdan         int lbl = sqlite3VdbeMakeLabel(pParse);
298772b9fdcfSdan         int addrNext = sqlite3VdbeCurrentAddr(v);
2988e7579a53Sdan         windowCodeRangeTest(&s, OP_Ge, s.current.csr, regEnd, s.end.csr, lbl);
2989e7579a53Sdan         windowCodeOp(&s, WINDOW_AGGINVERSE, regStart, 0);
299072b9fdcfSdan         windowCodeOp(&s, WINDOW_RETURN_ROW, 0, 0);
299172b9fdcfSdan         sqlite3VdbeAddOp2(v, OP_Goto, 0, addrNext);
299272b9fdcfSdan         sqlite3VdbeResolveLabel(v, lbl);
299372b9fdcfSdan       }else{
2994e7579a53Sdan         windowCodeOp(&s, WINDOW_RETURN_ROW, regEnd, 0);
2995e7579a53Sdan         windowCodeOp(&s, WINDOW_AGGINVERSE, regStart, 0);
299654975cdfSdan       }
299772b9fdcfSdan     }
2998b25a214dSdan   }else
2999b25a214dSdan   if( pMWin->eEnd==TK_PRECEDING ){
30003f49c321Sdan     int bRPS = (pMWin->eStart==TK_PRECEDING && pMWin->eFrmType==TK_RANGE);
3001e7579a53Sdan     windowCodeOp(&s, WINDOW_AGGSTEP, regEnd, 0);
3002e7579a53Sdan     if( bRPS ) windowCodeOp(&s, WINDOW_AGGINVERSE, regStart, 0);
30036c75b396Sdan     windowCodeOp(&s, WINDOW_RETURN_ROW, 0, 0);
3004e7579a53Sdan     if( !bRPS ) windowCodeOp(&s, WINDOW_AGGINVERSE, regStart, 0);
3005b25a214dSdan   }else{
3006ba9ee095Smistachkin     int addr = 0;
30076c75b396Sdan     windowCodeOp(&s, WINDOW_AGGSTEP, 0, 0);
300854975cdfSdan     if( pMWin->eEnd!=TK_UNBOUNDED ){
3009fc15f4c5Sdrh       if( pMWin->eFrmType==TK_RANGE ){
3010ba9ee095Smistachkin         int lbl = 0;
301172b9fdcfSdan         addr = sqlite3VdbeCurrentAddr(v);
3012e7579a53Sdan         if( regEnd ){
301372b9fdcfSdan           lbl = sqlite3VdbeMakeLabel(pParse);
3014e7579a53Sdan           windowCodeRangeTest(&s, OP_Ge, s.current.csr, regEnd, s.end.csr, lbl);
301572b9fdcfSdan         }
301672b9fdcfSdan         windowCodeOp(&s, WINDOW_RETURN_ROW, 0, 0);
3017e7579a53Sdan         windowCodeOp(&s, WINDOW_AGGINVERSE, regStart, 0);
3018e7579a53Sdan         if( regEnd ){
301972b9fdcfSdan           sqlite3VdbeAddOp2(v, OP_Goto, 0, addr);
302072b9fdcfSdan           sqlite3VdbeResolveLabel(v, lbl);
302172b9fdcfSdan         }
302272b9fdcfSdan       }else{
3023e7579a53Sdan         if( regEnd ){
3024e7579a53Sdan           addr = sqlite3VdbeAddOp3(v, OP_IfPos, regEnd, 0, 1);
30251d4b25faSdan           VdbeCoverage(v);
30261d4b25faSdan         }
30276c75b396Sdan         windowCodeOp(&s, WINDOW_RETURN_ROW, 0, 0);
3028e7579a53Sdan         windowCodeOp(&s, WINDOW_AGGINVERSE, regStart, 0);
3029e7579a53Sdan         if( regEnd ) sqlite3VdbeJumpHere(v, addr);
303054975cdfSdan       }
3031b25a214dSdan     }
303272b9fdcfSdan   }
3033680f6e8eSdan 
3034680f6e8eSdan   /* End of the main input loop */
3035935d9d82Sdan   sqlite3VdbeResolveLabel(v, lblWhereEnd);
3036680f6e8eSdan   sqlite3WhereEnd(pWInfo);
3037680f6e8eSdan 
3038680f6e8eSdan   /* Fall through */
3039cc7a850fSdan   if( pMWin->pPartition ){
3040680f6e8eSdan     addrInteger = sqlite3VdbeAddOp2(v, OP_Integer, 0, regFlushPart);
3041680f6e8eSdan     sqlite3VdbeJumpHere(v, addrGosubFlush);
3042680f6e8eSdan   }
3043680f6e8eSdan 
3044113a33c5Sdrh   s.regRowid = 0;
3045c813750bSdan   addrEmpty = sqlite3VdbeAddOp1(v, OP_Rewind, csrWrite);
30461d4b25faSdan   VdbeCoverage(v);
3047b25a214dSdan   if( pMWin->eEnd==TK_PRECEDING ){
30483f49c321Sdan     int bRPS = (pMWin->eStart==TK_PRECEDING && pMWin->eFrmType==TK_RANGE);
3049e7579a53Sdan     windowCodeOp(&s, WINDOW_AGGSTEP, regEnd, 0);
3050e7579a53Sdan     if( bRPS ) windowCodeOp(&s, WINDOW_AGGINVERSE, regStart, 0);
30516c75b396Sdan     windowCodeOp(&s, WINDOW_RETURN_ROW, 0, 0);
3052c813750bSdan   }else if( pMWin->eStart==TK_FOLLOWING ){
3053c813750bSdan     int addrStart;
3054c813750bSdan     int addrBreak1;
3055c813750bSdan     int addrBreak2;
3056c813750bSdan     int addrBreak3;
30576c75b396Sdan     windowCodeOp(&s, WINDOW_AGGSTEP, 0, 0);
3058fc15f4c5Sdrh     if( pMWin->eFrmType==TK_RANGE ){
305972b9fdcfSdan       addrStart = sqlite3VdbeCurrentAddr(v);
3060e7579a53Sdan       addrBreak2 = windowCodeOp(&s, WINDOW_AGGINVERSE, regStart, 1);
306172b9fdcfSdan       addrBreak1 = windowCodeOp(&s, WINDOW_RETURN_ROW, 0, 1);
306272b9fdcfSdan     }else
306354975cdfSdan     if( pMWin->eEnd==TK_UNBOUNDED ){
306454975cdfSdan       addrStart = sqlite3VdbeCurrentAddr(v);
3065e7579a53Sdan       addrBreak1 = windowCodeOp(&s, WINDOW_RETURN_ROW, regStart, 1);
30666c75b396Sdan       addrBreak2 = windowCodeOp(&s, WINDOW_AGGINVERSE, 0, 1);
306754975cdfSdan     }else{
306854975cdfSdan       assert( pMWin->eEnd==TK_FOLLOWING );
3069c813750bSdan       addrStart = sqlite3VdbeCurrentAddr(v);
3070e7579a53Sdan       addrBreak1 = windowCodeOp(&s, WINDOW_RETURN_ROW, regEnd, 1);
3071e7579a53Sdan       addrBreak2 = windowCodeOp(&s, WINDOW_AGGINVERSE, regStart, 1);
307254975cdfSdan     }
3073c813750bSdan     sqlite3VdbeAddOp2(v, OP_Goto, 0, addrStart);
3074c813750bSdan     sqlite3VdbeJumpHere(v, addrBreak2);
3075c813750bSdan     addrStart = sqlite3VdbeCurrentAddr(v);
30766c75b396Sdan     addrBreak3 = windowCodeOp(&s, WINDOW_RETURN_ROW, 0, 1);
3077c813750bSdan     sqlite3VdbeAddOp2(v, OP_Goto, 0, addrStart);
3078c813750bSdan     sqlite3VdbeJumpHere(v, addrBreak1);
3079c813750bSdan     sqlite3VdbeJumpHere(v, addrBreak3);
3080b25a214dSdan   }else{
308100267b8aSdan     int addrBreak;
3082c813750bSdan     int addrStart;
30836c75b396Sdan     windowCodeOp(&s, WINDOW_AGGSTEP, 0, 0);
3084c813750bSdan     addrStart = sqlite3VdbeCurrentAddr(v);
30856c75b396Sdan     addrBreak = windowCodeOp(&s, WINDOW_RETURN_ROW, 0, 1);
3086e7579a53Sdan     windowCodeOp(&s, WINDOW_AGGINVERSE, regStart, 0);
308700267b8aSdan     sqlite3VdbeAddOp2(v, OP_Goto, 0, addrStart);
308800267b8aSdan     sqlite3VdbeJumpHere(v, addrBreak);
3089b25a214dSdan   }
3090c813750bSdan   sqlite3VdbeJumpHere(v, addrEmpty);
3091c813750bSdan 
30926c75b396Sdan   sqlite3VdbeAddOp1(v, OP_ResetSorter, s.current.csr);
3093680f6e8eSdan   if( pMWin->pPartition ){
3094a0f6b833Sdan     if( pMWin->regStartRowid ){
3095a0f6b833Sdan       sqlite3VdbeAddOp2(v, OP_Integer, 1, pMWin->regStartRowid);
3096a0f6b833Sdan       sqlite3VdbeAddOp2(v, OP_Integer, 0, pMWin->regEndRowid);
3097a0f6b833Sdan     }
3098680f6e8eSdan     sqlite3VdbeChangeP1(v, addrInteger, sqlite3VdbeCurrentAddr(v));
3099680f6e8eSdan     sqlite3VdbeAddOp1(v, OP_Return, regFlushPart);
3100680f6e8eSdan   }
3101680f6e8eSdan }
3102680f6e8eSdan 
310367a9b8edSdan #endif /* SQLITE_OMIT_WINDOWFUNC */
3104