From: drh <> Date: Thu, 29 Feb 2024 19:40:38 +0000 (+0000) Subject: Attempt to fix multi-object DROP. Working better, but still not perfect. X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=c3004fc223ec9dd812dad7dc4ff5834f2064fec3;p=thirdparty%2Fsqlite.git Attempt to fix multi-object DROP. Working better, but still not perfect. FossilOrigin-Name: 02f9fc73eef80f528097581580977aae46942baac2d7fb205c52f7f25472f2a8 --- diff --git a/manifest b/manifest index 8e933bf204..84a66be780 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\sability\sto\sDROP\sone\sor\smore\sobjects\sof\sthe\ssame\sclass\nin\sa\ssingle\sstatement\sby\slisting\sthe\sobjects\sas\smultiple\sarguments\sto\sthe\nDROP\scommand. -D 2024-02-29T13:44:15.183 +C Attempt\sto\sfix\smulti-object\sDROP.\s\sWorking\sbetter,\sbut\sstill\snot\sperfect. +D 2024-02-29T19:40:38.822 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -692,7 +692,7 @@ F src/btmutex.c 79a43670447eacc651519a429f6ece9fd638563cf95b469d6891185ddae2b522 F src/btree.c 285b493d843e7ba8ef78b6ae7d31238e904901dbc0c484f7904de4cf18fd8802 F src/btree.h 55066f513eb095db935169dab1dc2f7c7a747ef223c533f5d4ad4dfed346cbd0 F src/btreeInt.h 98aadb6dcb77b012cab2574d6a728fad56b337fc946839b9898c4b4c969e30b6 -F src/build.c 786e47a8ccefa14fbdca52e22bc51dbe24074a9c7dbe4f2afd2050736a7352c5 +F src/build.c 25384963d1b9d6ebc73777bc7c1112973ba36ea8a8ca9f0a39bd94c047ba24eb F src/callback.c db3a45e376deff6a16c0058163fe0ae2b73a2945f3f408ca32cf74960b28d490 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 23331529e654be40ca97d171cbbffe9b3d4c71cc53b78fe5501230675952da8b @@ -702,7 +702,7 @@ F src/dbstat.c 3b677254d512fcafd4d0b341bf267b38b235ccfddbef24f9154e19360fa22e43 F src/delete.c cb766727c78e715f9fb7ec8a7d03658ed2a3016343ca687acfcec9083cdca500 F src/expr.c 2803f5e7e3458ced24c0de48ec3640cd7a68ec61350d99c9f30b1bcd6640bd61 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 -F src/fkey.c a47610f0a5c6cb0ad79f8fcef039c01833dec0c751bb695f28dc0ec6a4c3ba00 +F src/fkey.c b7ecbc98b4da91d03e3435ca6abc167efa30f6691b090820969c4be625739e45 F src/func.c 4204c56196847faefef57fa14e43b8e4d65eb8d7e65318abe463472e3fd148cb F src/global.c 765a0656d6cbf043cb272ff0ae38f39cc46713539ffe6793258ed3eb4b188b52 F src/hash.c 9ee4269fb1d6632a6fecfb9479c93a1f29271bddbbaf215dd60420bcb80c7220 @@ -755,7 +755,7 @@ F src/shell.c.in 2ec564ed3ff0147036be313efeb47b3dbfb8753d5eb5ea0e90636427c6b3a36 F src/sqlite.h.in 19a2db3995a699bd7f6dfb423856242bfceb7ec849a93c91d241d19fc28d9f0f F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 3f046c04ea3595d6bfda99b781926b17e672fd6d27da2ba6d8d8fc39981dcb54 -F src/sqliteInt.h 58b7295a748ca5ed9e211510205b4a66a24c68f864225b81e19d4cf6038b40a1 +F src/sqliteInt.h bdb0bba047cd39c8733c14131c379a91f3d1f437c57f11270db14860ab09dffd F src/sqliteLimit.h 6878ab64bdeb8c24a1d762d45635e34b96da21132179023338c93f820eee6728 F src/status.c cb11f8589a6912af2da3bb1ec509a94dd8ef27df4d4c1a97e0bcf2309ece972b F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 @@ -814,7 +814,7 @@ F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c F src/tokenize.c 3f703cacdab728d7741e5a6ac242006d74fe1c2754d4f03ed889d7253259bd68 F src/treeview.c c6fc972683fd00f975d8b32a81c1f25d2fb7d4035366bf45c9f5622d3ccd70ee -F src/trigger.c a23049b9771927763ade8389fb6a0494324bad15394893895f6aa4e346e6b295 +F src/trigger.c a6fd09ef8b4613db9b9db046ff5abacda4bf517a09da889031d22c7c18ac6c49 F src/update.c 6904814dd62a7a93bbb86d9f1419c7f134a9119582645854ab02b36b676d9f92 F src/upsert.c fa125a8d3410ce9a97b02cb50f7ae68a2476c405c76aa692d3acf6b8586e9242 F src/utf.c f23165685a67b4caf8ec08fb274cb3f319103decfb2a980b7cfd55d18dfa855e @@ -1069,7 +1069,7 @@ F test/diskfull.test 106391384780753ea6896b7b4f005d10e9866b6e F test/distinct.test 691c9e850b0d0b56b66e7e235453198cb4cf0760e324b7403d3c5abbeab0a014 F test/distinct2.test bb71cc7b5e58e895787f9910a788c254f679928d324732d063fe9bc202ecbe71 F test/distinctagg.test 40d7169ae5846caaf62c6e307d2ca3c333daf9b6f7cde888956a339a97afe85f -F test/drop-many.test 30dd091a4fd0a04b1a38e70c93f69c55749e62a3d895ac5e09277cd97caa5bbf w test/drop1.test +F test/drop-many.test 30dd091a4fd0a04b1a38e70c93f69c55749e62a3d895ac5e09277cd97caa5bbf F test/e_blobbytes.test 4c01dfe4f12087b92b20705a3fdfded45dc4ed16d5a211fed4e1d2786ba68a52 F test/e_blobclose.test 692fc02a058476c2222a63d97e3f3b2b809c1842e5525ded7f854d540ac2e075 F test/e_blobopen.test 29f6055ee453b8e679fe9570c4d3acfedbef821622c5dad16875148c5952ef50 @@ -2177,8 +2177,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 803481f25020f3c25941f1e7d1a8071937820dea951e8798198b0b0fa3fb48ce -R b06b7d333b1bcab630a4dab891f8b26c +P 2266086cf08ee710338667d1cf0b1e81ce7380101707db272ce27124404068a0 +R d3490d0df600a6062bf18828bf499fc3 U drh -Z 594e686b84606bfb7b18560464880c6c +Z 68bbccadbf2f82f26c1558f6e4711d24 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index c56c4d0e0a..7cbde21282 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2266086cf08ee710338667d1cf0b1e81ce7380101707db272ce27124404068a0 \ No newline at end of file +02f9fc73eef80f528097581580977aae46942baac2d7fb205c52f7f25472f2a8 \ No newline at end of file diff --git a/src/build.c b/src/build.c index 9302e0d195..dbad644304 100644 --- a/src/build.c +++ b/src/build.c @@ -3477,11 +3477,11 @@ static int tableMayNotBeDropped(sqlite3 *db, Table *pTab){ */ void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView, int noErr){ Table *pTab; - Vdbe *v; sqlite3 *db = pParse->db; int iDb; int ii; + (void)sqlite3GetVdbe(pParse); sqlite3ReadSchema(pParse); assert( pName!=0 || pParse->nErr!=0 ); for(ii=0; pParse->nErr==0 && iinSrc; ii++){ @@ -3572,17 +3572,41 @@ void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView, int noErr){ break; } #endif + /* If this table or view has appeared previously in the list of tables + ** or views to be dropped, then the prior appearance is sufficient so + ** skip this one. */ + if( ii>0 ){ + int jj; + for(jj=0; jja[jj].pTab!=pTab; jj++){} + if( jja[ii].pTab = pTab; + pTab->nTabRef++; + } + + for(ii=0; pParse->nErr==0 && iinSrc; ii++){ + pTab = pName->a[ii].pTab; + if( pTab ){ + iDb = sqlite3SchemaToIndex(db, pTab->pSchema); + + /* Generate code to clear this table from sqlite_statN and to + ** cascade foreign key constraints. + */ sqlite3BeginWriteOperation(pParse, 1, iDb); - if( !isView ){ + if( IsOrdinaryTable(pTab) ){ sqlite3ClearStatTables(pParse, iDb, "tbl", pTab->zName); - sqlite3FkDropTable(pParse, pName, pTab); + sqlite3FkDropTable(pParse, &pName->a[ii], pTab); } + } + } + + /* Generate code to actually delete the tables/views in a second pass. */ + for(ii=0; pParse->nErr==0 && iinSrc; ii++){ + pTab = pName->a[ii].pTab; + if( pTab ){ + iDb = sqlite3SchemaToIndex(db, pTab->pSchema); sqlite3CodeDropTable(pParse, pTab, iDb, isView); } } @@ -4586,8 +4610,8 @@ void sqlite3DefaultRowEst(Index *pIdx){ */ void sqlite3DropIndex(Parse *pParse, SrcList *pName, int ifExists){ Index *pIndex; - Vdbe *v; sqlite3 *db = pParse->db; + Vdbe *v; int iDb; int ii; @@ -4635,20 +4659,32 @@ void sqlite3DropIndex(Parse *pParse, SrcList *pName, int ifExists){ } #endif + /* Skip over redundant DROP INDEXes */ + if( ii>0 ){ + int jj; + for(jj=0; jja[jj].addrFillSub!=iDb ) continue; + if( pName->a[jj].regReturn!=pIndex->tnum ) continue; + break; + } + if( jja[ii].addrFillSub = iDb; + pName->a[ii].regReturn = pIndex->tnum; + /* Generate code to remove the index and from the schema table */ v = sqlite3GetVdbe(pParse); - if( v ){ - sqlite3BeginWriteOperation(pParse, 1, iDb); - sqlite3NestedParse(pParse, - "DELETE FROM %Q." LEGACY_SCHEMA_TABLE - " WHERE name=%Q AND type='index'", - db->aDb[iDb].zDbSName, pIndex->zName - ); - sqlite3ClearStatTables(pParse, iDb, "idx", pIndex->zName); - sqlite3ChangeCookie(pParse, iDb); - destroyRootPage(pParse, pIndex->tnum, iDb); - sqlite3VdbeAddOp4(v, OP_DropIndex, iDb, 0, 0, pIndex->zName, 0); - } + if( v==0 ) break; + sqlite3BeginWriteOperation(pParse, 1, iDb); + sqlite3NestedParse(pParse, + "DELETE FROM %Q." LEGACY_SCHEMA_TABLE + " WHERE name=%Q AND type='index'", + db->aDb[iDb].zDbSName, pIndex->zName + ); + sqlite3ClearStatTables(pParse, iDb, "idx", pIndex->zName); + sqlite3ChangeCookie(pParse, iDb); + destroyRootPage(pParse, pIndex->tnum, iDb); + sqlite3VdbeAddOp4(v, OP_DropIndex, iDb, 0, 0, pIndex->zName, 0); } sqlite3SrcListDelete(db, pName); } diff --git a/src/fkey.c b/src/fkey.c index bace1ae5e2..82c25b67da 100644 --- a/src/fkey.c +++ b/src/fkey.c @@ -732,11 +732,12 @@ void sqlite3FkClearTriggerCache(sqlite3 *db, int iDb){ ** the table from the database. Triggers are disabled while running this ** DELETE, but foreign key actions are not. */ -void sqlite3FkDropTable(Parse *pParse, SrcList *pName, Table *pTab){ +void sqlite3FkDropTable(Parse *pParse, SrcItem *pName, Table *pTab){ sqlite3 *db = pParse->db; if( (db->flags&SQLITE_ForeignKeys) && IsOrdinaryTable(pTab) ){ int iSkip = 0; Vdbe *v = sqlite3GetVdbe(pParse); + SrcList *pSrc; assert( v ); /* VDBE has already been allocated */ assert( IsOrdinaryTable(pTab) ); @@ -756,7 +757,12 @@ void sqlite3FkDropTable(Parse *pParse, SrcList *pName, Table *pTab){ } pParse->disableTriggers = 1; - sqlite3DeleteFrom(pParse, sqlite3SrcListDup(db, pName, 0), 0, 0, 0); + pSrc = sqlite3SrcListAppend(pParse, 0, 0, 0); + if( pSrc ){ + pSrc->a[0].zDatabase = sqlite3DbStrDup(db, pName->zDatabase); + pSrc->a[0].zName = sqlite3DbStrDup(db, pName->zName); + sqlite3DeleteFrom(pParse, pSrc, 0, 0, 0); + } pParse->disableTriggers = 0; /* If the DELETE has generated immediate foreign key constraint diff --git a/src/sqliteInt.h b/src/sqliteInt.h index f5920748ba..9a9a13f376 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -3314,6 +3314,7 @@ struct SrcItem { union { Index *pIBIndex; /* Index structure corresponding to u1.zIndexedBy */ CteUse *pCteUse; /* CTE Usage info when fg.isCte is true */ + Trigger *pTrig; /* Trigger in argument list of DROP TRIGGER */ } u2; }; @@ -5574,7 +5575,7 @@ const char *sqlite3JournalModename(int); */ #if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER) void sqlite3FkCheck(Parse*, Table*, int, int, int*, int); - void sqlite3FkDropTable(Parse*, SrcList *, Table*); + void sqlite3FkDropTable(Parse*, SrcItem*, Table*); void sqlite3FkActions(Parse*, Table*, ExprList*, int, int*, int); int sqlite3FkRequired(Parse*, Table*, int*, int); u32 sqlite3FkOldmask(Parse*, Table*); diff --git a/src/trigger.c b/src/trigger.c index c388bacfbe..8fe95c32c7 100644 --- a/src/trigger.c +++ b/src/trigger.c @@ -639,6 +639,7 @@ void sqlite3DropTrigger(Parse *pParse, SrcList *pName, int noErr){ pTrigger = sqlite3HashFind(&(db->aDb[j].pSchema->trigHash), zName); if( pTrigger ) break; } + pName->a[ii].u2.pTrig = pTrigger; if( !pTrigger ){ if( !noErr ){ sqlite3ErrorMsg(pParse, "no such trigger: %S", pName->a+ii); @@ -648,9 +649,16 @@ void sqlite3DropTrigger(Parse *pParse, SrcList *pName, int noErr){ testcase( ii>0 ); testcase( ii+1nSrc ); pParse->checkSchema = 1; - }else{ - sqlite3DropTriggerPtr(pParse, pTrigger); + continue; + } + if( ii>0 ){ + int jj; + for(jj=0; jja[jj].u2.pTrig==pTrigger ) break; + } + if( jj