Fix another issue to do with window-functions in aggregate queries.
FossilOrigin-Name: 6413e38a174044c28fa9b8b937e6c972d144547a246e6f2882e782538300d042
This commit is contained in:
parent
7392569f5e
commit
c0bb4459d3
18
manifest
18
manifest
@ -1,5 +1,5 @@
|
||||
C Fix\ssome\sproblems\swith\susing\swindow-functions\sin\saggregate\squeries.
|
||||
D 2018-06-12T18:40:17.751
|
||||
C Fix\sanother\sissue\sto\sdo\swith\swindow-functions\sin\saggregate\squeries.
|
||||
D 2018-06-12T20:53:38.832
|
||||
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
||||
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
||||
F Makefile.in 498b77b89a8cb42f2ee20fcd6317f279a45c0d6ff40d27825f94b69884c09bbe
|
||||
@ -436,7 +436,7 @@ F src/auth.c a38f3c63c974787ecf75e3213f8cac6568b9a7af7591fb0372ec0517dd16dca8
|
||||
F src/backup.c 78d3cecfbe28230a3a9a1793e2ead609f469be43e8f486ca996006be551857ab
|
||||
F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33
|
||||
F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6
|
||||
F src/btree.c 671207d68ac2fb32c782f9b65cd6f8a861757044b1448098cb08fab4fcf02947
|
||||
F src/btree.c 50425f7f26b10919bd14fa1af534b92c339bf7aac4b1ac8c70404f4e6f8220d8
|
||||
F src/btree.h 7b557914561f60a0eb76c2e22c23ab5b82f87b734a91c1b9385654b6474fdf7f
|
||||
F src/btreeInt.h 620ab4c7235f43572cf3ac2ac8723cbdf68073be4d29da24897c7b77dda5fd96
|
||||
F src/build.c 3b3bfa88800739e1f11313dcecfba5ef8e4757b6c929cdf7de9fcfc01002b81f
|
||||
@ -583,7 +583,7 @@ F src/where.c fe1a6f97c12cc9472ccce86166ba3f827cf61d6ae770c036a6396b63863baac4
|
||||
F src/whereInt.h b90ef9b9707ef750eab2a7a080c48fb4900315033274689def32d0cf5a81ebe4
|
||||
F src/wherecode.c 3317f2b083a66d3e65a03edf316ade4ccb0a99c9956273282ebb579b95d4ba96
|
||||
F src/whereexpr.c 6f022d6cc9daf56495f191b199352f783aff5cf268ba136b4d8cea3fb62d8c7d
|
||||
F src/window.c 5fc1e9a4367bdd6c5afd318a36ec0b1f702fa1e3384621501873ec6b3e94651a
|
||||
F src/window.c 45d149fe9926b7e9c610ef5234b6eef08f22cbdff855aa3f367b6af17499e90b
|
||||
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
|
||||
F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd
|
||||
F test/affinity3.test 6a101af2fc945ce2912f6fe54dd646018551710d
|
||||
@ -1622,8 +1622,8 @@ F test/window2.tcl 0983de5eade5eeda49469244799d5331bfe3199fca3f6c6d2a836aa08f4fb
|
||||
F test/window2.test 79747b2edde4ad424e0752b27529aedc86e91f3d8d88846fa17ff0cb67f65086
|
||||
F test/window3.tcl 654d61d73e10db089b22514d498bb23ec310f720c0f4b5f69f67fda83d672048
|
||||
F test/window3.test 41727668ee31d2ba50f78efcb5bf1bda2c5cffd889aa65243511004669d1ac25
|
||||
F test/window4.tcl e64db87bac34d9a726f2b97c40f4adbfc21650a26b7015b18f357062266a0062
|
||||
F test/window4.test 36df9adf8b305b427fee8c9604a958e8fecb85c2ba21f6819ad3e87610253001
|
||||
F test/window4.tcl a77a7ab3c60517abe06307e4204d65d11f5474c8062f30f536755dd083bf8224
|
||||
F test/window4.test 0fb98450ff5478f91b4f8c9440d4463ded30a7337029da4272894ccff0f227e2
|
||||
F test/with1.test 58475190cd8caaeebea8cfeb2a264ec97a0c492b8ffe9ad20cefbb23df462f96
|
||||
F test/with2.test e0030e2f0267a910d6c0e4f46f2dfe941c1cc0d4f659ba69b3597728e7e8f1ab
|
||||
F test/with3.test 5e8ce2c585170bbbc0544e2a01a4941fa0be173ba5265e5c92eb588cd99a232d
|
||||
@ -1740,7 +1740,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
|
||||
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
||||
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
||||
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
||||
P 0cd55e98a478740032f5569ddc00fa5b0e063e90db6e00ac7598c9b7c2fffeee
|
||||
R a9e6944f8f988df57ad1f0cd1beda118
|
||||
P fe7081e0952950f577234fcbb58f3c1efa4579267654fd2f713dc4804e470e7e
|
||||
R 7cbc79b684a204310b1cd3eb56d614ea
|
||||
U dan
|
||||
Z e98e199ae454a383acf0272ef0289805
|
||||
Z 4b5b4b6d9afcbd2c7bfd885559718021
|
||||
|
@ -1 +1 @@
|
||||
fe7081e0952950f577234fcbb58f3c1efa4579267654fd2f713dc4804e470e7e
|
||||
6413e38a174044c28fa9b8b937e6c972d144547a246e6f2882e782538300d042
|
@ -5185,6 +5185,11 @@ int sqlite3BtreeFirst(BtCursor *pCur, int *pRes){
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
** This function is a no-op if cursor pCur does not point to a valid row.
|
||||
** Otherwise, if pCur is valid, configure it so that the next call to
|
||||
** sqlite3BtreeNext() is a no-op.
|
||||
*/
|
||||
void sqlite3BtreeSkipNext(BtCursor *pCur){
|
||||
if( pCur->eState==CURSOR_VALID ){
|
||||
pCur->eState = CURSOR_SKIPNEXT;
|
||||
|
91
src/window.c
91
src/window.c
@ -129,6 +129,11 @@
|
||||
** ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
|
||||
**
|
||||
** See sqlite3WindowUpdate() for details.
|
||||
**
|
||||
** As well as some of the built-in window functions, aggregate window
|
||||
** functions min() and max() are implemented using VDBE instructions if
|
||||
** the start of the window frame is declared as anything other than
|
||||
** UNBOUNDED PRECEDING.
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -471,11 +476,28 @@ void sqlite3WindowFunctions(void){
|
||||
sqlite3InsertBuiltinFuncs(aWindowFuncs, ArraySize(aWindowFuncs));
|
||||
}
|
||||
|
||||
/*
|
||||
** This function is called immediately after resolving the function name
|
||||
** for a window function within a SELECT statement. Argument pList is a
|
||||
** linked list of WINDOW definitions for the current SELECT statement.
|
||||
** Argument pFunc is the function definition just resolved and pWin
|
||||
** is the Window object representing the associated OVER clause. This
|
||||
** function updates the contents of pWin as follows:
|
||||
**
|
||||
** * If the OVER clause refered to a named window (as in "max(x) OVER win"),
|
||||
** search list pList for a matching WINDOW definition, and update pWin
|
||||
** accordingly. If no such WINDOW clause can be found, leave an error
|
||||
** in pParse.
|
||||
**
|
||||
** * If the function is a built-in window function that requires the
|
||||
** window to be coerced (see "BUILT-IN WINDOW FUNCTIONS" at the top
|
||||
** of this file), pWin is updated here.
|
||||
*/
|
||||
void sqlite3WindowUpdate(
|
||||
Parse *pParse,
|
||||
Window *pList,
|
||||
Window *pWin,
|
||||
FuncDef *pFunc
|
||||
Window *pList, /* List of named windows for this SELECT */
|
||||
Window *pWin, /* Window frame to update */
|
||||
FuncDef *pFunc /* Window function definition */
|
||||
){
|
||||
if( pWin->zName ){
|
||||
Window *p;
|
||||
@ -523,16 +545,21 @@ void sqlite3WindowUpdate(
|
||||
pWin->pFunc = pFunc;
|
||||
}
|
||||
|
||||
/*
|
||||
** Context object passed through sqlite3WalkExprList() to
|
||||
** selectWindowRewriteExprCb() by selectWindowRewriteEList().
|
||||
*/
|
||||
typedef struct WindowRewrite WindowRewrite;
|
||||
struct WindowRewrite {
|
||||
Window *pWin;
|
||||
ExprList *pSub;
|
||||
};
|
||||
|
||||
static int selectWindowRewriteSelectCb(Walker *pWalker, Select *pSelect){
|
||||
return WRC_Prune;
|
||||
}
|
||||
|
||||
/*
|
||||
** Callback function used by selectWindowRewriteEList(). If necessary,
|
||||
** this function appends to the output expression-list and updates
|
||||
** expression (*ppExpr) in place.
|
||||
*/
|
||||
static int selectWindowRewriteExprCb(Walker *pWalker, Expr *pExpr){
|
||||
struct WindowRewrite *p = pWalker->u.pRewrite;
|
||||
Parse *pParse = pWalker->pParse;
|
||||
@ -578,7 +605,24 @@ static int selectWindowRewriteExprCb(Walker *pWalker, Expr *pExpr){
|
||||
|
||||
return WRC_Continue;
|
||||
}
|
||||
static int selectWindowRewriteSelectCb(Walker *pWalker, Select *pSelect){
|
||||
return WRC_Prune;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Iterate through each expression in expression-list pEList. For each:
|
||||
**
|
||||
** * TK_COLUMN,
|
||||
** * aggregate function, or
|
||||
** * window function with a Window object that is not a member of the
|
||||
** linked list passed as the second argument (pWin)
|
||||
**
|
||||
** Append the node to output expression-list (*ppSub). And replace it
|
||||
** with a TK_COLUMN that reads the (N-1)th element of table
|
||||
** pWin->iEphCsr, where N is the number of elements in (*ppSub) after
|
||||
** appending the new one.
|
||||
*/
|
||||
static int selectWindowRewriteEList(
|
||||
Parse *pParse,
|
||||
Window *pWin,
|
||||
@ -606,6 +650,10 @@ static int selectWindowRewriteEList(
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
** Append a copy of each expression in expression-list pAppend to
|
||||
** expression list pList. Return a pointer to the result list.
|
||||
*/
|
||||
static ExprList *exprListAppendList(
|
||||
Parse *pParse, /* Parsing context */
|
||||
ExprList *pList, /* List to which to append. Might be NULL */
|
||||
@ -627,21 +675,8 @@ static ExprList *exprListAppendList(
|
||||
** If the SELECT statement passed as the second argument does not invoke
|
||||
** any SQL window functions, this function is a no-op. Otherwise, it
|
||||
** rewrites the SELECT statement so that window function xStep functions
|
||||
** are invoked in the correct order. The simplest version of the
|
||||
** transformation is:
|
||||
**
|
||||
** SELECT win(args...) OVER (<list1>) FROM <src> ORDER BY <list2>
|
||||
**
|
||||
** to
|
||||
**
|
||||
** SELECT win(args...) FROM (
|
||||
** SELECT args... FROM <src> ORDER BY <list1>
|
||||
** ) ORDER BY <list2>
|
||||
**
|
||||
** where <src> may contain WHERE, GROUP BY and HAVING clauses, and <list1>
|
||||
** is the concatenation of the PARTITION BY and ORDER BY clauses in the
|
||||
** OVER clause.
|
||||
**
|
||||
** are invoked in the correct order as described under "SELECT REWRITING"
|
||||
** at the top of this file.
|
||||
*/
|
||||
int sqlite3WindowRewrite(Parse *pParse, Select *p){
|
||||
int rc = SQLITE_OK;
|
||||
@ -726,6 +761,9 @@ int sqlite3WindowRewrite(Parse *pParse, Select *p){
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
** Free the Window object passed as the second argument.
|
||||
*/
|
||||
void sqlite3WindowDelete(sqlite3 *db, Window *p){
|
||||
if( p ){
|
||||
sqlite3ExprDelete(db, p->pFilter);
|
||||
@ -738,6 +776,9 @@ void sqlite3WindowDelete(sqlite3 *db, Window *p){
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Free the linked list of Window objects starting at the second argument.
|
||||
*/
|
||||
void sqlite3WindowListDelete(sqlite3 *db, Window *p){
|
||||
while( p ){
|
||||
Window *pNext = p->pNextWin;
|
||||
@ -746,6 +787,9 @@ void sqlite3WindowListDelete(sqlite3 *db, Window *p){
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Allocate and return a new Window object.
|
||||
*/
|
||||
Window *sqlite3WindowAlloc(
|
||||
Parse *pParse,
|
||||
int eType,
|
||||
@ -768,6 +812,9 @@ Window *sqlite3WindowAlloc(
|
||||
return pWin;
|
||||
}
|
||||
|
||||
/*
|
||||
** Attach window object pWin to expression p.
|
||||
*/
|
||||
void sqlite3WindowAttach(Parse *pParse, Expr *p, Window *pWin){
|
||||
if( p ){
|
||||
p->pWin = pWin;
|
||||
|
@ -149,6 +149,14 @@ execsql_test 4.1 {
|
||||
SELECT max(c), max(b) OVER (ORDER BY b) FROM ttt GROUP BY b;
|
||||
}
|
||||
|
||||
execsql_test 4.2 {
|
||||
SELECT max(b) OVER (ORDER BY max(c)) FROM ttt GROUP BY b;
|
||||
}
|
||||
|
||||
execsql_test 4.3 {
|
||||
SELECT abs(max(b) OVER (ORDER BY b)) FROM ttt GROUP BY b;
|
||||
}
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
|
@ -231,4 +231,12 @@ do_execsql_test 4.1 {
|
||||
SELECT max(c), max(b) OVER (ORDER BY b) FROM ttt GROUP BY b;
|
||||
} {3 1 4 2 5 3}
|
||||
|
||||
do_execsql_test 4.2 {
|
||||
SELECT max(b) OVER (ORDER BY max(c)) FROM ttt GROUP BY b;
|
||||
} {1 2 3}
|
||||
|
||||
do_execsql_test 4.3 {
|
||||
SELECT abs(max(b) OVER (ORDER BY b)) FROM ttt GROUP BY b;
|
||||
} {1 2 3}
|
||||
|
||||
finish_test
|
||||
|
Loading…
Reference in New Issue
Block a user