1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-11-12 13:01:09 +03:00

Handle multiple window-functions in a single query.

FossilOrigin-Name: 35af0b750e70dcf0f343b115f4bbd0860a7e8064be204d4dfba1a43c22ff07b1
This commit is contained in:
dan
2018-05-17 14:26:27 +00:00
parent 86fb6e1738
commit 2e362f9775
5 changed files with 70 additions and 42 deletions

View File

@@ -1,5 +1,5 @@
C Start\sof\sexperimental\simplementation\sof\sSQL\swindow\sfunctions.\sDoes\snot\syet\nwork. C Handle\smultiple\swindow-functions\sin\sa\ssingle\squery.
D 2018-05-16T20:58:07.009 D 2018-05-17T14:26:27.790
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 bfc40f350586923e0419d2ea4b559c37ec10ee4b6e210e08c14401f8e340f0da F Makefile.in bfc40f350586923e0419d2ea4b559c37ec10ee4b6e210e08c14401f8e340f0da
@@ -445,7 +445,7 @@ F src/date.c ebe1dc7c8a347117bb02570f1a931c62dd78f4a2b1b516f4837d45b7d6426957
F src/dbpage.c 8db4c97f630e7d83f884ea75caf1ffd0988c160e9d530194d93721c80821e0f6 F src/dbpage.c 8db4c97f630e7d83f884ea75caf1ffd0988c160e9d530194d93721c80821e0f6
F src/dbstat.c edabb82611143727511a45ca0859b8cd037851ebe756ae3db289859dd18b6f91 F src/dbstat.c edabb82611143727511a45ca0859b8cd037851ebe756ae3db289859dd18b6f91
F src/delete.c b0f90749e22d5e41a12dbf940f4811138cf97da54b46b737089b93eb64a2896f F src/delete.c b0f90749e22d5e41a12dbf940f4811138cf97da54b46b737089b93eb64a2896f
F src/expr.c 6e443e4f9fabd3125800076f2a7cd90c84d2c106ed1815cbe5e9c96af2b9eb74 F src/expr.c af55e984d86b29f9cc1fbb785fd665ac254806d9ad5f791c668414dcb8ddcf0b
F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
F src/fkey.c d617daf66b5515e2b42c1405b2b4984c30ca50fb705ab164271a9bf66c69e331 F src/fkey.c d617daf66b5515e2b42c1405b2b4984c30ca50fb705ab164271a9bf66c69e331
F src/func.c 03c99a50c69f7d565e13179aad26af703b9df7752a4d690af1540c5e04ababc2 F src/func.c 03c99a50c69f7d565e13179aad26af703b9df7752a4d690af1540c5e04ababc2
@@ -493,7 +493,7 @@ F src/printf.c 1d1b4a568a58d0f32a5ff26c6b98db8a6e1883467f343a6406263cacd2e60c21
F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384
F src/resolve.c 8feaf2039bd1b17dd5021e0c5731cde741694b59032d0faf5c73df499c880ebf F src/resolve.c 8feaf2039bd1b17dd5021e0c5731cde741694b59032d0faf5c73df499c880ebf
F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac
F src/select.c 0e82e32d3bd536c90e778c930cdf7dafa5afd886cc8c467c443ff95c38109e10 F src/select.c 0b9d051a0b97d9ae20947e74f341dde248f15bbfda1834932b3d21097f4e080c
F src/shell.c.in 53affa90711f280342f7238f9c9aa9dcaed321ec6218a18043cf92154ef8a704 F src/shell.c.in 53affa90711f280342f7238f9c9aa9dcaed321ec6218a18043cf92154ef8a704
F src/sqlite.h.in 34be2d0d18bf4726538793bdc9854cd87f689fda4b3789515134cdbd68188cf4 F src/sqlite.h.in 34be2d0d18bf4726538793bdc9854cd87f689fda4b3789515134cdbd68188cf4
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
@@ -1613,7 +1613,7 @@ F test/win32heap.test 10fd891266bd00af68671e702317726375e5407561d859be1aa04696f2
F test/win32lock.test fbf107c91d8f5512be5a5b87c4c42ab9fdd54972 F test/win32lock.test fbf107c91d8f5512be5a5b87c4c42ab9fdd54972
F test/win32longpath.test 169c75a3b2e43481f4a62122510210c67b08f26d F test/win32longpath.test 169c75a3b2e43481f4a62122510210c67b08f26d
F test/win32nolock.test ac4f08811a562e45a5755e661f45ca85892bdbbc F test/win32nolock.test ac4f08811a562e45a5755e661f45ca85892bdbbc
F test/window1.test d1766b0cbaf87521a0245b18da8c907cc0d791b287a66e90c70f8b836985794d F test/window1.test c088fff1b97ec6dc51bc6c6df936e7d2fd2d4b2708fa9738fe13aa175a7e47c4
F test/with1.test 58475190cd8caaeebea8cfeb2a264ec97a0c492b8ffe9ad20cefbb23df462f96 F test/with1.test 58475190cd8caaeebea8cfeb2a264ec97a0c492b8ffe9ad20cefbb23df462f96
F test/with2.test e0030e2f0267a910d6c0e4f46f2dfe941c1cc0d4f659ba69b3597728e7e8f1ab F test/with2.test e0030e2f0267a910d6c0e4f46f2dfe941c1cc0d4f659ba69b3597728e7e8f1ab
F test/with3.test 5e8ce2c585170bbbc0544e2a01a4941fa0be173ba5265e5c92eb588cd99a232d F test/with3.test 5e8ce2c585170bbbc0544e2a01a4941fa0be173ba5265e5c92eb588cd99a232d
@@ -1730,11 +1730,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 ed5b09680fd6659ebbe5ace3c1c56f3962bbd75cfdf65c7565651900cf87917a P 3781e520854808fe02ad3fe77dd11fc917448c58ff1fd79123289dd91937decd
R 44bb3242b5e27ab54d0052d5f4fa0103 R ab1ec0d66b6e5c3f79bc48c2607263f7
T *branch * exp-window-functions
T *sym-exp-window-functions *
T +closed d103c041ccb3a009926b6aa34a283a7cb8e4a645711ecd7a3002a90558d02e9d
T -sym-trunk *
U dan U dan
Z 75ac74ab72bd7e468725d214860f2422 Z dc655b7af30130730642201f8ff47123

View File

@@ -1 +1 @@
3781e520854808fe02ad3fe77dd11fc917448c58ff1fd79123289dd91937decd 35af0b750e70dcf0f343b115f4bbd0860a7e8064be204d4dfba1a43c22ff07b1

View File

@@ -772,6 +772,7 @@ Expr *sqlite3ExprAlloc(
memset(pNew, 0, sizeof(Expr)); memset(pNew, 0, sizeof(Expr));
pNew->op = (u8)op; pNew->op = (u8)op;
pNew->iAgg = -1; pNew->iAgg = -1;
pNew->pWin = 0;
if( pToken ){ if( pToken ){
if( nExtra==0 ){ if( nExtra==0 ){
pNew->flags |= EP_IntValue|EP_Leaf; pNew->flags |= EP_IntValue|EP_Leaf;
@@ -861,6 +862,7 @@ Expr *sqlite3PExpr(
memset(p, 0, sizeof(Expr)); memset(p, 0, sizeof(Expr));
p->op = op & TKFLG_MASK; p->op = op & TKFLG_MASK;
p->iAgg = -1; p->iAgg = -1;
p->pWin = 0;
} }
sqlite3ExprAttachSubtrees(pParse->db, p, pLeft, pRight); sqlite3ExprAttachSubtrees(pParse->db, p, pLeft, pRight);
} }
@@ -1180,6 +1182,24 @@ static int dupedExprSize(Expr *p, int flags){
return nByte; return nByte;
} }
static Window *winDup(sqlite3 *db, Window *p){
Window *pNew = 0;
if( p ){
pNew = sqlite3DbMallocZero(db, sizeof(Window));
if( pNew ){
pNew->pFilter = sqlite3ExprDup(db, p->pFilter, 0);
pNew->pPartition = sqlite3ExprListDup(db, p->pPartition, 0);
pNew->pOrderBy = sqlite3ExprListDup(db, p->pOrderBy, 0);
pNew->eType = p->eType;
pNew->eEnd = p->eEnd;
pNew->eStart = p->eStart;
pNew->pStart = sqlite3ExprDup(db, pNew->pStart, 0);
pNew->pEnd = sqlite3ExprDup(db, pNew->pEnd, 0);
}
}
return pNew;
}
/* /*
** This function is similar to sqlite3ExprDup(), except that if pzBuffer ** This function is similar to sqlite3ExprDup(), except that if pzBuffer
** is not NULL then *pzBuffer is assumed to point to a buffer large enough ** is not NULL then *pzBuffer is assumed to point to a buffer large enough
@@ -1266,6 +1286,7 @@ static Expr *exprDup(sqlite3 *db, Expr *p, int dupFlags, u8 **pzBuffer){
*pzBuffer = zAlloc; *pzBuffer = zAlloc;
} }
}else{ }else{
pNew->pWin = winDup(db, p->pWin);
if( !ExprHasProperty(p, EP_TokenOnly|EP_Leaf) ){ if( !ExprHasProperty(p, EP_TokenOnly|EP_Leaf) ){
if( pNew->op==TK_SELECT_COLUMN ){ if( pNew->op==TK_SELECT_COLUMN ){
pNew->pLeft = p->pLeft; pNew->pLeft = p->pLeft;
@@ -1308,24 +1329,6 @@ static With *withDup(sqlite3 *db, With *p){
# define withDup(x,y) 0 # define withDup(x,y) 0
#endif #endif
static Window *winDup(sqlite3 *db, Window *p){
Window *pNew = 0;
if( p ){
pNew = sqlite3DbMallocZero(db, sizeof(Window));
if( pNew ){
pNew->pFilter = sqlite3ExprDup(db, p->pFilter, 0);
pNew->pPartition = sqlite3ExprListDup(db, p->pPartition, 0);
pNew->pOrderBy = sqlite3ExprListDup(db, p->pOrderBy, 0);
pNew->eType = p->eType;
pNew->eEnd = p->eEnd;
pNew->eStart = p->eStart;
pNew->pStart = sqlite3ExprDup(db, pNew->pStart, 0);
pNew->pEnd = sqlite3ExprDup(db, pNew->pEnd, 0);
}
}
return pNew;
}
/* /*
** The following group of routines make deep copies of expressions, ** The following group of routines make deep copies of expressions,
** expression lists, ID lists, and select statements. The copies can ** expression lists, ID lists, and select statements. The copies can
@@ -1490,7 +1493,7 @@ Select *sqlite3SelectDup(sqlite3 *db, Select *pDup, int flags){
pNew->addrOpenEphm[1] = -1; pNew->addrOpenEphm[1] = -1;
pNew->nSelectRow = p->nSelectRow; pNew->nSelectRow = p->nSelectRow;
pNew->pWith = withDup(db, p->pWith); pNew->pWith = withDup(db, p->pWith);
pNew->pWin = winDup(db, p->pWin); pNew->pWin = 0;
sqlite3SelectSetName(pNew, p->zSelName); sqlite3SelectSetName(pNew, p->zSelName);
*pp = pNew; *pp = pNew;
pp = &pNew->pPrior; pp = &pNew->pPrior;

View File

@@ -5418,6 +5418,17 @@ static int selectWindowRewriteExprCb(Walker *pWalker, Expr *pExpr){
int rc = WRC_Continue; int rc = WRC_Continue;
switch( pExpr->op ){ switch( pExpr->op ){
case TK_FUNCTION:
if( pExpr->pWin==0 ){
break;
}else if( pExpr->pWin==p->pWin ){
rc = WRC_Prune;
pExpr->pWin->pOwner = pExpr;
break;
}
/* Fall through. */
case TK_COLUMN: { case TK_COLUMN: {
Expr *pDup = sqlite3ExprDup(pParse->db, pExpr, 0); Expr *pDup = sqlite3ExprDup(pParse->db, pExpr, 0);
p->pSub = sqlite3ExprListAppend(pParse, p->pSub, pDup); p->pSub = sqlite3ExprListAppend(pParse, p->pSub, pDup);
@@ -5436,13 +5447,6 @@ static int selectWindowRewriteExprCb(Walker *pWalker, Expr *pExpr){
break; break;
} }
case TK_FUNCTION:
if( pExpr->pWin ){
rc = WRC_Prune;
pExpr->pWin->pOwner = pExpr;
}
break;
default: /* no-op */ default: /* no-op */
break; break;
} }
@@ -5530,9 +5534,6 @@ static int selectWindowRewrite(Parse *pParse, Select *p){
ExprList *pSublist = 0; /* Expression list for sub-query */ ExprList *pSublist = 0; /* Expression list for sub-query */
Window *pWin = p->pWin; Window *pWin = p->pWin;
/* TODO: This is of course temporary requirements */
assert( pWin->pNextWin==0 );
p->pSrc = 0; p->pSrc = 0;
p->pWhere = 0; p->pWhere = 0;
p->pGroupBy = 0; p->pGroupBy = 0;
@@ -5581,6 +5582,7 @@ static int selectWindowRewrite(Parse *pParse, Select *p){
}else{ }else{
pSub->selFlags |= SF_Expanded; pSub->selFlags |= SF_Expanded;
} }
pWin->pNextWin = 0;
} }
#if SELECTTRACE_ENABLED #if SELECTTRACE_ENABLED

View File

@@ -109,4 +109,31 @@ do_execsql_test 4.5 {
0 0 1 1 2 2 3 4 4 6 5 9 6 12 0 0 1 1 2 2 3 4 4 6 5 9 6 12
} }
do_execsql_test 4.6 {
SELECT a, sum(a) OVER (PARTITION BY c ORDER BY a) FROM t2 ORDER BY a
} {
0 0 1 1 2 2 3 3 4 5 5 7 6 9
}
do_execsql_test 4.7 {
SELECT a, sum(a) OVER (PARTITION BY b ORDER BY a DESC) FROM t2 ORDER BY a
} {
0 12 1 9 2 12 3 8 4 10 5 5 6 6
}
do_execsql_test 4.8 {
SELECT a,
sum(a) OVER (PARTITION BY b ORDER BY a DESC),
sum(a) OVER (PARTITION BY c ORDER BY a)
FROM t2 ORDER BY a
} {
0 12 0
1 9 1
2 12 2
3 8 3
4 10 5
5 5 7
6 6 9
}
finish_test finish_test