mirror of
https://github.com/sqlite/sqlite.git
synced 2025-11-06 15:49:35 +03:00
Add the logic to keep partial indices up to date through DML statements and
when new partial indices are created. This new logic is untested except to verify that it does not interfere with full indices. FossilOrigin-Name: fb9044d15ad4fd6ae4a38858c0c0e6fe9d4faa25
This commit is contained in:
28
manifest
28
manifest
@@ -1,5 +1,5 @@
|
|||||||
C Add\slogic\sto\sthe\squery\splanner\sto\sonly\suse\spartial\sindices\sif\sthe\sWHERE\sclause\nconstrains\sthe\ssearch\sto\srows\scovered\sby\sthe\spartial\sindex.\s\sThis\sis\sjust\ninfrastructure.\s\sThe\skey\sroutine,\ssqlite3ExprImpliesExpr(),\sis\scurrently\sa\nno-op\sso\sthat\spartial\sindices\swill\snever\sbe\sused.
|
C Add\sthe\slogic\sto\skeep\spartial\sindices\sup\sto\sdate\sthrough\sDML\sstatements\sand\nwhen\snew\spartial\sindices\sare\screated.\s\sThis\snew\slogic\sis\suntested\sexcept\sto\nverify\sthat\sit\sdoes\snot\sinterfere\swith\sfull\sindices.
|
||||||
D 2013-07-31T23:22:39.876
|
D 2013-08-01T01:14:43.210
|
||||||
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
||||||
F Makefile.in 5e41da95d92656a5004b03d3576e8b226858a28e
|
F Makefile.in 5e41da95d92656a5004b03d3576e8b226858a28e
|
||||||
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
||||||
@@ -166,13 +166,13 @@ F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7
|
|||||||
F src/btree.c 3f7bbfd72efb1cbf6a49515c376a031767ec930a
|
F src/btree.c 3f7bbfd72efb1cbf6a49515c376a031767ec930a
|
||||||
F src/btree.h 6fa8a3ff2483d0bb64a9f0105a8cedeac9e00cca
|
F src/btree.h 6fa8a3ff2483d0bb64a9f0105a8cedeac9e00cca
|
||||||
F src/btreeInt.h eecc84f02375b2bb7a44abbcbbe3747dde73edb2
|
F src/btreeInt.h eecc84f02375b2bb7a44abbcbbe3747dde73edb2
|
||||||
F src/build.c f1ef982f38df47b11e10edaf03fbcc77b80e4d35
|
F src/build.c 9422ab5fe5f3ea21575b50c182ebf2081253bed0
|
||||||
F src/callback.c d7e46f40c3cf53c43550b7da7a1d0479910b62cc
|
F src/callback.c d7e46f40c3cf53c43550b7da7a1d0479910b62cc
|
||||||
F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac
|
F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac
|
||||||
F src/ctime.c 4262c227bc91cecc61ae37ed3a40f08069cfa267
|
F src/ctime.c 4262c227bc91cecc61ae37ed3a40f08069cfa267
|
||||||
F src/date.c 067a81c9942c497aafd2c260e13add8a7d0c7dd4
|
F src/date.c 067a81c9942c497aafd2c260e13add8a7d0c7dd4
|
||||||
F src/delete.c aeabdabeeeaa0584127f291baa9617153d334778
|
F src/delete.c 2317c814866d9aa71fea16b3faf4fdd4d6a49b94
|
||||||
F src/expr.c 8a5e78f47c4919bd53c2ef3c652088d71d5c4d79
|
F src/expr.c 299f1de324676599b818e587b77e683978514461
|
||||||
F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
|
F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
|
||||||
F src/fkey.c 914a6bbd987d857c41ac9d244efa6641f36faadb
|
F src/fkey.c 914a6bbd987d857c41ac9d244efa6641f36faadb
|
||||||
F src/func.c 5c50c1ea31fd864b0fe921fe1a8d4c55acd609ef
|
F src/func.c 5c50c1ea31fd864b0fe921fe1a8d4c55acd609ef
|
||||||
@@ -180,7 +180,7 @@ F src/global.c 5caf4deab621abb45b4c607aad1bd21c20aac759
|
|||||||
F src/hash.c ac3470bbf1ca4ae4e306a8ecb0fdf1731810ffe4
|
F src/hash.c ac3470bbf1ca4ae4e306a8ecb0fdf1731810ffe4
|
||||||
F src/hash.h 8890a25af81fb85a9ad7790d32eedab4b994da22
|
F src/hash.h 8890a25af81fb85a9ad7790d32eedab4b994da22
|
||||||
F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08
|
F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08
|
||||||
F src/insert.c f7cb141e8ce257cb6b15c497f09e4e23d6055599
|
F src/insert.c 1e2eb1d4150c57f41dda8719f1b5ccb28abdacc2
|
||||||
F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d
|
F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d
|
||||||
F src/legacy.c 0df0b1550b9cc1f58229644735e317ac89131f12
|
F src/legacy.c 0df0b1550b9cc1f58229644735e317ac89131f12
|
||||||
F src/lempar.c cdf0a000315332fc9b50b62f3b5e22e080a0952b
|
F src/lempar.c cdf0a000315332fc9b50b62f3b5e22e080a0952b
|
||||||
@@ -210,7 +210,7 @@ F src/parse.y a950b48d4363f44dd98fef8a89fbd48970ebd9ce
|
|||||||
F src/pcache.c f8043b433a57aba85384a531e3937a804432a346
|
F src/pcache.c f8043b433a57aba85384a531e3937a804432a346
|
||||||
F src/pcache.h a5e4f5d9f5d592051d91212c5949517971ae6222
|
F src/pcache.h a5e4f5d9f5d592051d91212c5949517971ae6222
|
||||||
F src/pcache1.c d23d07716de96c7c0c2503ec5051a4384c3fb938
|
F src/pcache1.c d23d07716de96c7c0c2503ec5051a4384c3fb938
|
||||||
F src/pragma.c 2790c5175bc3f95d2a0cf39283d144b9b012fec7
|
F src/pragma.c f8936b23ce3eeddff4ab868c726d1546a6674418
|
||||||
F src/prepare.c fa6988589f39af8504a61731614cd4f6ae71554f
|
F src/prepare.c fa6988589f39af8504a61731614cd4f6ae71554f
|
||||||
F src/printf.c 41c49dac366a3a411190001a8ab495fa8887974e
|
F src/printf.c 41c49dac366a3a411190001a8ab495fa8887974e
|
||||||
F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50
|
F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50
|
||||||
@@ -221,7 +221,7 @@ F src/shell.c 52f975eae87c8338c4dfbf4c2842d2a0971f01fd
|
|||||||
F src/sqlite.h.in d6a7523d6795317aac574fccc67d9df25253771c
|
F src/sqlite.h.in d6a7523d6795317aac574fccc67d9df25253771c
|
||||||
F src/sqlite3.rc fea433eb0a59f4c9393c8e6d76a6e2596b1fe0c0
|
F src/sqlite3.rc fea433eb0a59f4c9393c8e6d76a6e2596b1fe0c0
|
||||||
F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc
|
F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc
|
||||||
F src/sqliteInt.h 911e2fe9bbd45c394e6396a1c00a8539285f82e6
|
F src/sqliteInt.h b69d7bac8a7fea89f11558f0659324f0551b0868
|
||||||
F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d
|
F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d
|
||||||
F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158
|
F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158
|
||||||
F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e
|
F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e
|
||||||
@@ -273,7 +273,7 @@ F src/test_vfstrace.c 34b544e80ba7fb77be15395a609c669df2e660a2
|
|||||||
F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
|
F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
|
||||||
F src/tokenize.c e0e8fd3cb90a88451f6b6425726c84747b6b20d7
|
F src/tokenize.c e0e8fd3cb90a88451f6b6425726c84747b6b20d7
|
||||||
F src/trigger.c 5c0ea9b8755e7c5e1a700f3e27ac4f8d92dd221e
|
F src/trigger.c 5c0ea9b8755e7c5e1a700f3e27ac4f8d92dd221e
|
||||||
F src/update.c 8e76c3d03e4b7b21cb250bd2df0c05e12993e577
|
F src/update.c 7f3fe64d8f3b44c44a1eac293f0f85f87c355b7a
|
||||||
F src/utf.c 8d819e2e5104a430fc2005f018db14347c95a38f
|
F src/utf.c 8d819e2e5104a430fc2005f018db14347c95a38f
|
||||||
F src/util.c f566b5138099a2df8533b190d0dcc74b7dfbe0c9
|
F src/util.c f566b5138099a2df8533b190d0dcc74b7dfbe0c9
|
||||||
F src/vacuum.c d9c5759f4c5a438bb43c2086f72c5d2edabc36c8
|
F src/vacuum.c d9c5759f4c5a438bb43c2086f72c5d2edabc36c8
|
||||||
@@ -281,7 +281,7 @@ F src/vdbe.c d6048a720c197db2f0e7d618e918bd2e2eff0322
|
|||||||
F src/vdbe.h f380af2a7fab32ba8a8b05bf042497636afec66d
|
F src/vdbe.h f380af2a7fab32ba8a8b05bf042497636afec66d
|
||||||
F src/vdbeInt.h e9b7c6b165a31a4715c5aa97223d20d265515231
|
F src/vdbeInt.h e9b7c6b165a31a4715c5aa97223d20d265515231
|
||||||
F src/vdbeapi.c 4d13580bd058b39623e8fcfc233b7df4b8191e8b
|
F src/vdbeapi.c 4d13580bd058b39623e8fcfc233b7df4b8191e8b
|
||||||
F src/vdbeaux.c c01594ecf5a78ef41a721f3465152bb91883a942
|
F src/vdbeaux.c 75206d58c2e1ea7ed2758106d591ff7a082ea909
|
||||||
F src/vdbeblob.c 5dc79627775bd9a9b494dd956e26297946417d69
|
F src/vdbeblob.c 5dc79627775bd9a9b494dd956e26297946417d69
|
||||||
F src/vdbemem.c 833005f1cbbf447289f1973dba2a0c2228c7b8ab
|
F src/vdbemem.c 833005f1cbbf447289f1973dba2a0c2228c7b8ab
|
||||||
F src/vdbesort.c 3937e06b2a0e354500e17dc206ef4c35770a5017
|
F src/vdbesort.c 3937e06b2a0e354500e17dc206ef4c35770a5017
|
||||||
@@ -290,7 +290,7 @@ F src/vtab.c 2e8b489db47e20ae36cd247932dc671c9ded0624
|
|||||||
F src/wal.c 7dc3966ef98b74422267e7e6e46e07ff6c6eb1b4
|
F src/wal.c 7dc3966ef98b74422267e7e6e46e07ff6c6eb1b4
|
||||||
F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4
|
F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4
|
||||||
F src/walker.c 4fa43583d0a84b48f93b1e88f11adf2065be4e73
|
F src/walker.c 4fa43583d0a84b48f93b1e88f11adf2065be4e73
|
||||||
F src/where.c afa338426730378f3d0aa9b24218462b6cca31f3
|
F src/where.c 14d48fe735a7d5f4d610d8b9396a9e7752539199
|
||||||
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
|
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
|
||||||
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
|
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
|
||||||
F test/aggnested.test 45c0201e28045ad38a530b5a144b73cd4aa2cfd6
|
F test/aggnested.test 45c0201e28045ad38a530b5a144b73cd4aa2cfd6
|
||||||
@@ -1104,7 +1104,7 @@ F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
|
|||||||
F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381
|
F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381
|
||||||
F tool/wherecosttest.c f407dc4c79786982a475261866a161cd007947ae
|
F tool/wherecosttest.c f407dc4c79786982a475261866a161cd007947ae
|
||||||
F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac
|
F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac
|
||||||
P f2aa7842c8b9df24294f09e2bde27b3f08c455c7
|
P 8ca3eac111e06a1854f878a74bffe8f20eb47f1b
|
||||||
R 7502b7f00f8eb060c8cfe6d979c2a415
|
R 9dc930e0b891070c4f237bde08c1f247
|
||||||
U drh
|
U drh
|
||||||
Z 8c5239fd3bb5391973b43192e175e4ae
|
Z dd655b435ca4957c549da40144eccbfa
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
8ca3eac111e06a1854f878a74bffe8f20eb47f1b
|
fb9044d15ad4fd6ae4a38858c0c0e6fe9d4faa25
|
||||||
@@ -2374,6 +2374,7 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){
|
|||||||
int addr1; /* Address of top of loop */
|
int addr1; /* Address of top of loop */
|
||||||
int addr2; /* Address to jump to for next iteration */
|
int addr2; /* Address to jump to for next iteration */
|
||||||
int tnum; /* Root page of index */
|
int tnum; /* Root page of index */
|
||||||
|
int iPartIdxLabel; /* Jump to this label to skip a row */
|
||||||
Vdbe *v; /* Generate code into this virtual machine */
|
Vdbe *v; /* Generate code into this virtual machine */
|
||||||
KeyInfo *pKey; /* KeyInfo for index */
|
KeyInfo *pKey; /* KeyInfo for index */
|
||||||
int regRecord; /* Register holding assemblied index record */
|
int regRecord; /* Register holding assemblied index record */
|
||||||
@@ -2413,8 +2414,9 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){
|
|||||||
addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iTab, 0);
|
addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iTab, 0);
|
||||||
regRecord = sqlite3GetTempReg(pParse);
|
regRecord = sqlite3GetTempReg(pParse);
|
||||||
|
|
||||||
sqlite3GenerateIndexKey(pParse, pIndex, iTab, regRecord, 1);
|
sqlite3GenerateIndexKey(pParse, pIndex, iTab, regRecord, 1, &iPartIdxLabel);
|
||||||
sqlite3VdbeAddOp2(v, OP_SorterInsert, iSorter, regRecord);
|
sqlite3VdbeAddOp2(v, OP_SorterInsert, iSorter, regRecord);
|
||||||
|
sqlite3VdbeResolveLabel(v, iPartIdxLabel);
|
||||||
sqlite3VdbeAddOp2(v, OP_Next, iTab, addr1+1);
|
sqlite3VdbeAddOp2(v, OP_Next, iTab, addr1+1);
|
||||||
sqlite3VdbeJumpHere(v, addr1);
|
sqlite3VdbeJumpHere(v, addr1);
|
||||||
addr1 = sqlite3VdbeAddOp2(v, OP_SorterSort, iSorter, 0);
|
addr1 = sqlite3VdbeAddOp2(v, OP_SorterSort, iSorter, 0);
|
||||||
@@ -2843,7 +2845,7 @@ Index *sqlite3CreateIndex(
|
|||||||
** has just been created, it contains no data and the index initialization
|
** has just been created, it contains no data and the index initialization
|
||||||
** step can be skipped.
|
** step can be skipped.
|
||||||
*/
|
*/
|
||||||
else{ /* if( db->init.busy==0 ) */
|
else if( pParse->nErr==0 ){
|
||||||
Vdbe *v;
|
Vdbe *v;
|
||||||
char *zStmt;
|
char *zStmt;
|
||||||
int iMem = ++pParse->nMem;
|
int iMem = ++pParse->nMem;
|
||||||
|
|||||||
27
src/delete.c
27
src/delete.c
@@ -591,11 +591,14 @@ void sqlite3GenerateRowIndexDelete(
|
|||||||
int i;
|
int i;
|
||||||
Index *pIdx;
|
Index *pIdx;
|
||||||
int r1;
|
int r1;
|
||||||
|
int iPartIdxLabel;
|
||||||
|
Vdbe *v = pParse->pVdbe;
|
||||||
|
|
||||||
for(i=1, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){
|
for(i=1, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){
|
||||||
if( aRegIdx!=0 && aRegIdx[i-1]==0 ) continue;
|
if( aRegIdx!=0 && aRegIdx[i-1]==0 ) continue;
|
||||||
r1 = sqlite3GenerateIndexKey(pParse, pIdx, iCur, 0, 0);
|
r1 = sqlite3GenerateIndexKey(pParse, pIdx, iCur, 0, 0, &iPartIdxLabel);
|
||||||
sqlite3VdbeAddOp3(pParse->pVdbe, OP_IdxDelete, iCur+i, r1,pIdx->nColumn+1);
|
sqlite3VdbeAddOp3(v, OP_IdxDelete, iCur+i, r1, pIdx->nColumn+1);
|
||||||
|
sqlite3VdbeResolveLabel(v, iPartIdxLabel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -609,13 +612,21 @@ void sqlite3GenerateRowIndexDelete(
|
|||||||
** registers that holds the elements of the index key. The
|
** registers that holds the elements of the index key. The
|
||||||
** block of registers has already been deallocated by the time
|
** block of registers has already been deallocated by the time
|
||||||
** this routine returns.
|
** this routine returns.
|
||||||
|
**
|
||||||
|
** If *piPartIdxLabel is not NULL, fill it in with a label and jump
|
||||||
|
** to that label if pIdx is a partial index that should be skipped.
|
||||||
|
** A partial index should be skipped if its WHERE clause evaluates
|
||||||
|
** to false or null. If pIdx is not a partial index, *piPartIdxLabel
|
||||||
|
** will be set to zero which is an empty label that is ignored by
|
||||||
|
** sqlite3VdbeResolveLabel().
|
||||||
*/
|
*/
|
||||||
int sqlite3GenerateIndexKey(
|
int sqlite3GenerateIndexKey(
|
||||||
Parse *pParse, /* Parsing context */
|
Parse *pParse, /* Parsing context */
|
||||||
Index *pIdx, /* The index for which to generate a key */
|
Index *pIdx, /* The index for which to generate a key */
|
||||||
int iCur, /* Cursor number for the pIdx->pTable table */
|
int iCur, /* Cursor number for the pIdx->pTable table */
|
||||||
int regOut, /* Write the new index key to this register */
|
int regOut, /* Write the new index key to this register */
|
||||||
int doMakeRec /* Run the OP_MakeRecord instruction if true */
|
int doMakeRec, /* Run the OP_MakeRecord instruction if true */
|
||||||
|
int *piPartIdxLabel /* OUT: Jump to this label to skip partial index */
|
||||||
){
|
){
|
||||||
Vdbe *v = pParse->pVdbe;
|
Vdbe *v = pParse->pVdbe;
|
||||||
int j;
|
int j;
|
||||||
@@ -623,6 +634,16 @@ int sqlite3GenerateIndexKey(
|
|||||||
int regBase;
|
int regBase;
|
||||||
int nCol;
|
int nCol;
|
||||||
|
|
||||||
|
if( piPartIdxLabel ){
|
||||||
|
if( pIdx->pPartIdxWhere ){
|
||||||
|
*piPartIdxLabel = sqlite3VdbeMakeLabel(v);
|
||||||
|
pParse->iPartIdxTab = iCur;
|
||||||
|
sqlite3ExprIfFalse(pParse, pIdx->pPartIdxWhere, *piPartIdxLabel,
|
||||||
|
SQLITE_JUMPIFNULL);
|
||||||
|
}else{
|
||||||
|
*piPartIdxLabel = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
nCol = pIdx->nColumn;
|
nCol = pIdx->nColumn;
|
||||||
regBase = sqlite3GetTempRange(pParse, nCol+1);
|
regBase = sqlite3GetTempRange(pParse, nCol+1);
|
||||||
sqlite3VdbeAddOp2(v, OP_Rowid, iCur, regBase+nCol);
|
sqlite3VdbeAddOp2(v, OP_Rowid, iCur, regBase+nCol);
|
||||||
|
|||||||
17
src/expr.c
17
src/expr.c
@@ -2362,15 +2362,20 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){
|
|||||||
/* Otherwise, fall thru into the TK_COLUMN case */
|
/* Otherwise, fall thru into the TK_COLUMN case */
|
||||||
}
|
}
|
||||||
case TK_COLUMN: {
|
case TK_COLUMN: {
|
||||||
if( pExpr->iTable<0 ){
|
int iTab = pExpr->iTable;
|
||||||
/* This only happens when coding check constraints */
|
if( iTab<0 ){
|
||||||
assert( pParse->ckBase>0 );
|
if( pParse->ckBase>0 ){
|
||||||
|
/* Generating CHECK constraints or inserting into partial index */
|
||||||
inReg = pExpr->iColumn + pParse->ckBase;
|
inReg = pExpr->iColumn + pParse->ckBase;
|
||||||
|
break;
|
||||||
}else{
|
}else{
|
||||||
inReg = sqlite3ExprCodeGetColumn(pParse, pExpr->pTab,
|
/* Deleting from a partial index */
|
||||||
pExpr->iColumn, pExpr->iTable, target,
|
iTab = pParse->iPartIdxTab;
|
||||||
pExpr->op2);
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
inReg = sqlite3ExprCodeGetColumn(pParse, pExpr->pTab,
|
||||||
|
pExpr->iColumn, iTab, target,
|
||||||
|
pExpr->op2);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TK_INTEGER: {
|
case TK_INTEGER: {
|
||||||
|
|||||||
22
src/insert.c
22
src/insert.c
@@ -1379,9 +1379,19 @@ void sqlite3GenerateConstraintChecks(
|
|||||||
for(iCur=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, iCur++){
|
for(iCur=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, iCur++){
|
||||||
int regIdx;
|
int regIdx;
|
||||||
int regR;
|
int regR;
|
||||||
|
int addrSkipRow = 0;
|
||||||
|
|
||||||
if( aRegIdx[iCur]==0 ) continue; /* Skip unused indices */
|
if( aRegIdx[iCur]==0 ) continue; /* Skip unused indices */
|
||||||
|
|
||||||
|
if( pIdx->pPartIdxWhere ){
|
||||||
|
sqlite3VdbeAddOp2(v, OP_Null, 0, aRegIdx[iCur]);
|
||||||
|
addrSkipRow = sqlite3VdbeMakeLabel(v);
|
||||||
|
pParse->ckBase = regData;
|
||||||
|
sqlite3ExprIfFalse(pParse, pIdx->pPartIdxWhere, addrSkipRow,
|
||||||
|
SQLITE_JUMPIFNULL);
|
||||||
|
pParse->ckBase = 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Create a key for accessing the index entry */
|
/* Create a key for accessing the index entry */
|
||||||
regIdx = sqlite3GetTempRange(pParse, pIdx->nColumn+1);
|
regIdx = sqlite3GetTempRange(pParse, pIdx->nColumn+1);
|
||||||
for(i=0; i<pIdx->nColumn; i++){
|
for(i=0; i<pIdx->nColumn; i++){
|
||||||
@@ -1470,6 +1480,7 @@ void sqlite3GenerateConstraintChecks(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
sqlite3VdbeJumpHere(v, j3);
|
sqlite3VdbeJumpHere(v, j3);
|
||||||
|
sqlite3VdbeResolveLabel(v, addrSkipRow);
|
||||||
sqlite3ReleaseTempReg(pParse, regR);
|
sqlite3ReleaseTempReg(pParse, regR);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1499,7 +1510,6 @@ void sqlite3CompleteInsertion(
|
|||||||
){
|
){
|
||||||
int i;
|
int i;
|
||||||
Vdbe *v;
|
Vdbe *v;
|
||||||
int nIdx;
|
|
||||||
Index *pIdx;
|
Index *pIdx;
|
||||||
u8 pik_flags;
|
u8 pik_flags;
|
||||||
int regData;
|
int regData;
|
||||||
@@ -1508,9 +1518,11 @@ void sqlite3CompleteInsertion(
|
|||||||
v = sqlite3GetVdbe(pParse);
|
v = sqlite3GetVdbe(pParse);
|
||||||
assert( v!=0 );
|
assert( v!=0 );
|
||||||
assert( pTab->pSelect==0 ); /* This table is not a VIEW */
|
assert( pTab->pSelect==0 ); /* This table is not a VIEW */
|
||||||
for(nIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nIdx++){}
|
for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
|
||||||
for(i=nIdx-1; i>=0; i--){
|
|
||||||
if( aRegIdx[i]==0 ) continue;
|
if( aRegIdx[i]==0 ) continue;
|
||||||
|
if( pIdx->pPartIdxWhere ){
|
||||||
|
sqlite3VdbeAddOp2(v, OP_IsNull, aRegIdx[i], sqlite3VdbeCurrentAddr(v)+2);
|
||||||
|
}
|
||||||
sqlite3VdbeAddOp2(v, OP_IdxInsert, baseCur+i+1, aRegIdx[i]);
|
sqlite3VdbeAddOp2(v, OP_IdxInsert, baseCur+i+1, aRegIdx[i]);
|
||||||
if( useSeekResult ){
|
if( useSeekResult ){
|
||||||
sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
|
sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
|
||||||
@@ -1612,6 +1624,7 @@ static int xferCompatibleCollation(const char *z1, const char *z2){
|
|||||||
** * The same DESC and ASC markings occurs on all columns
|
** * The same DESC and ASC markings occurs on all columns
|
||||||
** * The same onError processing (OE_Abort, OE_Ignore, etc)
|
** * The same onError processing (OE_Abort, OE_Ignore, etc)
|
||||||
** * The same collating sequence on each column
|
** * The same collating sequence on each column
|
||||||
|
** * The index has the exact same WHERE clause
|
||||||
*/
|
*/
|
||||||
static int xferCompatibleIndex(Index *pDest, Index *pSrc){
|
static int xferCompatibleIndex(Index *pDest, Index *pSrc){
|
||||||
int i;
|
int i;
|
||||||
@@ -1634,6 +1647,9 @@ static int xferCompatibleIndex(Index *pDest, Index *pSrc){
|
|||||||
return 0; /* Different collating sequences */
|
return 0; /* Different collating sequences */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if( sqlite3ExprCompare(pSrc->pPartIdxWhere, pDest->pPartIdxWhere) ){
|
||||||
|
return 0; /* Different WHERE clauses */
|
||||||
|
}
|
||||||
|
|
||||||
/* If no test above fails then the indices must be compatible */
|
/* If no test above fails then the indices must be compatible */
|
||||||
return 1;
|
return 1;
|
||||||
|
|||||||
@@ -1432,7 +1432,7 @@ void sqlite3Pragma(
|
|||||||
loopTop = sqlite3VdbeAddOp2(v, OP_Rewind, 1, 0);
|
loopTop = sqlite3VdbeAddOp2(v, OP_Rewind, 1, 0);
|
||||||
sqlite3VdbeAddOp2(v, OP_AddImm, 2, 1); /* increment entry count */
|
sqlite3VdbeAddOp2(v, OP_AddImm, 2, 1); /* increment entry count */
|
||||||
for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
|
for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
|
||||||
int jmp2;
|
int jmp2, jmp3;
|
||||||
int r1;
|
int r1;
|
||||||
static const VdbeOpList idxErr[] = {
|
static const VdbeOpList idxErr[] = {
|
||||||
{ OP_AddImm, 1, -1, 0},
|
{ OP_AddImm, 1, -1, 0},
|
||||||
@@ -1447,7 +1447,7 @@ void sqlite3Pragma(
|
|||||||
{ OP_IfPos, 1, 0, 0}, /* 9 */
|
{ OP_IfPos, 1, 0, 0}, /* 9 */
|
||||||
{ OP_Halt, 0, 0, 0},
|
{ OP_Halt, 0, 0, 0},
|
||||||
};
|
};
|
||||||
r1 = sqlite3GenerateIndexKey(pParse, pIdx, 1, 3, 0);
|
r1 = sqlite3GenerateIndexKey(pParse, pIdx, 1, 3, 0, &jmp3);
|
||||||
jmp2 = sqlite3VdbeAddOp4Int(v, OP_Found, j+2, 0, r1, pIdx->nColumn+1);
|
jmp2 = sqlite3VdbeAddOp4Int(v, OP_Found, j+2, 0, r1, pIdx->nColumn+1);
|
||||||
addr = sqlite3VdbeAddOpList(v, ArraySize(idxErr), idxErr);
|
addr = sqlite3VdbeAddOpList(v, ArraySize(idxErr), idxErr);
|
||||||
sqlite3VdbeChangeP4(v, addr+1, "rowid ", P4_STATIC);
|
sqlite3VdbeChangeP4(v, addr+1, "rowid ", P4_STATIC);
|
||||||
@@ -1455,6 +1455,7 @@ void sqlite3Pragma(
|
|||||||
sqlite3VdbeChangeP4(v, addr+4, pIdx->zName, P4_TRANSIENT);
|
sqlite3VdbeChangeP4(v, addr+4, pIdx->zName, P4_TRANSIENT);
|
||||||
sqlite3VdbeJumpHere(v, addr+9);
|
sqlite3VdbeJumpHere(v, addr+9);
|
||||||
sqlite3VdbeJumpHere(v, jmp2);
|
sqlite3VdbeJumpHere(v, jmp2);
|
||||||
|
sqlite3VdbeResolveLabel(v, jmp3);
|
||||||
}
|
}
|
||||||
sqlite3VdbeAddOp2(v, OP_Next, 1, loopTop+1);
|
sqlite3VdbeAddOp2(v, OP_Next, 1, loopTop+1);
|
||||||
sqlite3VdbeJumpHere(v, loopTop);
|
sqlite3VdbeJumpHere(v, loopTop);
|
||||||
|
|||||||
@@ -2204,6 +2204,7 @@ struct Parse {
|
|||||||
int nSet; /* Number of sets used so far */
|
int nSet; /* Number of sets used so far */
|
||||||
int nOnce; /* Number of OP_Once instructions so far */
|
int nOnce; /* Number of OP_Once instructions so far */
|
||||||
int ckBase; /* Base register of data during check constraints */
|
int ckBase; /* Base register of data during check constraints */
|
||||||
|
int iPartIdxTab; /* Table corresponding to a partial index */
|
||||||
int iCacheLevel; /* ColCache valid when aColCache[].iLevel<=iCacheLevel */
|
int iCacheLevel; /* ColCache valid when aColCache[].iLevel<=iCacheLevel */
|
||||||
int iCacheCnt; /* Counter used to generate aColCache[].lru values */
|
int iCacheCnt; /* Counter used to generate aColCache[].lru values */
|
||||||
struct yColCache {
|
struct yColCache {
|
||||||
@@ -2862,7 +2863,7 @@ int sqlite3ExprNeedsNoAffinityChange(const Expr*, char);
|
|||||||
int sqlite3IsRowid(const char*);
|
int sqlite3IsRowid(const char*);
|
||||||
void sqlite3GenerateRowDelete(Parse*, Table*, int, int, int, Trigger *, int);
|
void sqlite3GenerateRowDelete(Parse*, Table*, int, int, int, Trigger *, int);
|
||||||
void sqlite3GenerateRowIndexDelete(Parse*, Table*, int, int*);
|
void sqlite3GenerateRowIndexDelete(Parse*, Table*, int, int*);
|
||||||
int sqlite3GenerateIndexKey(Parse*, Index*, int, int, int);
|
int sqlite3GenerateIndexKey(Parse*, Index*, int, int, int, int*);
|
||||||
void sqlite3GenerateConstraintChecks(Parse*,Table*,int,int,
|
void sqlite3GenerateConstraintChecks(Parse*,Table*,int,int,
|
||||||
int*,int,int,int,int,int*);
|
int*,int,int,int,int,int*);
|
||||||
void sqlite3CompleteInsertion(Parse*, Table*, int, int, int*, int, int, int);
|
void sqlite3CompleteInsertion(Parse*, Table*, int, int, int*, int, int, int);
|
||||||
|
|||||||
@@ -246,7 +246,7 @@ void sqlite3Update(
|
|||||||
}
|
}
|
||||||
for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
|
for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
|
||||||
int reg;
|
int reg;
|
||||||
if( hasFK || chngRowid ){
|
if( hasFK || chngRowid || pIdx->pPartIdxWhere ){
|
||||||
reg = ++pParse->nMem;
|
reg = ++pParse->nMem;
|
||||||
}else{
|
}else{
|
||||||
reg = 0;
|
reg = 0;
|
||||||
|
|||||||
@@ -250,8 +250,8 @@ int sqlite3VdbeMakeLabel(Vdbe *p){
|
|||||||
void sqlite3VdbeResolveLabel(Vdbe *p, int x){
|
void sqlite3VdbeResolveLabel(Vdbe *p, int x){
|
||||||
int j = -1-x;
|
int j = -1-x;
|
||||||
assert( p->magic==VDBE_MAGIC_INIT );
|
assert( p->magic==VDBE_MAGIC_INIT );
|
||||||
assert( j>=0 && j<p->nLabel );
|
assert( j<p->nLabel );
|
||||||
if( p->aLabel ){
|
if( j>=0 && p->aLabel ){
|
||||||
p->aLabel[j] = p->nOp;
|
p->aLabel[j] = p->nOp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2235,7 +2235,7 @@ static void constructAutomaticIndex(
|
|||||||
/* Fill the automatic index with content */
|
/* Fill the automatic index with content */
|
||||||
addrTop = sqlite3VdbeAddOp1(v, OP_Rewind, pLevel->iTabCur);
|
addrTop = sqlite3VdbeAddOp1(v, OP_Rewind, pLevel->iTabCur);
|
||||||
regRecord = sqlite3GetTempReg(pParse);
|
regRecord = sqlite3GetTempReg(pParse);
|
||||||
sqlite3GenerateIndexKey(pParse, pIdx, pLevel->iTabCur, regRecord, 1);
|
sqlite3GenerateIndexKey(pParse, pIdx, pLevel->iTabCur, regRecord, 1, 0);
|
||||||
sqlite3VdbeAddOp2(v, OP_IdxInsert, pLevel->iIdxCur, regRecord);
|
sqlite3VdbeAddOp2(v, OP_IdxInsert, pLevel->iIdxCur, regRecord);
|
||||||
sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
|
sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
|
||||||
sqlite3VdbeAddOp2(v, OP_Next, pLevel->iTabCur, addrTop+1);
|
sqlite3VdbeAddOp2(v, OP_Next, pLevel->iTabCur, addrTop+1);
|
||||||
|
|||||||
Reference in New Issue
Block a user