/ Check-in [253ed40a]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Modify VFilter and VRename to use registers instead of the vdbe stack for inputs. (CVS 4670)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 253ed40aa36247fc846cc41c8612cd29899d9f8f
User & Date: danielk1977 2008-01-03 18:39:42
Context
2008-01-03
18:44
Update OP_Rowid, OP_Column and related opcodes to use registers. (CVS 4671) check-in: 4f396707 user: drh tags: trunk
18:39
Modify VFilter and VRename to use registers instead of the vdbe stack for inputs. (CVS 4670) check-in: 253ed40a user: danielk1977 tags: trunk
18:03
Registers (aka memory cells) in the VM are now numbered starting with 1 instead of 0. A register number of 0 means "no such register". (CVS 4669) check-in: 0b849805 user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Show Whitespace Changes Patch

Changes to src/alter.c.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
358
359
360
361
362
363
364

365

366
367
368
369
370
371
372
373
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** 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 $
*/
#include "sqliteInt.h"
#include <ctype.h>

/*
** The code in this file only exists if we are not omitting the
** ALTER TABLE logic from the build.
................................................................................
  /* If this is a virtual table, invoke the xRename() function if
  ** one is defined. The xRename() callback will modify the names
  ** 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 ){

    sqlite3VdbeAddOp4(v, OP_String8, 0, 0, 0, zName, 0);

    sqlite3VdbeAddOp4(v, OP_VRename, 0, 0, 0,(const char*)pTab->pVtab, P4_VTAB);
  }
#endif

  /* figure out how many UTF-8 characters are in zName */
  zTabName = pTab->zName;
  nTabName = sqlite3Utf8CharLen(zTabName, -1);








|







 







>

>
|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains C code routines that used to generate VDBE code
** that implements the ALTER TABLE command.
**
** $Id: alter.c,v 1.37 2008/01/03 18:39:42 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

/*
** The code in this file only exists if we are not omitting the
** ALTER TABLE logic from the build.
................................................................................
  /* If this is a virtual table, invoke the xRename() function if
  ** one is defined. The xRename() callback will modify the names
  ** 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);
    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;
  nTabName = sqlite3Utf8CharLen(zTabName, -1);

Changes to src/vdbe.c.

39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
....
4984
4985
4986
4987
4988
4989
4990
4991
4992
4993
4994
4995
4996
4997
4998
4999
5000
5001
5002

5003
5004
5005
5006
5007
5008
5009
5010
5011
5012
5013
5014
5015

5016


5017
5018
5019
5020
5021
5022
5023
5024
5025
5026
5027
5028
5029
5030
5031
5032
5033
5034
5035
5036
5037
5038
5039
5040
5041
5042
5043
5044
5045
5046
5047
5048
5049
5050
5051
5052
5053
5054
5055
5056
5057
5058
5059
....
5169
5170
5171
5172
5173
5174
5175
5176
5177
5178
5179
5180
5181
5182
5183
5184

5185
5186
5187
5188
5189
5190
5191
5192
5193
5194
5195
5196
5197
5198
5199
5200
5201
5202
**
** Various scripts scan this source file in order to generate HTML
** 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 $
*/
#include "sqliteInt.h"
#include <ctype.h>
#include "vdbeInt.h"

/*
** The following global variable is incremented every time a cursor
................................................................................
    }
  }
  break;
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */

#ifndef SQLITE_OMIT_VIRTUALTABLE
/* Opcode: VFilter P1 P2 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.
*/
case OP_VFilter: {   /* no-push */
  int nArg;


  const sqlite3_module *pModule;



  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;

  /* Invoke the xFilter method */
  {
    int res = 0;
    int i;
    Mem **apArg = p->apArg;
    for(i = 0; i<nArg; i++){
      apArg[i] = &pTos[i+1-2-nArg];
      storeTypeInfo(apArg[i], 0);
    }

    if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
    p->inVtabMethod = 1;
    rc = pModule->xFilter(pCur->pVtabCursor, pTos->u.i, 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;

    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
/* Opcode: VRowid P1 * *
**
................................................................................
  }

  break;
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */

#ifndef SQLITE_OMIT_VIRTUALTABLE
/* Opcode: VRename * * 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.
*/
case OP_VRename: {   /* no-push */
  sqlite3_vtab *pVtab = pOp->p4.pVtab;

  assert( pVtab->pModule->xRename );

  Stringify(pTos, encoding);

  if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
  sqlite3VtabLock(pVtab);
  rc = pVtab->pModule->xRename(pVtab, pTos->z);
  sqlite3VtabUnlock(db, pVtab);
  if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse;

  popStack(&pTos, 1);
  break;
}
#endif

#ifndef SQLITE_OMIT_VIRTUALTABLE
/* Opcode: VUpdate P1 P2 P3 P4
**







|







 







|









|
|
>
|
<
|

<
<
<
|
<



<
>

>
>






|
|
|







|





|











<
<







 







|



<
|



>


|



|



<







39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
....
4984
4985
4986
4987
4988
4989
4990
4991
4992
4993
4994
4995
4996
4997
4998
4999
5000
5001
5002
5003
5004

5005
5006



5007

5008
5009
5010

5011
5012
5013
5014
5015
5016
5017
5018
5019
5020
5021
5022
5023
5024
5025
5026
5027
5028
5029
5030
5031
5032
5033
5034
5035
5036
5037
5038
5039
5040
5041
5042
5043
5044
5045
5046
5047
5048


5049
5050
5051
5052
5053
5054
5055
....
5165
5166
5167
5168
5169
5170
5171
5172
5173
5174
5175

5176
5177
5178
5179
5180
5181
5182
5183
5184
5185
5186
5187
5188
5189
5190

5191
5192
5193
5194
5195
5196
5197
**
** Various scripts scan this source file in order to generate HTML
** 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.672 2008/01/03 18:39:42 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
#include "vdbeInt.h"

/*
** The following global variable is incremented every time a cursor
................................................................................
    }
  }
  break;
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */

#ifndef SQLITE_OMIT_VIRTUALTABLE
/* 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 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( (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; i<nArg; i++){
      apArg[i] = &pArgc[i+1];
      storeTypeInfo(apArg[i], 0);
    }

    if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
    p->inVtabMethod = 1;
    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;

    if( res ){
      pc = pOp->p2 - 1;
    }
  }



  break;
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */

#ifndef SQLITE_OMIT_VIRTUALTABLE
/* Opcode: VRowid P1 * *
**
................................................................................
  }

  break;
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */

#ifndef SQLITE_OMIT_VIRTUALTABLE
/* 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

** 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(pName, encoding);

  if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
  sqlite3VtabLock(pVtab);
  rc = pVtab->pModule->xRename(pVtab, pName->z);
  sqlite3VtabUnlock(db, pVtab);
  if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse;


  break;
}
#endif

#ifndef SQLITE_OMIT_VIRTUALTABLE
/* Opcode: VUpdate P1 P2 P3 P4
**

Changes to src/vdbeaux.c.

329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
      doesStatementRollback = 1;
#ifndef SQLITE_OMIT_VIRTUALTABLE
    }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;
      if( n>nMaxArgs ) nMaxArgs = n;
#endif
    }
    if( opcodeNoPush(opcode) ){
      nMaxStack--;
    }








|
|







329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
      doesStatementRollback = 1;
#ifndef SQLITE_OMIT_VIRTUALTABLE
    }else if( opcode==OP_VUpdate || opcode==OP_VRename ){
      doesStatementRollback = 1;
    }else if( opcode==OP_VFilter ){
      int n;
      assert( p->nOp - i >= 3 );
      assert( pOp[-1].opcode==OP_MemInt );
      n = pOp[-1].p1;
      if( n>nMaxArgs ) nMaxArgs = n;
#endif
    }
    if( opcodeNoPush(opcode) ){
      nMaxStack--;
    }

Changes to src/where.c.

12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
....
2267
2268
2269
2270
2271
2272
2273

2274
2275
2276
2277
2278
2279
2280
....
2285
2286
2287
2288
2289
2290
2291



2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
** This module contains C code that generates VDBE code used to process
** the WHERE clause of SQL statements.  This module is reponsible for
** 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 $
*/
#include "sqliteInt.h"

/*
** The number of bits in a Bitmask.  "BMS" means "BitMask Size".
*/
#define BMS  (sizeof(Bitmask)*8)
................................................................................

#ifndef SQLITE_OMIT_VIRTUALTABLE
    if( pLevel->pBestIdx ){
      /* Case 0:  The table is a virtual-table.  Use the VFilter and VNext
      **          to access the data.
      */
      int j;

      sqlite3_index_info *pBestIdx = pLevel->pBestIdx;
      int nConstraint = pBestIdx->nConstraint;
      struct sqlite3_index_constraint_usage *aUsage =
                                                  pBestIdx->aConstraintUsage;
      const struct sqlite3_index_constraint *aConstraint =
                                                  pBestIdx->aConstraint;

................................................................................
            int iTerm = aConstraint[k].iTermOffset;
            sqlite3ExprCode(pParse, wc.a[iTerm].pExpr->pRight);
            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,
                        pBestIdx->needToFreeIdxStr ? P4_MPRINTF : P4_STATIC);
      pBestIdx->needToFreeIdxStr = 0;
      for(j=0; j<pBestIdx->nConstraint; j++){
        if( aUsage[j].omit ){
          int iTerm = aConstraint[j].iTermOffset;
          disableTerm(pLevel, &wc.a[iTerm]);
        }







|







 







>







 







>
>
>
|
|
|







12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
....
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
....
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
** This module contains C code that generates VDBE code used to process
** the WHERE clause of SQL statements.  This module is reponsible for
** 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.271 2008/01/03 18:39:42 danielk1977 Exp $
*/
#include "sqliteInt.h"

/*
** The number of bits in a Bitmask.  "BMS" means "BitMask Size".
*/
#define BMS  (sizeof(Bitmask)*8)
................................................................................

#ifndef SQLITE_OMIT_VIRTUALTABLE
    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 =
                                                  pBestIdx->aConstraint;

................................................................................
            int iTerm = aConstraint[k].iTermOffset;
            sqlite3ExprCode(pParse, wc.a[iTerm].pExpr->pRight);
            break;
          }
        }
        if( k==nConstraint ) break;
      }
      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; j<pBestIdx->nConstraint; j++){
        if( aUsage[j].omit ){
          int iTerm = aConstraint[j].iTermOffset;
          disableTerm(pLevel, &wc.a[iTerm]);
        }