From: dan Date: Mon, 9 Dec 2019 08:13:43 +0000 (+0000) Subject: Avoid infinite recursion in the ALTER TABLE code when a view contains an unused CTE... X-Git-Tag: version-3.31.0~247 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=38096961c7cd109110ac21d3ed7dad7e0cb0ae06;p=thirdparty%2Fsqlite.git Avoid infinite recursion in the ALTER TABLE code when a view contains an unused CTE that references, directly or indirectly, the view itself. FossilOrigin-Name: 1d2e53a39b87e364685e21de137655b6eee725e4c6d27fc90865072d7c5892b5 --- diff --git a/manifest b/manifest index ff838aa5c8..39c8f9b321 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\spossible\snull\spointer\sdereferences\sin\sthe\sfts5_expr()\sscalar\sfunction. -D 2019-12-09T02:20:37.957 +C Avoid\sinfinite\srecursion\sin\sthe\sALTER\sTABLE\scode\swhen\sa\sview\scontains\san\sunused\sCTE\sthat\sreferences,\sdirectly\sor\sindirectly,\sthe\sview\sitself. +D 2019-12-09T08:13:43.318 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -461,7 +461,7 @@ F spec.template 86a4a43b99ebb3e75e6b9a735d5fd293a24e90ca F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a -F src/alter.c c49548d04914d370864c88ed4b5e3e3b112779ba70562ebd3f191b39be151536 +F src/alter.c ef3519bcc3da6e1d8c0bda63233fb315c99f08e8cd74fe3afb9eeaa2b424bfd4 F src/analyze.c b3ceec3fc052df8a96ca8a8c858d455dc5029ba681b4be98bb5c5a9162cfa58c F src/attach.c b30c44333d55a68c0a12920b5b9d40b254cbd3d4509bda77417209eeed8b3d80 F src/auth.c a3d5bfdba83d25abed1013a8c7a5f204e2e29b0c25242a56bc02bb0c07bf1e06 @@ -471,7 +471,7 @@ F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 F src/btree.c d22498af716953400e314d2d98d1dac3ea5c3b01e0fd243ef9e9b132c74114ec F src/btree.h f27a33c49280209a93385e218306c4ee5f46ba8d7649d2f81a7166b282232484 F src/btreeInt.h 91806f01fd1145a9a86ba3042f25c38d8faf6002701bf5e780742cf88bcff437 -F src/build.c ed6cc3e7e209d92b0ed2fa780c95b1a3aa7ecdd46a97671cfcca95079789bcc9 +F src/build.c 7c277ccc24c249b84f29ba829b0ed377e78487c93d17d999798641be0c20fad5 F src/callback.c 88615dfc0a82167b65b452b4b305dbf86be77200b3343c6ffc6d03e92a01d181 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 1b0724e66f95f33b160b1af85caaf9cceb325d22abf39bd24df4f54a73982251 @@ -532,7 +532,7 @@ F src/shell.c.in 4a3a9e1c11847b1904f2b01d087af1c052f660902755abab457cab1756817de F src/sqlite.h.in 2a23e8161775253d9cf383c2c6aa559005dc787d350dcb0be67a6c4cc3bd1d19 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 72af51aa4e912e14cd495fb6e7fac65f0940db80ed950d90911aff292cc47ce2 -F src/sqliteInt.h daef6c0ec05fdb3dd8ed1b2da6fa2fdce98917dc463a6a65b001f3be5e24ce4c +F src/sqliteInt.h 1ac4dfde728b9d5812d1223d668d5e1f43c6fe4f469d6a7a482f298a10a03210 F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b F src/status.c 46e7aec11f79dad50965a5ca5fa9de009f7d6bde08be2156f1538a0a296d4d0e F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34 @@ -637,7 +637,7 @@ F test/altermalloc.test 167a47de41b5c638f5f5c6efb59784002b196fff70f98d9b4ed3cd74 F test/altermalloc2.test fa7b1c1139ea39b8dec407cf1feb032ca8e0076bd429574969b619175ad0174b F test/altertab.test 4d8b79b0b88b62b90b710390df14fe99e0a3578345526886eaa550e28e3065dc F test/altertab2.test 8883693952f6d7fb5f754dbf1d694ed780aa883027bef04cb1fb99a3b88c9272 -F test/altertab3.test 18111c210a4992abe90247e4a83c6f6e901537288c42879d12680088612d0fa2 +F test/altertab3.test 3faf56b3f5af0dd2c12d954db4746521fc96543222da5b6e2633ed417640ce83 F test/amatch1.test b5ae7065f042b7f4c1c922933f4700add50cdb9f F test/analyze.test 547bb700f903107b38611b014ca645d6b5bb819f5210d7bf39c40802aafeb7d7 F test/analyze3.test 01f0b122e3e54ad2544f14f7cc7dcb4c2cb8753cad5e88c6b8d49615b3fd6a2b @@ -1852,7 +1852,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 9d75e1ccc72e9f536f45df3b24e9ecd25076cc1f7cf16b806b19e0e1b68e8326 -R 0a0e9aa93d1e91dec7ab207a55b0f9a7 +P c5d44143599f3fe98492b2b900fa3d77925c7be545096251055ceeab899a41f1 +R 22fd1a654a96a45bd7c185276aceb3b2 U dan -Z 52b4f37e443381d36a712c3afffc572f +Z 7090efa7effe7e9fcfeaeecdf4e29b8c diff --git a/manifest.uuid b/manifest.uuid index 12ca3fd406..5ae7f863d6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c5d44143599f3fe98492b2b900fa3d77925c7be545096251055ceeab899a41f1 \ No newline at end of file +1d2e53a39b87e364685e21de137655b6eee725e4c6d27fc90865072d7c5892b5 \ No newline at end of file diff --git a/src/alter.c b/src/alter.c index ff885e3d19..48fa527562 100644 --- a/src/alter.c +++ b/src/alter.c @@ -760,6 +760,7 @@ static int renameUnmapSelectCb(Walker *pWalker, Select *p){ Parse *pParse = pWalker->pParse; int i; if( pParse->nErr ) return WRC_Abort; + if( p->selFlags & SF_View ) return WRC_Prune; if( ALWAYS(p->pEList) ){ ExprList *pList = p->pEList; for(i=0; inExpr; i++){ @@ -851,6 +852,7 @@ static void renameTokenFind(Parse *pParse, struct RenameCtx *pCtx, void *pPtr){ ** descend into sub-select statements. */ static int renameColumnSelectCb(Walker *pWalker, Select *p){ + if( p->selFlags & SF_View ) return WRC_Prune; renameWalkWith(pWalker, p); return WRC_Continue; } @@ -1316,8 +1318,9 @@ static void renameColumnFunc( if( sParse.pNewTable ){ Select *pSelect = sParse.pNewTable->pSelect; if( pSelect ){ + pSelect->selFlags &= ~SF_View; sParse.rc = SQLITE_OK; - sqlite3SelectPrep(&sParse, sParse.pNewTable->pSelect, 0); + sqlite3SelectPrep(&sParse, pSelect, 0); rc = (db->mallocFailed ? SQLITE_NOMEM : sParse.rc); if( rc==SQLITE_OK ){ sqlite3WalkSelect(&sWalker, pSelect); @@ -1434,6 +1437,7 @@ static int renameTableSelectCb(Walker *pWalker, Select *pSelect){ int i; RenameCtx *p = pWalker->u.pRename; SrcList *pSrc = pSelect->pSrc; + if( pSelect->selFlags & SF_View ) return WRC_Prune; if( pSrc==0 ){ assert( pWalker->pParse->db->mallocFailed ); return WRC_Abort; @@ -1513,10 +1517,13 @@ static void renameTableFunc( if( pTab->pSelect ){ if( isLegacy==0 ){ + Select *pSelect = pTab->pSelect; NameContext sNC; memset(&sNC, 0, sizeof(sNC)); sNC.pParse = &sParse; + assert( pSelect->selFlags & SF_View ); + pSelect->selFlags &= ~SF_View; sqlite3SelectPrep(&sParse, pTab->pSelect, &sNC); if( sParse.nErr ) rc = sParse.rc; sqlite3WalkSelect(&sWalker, pTab->pSelect); diff --git a/src/build.c b/src/build.c index 46bf3677e1..171cc68cf4 100644 --- a/src/build.c +++ b/src/build.c @@ -2485,6 +2485,7 @@ void sqlite3CreateView( ** allocated rather than point to the input string - which means that ** they will persist after the current sqlite3_exec() call returns. */ + pSelect->selFlags |= SF_View; if( IN_RENAME_OBJECT ){ p->pSelect = pSelect; pSelect = 0; diff --git a/src/sqliteInt.h b/src/sqliteInt.h index b870bffcfb..2aca2abfa9 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2956,6 +2956,7 @@ struct Select { #define SF_ComplexResult 0x0040000 /* Result contains subquery or function */ #define SF_WhereBegin 0x0080000 /* Really a WhereBegin() call. Debug Only */ #define SF_WinRewrite 0x0100000 /* Window function rewrite accomplished */ +#define SF_View 0x0200000 /* SELECT statement is a view */ /* ** The results of a SELECT can be distributed in several ways, as defined diff --git a/test/altertab3.test b/test/altertab3.test index d684884bca..7103a810b5 100644 --- a/test/altertab3.test +++ b/test/altertab3.test @@ -487,5 +487,36 @@ do_execsql_test 21.1 { ALTER TABLE a RENAME a TO b; } +#------------------------------------------------------------------------ +# +reset_db +do_execsql_test 22.1 { + CREATE TABLE t1(a); + CREATE VIEW v2(b) AS SELECT * FROM v2; +} + +do_catchsql_test 22.2 { + ALTER TABLE t1 RENAME TO t4; +} {1 {error in view v2: view v2 is circularly defined}} + +do_execsql_test 22.3 { + DROP VIEW v2; + CREATE VIEW v2(b) AS WITH t3 AS (SELECT b FROM v2) SELECT * FROM t3; +} + +breakpoint +do_catchsql_test 22.4 { + ALTER TABLE t1 RENAME TO t4; +} {1 {error in view v2: view v2 is circularly defined}} + +do_execsql_test 22.5 { + DROP VIEW v2; + CREATE VIEW v2(b) AS WITH t3 AS (SELECT b FROM v2) VALUES(1); +} + +do_catchsql_test 22.6 { + ALTER TABLE t1 RENAME TO t4; +} {0 {}} + finish_test