Index: src/alter.c ================================================================== --- src/alter.c +++ src/alter.c @@ -10,11 +10,11 @@ ** ************************************************************************* ** This file contains C code routines that used to generate VDBE code ** that implements the ALTER TABLE command. ** -** $Id: alter.c,v 1.36 2008/01/03 00:01:24 drh Exp $ +** $Id: alter.c,v 1.37 2008/01/03 18:39:42 danielk1977 Exp $ */ #include "sqliteInt.h" #include /* @@ -360,12 +360,14 @@ ** of any resources used by the v-table implementation (including other ** SQLite tables) that are identified by the name of the virtual table. */ #ifndef SQLITE_OMIT_VIRTUALTABLE if( isVirtualRename ){ + int i; sqlite3VdbeAddOp4(v, OP_String8, 0, 0, 0, zName, 0); - sqlite3VdbeAddOp4(v, OP_VRename, 0, 0, 0,(const char*)pTab->pVtab, P4_VTAB); + i = sqlite3StackToReg(pParse, 1); + sqlite3VdbeAddOp4(v, OP_VRename, i, 0, 0,(const char*)pTab->pVtab, P4_VTAB); } #endif /* figure out how many UTF-8 characters are in zName */ zTabName = pTab->zName; Index: src/vdbe.c ================================================================== --- src/vdbe.c +++ src/vdbe.c @@ -41,11 +41,11 @@ ** documentation, headers files, or other derived files. The formatting ** of the code in this file is, therefore, important. See other comments ** in this file for details. If in doubt, do not deviate from existing ** commenting and indentation practices when changing or adding code. ** -** $Id: vdbe.c,v 1.671 2008/01/03 18:03:09 drh Exp $ +** $Id: vdbe.c,v 1.672 2008/01/03 18:39:42 danielk1977 Exp $ */ #include "sqliteInt.h" #include #include "vdbeInt.h" @@ -4986,59 +4986,57 @@ break; } #endif /* SQLITE_OMIT_VIRTUALTABLE */ #ifndef SQLITE_OMIT_VIRTUALTABLE -/* Opcode: VFilter P1 P2 P4 +/* Opcode: VFilter P1 P2 P3 P4 * ** ** P1 is a cursor opened using VOpen. P2 is an address to jump to if ** the filtered result set is empty. ** ** P4 is either NULL or a string that was generated by the xBestIndex ** method of the module. The interpretation of the P4 string is left ** to the module implementation. ** ** This opcode invokes the xFilter method on the virtual table specified -** by P1. The integer query plan parameter to xFilter is the top of the -** stack. Next down on the stack is the argc parameter. Beneath the -** next of stack are argc additional parameters which are passed to -** xFilter as argv. The topmost parameter (i.e. 3rd element popped from -** the stack) becomes argv[argc-1] when passed to xFilter. -** -** The integer query plan parameter, argc, and all argv stack values -** are popped from the stack before this instruction completes. -** -** A jump is made to P2 if the result set after filtering would be -** empty. +** by P1. The integer query plan parameter to xFilter is stored in register +** P3. Register P3+1 stores the argc parameter to be passed to the +** xFilter method. Registers P3+2..P3+1+argc are the argc additional +** parametersneath additional parameters which are passed to +** xFilter as argv. Register P3+2 becomes argv[0] when passed to xFilter. +** +** A jump is made to P2 if the result set after filtering would be empty. */ case OP_VFilter: { /* no-push */ int nArg; - + int iQuery; const sqlite3_module *pModule; + Mem *pQuery = &p->aMem[pOp->p3]; + Mem *pArgc = &pQuery[1]; Cursor *pCur = p->apCsr[pOp->p1]; assert( pCur->pVtabCursor ); pModule = pCur->pVtabCursor->pVtab->pModule; /* Grab the index number and argc parameters off the top of the stack. */ - assert( (&pTos[-1])>=p->aStack ); - assert( (pTos[0].flags&MEM_Int)!=0 && pTos[-1].flags==MEM_Int ); - nArg = pTos[-1].u.i; + assert( (pQuery->flags&MEM_Int)!=0 && pArgc->flags==MEM_Int ); + nArg = pArgc->u.i; + iQuery = pQuery->u.i; /* Invoke the xFilter method */ { int res = 0; int i; Mem **apArg = p->apArg; for(i = 0; iinVtabMethod = 1; - rc = pModule->xFilter(pCur->pVtabCursor, pTos->u.i, pOp->p4.z, nArg, apArg); + rc = pModule->xFilter(pCur->pVtabCursor, iQuery, pOp->p4.z, nArg, apArg); p->inVtabMethod = 0; if( rc==SQLITE_OK ){ res = pModule->xEof(pCur->pVtabCursor); } if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse; @@ -5046,12 +5044,10 @@ if( res ){ pc = pOp->p2 - 1; } } - /* Pop the index number, argc value and parameters off the stack */ - popStack(&pTos, 2+nArg); break; } #endif /* SQLITE_OMIT_VIRTUALTABLE */ #ifndef SQLITE_OMIT_VIRTUALTABLE @@ -5171,30 +5167,29 @@ break; } #endif /* SQLITE_OMIT_VIRTUALTABLE */ #ifndef SQLITE_OMIT_VIRTUALTABLE -/* Opcode: VRename * * P4 +/* Opcode: VRename P1 * P4 ** ** P4 is a pointer to a virtual table object, an sqlite3_vtab structure. ** This opcode invokes the corresponding xRename method. The value -** on the top of the stack is popped and passed as the zName argument -** to the xRename method. +** in register P1 is passed as the zName argument to the xRename method. */ case OP_VRename: { /* no-push */ sqlite3_vtab *pVtab = pOp->p4.pVtab; + Mem *pName = &p->aMem[pOp->p1]; assert( pVtab->pModule->xRename ); - Stringify(pTos, encoding); + Stringify(pName, encoding); if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse; sqlite3VtabLock(pVtab); - rc = pVtab->pModule->xRename(pVtab, pTos->z); + rc = pVtab->pModule->xRename(pVtab, pName->z); sqlite3VtabUnlock(db, pVtab); if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse; - popStack(&pTos, 1); break; } #endif #ifndef SQLITE_OMIT_VIRTUALTABLE Index: src/vdbeaux.c ================================================================== --- src/vdbeaux.c +++ src/vdbeaux.c @@ -331,12 +331,12 @@ }else if( opcode==OP_VUpdate || opcode==OP_VRename ){ doesStatementRollback = 1; }else if( opcode==OP_VFilter ){ int n; assert( p->nOp - i >= 3 ); - assert( pOp[-2].opcode==OP_Integer ); - n = pOp[-2].p1; + assert( pOp[-1].opcode==OP_MemInt ); + n = pOp[-1].p1; if( n>nMaxArgs ) nMaxArgs = n; #endif } if( opcodeNoPush(opcode) ){ nMaxStack--; Index: src/where.c ================================================================== --- src/where.c +++ src/where.c @@ -14,11 +14,11 @@ ** generating the code that loops through a table looking for applicable ** rows. Indices are selected and used to speed the search when doing ** so is applicable. Because this module is responsible for selecting ** indices, you might also think of this module as the "query optimizer". ** -** $Id: where.c,v 1.270 2008/01/03 18:03:09 drh Exp $ +** $Id: where.c,v 1.271 2008/01/03 18:39:42 danielk1977 Exp $ */ #include "sqliteInt.h" /* ** The number of bits in a Bitmask. "BMS" means "BitMask Size". @@ -2269,10 +2269,11 @@ if( pLevel->pBestIdx ){ /* Case 0: The table is a virtual-table. Use the VFilter and VNext ** to access the data. */ int j; + int iReg; /* P3 Value for OP_VFilter */ sqlite3_index_info *pBestIdx = pLevel->pBestIdx; int nConstraint = pBestIdx->nConstraint; struct sqlite3_index_constraint_usage *aUsage = pBestIdx->aConstraintUsage; const struct sqlite3_index_constraint *aConstraint = @@ -2287,13 +2288,16 @@ break; } } if( k==nConstraint ) break; } - sqlite3VdbeAddOp2(v, OP_Integer, j-1, 0); - sqlite3VdbeAddOp2(v, OP_Integer, pBestIdx->idxNum, 0); - sqlite3VdbeAddOp4(v, OP_VFilter, iCur, brk, 0, pBestIdx->idxStr, + iReg = ++pParse->nMem; + pParse->nMem++; + sqlite3StackToReg(pParse, j-1); + sqlite3VdbeAddOp2(v, OP_MemInt, pBestIdx->idxNum, iReg); + sqlite3VdbeAddOp2(v, OP_MemInt, j-1, iReg+1); + sqlite3VdbeAddOp4(v, OP_VFilter, iCur, brk, iReg, pBestIdx->idxStr, pBestIdx->needToFreeIdxStr ? P4_MPRINTF : P4_STATIC); pBestIdx->needToFreeIdxStr = 0; for(j=0; jnConstraint; j++){ if( aUsage[j].omit ){ int iTerm = aConstraint[j].iTermOffset;