SQLite

Check-in [253ed40aa3]
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
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 253ed40aa36247fc846cc41c8612cd29899d9f8f
User & Date: danielk1977 2008-01-03 18:39:42.000
Context
2008-01-03
18:44
Update OP_Rowid, OP_Column and related opcodes to use registers. (CVS 4671) (check-in: 4f3967073d user: drh tags: trunk)
18:39
Modify VFilter and VRename to use registers instead of the vdbe stack for inputs. (CVS 4670) (check-in: 253ed40aa3 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: 0b849805c3 user: drh tags: trunk)
Changes
Side-by-Side Diff Ignore Whitespace Patch
Changes to src/alter.c.
8
9
10
11
12
13
14
15

16
17
18
19
20
21
22
8
9
10
11
12
13
14

15
16
17
18
19
20
21
22







-
+







**    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 $
** $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.
358
359
360
361
362
363
364

365

366

367
368
369
370
371
372
373
358
359
360
361
362
363
364
365
366
367

368
369
370
371
372
373
374
375







+

+
-
+







  /* 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, 0, 0, 0,(const char*)pTab->pVtab, P4_VTAB);
    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
39
40
41
42
43
44
45

46
47
48
49
50
51
52
53







-
+







**
** 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 $
** $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
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
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







-
+









-
-
-
+
+
+
+
-
-
+

-
-
-
-
+
-



-
+

+
+






-
-
-
+
+
+







-
+





-
+











-
-







    }
  }
  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
** 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. The topmost parameter (i.e. 3rd element popped from
** the stack) becomes argv[argc-1] when passed to xFilter.
** xFilter as argv. Register P3+2 becomes argv[0] 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 
** A jump is made to P2 if the result set after filtering would be empty.
** 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; i<nArg; i++){
      apArg[i] = &pTos[i+1-2-nArg];
      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, 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;

    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 * *
**
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
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







-
+



-
-
+



+


-
+



-
+



-







  }

  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
/* 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
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;
      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
12
13
14
15
16
17
18

19
20
21
22
23
24
25
26







-
+







** 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 $
** $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)
2267
2268
2269
2270
2271
2272
2273

2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291



2292
2293
2294



2295
2296
2297
2298
2299
2300
2301
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295



2296
2297
2298
2299
2300
2301
2302
2303
2304
2305







+


















+
+
+
-
-
-
+
+
+








#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;

      for(j=1; j<=nConstraint; j++){
        int k;
        for(k=0; k<nConstraint; k++){
          if( aUsage[k].argvIndex==j ){
            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_Integer, j-1, 0);
      sqlite3VdbeAddOp2(v, OP_Integer, pBestIdx->idxNum, 0);
      sqlite3VdbeAddOp4(v, OP_VFilter, iCur, brk, 0, pBestIdx->idxStr,
      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]);
        }