diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/expr.c | 14 | ||||
-rw-r--r-- | src/select.c | 13 | ||||
-rw-r--r-- | src/vdbe.c | 17 | ||||
-rw-r--r-- | src/vdbe.h | 2 | ||||
-rw-r--r-- | src/vdbeaux.c | 13 | ||||
-rw-r--r-- | src/vdbeblob.c | 4 | ||||
-rw-r--r-- | src/where.c | 3 |
7 files changed, 38 insertions, 28 deletions
diff --git a/src/expr.c b/src/expr.c index 7bfcf5733..6fd08b27f 100644 --- a/src/expr.c +++ b/src/expr.c @@ -1462,8 +1462,7 @@ int sqlite3FindInIndex(Parse *pParse, Expr *pX, int *prNotFound){ int iMem = ++pParse->nMem; int iAddr; - iAddr = sqlite3VdbeAddOp1(v, OP_If, iMem); - sqlite3VdbeAddOp2(v, OP_Integer, 1, iMem); + iAddr = sqlite3VdbeAddOp1(v, OP_Once, iMem); sqlite3OpenTable(pParse, iTab, iDb, pTab, OP_OpenRead); eType = IN_INDEX_ROWID; @@ -1494,8 +1493,7 @@ int sqlite3FindInIndex(Parse *pParse, Expr *pX, int *prNotFound){ char *pKey; pKey = (char *)sqlite3IndexKeyinfo(pParse, pIdx); - iAddr = sqlite3VdbeAddOp1(v, OP_If, iMem); - sqlite3VdbeAddOp2(v, OP_Integer, 1, iMem); + iAddr = sqlite3VdbeAddOp1(v, OP_Once, iMem); sqlite3VdbeAddOp4(v, OP_OpenRead, iTab, pIdx->tnum, iDb, pKey,P4_KEYINFO_HANDOFF); @@ -1580,6 +1578,7 @@ int sqlite3CodeSubselect( int rReg = 0; /* Register storing resulting */ Vdbe *v = sqlite3GetVdbe(pParse); if( NEVER(v==0) ) return 0; + assert( sqlite3VdbeCurrentAddr(v)>0 ); sqlite3ExprCachePush(pParse); /* This code must be run in its entirety every time it is encountered @@ -1594,8 +1593,7 @@ int sqlite3CodeSubselect( */ if( !ExprHasAnyProperty(pExpr, EP_VarSelect) && !pParse->pTriggerTab ){ int mem = ++pParse->nMem; - sqlite3VdbeAddOp1(v, OP_If, mem); - testAddr = sqlite3VdbeAddOp2(v, OP_Integer, 1, mem); + testAddr = sqlite3VdbeAddOp1(v, OP_Once, mem); assert( testAddr>0 || pParse->db->mallocFailed ); } @@ -1695,7 +1693,7 @@ int sqlite3CodeSubselect( ** expression we need to rerun this code each time. */ if( testAddr && !sqlite3ExprIsConstant(pE2) ){ - sqlite3VdbeChangeToNoop(v, testAddr-1, 2); + sqlite3VdbeChangeToNoop(v, testAddr); testAddr = 0; } @@ -1766,7 +1764,7 @@ int sqlite3CodeSubselect( } if( testAddr ){ - sqlite3VdbeJumpHere(v, testAddr-1); + sqlite3VdbeJumpHere(v, testAddr); } sqlite3ExprCachePop(pParse, 1); diff --git a/src/select.c b/src/select.c index 2ddc751b5..277f5c026 100644 --- a/src/select.c +++ b/src/select.c @@ -3831,7 +3831,7 @@ int sqlite3Select( ** is a register allocated to hold the subroutine return address */ int topAddr = sqlite3VdbeAddOp0(v, OP_Goto); - int regOnce = 0; + int onceAddr = 0; assert( pItem->addrFillSub==0 ); pItem->addrFillSub = topAddr+1; pItem->regReturn = ++pParse->nMem; @@ -3839,15 +3839,14 @@ int sqlite3Select( /* If the subquery is no correlated and if we are not inside of ** a trigger, then we only need to compute the value of the subquery ** once. */ - regOnce = ++pParse->nMem; - sqlite3VdbeAddOp1(v, OP_If, regOnce); - sqlite3VdbeAddOp2(v, OP_Integer, 1, regOnce); + int regOnce = ++pParse->nMem; + onceAddr = sqlite3VdbeAddOp1(v, OP_Once, regOnce); } sqlite3SelectDestInit(&dest, SRT_EphemTab, pItem->iCursor); explainSetInteger(pItem->iSelectId, (u8)pParse->iNextSelectId); sqlite3Select(pParse, pSub, &dest); pItem->pTab->nRowEst = (unsigned)pSub->nSelectRow; - if( regOnce ) sqlite3VdbeJumpHere(v, topAddr+1); + if( onceAddr ) sqlite3VdbeJumpHere(v, onceAddr); sqlite3VdbeAddOp1(v, OP_Return, pItem->regReturn); sqlite3VdbeJumpHere(v, topAddr); sqlite3VdbeAddOp2(v, OP_Gosub, pItem->regReturn, topAddr+1); @@ -3991,7 +3990,7 @@ int sqlite3Select( ** into an OP_Noop. */ if( addrSortIndex>=0 && pOrderBy==0 ){ - sqlite3VdbeChangeToNoop(v, addrSortIndex, 1); + sqlite3VdbeChangeToNoop(v, addrSortIndex); p->addrOpenEphm[2] = -1; } @@ -4274,7 +4273,7 @@ int sqlite3Select( sqlite3VdbeAddOp2(v, OP_SorterNext, sAggInfo.sortingIdx, addrTopOfLoop); }else{ sqlite3WhereEnd(pWInfo); - sqlite3VdbeChangeToNoop(v, addrSortingIdx, 1); + sqlite3VdbeChangeToNoop(v, addrSortingIdx); } /* Output the final row of result diff --git a/src/vdbe.c b/src/vdbe.c index 906058c1f..4f7fd6bbe 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -2021,6 +2021,16 @@ case OP_BitNot: { /* same as TK_BITNOT, in1, out2 */ break; } +/* Opcode: Once P1 P2 * * * +** +** Jump to P2 if the value in register P1 is a not null or zero. If +** the value is NULL or zero, fall through and change the P1 register +** to an integer 1. +** +** When P1 is not used otherwise in a program, this opcode falls through +** once and jumps on all subsequent invocations. It is the equivalent +** of "OP_If P1 P2", followed by "OP_Integer 1 P1". +*/ /* Opcode: If P1 P2 P3 * * ** ** Jump to P2 if the value in register P1 is true. The value @@ -2033,6 +2043,7 @@ case OP_BitNot: { /* same as TK_BITNOT, in1, out2 */ ** is considered true if it has a numeric value of zero. If the value ** in P1 is NULL then take the jump if P3 is true. */ +case OP_Once: /* jump, in1 */ case OP_If: /* jump, in1 */ case OP_IfNot: { /* jump, in1 */ int c; @@ -2049,6 +2060,12 @@ case OP_IfNot: { /* jump, in1 */ } if( c ){ pc = pOp->p2-1; + }else if( pOp->opcode==OP_Once ){ + assert( (pIn1->flags & (MEM_Agg|MEM_Dyn|MEM_RowSet|MEM_Frame))==0 ); + memAboutToChange(p, pIn1); + pIn1->flags = MEM_Int; + pIn1->u.i = 1; + REGISTER_TRACE(pOp->p1, pIn1); } break; } diff --git a/src/vdbe.h b/src/vdbe.h index f4691c0e8..948c73bca 100644 --- a/src/vdbe.h +++ b/src/vdbe.h @@ -180,7 +180,7 @@ void sqlite3VdbeChangeP2(Vdbe*, u32 addr, int P2); void sqlite3VdbeChangeP3(Vdbe*, u32 addr, int P3); void sqlite3VdbeChangeP5(Vdbe*, u8 P5); void sqlite3VdbeJumpHere(Vdbe*, int addr); -void sqlite3VdbeChangeToNoop(Vdbe*, int addr, int N); +void sqlite3VdbeChangeToNoop(Vdbe*, int addr); void sqlite3VdbeChangeP4(Vdbe*, int addr, const char *zP4, int N); void sqlite3VdbeUsesBtree(Vdbe*, int); VdbeOp *sqlite3VdbeGetOp(Vdbe*, int); diff --git a/src/vdbeaux.c b/src/vdbeaux.c index b00768477..1d5f713af 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -670,18 +670,15 @@ void sqlite3VdbeLinkSubProgram(Vdbe *pVdbe, SubProgram *p){ } /* -** Change N opcodes starting at addr to No-ops. +** Change the opcode at addr into OP_Noop */ -void sqlite3VdbeChangeToNoop(Vdbe *p, int addr, int N){ +void sqlite3VdbeChangeToNoop(Vdbe *p, int addr){ if( p->aOp ){ VdbeOp *pOp = &p->aOp[addr]; sqlite3 *db = p->db; - while( N-- ){ - freeP4(db, pOp->p4type, pOp->p4.p); - memset(pOp, 0, sizeof(pOp[0])); - pOp->opcode = OP_Noop; - pOp++; - } + freeP4(db, pOp->p4type, pOp->p4.p); + memset(pOp, 0, sizeof(pOp[0])); + pOp->opcode = OP_Noop; } } diff --git a/src/vdbeblob.c b/src/vdbeblob.c index a8728e6d2..ae77a47ba 100644 --- a/src/vdbeblob.c +++ b/src/vdbeblob.c @@ -273,7 +273,7 @@ int sqlite3_blob_open( /* Configure the OP_TableLock instruction */ #ifdef SQLITE_OMIT_SHARED_CACHE - sqlite3VdbeChangeToNoop(v, 2, 1); + sqlite3VdbeChangeToNoop(v, 2); #else sqlite3VdbeChangeP1(v, 2, iDb); sqlite3VdbeChangeP2(v, 2, pTab->tnum); @@ -283,7 +283,7 @@ int sqlite3_blob_open( /* Remove either the OP_OpenWrite or OpenRead. Set the P2 ** parameter of the other to pTab->tnum. */ - sqlite3VdbeChangeToNoop(v, 4 - flags, 1); + sqlite3VdbeChangeToNoop(v, 4 - flags); sqlite3VdbeChangeP2(v, 3 + flags, pTab->tnum); sqlite3VdbeChangeP3(v, 3 + flags, iDb); diff --git a/src/where.c b/src/where.c index 21fb7f45f..17490b0e8 100644 --- a/src/where.c +++ b/src/where.c @@ -1994,8 +1994,7 @@ static void constructAutomaticIndex( v = pParse->pVdbe; assert( v!=0 ); regIsInit = ++pParse->nMem; - addrInit = sqlite3VdbeAddOp1(v, OP_If, regIsInit); - sqlite3VdbeAddOp2(v, OP_Integer, 1, regIsInit); + addrInit = sqlite3VdbeAddOp1(v, OP_Once, regIsInit); /* Count the number of columns that will be added to the index ** and used to match WHERE clause constraints */ |