From: dan Date: Tue, 17 Mar 2026 11:17:54 +0000 (+0000) Subject: Change the sqlite3VdbeFindDeleteKey() routine so that all index fields that are not... X-Git-Tag: major-release~74^2~17 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=022f2f96bca61d6f21e1b5aee0870058bf8f6c11;p=thirdparty%2Fsqlite.git Change the sqlite3VdbeFindDeleteKey() routine so that all index fields that are not expressions or virtual columns must match the table for the delete to succeed. FossilOrigin-Name: eccd9fcfa7e34ddcdeb671544c6afac7aa0d4665c5e1df7c8e53c41387ed0386 --- diff --git a/manifest b/manifest index c7c3cd89c7..8a8f30db66 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\strunk\senhancements\sinto\sthe\sidxdelete-tolerance\sbranch -D 2026-03-17T09:53:02.101 +C Change\sthe\ssqlite3VdbeFindDeleteKey()\sroutine\sso\sthat\sall\sindex\sfields\sthat\sare\snot\sexpressions\sor\svirtual\scolumns\smust\smatch\sthe\stable\sfor\sthe\sdelete\sto\ssucceed. +D 2026-03-17T11:17:54.759 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -682,7 +682,7 @@ F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/date.c 61e92f1f7e2e88e1cd91e91dc69eb2b2854e7877254470f9fabd776bfac922b8 F src/dbpage.c c9ea81c11727f27e02874611e92773e68e2a90a875ef2404b084564c235fd91f F src/dbstat.c 73362c0df0f40ad5523a6f5501224959d0976757b511299bf892313e79d14f5c -F src/delete.c cc318f7e5e9d9606c3600c7af96e836597f0f4d77ff7914ef03c5f906f4a43b4 +F src/delete.c 39258c930aabe3e4949cfa634f27684a1a4dd27fbd3c0e151bc968d007d1f84f F src/expr.c 51e9c77ff5d9a21439e611fe6571a3cd50387e526e13c5614fd407e5b8571930 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 931f74cec1dc8038a0217ef340c91ce147dd1bbed08dc40c47ee0ec6edfffb08 @@ -799,11 +799,11 @@ F src/upsert.c 215328c3f91623c520ec8672c44323553f12caeb4f01b1090ebdca99fdf7b4f1 F src/utf.c 7267c3fb9e2467020507601af3354c2446c61f444387e094c779dccd5ca62165 F src/util.c cf91389b58590edfb5978199ef59488ef8e3723e1ba1aa0ff15c62f8a658b95f F src/vacuum.c d3d35d8ae893d419ade5fa196d761a83bddcbb62137a1a157ae751ef38b26e82 -F src/vdbe.c 31ca4aaad332c3b973c5fb74bc76972a856fcb99c581e68efc35b6e9299a6d6c -F src/vdbe.h 966d0677a540b7ea6549b7c4e1312fc0d830fce3a235a58c801f2cc31cf5ecf9 -F src/vdbeInt.h 68d4adddb1eb48cdbaff8cce1305ac6bc5ad9115f1a37087a13d01a045303e7a +F src/vdbe.c 8442ec7a77cca0b8c465bfcc57b1f548865aec44e8cf16aa21adb6772a2803b5 +F src/vdbe.h fd7a85ab0d538db5c036b06c9c2e6493d6df4b22ce6f7c3ef64799d71fbbaa1c +F src/vdbeInt.h e876d6c5fd5f2eee4d818d49dabd615c88147a131f773edf5bd329e5b66cd365 F src/vdbeapi.c 6cdcbe5c7afa754c998e73d2d5d2805556268362914b952811bdfb9c78a37cf1 -F src/vdbeaux.c f2f97545ace70c7d3171b3a38c6313e59c317916370a74fc82fadf0c924e6e79 +F src/vdbeaux.c 34641d8268fcf86434eb8fe7d0afb4bcd858e0107c2df3f341e7e76c25eb3bc9 F src/vdbeblob.c b3f0640db9642fbdc88bd6ebcc83d6009514cafc98f062f675f2c8d505d82692 F src/vdbemem.c 317ec5e870ddb16951b606c9fe8be22baef22ecbe46f58fdefc259662238afb7 F src/vdbesort.c b69220f4ea9ffea5fdef34d968c60305444eea909252a81933b54c296d9cca70 @@ -1081,7 +1081,7 @@ F test/e_wal.test db7c33642711cf3c7959714b5f012aca08cacfa78da0382f95e849eb3ba66a F test/e_walauto.test 248af31e73c98df23476a22bdb815524c9dc3ba8 F test/e_walckpt.test 16e7d006e8687654ee59e7ad5a6d285ba23f0fe0eeb87f790afd6bc9cf1d1924 F test/e_walhook.test 01b494287ba9e60b70f6ebf3c6c62e0ffe01788e344a4846b08e5de0b344cb66 -F test/eiib1.test b1e4361242f6215dd82ca3903bbec7832f1085f68bbf9d4d773ab0fbc71e924c +F test/eiib1.test 92df1db7db9ba2024e4151019caf0d2f00b7855b548e8df4e773ec963b6fbe0c F test/emptytable.test a38110becbdfa6325cd65cb588dca658cd885f62 F test/enc.test b5503a87b31cea8a5084c6e447383f9ca08933bd2f29d97b6b6201081b2343eb F test/enc2.test 872afe58db772e7dfa1ad8e0759f8cc820e9efc8172d460fae83023101c2e435 @@ -2194,8 +2194,8 @@ F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee F tool/warnings.sh d924598cf2f55a4ecbc2aeb055c10bd5f48114793e7ba25f9585435da29e7e98 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f F tool/winmain.c 00c8fb88e365c9017db14c73d3c78af62194d9644feaf60e220ab0f411f3604c -P f66cb3dc275d3f31e57576466e697a6c7c5179144babab08d75b624e9846ecc3 704ddfd0df57c2b137af88264df20a540e3f8f114a58ae5e31b40ab8259bb63e -R 1a6d1a6d80f42677ecead1da6c93305a -U drh -Z 4d0938105db2727fa5b7a43131c4525b +P 5f5ab3eb3618b6a2799355df50bfdf94121161f7cadba6253963036d9f284f08 +R 3a87a584039b1feb9335e171078664f3 +U dan +Z 85992f44adf014214f0cee4e807ed494 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 8412866476..537c8aa23c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5f5ab3eb3618b6a2799355df50bfdf94121161f7cadba6253963036d9f284f08 +eccd9fcfa7e34ddcdeb671544c6afac7aa0d4665c5e1df7c8e53c41387ed0386 diff --git a/src/delete.c b/src/delete.c index 8507da9dab..e89a8c8e96 100644 --- a/src/delete.c +++ b/src/delete.c @@ -922,8 +922,10 @@ void sqlite3GenerateRowIndexDelete( VdbeModuleComment((v, "GenRowIdxDel for %s", pIdx->zName)); r1 = sqlite3GenerateIndexKey(pParse, pIdx, iDataCur, 0, 1, &iPartIdxLabel, pPrior, r1); - sqlite3VdbeAddOp4Int(v, OP_IdxDelete, iIdxCur+i, r1, - pIdx->uniqNotNull ? pIdx->nKeyCol : pIdx->nColumn, pIdx->nKeyCol); + sqlite3VdbeAddOp3(v, OP_IdxDelete, iIdxCur+i, r1, + pIdx->uniqNotNull ? pIdx->nKeyCol : pIdx->nColumn + ); + sqlite3VdbeChangeP4(v, -1, pIdx, P4_INDEX); sqlite3ResolvePartIdxLabel(pParse, iPartIdxLabel); pPrior = pIdx; } diff --git a/src/vdbe.c b/src/vdbe.c index 34e325eec2..b643f1e1e9 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -6629,7 +6629,7 @@ case OP_SorterInsert: { /* in2 */ ** an unpacked index key. This opcode removes that entry from the ** index opened by cursor P1. ** -** P4 is the number of non-PK columns in the index entry. +** P4 is a pointer to an Index structure. ** ** Raise an SQLITE_CORRUPT_INDEX error if no matching index entry is found ** and not in writable_schema mode. @@ -6656,7 +6656,7 @@ case OP_IdxDelete: { rc = sqlite3BtreeIndexMoveto(pCrsr, &r, &res); if( rc ) goto abort_due_to_error; if( res!=0 ){ - rc = sqlite3VdbeFindDeleteKey(pCrsr, pOp->p4.i, &r, &res); + rc = sqlite3VdbeFindDeleteKey(pCrsr, pOp->p4.pIdx, &r, &res); if( rc!=SQLITE_OK ) goto abort_due_to_error; if( res!=0 ){ if( !sqlite3WritableSchema(db) ){ diff --git a/src/vdbe.h b/src/vdbe.h index a2905eae4d..312feb3dcc 100644 --- a/src/vdbe.h +++ b/src/vdbe.h @@ -75,6 +75,7 @@ struct VdbeOp { SubProgram *pProgram; /* Used when p4type is P4_SUBPROGRAM */ Table *pTab; /* Used when p4type is P4_TABLE */ SubrtnSig *pSubrtnSig; /* Used when p4type is P4_SUBRTNSIG */ + Index *pIdx; /* Used when p4type is P4_INDEX */ #ifdef SQLITE_ENABLE_CURSOR_HINTS Expr *pExpr; /* Used when p4type is P4_EXPR */ #endif @@ -129,20 +130,21 @@ typedef struct VdbeOpList VdbeOpList; #define P4_INT32 (-3) /* P4 is a 32-bit signed integer */ #define P4_SUBPROGRAM (-4) /* P4 is a pointer to a SubProgram structure */ #define P4_TABLE (-5) /* P4 is a pointer to a Table structure */ +#define P4_INDEX (-6) /* P4 is a pointer to an Index structure */ /* Above do not own any resources. Must free those below */ #define P4_FREE_IF_LE (-6) -#define P4_DYNAMIC (-6) /* Pointer to memory from sqliteMalloc() */ -#define P4_FUNCDEF (-7) /* P4 is a pointer to a FuncDef structure */ -#define P4_KEYINFO (-8) /* P4 is a pointer to a KeyInfo structure */ -#define P4_EXPR (-9) /* P4 is a pointer to an Expr tree */ -#define P4_MEM (-10) /* P4 is a pointer to a Mem* structure */ -#define P4_VTAB (-11) /* P4 is a pointer to an sqlite3_vtab structure */ -#define P4_REAL (-12) /* P4 is a 64-bit floating point value */ -#define P4_INT64 (-13) /* P4 is a 64-bit signed integer */ -#define P4_INTARRAY (-14) /* P4 is a vector of 32-bit integers */ -#define P4_FUNCCTX (-15) /* P4 is a pointer to an sqlite3_context object */ -#define P4_TABLEREF (-16) /* Like P4_TABLE, but reference counted */ -#define P4_SUBRTNSIG (-17) /* P4 is a SubrtnSig pointer */ +#define P4_DYNAMIC (-7) /* Pointer to memory from sqliteMalloc() */ +#define P4_FUNCDEF (-8) /* P4 is a pointer to a FuncDef structure */ +#define P4_KEYINFO (-9) /* P4 is a pointer to a KeyInfo structure */ +#define P4_EXPR (-10) /* P4 is a pointer to an Expr tree */ +#define P4_MEM (-11) /* P4 is a pointer to a Mem* structure */ +#define P4_VTAB (-12) /* P4 is a pointer to an sqlite3_vtab structure */ +#define P4_REAL (-13) /* P4 is a 64-bit floating point value */ +#define P4_INT64 (-14) /* P4 is a 64-bit signed integer */ +#define P4_INTARRAY (-15) /* P4 is a vector of 32-bit integers */ +#define P4_FUNCCTX (-16) /* P4 is a pointer to an sqlite3_context object */ +#define P4_TABLEREF (-17) /* Like P4_TABLE, but reference counted */ +#define P4_SUBRTNSIG (-18) /* P4 is a SubrtnSig pointer */ /* Error message codes for OP_Halt */ #define P5_ConstraintNotNull 1 diff --git a/src/vdbeInt.h b/src/vdbeInt.h index eb29631801..57f4714155 100644 --- a/src/vdbeInt.h +++ b/src/vdbeInt.h @@ -687,7 +687,7 @@ void sqlite3VdbePreUpdateHook( Vdbe*,VdbeCursor*,int,const char*,Table*,i64,int,int); #endif int sqlite3VdbeTransferError(Vdbe *p); -int sqlite3VdbeFindDeleteKey(BtCursor*, int, UnpackedRecord*, int*); +int sqlite3VdbeFindDeleteKey(BtCursor*, Index*, UnpackedRecord*, int*); int sqlite3VdbeSorterInit(sqlite3 *, int, VdbeCursor *); void sqlite3VdbeSorterReset(sqlite3 *, VdbeSorter *); diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 839d59981a..09e18790af 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -5395,14 +5395,14 @@ void sqlite3VdbeSetVarmask(Vdbe *v, int iVar){ /* ** This function compares the unpacked record with the current key that -** cursor pCur points to, ignoring the first nKeyCol fields. It returns -** the usual less than zero, zero, or greater than zero if the remaining -** fields of the cursor cursor key are less than, equal to or greater -** than those in (*p). +** cursor pCur points to, ignoring any fields for which the corresponding +** bit in parameter "mask" is set. Return the usual less than zero, zero, or +** greater than zero if the remaining fields of the cursor cursor key are less +** than, equal to or greater than those in (*p). */ static int vdbeIsDeleteKey( BtCursor *pCur, /* Cursor open on index */ - int nKeyCol, + Bitmask mask, UnpackedRecord *p, /* Index key being deleted */ int *piRes /* 0 for a match, non-zero for not a match */ ){ @@ -5443,7 +5443,7 @@ static int vdbeIsDeleteKey( nSerial = sqlite3VdbeSerialTypeLen(iSerial); if( (idxRec+nSerial)>nRec ){ rc = SQLITE_CORRUPT_BKPT; - }else if( ii>=nKeyCol ){ + }else if( ii>=BMS || (mask & MASKBIT(ii))==0 ){ sqlite3VdbeSerialGet(&aRec[idxRec], iSerial, &mem); res = sqlite3MemCompare(&mem, &p->aMem[ii], p->pKeyInfo->aColl[ii]); if( res!=0 ) break; @@ -5482,7 +5482,7 @@ static int vdbeIsDeleteKey( */ int sqlite3VdbeFindDeleteKey( BtCursor *pCur, - int nKeyCol, + Index *pIdx, UnpackedRecord *p, int *pRes ){ @@ -5492,42 +5492,62 @@ int sqlite3VdbeFindDeleteKey( int rc = SQLITE_OK; int ii = 0; - /* Move the cursor back BTREE_FDK_RANGE entries. If this hits an EOF, - ** position the cursor at the first entry in the index and set nStep - ** to -1 so that the first loop below scans the entire index. Otherwise, - ** set nStep to BTREE_FDK_RANGE*2 so that the first loop below scans - ** just that many entries. */ - for(ii=0; sqlite3BtreeEof(pCur)==0 && iinColumn, BMS); ii++){ + int iCol = pIdx->aiColumn[ii]; + if( (iCol==XN_EXPR) + || (iCol>=0 && (pIdx->pTable->aCol[iCol].colFlags & COLFLAG_VIRTUAL)) + ){ + mask |= MASKBIT(ii); + } } - /* This loop runs at most twice to search for a key with matching PK - ** fields in the index. The second iteration always searches the entire - ** index. The first iteration searches nStep entries starting with the - ** current cursor entry if (nStep>=0), or the entire index if (nStep<0). */ - while( 1 ){ - for(ii=0; rc==SQLITE_OK && (ii=0), or the entire index if (nStep<0). */ + while( 1 ){ + for(ii=0; rc==SQLITE_OK && (ii