mirror of
https://github.com/sqlite/sqlite.git
synced 2025-11-12 13:01:09 +03:00
Changes to allow DELETE operations on virtual tables to use the onepass strategy under some circumstances.
FossilOrigin-Name: e73f919fae1833c6ffb36eddbc76d9a8d9324214
This commit is contained in:
23
manifest
23
manifest
@@ -1,5 +1,5 @@
|
|||||||
C Add\stest\scases\sto\sthe\sONEPASS\soptimization\scorruption\sproblem\sfixed\sby\sthe\nprevious\scheck-in.
|
C Changes\sto\sallow\sDELETE\soperations\son\svirtual\stables\sto\suse\sthe\sonepass\sstrategy\sunder\ssome\scircumstances.
|
||||||
D 2015-09-28T15:08:28.795
|
D 2015-09-28T15:20:58.913
|
||||||
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
||||||
F Makefile.in 2143eeef6d0cc26006ae5fc4bb242a4a8b973412
|
F Makefile.in 2143eeef6d0cc26006ae5fc4bb242a4a8b973412
|
||||||
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
||||||
@@ -285,13 +285,13 @@ F src/btmutex.c 45a968cc85afed9b5e6cf55bf1f42f8d18107f79
|
|||||||
F src/btree.c 164583151135a3764672c2c25aa8e4fa06bdb12b
|
F src/btree.c 164583151135a3764672c2c25aa8e4fa06bdb12b
|
||||||
F src/btree.h 40189aefdc2b830d25c8b58fd7d56538481bfdd7
|
F src/btree.h 40189aefdc2b830d25c8b58fd7d56538481bfdd7
|
||||||
F src/btreeInt.h 8177c9ab90d772d6d2c6c517e05bed774b7c92c0
|
F src/btreeInt.h 8177c9ab90d772d6d2c6c517e05bed774b7c92c0
|
||||||
F src/build.c edc5a29cd55257b05be837c3613e2cade02b3e03
|
F src/build.c 361f58b73aad7804f5706bf62d210bd9cd608041
|
||||||
F src/callback.c 7b44ce59674338ad48b0e84e7b72f935ea4f68b0
|
F src/callback.c 7b44ce59674338ad48b0e84e7b72f935ea4f68b0
|
||||||
F src/complete.c addcd8160b081131005d5bc2d34adf20c1c5c92f
|
F src/complete.c addcd8160b081131005d5bc2d34adf20c1c5c92f
|
||||||
F src/ctime.c 5a0b735dc95604766f5dac73973658eef782ee8b
|
F src/ctime.c 5a0b735dc95604766f5dac73973658eef782ee8b
|
||||||
F src/date.c fb1c99172017dcc8e237339132c91a21a0788584
|
F src/date.c fb1c99172017dcc8e237339132c91a21a0788584
|
||||||
F src/dbstat.c e637e7a7ff40ef32132a418c6fdf1cfb63aa27c7
|
F src/dbstat.c e637e7a7ff40ef32132a418c6fdf1cfb63aa27c7
|
||||||
F src/delete.c 371df4fc86e96efeaed3d37565aef77f956be109
|
F src/delete.c b454df59d57cb3f07118dfc68821760593fcaab3
|
||||||
F src/expr.c 3a76afcdac925294c39903b7002ddb9e5fd29863
|
F src/expr.c 3a76afcdac925294c39903b7002ddb9e5fd29863
|
||||||
F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
|
F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
|
||||||
F src/fkey.c 83e1baba999bed3144ea5a2143fc922edf51135f
|
F src/fkey.c 83e1baba999bed3144ea5a2143fc922edf51135f
|
||||||
@@ -342,7 +342,7 @@ F src/resolve.c 1954a0f01bf65d78d7d559aea3d5c67f33376d91
|
|||||||
F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e
|
F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e
|
||||||
F src/select.c 33230303f5f32430ee971a6fcc6a370e4a93ae1a
|
F src/select.c 33230303f5f32430ee971a6fcc6a370e4a93ae1a
|
||||||
F src/shell.c a11b20da4c6630e0e8f83c47ce36f717dd0422f0
|
F src/shell.c a11b20da4c6630e0e8f83c47ce36f717dd0422f0
|
||||||
F src/sqlite.h.in 02f6ed7de3a96d10bd1e6e5803e4e4b786dff014
|
F src/sqlite.h.in eade8bcc0456ff4d3f7ecfbbd3c4eec117314f26
|
||||||
F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad
|
F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad
|
||||||
F src/sqlite3ext.h 64350bf36833a56ad675e27392a913f417c5c308
|
F src/sqlite3ext.h 64350bf36833a56ad675e27392a913f417c5c308
|
||||||
F src/sqliteInt.h 5afc6e50402be1e0a870f28e1cd8b32eb9db590f
|
F src/sqliteInt.h 5afc6e50402be1e0a870f28e1cd8b32eb9db590f
|
||||||
@@ -417,7 +417,7 @@ F src/vxworks.h c18586c8edc1bddbc15c004fa16aeb1e1342b4fb
|
|||||||
F src/wal.c 18b0ed49830cf04fe2d68224b41838a73ac6cd24
|
F src/wal.c 18b0ed49830cf04fe2d68224b41838a73ac6cd24
|
||||||
F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4
|
F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4
|
||||||
F src/walker.c 2e14d17f592d176b6dc879c33fbdec4fbccaa2ba
|
F src/walker.c 2e14d17f592d176b6dc879c33fbdec4fbccaa2ba
|
||||||
F src/where.c f2c4905e47fe80043a0c45f374f555615da365ba
|
F src/where.c d07fb77010949be9b96e9120b4653712bf9f74ae
|
||||||
F src/whereInt.h 7892bb54cf9ca0ae5c7e6094491b94c9286dc647
|
F src/whereInt.h 7892bb54cf9ca0ae5c7e6094491b94c9286dc647
|
||||||
F src/wherecode.c 7660e1ad16817a921b099af553f3e1349352d16f
|
F src/wherecode.c 7660e1ad16817a921b099af553f3e1349352d16f
|
||||||
F src/whereexpr.c 2473e4350e30f9b55d1c6a8f66ca23c689f23f1d
|
F src/whereexpr.c 2473e4350e30f9b55d1c6a8f66ca23c689f23f1d
|
||||||
@@ -1388,7 +1388,10 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
|
|||||||
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
|
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
|
||||||
F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b
|
F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b
|
||||||
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
|
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
|
||||||
P 9d057f52217e7ef9c3f3eb84117abe3365503f44
|
P 5c14d447055bb337428eb1fe0a2934abee381829
|
||||||
R 075466467a3c577c7bea65d16a397b4e
|
R 3d1a8d879c965d0f75999b9c5903a435
|
||||||
U drh
|
T *branch * vtab-onepass
|
||||||
Z a775dc5a399b71fca215b8951f694541
|
T *sym-vtab-onepass *
|
||||||
|
T -sym-trunk *
|
||||||
|
U dan
|
||||||
|
Z 049fa8c468f3a0165cbcd245b0299bac
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
5c14d447055bb337428eb1fe0a2934abee381829
|
e73f919fae1833c6ffb36eddbc76d9a8d9324214
|
||||||
@@ -192,6 +192,8 @@ void sqlite3FinishCoding(Parse *pParse){
|
|||||||
db->aDb[iDb].pSchema->iGeneration /* P4 */
|
db->aDb[iDb].pSchema->iGeneration /* P4 */
|
||||||
);
|
);
|
||||||
if( db->init.busy==0 ) sqlite3VdbeChangeP5(v, 1);
|
if( db->init.busy==0 ) sqlite3VdbeChangeP5(v, 1);
|
||||||
|
VdbeComment((v,
|
||||||
|
"usesStmtJournal=%d", pParse->mayAbort && pParse->isMultiWrite));
|
||||||
}
|
}
|
||||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||||
for(i=0; i<pParse->nVtabLock; i++){
|
for(i=0; i<pParse->nVtabLock; i++){
|
||||||
|
|||||||
12
src/delete.c
12
src/delete.c
@@ -411,7 +411,7 @@ void sqlite3DeleteFrom(
|
|||||||
pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0, 0, wcf, iTabCur+1);
|
pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0, 0, wcf, iTabCur+1);
|
||||||
if( pWInfo==0 ) goto delete_from_cleanup;
|
if( pWInfo==0 ) goto delete_from_cleanup;
|
||||||
eOnePass = sqlite3WhereOkOnePass(pWInfo, aiCurOnePass);
|
eOnePass = sqlite3WhereOkOnePass(pWInfo, aiCurOnePass);
|
||||||
assert( IsVirtual(pTab)==0 || eOnePass==ONEPASS_OFF );
|
assert( IsVirtual(pTab)==0 || eOnePass!=ONEPASS_MULTI );
|
||||||
assert( IsVirtual(pTab) || bComplex || eOnePass!=ONEPASS_OFF );
|
assert( IsVirtual(pTab) || bComplex || eOnePass!=ONEPASS_OFF );
|
||||||
|
|
||||||
/* Keep track of the number of rows to be deleted */
|
/* Keep track of the number of rows to be deleted */
|
||||||
@@ -465,7 +465,7 @@ void sqlite3DeleteFrom(
|
|||||||
|
|
||||||
/* If this DELETE cannot use the ONEPASS strategy, this is the
|
/* If this DELETE cannot use the ONEPASS strategy, this is the
|
||||||
** end of the WHERE loop */
|
** end of the WHERE loop */
|
||||||
if( eOnePass!=ONEPASS_OFF ){
|
if( eOnePass!=ONEPASS_OFF && !IsVirtual(pTab) ){
|
||||||
addrBypass = sqlite3VdbeMakeLabel(v);
|
addrBypass = sqlite3VdbeMakeLabel(v);
|
||||||
}else{
|
}else{
|
||||||
sqlite3WhereEnd(pWInfo);
|
sqlite3WhereEnd(pWInfo);
|
||||||
@@ -494,7 +494,7 @@ void sqlite3DeleteFrom(
|
|||||||
*/
|
*/
|
||||||
if( eOnePass!=ONEPASS_OFF ){
|
if( eOnePass!=ONEPASS_OFF ){
|
||||||
assert( nKey==nPk ); /* OP_Found will use an unpacked key */
|
assert( nKey==nPk ); /* OP_Found will use an unpacked key */
|
||||||
if( aToOpen[iDataCur-iTabCur] ){
|
if( !IsVirtual(pTab) && aToOpen[iDataCur-iTabCur] ){
|
||||||
assert( pPk!=0 || pTab->pSelect!=0 );
|
assert( pPk!=0 || pTab->pSelect!=0 );
|
||||||
sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, addrBypass, iKey, nKey);
|
sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, addrBypass, iKey, nKey);
|
||||||
VdbeCoverage(v);
|
VdbeCoverage(v);
|
||||||
@@ -516,7 +516,11 @@ void sqlite3DeleteFrom(
|
|||||||
sqlite3VtabMakeWritable(pParse, pTab);
|
sqlite3VtabMakeWritable(pParse, pTab);
|
||||||
sqlite3VdbeAddOp4(v, OP_VUpdate, 0, 1, iKey, pVTab, P4_VTAB);
|
sqlite3VdbeAddOp4(v, OP_VUpdate, 0, 1, iKey, pVTab, P4_VTAB);
|
||||||
sqlite3VdbeChangeP5(v, OE_Abort);
|
sqlite3VdbeChangeP5(v, OE_Abort);
|
||||||
|
assert( eOnePass==ONEPASS_OFF || eOnePass==ONEPASS_SINGLE );
|
||||||
sqlite3MayAbort(pParse);
|
sqlite3MayAbort(pParse);
|
||||||
|
if( eOnePass==ONEPASS_SINGLE && pParse==sqlite3ParseToplevel(pParse) ){
|
||||||
|
pParse->isMultiWrite = 0;
|
||||||
|
}
|
||||||
}else
|
}else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
@@ -531,8 +535,10 @@ void sqlite3DeleteFrom(
|
|||||||
|
|
||||||
/* End of the loop over all rowids/primary-keys. */
|
/* End of the loop over all rowids/primary-keys. */
|
||||||
if( eOnePass!=ONEPASS_OFF ){
|
if( eOnePass!=ONEPASS_OFF ){
|
||||||
|
if( !IsVirtual(pTab) ){
|
||||||
sqlite3VdbeResolveLabel(v, addrBypass);
|
sqlite3VdbeResolveLabel(v, addrBypass);
|
||||||
sqlite3WhereEnd(pWInfo);
|
sqlite3WhereEnd(pWInfo);
|
||||||
|
}
|
||||||
}else if( pPk ){
|
}else if( pPk ){
|
||||||
sqlite3VdbeAddOp2(v, OP_Next, iEphCur, addrLoop+1); VdbeCoverage(v);
|
sqlite3VdbeAddOp2(v, OP_Next, iEphCur, addrLoop+1); VdbeCoverage(v);
|
||||||
sqlite3VdbeJumpHere(v, addrLoop);
|
sqlite3VdbeJumpHere(v, addrLoop);
|
||||||
|
|||||||
@@ -5668,8 +5668,15 @@ struct sqlite3_index_info {
|
|||||||
double estimatedCost; /* Estimated cost of using this index */
|
double estimatedCost; /* Estimated cost of using this index */
|
||||||
/* Fields below are only available in SQLite 3.8.2 and later */
|
/* Fields below are only available in SQLite 3.8.2 and later */
|
||||||
sqlite3_int64 estimatedRows; /* Estimated number of rows returned */
|
sqlite3_int64 estimatedRows; /* Estimated number of rows returned */
|
||||||
|
/* Fields below are only available in SQLite 3.8.12 and later */
|
||||||
|
int flags; /* Mask of SQLITE_INDEX_SCAN_* flags */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
** CAPI3REF: Virtual Table Scan Flags
|
||||||
|
*/
|
||||||
|
#define SQLITE_INDEX_SCAN_UNIQUE 1 /* Scan visits at most 1 row */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** CAPI3REF: Virtual Table Constraint Operator Codes
|
** CAPI3REF: Virtual Table Constraint Operator Codes
|
||||||
**
|
**
|
||||||
|
|||||||
10
src/where.c
10
src/where.c
@@ -2832,6 +2832,7 @@ static int whereLoopAddVirtual(
|
|||||||
pIdxInfo->orderByConsumed = 0;
|
pIdxInfo->orderByConsumed = 0;
|
||||||
pIdxInfo->estimatedCost = SQLITE_BIG_DBL / (double)2;
|
pIdxInfo->estimatedCost = SQLITE_BIG_DBL / (double)2;
|
||||||
pIdxInfo->estimatedRows = 25;
|
pIdxInfo->estimatedRows = 25;
|
||||||
|
pIdxInfo->flags = 0;
|
||||||
rc = vtabBestIndex(pParse, pTab, pIdxInfo);
|
rc = vtabBestIndex(pParse, pTab, pIdxInfo);
|
||||||
if( rc ) goto whereLoopAddVtab_exit;
|
if( rc ) goto whereLoopAddVtab_exit;
|
||||||
pIdxCons = *(struct sqlite3_index_constraint**)&pIdxInfo->aConstraint;
|
pIdxCons = *(struct sqlite3_index_constraint**)&pIdxInfo->aConstraint;
|
||||||
@@ -2877,6 +2878,7 @@ static int whereLoopAddVirtual(
|
|||||||
** (2) Multiple outputs from a single IN value will not merge
|
** (2) Multiple outputs from a single IN value will not merge
|
||||||
** together. */
|
** together. */
|
||||||
pIdxInfo->orderByConsumed = 0;
|
pIdxInfo->orderByConsumed = 0;
|
||||||
|
pIdxInfo->flags &= ~SQLITE_INDEX_SCAN_UNIQUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2892,6 +2894,14 @@ static int whereLoopAddVirtual(
|
|||||||
pNew->rSetup = 0;
|
pNew->rSetup = 0;
|
||||||
pNew->rRun = sqlite3LogEstFromDouble(pIdxInfo->estimatedCost);
|
pNew->rRun = sqlite3LogEstFromDouble(pIdxInfo->estimatedCost);
|
||||||
pNew->nOut = sqlite3LogEst(pIdxInfo->estimatedRows);
|
pNew->nOut = sqlite3LogEst(pIdxInfo->estimatedRows);
|
||||||
|
|
||||||
|
/* Set the WHERE_ONEROW flag if the xBestIndex() method indicated
|
||||||
|
** that the scan will visit at most one row. Clear it otherwise. */
|
||||||
|
if( pIdxInfo->flags & SQLITE_INDEX_SCAN_UNIQUE ){
|
||||||
|
pNew->wsFlags |= WHERE_ONEROW;
|
||||||
|
}else{
|
||||||
|
pNew->wsFlags &= ~WHERE_ONEROW;
|
||||||
|
}
|
||||||
whereLoopInsert(pBuilder, pNew);
|
whereLoopInsert(pBuilder, pNew);
|
||||||
if( pNew->u.vtab.needFree ){
|
if( pNew->u.vtab.needFree ){
|
||||||
sqlite3_free(pNew->u.vtab.idxStr);
|
sqlite3_free(pNew->u.vtab.idxStr);
|
||||||
|
|||||||
Reference in New Issue
Block a user