From be12083bc792b35441f217aec141a3a4b8bd44bf Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 17 May 2021 16:20:41 +0000 Subject: [PATCH] Fix problems with refering to CTEs from within sub-selects in PARTITION BY or ORDER BY clauses of window frame definitions. Also a problem with renaming a column when the schema contains a trigger containing a correlated sub-select within a window frames PARTITION BY or ORDER BY clause. FossilOrigin-Name: 4c6cd54a8db78e5535912e76856bed4f797261aaca4248c69d2e2452194de297 --- manifest | 28 +++++++++++------------ manifest.uuid | 2 +- src/resolve.c | 26 +++++++++++----------- src/select.c | 6 ++--- src/sqliteInt.h | 6 +++++ src/walker.c | 3 +++ test/altertab.test | 31 ++++++++++++++++++++++++++ test/window1.test | 7 ++++++ test/window8.tcl | 54 +++++++++++++++++++++++++++++++++++++++++++++ test/window8.test | 55 ++++++++++++++++++++++++++++++++++++++++++++++ 10 files changed, 186 insertions(+), 32 deletions(-) diff --git a/manifest b/manifest index c5b07b2745..fdccc0b92a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C When\sdeleting\san\sSQL\sfunction\sthat\sdoes\snot\sexist,\sreturn\swithout\sdoing\nanything\sat\sall\srather\sthan\screating\sa\stombstone\sfunction.\s\sIn\sthis\sway,\nfunction\sdeletes\sthat\shappen\sinside\svirtual-table\sdestructors\sthat\sare\srun\nwhen\sa\sdatabase\sconnection\sis\sclosing\sdo\snot\screate\snew\stombstones\sin\sthe\nfunction\stable\safter\sthe\sfunction\stable\shas\salready\sbeen\spurged.\n[forum:/forumpost/726219164b|forum\spost\s726219164b]. -D 2021-05-17T13:11:24.573 +C Fix\sproblems\swith\srefering\sto\sCTEs\sfrom\swithin\ssub-selects\sin\sPARTITION\sBY\sor\sORDER\sBY\sclauses\sof\swindow\sframe\sdefinitions.\sAlso\sa\sproblem\swith\srenaming\sa\scolumn\swhen\sthe\sschema\scontains\sa\strigger\scontaining\sa\scorrelated\ssub-select\swithin\sa\swindow\sframes\sPARTITION\sBY\sor\sORDER\sBY\sclause. +D 2021-05-17T16:20:41.216 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -541,14 +541,14 @@ F src/pragma.h 8dc78ab7e9ec6ce3ded8332810a2066f1ef6267e2e03cd7356ee00276125c6cf F src/prepare.c d778af9986f3b0107c5b255dcfe2696e8e99e00fb77c5115bbfea4e92c3302e7 F src/printf.c 78fabb49b9ac9a12dd1c89d744abdc9b67fd3205e62967e158f78b965a29ec4b F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 -F src/resolve.c c38bbb89d7ba7a8673ec4f59b63e0980eb859c39ff2acc5df8b3d0f2dcd33115 +F src/resolve.c 40e216d9a72e52841a9c8e0aec7d367bade8e2df17b804653b539b20c1ab5660 F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 -F src/select.c c380cca3aea949c7af58c39cd73defaedf7cb3f7fb4aa436b3a622e393579341 +F src/select.c 0ba381ae7f9f4f84bed7d3a357703fd08b587fef6477f78953d8bcfe4e42328f F src/shell.c.in 1b32ba2918ede13b68df47c7b92b72ba0d06e68d384e78bb9d7456527271d400 F src/sqlite.h.in 5c950066775ca9efdaa49077c05d38d0bef6418f3bd07d2dce0210f1d2f3c326 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 61b38c073d5e1e96a3d45271b257aef27d0d13da2bea5347692ae579475cd95e -F src/sqliteInt.h 2b1cbc7f78346ac83ea962e5daf6a201e223cf1902e0cfde54f37cf3d82fcc24 +F src/sqliteInt.h f65c88936a59477d11f4599d0b2c3f08339e60d23e9e312dfe5e1782380b721e F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657 F src/status.c 4b8bc2a6905163a38b739854a35b826c737333fab5b1f8e03fa7eb9a4799c4c1 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 @@ -629,7 +629,7 @@ F src/vtab.c b928405ccb66040fc6c3a11eaa93ddb02cbf20f9ab6860b301b222b9b50dc089 F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c c8ec20a1ca161d5635a4f19c2a4efec2e006e19a8a61f272bf6bce1c80ab7436 F src/wal.h c3aa7825bfa2fe0d85bef2db94655f99870a285778baa36307c0a16da32b226a -F src/walker.c 6e540867a30d81e00205995fa2dc0e3d25365a7402251c9fd5d19aa4ff5e60b6 +F src/walker.c 7342becedf3f8a26f9817f08436bdf8b56ad69af83705f6b9320a0ad3092c2ac F src/where.c 32f41c3c93c6785e0077e3a2cdc669c3ccfe70173787847be77f294c18fc7dc3 F src/whereInt.h 9248161dd004f625ce5d3841ca9b99fed3fc8d61522cf76340fc5217dbe1375b F src/wherecode.c b4c21439f0549bb5c571214e08ddb5ec58d5e972f4b4c87c0cc79351edd43704 @@ -657,7 +657,7 @@ F test/altermalloc.test 167a47de41b5c638f5f5c6efb59784002b196fff70f98d9b4ed3cd74 F test/altermalloc2.test fa7b1c1139ea39b8dec407cf1feb032ca8e0076bd429574969b619175ad0174b F test/altermalloc3.test 059841a3de6b6780efd9f0b30bf1d9b4443c555f68d39975cbcac2583167b239 F test/alterqf.test 67568ad152db8c1187b15633b801242cf960f1beafc51261a3d1725d910baeb2 -F test/altertab.test 281e89a69323a86294f7824b17c60c425a4cdcd764f346469d2d544aa233f72d +F test/altertab.test c7966d92e4da535050b911e1e9972ecb3a5befb0b2d22026b132cf5003d43dec F test/altertab2.test b0d62f323ca5dab42b0bc028c52e310ebdd13e655e8fac070fe622bad7852c2b F test/altertab3.test 2b82fa2236a3a91553d53ae5555d8e723c7eec174c41f1fa62ff497355398479 F test/amatch1.test b5ae7065f042b7f4c1c922933f4700add50cdb9f @@ -1770,7 +1770,7 @@ F test/win32heap.test 10fd891266bd00af68671e702317726375e5407561d859be1aa04696f2 F test/win32lock.test fbf107c91d8f5512be5a5b87c4c42ab9fdd54972 F test/win32longpath.test 4baffc3acb2e5188a5e3a895b2b543ed09e62f7c72d713c1feebf76222fe9976 F test/win32nolock.test ac4f08811a562e45a5755e661f45ca85892bdbbc -F test/window1.test 5950af3f6fe084b8cc889501b25721f62dcfc9ff548031f40c54b9617d88958b +F test/window1.test 138f328242eca1523154eca116b23033a688fcf3e6c01c572373df31c1e90029 F test/window2.tcl 492c125fa550cda1dd3555768a2303b3effbeceee215293adf8871efc25f1476 F test/window2.test e466a88bd626d66edc3d352d7d7e1d5531e0079b549ba44efb029d1fbff9fd3c F test/window3.tcl acea6e86a4324a210fd608d06741010ca83ded9fde438341cb978c49928faf03 @@ -1781,8 +1781,8 @@ F test/window5.test d328dd18221217c49c144181975eea17339eaeaf0e9aa558cee3afb84652 F test/window6.test f8d674254b23289cc17c84d79dec7eda7caa1dfb7836c43122cfdf3640d1df32 F test/window7.tcl 6a1210f05d40ec89c22960213a22cd3f98d4e2f2eb20646c83c8c30d4d76108f F test/window7.test 1d31276961ae7801edc72173edaf7593e3cbc79c06d1f1f09e20d8418af403cd -F test/window8.tcl f2711aa3571e4e6b0dad98db8d95fd6cb8d9db0c92bbdf535f153b07606a1ce2 -F test/window8.test c4331b27a6f66d69fa8f8bab10cc731db1a81d293ae108a68f7c3487fa94e65b +F test/window8.tcl 3d3c206107b92e173504daa20617ff85d8d3a7beb33e4d209356a7c47cfcb592 +F test/window8.test 2cdfaa1fd9ea591aea1a917ff361ff1a1aabe270f566244286e9d1d9c8c951a0 F test/window9.test 349c71eab4288a1ffc19e2f65872ec2c37e6cf8a1dda2ad300364b7450ae4836 F test/windowA.test 6d63dc1260daa17141a55007600581778523a8b420629f1282d2acfc36af23be F test/windowB.test 6e601f8178ba8ba28b2f19e74fe613815084bb4a8d2ad942defc7d42e191e521 @@ -1913,7 +1913,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 0d77e371c47107f67550e9bedfd26808fcfd84c7473f94b6053f75f0e3463c73 -R 5520b01c6892a5b553d075270b83a75a -U drh -Z da5b9c2841a8220ca7f95ee9ed964538 +P 391c73132c80df944fb49a17d8fe78203c54ac48f968ee9dd9dd8c769c0b4b10 +R 1a3c07521ec89dbf97d54d6a90575f54 +U dan +Z 75dc52bd6cfb538aa08788239a9d470b diff --git a/manifest.uuid b/manifest.uuid index a4786137ab..c42fc68fce 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -391c73132c80df944fb49a17d8fe78203c54ac48f968ee9dd9dd8c769c0b4b10 \ No newline at end of file +4c6cd54a8db78e5535912e76856bed4f797261aaca4248c69d2e2452194de297 \ No newline at end of file diff --git a/src/resolve.c b/src/resolve.c index 4f5c5b9614..d5cec3550a 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -1715,6 +1715,19 @@ static int resolveSelectStep(Walker *pWalker, Select *p){ } } +#ifndef SQLITE_OMIT_WINDOWFUNC + if( IN_RENAME_OBJECT ){ + Window *pWin; + for(pWin=p->pWinDefn; pWin; pWin=pWin->pNextWin){ + if( sqlite3ResolveExprListNames(&sNC, pWin->pOrderBy) + || sqlite3ResolveExprListNames(&sNC, pWin->pPartition) + ){ + return WRC_Abort; + } + } + } +#endif + /* The ORDER BY and GROUP BY clauses may not refer to terms in ** outer queries */ @@ -1771,19 +1784,6 @@ static int resolveSelectStep(Walker *pWalker, Select *p){ } } -#ifndef SQLITE_OMIT_WINDOWFUNC - if( IN_RENAME_OBJECT ){ - Window *pWin; - for(pWin=p->pWinDefn; pWin; pWin=pWin->pNextWin){ - if( sqlite3ResolveExprListNames(&sNC, pWin->pOrderBy) - || sqlite3ResolveExprListNames(&sNC, pWin->pPartition) - ){ - return WRC_Abort; - } - } - } -#endif - /* If this is part of a compound SELECT, check that it has the right ** number of expressions in the select list. */ if( p->pNext && p->pEList->nExpr!=p->pNext->pEList->nExpr ){ diff --git a/src/select.c b/src/select.c index 0f7b6e9ac8..e18333e7b8 100644 --- a/src/select.c +++ b/src/select.c @@ -5213,7 +5213,7 @@ static int resolveFromTermToCte( ** sqlite3SelectExpand() when walking a SELECT tree to resolve table ** names and other FROM clause elements. */ -static void selectPopWith(Walker *pWalker, Select *p){ +void sqlite3SelectPopWith(Walker *pWalker, Select *p){ Parse *pParse = pWalker->pParse; if( OK_IF_ALWAYS_TRUE(pParse->pWith) && p->pPrior==0 ){ With *pWith = findRightmost(p)->pWith; @@ -5223,8 +5223,6 @@ static void selectPopWith(Walker *pWalker, Select *p){ } } } -#else -#define selectPopWith 0 #endif /* @@ -5611,7 +5609,7 @@ static void sqlite3SelectExpand(Parse *pParse, Select *pSelect){ sqlite3WalkSelect(&w, pSelect); } w.xSelectCallback = selectExpander; - w.xSelectCallback2 = selectPopWith; + w.xSelectCallback2 = sqlite3SelectPopWith; w.eCode = 0; sqlite3WalkSelect(&w, pSelect); } diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 5a9bef5156..0f833fca09 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -3886,6 +3886,12 @@ void sqlite3WalkWinDefnDummyCallback(Walker*,Select*); void sqlite3SelectWalkAssert2(Walker*, Select*); #endif +#ifndef SQLITE_OMIT_CTE +void sqlite3SelectPopWith(Walker*, Select*); +#else +# define sqlite3SelectPopWith 0 +#endif + /* ** Return code from the parse-tree walking primitives and their ** callbacks. diff --git a/src/walker.c b/src/walker.c index e0acd5de22..8c0308473a 100644 --- a/src/walker.c +++ b/src/walker.c @@ -140,6 +140,9 @@ int sqlite3WalkSelectExpr(Walker *pWalker, Select *p){ Parse *pParse; if( pWalker->xSelectCallback2==sqlite3WalkWinDefnDummyCallback || ((pParse = pWalker->pParse)!=0 && IN_RENAME_OBJECT) +#ifndef SQLITE_OMIT_CTE + || pWalker->xSelectCallback2==sqlite3SelectPopWith +#endif ){ /* The following may return WRC_Abort if there are unresolvable ** symbols (e.g. a table that does not exist) in a window definition. */ diff --git a/test/altertab.test b/test/altertab.test index d8dd987410..576d391ced 100644 --- a/test/altertab.test +++ b/test/altertab.test @@ -768,4 +768,35 @@ do_execsql_test 26.1 { SELECT * FROM t1x; } {2 1} +#------------------------------------------------------------------------- +reset_db + +do_execsql_test 27.1 { + + create table t_sa ( + c_muyat INTEGER NOT NULL, + c_d4u TEXT + ); + + create table t2 ( abc ); + + CREATE TRIGGER trig AFTER DELETE ON t_sa + BEGIN + DELETE FROM t_sa WHERE ( + SELECT 123 FROM t2 + WINDOW oamat7fzf AS ( PARTITION BY t_sa.c_d4u ) + ); + END; +} + + +breakpoint +do_execsql_test 27.2 { + alter table t_sa rename column c_muyat to c_dg; +} + + + + + finish_test diff --git a/test/window1.test b/test/window1.test index ccf798caa6..a75489a38c 100644 --- a/test/window1.test +++ b/test/window1.test @@ -2090,6 +2090,13 @@ do_catchsql_test 67.1 { SELECT nth_value(a,2) OVER w1 WINDOW w1 AS ( ORDER BY ((SELECT 1 FROM v1)) ) ) +} {1 {no such table: v1}} + +do_catchsql_test 67.2 { + SELECT a,c,b FROM t1 INTERSECT SELECT a,b,c FROM t1 ORDER BY ( + SELECT nth_value(a,2) OVER w1 + WINDOW w1 AS ( ORDER BY ((SELECT 1 FROM t2)) ) + ) } {1 {1st ORDER BY term does not match any column in the result set}} # 2021-05-07 diff --git a/test/window8.tcl b/test/window8.tcl index a8333f1907..d07777d74f 100644 --- a/test/window8.tcl +++ b/test/window8.tcl @@ -418,6 +418,60 @@ execsql_test 7.$tn.9 " " } +========== + +execsql_test 8.0 { + DROP TABLE IF EXISTS tx; + CREATE TABLE tx(a INTEGER PRIMARY KEY); + INSERT INTO tx VALUES(1), (2), (3), (4), (5), (6); + + DROP TABLE IF EXISTS map; + CREATE TABLE map(v INTEGER PRIMARY KEY, t TEXT); + INSERT INTO map VALUES + (1, 'odd'), (2, 'even'), (3, 'odd'), + (4, 'even'), (5, 'odd'), (6, 'even'); +} + +execsql_test 8.1 { + SELECT sum(a) OVER ( + PARTITION BY ( + SELECT t FROM map WHERE v=a + ) ORDER BY a + ) FROM tx; +} + +execsql_test 8.2 { + SELECT sum(a) OVER win FROM tx + WINDOW win AS ( + PARTITION BY ( + SELECT t FROM map WHERE v=a + ) ORDER BY a + ); +} + +execsql_test 8.3 { + WITH map2 AS ( + SELECT * FROM map + ) + SELECT sum(a) OVER ( + PARTITION BY ( + SELECT t FROM map2 WHERE v=a + ) ORDER BY a + ) FROM tx; +} + +execsql_test 8.4 { + WITH map2 AS ( + SELECT * FROM map + ) + SELECT sum(a) OVER win FROM tx + WINDOW win AS ( + PARTITION BY ( + SELECT t FROM map2 WHERE v=a + ) ORDER BY a + ); +} + finish_test diff --git a/test/window8.test b/test/window8.test index ed720ebd41..167cba8e65 100644 --- a/test/window8.test +++ b/test/window8.test @@ -6469,4 +6469,59 @@ do_execsql_test 7.4.9 { ); } {4 4 4 {} {} {}} +#========================================================================== + +do_execsql_test 8.0 { + DROP TABLE IF EXISTS tx; + CREATE TABLE tx(a INTEGER PRIMARY KEY); + INSERT INTO tx VALUES(1), (2), (3), (4), (5), (6); + + DROP TABLE IF EXISTS map; + CREATE TABLE map(v INTEGER PRIMARY KEY, t TEXT); + INSERT INTO map VALUES + (1, 'odd'), (2, 'even'), (3, 'odd'), + (4, 'even'), (5, 'odd'), (6, 'even'); +} {} + +do_execsql_test 8.1 { + SELECT sum(a) OVER ( + PARTITION BY ( + SELECT t FROM map WHERE v=a + ) ORDER BY a + ) FROM tx; +} {2 6 12 1 4 9} + +do_execsql_test 8.2 { + SELECT sum(a) OVER win FROM tx + WINDOW win AS ( + PARTITION BY ( + SELECT t FROM map WHERE v=a + ) ORDER BY a + ); +} {2 6 12 1 4 9} + +do_execsql_test 8.3 { + WITH map2 AS ( + SELECT * FROM map + ) + SELECT sum(a) OVER ( + PARTITION BY ( + SELECT t FROM map2 WHERE v=a + ) ORDER BY a + ) FROM tx; +} {2 6 12 1 4 9} + +breakpoint +do_execsql_test 8.4 { + WITH map2 AS ( + SELECT * FROM map + ) + SELECT sum(a) OVER win FROM tx + WINDOW win AS ( + PARTITION BY ( + SELECT t FROM map2 WHERE v=a + ) ORDER BY a + ); +} {2 6 12 1 4 9} + finish_test