Use symbolic names ONEPASS_OFF, ONEPASS_SINGLE, and ONEPASS_MULTI for the
various modes of the one-pass optimization. FossilOrigin-Name: 16e56bdadef903c6439a487f2683388aeeb0c625
This commit is contained in:
parent
66336f3755
commit
b0264eeca1
22
manifest
22
manifest
@ -1,5 +1,5 @@
|
||||
C Fix\sa\scompiler\swarning\sand\sproviding\smissing\sVdbeCoverage()\scalls.
|
||||
D 2015-09-14T14:08:25.548
|
||||
C Use\ssymbolic\snames\sONEPASS_OFF,\sONEPASS_SINGLE,\sand\sONEPASS_MULTI\sfor\sthe\nvarious\smodes\sof\sthe\sone-pass\soptimization.
|
||||
D 2015-09-14T14:45:50.973
|
||||
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
||||
F Makefile.in f85066ce844a28b671aaeeff320921cd0ce36239
|
||||
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
||||
@ -291,7 +291,7 @@ F src/complete.c addcd8160b081131005d5bc2d34adf20c1c5c92f
|
||||
F src/ctime.c 5a0b735dc95604766f5dac73973658eef782ee8b
|
||||
F src/date.c fb1c99172017dcc8e237339132c91a21a0788584
|
||||
F src/dbstat.c e637e7a7ff40ef32132a418c6fdf1cfb63aa27c7
|
||||
F src/delete.c 33dedc277b1b7267734b41580c280ebb7610270d
|
||||
F src/delete.c 249a287682dd6e7ab362dd81e4d65abe2d5c3ce4
|
||||
F src/expr.c 3a76afcdac925294c39903b7002ddb9e5fd29863
|
||||
F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
|
||||
F src/fkey.c 83e1baba999bed3144ea5a2143fc922edf51135f
|
||||
@ -300,7 +300,7 @@ F src/global.c 508e4087f7b41d688e4762dcf4d4fe28cfbc87f9
|
||||
F src/hash.c 4263fbc955f26c2e8cdc0cf214bc42435aa4e4f5
|
||||
F src/hash.h c8f3c31722cf3277d03713909761e152a5b81094
|
||||
F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08
|
||||
F src/insert.c db8a34cf8ba600ac1cebb3c03e93c92154d0fc4c
|
||||
F src/insert.c ace93aa254f86b1bddb20eb9bf382f6b851bbda5
|
||||
F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d
|
||||
F src/legacy.c ba1863ea58c4c840335a84ec276fc2b25e22bc4e
|
||||
F src/lempar.c d344a95d60c24e2f490ee59db9784b1b17439012
|
||||
@ -345,7 +345,7 @@ F src/shell.c 6332ef06db1390ef812cfdff1fc97b4fd76cdd42
|
||||
F src/sqlite.h.in 50f83145c6543000b7d27525ecaec59a23d8280b
|
||||
F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad
|
||||
F src/sqlite3ext.h 64350bf36833a56ad675e27392a913f417c5c308
|
||||
F src/sqliteInt.h 91bf09de55402157d1476a61df46ef6cfbc0bbc3
|
||||
F src/sqliteInt.h 5afc6e50402be1e0a870f28e1cd8b32eb9db590f
|
||||
F src/sqliteLimit.h 216557999cb45f2e3578ed53ebefe228d779cb46
|
||||
F src/status.c f266ad8a2892d659b74f0f50cb6a88b6e7c12179
|
||||
F src/table.c 51b46b2a62d1b3a959633d593b89bab5e2c9155e
|
||||
@ -417,9 +417,9 @@ F src/vxworks.h c18586c8edc1bddbc15c004fa16aeb1e1342b4fb
|
||||
F src/wal.c 18b0ed49830cf04fe2d68224b41838a73ac6cd24
|
||||
F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4
|
||||
F src/walker.c 2e14d17f592d176b6dc879c33fbdec4fbccaa2ba
|
||||
F src/where.c 98cbedead64380fc26a098350f43d92237c8fa17
|
||||
F src/whereInt.h 292d3ac90da4eab1e03ac8452f1add746bcafaa1
|
||||
F src/wherecode.c 91c50036928edf53bdfe7a2db13f2a40342b4f46
|
||||
F src/where.c 882fb44b36201fafc32dd7d59366f852806b7e70
|
||||
F src/whereInt.h 7892bb54cf9ca0ae5c7e6094491b94c9286dc647
|
||||
F src/wherecode.c 186b493599000e640203be0a441223b395dabd24
|
||||
F src/whereexpr.c 2473e4350e30f9b55d1c6a8f66ca23c689f23f1d
|
||||
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
|
||||
F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd
|
||||
@ -1387,7 +1387,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
|
||||
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
|
||||
F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b
|
||||
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
|
||||
P 8b93cc5937000535c35c763c9326507a19892a6e
|
||||
R 761047ba83700d06df34cef492a4fea0
|
||||
P 2edd2e5edd60210e18db58bce1e096dd211b6ece
|
||||
R 664fd3c2c4c1207a1dc899fd67c056b8
|
||||
U drh
|
||||
Z 4b77c33ded83fae554d0e60cce550d5b
|
||||
Z ed742f4af7607da542ef263fbb0dcf2e
|
||||
|
@ -1 +1 @@
|
||||
2edd2e5edd60210e18db58bce1e096dd211b6ece
|
||||
16e56bdadef903c6439a487f2683388aeeb0c625
|
40
src/delete.c
40
src/delete.c
@ -235,7 +235,7 @@ void sqlite3DeleteFrom(
|
||||
int iDb; /* Database number */
|
||||
int memCnt = -1; /* Memory cell used for change counting */
|
||||
int rcauth; /* Value returned by authorization callback */
|
||||
int eOnePass; /* Non-zero for one-pass algorithm without the FIFO */
|
||||
int eOnePass; /* ONEPASS_OFF or _SINGLE or _MULTI */
|
||||
int aiCurOnePass[2]; /* The write cursors opened by WHERE_ONEPASS */
|
||||
u8 *aToOpen = 0; /* Open cursor iTabCur+j if aToOpen[j] is true */
|
||||
Index *pPk; /* The PRIMARY KEY index on the table */
|
||||
@ -400,14 +400,14 @@ void sqlite3DeleteFrom(
|
||||
** to be deleted, based on the WHERE clause. Set variable eOnePass
|
||||
** to indicate the strategy used to implement this delete:
|
||||
**
|
||||
** 0: Two-pass approach - use a FIFO for rowids/PK values.
|
||||
** 1: One-pass approach - at most one row deleted.
|
||||
** 2: One-pass approach - any number of rows may be deleted.
|
||||
** ONEPASS_OFF: Two-pass approach - use a FIFO for rowids/PK values.
|
||||
** ONEPASS_SINGLE: One-pass approach - at most one row deleted.
|
||||
** ONEPASS_MULTI: One-pass approach - any number of rows may be deleted.
|
||||
*/
|
||||
pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0, 0, wcf, iTabCur+1);
|
||||
if( pWInfo==0 ) goto delete_from_cleanup;
|
||||
eOnePass = sqlite3WhereOkOnePass(pWInfo, aiCurOnePass);
|
||||
assert( IsVirtual(pTab)==0 || eOnePass==0 );
|
||||
assert( IsVirtual(pTab)==0 || eOnePass==ONEPASS_OFF );
|
||||
|
||||
/* Keep track of the number of rows to be deleted */
|
||||
if( db->flags & SQLITE_CountRows ){
|
||||
@ -428,7 +428,7 @@ void sqlite3DeleteFrom(
|
||||
if( iKey>pParse->nMem ) pParse->nMem = iKey;
|
||||
}
|
||||
|
||||
if( eOnePass ){
|
||||
if( eOnePass!=ONEPASS_OFF ){
|
||||
/* For ONEPASS, no need to store the rowid/primary-key. There is only
|
||||
** one, so just keep it in its register(s) and fall through to the
|
||||
** delete code. */
|
||||
@ -460,7 +460,7 @@ void sqlite3DeleteFrom(
|
||||
|
||||
/* If this DELETE cannot use the ONEPASS strategy, this is the
|
||||
** end of the WHERE loop */
|
||||
if( eOnePass ){
|
||||
if( eOnePass!=ONEPASS_OFF ){
|
||||
addrBypass = sqlite3VdbeMakeLabel(v);
|
||||
}else{
|
||||
sqlite3WhereEnd(pWInfo);
|
||||
@ -473,7 +473,7 @@ void sqlite3DeleteFrom(
|
||||
*/
|
||||
if( !isView ){
|
||||
int iAddrOnce = 0;
|
||||
if( eOnePass==2 ){
|
||||
if( eOnePass==ONEPASS_MULTI ){
|
||||
iAddrOnce = sqlite3CodeOnce(pParse); VdbeCoverage(v);
|
||||
}
|
||||
testcase( IsVirtual(pTab) );
|
||||
@ -481,13 +481,13 @@ void sqlite3DeleteFrom(
|
||||
&iDataCur, &iIdxCur);
|
||||
assert( pPk || IsVirtual(pTab) || iDataCur==iTabCur );
|
||||
assert( pPk || IsVirtual(pTab) || iIdxCur==iDataCur+1 );
|
||||
if( eOnePass==2 ) sqlite3VdbeJumpHere(v, iAddrOnce);
|
||||
if( eOnePass==ONEPASS_MULTI ) sqlite3VdbeJumpHere(v, iAddrOnce);
|
||||
}
|
||||
|
||||
/* Set up a loop over the rowids/primary-keys that were found in the
|
||||
** where-clause loop above.
|
||||
*/
|
||||
if( eOnePass ){
|
||||
if( eOnePass!=ONEPASS_OFF ){
|
||||
assert( nKey==nPk ); /* OP_Found will use an unpacked key */
|
||||
if( aToOpen[iDataCur-iTabCur] ){
|
||||
assert( pPk!=0 || pTab->pSelect!=0 );
|
||||
@ -525,7 +525,7 @@ void sqlite3DeleteFrom(
|
||||
}
|
||||
|
||||
/* End of the loop over all rowids/primary-keys. */
|
||||
if( eOnePass ){
|
||||
if( eOnePass!=ONEPASS_OFF ){
|
||||
sqlite3VdbeResolveLabel(v, addrBypass);
|
||||
sqlite3WhereEnd(pWInfo);
|
||||
}else if( pPk ){
|
||||
@ -601,13 +601,13 @@ delete_from_cleanup:
|
||||
** single memory location iPk.
|
||||
**
|
||||
** eMode:
|
||||
** Parameter eMode may be passed either 0, 1 or 2. If it is passed a
|
||||
** non-zero value, then it is guaranteed that cursor iDataCur already
|
||||
** points to the row to delete. If it is passed 0, then this function
|
||||
** must seek iDataCur to the entry identified by iPk and nPk before
|
||||
** reading from it.
|
||||
** Parameter eMode may be passed either ONEPASS_OFF (0), ONEPASS_SINGLE, or
|
||||
** ONEPASS_MULTI. If eMode is not ONEPASS_OFF, then the cursor
|
||||
** iDataCur already points to the row to delete. If eMode is ONEPASS_OFF
|
||||
** then this function must seek iDataCur to the entry identified by iPk
|
||||
** and nPk before reading from it.
|
||||
**
|
||||
** If eMode is passed the value 2, then this call is being made as part
|
||||
** If eMode is ONEPASS_MULTI, then this call is being made as part
|
||||
** of a ONEPASS delete that affects multiple rows. In this case, if
|
||||
** iIdxNoSeek is a valid cursor number (>=0), then its position should
|
||||
** be preserved following the delete operation. Or, if iIdxNoSeek is not
|
||||
@ -629,7 +629,7 @@ void sqlite3GenerateRowDelete(
|
||||
i16 nPk, /* Number of PRIMARY KEY memory cells */
|
||||
u8 count, /* If non-zero, increment the row change counter */
|
||||
u8 onconf, /* Default ON CONFLICT policy for triggers */
|
||||
u8 eMode, /* See explanation above */
|
||||
u8 eMode, /* ONEPASS_OFF, _SINGLE, or _MULTI. See above */
|
||||
int iIdxNoSeek /* Cursor number of cursor that does not need seeking */
|
||||
){
|
||||
Vdbe *v = pParse->pVdbe; /* Vdbe */
|
||||
@ -647,7 +647,7 @@ void sqlite3GenerateRowDelete(
|
||||
** not attempt to delete it or fire any DELETE triggers. */
|
||||
iLabel = sqlite3VdbeMakeLabel(v);
|
||||
opSeek = HasRowid(pTab) ? OP_NotExists : OP_NotFound;
|
||||
if( eMode==0 ){
|
||||
if( eMode==ONEPASS_OFF ){
|
||||
sqlite3VdbeAddOp4Int(v, opSeek, iDataCur, iLabel, iPk, nPk);
|
||||
VdbeCoverageIf(v, opSeek==OP_NotExists);
|
||||
VdbeCoverageIf(v, opSeek==OP_NotFound);
|
||||
@ -715,7 +715,7 @@ void sqlite3GenerateRowDelete(
|
||||
if( iIdxNoSeek>=0 ){
|
||||
sqlite3VdbeAddOp1(v, OP_Delete, iIdxNoSeek);
|
||||
}
|
||||
sqlite3VdbeChangeP5(v, eMode==2);
|
||||
sqlite3VdbeChangeP5(v, eMode==ONEPASS_MULTI);
|
||||
}
|
||||
|
||||
/* Do any ON CASCADE, SET NULL or SET DEFAULT operations required to
|
||||
|
@ -1347,7 +1347,8 @@ void sqlite3GenerateConstraintChecks(
|
||||
if( pTrigger || sqlite3FkRequired(pParse, pTab, 0, 0) ){
|
||||
sqlite3MultiWrite(pParse);
|
||||
sqlite3GenerateRowDelete(pParse, pTab, pTrigger, iDataCur, iIdxCur,
|
||||
regNewData, 1, 0, OE_Replace, 1, -1);
|
||||
regNewData, 1, 0, OE_Replace,
|
||||
ONEPASS_SINGLE, -1);
|
||||
}else if( pTab->pIndex ){
|
||||
sqlite3MultiWrite(pParse);
|
||||
sqlite3GenerateRowIndexDelete(pParse, pTab, iDataCur, iIdxCur, 0, -1);
|
||||
@ -1528,7 +1529,8 @@ void sqlite3GenerateConstraintChecks(
|
||||
pTrigger = sqlite3TriggersExist(pParse, pTab, TK_DELETE, 0, 0);
|
||||
}
|
||||
sqlite3GenerateRowDelete(pParse, pTab, pTrigger, iDataCur, iIdxCur,
|
||||
regR, nPkField, 0, OE_Replace, pIdx==pPk, -1);
|
||||
regR, nPkField, 0, OE_Replace,
|
||||
(pIdx==pPk ? ONEPASS_SINGLE : ONEPASS_OFF), -1);
|
||||
seenReplace = 1;
|
||||
break;
|
||||
}
|
||||
|
@ -3381,6 +3381,9 @@ int sqlite3WhereIsSorted(WhereInfo*);
|
||||
int sqlite3WhereContinueLabel(WhereInfo*);
|
||||
int sqlite3WhereBreakLabel(WhereInfo*);
|
||||
int sqlite3WhereOkOnePass(WhereInfo*, int*);
|
||||
#define ONEPASS_OFF 0 /* Use of ONEPASS not allowed */
|
||||
#define ONEPASS_SINGLE 1 /* ONEPASS valid for a single row update */
|
||||
#define ONEPASS_MULTI 2 /* ONEPASS is valid for multiple rows */
|
||||
void sqlite3ExprCodeLoadIndexColumn(Parse*, Index*, int, int, int);
|
||||
int sqlite3ExprCodeGetColumn(Parse*, Table*, int, int, int, u8);
|
||||
void sqlite3ExprCodeGetColumnOfTable(Vdbe*, Table*, int, int, int);
|
||||
|
25
src/where.c
25
src/where.c
@ -69,9 +69,11 @@ int sqlite3WhereBreakLabel(WhereInfo *pWInfo){
|
||||
}
|
||||
|
||||
/*
|
||||
** Return TRUE if an UPDATE or DELETE statement can operate directly on
|
||||
** the rowids returned by a WHERE clause. Return FALSE if doing an
|
||||
** UPDATE or DELETE might change subsequent WHERE clause results.
|
||||
** Return ONEPASS_OFF (0) if an UPDATE or DELETE statement is unable to
|
||||
** operate directly on the rowis returned by a WHERE clause. Return
|
||||
** ONEPASS_SINGLE (1) if the statement can operation directly because only
|
||||
** a single row is to be changed. Return ONEPASS_MULTI (2) if the one-pass
|
||||
** optimization can be used on multiple
|
||||
**
|
||||
** If the ONEPASS optimization is used (if this routine returns true)
|
||||
** then also write the indices of open cursors used by ONEPASS
|
||||
@ -85,7 +87,7 @@ int sqlite3WhereBreakLabel(WhereInfo *pWInfo){
|
||||
*/
|
||||
int sqlite3WhereOkOnePass(WhereInfo *pWInfo, int *aiCur){
|
||||
memcpy(aiCur, pWInfo->aiCurOnePass, sizeof(int)*2);
|
||||
return pWInfo->okOnePass;
|
||||
return pWInfo->eOnePass;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -4017,6 +4019,7 @@ WhereInfo *sqlite3WhereBegin(
|
||||
pWInfo->iBreak = pWInfo->iContinue = sqlite3VdbeMakeLabel(v);
|
||||
pWInfo->wctrlFlags = wctrlFlags;
|
||||
pWInfo->savedNQueryLoop = pParse->nQueryLoop;
|
||||
assert( pWInfo->eOnePass==ONEPASS_OFF ); /* ONEPASS defaults to OFF */
|
||||
pMaskSet = &pWInfo->sMaskSet;
|
||||
sWLB.pWInfo = pWInfo;
|
||||
sWLB.pWC = &pWInfo->sWC;
|
||||
@ -4209,7 +4212,7 @@ WhereInfo *sqlite3WhereBegin(
|
||||
if( bOnerow || ( (wctrlFlags & WHERE_ONEPASS_MULTIROW)
|
||||
&& 0==(wsFlags & WHERE_VIRTUALTABLE)
|
||||
)){
|
||||
pWInfo->okOnePass = bOnerow ? 1 : 2;
|
||||
pWInfo->eOnePass = bOnerow ? ONEPASS_SINGLE : ONEPASS_MULTI;
|
||||
if( HasRowid(pTabList->a[0].pTab) ){
|
||||
pWInfo->a[0].pWLoop->wsFlags &= ~WHERE_IDX_ONLY;
|
||||
}
|
||||
@ -4243,15 +4246,15 @@ WhereInfo *sqlite3WhereBegin(
|
||||
if( (pLoop->wsFlags & WHERE_IDX_ONLY)==0
|
||||
&& (wctrlFlags & WHERE_OMIT_OPEN_CLOSE)==0 ){
|
||||
int op = OP_OpenRead;
|
||||
if( pWInfo->okOnePass ){
|
||||
if( pWInfo->eOnePass!=ONEPASS_OFF ){
|
||||
op = OP_OpenWrite;
|
||||
pWInfo->aiCurOnePass[0] = pTabItem->iCursor;
|
||||
};
|
||||
sqlite3OpenTable(pParse, pTabItem->iCursor, iDb, pTab, op);
|
||||
assert( pTabItem->iCursor==pLevel->iTabCur );
|
||||
testcase( !pWInfo->okOnePass && pTab->nCol==BMS-1 );
|
||||
testcase( !pWInfo->okOnePass && pTab->nCol==BMS );
|
||||
if( !pWInfo->okOnePass && pTab->nCol<BMS && HasRowid(pTab) ){
|
||||
testcase( pWInfo->eOnePass==ONEPASS_OFF && pTab->nCol==BMS-1 );
|
||||
testcase( pWInfo->eOnePass==ONEPASS_OFF && pTab->nCol==BMS );
|
||||
if( pWInfo->eOnePass==ONEPASS_OFF && pTab->nCol<BMS && HasRowid(pTab) ){
|
||||
Bitmask b = pTabItem->colUsed;
|
||||
int n = 0;
|
||||
for(; b; b=b>>1, n++){}
|
||||
@ -4279,7 +4282,7 @@ WhereInfo *sqlite3WhereBegin(
|
||||
** WITHOUT ROWID table. No need for a separate index */
|
||||
iIndexCur = pLevel->iTabCur;
|
||||
op = 0;
|
||||
}else if( pWInfo->okOnePass ){
|
||||
}else if( pWInfo->eOnePass!=ONEPASS_OFF ){
|
||||
Index *pJ = pTabItem->pTab->pIndex;
|
||||
iIndexCur = iIdxCur;
|
||||
assert( wctrlFlags & WHERE_ONEPASS_DESIRED );
|
||||
@ -4487,7 +4490,7 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){
|
||||
&& (pWInfo->wctrlFlags & WHERE_OMIT_OPEN_CLOSE)==0
|
||||
){
|
||||
int ws = pLoop->wsFlags;
|
||||
if( !pWInfo->okOnePass && (ws & WHERE_IDX_ONLY)==0 ){
|
||||
if( pWInfo->eOnePass==ONEPASS_OFF && (ws & WHERE_IDX_ONLY)==0 ){
|
||||
sqlite3VdbeAddOp1(v, OP_Close, pTabItem->iCursor);
|
||||
}
|
||||
if( (ws & WHERE_INDEXED)!=0
|
||||
|
@ -412,7 +412,7 @@ struct WhereInfo {
|
||||
u16 wctrlFlags; /* Flags originally passed to sqlite3WhereBegin() */
|
||||
i8 nOBSat; /* Number of ORDER BY terms satisfied by indices */
|
||||
u8 sorted; /* True if really sorted (not just grouped) */
|
||||
u8 okOnePass; /* Ok to use one-pass algorithm for UPDATE/DELETE */
|
||||
u8 eOnePass; /* ONEPASS_OFF, or _SINGLE, or _MULTI */
|
||||
u8 untestedTerms; /* Not all WHERE terms resolved by outer loop */
|
||||
u8 eDistinct; /* One of the WHERE_DISTINCT_* values below */
|
||||
u8 nLevel; /* Number of nested loop */
|
||||
|
@ -1069,7 +1069,7 @@ Bitmask sqlite3WhereCodeOneLoopStart(
|
||||
iRowidReg = ++pParse->nMem;
|
||||
sqlite3VdbeAddOp2(v, OP_IdxRowid, iIdxCur, iRowidReg);
|
||||
sqlite3ExprCacheStore(pParse, iCur, -1, iRowidReg);
|
||||
if( pWInfo->okOnePass ){
|
||||
if( pWInfo->eOnePass!=ONEPASS_OFF ){
|
||||
sqlite3VdbeAddOp3(v, OP_NotExists, iCur, 0, iRowidReg);
|
||||
VdbeCoverage(v);
|
||||
}else{
|
||||
|
Loading…
x
Reference in New Issue
Block a user