Add assert() statements on the nExtraDelete variable in vdbe.c to try to verify

that the FORDELETE and IDXDELETE flags are being generated correctly.  Those
flags are not currently generated correctly, and so the assert()s trip on this
check-in.

FossilOrigin-Name: dde1db0dd2e2cf04706117629756c352b178ebb8
This commit is contained in:
drh
2016-01-27 15:49:32 +00:00
parent 8716bfd8cd
commit b89aeb6aa2
7 changed files with 62 additions and 23 deletions
+7 -4
View File
@@ -479,13 +479,12 @@ void sqlite3DeleteFrom(
*/
if( !isView ){
int iAddrOnce = 0;
u8 p5 = (eOnePass==ONEPASS_OFF ? 0 : OPFLAG_FORDELETE);
if( eOnePass==ONEPASS_MULTI ){
iAddrOnce = sqlite3CodeOnce(pParse); VdbeCoverage(v);
}
testcase( IsVirtual(pTab) );
sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, p5, iTabCur,
aToOpen, &iDataCur, &iIdxCur);
sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, OPFLAG_FORDELETE,
iTabCur, aToOpen, &iDataCur, &iIdxCur);
assert( pPk || IsVirtual(pTab) || iDataCur==iTabCur );
assert( pPk || IsVirtual(pTab) || iIdxCur==iDataCur+1 );
if( eOnePass==ONEPASS_MULTI ) sqlite3VdbeJumpHere(v, iAddrOnce);
@@ -724,9 +723,13 @@ void sqlite3GenerateRowDelete(
if( count ){
sqlite3VdbeChangeP4(v, -1, pTab->zName, P4_TRANSIENT);
}
if( eMode!=ONEPASS_OFF ){
sqlite3VdbeChangeP5(v, OPFLAG_IDXDELETE);
p5 = OPFLAG_IDXDELETE;
}
if( iIdxNoSeek>=0 ){
sqlite3VdbeAddOp1(v, OP_Delete, iIdxNoSeek);
if( eMode!=ONEPASS_OFF ) p5 = OPFLAG_IDXDELETE;
p5 = 0;
}
if( eMode==ONEPASS_MULTI ) p5 |= OPFLAG_SAVEPOSITION;
sqlite3VdbeChangeP5(v, p5);
+6 -5
View File
@@ -1647,7 +1647,7 @@ int sqlite3OpenTableAndIndices(
Parse *pParse, /* Parsing context */
Table *pTab, /* Table to be opened */
int op, /* OP_OpenRead or OP_OpenWrite */
u8 p5, /* P5 value for OP_Open* instructions */
u8 p5, /* P5 value for OP_Open* opcodes (except on WITHOUT ROWID) */
int iBase, /* Use this for the table cursor, if there is one */
u8 *aToOpen, /* If not NULL: boolean for each table and index */
int *piDataCur, /* Write the database source cursor number here */
@@ -1682,15 +1682,16 @@ int sqlite3OpenTableAndIndices(
for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
int iIdxCur = iBase++;
assert( pIdx->pSchema==pTab->pSchema );
if( IsPrimaryKeyIndex(pIdx) && !HasRowid(pTab) && piDataCur ){
*piDataCur = iIdxCur;
}
if( aToOpen==0 || aToOpen[i+1] ){
sqlite3VdbeAddOp3(v, op, iIdxCur, pIdx->tnum, iDb);
sqlite3VdbeSetP4KeyInfo(pParse, pIdx);
sqlite3VdbeChangeP5(v, p5);
VdbeComment((v, "%s", pIdx->zName));
}
if( IsPrimaryKeyIndex(pIdx) && !HasRowid(pTab) ){
if( piDataCur ) *piDataCur = iIdxCur;
}else{
sqlite3VdbeChangeP5(v, p5);
}
}
if( iBase>pParse->nTab ) pParse->nTab = iBase;
return i;
+32 -2
View File
@@ -551,6 +551,9 @@ int sqlite3VdbeExec(
Op *pOp = aOp; /* Current operation */
#if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE)
Op *pOrigOp; /* Value of pOp at the top of the loop */
#endif
#ifdef SQLITE_DEBUG
int nExtraDelete = 0; /* Verifies FORDELETE and IDXDELETE flags */
#endif
int rc = SQLITE_OK; /* Value to return */
sqlite3 *db = p->db; /* The database */
@@ -3392,6 +3395,9 @@ case OP_OpenWrite:
pCur->nullRow = 1;
pCur->isOrdered = 1;
pCur->pgnoRoot = p2;
#ifdef SQLITE_DEBUG
pCur->wrFlag = wrFlag;
#endif
rc = sqlite3BtreeCursor(pX, p2, wrFlag, pKeyInfo, pCur->uc.pCursor);
pCur->pKeyInfo = pKeyInfo;
/* Set the VdbeCursor.isTable variable. Previous versions of
@@ -4390,10 +4396,24 @@ case OP_Delete: {
assert( pC->movetoTarget==iKey );
}
#endif
/* Only flags that can be set are SAVEPOISTION and IDXDELETE */
assert( (pOp->p5 & ~(OPFLAG_SAVEPOSITION|OPFLAG_IDXDELETE))==0 );
assert( OPFLAG_SAVEPOSITION==BTREE_SAVEPOSITION );
assert( OPFLAG_IDXDELETE==BTREE_IDXDELETE );
#ifdef SQLITE_DEBUG
if( pC->isEphemeral==0
&& (pOp->p5 & OPFLAG_IDXDELETE)==0
&& (pC->wrFlag & OPFLAG_FORDELETE)==0
){
nExtraDelete++;
}
if( pOp->p2 & OPFLAG_NCHANGE ){
nExtraDelete--;
}
#endif
rc = sqlite3BtreeDelete(pC->uc.pCursor, pOp->p5);
pC->cacheStatus = CACHE_STALE;
@@ -4939,7 +4959,16 @@ case OP_IdxDelete: {
r.default_rc = 0;
r.aMem = &aMem[pOp->p2];
#ifdef SQLITE_DEBUG
{ int i; for(i=0; i<r.nField; i++) assert( memIsValid(&r.aMem[i]) ); }
{
int i;
for(i=0; i<r.nField; i++) assert( memIsValid(&r.aMem[i]) );
if( pC->isEphemeral==0
&& (pOp->p5 & OPFLAG_IDXDELETE)==0
&& (pC->wrFlag & OPFLAG_FORDELETE)==0
){
nExtraDelete++;
}
}
#endif
rc = sqlite3BtreeMovetoUnpacked(pCrsr, &r, 0, 0, &res);
if( rc==SQLITE_OK && res==0 ){
@@ -6762,6 +6791,7 @@ vdbe_return:
testcase( nVmStep>0 );
p->aCounter[SQLITE_STMTSTATUS_VM_STEP] += (int)nVmStep;
sqlite3VdbeLeave(p);
assert( nExtraDelete==0 || sqlite3_strlike("DELETE%",p->zSql,0)!=0 );
return rc;
/* Jump to here if a string or blob larger than SQLITE_MAX_LENGTH
+1
View File
@@ -82,6 +82,7 @@ struct VdbeCursor {
u8 isTable; /* True for rowid tables. False for indexes */
#ifdef SQLITE_DEBUG
u8 seekOp; /* Most recent seek operation on this cursor */
u8 wrFlag; /* The wrFlag argument to sqlite3BtreeCursor() */
#endif
Bool isEphemeral:1; /* True for an ephemeral table */
Bool useRandomRowid:1;/* Generate new record numbers semi-randomly */