Skip to content

Commit 3809696

Browse files
author
dan
committed
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
1 parent c19e22f commit 3809696

File tree

6 files changed

+51
-11
lines changed

6 files changed

+51
-11
lines changed

Diff for: manifest

+9-9
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
C Fix\spossible\snull\spointer\sdereferences\sin\sthe\sfts5_expr()\sscalar\sfunction.
2-
D 2019-12-09T02:20:37.957
1+
C Avoid\sinfinite\srecursion\sin\sthe\sALTER\sTABLE\scode\swhen\sa\sview\scontains\san\sunused\sCTE\sthat\sreferences,\sdirectly\sor\sindirectly,\sthe\sview\sitself.
2+
D 2019-12-09T08:13:43.318
33
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
44
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
55
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@@ -461,7 +461,7 @@ F spec.template 86a4a43b99ebb3e75e6b9a735d5fd293a24e90ca
461461
F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b
462462
F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786
463463
F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a
464-
F src/alter.c c49548d04914d370864c88ed4b5e3e3b112779ba70562ebd3f191b39be151536
464+
F src/alter.c ef3519bcc3da6e1d8c0bda63233fb315c99f08e8cd74fe3afb9eeaa2b424bfd4
465465
F src/analyze.c b3ceec3fc052df8a96ca8a8c858d455dc5029ba681b4be98bb5c5a9162cfa58c
466466
F src/attach.c b30c44333d55a68c0a12920b5b9d40b254cbd3d4509bda77417209eeed8b3d80
467467
F src/auth.c a3d5bfdba83d25abed1013a8c7a5f204e2e29b0c25242a56bc02bb0c07bf1e06
@@ -471,7 +471,7 @@ F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6
471471
F src/btree.c d22498af716953400e314d2d98d1dac3ea5c3b01e0fd243ef9e9b132c74114ec
472472
F src/btree.h f27a33c49280209a93385e218306c4ee5f46ba8d7649d2f81a7166b282232484
473473
F src/btreeInt.h 91806f01fd1145a9a86ba3042f25c38d8faf6002701bf5e780742cf88bcff437
474-
F src/build.c ed6cc3e7e209d92b0ed2fa780c95b1a3aa7ecdd46a97671cfcca95079789bcc9
474+
F src/build.c 7c277ccc24c249b84f29ba829b0ed377e78487c93d17d999798641be0c20fad5
475475
F src/callback.c 88615dfc0a82167b65b452b4b305dbf86be77200b3343c6ffc6d03e92a01d181
476476
F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e
477477
F src/ctime.c 1b0724e66f95f33b160b1af85caaf9cceb325d22abf39bd24df4f54a73982251
@@ -532,7 +532,7 @@ F src/shell.c.in 4a3a9e1c11847b1904f2b01d087af1c052f660902755abab457cab1756817de
532532
F src/sqlite.h.in 2a23e8161775253d9cf383c2c6aa559005dc787d350dcb0be67a6c4cc3bd1d19
533533
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
534534
F src/sqlite3ext.h 72af51aa4e912e14cd495fb6e7fac65f0940db80ed950d90911aff292cc47ce2
535-
F src/sqliteInt.h daef6c0ec05fdb3dd8ed1b2da6fa2fdce98917dc463a6a65b001f3be5e24ce4c
535+
F src/sqliteInt.h 1ac4dfde728b9d5812d1223d668d5e1f43c6fe4f469d6a7a482f298a10a03210
536536
F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b
537537
F src/status.c 46e7aec11f79dad50965a5ca5fa9de009f7d6bde08be2156f1538a0a296d4d0e
538538
F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34
@@ -637,7 +637,7 @@ F test/altermalloc.test 167a47de41b5c638f5f5c6efb59784002b196fff70f98d9b4ed3cd74
637637
F test/altermalloc2.test fa7b1c1139ea39b8dec407cf1feb032ca8e0076bd429574969b619175ad0174b
638638
F test/altertab.test 4d8b79b0b88b62b90b710390df14fe99e0a3578345526886eaa550e28e3065dc
639639
F test/altertab2.test 8883693952f6d7fb5f754dbf1d694ed780aa883027bef04cb1fb99a3b88c9272
640-
F test/altertab3.test 18111c210a4992abe90247e4a83c6f6e901537288c42879d12680088612d0fa2
640+
F test/altertab3.test 3faf56b3f5af0dd2c12d954db4746521fc96543222da5b6e2633ed417640ce83
641641
F test/amatch1.test b5ae7065f042b7f4c1c922933f4700add50cdb9f
642642
F test/analyze.test 547bb700f903107b38611b014ca645d6b5bb819f5210d7bf39c40802aafeb7d7
643643
F test/analyze3.test 01f0b122e3e54ad2544f14f7cc7dcb4c2cb8753cad5e88c6b8d49615b3fd6a2b
@@ -1852,7 +1852,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
18521852
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
18531853
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
18541854
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
1855-
P 9d75e1ccc72e9f536f45df3b24e9ecd25076cc1f7cf16b806b19e0e1b68e8326
1856-
R 0a0e9aa93d1e91dec7ab207a55b0f9a7
1855+
P c5d44143599f3fe98492b2b900fa3d77925c7be545096251055ceeab899a41f1
1856+
R 22fd1a654a96a45bd7c185276aceb3b2
18571857
U dan
1858-
Z 52b4f37e443381d36a712c3afffc572f
1858+
Z 7090efa7effe7e9fcfeaeecdf4e29b8c

Diff for: manifest.uuid

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
c5d44143599f3fe98492b2b900fa3d77925c7be545096251055ceeab899a41f1
1+
1d2e53a39b87e364685e21de137655b6eee725e4c6d27fc90865072d7c5892b5

Diff for: src/alter.c

+8-1
Original file line numberDiff line numberDiff line change
@@ -760,6 +760,7 @@ static int renameUnmapSelectCb(Walker *pWalker, Select *p){
760760
Parse *pParse = pWalker->pParse;
761761
int i;
762762
if( pParse->nErr ) return WRC_Abort;
763+
if( p->selFlags & SF_View ) return WRC_Prune;
763764
if( ALWAYS(p->pEList) ){
764765
ExprList *pList = p->pEList;
765766
for(i=0; i<pList->nExpr; i++){
@@ -851,6 +852,7 @@ static void renameTokenFind(Parse *pParse, struct RenameCtx *pCtx, void *pPtr){
851852
** descend into sub-select statements.
852853
*/
853854
static int renameColumnSelectCb(Walker *pWalker, Select *p){
855+
if( p->selFlags & SF_View ) return WRC_Prune;
854856
renameWalkWith(pWalker, p);
855857
return WRC_Continue;
856858
}
@@ -1316,8 +1318,9 @@ static void renameColumnFunc(
13161318
if( sParse.pNewTable ){
13171319
Select *pSelect = sParse.pNewTable->pSelect;
13181320
if( pSelect ){
1321+
pSelect->selFlags &= ~SF_View;
13191322
sParse.rc = SQLITE_OK;
1320-
sqlite3SelectPrep(&sParse, sParse.pNewTable->pSelect, 0);
1323+
sqlite3SelectPrep(&sParse, pSelect, 0);
13211324
rc = (db->mallocFailed ? SQLITE_NOMEM : sParse.rc);
13221325
if( rc==SQLITE_OK ){
13231326
sqlite3WalkSelect(&sWalker, pSelect);
@@ -1434,6 +1437,7 @@ static int renameTableSelectCb(Walker *pWalker, Select *pSelect){
14341437
int i;
14351438
RenameCtx *p = pWalker->u.pRename;
14361439
SrcList *pSrc = pSelect->pSrc;
1440+
if( pSelect->selFlags & SF_View ) return WRC_Prune;
14371441
if( pSrc==0 ){
14381442
assert( pWalker->pParse->db->mallocFailed );
14391443
return WRC_Abort;
@@ -1513,10 +1517,13 @@ static void renameTableFunc(
15131517

15141518
if( pTab->pSelect ){
15151519
if( isLegacy==0 ){
1520+
Select *pSelect = pTab->pSelect;
15161521
NameContext sNC;
15171522
memset(&sNC, 0, sizeof(sNC));
15181523
sNC.pParse = &sParse;
15191524

1525+
assert( pSelect->selFlags & SF_View );
1526+
pSelect->selFlags &= ~SF_View;
15201527
sqlite3SelectPrep(&sParse, pTab->pSelect, &sNC);
15211528
if( sParse.nErr ) rc = sParse.rc;
15221529
sqlite3WalkSelect(&sWalker, pTab->pSelect);

Diff for: src/build.c

+1
Original file line numberDiff line numberDiff line change
@@ -2485,6 +2485,7 @@ void sqlite3CreateView(
24852485
** allocated rather than point to the input string - which means that
24862486
** they will persist after the current sqlite3_exec() call returns.
24872487
*/
2488+
pSelect->selFlags |= SF_View;
24882489
if( IN_RENAME_OBJECT ){
24892490
p->pSelect = pSelect;
24902491
pSelect = 0;

Diff for: src/sqliteInt.h

+1
Original file line numberDiff line numberDiff line change
@@ -2956,6 +2956,7 @@ struct Select {
29562956
#define SF_ComplexResult 0x0040000 /* Result contains subquery or function */
29572957
#define SF_WhereBegin 0x0080000 /* Really a WhereBegin() call. Debug Only */
29582958
#define SF_WinRewrite 0x0100000 /* Window function rewrite accomplished */
2959+
#define SF_View 0x0200000 /* SELECT statement is a view */
29592960

29602961
/*
29612962
** The results of a SELECT can be distributed in several ways, as defined

Diff for: test/altertab3.test

+31
Original file line numberDiff line numberDiff line change
@@ -487,5 +487,36 @@ do_execsql_test 21.1 {
487487
ALTER TABLE a RENAME a TO b;
488488
}
489489

490+
#------------------------------------------------------------------------
491+
#
492+
reset_db
493+
do_execsql_test 22.1 {
494+
CREATE TABLE t1(a);
495+
CREATE VIEW v2(b) AS SELECT * FROM v2;
496+
}
497+
498+
do_catchsql_test 22.2 {
499+
ALTER TABLE t1 RENAME TO t4;
500+
} {1 {error in view v2: view v2 is circularly defined}}
501+
502+
do_execsql_test 22.3 {
503+
DROP VIEW v2;
504+
CREATE VIEW v2(b) AS WITH t3 AS (SELECT b FROM v2) SELECT * FROM t3;
505+
}
506+
507+
breakpoint
508+
do_catchsql_test 22.4 {
509+
ALTER TABLE t1 RENAME TO t4;
510+
} {1 {error in view v2: view v2 is circularly defined}}
511+
512+
do_execsql_test 22.5 {
513+
DROP VIEW v2;
514+
CREATE VIEW v2(b) AS WITH t3 AS (SELECT b FROM v2) VALUES(1);
515+
}
516+
517+
do_catchsql_test 22.6 {
518+
ALTER TABLE t1 RENAME TO t4;
519+
} {0 {}}
520+
490521

491522
finish_test

0 commit comments

Comments
 (0)