OpenCoverage

window.c

Absolute File Name:/home/opencoverage/opencoverage/guest-scripts/sqlite/src/src/window.c
Source codeSwitch to Preprocessed file
LineSourceCount
1/*-
2** 2018 May 08-
3**-
4** The author disclaims copyright to this source code. In place of-
5** a legal notice, here is a blessing:-
6**-
7** May you do good and not evil.-
8** May you find forgiveness for yourself and forgive others.-
9** May you share freely, never taking more than you give.-
10**-
11*************************************************************************-
12*/-
13#include "sqliteInt.h"-
14-
15#ifndef SQLITE_OMIT_WINDOWFUNC-
16-
17/*-
18** SELECT REWRITING-
19**-
20** Any SELECT statement that contains one or more window functions in-
21** either the select list or ORDER BY clause (the only two places window-
22** functions may be used) is transformed by function sqlite3WindowRewrite()-
23** in order to support window function processing. For example, with the-
24** schema:-
25**-
26** CREATE TABLE t1(a, b, c, d, e, f, g);-
27**-
28** the statement:-
29**-
30** SELECT a+1, max(b) OVER (PARTITION BY c ORDER BY d) FROM t1 ORDER BY e;-
31**-
32** is transformed to:-
33**-
34** SELECT a+1, max(b) OVER (PARTITION BY c ORDER BY d) FROM (-
35** SELECT a, e, c, d, b FROM t1 ORDER BY c, d-
36** ) ORDER BY e;-
37**-
38** The flattening optimization is disabled when processing this transformed-
39** SELECT statement. This allows the implementation of the window function-
40** (in this case max()) to process rows sorted in order of (c, d), which-
41** makes things easier for obvious reasons. More generally:-
42**-
43** * FROM, WHERE, GROUP BY and HAVING clauses are all moved to -
44** the sub-query.-
45**-
46** * ORDER BY, LIMIT and OFFSET remain part of the parent query.-
47**-
48** * Terminals from each of the expression trees that make up the -
49** select-list and ORDER BY expressions in the parent query are-
50** selected by the sub-query. For the purposes of the transformation,-
51** terminals are column references and aggregate functions.-
52**-
53** If there is more than one window function in the SELECT that uses-
54** the same window declaration (the OVER bit), then a single scan may-
55** be used to process more than one window function. For example:-
56**-
57** SELECT max(b) OVER (PARTITION BY c ORDER BY d), -
58** min(e) OVER (PARTITION BY c ORDER BY d) -
59** FROM t1;-
60**-
61** is transformed in the same way as the example above. However:-
62**-
63** SELECT max(b) OVER (PARTITION BY c ORDER BY d), -
64** min(e) OVER (PARTITION BY a ORDER BY b) -
65** FROM t1;-
66**-
67** Must be transformed to:-
68**-
69** SELECT max(b) OVER (PARTITION BY c ORDER BY d) FROM (-
70** SELECT e, min(e) OVER (PARTITION BY a ORDER BY b), c, d, b FROM-
71** SELECT a, e, c, d, b FROM t1 ORDER BY a, b-
72** ) ORDER BY c, d-
73** ) ORDER BY e;-
74**-
75** so that both min() and max() may process rows in the order defined by-
76** their respective window declarations.-
77**-
78** INTERFACE WITH SELECT.C-
79**-
80** When processing the rewritten SELECT statement, code in select.c calls-
81** sqlite3WhereBegin() to begin iterating through the results of the-
82** sub-query, which is always implemented as a co-routine. It then calls-
83** sqlite3WindowCodeStep() to process rows and finish the scan by calling-
84** sqlite3WhereEnd().-
85**-
86** sqlite3WindowCodeStep() generates VM code so that, for each row returned-
87** by the sub-query a sub-routine (OP_Gosub) coded by select.c is invoked.-
88** When the sub-routine is invoked:-
89**-
90** * The results of all window-functions for the row are stored-
91** in the associated Window.regResult registers.-
92**-
93** * The required terminal values are stored in the current row of-
94** temp table Window.iEphCsr.-
95**-
96** In some cases, depending on the window frame and the specific window-
97** functions invoked, sqlite3WindowCodeStep() caches each entire partition-
98** in a temp table before returning any rows. In other cases it does not.-
99** This detail is encapsulated within this file, the code generated by-
100** select.c is the same in either case.-
101**-
102** BUILT-IN WINDOW FUNCTIONS-
103**-
104** This implementation features the following built-in window functions:-
105**-
106** row_number()-
107** rank()-
108** dense_rank()-
109** percent_rank()-
110** cume_dist()-
111** ntile(N)-
112** lead(expr [, offset [, default]])-
113** lag(expr [, offset [, default]])-
114** first_value(expr)-
115** last_value(expr)-
116** nth_value(expr, N)-
117** -
118** These are the same built-in window functions supported by Postgres. -
119** Although the behaviour of aggregate window functions (functions that-
120** can be used as either aggregates or window funtions) allows them to-
121** be implemented using an API, built-in window functions are much more-
122** esoteric. Additionally, some window functions (e.g. nth_value()) -
123** may only be implemented by caching the entire partition in memory.-
124** As such, some built-in window functions use the same API as aggregate-
125** window functions and some are implemented directly using VDBE -
126** instructions. Additionally, for those functions that use the API, the-
127** window frame is sometimes modified before the SELECT statement is-
128** rewritten. For example, regardless of the specified window frame, the-
129** row_number() function always uses:-
130**-
131** ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW-
132**-
133** See sqlite3WindowUpdate() for details.-
134**-
135** As well as some of the built-in window functions, aggregate window-
136** functions min() and max() are implemented using VDBE instructions if-
137** the start of the window frame is declared as anything other than -
138** UNBOUNDED PRECEDING.-
139*/-
140-
141/*-
142** Implementation of built-in window function row_number(). Assumes that the-
143** window frame has been coerced to:-
144**-
145** ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW-
146*/-
147static void row_numberStepFunc(-
148 sqlite3_context *pCtx, -
149 int nArg,-
150 sqlite3_value **apArg-
151){-
152 i64 *p = (i64*)sqlite3_aggregate_context(pCtx, sizeof(*p));-
153 if( p ) (*p)++;
executed 13692 times by 1 test: (*p)++;
Executed by:
  • Self test (438)
pDescription
TRUEevaluated 13692 times by 1 test
Evaluated by:
  • Self test (438)
FALSEnever evaluated
0-13692
154 UNUSED_PARAMETER(nArg);-
155 UNUSED_PARAMETER(apArg);-
156}
executed 13692 times by 1 test: end of block
Executed by:
  • Self test (438)
13692
157static void row_numberValueFunc(sqlite3_context *pCtx){-
158 i64 *p = (i64*)sqlite3_aggregate_context(pCtx, sizeof(*p));-
159 sqlite3_result_int64(pCtx, (p ? *p : 0));-
160}
executed 13767 times by 1 test: end of block
Executed by:
  • Self test (438)
13767
161-
162/*-
163** Context object type used by rank(), dense_rank(), percent_rank() and-
164** cume_dist().-
165*/-
166struct CallCount {-
167 i64 nValue;-
168 i64 nStep;-
169 i64 nTotal;-
170};-
171-
172/*-
173** Implementation of built-in window function dense_rank(). Assumes that-
174** the window frame has been set to:-
175**-
176** RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW -
177*/-
178static void dense_rankStepFunc(-
179 sqlite3_context *pCtx, -
180 int nArg,-
181 sqlite3_value **apArg-
182){-
183 struct CallCount *p;-
184 p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p));-
185 if( p ) p->nStep = 1;
executed 23929 times by 1 test: p->nStep = 1;
Executed by:
  • Self test (438)
pDescription
TRUEevaluated 23929 times by 1 test
Evaluated by:
  • Self test (438)
FALSEnever evaluated
0-23929
186 UNUSED_PARAMETER(nArg);-
187 UNUSED_PARAMETER(apArg);-
188}
executed 23929 times by 1 test: end of block
Executed by:
  • Self test (438)
23929
189static void dense_rankValueFunc(sqlite3_context *pCtx){-
190 struct CallCount *p;-
191 p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p));-
192 if( p ){
pDescription
TRUEevaluated 10703 times by 1 test
Evaluated by:
  • Self test (438)
FALSEnever evaluated
0-10703
193 if( p->nStep ){
p->nStepDescription
TRUEevaluated 10581 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 122 times by 1 test
Evaluated by:
  • Self test (438)
122-10581
194 p->nValue++;-
195 p->nStep = 0;-
196 }
executed 10581 times by 1 test: end of block
Executed by:
  • Self test (438)
10581
197 sqlite3_result_int64(pCtx, p->nValue);-
198 }
executed 10703 times by 1 test: end of block
Executed by:
  • Self test (438)
10703
199}
executed 10703 times by 1 test: end of block
Executed by:
  • Self test (438)
10703
200-
201/*-
202** Implementation of built-in window function rank(). Assumes that-
203** the window frame has been set to:-
204**-
205** RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW -
206*/-
207static void rankStepFunc(-
208 sqlite3_context *pCtx, -
209 int nArg,-
210 sqlite3_value **apArg-
211){-
212 struct CallCount *p;-
213 p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p));-
214 if( p ){
pDescription
TRUEevaluated 23967 times by 1 test
Evaluated by:
  • Self test (438)
FALSEnever evaluated
0-23967
215 p->nStep++;-
216 if( p->nValue==0 ){
p->nValue==0Description
TRUEevaluated 10604 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 13363 times by 1 test
Evaluated by:
  • Self test (438)
10604-13363
217 p->nValue = p->nStep;-
218 }
executed 10604 times by 1 test: end of block
Executed by:
  • Self test (438)
10604
219 }
executed 23967 times by 1 test: end of block
Executed by:
  • Self test (438)
23967
220 UNUSED_PARAMETER(nArg);-
221 UNUSED_PARAMETER(apArg);-
222}
executed 23967 times by 1 test: end of block
Executed by:
  • Self test (438)
23967
223static void rankValueFunc(sqlite3_context *pCtx){-
224 struct CallCount *p;-
225 p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p));-
226 if( p ){
pDescription
TRUEevaluated 10731 times by 1 test
Evaluated by:
  • Self test (438)
FALSEnever evaluated
0-10731
227 sqlite3_result_int64(pCtx, p->nValue);-
228 p->nValue = 0;-
229 }
executed 10731 times by 1 test: end of block
Executed by:
  • Self test (438)
10731
230}
executed 10731 times by 1 test: end of block
Executed by:
  • Self test (438)
10731
231-
232/*-
233** Implementation of built-in window function percent_rank(). Assumes that-
234** the window frame has been set to:-
235**-
236** RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW -
237*/-
238static void percent_rankStepFunc(-
239 sqlite3_context *pCtx, -
240 int nArg,-
241 sqlite3_value **apArg-
242){-
243 struct CallCount *p;-
244 UNUSED_PARAMETER(nArg); assert( nArg==1 );-
245-
246 p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p));-
247 if( p ){
pDescription
TRUEevaluated 20512 times by 1 test
Evaluated by:
  • Self test (438)
FALSEnever evaluated
0-20512
248 if( p->nTotal==0 ){
p->nTotal==0Description
TRUEevaluated 430 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 20082 times by 1 test
Evaluated by:
  • Self test (438)
430-20082
249 p->nTotal = sqlite3_value_int64(apArg[0]);-
250 }
executed 430 times by 1 test: end of block
Executed by:
  • Self test (438)
430
251 p->nStep++;-
252 if( p->nValue==0 ){
p->nValue==0Description
TRUEevaluated 10409 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 10103 times by 1 test
Evaluated by:
  • Self test (438)
10103-10409
253 p->nValue = p->nStep;-
254 }
executed 10409 times by 1 test: end of block
Executed by:
  • Self test (438)
10409
255 }
executed 20512 times by 1 test: end of block
Executed by:
  • Self test (438)
20512
256}
executed 20512 times by 1 test: end of block
Executed by:
  • Self test (438)
20512
257static void percent_rankValueFunc(sqlite3_context *pCtx){-
258 struct CallCount *p;-
259 p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p));-
260 if( p ){
pDescription
TRUEevaluated 11268 times by 1 test
Evaluated by:
  • Self test (438)
FALSEnever evaluated
0-11268
261 if( p->nTotal>1 ){
p->nTotal>1Description
TRUEevaluated 10835 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 433 times by 1 test
Evaluated by:
  • Self test (438)
433-10835
262 double r = (double)(p->nValue-1) / (double)(p->nTotal-1);-
263 sqlite3_result_double(pCtx, r);-
264 }else{
executed 10835 times by 1 test: end of block
Executed by:
  • Self test (438)
10835
265 sqlite3_result_double(pCtx, 0.0);-
266 }
executed 433 times by 1 test: end of block
Executed by:
  • Self test (438)
433
267 p->nValue = 0;-
268 }
executed 11268 times by 1 test: end of block
Executed by:
  • Self test (438)
11268
269}
executed 11268 times by 1 test: end of block
Executed by:
  • Self test (438)
11268
270-
271/*-
272** Implementation of built-in window function cume_dist(). Assumes that-
273** the window frame has been set to:-
274**-
275** RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW -
276*/-
277static void cume_distStepFunc(-
278 sqlite3_context *pCtx, -
279 int nArg,-
280 sqlite3_value **apArg-
281){-
282 struct CallCount *p;-
283 assert( nArg==1 ); UNUSED_PARAMETER(nArg);-
284-
285 p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p));-
286 if( p ){
pDescription
TRUEevaluated 20505 times by 1 test
Evaluated by:
  • Self test (438)
FALSEnever evaluated
0-20505
287 if( p->nTotal==0 ){
p->nTotal==0Description
TRUEevaluated 426 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 20079 times by 1 test
Evaluated by:
  • Self test (438)
426-20079
288 p->nTotal = sqlite3_value_int64(apArg[0]);-
289 }
executed 426 times by 1 test: end of block
Executed by:
  • Self test (438)
426
290 p->nStep++;-
291 }
executed 20505 times by 1 test: end of block
Executed by:
  • Self test (438)
20505
292}
executed 20505 times by 1 test: end of block
Executed by:
  • Self test (438)
20505
293static void cume_distValueFunc(sqlite3_context *pCtx){-
294 struct CallCount *p;-
295 p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p));-
296 if( p && p->nTotal ){
pDescription
TRUEevaluated 11256 times by 1 test
Evaluated by:
  • Self test (438)
FALSEnever evaluated
p->nTotalDescription
TRUEevaluated 10831 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 425 times by 1 test
Evaluated by:
  • Self test (438)
0-11256
297 double r = (double)(p->nStep) / (double)(p->nTotal);-
298 sqlite3_result_double(pCtx, r);-
299 }
executed 10831 times by 1 test: end of block
Executed by:
  • Self test (438)
10831
300}
executed 11256 times by 1 test: end of block
Executed by:
  • Self test (438)
11256
301-
302/*-
303** Context object for ntile() window function.-
304*/-
305struct NtileCtx {-
306 i64 nTotal; /* Total rows in partition */-
307 i64 nParam; /* Parameter passed to ntile(N) */-
308 i64 iRow; /* Current row */-
309};-
310-
311/*-
312** Implementation of ntile(). This assumes that the window frame has-
313** been coerced to:-
314**-
315** ROWS UNBOUNDED PRECEDING AND CURRENT ROW-
316*/-
317static void ntileStepFunc(-
318 sqlite3_context *pCtx, -
319 int nArg,-
320 sqlite3_value **apArg-
321){-
322 struct NtileCtx *p;-
323 assert( nArg==2 ); UNUSED_PARAMETER(nArg);-
324 p = (struct NtileCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p));-
325 if( p ){
pDescription
TRUEevaluated 24115 times by 1 test
Evaluated by:
  • Self test (438)
FALSEnever evaluated
0-24115
326 if( p->nTotal==0 ){
p->nTotal==0Description
TRUEevaluated 3848 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 20267 times by 1 test
Evaluated by:
  • Self test (438)
3848-20267
327 p->nParam = sqlite3_value_int64(apArg[0]);-
328 p->nTotal = sqlite3_value_int64(apArg[1]);-
329 if( p->nParam<=0 ){
p->nParam<=0Description
TRUEevaluated 3 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 3845 times by 1 test
Evaluated by:
  • Self test (438)
3-3845
330 sqlite3_result_error(-
331 pCtx, "argument of ntile must be a positive integer", -1-
332 );-
333 }
executed 3 times by 1 test: end of block
Executed by:
  • Self test (438)
3
334 }
executed 3848 times by 1 test: end of block
Executed by:
  • Self test (438)
3848
335 p->iRow++;-
336 }
executed 24115 times by 1 test: end of block
Executed by:
  • Self test (438)
24115
337}
executed 24115 times by 1 test: end of block
Executed by:
  • Self test (438)
24115
338static void ntileValueFunc(sqlite3_context *pCtx){-
339 struct NtileCtx *p;-
340 p = (struct NtileCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p));-
341 if( p && p->nParam>0 ){
pDescription
TRUEevaluated 31791 times by 1 test
Evaluated by:
  • Self test (438)
FALSEnever evaluated
p->nParam>0Description
TRUEevaluated 27957 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 3834 times by 1 test
Evaluated by:
  • Self test (438)
0-31791
342 int nSize = (p->nTotal / p->nParam);-
343 if( nSize==0 ){
nSize==0Description
TRUEevaluated 14107 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 13850 times by 1 test
Evaluated by:
  • Self test (438)
13850-14107
344 sqlite3_result_int64(pCtx, p->iRow);-
345 }else{
executed 14107 times by 1 test: end of block
Executed by:
  • Self test (438)
14107
346 i64 nLarge = p->nTotal - p->nParam*nSize;-
347 i64 iSmall = nLarge*(nSize+1);-
348 i64 iRow = p->iRow-1;-
349-
350 assert( (nLarge*(nSize+1) + (p->nParam-nLarge)*nSize)==p->nTotal );-
351-
352 if( iRow<iSmall ){
iRow<iSmallDescription
TRUEevaluated 10011 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 3839 times by 1 test
Evaluated by:
  • Self test (438)
3839-10011
353 sqlite3_result_int64(pCtx, 1 + iRow/(nSize+1));-
354 }else{
executed 10011 times by 1 test: end of block
Executed by:
  • Self test (438)
10011
355 sqlite3_result_int64(pCtx, 1 + nLarge + (iRow-iSmall)/nSize);-
356 }
executed 3839 times by 1 test: end of block
Executed by:
  • Self test (438)
3839
357 }-
358 }-
359}
executed 31791 times by 1 test: end of block
Executed by:
  • Self test (438)
31791
360-
361/*-
362** Context object for last_value() window function.-
363*/-
364struct LastValueCtx {-
365 sqlite3_value *pVal;-
366 int nVal;-
367};-
368-
369/*-
370** Implementation of last_value().-
371*/-
372static void last_valueStepFunc(-
373 sqlite3_context *pCtx, -
374 int nArg,-
375 sqlite3_value **apArg-
376){-
377 struct LastValueCtx *p;-
378 UNUSED_PARAMETER(nArg);-
379 p = (struct LastValueCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p));-
380 if( p ){
pDescription
TRUEevaluated 19965 times by 1 test
Evaluated by:
  • Self test (438)
FALSEnever evaluated
0-19965
381 sqlite3_value_free(p->pVal);-
382 p->pVal = sqlite3_value_dup(apArg[0]);-
383 if( p->pVal==0 ){
p->pVal==0Description
TRUEnever evaluated
FALSEevaluated 19965 times by 1 test
Evaluated by:
  • Self test (438)
0-19965
384 sqlite3_result_error_nomem(pCtx);-
385 }else{
never executed: end of block
0
386 p->nVal++;-
387 }
executed 19965 times by 1 test: end of block
Executed by:
  • Self test (438)
19965
388 }-
389}
executed 19965 times by 1 test: end of block
Executed by:
  • Self test (438)
19965
390static void last_valueInvFunc(-
391 sqlite3_context *pCtx, -
392 int nArg,-
393 sqlite3_value **apArg-
394){-
395 struct LastValueCtx *p;-
396 UNUSED_PARAMETER(nArg);-
397 UNUSED_PARAMETER(apArg);-
398 p = (struct LastValueCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p));-
399 if( ALWAYS(p) ){
(p)Description
TRUEevaluated 9900 times by 1 test
Evaluated by:
  • Self test (438)
FALSEnever evaluated
0-9900
400 p->nVal--;-
401 if( p->nVal==0 ){
p->nVal==0Description
TRUEevaluated 1430 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 8470 times by 1 test
Evaluated by:
  • Self test (438)
1430-8470
402 sqlite3_value_free(p->pVal);-
403 p->pVal = 0;-
404 }
executed 1430 times by 1 test: end of block
Executed by:
  • Self test (438)
1430
405 }
executed 9900 times by 1 test: end of block
Executed by:
  • Self test (438)
9900
406}
executed 9900 times by 1 test: end of block
Executed by:
  • Self test (438)
9900
407static void last_valueValueFunc(sqlite3_context *pCtx){-
408 struct LastValueCtx *p;-
409 p = (struct LastValueCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p));-
410 if( p && p->pVal ){
pDescription
TRUEevaluated 17829 times by 1 test
Evaluated by:
  • Self test (438)
FALSEnever evaluated
p->pValDescription
TRUEevaluated 16742 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 1087 times by 1 test
Evaluated by:
  • Self test (438)
0-17829
411 sqlite3_result_value(pCtx, p->pVal);-
412 }
executed 16742 times by 1 test: end of block
Executed by:
  • Self test (438)
16742
413}
executed 17829 times by 1 test: end of block
Executed by:
  • Self test (438)
17829
414static void last_valueFinalizeFunc(sqlite3_context *pCtx){-
415 struct LastValueCtx *p;-
416 p = (struct LastValueCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p));-
417 if( p && p->pVal ){
pDescription
TRUEevaluated 4806 times by 1 test
Evaluated by:
  • Self test (438)
FALSEnever evaluated
p->pValDescription
TRUEevaluated 3941 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 865 times by 1 test
Evaluated by:
  • Self test (438)
0-4806
418 sqlite3_result_value(pCtx, p->pVal);-
419 sqlite3_value_free(p->pVal);-
420 p->pVal = 0;-
421 }
executed 3941 times by 1 test: end of block
Executed by:
  • Self test (438)
3941
422}
executed 4806 times by 1 test: end of block
Executed by:
  • Self test (438)
4806
423-
424/*-
425** Static names for the built-in window function names. These static-
426** names are used, rather than string literals, so that FuncDef objects-
427** can be associated with a particular window function by direct-
428** comparison of the zName pointer. Example:-
429**-
430** if( pFuncDef->zName==row_valueName ){ ... }-
431*/-
432static const char row_numberName[] = "row_number";-
433static const char dense_rankName[] = "dense_rank";-
434static const char rankName[] = "rank";-
435static const char percent_rankName[] = "percent_rank";-
436static const char cume_distName[] = "cume_dist";-
437static const char ntileName[] = "ntile";-
438static const char last_valueName[] = "last_value";-
439static const char nth_valueName[] = "nth_value";-
440static const char first_valueName[] = "first_value";-
441static const char leadName[] = "lead";-
442static const char lagName[] = "lag";-
443-
444/*-
445** No-op implementations of xStep() and xFinalize(). Used as place-holders-
446** for built-in window functions that never call those interfaces.-
447**-
448** The noopValueFunc() is called but is expected to do nothing. The-
449** noopStepFunc() is never called, and so it is marked with NO_TEST to-
450** let the test coverage routine know not to expect this function to be-
451** invoked.-
452*/-
453static void noopStepFunc( /*NO_TEST*/-
454 sqlite3_context *p, /*NO_TEST*/-
455 int n, /*NO_TEST*/-
456 sqlite3_value **a /*NO_TEST*/-
457){ /*NO_TEST*/-
458 UNUSED_PARAMETER(p); /*NO_TEST*/-
459 UNUSED_PARAMETER(n); /*NO_TEST*/-
460 UNUSED_PARAMETER(a); /*NO_TEST*/-
461 assert(0); /*NO_TEST*/-
462}
never executed: end of block
/*NO_TEST*/
never executed: end of block
0
463static
executed 40724 times by 1 test: end of block
Executed by:
  • Self test (438)
void noopValueFunc(sqlite3_context *p){ UNUSED_PARAMETER(p); /*no-op*/ }
executed 40724 times by 1 test: end of block
Executed by:
  • Self test (438)
40724
464-
465/* Window functions that use all window interfaces: xStep, xFinal,-
466** xValue, and xInverse */-
467#define WINDOWFUNCALL(name,nArg,extra) { \-
468 nArg, (SQLITE_UTF8|SQLITE_FUNC_WINDOW|extra), 0, 0, \-
469 name ## StepFunc, name ## FinalizeFunc, name ## ValueFunc, \-
470 name ## InvFunc, name ## Name, {0} \-
471}-
472-
473/* Window functions that are implemented using bytecode and thus have-
474** no-op routines for their methods */-
475#define WINDOWFUNCNOOP(name,nArg,extra) { \-
476 nArg, (SQLITE_UTF8|SQLITE_FUNC_WINDOW|extra), 0, 0, \-
477 noopStepFunc, noopValueFunc, noopValueFunc, \-
478 noopStepFunc, name ## Name, {0} \-
479}-
480-
481/* Window functions that use all window interfaces: xStep, the-
482** same routine for xFinalize and xValue and which never call-
483** xInverse. */-
484#define WINDOWFUNCX(name,nArg,extra) { \-
485 nArg, (SQLITE_UTF8|SQLITE_FUNC_WINDOW|extra), 0, 0, \-
486 name ## StepFunc, name ## ValueFunc, name ## ValueFunc, \-
487 noopStepFunc, name ## Name, {0} \-
488}-
489-
490-
491/*-
492** Register those built-in window functions that are not also aggregates.-
493*/-
494void sqlite3WindowFunctions(void){-
495 static FuncDef aWindowFuncs[] = {-
496 WINDOWFUNCX(row_number, 0, 0),-
497 WINDOWFUNCX(dense_rank, 0, 0),-
498 WINDOWFUNCX(rank, 0, 0),-
499 WINDOWFUNCX(percent_rank, 0, SQLITE_FUNC_WINDOW_SIZE),-
500 WINDOWFUNCX(cume_dist, 0, SQLITE_FUNC_WINDOW_SIZE),-
501 WINDOWFUNCX(ntile, 1, SQLITE_FUNC_WINDOW_SIZE),-
502 WINDOWFUNCALL(last_value, 1, 0),-
503 WINDOWFUNCNOOP(nth_value, 2, 0),-
504 WINDOWFUNCNOOP(first_value, 1, 0),-
505 WINDOWFUNCNOOP(lead, 1, 0),-
506 WINDOWFUNCNOOP(lead, 2, 0),-
507 WINDOWFUNCNOOP(lead, 3, 0),-
508 WINDOWFUNCNOOP(lag, 1, 0),-
509 WINDOWFUNCNOOP(lag, 2, 0),-
510 WINDOWFUNCNOOP(lag, 3, 0),-
511 };-
512 sqlite3InsertBuiltinFuncs(aWindowFuncs, ArraySize(aWindowFuncs));-
513}
executed 534 times by 438 tests: end of block
Executed by:
  • Self test
  • Self test (10)
  • Self test (100)
  • Self test (101)
  • Self test (102)
  • Self test (103)
  • Self test (104)
  • Self test (105)
  • Self test (106)
  • Self test (107)
  • Self test (108)
  • Self test (109)
  • Self test (11)
  • Self test (110)
  • Self test (111)
  • Self test (112)
  • Self test (113)
  • Self test (114)
  • Self test (115)
  • Self test (116)
  • Self test (117)
  • Self test (118)
  • Self test (119)
  • Self test (12)
  • Self test (120)
  • ...
534
514-
515/*-
516** This function is called immediately after resolving the function name-
517** for a window function within a SELECT statement. Argument pList is a-
518** linked list of WINDOW definitions for the current SELECT statement.-
519** Argument pFunc is the function definition just resolved and pWin-
520** is the Window object representing the associated OVER clause. This-
521** function updates the contents of pWin as follows:-
522**-
523** * If the OVER clause refered to a named window (as in "max(x) OVER win"),-
524** search list pList for a matching WINDOW definition, and update pWin-
525** accordingly. If no such WINDOW clause can be found, leave an error-
526** in pParse.-
527**-
528** * If the function is a built-in window function that requires the-
529** window to be coerced (see "BUILT-IN WINDOW FUNCTIONS" at the top-
530** of this file), pWin is updated here.-
531*/-
532void sqlite3WindowUpdate(-
533 Parse *pParse, -
534 Window *pList, /* List of named windows for this SELECT */-
535 Window *pWin, /* Window frame to update */-
536 FuncDef *pFunc /* Window function definition */-
537){-
538 if( pWin->zName && pWin->eType==0 ){
pWin->zNameDescription
TRUEevaluated 222 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 1909 times by 1 test
Evaluated by:
  • Self test (438)
pWin->eType==0Description
TRUEevaluated 209 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 13 times by 1 test
Evaluated by:
  • Self test (438)
13-1909
539 Window *p;-
540 for(p=pList; p; p=p->pNextWin){
pDescription
TRUEevaluated 210 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 1 time by 1 test
Evaluated by:
  • Self test (438)
1-210
541 if( sqlite3StrICmp(p->zName, pWin->zName)==0 ) break;
executed 208 times by 1 test: break;
Executed by:
  • Self test (438)
sqlite3StrICmp...Win->zName)==0Description
TRUEevaluated 208 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 2 times by 1 test
Evaluated by:
  • Self test (438)
2-208
542 }
executed 2 times by 1 test: end of block
Executed by:
  • Self test (438)
2
543 if( p==0 ){
p==0Description
TRUEevaluated 1 time by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 208 times by 1 test
Evaluated by:
  • Self test (438)
1-208
544 sqlite3ErrorMsg(pParse, "no such window: %s", pWin->zName);-
545 return;
executed 1 time by 1 test: return;
Executed by:
  • Self test (438)
1
546 }-
547 pWin->pPartition = sqlite3ExprListDup(pParse->db, p->pPartition, 0);-
548 pWin->pOrderBy = sqlite3ExprListDup(pParse->db, p->pOrderBy, 0);-
549 pWin->pStart = sqlite3ExprDup(pParse->db, p->pStart, 0);-
550 pWin->pEnd = sqlite3ExprDup(pParse->db, p->pEnd, 0);-
551 pWin->eStart = p->eStart;-
552 pWin->eEnd = p->eEnd;-
553 pWin->eType = p->eType;-
554 }
executed 208 times by 1 test: end of block
Executed by:
  • Self test (438)
208
555 if( pFunc->funcFlags & SQLITE_FUNC_WINDOW ){
pFunc->funcFlags & 0x10000Description
TRUEevaluated 1269 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 861 times by 1 test
Evaluated by:
  • Self test (438)
861-1269
556 sqlite3 *db = pParse->db;-
557 if( pWin->pFilter ){
pWin->pFilterDescription
TRUEevaluated 1 time by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 1268 times by 1 test
Evaluated by:
  • Self test (438)
1-1268
558 sqlite3ErrorMsg(pParse, -
559 "FILTER clause may only be used with aggregate window functions"-
560 );-
561 }else
executed 1 time by 1 test: end of block
Executed by:
  • Self test (438)
1
562 if( pFunc->zName==row_numberName || pFunc->zName==ntileName ){
pFunc->zName==row_numberNameDescription
TRUEevaluated 73 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 1195 times by 1 test
Evaluated by:
  • Self test (438)
pFunc->zName==ntileNameDescription
TRUEevaluated 143 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 1052 times by 1 test
Evaluated by:
  • Self test (438)
73-1195
563 sqlite3ExprDelete(db, pWin->pStart);-
564 sqlite3ExprDelete(db, pWin->pEnd);-
565 pWin->pStart = pWin->pEnd = 0;-
566 pWin->eType = TK_ROWS;-
567 pWin->eStart = TK_UNBOUNDED;-
568 pWin->eEnd = TK_CURRENT;-
569 }else
executed 216 times by 1 test: end of block
Executed by:
  • Self test (438)
216
570-
571 if( pFunc->zName==dense_rankName || pFunc->zName==rankName
pFunc->zName==dense_rankNameDescription
TRUEevaluated 139 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 913 times by 1 test
Evaluated by:
  • Self test (438)
pFunc->zName==rankNameDescription
TRUEevaluated 146 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 767 times by 1 test
Evaluated by:
  • Self test (438)
139-913
572 || pFunc->zName==percent_rankName || pFunc->zName==cume_distName
pFunc->zName==percent_rankNameDescription
TRUEevaluated 104 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 663 times by 1 test
Evaluated by:
  • Self test (438)
pFunc->zName==cume_distNameDescription
TRUEevaluated 103 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 560 times by 1 test
Evaluated by:
  • Self test (438)
103-663
573 ){-
574 sqlite3ExprDelete(db, pWin->pStart);-
575 sqlite3ExprDelete(db, pWin->pEnd);-
576 pWin->pStart = pWin->pEnd = 0;-
577 pWin->eType = TK_RANGE;-
578 pWin->eStart = TK_UNBOUNDED;-
579 pWin->eEnd = TK_CURRENT;-
580 }
executed 492 times by 1 test: end of block
Executed by:
  • Self test (438)
492
581 }
executed 1269 times by 1 test: end of block
Executed by:
  • Self test (438)
1269
582 pWin->pFunc = pFunc;-
583}
executed 2130 times by 1 test: end of block
Executed by:
  • Self test (438)
2130
584-
585/*-
586** Context object passed through sqlite3WalkExprList() to-
587** selectWindowRewriteExprCb() by selectWindowRewriteEList().-
588*/-
589typedef struct WindowRewrite WindowRewrite;-
590struct WindowRewrite {-
591 Window *pWin;-
592 SrcList *pSrc;-
593 ExprList *pSub;-
594 Select *pSubSelect; /* Current sub-select, if any */-
595};-
596-
597/*-
598** Callback function used by selectWindowRewriteEList(). If necessary,-
599** this function appends to the output expression-list and updates -
600** expression (*ppExpr) in place.-
601*/-
602static int selectWindowRewriteExprCb(Walker *pWalker, Expr *pExpr){-
603 struct WindowRewrite *p = pWalker->u.pRewrite;-
604 Parse *pParse = pWalker->pParse;-
605-
606 /* If this function is being called from within a scalar sub-select-
607 ** that used by the SELECT statement being processed, only process-
608 ** TK_COLUMN expressions that refer to it (the outer SELECT). Do-
609 ** not process aggregates or window functions at all, as they belong-
610 ** to the scalar sub-select. */-
611 if( p->pSubSelect ){
p->pSubSelectDescription
TRUEevaluated 4 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 3137 times by 1 test
Evaluated by:
  • Self test (438)
4-3137
612 if( pExpr->op!=TK_COLUMN ){
pExpr->op!=158Description
TRUEevaluated 1 time by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 3 times by 1 test
Evaluated by:
  • Self test (438)
1-3
613 return WRC_Continue;
executed 1 time by 1 test: return 0;
Executed by:
  • Self test (438)
1
614 }else{-
615 int nSrc = p->pSrc->nSrc;-
616 int i;-
617 for(i=0; i<nSrc; i++){
i<nSrcDescription
TRUEevaluated 3 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 2 times by 1 test
Evaluated by:
  • Self test (438)
2-3
618 if( pExpr->iTable==p->pSrc->a[i].iCursor ) break;
executed 1 time by 1 test: break;
Executed by:
  • Self test (438)
pExpr->iTable=...->a[i].iCursorDescription
TRUEevaluated 1 time by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 2 times by 1 test
Evaluated by:
  • Self test (438)
1-2
619 }
executed 2 times by 1 test: end of block
Executed by:
  • Self test (438)
2
620 if( i==nSrc ) return WRC_Continue;
executed 2 times by 1 test: return 0;
Executed by:
  • Self test (438)
i==nSrcDescription
TRUEevaluated 2 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 1 time by 1 test
Evaluated by:
  • Self test (438)
1-2
621 }
executed 1 time by 1 test: end of block
Executed by:
  • Self test (438)
1
622 }-
623-
624 switch( pExpr->op ){-
625-
626 case TK_FUNCTION:
executed 2127 times by 1 test: case 157:
Executed by:
  • Self test (438)
2127
627 if( !ExprHasProperty(pExpr, EP_WinFunc) ){
!(((pExpr)->fl...x1000000))!=0)Description
TRUEevaluated 1 time by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 2126 times by 1 test
Evaluated by:
  • Self test (438)
1-2126
628 break;
executed 1 time by 1 test: break;
Executed by:
  • Self test (438)
1
629 }else{-
630 Window *pWin;-
631 for(pWin=p->pWin; pWin; pWin=pWin->pNextWin){
pWinDescription
TRUEevaluated 2316 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 170 times by 1 test
Evaluated by:
  • Self test (438)
170-2316
632 if( pExpr->y.pWin==pWin ){
pExpr->y.pWin==pWinDescription
TRUEevaluated 1956 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 360 times by 1 test
Evaluated by:
  • Self test (438)
360-1956
633 assert( pWin->pOwner==pExpr );-
634 return WRC_Prune;
executed 1956 times by 1 test: return 1;
Executed by:
  • Self test (438)
1956
635 }-
636 }
executed 360 times by 1 test: end of block
Executed by:
  • Self test (438)
360
637 }
executed 170 times by 1 test: end of block
Executed by:
  • Self test (438)
170
638 /* Fall through. */-
639-
640 case TK_AGG_FUNCTION:
code before this statement executed 170 times by 1 test: case 159:
Executed by:
  • Self test (438)
executed 1 time by 1 test: case 159:
Executed by:
  • Self test (438)
1-170
641 case TK_COLUMN: {
executed 934 times by 1 test: case 158:
Executed by:
  • Self test (438)
934
642 Expr *pDup = sqlite3ExprDup(pParse->db, pExpr, 0);-
643 p->pSub = sqlite3ExprListAppend(pParse, p->pSub, pDup);-
644 if( p->pSub ){
p->pSubDescription
TRUEevaluated 1105 times by 1 test
Evaluated by:
  • Self test (438)
FALSEnever evaluated
0-1105
645 assert( ExprHasProperty(pExpr, EP_Static)==0 );-
646 ExprSetProperty(pExpr, EP_Static);-
647 sqlite3ExprDelete(pParse->db, pExpr);-
648 ExprClearProperty(pExpr, EP_Static);-
649 memset(pExpr, 0, sizeof(Expr));-
650-
651 pExpr->op = TK_COLUMN;-
652 pExpr->iColumn = p->pSub->nExpr-1;-
653 pExpr->iTable = p->pWin->iEphCsr;-
654 }
executed 1105 times by 1 test: end of block
Executed by:
  • Self test (438)
1105
655-
656 break;
executed 1105 times by 1 test: break;
Executed by:
  • Self test (438)
1105
657 }-
658-
659 default: /* no-op */
executed 76 times by 1 test: default:
Executed by:
  • Self test (438)
76
660 break;
executed 76 times by 1 test: break;
Executed by:
  • Self test (438)
76
661 }-
662-
663 return WRC_Continue;
executed 1182 times by 1 test: return 0;
Executed by:
  • Self test (438)
1182
664}-
665static int selectWindowRewriteSelectCb(Walker *pWalker, Select *pSelect){-
666 struct WindowRewrite *p = pWalker->u.pRewrite;-
667 Select *pSave = p->pSubSelect;-
668 if( pSave==pSelect ){
pSave==pSelectDescription
TRUEevaluated 1 time by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 1 time by 1 test
Evaluated by:
  • Self test (438)
1
669 return WRC_Continue;
executed 1 time by 1 test: return 0;
Executed by:
  • Self test (438)
1
670 }else{-
671 p->pSubSelect = pSelect;-
672 sqlite3WalkSelect(pWalker, pSelect);-
673 p->pSubSelect = pSave;-
674 }
executed 1 time by 1 test: end of block
Executed by:
  • Self test (438)
1
675 return WRC_Prune;
executed 1 time by 1 test: return 1;
Executed by:
  • Self test (438)
1
676}-
677-
678-
679/*-
680** Iterate through each expression in expression-list pEList. For each:-
681**-
682** * TK_COLUMN,-
683** * aggregate function, or-
684** * window function with a Window object that is not a member of the -
685** Window list passed as the second argument (pWin).-
686**-
687** Append the node to output expression-list (*ppSub). And replace it-
688** with a TK_COLUMN that reads the (N-1)th element of table -
689** pWin->iEphCsr, where N is the number of elements in (*ppSub) after-
690** appending the new one.-
691*/-
692static void selectWindowRewriteEList(-
693 Parse *pParse, -
694 Window *pWin,-
695 SrcList *pSrc,-
696 ExprList *pEList, /* Rewrite expressions in this list */-
697 ExprList **ppSub /* IN/OUT: Sub-select expression-list */-
698){-
699 Walker sWalker;-
700 WindowRewrite sRewrite;-
701-
702 memset(&sWalker, 0, sizeof(Walker));-
703 memset(&sRewrite, 0, sizeof(WindowRewrite));-
704-
705 sRewrite.pSub = *ppSub;-
706 sRewrite.pWin = pWin;-
707 sRewrite.pSrc = pSrc;-
708-
709 sWalker.pParse = pParse;-
710 sWalker.xExprCallback = selectWindowRewriteExprCb;-
711 sWalker.xSelectCallback = selectWindowRewriteSelectCb;-
712 sWalker.u.pRewrite = &sRewrite;-
713-
714 (void)sqlite3WalkExprList(&sWalker, pEList);-
715-
716 *ppSub = sRewrite.pSub;-
717}
executed 3618 times by 1 test: end of block
Executed by:
  • Self test (438)
3618
718-
719/*-
720** Append a copy of each expression in expression-list pAppend to-
721** expression list pList. Return a pointer to the result list.-
722*/-
723static ExprList *exprListAppendList(-
724 Parse *pParse, /* Parsing context */-
725 ExprList *pList, /* List to which to append. Might be NULL */-
726 ExprList *pAppend /* List of values to append. Might be NULL */-
727){-
728 if( pAppend ){
pAppendDescription
TRUEevaluated 5746 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 1637 times by 1 test
Evaluated by:
  • Self test (438)
1637-5746
729 int i;-
730 int nInit = pList ? pList->nExpr : 0;
pListDescription
TRUEevaluated 3576 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 2170 times by 1 test
Evaluated by:
  • Self test (438)
2170-3576
731 for(i=0; i<pAppend->nExpr; i++){
i<pAppend->nExprDescription
TRUEevaluated 7141 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 5746 times by 1 test
Evaluated by:
  • Self test (438)
5746-7141
732 Expr *pDup = sqlite3ExprDup(pParse->db, pAppend->a[i].pExpr, 0);-
733 pList = sqlite3ExprListAppend(pParse, pList, pDup);-
734 if( pList ) pList->a[nInit+i].sortOrder = pAppend->a[i].sortOrder;
executed 7141 times by 1 test: pList->a[nInit+i].sortOrder = pAppend->a[i].sortOrder;
Executed by:
  • Self test (438)
pListDescription
TRUEevaluated 7141 times by 1 test
Evaluated by:
  • Self test (438)
FALSEnever evaluated
0-7141
735 }
executed 7141 times by 1 test: end of block
Executed by:
  • Self test (438)
7141
736 }
executed 5746 times by 1 test: end of block
Executed by:
  • Self test (438)
5746
737 return pList;
executed 7383 times by 1 test: return pList;
Executed by:
  • Self test (438)
7383
738}-
739-
740/*-
741** If the SELECT statement passed as the second argument does not invoke-
742** any SQL window functions, this function is a no-op. Otherwise, it -
743** rewrites the SELECT statement so that window function xStep functions-
744** are invoked in the correct order as described under "SELECT REWRITING"-
745** at the top of this file.-
746*/-
747int sqlite3WindowRewrite(Parse *pParse, Select *p){-
748 int rc = SQLITE_OK;-
749 if( p->pWin ){
p->pWinDescription
TRUEevaluated 1809 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 313444 times by 435 tests
Evaluated by:
  • Self test
  • Self test (10)
  • Self test (100)
  • Self test (101)
  • Self test (103)
  • Self test (104)
  • Self test (105)
  • Self test (106)
  • Self test (107)
  • Self test (108)
  • Self test (109)
  • Self test (11)
  • Self test (110)
  • Self test (111)
  • Self test (112)
  • Self test (113)
  • Self test (114)
  • Self test (115)
  • Self test (116)
  • Self test (117)
  • Self test (118)
  • Self test (119)
  • Self test (12)
  • Self test (120)
  • Self test (121)
  • ...
1809-313444
750 Vdbe *v = sqlite3GetVdbe(pParse);-
751 sqlite3 *db = pParse->db;-
752 Select *pSub = 0; /* The subquery */-
753 SrcList *pSrc = p->pSrc;-
754 Expr *pWhere = p->pWhere;-
755 ExprList *pGroupBy = p->pGroupBy;-
756 Expr *pHaving = p->pHaving;-
757 ExprList *pSort = 0;-
758-
759 ExprList *pSublist = 0; /* Expression list for sub-query */-
760 Window *pMWin = p->pWin; /* Master window object */-
761 Window *pWin; /* Window object iterator */-
762-
763 p->pSrc = 0;-
764 p->pWhere = 0;-
765 p->pGroupBy = 0;-
766 p->pHaving = 0;-
767-
768 /* Create the ORDER BY clause for the sub-select. This is the concatenation-
769 ** of the window PARTITION and ORDER BY clauses. Then, if this makes it-
770 ** redundant, remove the ORDER BY from the parent SELECT. */-
771 pSort = sqlite3ExprListDup(db, pMWin->pPartition, 0);-
772 pSort = exprListAppendList(pParse, pSort, pMWin->pOrderBy);-
773 if( pSort && p->pOrderBy ){
pSortDescription
TRUEevaluated 1751 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 58 times by 1 test
Evaluated by:
  • Self test (438)
p->pOrderByDescription
TRUEevaluated 316 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 1435 times by 1 test
Evaluated by:
  • Self test (438)
58-1751
774 if( sqlite3ExprListCompare(pSort, p->pOrderBy, -1)==0 ){
sqlite3ExprLis...rderBy, -1)==0Description
TRUEevaluated 110 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 206 times by 1 test
Evaluated by:
  • Self test (438)
110-206
775 sqlite3ExprListDelete(db, p->pOrderBy);-
776 p->pOrderBy = 0;-
777 }
executed 110 times by 1 test: end of block
Executed by:
  • Self test (438)
110
778 }
executed 316 times by 1 test: end of block
Executed by:
  • Self test (438)
316
779-
780 /* Assign a cursor number for the ephemeral table used to buffer rows.-
781 ** The OpenEphemeral instruction is coded later, after it is known how-
782 ** many columns the table will have. */-
783 pMWin->iEphCsr = pParse->nTab++;-
784-
785 selectWindowRewriteEList(pParse, pMWin, pSrc, p->pEList, &pSublist);-
786 selectWindowRewriteEList(pParse, pMWin, pSrc, p->pOrderBy, &pSublist);-
787 pMWin->nBufferCol = (pSublist ? pSublist->nExpr : 0);
pSublistDescription
TRUEevaluated 435 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 1374 times by 1 test
Evaluated by:
  • Self test (438)
435-1374
788-
789 /* Append the PARTITION BY and ORDER BY expressions to the to the -
790 ** sub-select expression list. They are required to figure out where -
791 ** boundaries for partitions and sets of peer rows lie. */-
792 pSublist = exprListAppendList(pParse, pSublist, pMWin->pPartition);-
793 pSublist = exprListAppendList(pParse, pSublist, pMWin->pOrderBy);-
794-
795 /* Append the arguments passed to each window function to the-
796 ** sub-select expression list. Also allocate two registers for each-
797 ** window function - one for the accumulator, another for interim-
798 ** results. */-
799 for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
pWinDescription
TRUEevaluated 1956 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 1809 times by 1 test
Evaluated by:
  • Self test (438)
1809-1956
800 pWin->iArgCol = (pSublist ? pSublist->nExpr : 0);
pSublistDescription
TRUEevaluated 1914 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 42 times by 1 test
Evaluated by:
  • Self test (438)
42-1914
801 pSublist = exprListAppendList(pParse, pSublist, pWin->pOwner->x.pList);-
802 if( pWin->pFilter ){
pWin->pFilterDescription
TRUEevaluated 72 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 1884 times by 1 test
Evaluated by:
  • Self test (438)
72-1884
803 Expr *pFilter = sqlite3ExprDup(db, pWin->pFilter, 0);-
804 pSublist = sqlite3ExprListAppend(pParse, pSublist, pFilter);-
805 }
executed 72 times by 1 test: end of block
Executed by:
  • Self test (438)
72
806 pWin->regAccum = ++pParse->nMem;-
807 pWin->regResult = ++pParse->nMem;-
808 sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regAccum);-
809 }
executed 1956 times by 1 test: end of block
Executed by:
  • Self test (438)
1956
810-
811 /* If there is no ORDER BY or PARTITION BY clause, and the window-
812 ** function accepts zero arguments, and there are no other columns-
813 ** selected (e.g. "SELECT row_number() OVER () FROM t1"), it is possible-
814 ** that pSublist is still NULL here. Add a constant expression here to -
815 ** keep everything legal in this case. -
816 */-
817 if( pSublist==0 ){
pSublist==0Description
TRUEevaluated 20 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 1789 times by 1 test
Evaluated by:
  • Self test (438)
20-1789
818 pSublist = sqlite3ExprListAppend(pParse, 0, -
819 sqlite3ExprAlloc(db, TK_INTEGER, &sqlite3IntTokens[0], 0)-
820 );-
821 }
executed 20 times by 1 test: end of block
Executed by:
  • Self test (438)
20
822-
823 pSub = sqlite3SelectNew(-
824 pParse, pSublist, pSrc, pWhere, pGroupBy, pHaving, pSort, 0, 0-
825 );-
826 p->pSrc = sqlite3SrcListAppend(db, 0, 0, 0);-
827 assert( p->pSrc || db->mallocFailed );-
828 if( p->pSrc ){
p->pSrcDescription
TRUEevaluated 1809 times by 1 test
Evaluated by:
  • Self test (438)
FALSEnever evaluated
0-1809
829 p->pSrc->a[0].pSelect = pSub;-
830 sqlite3SrcListAssignCursors(pParse, p->pSrc);-
831 if( sqlite3ExpandSubquery(pParse, &p->pSrc->a[0]) ){
sqlite3ExpandS...p->pSrc->a[0])Description
TRUEnever evaluated
FALSEevaluated 1809 times by 1 test
Evaluated by:
  • Self test (438)
0-1809
832 rc = SQLITE_NOMEM;-
833 }else{
never executed: end of block
0
834 pSub->selFlags |= SF_Expanded;-
835 p->selFlags &= ~SF_Aggregate;-
836 sqlite3SelectPrep(pParse, pSub, 0);-
837 }
executed 1809 times by 1 test: end of block
Executed by:
  • Self test (438)
1809
838-
839 sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pMWin->iEphCsr, pSublist->nExpr);-
840 }else{
executed 1809 times by 1 test: end of block
Executed by:
  • Self test (438)
1809
841 sqlite3SelectDelete(db, pSub);-
842 }
never executed: end of block
0
843 if( db->mallocFailed ) rc = SQLITE_NOMEM;
never executed: rc = 7;
db->mallocFailedDescription
TRUEnever evaluated
FALSEevaluated 1809 times by 1 test
Evaluated by:
  • Self test (438)
0-1809
844 }
executed 1809 times by 1 test: end of block
Executed by:
  • Self test (438)
1809
845-
846 return rc;
executed 315253 times by 435 tests: return rc;
Executed by:
  • Self test
  • Self test (10)
  • Self test (100)
  • Self test (101)
  • Self test (103)
  • Self test (104)
  • Self test (105)
  • Self test (106)
  • Self test (107)
  • Self test (108)
  • Self test (109)
  • Self test (11)
  • Self test (110)
  • Self test (111)
  • Self test (112)
  • Self test (113)
  • Self test (114)
  • Self test (115)
  • Self test (116)
  • Self test (117)
  • Self test (118)
  • Self test (119)
  • Self test (12)
  • Self test (120)
  • Self test (121)
  • ...
315253
847}-
848-
849/*-
850** Free the Window object passed as the second argument.-
851*/-
852void sqlite3WindowDelete(sqlite3 *db, Window *p){-
853 if( p ){
pDescription
TRUEevaluated 2323 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 6 times by 1 test
Evaluated by:
  • Self test (438)
6-2323
854 sqlite3ExprDelete(db, p->pFilter);-
855 sqlite3ExprListDelete(db, p->pPartition);-
856 sqlite3ExprListDelete(db, p->pOrderBy);-
857 sqlite3ExprDelete(db, p->pEnd);-
858 sqlite3ExprDelete(db, p->pStart);-
859 sqlite3DbFree(db, p->zName);-
860 sqlite3DbFree(db, p);-
861 }
executed 2323 times by 1 test: end of block
Executed by:
  • Self test (438)
2323
862}
executed 2329 times by 1 test: end of block
Executed by:
  • Self test (438)
2329
863-
864/*-
865** Free the linked list of Window objects starting at the second argument.-
866*/-
867void sqlite3WindowListDelete(sqlite3 *db, Window *p){-
868 while( p ){
pDescription
TRUEevaluated 126 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 125 times by 1 test
Evaluated by:
  • Self test (438)
125-126
869 Window *pNext = p->pNextWin;-
870 sqlite3WindowDelete(db, p);-
871 p = pNext;-
872 }
executed 126 times by 1 test: end of block
Executed by:
  • Self test (438)
126
873}
executed 125 times by 1 test: end of block
Executed by:
  • Self test (438)
125
874-
875/*-
876** The argument expression is an PRECEDING or FOLLOWING offset. The-
877** value should be a non-negative integer. If the value is not a-
878** constant, change it to NULL. The fact that it is then a non-negative-
879** integer will be caught later. But it is important not to leave-
880** variable values in the expression tree.-
881*/-
882static Expr *sqlite3WindowOffsetExpr(Parse *pParse, Expr *pExpr){-
883 if( 0==sqlite3ExprIsConstant(pExpr) ){
0==sqlite3Expr...onstant(pExpr)Description
TRUEevaluated 2 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 3750 times by 1 test
Evaluated by:
  • Self test (438)
2-3750
884 sqlite3ExprDelete(pParse->db, pExpr);-
885 pExpr = sqlite3ExprAlloc(pParse->db, TK_NULL, 0, 0);-
886 }
executed 2 times by 1 test: end of block
Executed by:
  • Self test (438)
2
887 return pExpr;
executed 3752 times by 1 test: return pExpr;
Executed by:
  • Self test (438)
3752
888}-
889-
890/*-
891** Allocate and return a new Window object describing a Window Definition.-
892*/-
893Window *sqlite3WindowAlloc(-
894 Parse *pParse, /* Parsing context */-
895 int eType, /* Frame type. TK_RANGE or TK_ROWS */-
896 int eStart, /* Start type: CURRENT, PRECEDING, FOLLOWING, UNBOUNDED */-
897 Expr *pStart, /* Start window size if TK_PRECEDING or FOLLOWING */-
898 int eEnd, /* End type: CURRENT, FOLLOWING, TK_UNBOUNDED, PRECEDING */-
899 Expr *pEnd /* End window size if TK_FOLLOWING or PRECEDING */-
900){-
901 Window *pWin = 0;-
902-
903 /* Parser assures the following: */-
904 assert( eType==TK_RANGE || eType==TK_ROWS );-
905 assert( eStart==TK_CURRENT || eStart==TK_PRECEDING-
906 || eStart==TK_UNBOUNDED || eStart==TK_FOLLOWING );-
907 assert( eEnd==TK_CURRENT || eEnd==TK_FOLLOWING-
908 || eEnd==TK_UNBOUNDED || eEnd==TK_PRECEDING );-
909 assert( (eStart==TK_PRECEDING || eStart==TK_FOLLOWING)==(pStart!=0) );-
910 assert( (eEnd==TK_FOLLOWING || eEnd==TK_PRECEDING)==(pEnd!=0) );-
911-
912-
913 /* If a frame is declared "RANGE" (not "ROWS"), then it may not use-
914 ** either "<expr> PRECEDING" or "<expr> FOLLOWING".-
915 */-
916 if( eType==TK_RANGE && (pStart!=0 || pEnd!=0) ){
eType==86Description
TRUEevaluated 693 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 1189 times by 1 test
Evaluated by:
  • Self test (438)
pStart!=0Description
TRUEevaluated 1 time by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 692 times by 1 test
Evaluated by:
  • Self test (438)
pEnd!=0Description
TRUEevaluated 1 time by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 691 times by 1 test
Evaluated by:
  • Self test (438)
1-1189
917 sqlite3ErrorMsg(pParse, "RANGE must use only UNBOUNDED or CURRENT ROW");-
918 goto windowAllocErr;
executed 2 times by 1 test: goto windowAllocErr;
Executed by:
  • Self test (438)
2
919 }-
920-
921 /* Additionally, the-
922 ** starting boundary type may not occur earlier in the following list than-
923 ** the ending boundary type:-
924 **-
925 ** UNBOUNDED PRECEDING-
926 ** <expr> PRECEDING-
927 ** CURRENT ROW-
928 ** <expr> FOLLOWING-
929 ** UNBOUNDED FOLLOWING-
930 **-
931 ** The parser ensures that "UNBOUNDED PRECEDING" cannot be used as an ending-
932 ** boundary, and than "UNBOUNDED FOLLOWING" cannot be used as a starting-
933 ** frame boundary.-
934 */-
935 if( (eStart==TK_CURRENT && eEnd==TK_PRECEDING)
eStart==82Description
TRUEevaluated 449 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 1431 times by 1 test
Evaluated by:
  • Self test (438)
eEnd==85Description
TRUEevaluated 1 time by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 448 times by 1 test
Evaluated by:
  • Self test (438)
1-1431
936 || (eStart==TK_FOLLOWING && (eEnd==TK_PRECEDING || eEnd==TK_CURRENT))
eStart==83Description
TRUEevaluated 189 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 1690 times by 1 test
Evaluated by:
  • Self test (438)
eEnd==85Description
TRUEevaluated 1 time by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 188 times by 1 test
Evaluated by:
  • Self test (438)
eEnd==82Description
TRUEevaluated 2 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 186 times by 1 test
Evaluated by:
  • Self test (438)
1-1690
937 ){-
938 sqlite3ErrorMsg(pParse, "unsupported frame delimiter for ROWS");-
939 goto windowAllocErr;
executed 4 times by 1 test: goto windowAllocErr;
Executed by:
  • Self test (438)
4
940 }-
941-
942 pWin = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window));-
943 if( pWin==0 ) goto windowAllocErr;
never executed: goto windowAllocErr;
pWin==0Description
TRUEnever evaluated
FALSEevaluated 1876 times by 1 test
Evaluated by:
  • Self test (438)
0-1876
944 pWin->eType = eType;-
945 pWin->eStart = eStart;-
946 pWin->eEnd = eEnd;-
947 pWin->pEnd = sqlite3WindowOffsetExpr(pParse, pEnd);-
948 pWin->pStart = sqlite3WindowOffsetExpr(pParse, pStart);-
949 return pWin;
executed 1876 times by 1 test: return pWin;
Executed by:
  • Self test (438)
1876
950-
951windowAllocErr:-
952 sqlite3ExprDelete(pParse->db, pEnd);-
953 sqlite3ExprDelete(pParse->db, pStart);-
954 return 0;
executed 6 times by 1 test: return 0;
Executed by:
  • Self test (438)
6
955}-
956-
957/*-
958** Attach window object pWin to expression p.-
959*/-
960void sqlite3WindowAttach(Parse *pParse, Expr *p, Window *pWin){-
961 if( p ){
pDescription
TRUEevaluated 1969 times by 1 test
Evaluated by:
  • Self test (438)
FALSEnever evaluated
0-1969
962 assert( p->op==TK_FUNCTION );-
963 /* This routine is only called for the parser. If pWin was not-
964 ** allocated due to an OOM, then the parser would fail before ever-
965 ** invoking this routine */-
966 if( ALWAYS(pWin) ){
(pWin)Description
TRUEevaluated 1969 times by 1 test
Evaluated by:
  • Self test (438)
FALSEnever evaluated
0-1969
967 p->y.pWin = pWin;-
968 ExprSetProperty(p, EP_WinFunc);-
969 pWin->pOwner = p;-
970 if( p->flags & EP_Distinct ){
p->flags & 0x000010Description
TRUEevaluated 1 time by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 1968 times by 1 test
Evaluated by:
  • Self test (438)
1-1968
971 sqlite3ErrorMsg(pParse,-
972 "DISTINCT is not supported for window functions");-
973 }
executed 1 time by 1 test: end of block
Executed by:
  • Self test (438)
1
974 }
executed 1969 times by 1 test: end of block
Executed by:
  • Self test (438)
1969
975 }else{
executed 1969 times by 1 test: end of block
Executed by:
  • Self test (438)
1969
976 sqlite3WindowDelete(pParse->db, pWin);-
977 }
never executed: end of block
0
978}-
979-
980/*-
981** Return 0 if the two window objects are identical, or non-zero otherwise.-
982** Identical window objects can be processed in a single scan.-
983*/-
984int sqlite3WindowCompare(Parse *pParse, Window *p1, Window *p2){-
985 if( p1->eType!=p2->eType ) return 1;
executed 45 times by 1 test: return 1;
Executed by:
  • Self test (438)
p1->eType!=p2->eTypeDescription
TRUEevaluated 45 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 271 times by 1 test
Evaluated by:
  • Self test (438)
45-271
986 if( p1->eStart!=p2->eStart ) return 1;
executed 32 times by 1 test: return 1;
Executed by:
  • Self test (438)
p1->eStart!=p2->eStartDescription
TRUEevaluated 32 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 239 times by 1 test
Evaluated by:
  • Self test (438)
32-239
987 if( p1->eEnd!=p2->eEnd ) return 1;
executed 24 times by 1 test: return 1;
Executed by:
  • Self test (438)
p1->eEnd!=p2->eEndDescription
TRUEevaluated 24 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 215 times by 1 test
Evaluated by:
  • Self test (438)
24-215
988 if( sqlite3ExprCompare(pParse, p1->pStart, p2->pStart, -1) ) return 1;
executed 4 times by 1 test: return 1;
Executed by:
  • Self test (438)
sqlite3ExprCom...2->pStart, -1)Description
TRUEevaluated 4 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 211 times by 1 test
Evaluated by:
  • Self test (438)
4-211
989 if( sqlite3ExprCompare(pParse, p1->pEnd, p2->pEnd, -1) ) return 1;
executed 4 times by 1 test: return 1;
Executed by:
  • Self test (438)
sqlite3ExprCom... p2->pEnd, -1)Description
TRUEevaluated 4 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 207 times by 1 test
Evaluated by:
  • Self test (438)
4-207
990 if( sqlite3ExprListCompare(p1->pPartition, p2->pPartition, -1) ) return 1;
executed 25 times by 1 test: return 1;
Executed by:
  • Self test (438)
sqlite3ExprLis...Partition, -1)Description
TRUEevaluated 25 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 182 times by 1 test
Evaluated by:
  • Self test (438)
25-182
991 if( sqlite3ExprListCompare(p1->pOrderBy, p2->pOrderBy, -1) ) return 1;
executed 25 times by 1 test: return 1;
Executed by:
  • Self test (438)
sqlite3ExprLis...>pOrderBy, -1)Description
TRUEevaluated 25 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 157 times by 1 test
Evaluated by:
  • Self test (438)
25-157
992 return 0;
executed 157 times by 1 test: return 0;
Executed by:
  • Self test (438)
157
993}-
994-
995-
996/*-
997** This is called by code in select.c before it calls sqlite3WhereBegin()-
998** to begin iterating through the sub-query results. It is used to allocate-
999** and initialize registers and cursors used by sqlite3WindowCodeStep().-
1000*/-
1001void sqlite3WindowCodeInit(Parse *pParse, Window *pMWin){-
1002 Window *pWin;-
1003 Vdbe *v = sqlite3GetVdbe(pParse);-
1004 int nPart = (pMWin->pPartition ? pMWin->pPartition->nExpr : 0);
pMWin->pPartitionDescription
TRUEevaluated 934 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 875 times by 1 test
Evaluated by:
  • Self test (438)
875-934
1005 nPart += (pMWin->pOrderBy ? pMWin->pOrderBy->nExpr : 0);
pMWin->pOrderByDescription
TRUEevaluated 1731 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 78 times by 1 test
Evaluated by:
  • Self test (438)
78-1731
1006 if( nPart ){
nPartDescription
TRUEevaluated 1751 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 58 times by 1 test
Evaluated by:
  • Self test (438)
58-1751
1007 pMWin->regPart = pParse->nMem+1;-
1008 pParse->nMem += nPart;-
1009 sqlite3VdbeAddOp3(v, OP_Null, 0, pMWin->regPart, pMWin->regPart+nPart-1);-
1010 }
executed 1751 times by 1 test: end of block
Executed by:
  • Self test (438)
1751
1011-
1012 for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
pWinDescription
TRUEevaluated 1956 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 1809 times by 1 test
Evaluated by:
  • Self test (438)
1809-1956
1013 FuncDef *p = pWin->pFunc;-
1014 if( (p->funcFlags & SQLITE_FUNC_MINMAX) && pWin->eStart!=TK_UNBOUNDED ){
(p->funcFlags & 0x1000)Description
TRUEevaluated 207 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 1749 times by 1 test
Evaluated by:
  • Self test (438)
pWin->eStart!=87Description
TRUEevaluated 94 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 113 times by 1 test
Evaluated by:
  • Self test (438)
94-1749
1015 /* The inline versions of min() and max() require a single ephemeral-
1016 ** table and 3 registers. The registers are used as follows:-
1017 **-
1018 ** regApp+0: slot to copy min()/max() argument to for MakeRecord-
1019 ** regApp+1: integer value used to ensure keys are unique-
1020 ** regApp+2: output of MakeRecord-
1021 */-
1022 ExprList *pList = pWin->pOwner->x.pList;-
1023 KeyInfo *pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pList, 0, 0);-
1024 pWin->csrApp = pParse->nTab++;-
1025 pWin->regApp = pParse->nMem+1;-
1026 pParse->nMem += 3;-
1027 if( pKeyInfo && pWin->pFunc->zName[1]=='i' ){
pKeyInfoDescription
TRUEevaluated 94 times by 1 test
Evaluated by:
  • Self test (438)
FALSEnever evaluated
pWin->pFunc->zName[1]=='i'Description
TRUEevaluated 44 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 50 times by 1 test
Evaluated by:
  • Self test (438)
0-94
1028 assert( pKeyInfo->aSortOrder[0]==0 );-
1029 pKeyInfo->aSortOrder[0] = 1;-
1030 }
executed 44 times by 1 test: end of block
Executed by:
  • Self test (438)
44
1031 sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pWin->csrApp, 2);-
1032 sqlite3VdbeAppendP4(v, pKeyInfo, P4_KEYINFO);-
1033 sqlite3VdbeAddOp2(v, OP_Integer, 0, pWin->regApp+1);-
1034 }
executed 94 times by 1 test: end of block
Executed by:
  • Self test (438)
94
1035 else if( p->zName==nth_valueName || p->zName==first_valueName ){
p->zName==nth_valueNameDescription
TRUEevaluated 118 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 1744 times by 1 test
Evaluated by:
  • Self test (438)
p->zName==first_valueNameDescription
TRUEevaluated 103 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 1641 times by 1 test
Evaluated by:
  • Self test (438)
103-1744
1036 /* Allocate two registers at pWin->regApp. These will be used to-
1037 ** store the start and end index of the current frame. */-
1038 assert( pMWin->iEphCsr );-
1039 pWin->regApp = pParse->nMem+1;-
1040 pWin->csrApp = pParse->nTab++;-
1041 pParse->nMem += 2;-
1042 sqlite3VdbeAddOp2(v, OP_OpenDup, pWin->csrApp, pMWin->iEphCsr);-
1043 }
executed 221 times by 1 test: end of block
Executed by:
  • Self test (438)
221
1044 else if( p->zName==leadName || p->zName==lagName ){
p->zName==leadNameDescription
TRUEevaluated 122 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 1519 times by 1 test
Evaluated by:
  • Self test (438)
p->zName==lagNameDescription
TRUEevaluated 107 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 1412 times by 1 test
Evaluated by:
  • Self test (438)
107-1519
1045 assert( pMWin->iEphCsr );-
1046 pWin->csrApp = pParse->nTab++;-
1047 sqlite3VdbeAddOp2(v, OP_OpenDup, pWin->csrApp, pMWin->iEphCsr);-
1048 }
executed 229 times by 1 test: end of block
Executed by:
  • Self test (438)
229
1049 }
executed 1956 times by 1 test: end of block
Executed by:
  • Self test (438)
1956
1050}
executed 1809 times by 1 test: end of block
Executed by:
  • Self test (438)
1809
1051-
1052/*-
1053** A "PRECEDING <expr>" (eCond==0) or "FOLLOWING <expr>" (eCond==1) or the-
1054** value of the second argument to nth_value() (eCond==2) has just been-
1055** evaluated and the result left in register reg. This function generates VM-
1056** code to check that the value is a non-negative integer and throws an-
1057** exception if it is not.-
1058*/-
1059static void windowCheckIntValue(Parse *pParse, int reg, int eCond){-
1060 static const char *azErr[] = {-
1061 "frame starting offset must be a non-negative integer",-
1062 "frame ending offset must be a non-negative integer",-
1063 "second argument to nth_value must be a positive integer"-
1064 };-
1065 static int aOp[] = { OP_Ge, OP_Ge, OP_Gt };-
1066 Vdbe *v = sqlite3GetVdbe(pParse);-
1067 int regZero = sqlite3GetTempReg(pParse);-
1068 assert( eCond==0 || eCond==1 || eCond==2 );-
1069 sqlite3VdbeAddOp2(v, OP_Integer, 0, regZero);-
1070 sqlite3VdbeAddOp2(v, OP_MustBeInt, reg, sqlite3VdbeCurrentAddr(v)+2);-
1071 VdbeCoverageIf(v, eCond==0);-
1072 VdbeCoverageIf(v, eCond==1);-
1073 VdbeCoverageIf(v, eCond==2);-
1074 sqlite3VdbeAddOp3(v, aOp[eCond], regZero, sqlite3VdbeCurrentAddr(v)+2, reg);-
1075 VdbeCoverageNeverNullIf(v, eCond==0);-
1076 VdbeCoverageNeverNullIf(v, eCond==1);-
1077 VdbeCoverageNeverNullIf(v, eCond==2);-
1078 sqlite3VdbeAddOp2(v, OP_Halt, SQLITE_ERROR, OE_Abort);-
1079 sqlite3VdbeAppendP4(v, (void*)azErr[eCond], P4_STATIC);-
1080 sqlite3ReleaseTempReg(pParse, regZero);-
1081}
executed 901 times by 1 test: end of block
Executed by:
  • Self test (438)
901
1082-
1083/*-
1084** Return the number of arguments passed to the window-function associated-
1085** with the object passed as the only argument to this function.-
1086*/-
1087static int windowArgCount(Window *pWin){-
1088 ExprList *pList = pWin->pOwner->x.pList;-
1089 return (pList ? pList->nExpr : 0);
executed 8183 times by 1 test: return (pList ? pList->nExpr : 0);
Executed by:
  • Self test (438)
pListDescription
TRUEevaluated 5704 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 2479 times by 1 test
Evaluated by:
  • Self test (438)
2479-8183
1090}-
1091-
1092/*-
1093** Generate VM code to invoke either xStep() (if bInverse is 0) or -
1094** xInverse (if bInverse is non-zero) for each window function in the -
1095** linked list starting at pMWin. Or, for built-in window functions-
1096** that do not use the standard function API, generate the required-
1097** inline VM code.-
1098**-
1099** If argument csr is greater than or equal to 0, then argument reg is-
1100** the first register in an array of registers guaranteed to be large-
1101** enough to hold the array of arguments for each function. In this case-
1102** the arguments are extracted from the current row of csr into the-
1103** array of registers before invoking OP_AggStep or OP_AggInverse-
1104**-
1105** Or, if csr is less than zero, then the array of registers at reg is-
1106** already populated with all columns from the current row of the sub-query.-
1107**-
1108** If argument regPartSize is non-zero, then it is a register containing the-
1109** number of rows in the current partition.-
1110*/-
1111static void windowAggStep(-
1112 Parse *pParse, -
1113 Window *pMWin, /* Linked list of window functions */-
1114 int csr, /* Read arguments from this cursor */-
1115 int bInverse, /* True to invoke xInverse instead of xStep */-
1116 int reg, /* Array of registers */-
1117 int regPartSize /* Register containing size of partition */-
1118){-
1119 Vdbe *v = sqlite3GetVdbe(pParse);-
1120 Window *pWin;-
1121 for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
pWinDescription
TRUEevaluated 2609 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 2410 times by 1 test
Evaluated by:
  • Self test (438)
2410-2609
1122 int flags = pWin->pFunc->funcFlags;-
1123 int regArg;-
1124 int nArg = windowArgCount(pWin);-
1125-
1126 if( csr>=0 ){
csr>=0Description
TRUEevaluated 1945 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 664 times by 1 test
Evaluated by:
  • Self test (438)
664-1945
1127 int i;-
1128 for(i=0; i<nArg; i++){
i<nArgDescription
TRUEevaluated 2388 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 1945 times by 1 test
Evaluated by:
  • Self test (438)
1945-2388
1129 sqlite3VdbeAddOp3(v, OP_Column, csr, pWin->iArgCol+i, reg+i);-
1130 }
executed 2388 times by 1 test: end of block
Executed by:
  • Self test (438)
2388
1131 regArg = reg;-
1132 if( flags & SQLITE_FUNC_WINDOW_SIZE ){
flags & 0x20000Description
TRUEevaluated 350 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 1595 times by 1 test
Evaluated by:
  • Self test (438)
350-1595
1133 if( nArg==0 ){
nArg==0Description
TRUEevaluated 207 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 143 times by 1 test
Evaluated by:
  • Self test (438)
143-207
1134 regArg = regPartSize;-
1135 }else{
executed 207 times by 1 test: end of block
Executed by:
  • Self test (438)
207
1136 sqlite3VdbeAddOp2(v, OP_SCopy, regPartSize, reg+nArg);-
1137 }
executed 143 times by 1 test: end of block
Executed by:
  • Self test (438)
143
1138 nArg++;-
1139 }
executed 350 times by 1 test: end of block
Executed by:
  • Self test (438)
350
1140 }else{
executed 1945 times by 1 test: end of block
Executed by:
  • Self test (438)
1945
1141 assert( !(flags & SQLITE_FUNC_WINDOW_SIZE) );-
1142 regArg = reg + pWin->iArgCol;-
1143 }
executed 664 times by 1 test: end of block
Executed by:
  • Self test (438)
664
1144-
1145 if( (pWin->pFunc->funcFlags & SQLITE_FUNC_MINMAX)
(pWin->pFunc->...lags & 0x1000)Description
TRUEevaluated 291 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 2318 times by 1 test
Evaluated by:
  • Self test (438)
291-2318
1146 && pWin->eStart!=TK_UNBOUNDED
pWin->eStart!=87Description
TRUEevaluated 178 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 113 times by 1 test
Evaluated by:
  • Self test (438)
113-178
1147 ){-
1148 int addrIsNull = sqlite3VdbeAddOp1(v, OP_IsNull, regArg);-
1149 VdbeCoverage(v);-
1150 if( bInverse==0 ){
bInverse==0Description
TRUEevaluated 94 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 84 times by 1 test
Evaluated by:
  • Self test (438)
84-94
1151 sqlite3VdbeAddOp2(v, OP_AddImm, pWin->regApp+1, 1);-
1152 sqlite3VdbeAddOp2(v, OP_SCopy, regArg, pWin->regApp);-
1153 sqlite3VdbeAddOp3(v, OP_MakeRecord, pWin->regApp, 2, pWin->regApp+2);-
1154 sqlite3VdbeAddOp2(v, OP_IdxInsert, pWin->csrApp, pWin->regApp+2);-
1155 }else{
executed 94 times by 1 test: end of block
Executed by:
  • Self test (438)
94
1156 sqlite3VdbeAddOp4Int(v, OP_SeekGE, pWin->csrApp, 0, regArg, 1);-
1157 VdbeCoverageNeverTaken(v);-
1158 sqlite3VdbeAddOp1(v, OP_Delete, pWin->csrApp);-
1159 sqlite3VdbeJumpHere(v, sqlite3VdbeCurrentAddr(v)-2);-
1160 }
executed 84 times by 1 test: end of block
Executed by:
  • Self test (438)
84
1161 sqlite3VdbeJumpHere(v, addrIsNull);-
1162 }else if( pWin->regApp ){
executed 178 times by 1 test: end of block
Executed by:
  • Self test (438)
pWin->regAppDescription
TRUEevaluated 353 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 2078 times by 1 test
Evaluated by:
  • Self test (438)
178-2078
1163 assert( pWin->pFunc->zName==nth_valueName-
1164 || pWin->pFunc->zName==first_valueName-
1165 );-
1166 assert( bInverse==0 || bInverse==1 );-
1167 sqlite3VdbeAddOp2(v, OP_AddImm, pWin->regApp+1-bInverse, 1);-
1168 }else if( pWin->pFunc->zName==leadName
executed 353 times by 1 test: end of block
Executed by:
  • Self test (438)
pWin->pFunc->zName==leadNameDescription
TRUEevaluated 188 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 1890 times by 1 test
Evaluated by:
  • Self test (438)
188-1890
1169 || pWin->pFunc->zName==lagName
pWin->pFunc->zName==lagNameDescription
TRUEevaluated 173 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 1717 times by 1 test
Evaluated by:
  • Self test (438)
173-1717
1170 ){-
1171 /* no-op */-
1172 }else{
executed 361 times by 1 test: end of block
Executed by:
  • Self test (438)
361
1173 int addrIf = 0;-
1174 if( pWin->pFilter ){
pWin->pFilterDescription
TRUEevaluated 113 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 1604 times by 1 test
Evaluated by:
  • Self test (438)
113-1604
1175 int regTmp;-
1176 assert( nArg==0 || nArg==pWin->pOwner->x.pList->nExpr );-
1177 assert( nArg || pWin->pOwner->x.pList==0 );-
1178 if( csr>0 ){
csr>0Description
TRUEevaluated 94 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 19 times by 1 test
Evaluated by:
  • Self test (438)
19-94
1179 regTmp = sqlite3GetTempReg(pParse);-
1180 sqlite3VdbeAddOp3(v, OP_Column, csr, pWin->iArgCol+nArg,regTmp);-
1181 }else{
executed 94 times by 1 test: end of block
Executed by:
  • Self test (438)
94
1182 regTmp = regArg + nArg;-
1183 }
executed 19 times by 1 test: end of block
Executed by:
  • Self test (438)
19
1184 addrIf = sqlite3VdbeAddOp3(v, OP_IfNot, regTmp, 0, 1);-
1185 VdbeCoverage(v);-
1186 if( csr>0 ){
csr>0Description
TRUEevaluated 94 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 19 times by 1 test
Evaluated by:
  • Self test (438)
19-94
1187 sqlite3ReleaseTempReg(pParse, regTmp);-
1188 }
executed 94 times by 1 test: end of block
Executed by:
  • Self test (438)
94
1189 }
executed 113 times by 1 test: end of block
Executed by:
  • Self test (438)
113
1190 if( pWin->pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL ){
pWin->pFunc->f...Flags & 0x0020Description
TRUEevaluated 113 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 1604 times by 1 test
Evaluated by:
  • Self test (438)
113-1604
1191 CollSeq *pColl;-
1192 assert( nArg>0 );-
1193 pColl = sqlite3ExprNNCollSeq(pParse, pWin->pOwner->x.pList->a[0].pExpr);-
1194 sqlite3VdbeAddOp4(v, OP_CollSeq, 0,0,0, (const char*)pColl, P4_COLLSEQ);-
1195 }
executed 113 times by 1 test: end of block
Executed by:
  • Self test (438)
113
1196 sqlite3VdbeAddOp3(v, bInverse? OP_AggInverse : OP_AggStep, -
1197 bInverse, regArg, pWin->regAccum);-
1198 sqlite3VdbeAppendP4(v, pWin->pFunc, P4_FUNCDEF);-
1199 sqlite3VdbeChangeP5(v, (u8)nArg);-
1200 if( addrIf ) sqlite3VdbeJumpHere(v, addrIf);
executed 113 times by 1 test: sqlite3VdbeJumpHere(v, addrIf);
Executed by:
  • Self test (438)
addrIfDescription
TRUEevaluated 113 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 1604 times by 1 test
Evaluated by:
  • Self test (438)
113-1604
1201 }
executed 1717 times by 1 test: end of block
Executed by:
  • Self test (438)
1717
1202 }-
1203}
executed 2410 times by 1 test: end of block
Executed by:
  • Self test (438)
2410
1204-
1205/*-
1206** Generate VM code to invoke either xValue() (bFinal==0) or xFinalize()-
1207** (bFinal==1) for each window function in the linked list starting at-
1208** pMWin. Or, for built-in window-functions that do not use the standard-
1209** API, generate the equivalent VM code.-
1210*/-
1211static void windowAggFinal(Parse *pParse, Window *pMWin, int bFinal){-
1212 Vdbe *v = sqlite3GetVdbe(pParse);-
1213 Window *pWin;-
1214-
1215 for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
pWinDescription
TRUEevaluated 3460 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 3187 times by 1 test
Evaluated by:
  • Self test (438)
3187-3460
1216 if( (pWin->pFunc->funcFlags & SQLITE_FUNC_MINMAX)
(pWin->pFunc->...lags & 0x1000)Description
TRUEevaluated 400 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 3060 times by 1 test
Evaluated by:
  • Self test (438)
400-3060
1217 && pWin->eStart!=TK_UNBOUNDED
pWin->eStart!=87Description
TRUEevaluated 122 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 278 times by 1 test
Evaluated by:
  • Self test (438)
122-278
1218 ){-
1219 sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regResult);-
1220 sqlite3VdbeAddOp1(v, OP_Last, pWin->csrApp);-
1221 VdbeCoverage(v);-
1222 sqlite3VdbeAddOp3(v, OP_Column, pWin->csrApp, 0, pWin->regResult);-
1223 sqlite3VdbeJumpHere(v, sqlite3VdbeCurrentAddr(v)-2);-
1224 if( bFinal ){
bFinalDescription
TRUEevaluated 28 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 94 times by 1 test
Evaluated by:
  • Self test (438)
28-94
1225 sqlite3VdbeAddOp1(v, OP_ResetSorter, pWin->csrApp);-
1226 }
executed 28 times by 1 test: end of block
Executed by:
  • Self test (438)
28
1227 }else if( pWin->regApp ){
executed 122 times by 1 test: end of block
Executed by:
  • Self test (438)
pWin->regAppDescription
TRUEevaluated 286 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 3052 times by 1 test
Evaluated by:
  • Self test (438)
122-3052
1228 }else{
executed 286 times by 1 test: end of block
Executed by:
  • Self test (438)
286
1229 if( bFinal ){
bFinalDescription
TRUEevaluated 1072 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 1980 times by 1 test
Evaluated by:
  • Self test (438)
1072-1980
1230 sqlite3VdbeAddOp2(v, OP_AggFinal, pWin->regAccum, windowArgCount(pWin));-
1231 sqlite3VdbeAppendP4(v, pWin->pFunc, P4_FUNCDEF);-
1232 sqlite3VdbeAddOp2(v, OP_Copy, pWin->regAccum, pWin->regResult);-
1233 sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regAccum);-
1234 }else{
executed 1072 times by 1 test: end of block
Executed by:
  • Self test (438)
1072
1235 sqlite3VdbeAddOp3(v, OP_AggValue, pWin->regAccum, windowArgCount(pWin),-
1236 pWin->regResult);-
1237 sqlite3VdbeAppendP4(v, pWin->pFunc, P4_FUNCDEF);-
1238 }
executed 1980 times by 1 test: end of block
Executed by:
  • Self test (438)
1980
1239 }-
1240 }-
1241}
executed 3187 times by 1 test: end of block
Executed by:
  • Self test (438)
3187
1242-
1243/*-
1244** This function generates VM code to invoke the sub-routine at address-
1245** lblFlushPart once for each partition with the entire partition cached in-
1246** the Window.iEphCsr temp table.-
1247*/-
1248static void windowPartitionCache(-
1249 Parse *pParse,-
1250 Select *p, /* The rewritten SELECT statement */-
1251 WhereInfo *pWInfo, /* WhereInfo to call WhereEnd() on */-
1252 int regFlushPart, /* Register to use with Gosub lblFlushPart */-
1253 int lblFlushPart, /* Subroutine to Gosub to */-
1254 int *pRegSize /* OUT: Register containing partition size */-
1255){-
1256 Window *pMWin = p->pWin;-
1257 Vdbe *v = sqlite3GetVdbe(pParse);-
1258 int iSubCsr = p->pSrc->a[0].iCursor;-
1259 int nSub = p->pSrc->a[0].pTab->nCol;-
1260 int k;-
1261-
1262 int reg = pParse->nMem+1;-
1263 int regRecord = reg+nSub;-
1264 int regRowid = regRecord+1;-
1265-
1266 *pRegSize = regRowid;-
1267 pParse->nMem += nSub + 2;-
1268-
1269 /* Load the column values for the row returned by the sub-select-
1270 ** into an array of registers starting at reg. */-
1271 for(k=0; k<nSub; k++){
k<nSubDescription
TRUEevaluated 4172 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 1212 times by 1 test
Evaluated by:
  • Self test (438)
1212-4172
1272 sqlite3VdbeAddOp3(v, OP_Column, iSubCsr, k, reg+k);-
1273 }
executed 4172 times by 1 test: end of block
Executed by:
  • Self test (438)
4172
1274 sqlite3VdbeAddOp3(v, OP_MakeRecord, reg, nSub, regRecord);-
1275-
1276 /* Check if this is the start of a new partition. If so, call the-
1277 ** flush_partition sub-routine. */-
1278 if( pMWin->pPartition ){
pMWin->pPartitionDescription
TRUEevaluated 583 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 629 times by 1 test
Evaluated by:
  • Self test (438)
583-629
1279 int addr;-
1280 ExprList *pPart = pMWin->pPartition;-
1281 int nPart = pPart->nExpr;-
1282 int regNewPart = reg + pMWin->nBufferCol;-
1283 KeyInfo *pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pPart, 0, 0);-
1284-
1285 addr = sqlite3VdbeAddOp3(v, OP_Compare, regNewPart, pMWin->regPart,nPart);-
1286 sqlite3VdbeAppendP4(v, (void*)pKeyInfo, P4_KEYINFO);-
1287 sqlite3VdbeAddOp3(v, OP_Jump, addr+2, addr+4, addr+2);-
1288 VdbeCoverageEqNe(v);-
1289 sqlite3VdbeAddOp3(v, OP_Copy, regNewPart, pMWin->regPart, nPart-1);-
1290 sqlite3VdbeAddOp2(v, OP_Gosub, regFlushPart, lblFlushPart);-
1291 VdbeComment((v, "call flush_partition"));-
1292 }
executed 583 times by 1 test: end of block
Executed by:
  • Self test (438)
583
1293-
1294 /* Buffer the current row in the ephemeral table. */-
1295 sqlite3VdbeAddOp2(v, OP_NewRowid, pMWin->iEphCsr, regRowid);-
1296 sqlite3VdbeAddOp3(v, OP_Insert, pMWin->iEphCsr, regRecord, regRowid);-
1297-
1298 /* End of the input loop */-
1299 sqlite3WhereEnd(pWInfo);-
1300-
1301 /* Invoke "flush_partition" to deal with the final (or only) partition */-
1302 sqlite3VdbeAddOp2(v, OP_Gosub, regFlushPart, lblFlushPart);-
1303 VdbeComment((v, "call flush_partition"));-
1304}
executed 1212 times by 1 test: end of block
Executed by:
  • Self test (438)
1212
1305-
1306/*-
1307** Invoke the sub-routine at regGosub (generated by code in select.c) to-
1308** return the current row of Window.iEphCsr. If all window functions are-
1309** aggregate window functions that use the standard API, a single-
1310** OP_Gosub instruction is all that this routine generates. Extra VM code-
1311** for per-row processing is only generated for the following built-in window-
1312** functions:-
1313**-
1314** nth_value()-
1315** first_value()-
1316** lag()-
1317** lead()-
1318*/-
1319static void windowReturnOneRow(-
1320 Parse *pParse,-
1321 Window *pMWin,-
1322 int regGosub,-
1323 int addrGosub-
1324){-
1325 Vdbe *v = sqlite3GetVdbe(pParse);-
1326 Window *pWin;-
1327 for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
pWinDescription
TRUEevaluated 1811 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 1709 times by 1 test
Evaluated by:
  • Self test (438)
1709-1811
1328 FuncDef *pFunc = pWin->pFunc;-
1329 if( pFunc->zName==nth_valueName
pFunc->zName==nth_valueNameDescription
TRUEevaluated 158 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 1653 times by 1 test
Evaluated by:
  • Self test (438)
158-1653
1330 || pFunc->zName==first_valueName
pFunc->zName==first_valueNameDescription
TRUEevaluated 128 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 1525 times by 1 test
Evaluated by:
  • Self test (438)
128-1525
1331 ){-
1332 int csr = pWin->csrApp;-
1333 int lbl = sqlite3VdbeMakeLabel(v);-
1334 int tmpReg = sqlite3GetTempReg(pParse);-
1335 sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regResult);-
1336-
1337 if( pFunc->zName==nth_valueName ){
pFunc->zName==nth_valueNameDescription
TRUEevaluated 158 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 128 times by 1 test
Evaluated by:
  • Self test (438)
128-158
1338 sqlite3VdbeAddOp3(v, OP_Column, pMWin->iEphCsr, pWin->iArgCol+1,tmpReg);-
1339 windowCheckIntValue(pParse, tmpReg, 2);-
1340 }else{
executed 158 times by 1 test: end of block
Executed by:
  • Self test (438)
158
1341 sqlite3VdbeAddOp2(v, OP_Integer, 1, tmpReg);-
1342 }
executed 128 times by 1 test: end of block
Executed by:
  • Self test (438)
128
1343 sqlite3VdbeAddOp3(v, OP_Add, tmpReg, pWin->regApp, tmpReg);-
1344 sqlite3VdbeAddOp3(v, OP_Gt, pWin->regApp+1, lbl, tmpReg);-
1345 VdbeCoverageNeverNull(v);-
1346 sqlite3VdbeAddOp3(v, OP_SeekRowid, csr, 0, tmpReg);-
1347 VdbeCoverageNeverTaken(v);-
1348 sqlite3VdbeAddOp3(v, OP_Column, csr, pWin->iArgCol, pWin->regResult);-
1349 sqlite3VdbeResolveLabel(v, lbl);-
1350 sqlite3ReleaseTempReg(pParse, tmpReg);-
1351 }
executed 286 times by 1 test: end of block
Executed by:
  • Self test (438)
286
1352 else if( pFunc->zName==leadName || pFunc->zName==lagName ){
pFunc->zName==leadNameDescription
TRUEevaluated 166 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 1359 times by 1 test
Evaluated by:
  • Self test (438)
pFunc->zName==lagNameDescription
TRUEevaluated 136 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 1223 times by 1 test
Evaluated by:
  • Self test (438)
136-1359
1353 int nArg = pWin->pOwner->x.pList->nExpr;-
1354 int iEph = pMWin->iEphCsr;-
1355 int csr = pWin->csrApp;-
1356 int lbl = sqlite3VdbeMakeLabel(v);-
1357 int tmpReg = sqlite3GetTempReg(pParse);-
1358-
1359 if( nArg<3 ){
nArg<3Description
TRUEevaluated 292 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 10 times by 1 test
Evaluated by:
  • Self test (438)
10-292
1360 sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regResult);-
1361 }else{
executed 292 times by 1 test: end of block
Executed by:
  • Self test (438)
292
1362 sqlite3VdbeAddOp3(v, OP_Column, iEph, pWin->iArgCol+2, pWin->regResult);-
1363 }
executed 10 times by 1 test: end of block
Executed by:
  • Self test (438)
10
1364 sqlite3VdbeAddOp2(v, OP_Rowid, iEph, tmpReg);-
1365 if( nArg<2 ){
nArg<2Description
TRUEevaluated 22 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 280 times by 1 test
Evaluated by:
  • Self test (438)
22-280
1366 int val = (pFunc->zName==leadName ? 1 : -1);
pFunc->zName==leadNameDescription
TRUEevaluated 18 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 4 times by 1 test
Evaluated by:
  • Self test (438)
4-18
1367 sqlite3VdbeAddOp2(v, OP_AddImm, tmpReg, val);-
1368 }else{
executed 22 times by 1 test: end of block
Executed by:
  • Self test (438)
22
1369 int op = (pFunc->zName==leadName ? OP_Add : OP_Subtract);
pFunc->zName==leadNameDescription
TRUEevaluated 148 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 132 times by 1 test
Evaluated by:
  • Self test (438)
132-148
1370 int tmpReg2 = sqlite3GetTempReg(pParse);-
1371 sqlite3VdbeAddOp3(v, OP_Column, iEph, pWin->iArgCol+1, tmpReg2);-
1372 sqlite3VdbeAddOp3(v, op, tmpReg2, tmpReg, tmpReg);-
1373 sqlite3ReleaseTempReg(pParse, tmpReg2);-
1374 }
executed 280 times by 1 test: end of block
Executed by:
  • Self test (438)
280
1375-
1376 sqlite3VdbeAddOp3(v, OP_SeekRowid, csr, lbl, tmpReg);-
1377 VdbeCoverage(v);-
1378 sqlite3VdbeAddOp3(v, OP_Column, csr, pWin->iArgCol, pWin->regResult);-
1379 sqlite3VdbeResolveLabel(v, lbl);-
1380 sqlite3ReleaseTempReg(pParse, tmpReg);-
1381 }
executed 302 times by 1 test: end of block
Executed by:
  • Self test (438)
302
1382 }
executed 1811 times by 1 test: end of block
Executed by:
  • Self test (438)
1811
1383 sqlite3VdbeAddOp2(v, OP_Gosub, regGosub, addrGosub);-
1384}
executed 1709 times by 1 test: end of block
Executed by:
  • Self test (438)
1709
1385-
1386/*-
1387** Invoke the code generated by windowReturnOneRow() and, optionally, the-
1388** xInverse() function for each window function, for one or more rows-
1389** from the Window.iEphCsr temp table. This routine generates VM code-
1390** similar to:-
1391**-
1392** while( regCtr>0 ){-
1393** regCtr--;-
1394** windowReturnOneRow()-
1395** if( bInverse ){-
1396** AggInverse-
1397** }-
1398** Next (Window.iEphCsr)-
1399** }-
1400*/-
1401static void windowReturnRows(-
1402 Parse *pParse,-
1403 Window *pMWin, /* List of window functions */-
1404 int regCtr, /* Register containing number of rows */-
1405 int regGosub, /* Register for Gosub addrGosub */-
1406 int addrGosub, /* Address of sub-routine for ReturnOneRow */-
1407 int regInvArg, /* Array of registers for xInverse args */-
1408 int regInvSize /* Register containing size of partition */-
1409){-
1410 int addr;-
1411 Vdbe *v = sqlite3GetVdbe(pParse);-
1412 windowAggFinal(pParse, pMWin, 0);-
1413 addr = sqlite3VdbeAddOp3(v, OP_IfPos, regCtr, sqlite3VdbeCurrentAddr(v)+2 ,1);-
1414 VdbeCoverage(v);-
1415 sqlite3VdbeAddOp2(v, OP_Goto, 0, 0);-
1416 windowReturnOneRow(pParse, pMWin, regGosub, addrGosub);-
1417 if( regInvArg ){
regInvArgDescription
TRUEevaluated 85 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 936 times by 1 test
Evaluated by:
  • Self test (438)
85-936
1418 windowAggStep(pParse, pMWin, pMWin->iEphCsr, 1, regInvArg, regInvSize);-
1419 }
executed 85 times by 1 test: end of block
Executed by:
  • Self test (438)
85
1420 sqlite3VdbeAddOp2(v, OP_Next, pMWin->iEphCsr, addr);-
1421 VdbeCoverage(v);-
1422 sqlite3VdbeJumpHere(v, addr+1); /* The OP_Goto */-
1423}
executed 1021 times by 1 test: end of block
Executed by:
  • Self test (438)
1021
1424-
1425/*-
1426** Generate code to set the accumulator register for each window function-
1427** in the linked list passed as the second argument to NULL. And perform-
1428** any equivalent initialization required by any built-in window functions-
1429** in the list.-
1430*/-
1431static int windowInitAccum(Parse *pParse, Window *pMWin){-
1432 Vdbe *v = sqlite3GetVdbe(pParse);-
1433 int regArg;-
1434 int nArg = 0;-
1435 Window *pWin;-
1436 for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
pWinDescription
TRUEevaluated 1292 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 1212 times by 1 test
Evaluated by:
  • Self test (438)
1212-1292
1437 FuncDef *pFunc = pWin->pFunc;-
1438 sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regAccum);-
1439 nArg = MAX(nArg, windowArgCount(pWin));
(nArg)>(windowArgCount(pWin))Description
TRUEevaluated 62 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 1230 times by 1 test
Evaluated by:
  • Self test (438)
62-1230
1440 if( pFunc->zName==nth_valueName
pFunc->zName==nth_valueNameDescription
TRUEevaluated 118 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 1174 times by 1 test
Evaluated by:
  • Self test (438)
118-1174
1441 || pFunc->zName==first_valueName
pFunc->zName==first_valueNameDescription
TRUEevaluated 103 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 1071 times by 1 test
Evaluated by:
  • Self test (438)
103-1071
1442 ){-
1443 sqlite3VdbeAddOp2(v, OP_Integer, 0, pWin->regApp);-
1444 sqlite3VdbeAddOp2(v, OP_Integer, 0, pWin->regApp+1);-
1445 }
executed 221 times by 1 test: end of block
Executed by:
  • Self test (438)
221
1446-
1447 if( (pFunc->funcFlags & SQLITE_FUNC_MINMAX) && pWin->csrApp ){
(pFunc->funcFlags & 0x1000)Description
TRUEevaluated 92 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 1200 times by 1 test
Evaluated by:
  • Self test (438)
pWin->csrAppDescription
TRUEevaluated 84 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 8 times by 1 test
Evaluated by:
  • Self test (438)
8-1200
1448 assert( pWin->eStart!=TK_UNBOUNDED );-
1449 sqlite3VdbeAddOp1(v, OP_ResetSorter, pWin->csrApp);-
1450 sqlite3VdbeAddOp2(v, OP_Integer, 0, pWin->regApp+1);-
1451 }
executed 84 times by 1 test: end of block
Executed by:
  • Self test (438)
84
1452 }
executed 1292 times by 1 test: end of block
Executed by:
  • Self test (438)
1292
1453 regArg = pParse->nMem+1;-
1454 pParse->nMem += nArg;-
1455 return regArg;
executed 1212 times by 1 test: return regArg;
Executed by:
  • Self test (438)
1212
1456}-
1457-
1458-
1459/*-
1460** This function does the work of sqlite3WindowCodeStep() for all "ROWS"-
1461** window frame types except for "BETWEEN UNBOUNDED PRECEDING AND CURRENT-
1462** ROW". Pseudo-code for each follows.-
1463**-
1464** ROWS BETWEEN <expr1> PRECEDING AND <expr2> FOLLOWING-
1465**-
1466** ...-
1467** if( new partition ){-
1468** Gosub flush_partition-
1469** }-
1470** Insert (record in eph-table)-
1471** sqlite3WhereEnd()-
1472** Gosub flush_partition-
1473** -
1474** flush_partition:-
1475** Once {-
1476** OpenDup (iEphCsr -> csrStart)-
1477** OpenDup (iEphCsr -> csrEnd)-
1478** }-
1479** regStart = <expr1> // PRECEDING expression-
1480** regEnd = <expr2> // FOLLOWING expression-
1481** if( regStart<0 || regEnd<0 ){ error! }-
1482** Rewind (csr,csrStart,csrEnd) // if EOF goto flush_partition_done-
1483** Next(csrEnd) // if EOF skip Aggstep-
1484** Aggstep (csrEnd)-
1485** if( (regEnd--)<=0 ){-
1486** AggFinal (xValue)-
1487** Gosub addrGosub-
1488** Next(csr) // if EOF goto flush_partition_done-
1489** if( (regStart--)<=0 ){-
1490** AggInverse (csrStart)-
1491** Next(csrStart)-
1492** }-
1493** }-
1494** flush_partition_done:-
1495** ResetSorter (csr)-
1496** Return-
1497**-
1498** ROWS BETWEEN <expr> PRECEDING AND CURRENT ROW-
1499** ROWS BETWEEN CURRENT ROW AND <expr> FOLLOWING-
1500** ROWS BETWEEN UNBOUNDED PRECEDING AND <expr> FOLLOWING-
1501**-
1502** These are similar to the above. For "CURRENT ROW", intialize the-
1503** register to 0. For "UNBOUNDED PRECEDING" to infinity.-
1504**-
1505** ROWS BETWEEN <expr> PRECEDING AND UNBOUNDED FOLLOWING-
1506** ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING-
1507**-
1508** Rewind (csr,csrStart,csrEnd) // if EOF goto flush_partition_done-
1509** while( 1 ){-
1510** Next(csrEnd) // Exit while(1) at EOF-
1511** Aggstep (csrEnd)-
1512** }-
1513** while( 1 ){-
1514** AggFinal (xValue)-
1515** Gosub addrGosub-
1516** Next(csr) // if EOF goto flush_partition_done-
1517** if( (regStart--)<=0 ){-
1518** AggInverse (csrStart)-
1519** Next(csrStart)-
1520** }-
1521** }-
1522**-
1523** For the "CURRENT ROW AND UNBOUNDED FOLLOWING" case, the final if() -
1524** condition is always true (as if regStart were initialized to 0).-
1525**-
1526** RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING-
1527** -
1528** This is the only RANGE case handled by this routine. It modifies the-
1529** second while( 1 ) loop in "ROWS BETWEEN CURRENT ... UNBOUNDED..." to-
1530** be:-
1531**-
1532** while( 1 ){-
1533** AggFinal (xValue)-
1534** while( 1 ){-
1535** regPeer++-
1536** Gosub addrGosub-
1537** Next(csr) // if EOF goto flush_partition_done-
1538** if( new peer ) break;-
1539** }-
1540** while( (regPeer--)>0 ){-
1541** AggInverse (csrStart)-
1542** Next(csrStart)-
1543** }-
1544** }-
1545**-
1546** ROWS BETWEEN <expr> FOLLOWING AND <expr> FOLLOWING-
1547**-
1548** regEnd = regEnd - regStart-
1549** Rewind (csr,csrStart,csrEnd) // if EOF goto flush_partition_done-
1550** Aggstep (csrEnd)-
1551** Next(csrEnd) // if EOF fall-through-
1552** if( (regEnd--)<=0 ){-
1553** if( (regStart--)<=0 ){-
1554** AggFinal (xValue)-
1555** Gosub addrGosub-
1556** Next(csr) // if EOF goto flush_partition_done-
1557** }-
1558** AggInverse (csrStart)-
1559** Next (csrStart)-
1560** }-
1561**-
1562** ROWS BETWEEN <expr> PRECEDING AND <expr> PRECEDING-
1563**-
1564** Replace the bit after "Rewind" in the above with:-
1565**-
1566** if( (regEnd--)<=0 ){-
1567** AggStep (csrEnd)-
1568** Next (csrEnd)-
1569** }-
1570** AggFinal (xValue)-
1571** Gosub addrGosub-
1572** Next(csr) // if EOF goto flush_partition_done-
1573** if( (regStart--)<=0 ){-
1574** AggInverse (csr2)-
1575** Next (csr2)-
1576** }-
1577**-
1578*/-
1579static void windowCodeRowExprStep(-
1580 Parse *pParse, -
1581 Select *p,-
1582 WhereInfo *pWInfo,-
1583 int regGosub, -
1584 int addrGosub-
1585){-
1586 Window *pMWin = p->pWin;-
1587 Vdbe *v = sqlite3GetVdbe(pParse);-
1588 int regFlushPart; /* Register for "Gosub flush_partition" */-
1589 int lblFlushPart; /* Label for "Gosub flush_partition" */-
1590 int lblFlushDone; /* Label for "Gosub flush_partition_done" */-
1591-
1592 int regArg;-
1593 int addr;-
1594 int csrStart = pParse->nTab++;-
1595 int csrEnd = pParse->nTab++;-
1596 int regStart; /* Value of <expr> PRECEDING */-
1597 int regEnd; /* Value of <expr> FOLLOWING */-
1598 int addrGoto;-
1599 int addrTop;-
1600 int addrIfPos1 = 0;-
1601 int addrIfPos2 = 0;-
1602 int regSize = 0;-
1603-
1604 assert( pMWin->eStart==TK_PRECEDING -
1605 || pMWin->eStart==TK_CURRENT -
1606 || pMWin->eStart==TK_FOLLOWING -
1607 || pMWin->eStart==TK_UNBOUNDED -
1608 );-
1609 assert( pMWin->eEnd==TK_FOLLOWING -
1610 || pMWin->eEnd==TK_CURRENT -
1611 || pMWin->eEnd==TK_UNBOUNDED -
1612 || pMWin->eEnd==TK_PRECEDING -
1613 );-
1614-
1615 /* Allocate register and label for the "flush_partition" sub-routine. */-
1616 regFlushPart = ++pParse->nMem;-
1617 lblFlushPart = sqlite3VdbeMakeLabel(v);-
1618 lblFlushDone = sqlite3VdbeMakeLabel(v);-
1619-
1620 regStart = ++pParse->nMem;-
1621 regEnd = ++pParse->nMem;-
1622-
1623 windowPartitionCache(pParse, p, pWInfo, regFlushPart, lblFlushPart, &regSize);-
1624-
1625 addrGoto = sqlite3VdbeAddOp0(v, OP_Goto);-
1626-
1627 /* Start of "flush_partition" */-
1628 sqlite3VdbeResolveLabel(v, lblFlushPart);-
1629 sqlite3VdbeAddOp2(v, OP_Once, 0, sqlite3VdbeCurrentAddr(v)+3);-
1630 VdbeCoverage(v);-
1631 VdbeComment((v, "Flush_partition subroutine"));-
1632 sqlite3VdbeAddOp2(v, OP_OpenDup, csrStart, pMWin->iEphCsr);-
1633 sqlite3VdbeAddOp2(v, OP_OpenDup, csrEnd, pMWin->iEphCsr);-
1634-
1635 /* If either regStart or regEnd are not non-negative integers, throw -
1636 ** an exception. */-
1637 if( pMWin->pStart ){
pMWin->pStartDescription
TRUEevaluated 374 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 314 times by 1 test
Evaluated by:
  • Self test (438)
314-374
1638 sqlite3ExprCode(pParse, pMWin->pStart, regStart);-
1639 windowCheckIntValue(pParse, regStart, 0);-
1640 }
executed 374 times by 1 test: end of block
Executed by:
  • Self test (438)
374
1641 if( pMWin->pEnd ){
pMWin->pEndDescription
TRUEevaluated 369 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 319 times by 1 test
Evaluated by:
  • Self test (438)
319-369
1642 sqlite3ExprCode(pParse, pMWin->pEnd, regEnd);-
1643 windowCheckIntValue(pParse, regEnd, 1);-
1644 }
executed 369 times by 1 test: end of block
Executed by:
  • Self test (438)
369
1645-
1646 /* If this is "ROWS <expr1> FOLLOWING AND ROWS <expr2> FOLLOWING", do:-
1647 **-
1648 ** if( regEnd<regStart ){-
1649 ** // The frame always consists of 0 rows-
1650 ** regStart = regSize;-
1651 ** }-
1652 ** regEnd = regEnd - regStart;-
1653 */-
1654 if( pMWin->pEnd && pMWin->eStart==TK_FOLLOWING ){
pMWin->pEndDescription
TRUEevaluated 369 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 319 times by 1 test
Evaluated by:
  • Self test (438)
pMWin->eStart==83Description
TRUEevaluated 66 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 303 times by 1 test
Evaluated by:
  • Self test (438)
66-369
1655 assert( pMWin->pStart!=0 );-
1656 assert( pMWin->eEnd==TK_FOLLOWING );-
1657 sqlite3VdbeAddOp3(v, OP_Ge, regStart, sqlite3VdbeCurrentAddr(v)+2, regEnd);-
1658 VdbeCoverageNeverNull(v);-
1659 sqlite3VdbeAddOp2(v, OP_Copy, regSize, regStart);-
1660 sqlite3VdbeAddOp3(v, OP_Subtract, regStart, regEnd, regEnd);-
1661 }
executed 66 times by 1 test: end of block
Executed by:
  • Self test (438)
66
1662-
1663 if( pMWin->pStart && pMWin->eEnd==TK_PRECEDING ){
pMWin->pStartDescription
TRUEevaluated 374 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 314 times by 1 test
Evaluated by:
  • Self test (438)
pMWin->eEnd==85Description
TRUEevaluated 85 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 289 times by 1 test
Evaluated by:
  • Self test (438)
85-374
1664 assert( pMWin->pEnd!=0 );-
1665 assert( pMWin->eStart==TK_PRECEDING );-
1666 sqlite3VdbeAddOp3(v, OP_Le, regStart, sqlite3VdbeCurrentAddr(v)+3, regEnd);-
1667 VdbeCoverageNeverNull(v);-
1668 sqlite3VdbeAddOp2(v, OP_Copy, regSize, regStart);-
1669 sqlite3VdbeAddOp2(v, OP_Copy, regSize, regEnd);-
1670 }
executed 85 times by 1 test: end of block
Executed by:
  • Self test (438)
85
1671-
1672 /* Initialize the accumulator register for each window function to NULL */-
1673 regArg = windowInitAccum(pParse, pMWin);-
1674-
1675 sqlite3VdbeAddOp2(v, OP_Rewind, pMWin->iEphCsr, lblFlushDone);-
1676 VdbeCoverage(v);-
1677 sqlite3VdbeAddOp2(v, OP_Rewind, csrStart, lblFlushDone);-
1678 VdbeCoverageNeverTaken(v);-
1679 sqlite3VdbeChangeP5(v, 1);-
1680 sqlite3VdbeAddOp2(v, OP_Rewind, csrEnd, lblFlushDone);-
1681 VdbeCoverageNeverTaken(v);-
1682 sqlite3VdbeChangeP5(v, 1);-
1683-
1684 /* Invoke AggStep function for each window function using the row that-
1685 ** csrEnd currently points to. Or, if csrEnd is already at EOF,-
1686 ** do nothing. */-
1687 addrTop = sqlite3VdbeCurrentAddr(v);-
1688 if( pMWin->eEnd==TK_PRECEDING ){
pMWin->eEnd==85Description
TRUEevaluated 128 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 560 times by 1 test
Evaluated by:
  • Self test (438)
128-560
1689 addrIfPos1 = sqlite3VdbeAddOp3(v, OP_IfPos, regEnd, 0 , 1);-
1690 VdbeCoverage(v);-
1691 }
executed 128 times by 1 test: end of block
Executed by:
  • Self test (438)
128
1692 sqlite3VdbeAddOp2(v, OP_Next, csrEnd, sqlite3VdbeCurrentAddr(v)+2);-
1693 VdbeCoverage(v);-
1694 addr = sqlite3VdbeAddOp0(v, OP_Goto);-
1695 windowAggStep(pParse, pMWin, csrEnd, 0, regArg, regSize);-
1696 if( pMWin->eEnd==TK_UNBOUNDED ){
pMWin->eEnd==87Description
TRUEevaluated 188 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 500 times by 1 test
Evaluated by:
  • Self test (438)
188-500
1697 sqlite3VdbeAddOp2(v, OP_Goto, 0, addrTop);-
1698 sqlite3VdbeJumpHere(v, addr);-
1699 addrTop = sqlite3VdbeCurrentAddr(v);-
1700 }else{
executed 188 times by 1 test: end of block
Executed by:
  • Self test (438)
188
1701 sqlite3VdbeJumpHere(v, addr);-
1702 if( pMWin->eEnd==TK_PRECEDING ){
pMWin->eEnd==85Description
TRUEevaluated 128 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 372 times by 1 test
Evaluated by:
  • Self test (438)
128-372
1703 sqlite3VdbeJumpHere(v, addrIfPos1);-
1704 }
executed 128 times by 1 test: end of block
Executed by:
  • Self test (438)
128
1705 }
executed 500 times by 1 test: end of block
Executed by:
  • Self test (438)
500
1706-
1707 if( pMWin->eEnd==TK_FOLLOWING ){
pMWin->eEnd==83Description
TRUEevaluated 241 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 447 times by 1 test
Evaluated by:
  • Self test (438)
241-447
1708 addrIfPos1 = sqlite3VdbeAddOp3(v, OP_IfPos, regEnd, 0 , 1);-
1709 VdbeCoverage(v);-
1710 }
executed 241 times by 1 test: end of block
Executed by:
  • Self test (438)
241
1711 if( pMWin->eStart==TK_FOLLOWING ){
pMWin->eStart==83Description
TRUEevaluated 110 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 578 times by 1 test
Evaluated by:
  • Self test (438)
110-578
1712 addrIfPos2 = sqlite3VdbeAddOp3(v, OP_IfPos, regStart, 0 , 1);-
1713 VdbeCoverage(v);-
1714 }
executed 110 times by 1 test: end of block
Executed by:
  • Self test (438)
110
1715 windowAggFinal(pParse, pMWin, 0);-
1716 windowReturnOneRow(pParse, pMWin, regGosub, addrGosub);-
1717 sqlite3VdbeAddOp2(v, OP_Next, pMWin->iEphCsr, sqlite3VdbeCurrentAddr(v)+2);-
1718 VdbeCoverage(v);-
1719 sqlite3VdbeAddOp2(v, OP_Goto, 0, lblFlushDone);-
1720 if( pMWin->eStart==TK_FOLLOWING ){
pMWin->eStart==83Description
TRUEevaluated 110 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 578 times by 1 test
Evaluated by:
  • Self test (438)
110-578
1721 sqlite3VdbeJumpHere(v, addrIfPos2);-
1722 }
executed 110 times by 1 test: end of block
Executed by:
  • Self test (438)
110
1723-
1724 if( pMWin->eStart==TK_CURRENT
pMWin->eStart==82Description
TRUEevaluated 142 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 546 times by 1 test
Evaluated by:
  • Self test (438)
142-546
1725 || pMWin->eStart==TK_PRECEDING
pMWin->eStart==85Description
TRUEevaluated 264 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 282 times by 1 test
Evaluated by:
  • Self test (438)
264-282
1726 || pMWin->eStart==TK_FOLLOWING
pMWin->eStart==83Description
TRUEevaluated 110 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 172 times by 1 test
Evaluated by:
  • Self test (438)
110-172
1727 ){-
1728 int lblSkipInverse = sqlite3VdbeMakeLabel(v);;-
1729 if( pMWin->eStart==TK_PRECEDING ){
pMWin->eStart==85Description
TRUEevaluated 264 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 252 times by 1 test
Evaluated by:
  • Self test (438)
252-264
1730 sqlite3VdbeAddOp3(v, OP_IfPos, regStart, lblSkipInverse, 1);-
1731 VdbeCoverage(v);-
1732 }
executed 264 times by 1 test: end of block
Executed by:
  • Self test (438)
264
1733 if( pMWin->eStart==TK_FOLLOWING ){
pMWin->eStart==83Description
TRUEevaluated 110 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 406 times by 1 test
Evaluated by:
  • Self test (438)
110-406
1734 sqlite3VdbeAddOp2(v, OP_Next, csrStart, sqlite3VdbeCurrentAddr(v)+2);-
1735 VdbeCoverage(v);-
1736 sqlite3VdbeAddOp2(v, OP_Goto, 0, lblSkipInverse);-
1737 }else{
executed 110 times by 1 test: end of block
Executed by:
  • Self test (438)
110
1738 sqlite3VdbeAddOp2(v, OP_Next, csrStart, sqlite3VdbeCurrentAddr(v)+1);-
1739 VdbeCoverageAlwaysTaken(v);-
1740 }
executed 406 times by 1 test: end of block
Executed by:
  • Self test (438)
406
1741 windowAggStep(pParse, pMWin, csrStart, 1, regArg, regSize);-
1742 sqlite3VdbeResolveLabel(v, lblSkipInverse);-
1743 }
executed 516 times by 1 test: end of block
Executed by:
  • Self test (438)
516
1744 if( pMWin->eEnd==TK_FOLLOWING ){
pMWin->eEnd==83Description
TRUEevaluated 241 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 447 times by 1 test
Evaluated by:
  • Self test (438)
241-447
1745 sqlite3VdbeJumpHere(v, addrIfPos1);-
1746 }
executed 241 times by 1 test: end of block
Executed by:
  • Self test (438)
241
1747 sqlite3VdbeAddOp2(v, OP_Goto, 0, addrTop);-
1748-
1749 /* flush_partition_done: */-
1750 sqlite3VdbeResolveLabel(v, lblFlushDone);-
1751 sqlite3VdbeAddOp1(v, OP_ResetSorter, pMWin->iEphCsr);-
1752 sqlite3VdbeAddOp1(v, OP_Return, regFlushPart);-
1753 VdbeComment((v, "end flush_partition subroutine"));-
1754-
1755 /* Jump to here to skip over flush_partition */-
1756 sqlite3VdbeJumpHere(v, addrGoto);-
1757}
executed 688 times by 1 test: end of block
Executed by:
  • Self test (438)
688
1758-
1759/*-
1760** This function does the work of sqlite3WindowCodeStep() for cases that-
1761** would normally be handled by windowCodeDefaultStep() when there are-
1762** one or more built-in window-functions that require the entire partition-
1763** to be cached in a temp table before any rows can be returned. Additionally.-
1764** "RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING" is always handled by-
1765** this function.-
1766**-
1767** Pseudo-code corresponding to the VM code generated by this function-
1768** for each type of window follows.-
1769**-
1770** RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW-
1771**-
1772** flush_partition:-
1773** Once {-
1774** OpenDup (iEphCsr -> csrLead)-
1775** }-
1776** Integer ctr 0-
1777** foreach row (csrLead){-
1778** if( new peer ){-
1779** AggFinal (xValue)-
1780** for(i=0; i<ctr; i++){-
1781** Gosub addrGosub-
1782** Next iEphCsr-
1783** }-
1784** Integer ctr 0-
1785** }-
1786** AggStep (csrLead)-
1787** Incr ctr-
1788** }-
1789**-
1790** AggFinal (xFinalize)-
1791** for(i=0; i<ctr; i++){-
1792** Gosub addrGosub-
1793** Next iEphCsr-
1794** }-
1795**-
1796** ResetSorter (csr)-
1797** Return-
1798**-
1799** ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW-
1800**-
1801** As above, except that the "if( new peer )" branch is always taken.-
1802**-
1803** RANGE BETWEEN CURRENT ROW AND CURRENT ROW -
1804**-
1805** As above, except that each of the for() loops becomes:-
1806**-
1807** for(i=0; i<ctr; i++){-
1808** Gosub addrGosub-
1809** AggInverse (iEphCsr)-
1810** Next iEphCsr-
1811** }-
1812**-
1813** RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING-
1814**-
1815** flush_partition:-
1816** Once {-
1817** OpenDup (iEphCsr -> csrLead)-
1818** }-
1819** foreach row (csrLead) {-
1820** AggStep (csrLead)-
1821** }-
1822** foreach row (iEphCsr) {-
1823** Gosub addrGosub-
1824** }-
1825** -
1826** RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING-
1827**-
1828** flush_partition:-
1829** Once {-
1830** OpenDup (iEphCsr -> csrLead)-
1831** }-
1832** foreach row (csrLead){-
1833** AggStep (csrLead)-
1834** }-
1835** Rewind (csrLead)-
1836** Integer ctr 0-
1837** foreach row (csrLead){-
1838** if( new peer ){-
1839** AggFinal (xValue)-
1840** for(i=0; i<ctr; i++){-
1841** Gosub addrGosub-
1842** AggInverse (iEphCsr)-
1843** Next iEphCsr-
1844** }-
1845** Integer ctr 0-
1846** }-
1847** Incr ctr-
1848** }-
1849**-
1850** AggFinal (xFinalize)-
1851** for(i=0; i<ctr; i++){-
1852** Gosub addrGosub-
1853** Next iEphCsr-
1854** }-
1855**-
1856** ResetSorter (csr)-
1857** Return-
1858*/-
1859static void windowCodeCacheStep(-
1860 Parse *pParse, -
1861 Select *p,-
1862 WhereInfo *pWInfo,-
1863 int regGosub, -
1864 int addrGosub-
1865){-
1866 Window *pMWin = p->pWin;-
1867 Vdbe *v = sqlite3GetVdbe(pParse);-
1868 int k;-
1869 int addr;-
1870 ExprList *pPart = pMWin->pPartition;-
1871 ExprList *pOrderBy = pMWin->pOrderBy;-
1872 int nPeer = pOrderBy ? pOrderBy->nExpr : 0;
pOrderByDescription
TRUEevaluated 521 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 3 times by 1 test
Evaluated by:
  • Self test (438)
3-521
1873 int regNewPeer;-
1874-
1875 int addrGoto; /* Address of Goto used to jump flush_par.. */-
1876 int addrNext; /* Jump here for next iteration of loop */-
1877 int regFlushPart;-
1878 int lblFlushPart;-
1879 int csrLead;-
1880 int regCtr;-
1881 int regArg; /* Register array to martial function args */-
1882 int regSize;-
1883 int lblEmpty;-
1884 int bReverse = pMWin->pOrderBy && pMWin->eStart==TK_CURRENT
pMWin->pOrderByDescription
TRUEevaluated 521 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 3 times by 1 test
Evaluated by:
  • Self test (438)
pMWin->eStart==82Description
TRUEevaluated 85 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 436 times by 1 test
Evaluated by:
  • Self test (438)
3-521
1885 && pMWin->eEnd==TK_UNBOUNDED;
pMWin->eEnd==87Description
TRUEevaluated 61 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 24 times by 1 test
Evaluated by:
  • Self test (438)
24-61
1886-
1887 assert( (pMWin->eStart==TK_UNBOUNDED && pMWin->eEnd==TK_CURRENT) -
1888 || (pMWin->eStart==TK_UNBOUNDED && pMWin->eEnd==TK_UNBOUNDED) -
1889 || (pMWin->eStart==TK_CURRENT && pMWin->eEnd==TK_CURRENT) -
1890 || (pMWin->eStart==TK_CURRENT && pMWin->eEnd==TK_UNBOUNDED) -
1891 );-
1892-
1893 lblEmpty = sqlite3VdbeMakeLabel(v);-
1894 regNewPeer = pParse->nMem+1;-
1895 pParse->nMem += nPeer;-
1896-
1897 /* Allocate register and label for the "flush_partition" sub-routine. */-
1898 regFlushPart = ++pParse->nMem;-
1899 lblFlushPart = sqlite3VdbeMakeLabel(v);-
1900-
1901 csrLead = pParse->nTab++;-
1902 regCtr = ++pParse->nMem;-
1903-
1904 windowPartitionCache(pParse, p, pWInfo, regFlushPart, lblFlushPart, &regSize);-
1905 addrGoto = sqlite3VdbeAddOp0(v, OP_Goto);-
1906-
1907 /* Start of "flush_partition" */-
1908 sqlite3VdbeResolveLabel(v, lblFlushPart);-
1909 sqlite3VdbeAddOp2(v, OP_Once, 0, sqlite3VdbeCurrentAddr(v)+2);-
1910 VdbeCoverage(v);-
1911 sqlite3VdbeAddOp2(v, OP_OpenDup, csrLead, pMWin->iEphCsr);-
1912-
1913 /* Initialize the accumulator register for each window function to NULL */-
1914 regArg = windowInitAccum(pParse, pMWin);-
1915-
1916 sqlite3VdbeAddOp2(v, OP_Integer, 0, regCtr);-
1917 sqlite3VdbeAddOp2(v, OP_Rewind, csrLead, lblEmpty);-
1918 VdbeCoverage(v);-
1919 sqlite3VdbeAddOp2(v, OP_Rewind, pMWin->iEphCsr, lblEmpty);-
1920 VdbeCoverageNeverTaken(v);-
1921-
1922 if( bReverse ){
bReverseDescription
TRUEevaluated 61 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 463 times by 1 test
Evaluated by:
  • Self test (438)
61-463
1923 int addr2 = sqlite3VdbeCurrentAddr(v);-
1924 windowAggStep(pParse, pMWin, csrLead, 0, regArg, regSize);-
1925 sqlite3VdbeAddOp2(v, OP_Next, csrLead, addr2);-
1926 VdbeCoverage(v);-
1927 sqlite3VdbeAddOp2(v, OP_Rewind, csrLead, lblEmpty);-
1928 VdbeCoverageNeverTaken(v);-
1929 }
executed 61 times by 1 test: end of block
Executed by:
  • Self test (438)
61
1930 addrNext = sqlite3VdbeCurrentAddr(v);-
1931-
1932 if( pOrderBy && (pMWin->eEnd==TK_CURRENT || pMWin->eStart==TK_CURRENT) ){
pOrderByDescription
TRUEevaluated 521 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 3 times by 1 test
Evaluated by:
  • Self test (438)
pMWin->eEnd==82Description
TRUEevaluated 436 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 85 times by 1 test
Evaluated by:
  • Self test (438)
pMWin->eStart==82Description
TRUEevaluated 61 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 24 times by 1 test
Evaluated by:
  • Self test (438)
3-521
1933 int bCurrent = (pMWin->eStart==TK_CURRENT);-
1934 int addrJump = 0; /* Address of OP_Jump below */-
1935 if( pMWin->eType==TK_RANGE ){
pMWin->eType==86Description
TRUEevaluated 346 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 151 times by 1 test
Evaluated by:
  • Self test (438)
151-346
1936 int iOff = pMWin->nBufferCol + (pPart ? pPart->nExpr : 0);
pPartDescription
TRUEevaluated 165 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 181 times by 1 test
Evaluated by:
  • Self test (438)
165-181
1937 int regPeer = pMWin->regPart + (pPart ? pPart->nExpr : 0);
pPartDescription
TRUEevaluated 165 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 181 times by 1 test
Evaluated by:
  • Self test (438)
165-181
1938 KeyInfo *pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pOrderBy, 0, 0);-
1939 for(k=0; k<nPeer; k++){
k<nPeerDescription
TRUEevaluated 388 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 346 times by 1 test
Evaluated by:
  • Self test (438)
346-388
1940 sqlite3VdbeAddOp3(v, OP_Column, csrLead, iOff+k, regNewPeer+k);-
1941 }
executed 388 times by 1 test: end of block
Executed by:
  • Self test (438)
388
1942 addr = sqlite3VdbeAddOp3(v, OP_Compare, regNewPeer, regPeer, nPeer);-
1943 sqlite3VdbeAppendP4(v, (void*)pKeyInfo, P4_KEYINFO);-
1944 addrJump = sqlite3VdbeAddOp3(v, OP_Jump, addr+2, 0, addr+2);-
1945 VdbeCoverage(v);-
1946 sqlite3VdbeAddOp3(v, OP_Copy, regNewPeer, regPeer, nPeer-1);-
1947 }
executed 346 times by 1 test: end of block
Executed by:
  • Self test (438)
346
1948-
1949 windowReturnRows(pParse, pMWin, regCtr, regGosub, addrGosub, -
1950 (bCurrent ? regArg : 0), (bCurrent ? regSize : 0)-
1951 );-
1952 if( addrJump ) sqlite3VdbeJumpHere(v, addrJump);
executed 346 times by 1 test: sqlite3VdbeJumpHere(v, addrJump);
Executed by:
  • Self test (438)
addrJumpDescription
TRUEevaluated 346 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 151 times by 1 test
Evaluated by:
  • Self test (438)
151-346
1953 }
executed 497 times by 1 test: end of block
Executed by:
  • Self test (438)
497
1954-
1955 if( bReverse==0 ){
bReverse==0Description
TRUEevaluated 463 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 61 times by 1 test
Evaluated by:
  • Self test (438)
61-463
1956 windowAggStep(pParse, pMWin, csrLead, 0, regArg, regSize);-
1957 }
executed 463 times by 1 test: end of block
Executed by:
  • Self test (438)
463
1958 sqlite3VdbeAddOp2(v, OP_AddImm, regCtr, 1);-
1959 sqlite3VdbeAddOp2(v, OP_Next, csrLead, addrNext);-
1960 VdbeCoverage(v);-
1961-
1962 windowReturnRows(pParse, pMWin, regCtr, regGosub, addrGosub, 0, 0);-
1963-
1964 sqlite3VdbeResolveLabel(v, lblEmpty);-
1965 sqlite3VdbeAddOp1(v, OP_ResetSorter, pMWin->iEphCsr);-
1966 sqlite3VdbeAddOp1(v, OP_Return, regFlushPart);-
1967-
1968 /* Jump to here to skip over flush_partition */-
1969 sqlite3VdbeJumpHere(v, addrGoto);-
1970}
executed 524 times by 1 test: end of block
Executed by:
  • Self test (438)
524
1971-
1972-
1973/*-
1974** RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW-
1975**-
1976** ...-
1977** if( new partition ){-
1978** AggFinal (xFinalize)-
1979** Gosub addrGosub-
1980** ResetSorter eph-table-
1981** }-
1982** else if( new peer ){-
1983** AggFinal (xValue)-
1984** Gosub addrGosub-
1985** ResetSorter eph-table-
1986** }-
1987** AggStep-
1988** Insert (record into eph-table)-
1989** sqlite3WhereEnd()-
1990** AggFinal (xFinalize)-
1991** Gosub addrGosub-
1992**-
1993** RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING-
1994**-
1995** As above, except take no action for a "new peer". Invoke-
1996** the sub-routine once only for each partition.-
1997**-
1998** RANGE BETWEEN CURRENT ROW AND CURRENT ROW-
1999**-
2000** As above, except that the "new peer" condition is handled in the-
2001** same way as "new partition" (so there is no "else if" block).-
2002**-
2003** ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW-
2004** -
2005** As above, except assume every row is a "new peer".-
2006*/-
2007static void windowCodeDefaultStep(-
2008 Parse *pParse, -
2009 Select *p,-
2010 WhereInfo *pWInfo,-
2011 int regGosub, -
2012 int addrGosub-
2013){-
2014 Window *pMWin = p->pWin;-
2015 Vdbe *v = sqlite3GetVdbe(pParse);-
2016 int k;-
2017 int iSubCsr = p->pSrc->a[0].iCursor;-
2018 int nSub = p->pSrc->a[0].pTab->nCol;-
2019 int reg = pParse->nMem+1;-
2020 int regRecord = reg+nSub;-
2021 int regRowid = regRecord+1;-
2022 int addr;-
2023 ExprList *pPart = pMWin->pPartition;-
2024 ExprList *pOrderBy = pMWin->pOrderBy;-
2025-
2026 assert( pMWin->eType==TK_RANGE -
2027 || (pMWin->eStart==TK_UNBOUNDED && pMWin->eEnd==TK_CURRENT)-
2028 );-
2029-
2030 assert( (pMWin->eStart==TK_UNBOUNDED && pMWin->eEnd==TK_CURRENT)-
2031 || (pMWin->eStart==TK_UNBOUNDED && pMWin->eEnd==TK_UNBOUNDED)-
2032 || (pMWin->eStart==TK_CURRENT && pMWin->eEnd==TK_CURRENT)-
2033 || (pMWin->eStart==TK_CURRENT && pMWin->eEnd==TK_UNBOUNDED && !pOrderBy)-
2034 );-
2035-
2036 if( pMWin->eEnd==TK_UNBOUNDED ){
pMWin->eEnd==87Description
TRUEevaluated 36 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 561 times by 1 test
Evaluated by:
  • Self test (438)
36-561
2037 pOrderBy = 0;-
2038 }
executed 36 times by 1 test: end of block
Executed by:
  • Self test (438)
36
2039-
2040 pParse->nMem += nSub + 2;-
2041-
2042 /* Load the individual column values of the row returned by-
2043 ** the sub-select into an array of registers. */-
2044 for(k=0; k<nSub; k++){
k<nSubDescription
TRUEevaluated 2064 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 597 times by 1 test
Evaluated by:
  • Self test (438)
597-2064
2045 sqlite3VdbeAddOp3(v, OP_Column, iSubCsr, k, reg+k);-
2046 }
executed 2064 times by 1 test: end of block
Executed by:
  • Self test (438)
2064
2047-
2048 /* Check if this is the start of a new partition or peer group. */-
2049 if( pPart || pOrderBy ){
pPartDescription
TRUEevaluated 351 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 246 times by 1 test
Evaluated by:
  • Self test (438)
pOrderByDescription
TRUEevaluated 221 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 25 times by 1 test
Evaluated by:
  • Self test (438)
25-351
2050 int nPart = (pPart ? pPart->nExpr : 0);
pPartDescription
TRUEevaluated 351 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 221 times by 1 test
Evaluated by:
  • Self test (438)
221-351
2051 int addrGoto = 0;-
2052 int addrJump = 0;-
2053 int nPeer = (pOrderBy ? pOrderBy->nExpr : 0);
pOrderByDescription
TRUEevaluated 530 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 42 times by 1 test
Evaluated by:
  • Self test (438)
42-530
2054-
2055 if( pPart ){
pPartDescription
TRUEevaluated 351 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 221 times by 1 test
Evaluated by:
  • Self test (438)
221-351
2056 int regNewPart = reg + pMWin->nBufferCol;-
2057 KeyInfo *pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pPart, 0, 0);-
2058 addr = sqlite3VdbeAddOp3(v, OP_Compare, regNewPart, pMWin->regPart,nPart);-
2059 sqlite3VdbeAppendP4(v, (void*)pKeyInfo, P4_KEYINFO);-
2060 addrJump = sqlite3VdbeAddOp3(v, OP_Jump, addr+2, 0, addr+2);-
2061 VdbeCoverageEqNe(v);-
2062 windowAggFinal(pParse, pMWin, 1);-
2063 if( pOrderBy ){
pOrderByDescription
TRUEevaluated 309 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 42 times by 1 test
Evaluated by:
  • Self test (438)
42-309
2064 addrGoto = sqlite3VdbeAddOp0(v, OP_Goto);-
2065 }
executed 309 times by 1 test: end of block
Executed by:
  • Self test (438)
309
2066 }
executed 351 times by 1 test: end of block
Executed by:
  • Self test (438)
351
2067-
2068 if( pOrderBy ){
pOrderByDescription
TRUEevaluated 530 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 42 times by 1 test
Evaluated by:
  • Self test (438)
42-530
2069 int regNewPeer = reg + pMWin->nBufferCol + nPart;-
2070 int regPeer = pMWin->regPart + nPart;-
2071-
2072 if( addrJump ) sqlite3VdbeJumpHere(v, addrJump);
executed 309 times by 1 test: sqlite3VdbeJumpHere(v, addrJump);
Executed by:
  • Self test (438)
addrJumpDescription
TRUEevaluated 309 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 221 times by 1 test
Evaluated by:
  • Self test (438)
221-309
2073 if( pMWin->eType==TK_RANGE ){
pMWin->eType==86Description
TRUEevaluated 454 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 76 times by 1 test
Evaluated by:
  • Self test (438)
76-454
2074 KeyInfo *pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pOrderBy, 0, 0);-
2075 addr = sqlite3VdbeAddOp3(v, OP_Compare, regNewPeer, regPeer, nPeer);-
2076 sqlite3VdbeAppendP4(v, (void*)pKeyInfo, P4_KEYINFO);-
2077 addrJump = sqlite3VdbeAddOp3(v, OP_Jump, addr+2, 0, addr+2);-
2078 VdbeCoverage(v);-
2079 }else{
executed 454 times by 1 test: end of block
Executed by:
  • Self test (438)
454
2080 addrJump = 0;-
2081 }
executed 76 times by 1 test: end of block
Executed by:
  • Self test (438)
76
2082 windowAggFinal(pParse, pMWin, pMWin->eStart==TK_CURRENT);-
2083 if( addrGoto ) sqlite3VdbeJumpHere(v, addrGoto);
executed 309 times by 1 test: sqlite3VdbeJumpHere(v, addrGoto);
Executed by:
  • Self test (438)
addrGotoDescription
TRUEevaluated 309 times by 1 test
Evaluated by:
  • Self test (438)
FALSEevaluated 221 times by 1 test
Evaluated by:
  • Self test (438)
221-309
2084 }
executed 530 times by 1 test: end of block
Executed by:
  • Self test (438)
530
2085-
2086 sqlite3VdbeAddOp2(v, OP_Rewind, pMWin->iEphCsr,sqlite3VdbeCurrentAddr(v)+3);-
2087 VdbeCoverage(v);-
2088 sqlite3VdbeAddOp2(v, OP_Gosub, regGosub, addrGosub