mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-07 02:42:48 +03:00
Identify specific FuncDef objects for window functions using the pointer to
the function name (FuncDef.zName) rather than the pointer to the xStep method. This allows xStep method pointer to be replaced with a single noopStepFunc() procedure, and thus save having lots of different no-op step functions. FossilOrigin-Name: 410e13b0e0fb6e040808f076014d55ecf2b541c5439b4fd53c5bdcb8d800098e
This commit is contained in:
12
manifest
12
manifest
@@ -1,5 +1,5 @@
|
|||||||
C Simplifications\sto\sthe\simplementation\sof\sthe\ssum()\sSQL\sfunction.
|
C Identify\sspecific\sFuncDef\sobjects\sfor\swindow\sfunctions\susing\sthe\spointer\sto\nthe\sfunction\sname\s(FuncDef.zName)\srather\sthan\sthe\spointer\sto\sthe\sxStep\smethod.\nThis\sallows\sxStep\smethod\spointer\sto\sbe\sreplaced\swith\sa\ssingle\snoopStepFunc()\nprocedure,\sand\sthus\ssave\shaving\slots\sof\sdifferent\sno-op\sstep\sfunctions.
|
||||||
D 2018-07-07T20:55:16.666
|
D 2018-07-08T01:02:26.110
|
||||||
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
||||||
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
||||||
F Makefile.in 0a3a6c81e6fcb969ff9106e882f0a08547014ba463cb6beca4c4efaecc924ee6
|
F Makefile.in 0a3a6c81e6fcb969ff9106e882f0a08547014ba463cb6beca4c4efaecc924ee6
|
||||||
@@ -584,7 +584,7 @@ F src/where.c 0bcbf9e191ca07f9ea2008aa80e70ded46bcdffd26560c83397da501f00aece6
|
|||||||
F src/whereInt.h b90ef9b9707ef750eab2a7a080c48fb4900315033274689def32d0cf5a81ebe4
|
F src/whereInt.h b90ef9b9707ef750eab2a7a080c48fb4900315033274689def32d0cf5a81ebe4
|
||||||
F src/wherecode.c 3317f2b083a66d3e65a03edf316ade4ccb0a99c9956273282ebb579b95d4ba96
|
F src/wherecode.c 3317f2b083a66d3e65a03edf316ade4ccb0a99c9956273282ebb579b95d4ba96
|
||||||
F src/whereexpr.c 571618c67a3eb5ce0f1158c2792c1aee9b4a4a264392fc4fb1b35467f80abf9a
|
F src/whereexpr.c 571618c67a3eb5ce0f1158c2792c1aee9b4a4a264392fc4fb1b35467f80abf9a
|
||||||
F src/window.c 0ff9000757e6634f4bbf59e8273ba21d47992b7b782db5bde76db0eee90964e3
|
F src/window.c e42415fb8d1421fd9353872244e8a90f4025cd6a4a215f1603f06735e9be20b6
|
||||||
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
|
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
|
||||||
F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd
|
F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd
|
||||||
F test/affinity3.test 6a101af2fc945ce2912f6fe54dd646018551710d
|
F test/affinity3.test 6a101af2fc945ce2912f6fe54dd646018551710d
|
||||||
@@ -1745,7 +1745,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
|
|||||||
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
||||||
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
||||||
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
||||||
P ae3fc7652f27ba0a86f4c26f64c2e148d9496a5edb7f54dc9980edd91c326e4f
|
P a8b13002378fc4ef0b41c367b44b67bf2b28b6624303c087a3c6d657b5bfe32e
|
||||||
R 7fefa3b6e3f1ad000f6b20afb58dadef
|
R 8358a593d4ce0687282d59db38a347ed
|
||||||
U drh
|
U drh
|
||||||
Z a5540dd7ff49b20c02f142203cdf3720
|
Z 0694fc0bf0c4178f6f522b94761738e7
|
||||||
|
@@ -1 +1 @@
|
|||||||
a8b13002378fc4ef0b41c367b44b67bf2b28b6624303c087a3c6d657b5bfe32e
|
410e13b0e0fb6e040808f076014d55ecf2b541c5439b4fd53c5bdcb8d800098e
|
181
src/window.c
181
src/window.c
@@ -152,12 +152,6 @@ static void row_numberStepFunc(
|
|||||||
i64 *p = (i64*)sqlite3_aggregate_context(pCtx, sizeof(*p));
|
i64 *p = (i64*)sqlite3_aggregate_context(pCtx, sizeof(*p));
|
||||||
if( p ) (*p)++;
|
if( p ) (*p)++;
|
||||||
}
|
}
|
||||||
static void row_numberInvFunc(
|
|
||||||
sqlite3_context *pCtx,
|
|
||||||
int nArg,
|
|
||||||
sqlite3_value **apArg
|
|
||||||
){
|
|
||||||
}
|
|
||||||
static void row_numberValueFunc(sqlite3_context *pCtx){
|
static void row_numberValueFunc(sqlite3_context *pCtx){
|
||||||
i64 *p = (i64*)sqlite3_aggregate_context(pCtx, sizeof(*p));
|
i64 *p = (i64*)sqlite3_aggregate_context(pCtx, sizeof(*p));
|
||||||
sqlite3_result_int64(pCtx, (p ? *p : 0));
|
sqlite3_result_int64(pCtx, (p ? *p : 0));
|
||||||
@@ -188,12 +182,6 @@ static void dense_rankStepFunc(
|
|||||||
p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p));
|
p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p));
|
||||||
if( p ) p->nStep = 1;
|
if( p ) p->nStep = 1;
|
||||||
}
|
}
|
||||||
static void dense_rankInvFunc(
|
|
||||||
sqlite3_context *pCtx,
|
|
||||||
int nArg,
|
|
||||||
sqlite3_value **apArg
|
|
||||||
){
|
|
||||||
}
|
|
||||||
static void dense_rankValueFunc(sqlite3_context *pCtx){
|
static void dense_rankValueFunc(sqlite3_context *pCtx){
|
||||||
struct CallCount *p;
|
struct CallCount *p;
|
||||||
p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p));
|
p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p));
|
||||||
@@ -226,12 +214,6 @@ static void rankStepFunc(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static void rankInvFunc(
|
|
||||||
sqlite3_context *pCtx,
|
|
||||||
int nArg,
|
|
||||||
sqlite3_value **apArg
|
|
||||||
){
|
|
||||||
}
|
|
||||||
static void rankValueFunc(sqlite3_context *pCtx){
|
static void rankValueFunc(sqlite3_context *pCtx){
|
||||||
struct CallCount *p;
|
struct CallCount *p;
|
||||||
p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p));
|
p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p));
|
||||||
@@ -266,12 +248,6 @@ static void percent_rankStepFunc(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static void percent_rankInvFunc(
|
|
||||||
sqlite3_context *pCtx,
|
|
||||||
int nArg,
|
|
||||||
sqlite3_value **apArg
|
|
||||||
){
|
|
||||||
}
|
|
||||||
static void percent_rankValueFunc(sqlite3_context *pCtx){
|
static void percent_rankValueFunc(sqlite3_context *pCtx){
|
||||||
struct CallCount *p;
|
struct CallCount *p;
|
||||||
p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p));
|
p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p));
|
||||||
@@ -308,12 +284,6 @@ static void cume_distStepFunc(
|
|||||||
p->nStep++;
|
p->nStep++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static void cume_distInvFunc(
|
|
||||||
sqlite3_context *pCtx,
|
|
||||||
int nArg,
|
|
||||||
sqlite3_value **apArg
|
|
||||||
){
|
|
||||||
}
|
|
||||||
static void cume_distValueFunc(sqlite3_context *pCtx){
|
static void cume_distValueFunc(sqlite3_context *pCtx){
|
||||||
struct CallCount *p;
|
struct CallCount *p;
|
||||||
p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p));
|
p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p));
|
||||||
@@ -359,12 +329,6 @@ static void ntileStepFunc(
|
|||||||
p->iRow++;
|
p->iRow++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static void ntileInvFunc(
|
|
||||||
sqlite3_context *pCtx,
|
|
||||||
int nArg,
|
|
||||||
sqlite3_value **apArg
|
|
||||||
){
|
|
||||||
}
|
|
||||||
static void ntileValueFunc(sqlite3_context *pCtx){
|
static void ntileValueFunc(sqlite3_context *pCtx){
|
||||||
struct NtileCtx *p;
|
struct NtileCtx *p;
|
||||||
p = (struct NtileCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p));
|
p = (struct NtileCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p));
|
||||||
@@ -449,50 +413,89 @@ static void last_valueFinalizeFunc(sqlite3_context *pCtx){
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** No-op implementations of nth_value(), first_value(), lead() and lag().
|
** Static names for the built-in window function names. These static
|
||||||
** These are all implemented inline using VDBE instructions.
|
** names are used, rather than string literals, so that FuncDef objects
|
||||||
|
** can be associated with a particular window function by direct
|
||||||
|
** comparison of the zName pointer. Example:
|
||||||
|
**
|
||||||
|
** if( pFuncDef->zName==row_valueName ){ ... }
|
||||||
*/
|
*/
|
||||||
static void nth_valueStepFunc(sqlite3_context *pCtx, int n, sqlite3_value **a){}
|
static const char row_numberName[] = "row_number";
|
||||||
static void nth_valueInvFunc(sqlite3_context *pCtx, int n, sqlite3_value **ap){}
|
static const char dense_rankName[] = "dense_rank";
|
||||||
static void nth_valueValueFunc(sqlite3_context *pCtx){}
|
static const char rankName[] = "rank";
|
||||||
static void first_valueStepFunc(sqlite3_context *p, int n, sqlite3_value **ap){}
|
static const char percent_rankName[] = "percent_rank";
|
||||||
static void first_valueInvFunc(sqlite3_context *p, int n, sqlite3_value **ap){}
|
static const char cume_distName[] = "cume_dist";
|
||||||
static void first_valueValueFunc(sqlite3_context *pCtx){}
|
static const char ntileName[] = "ntile";
|
||||||
static void leadStepFunc(sqlite3_context *pCtx, int n, sqlite3_value **ap){}
|
static const char last_valueName[] = "last_value";
|
||||||
static void leadInvFunc(sqlite3_context *pCtx, int n, sqlite3_value **ap){}
|
static const char nth_valueName[] = "nth_value";
|
||||||
static void leadValueFunc(sqlite3_context *pCtx){}
|
static const char first_valueName[] = "first_value";
|
||||||
static void lagStepFunc(sqlite3_context *pCtx, int n, sqlite3_value **ap){}
|
static const char leadName[] = "lead";
|
||||||
static void lagInvFunc(sqlite3_context *pCtx, int n, sqlite3_value **ap){}
|
static const char lagName[] = "lag";
|
||||||
static void lagValueFunc(sqlite3_context *pCtx){}
|
|
||||||
|
|
||||||
#define WINDOWFUNC(name,nArg,extra) { \
|
/*
|
||||||
nArg, (SQLITE_UTF8|SQLITE_FUNC_WINDOW|extra), 0, 0, \
|
** No-op implementations of xStep() and xFinalize(). Used as place-holders
|
||||||
name ## StepFunc, name ## ValueFunc, name ## ValueFunc, \
|
** for built-in window functions that never call those interfaces.
|
||||||
name ## InvFunc, #name \
|
**
|
||||||
}
|
** The noopValueFunc() is called but is expected to do nothing. The
|
||||||
|
** noopStepFunc() is never called, and so it is marked with NO_TEST to
|
||||||
|
** let the test coverage routine know not to expect this function to be
|
||||||
|
** invoked.
|
||||||
|
*/
|
||||||
|
static void noopStepFunc( /*NO_TEST*/
|
||||||
|
sqlite3_context *p, /*NO_TEST*/
|
||||||
|
int n, /*NO_TEST*/
|
||||||
|
sqlite3_value **a /*NO_TEST*/
|
||||||
|
){ /*NO_TEST*/
|
||||||
|
assert(0); /*NO_TEST*/
|
||||||
|
} /*NO_TEST*/
|
||||||
|
static void noopValueFunc(sqlite3_context *p){ /*no-op*/; }
|
||||||
|
|
||||||
#define WINDOWFUNCF(name,nArg,extra) { \
|
/* Window functions that use all window interfaces: xStep, xFinal,
|
||||||
|
** xValue, and xInverse */
|
||||||
|
#define WINDOWFUNCALL(name,nArg,extra) { \
|
||||||
nArg, (SQLITE_UTF8|SQLITE_FUNC_WINDOW|extra), 0, 0, \
|
nArg, (SQLITE_UTF8|SQLITE_FUNC_WINDOW|extra), 0, 0, \
|
||||||
name ## StepFunc, name ## FinalizeFunc, name ## ValueFunc, \
|
name ## StepFunc, name ## FinalizeFunc, name ## ValueFunc, \
|
||||||
name ## InvFunc, #name \
|
name ## InvFunc, name ## Name \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Window functions that are implemented using bytecode and thus have
|
||||||
|
** no-op routines for their methods */
|
||||||
|
#define WINDOWFUNCNOOP(name,nArg,extra) { \
|
||||||
|
nArg, (SQLITE_UTF8|SQLITE_FUNC_WINDOW|extra), 0, 0, \
|
||||||
|
noopStepFunc, noopValueFunc, noopValueFunc, \
|
||||||
|
noopStepFunc, name ## Name \
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Window functions that use all window interfaces: xStep, the
|
||||||
|
** same routine for xFinalize and xValue and which never call
|
||||||
|
** xInverse. */
|
||||||
|
#define WINDOWFUNCX(name,nArg,extra) { \
|
||||||
|
nArg, (SQLITE_UTF8|SQLITE_FUNC_WINDOW|extra), 0, 0, \
|
||||||
|
name ## StepFunc, name ## ValueFunc, name ## ValueFunc, \
|
||||||
|
noopStepFunc, name ## Name \
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Register those built-in window functions that are not also aggregates.
|
** Register those built-in window functions that are not also aggregates.
|
||||||
*/
|
*/
|
||||||
void sqlite3WindowFunctions(void){
|
void sqlite3WindowFunctions(void){
|
||||||
static FuncDef aWindowFuncs[] = {
|
static FuncDef aWindowFuncs[] = {
|
||||||
WINDOWFUNC(row_number, 0, 0),
|
WINDOWFUNCX(row_number, 0, 0),
|
||||||
WINDOWFUNC(dense_rank, 0, 0),
|
WINDOWFUNCX(dense_rank, 0, 0),
|
||||||
WINDOWFUNC(rank, 0, 0),
|
WINDOWFUNCX(rank, 0, 0),
|
||||||
WINDOWFUNC(percent_rank, 0, SQLITE_FUNC_WINDOW_SIZE),
|
WINDOWFUNCX(percent_rank, 0, SQLITE_FUNC_WINDOW_SIZE),
|
||||||
WINDOWFUNC(cume_dist, 0, SQLITE_FUNC_WINDOW_SIZE),
|
WINDOWFUNCX(cume_dist, 0, SQLITE_FUNC_WINDOW_SIZE),
|
||||||
WINDOWFUNC(ntile, 1, SQLITE_FUNC_WINDOW_SIZE),
|
WINDOWFUNCX(ntile, 1, SQLITE_FUNC_WINDOW_SIZE),
|
||||||
WINDOWFUNCF(last_value, 1, 0),
|
WINDOWFUNCALL(last_value, 1, 0),
|
||||||
WINDOWFUNC(nth_value, 2, 0),
|
WINDOWFUNCNOOP(nth_value, 2, 0),
|
||||||
WINDOWFUNC(first_value, 1, 0),
|
WINDOWFUNCNOOP(first_value, 1, 0),
|
||||||
WINDOWFUNC(lead, 1, 0), WINDOWFUNC(lead, 2, 0), WINDOWFUNC(lead, 3, 0),
|
WINDOWFUNCNOOP(lead, 1, 0),
|
||||||
WINDOWFUNC(lag, 1, 0), WINDOWFUNC(lag, 2, 0), WINDOWFUNC(lag, 3, 0),
|
WINDOWFUNCNOOP(lead, 2, 0),
|
||||||
|
WINDOWFUNCNOOP(lead, 3, 0),
|
||||||
|
WINDOWFUNCNOOP(lag, 1, 0),
|
||||||
|
WINDOWFUNCNOOP(lag, 2, 0),
|
||||||
|
WINDOWFUNCNOOP(lag, 3, 0),
|
||||||
};
|
};
|
||||||
sqlite3InsertBuiltinFuncs(aWindowFuncs, ArraySize(aWindowFuncs));
|
sqlite3InsertBuiltinFuncs(aWindowFuncs, ArraySize(aWindowFuncs));
|
||||||
}
|
}
|
||||||
@@ -544,7 +547,7 @@ void sqlite3WindowUpdate(
|
|||||||
"FILTER clause may only be used with aggregate window functions"
|
"FILTER clause may only be used with aggregate window functions"
|
||||||
);
|
);
|
||||||
}else
|
}else
|
||||||
if( pFunc->xSFunc==row_numberStepFunc || pFunc->xSFunc==ntileStepFunc ){
|
if( pFunc->zName==row_numberName || pFunc->zName==ntileName ){
|
||||||
sqlite3ExprDelete(db, pWin->pStart);
|
sqlite3ExprDelete(db, pWin->pStart);
|
||||||
sqlite3ExprDelete(db, pWin->pEnd);
|
sqlite3ExprDelete(db, pWin->pEnd);
|
||||||
pWin->pStart = pWin->pEnd = 0;
|
pWin->pStart = pWin->pEnd = 0;
|
||||||
@@ -553,8 +556,8 @@ void sqlite3WindowUpdate(
|
|||||||
pWin->eEnd = TK_CURRENT;
|
pWin->eEnd = TK_CURRENT;
|
||||||
}else
|
}else
|
||||||
|
|
||||||
if( pFunc->xSFunc==dense_rankStepFunc || pFunc->xSFunc==rankStepFunc
|
if( pFunc->zName==dense_rankName || pFunc->zName==rankName
|
||||||
|| pFunc->xSFunc==percent_rankStepFunc || pFunc->xSFunc==cume_distStepFunc
|
|| pFunc->zName==percent_rankName || pFunc->zName==cume_distName
|
||||||
){
|
){
|
||||||
sqlite3ExprDelete(db, pWin->pStart);
|
sqlite3ExprDelete(db, pWin->pStart);
|
||||||
sqlite3ExprDelete(db, pWin->pEnd);
|
sqlite3ExprDelete(db, pWin->pEnd);
|
||||||
@@ -981,7 +984,7 @@ void sqlite3WindowCodeInit(Parse *pParse, Window *pMWin){
|
|||||||
sqlite3VdbeAppendP4(v, pKeyInfo, P4_KEYINFO);
|
sqlite3VdbeAppendP4(v, pKeyInfo, P4_KEYINFO);
|
||||||
sqlite3VdbeAddOp2(v, OP_Integer, 0, pWin->regApp+1);
|
sqlite3VdbeAddOp2(v, OP_Integer, 0, pWin->regApp+1);
|
||||||
}
|
}
|
||||||
else if( p->xSFunc==nth_valueStepFunc || p->xSFunc==first_valueStepFunc ){
|
else if( p->zName==nth_valueName || p->zName==first_valueName ){
|
||||||
/* Allocate two registers at pWin->regApp. These will be used to
|
/* Allocate two registers at pWin->regApp. These will be used to
|
||||||
** store the start and end index of the current frame. */
|
** store the start and end index of the current frame. */
|
||||||
assert( pMWin->iEphCsr );
|
assert( pMWin->iEphCsr );
|
||||||
@@ -990,7 +993,7 @@ void sqlite3WindowCodeInit(Parse *pParse, Window *pMWin){
|
|||||||
pParse->nMem += 2;
|
pParse->nMem += 2;
|
||||||
sqlite3VdbeAddOp2(v, OP_OpenDup, pWin->csrApp, pMWin->iEphCsr);
|
sqlite3VdbeAddOp2(v, OP_OpenDup, pWin->csrApp, pMWin->iEphCsr);
|
||||||
}
|
}
|
||||||
else if( p->xSFunc==leadStepFunc || p->xSFunc==lagStepFunc ){
|
else if( p->zName==leadName || p->zName==lagName ){
|
||||||
assert( pMWin->iEphCsr );
|
assert( pMWin->iEphCsr );
|
||||||
pWin->csrApp = pParse->nTab++;
|
pWin->csrApp = pParse->nTab++;
|
||||||
sqlite3VdbeAddOp2(v, OP_OpenDup, pWin->csrApp, pMWin->iEphCsr);
|
sqlite3VdbeAddOp2(v, OP_OpenDup, pWin->csrApp, pMWin->iEphCsr);
|
||||||
@@ -1101,13 +1104,13 @@ static void windowAggStep(
|
|||||||
}
|
}
|
||||||
sqlite3VdbeJumpHere(v, addrIsNull);
|
sqlite3VdbeJumpHere(v, addrIsNull);
|
||||||
}else if( pWin->regApp ){
|
}else if( pWin->regApp ){
|
||||||
assert( pWin->pFunc->xSFunc==nth_valueStepFunc
|
assert( pWin->pFunc->zName==nth_valueName
|
||||||
|| pWin->pFunc->xSFunc==first_valueStepFunc
|
|| pWin->pFunc->zName==first_valueName
|
||||||
);
|
);
|
||||||
assert( bInverse==0 || bInverse==1 );
|
assert( bInverse==0 || bInverse==1 );
|
||||||
sqlite3VdbeAddOp2(v, OP_AddImm, pWin->regApp+1-bInverse, 1);
|
sqlite3VdbeAddOp2(v, OP_AddImm, pWin->regApp+1-bInverse, 1);
|
||||||
}else if( pWin->pFunc->xSFunc==leadStepFunc
|
}else if( pWin->pFunc->zName==leadName
|
||||||
|| pWin->pFunc->xSFunc==lagStepFunc
|
|| pWin->pFunc->zName==lagName
|
||||||
){
|
){
|
||||||
/* no-op */
|
/* no-op */
|
||||||
}else{
|
}else{
|
||||||
@@ -1263,15 +1266,15 @@ static void windowReturnOneRow(
|
|||||||
Window *pWin;
|
Window *pWin;
|
||||||
for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
|
for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
|
||||||
FuncDef *pFunc = pWin->pFunc;
|
FuncDef *pFunc = pWin->pFunc;
|
||||||
if( pFunc->xSFunc==nth_valueStepFunc
|
if( pFunc->zName==nth_valueName
|
||||||
|| pFunc->xSFunc==first_valueStepFunc
|
|| pFunc->zName==first_valueName
|
||||||
){
|
){
|
||||||
int csr = pWin->csrApp;
|
int csr = pWin->csrApp;
|
||||||
int lbl = sqlite3VdbeMakeLabel(v);
|
int lbl = sqlite3VdbeMakeLabel(v);
|
||||||
int tmpReg = sqlite3GetTempReg(pParse);
|
int tmpReg = sqlite3GetTempReg(pParse);
|
||||||
sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regResult);
|
sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regResult);
|
||||||
|
|
||||||
if( pFunc->xSFunc==nth_valueStepFunc ){
|
if( pFunc->zName==nth_valueName ){
|
||||||
sqlite3VdbeAddOp3(v, OP_Column, pMWin->iEphCsr, pWin->iArgCol+1,tmpReg);
|
sqlite3VdbeAddOp3(v, OP_Column, pMWin->iEphCsr, pWin->iArgCol+1,tmpReg);
|
||||||
}else{
|
}else{
|
||||||
sqlite3VdbeAddOp2(v, OP_Integer, 1, tmpReg);
|
sqlite3VdbeAddOp2(v, OP_Integer, 1, tmpReg);
|
||||||
@@ -1285,7 +1288,7 @@ static void windowReturnOneRow(
|
|||||||
sqlite3VdbeResolveLabel(v, lbl);
|
sqlite3VdbeResolveLabel(v, lbl);
|
||||||
sqlite3ReleaseTempReg(pParse, tmpReg);
|
sqlite3ReleaseTempReg(pParse, tmpReg);
|
||||||
}
|
}
|
||||||
else if( pFunc->xSFunc==leadStepFunc || pFunc->xSFunc==lagStepFunc ){
|
else if( pFunc->zName==leadName || pFunc->zName==lagName ){
|
||||||
int nArg = pWin->pOwner->x.pList->nExpr;
|
int nArg = pWin->pOwner->x.pList->nExpr;
|
||||||
int iEph = pMWin->iEphCsr;
|
int iEph = pMWin->iEphCsr;
|
||||||
int csr = pWin->csrApp;
|
int csr = pWin->csrApp;
|
||||||
@@ -1299,10 +1302,10 @@ static void windowReturnOneRow(
|
|||||||
}
|
}
|
||||||
sqlite3VdbeAddOp2(v, OP_Rowid, iEph, tmpReg);
|
sqlite3VdbeAddOp2(v, OP_Rowid, iEph, tmpReg);
|
||||||
if( nArg<2 ){
|
if( nArg<2 ){
|
||||||
int val = (pFunc->xSFunc==leadStepFunc ? 1 : -1);
|
int val = (pFunc->zName==leadName ? 1 : -1);
|
||||||
sqlite3VdbeAddOp2(v, OP_AddImm, tmpReg, val);
|
sqlite3VdbeAddOp2(v, OP_AddImm, tmpReg, val);
|
||||||
}else{
|
}else{
|
||||||
int op = (pFunc->xSFunc==leadStepFunc ? OP_Add : OP_Subtract);
|
int op = (pFunc->zName==leadName ? OP_Add : OP_Subtract);
|
||||||
int tmpReg2 = sqlite3GetTempReg(pParse);
|
int tmpReg2 = sqlite3GetTempReg(pParse);
|
||||||
sqlite3VdbeAddOp3(v, OP_Column, iEph, pWin->iArgCol+1, tmpReg2);
|
sqlite3VdbeAddOp3(v, OP_Column, iEph, pWin->iArgCol+1, tmpReg2);
|
||||||
sqlite3VdbeAddOp3(v, op, tmpReg2, tmpReg, tmpReg);
|
sqlite3VdbeAddOp3(v, op, tmpReg2, tmpReg, tmpReg);
|
||||||
@@ -1373,8 +1376,8 @@ static int windowInitAccum(Parse *pParse, Window *pMWin){
|
|||||||
FuncDef *pFunc = pWin->pFunc;
|
FuncDef *pFunc = pWin->pFunc;
|
||||||
sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regAccum);
|
sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regAccum);
|
||||||
nArg = MAX(nArg, windowArgCount(pWin));
|
nArg = MAX(nArg, windowArgCount(pWin));
|
||||||
if( pFunc->xSFunc==nth_valueStepFunc
|
if( pFunc->zName==nth_valueName
|
||||||
|| pFunc->xSFunc==first_valueStepFunc
|
|| pFunc->zName==first_valueName
|
||||||
){
|
){
|
||||||
sqlite3VdbeAddOp2(v, OP_Integer, 0, pWin->regApp);
|
sqlite3VdbeAddOp2(v, OP_Integer, 0, pWin->regApp);
|
||||||
sqlite3VdbeAddOp2(v, OP_Integer, 0, pWin->regApp+1);
|
sqlite3VdbeAddOp2(v, OP_Integer, 0, pWin->regApp+1);
|
||||||
@@ -2160,10 +2163,10 @@ void sqlite3WindowCodeStep(
|
|||||||
for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
|
for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
|
||||||
FuncDef *pFunc = pWin->pFunc;
|
FuncDef *pFunc = pWin->pFunc;
|
||||||
if( (pFunc->funcFlags & SQLITE_FUNC_WINDOW_SIZE)
|
if( (pFunc->funcFlags & SQLITE_FUNC_WINDOW_SIZE)
|
||||||
|| (pFunc->xSFunc==nth_valueStepFunc)
|
|| (pFunc->zName==nth_valueName)
|
||||||
|| (pFunc->xSFunc==first_valueStepFunc)
|
|| (pFunc->zName==first_valueName)
|
||||||
|| (pFunc->xSFunc==leadStepFunc)
|
|| (pFunc->zName==leadName)
|
||||||
|| (pFunc->xSFunc==lagStepFunc)
|
|| (pFunc->zName==lagName)
|
||||||
){
|
){
|
||||||
bCache = 1;
|
bCache = 1;
|
||||||
break;
|
break;
|
||||||
|
Reference in New Issue
Block a user