/ Check-in [35da261d]
Login
SQLite training in Houston TX on 2019-11-05 (details)
Part of the 2019 Tcl Conference

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

Overview
Comment:Change OP_OpenRead and OP_OpenWrite so that the database number is read from the P3 operand, not the stack. (CVS 4663)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 35da261daf602b1e938f05bbad1ff99213d9f4b9
User & Date: danielk1977 2008-01-03 07:54:24
Context
2008-01-03
08:08
Combine the OP_Column and OP_DfltValue opcodes. (CVS 4664) check-in: c30f8206 user: danielk1977 tags: trunk
07:54
Change OP_OpenRead and OP_OpenWrite so that the database number is read from the P3 operand, not the stack. (CVS 4663) check-in: 35da261d user: danielk1977 tags: trunk
07:09
Fix EXPLAIN and EXPLAIN query plan to work with new opcode format. (CVS 4662) check-in: b166c33a user: danielk1977 tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/analyze.c.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
..
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
...
118
119
120
121
122
123
124
125
126
127
128

129
130
131
132
133
134
135
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains code associated with the ANALYZE command.
**
** @(#) $Id: analyze.c,v 1.27 2008/01/03 00:01:24 drh Exp $
*/
#ifndef SQLITE_OMIT_ANALYZE
#include "sqliteInt.h"

/*
** This routine generates code that opens the sqlite_stat1 table on cursor
** iStatCur.
................................................................................
  ** by this vdbe program, lock it for writing at the shared-cache level. 
  ** If this vdbe did create the sqlite_stat1 table, then it must have 
  ** already obtained a schema-lock, making the write-lock redundant.
  */
  if( iRootPage>0 ){
    sqlite3TableLock(pParse, iDb, iRootPage, 1, "sqlite_stat1");
  }
  sqlite3VdbeAddOp1(v, OP_Integer, iDb);
  sqlite3VdbeAddOp2(v, OP_OpenWrite, iStatCur, iRootPage);
  sqlite3VdbeAddOp2(v, OP_SetNumColumns, iStatCur, 3);
}

/*
** Generate code to do an analysis of all indices associated with
** a single table.
*/
................................................................................
  iIdxCur = pParse->nTab;
  for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
    KeyInfo *pKey = sqlite3IndexKeyinfo(pParse, pIdx);

    /* Open a cursor to the index to be analyzed
    */
    assert( iDb==sqlite3SchemaToIndex(pParse->db, pIdx->pSchema) );
    sqlite3VdbeAddOp1(v, OP_Integer, iDb);
    VdbeComment((v, "%s", pIdx->zName));
    sqlite3VdbeAddOp4(v, OP_OpenRead, iIdxCur, pIdx->tnum, 0,
        (char *)pKey, P4_KEYINFO_HANDOFF);

    nCol = pIdx->nColumn;
    if( iMem+nCol*2>=pParse->nMem ){
      pParse->nMem = iMem+nCol*2+1;
    }
    sqlite3VdbeAddOp2(v, OP_SetNumColumns, iIdxCur, nCol+1);

    /* Memory cells are used as follows:







|







 







<
|







 







<
<
|

>







7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
..
68
69
70
71
72
73
74

75
76
77
78
79
80
81
82
...
117
118
119
120
121
122
123


124
125
126
127
128
129
130
131
132
133
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains code associated with the ANALYZE command.
**
** @(#) $Id: analyze.c,v 1.28 2008/01/03 07:54:24 danielk1977 Exp $
*/
#ifndef SQLITE_OMIT_ANALYZE
#include "sqliteInt.h"

/*
** This routine generates code that opens the sqlite_stat1 table on cursor
** iStatCur.
................................................................................
  ** by this vdbe program, lock it for writing at the shared-cache level. 
  ** If this vdbe did create the sqlite_stat1 table, then it must have 
  ** already obtained a schema-lock, making the write-lock redundant.
  */
  if( iRootPage>0 ){
    sqlite3TableLock(pParse, iDb, iRootPage, 1, "sqlite_stat1");
  }

  sqlite3VdbeAddOp3(v, OP_OpenWrite, iStatCur, iRootPage, iDb);
  sqlite3VdbeAddOp2(v, OP_SetNumColumns, iStatCur, 3);
}

/*
** Generate code to do an analysis of all indices associated with
** a single table.
*/
................................................................................
  iIdxCur = pParse->nTab;
  for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
    KeyInfo *pKey = sqlite3IndexKeyinfo(pParse, pIdx);

    /* Open a cursor to the index to be analyzed
    */
    assert( iDb==sqlite3SchemaToIndex(pParse->db, pIdx->pSchema) );


    sqlite3VdbeAddOp4(v, OP_OpenRead, iIdxCur, pIdx->tnum, iDb,
        (char *)pKey, P4_KEYINFO_HANDOFF);
    VdbeComment((v, "%s", pIdx->zName));
    nCol = pIdx->nColumn;
    if( iMem+nCol*2>=pParse->nMem ){
      pParse->nMem = iMem+nCol*2+1;
    }
    sqlite3VdbeAddOp2(v, OP_SetNumColumns, iIdxCur, nCol+1);

    /* Memory cells are used as follows:

Changes to src/build.c.

18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
...
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
....
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
....
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
**     CREATE INDEX
**     DROP INDEX
**     creating ID lists
**     BEGIN TRANSACTION
**     COMMIT
**     ROLLBACK
**
** $Id: build.c,v 1.453 2008/01/03 00:01:24 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

/*
** This routine is called when a new SQL statement is beginning to
** be parsed.  Initialize the pParse structure as needed.
................................................................................
/*
** Open the sqlite_master table stored in database number iDb for
** writing. The table is opened using cursor 0.
*/
void sqlite3OpenMasterTable(Parse *p, int iDb){
  Vdbe *v = sqlite3GetVdbe(p);
  sqlite3TableLock(p, iDb, MASTER_ROOT, 1, SCHEMA_TABLE(iDb));
  sqlite3VdbeAddOp1(v, OP_Integer, iDb);
  sqlite3VdbeAddOp2(v, OP_OpenWrite, 0, MASTER_ROOT);
  sqlite3VdbeAddOp2(v, OP_SetNumColumns, 0, 5); /* sqlite_master has 5 columns */
}

/*
** The token *pName contains the name of a database (either "main" or
** "temp" or the name of an attached db). This routine returns the
** index of the named database in db->aDb[], or -1 if the named db 
................................................................................
    ** a schema-lock excludes all other database users, the write-lock would
    ** be redundant.
    */
    if( pSelect ){
      SelectDest dest = {SRT_Table, 1, 0};
      Table *pSelTab;
      sqlite3VdbeAddOp1(v, OP_Dup, 0);
      sqlite3VdbeAddOp1(v, OP_Integer, iDb);
      sqlite3VdbeAddOp2(v, OP_OpenWrite, 1, 0);
      pParse->nTab = 2;
      sqlite3Select(pParse, pSelect, &dest, 0, 0, 0, 0);
      sqlite3VdbeAddOp1(v, OP_Close, 1);
      if( pParse->nErr==0 ){
        pSelTab = sqlite3ResultSetOfSelect(pParse, 0, pSelect);
        if( pSelTab==0 ) return;
        assert( p->aCol==0 );
................................................................................
  if( memRootPage>=0 ){
    sqlite3VdbeAddOp1(v, OP_MemLoad, memRootPage);
    tnum = 0;
  }else{
    tnum = pIndex->tnum;
    sqlite3VdbeAddOp2(v, OP_Clear, tnum, iDb);
  }
  sqlite3VdbeAddOp1(v, OP_Integer, iDb);
  pKey = sqlite3IndexKeyinfo(pParse, pIndex);
  sqlite3VdbeAddOp4(v, OP_OpenWrite, iIdx, tnum, 0, 
                    (char *)pKey, P4_KEYINFO_HANDOFF);
  sqlite3OpenTable(pParse, iTab, iDb, pTab, OP_OpenRead);
  addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iTab, 0);
  sqlite3GenerateIndexKey(v, pIndex, iTab);
  if( pIndex->onError!=OE_None ){
    int curaddr = sqlite3VdbeCurrentAddr(v);
    int addr2 = curaddr+4;







|







 







<
|







 







<
|







 







<

|







18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
...
596
597
598
599
600
601
602

603
604
605
606
607
608
609
610
....
1490
1491
1492
1493
1494
1495
1496

1497
1498
1499
1500
1501
1502
1503
1504
....
2237
2238
2239
2240
2241
2242
2243

2244
2245
2246
2247
2248
2249
2250
2251
2252
**     CREATE INDEX
**     DROP INDEX
**     creating ID lists
**     BEGIN TRANSACTION
**     COMMIT
**     ROLLBACK
**
** $Id: build.c,v 1.454 2008/01/03 07:54:24 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

/*
** This routine is called when a new SQL statement is beginning to
** be parsed.  Initialize the pParse structure as needed.
................................................................................
/*
** Open the sqlite_master table stored in database number iDb for
** writing. The table is opened using cursor 0.
*/
void sqlite3OpenMasterTable(Parse *p, int iDb){
  Vdbe *v = sqlite3GetVdbe(p);
  sqlite3TableLock(p, iDb, MASTER_ROOT, 1, SCHEMA_TABLE(iDb));

  sqlite3VdbeAddOp3(v, OP_OpenWrite, 0, MASTER_ROOT, iDb);
  sqlite3VdbeAddOp2(v, OP_SetNumColumns, 0, 5); /* sqlite_master has 5 columns */
}

/*
** The token *pName contains the name of a database (either "main" or
** "temp" or the name of an attached db). This routine returns the
** index of the named database in db->aDb[], or -1 if the named db 
................................................................................
    ** a schema-lock excludes all other database users, the write-lock would
    ** be redundant.
    */
    if( pSelect ){
      SelectDest dest = {SRT_Table, 1, 0};
      Table *pSelTab;
      sqlite3VdbeAddOp1(v, OP_Dup, 0);

      sqlite3VdbeAddOp3(v, OP_OpenWrite, 1, 0, iDb);
      pParse->nTab = 2;
      sqlite3Select(pParse, pSelect, &dest, 0, 0, 0, 0);
      sqlite3VdbeAddOp1(v, OP_Close, 1);
      if( pParse->nErr==0 ){
        pSelTab = sqlite3ResultSetOfSelect(pParse, 0, pSelect);
        if( pSelTab==0 ) return;
        assert( p->aCol==0 );
................................................................................
  if( memRootPage>=0 ){
    sqlite3VdbeAddOp1(v, OP_MemLoad, memRootPage);
    tnum = 0;
  }else{
    tnum = pIndex->tnum;
    sqlite3VdbeAddOp2(v, OP_Clear, tnum, iDb);
  }

  pKey = sqlite3IndexKeyinfo(pParse, pIndex);
  sqlite3VdbeAddOp4(v, OP_OpenWrite, iIdx, tnum, iDb, 
                    (char *)pKey, P4_KEYINFO_HANDOFF);
  sqlite3OpenTable(pParse, iTab, iDb, pTab, OP_OpenRead);
  addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iTab, 0);
  sqlite3GenerateIndexKey(v, pIndex, iTab);
  if( pIndex->onError!=OE_None ){
    int curaddr = sqlite3VdbeCurrentAddr(v);
    int addr2 = curaddr+4;

Changes to src/delete.c.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
..
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
**    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 are called by the parser
** in order to generate code for DELETE FROM statements.
**
** $Id: delete.c,v 1.140 2008/01/03 00:01:24 drh Exp $
*/
#include "sqliteInt.h"

/*
** Look up every table that is named in pSrc.  If any table is not found,
** add an error message to pParse->zErrMsg and return NULL.  If all tables
** are found, return a pointer to the last table.
................................................................................
  int opcode      /* OP_OpenRead or OP_OpenWrite */
){
  Vdbe *v;
  if( IsVirtual(pTab) ) return;
  v = sqlite3GetVdbe(p);
  assert( opcode==OP_OpenWrite || opcode==OP_OpenRead );
  sqlite3TableLock(p, iDb, pTab->tnum, (opcode==OP_OpenWrite), pTab->zName);
  sqlite3VdbeAddOp1(v, OP_Integer, iDb);
  VdbeComment((v, "%s", pTab->zName));
  sqlite3VdbeAddOp2(v, opcode, iCur, pTab->tnum);
  sqlite3VdbeAddOp2(v, OP_SetNumColumns, iCur, pTab->nCol);
}


/*
** Generate code for a DELETE FROM statement.
**







|







 







|

<







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
..
71
72
73
74
75
76
77
78
79

80
81
82
83
84
85
86
**    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 are called by the parser
** in order to generate code for DELETE FROM statements.
**
** $Id: delete.c,v 1.141 2008/01/03 07:54:24 danielk1977 Exp $
*/
#include "sqliteInt.h"

/*
** Look up every table that is named in pSrc.  If any table is not found,
** add an error message to pParse->zErrMsg and return NULL.  If all tables
** are found, return a pointer to the last table.
................................................................................
  int opcode      /* OP_OpenRead or OP_OpenWrite */
){
  Vdbe *v;
  if( IsVirtual(pTab) ) return;
  v = sqlite3GetVdbe(p);
  assert( opcode==OP_OpenWrite || opcode==OP_OpenRead );
  sqlite3TableLock(p, iDb, pTab->tnum, (opcode==OP_OpenWrite), pTab->zName);
  sqlite3VdbeAddOp3(v, opcode, iCur, pTab->tnum, iDb);
  VdbeComment((v, "%s", pTab->zName));

  sqlite3VdbeAddOp2(v, OP_SetNumColumns, iCur, pTab->nCol);
}


/*
** Generate code for a DELETE FROM statement.
**

Changes to src/expr.c.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
....
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653

1654
1655
1656
1657
1658
1659
1660
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains routines used for analyzing expressions and
** for generating VDBE code that evaluates expressions in SQLite.
**
** $Id: expr.c,v 1.325 2008/01/03 00:01:24 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

/*
** Return the 'affinity' of the expression pExpr if any.
**
................................................................................
          iDb = sqlite3SchemaToIndex(db, pIdx->pSchema);
          sqlite3VdbeUsesBtree(v, iDb);

          sqlite3VdbeAddOp1(v, OP_MemLoad, iMem);
          iAddr = sqlite3VdbeAddOp2(v, OP_If, 0, iMem);
          sqlite3VdbeAddOp2(v, OP_MemInt, 1, iMem);
  
          sqlite3VdbeAddOp1(v, OP_Integer, iDb);
          VdbeComment((v, "%s", pIdx->zName));
          sqlite3VdbeAddOp4(v, OP_OpenRead, iTab, pIdx->tnum, 0,
                               pKey,P4_KEYINFO_HANDOFF);

          eType = IN_INDEX_INDEX;
          sqlite3VdbeAddOp2(v, OP_SetNumColumns, iTab, pIdx->nColumn);

          sqlite3VdbeJumpHere(v, iAddr);
        }
      }
    }







|







 







<
<
|

>







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
....
1643
1644
1645
1646
1647
1648
1649


1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains routines used for analyzing expressions and
** for generating VDBE code that evaluates expressions in SQLite.
**
** $Id: expr.c,v 1.326 2008/01/03 07:54:24 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

/*
** Return the 'affinity' of the expression pExpr if any.
**
................................................................................
          iDb = sqlite3SchemaToIndex(db, pIdx->pSchema);
          sqlite3VdbeUsesBtree(v, iDb);

          sqlite3VdbeAddOp1(v, OP_MemLoad, iMem);
          iAddr = sqlite3VdbeAddOp2(v, OP_If, 0, iMem);
          sqlite3VdbeAddOp2(v, OP_MemInt, 1, iMem);
  


          sqlite3VdbeAddOp4(v, OP_OpenRead, iTab, pIdx->tnum, iDb,
                               pKey,P4_KEYINFO_HANDOFF);
          VdbeComment((v, "%s", pIdx->zName));
          eType = IN_INDEX_INDEX;
          sqlite3VdbeAddOp2(v, OP_SetNumColumns, iTab, pIdx->nColumn);

          sqlite3VdbeJumpHere(v, iAddr);
        }
      }
    }

Changes to src/insert.c.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
...
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
...
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
....
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288

1289
1290
1291
1292
1293
1294
1295
....
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589

1590
1591
1592
1593

1594
1595
1596
1597
1598
1599
1600
**    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 are called by the parser
** to handle INSERT statements in SQLite.
**
** $Id: insert.c,v 1.202 2008/01/03 00:01:24 drh Exp $
*/
#include "sqliteInt.h"

/*
** Set P4 of the most recently inserted opcode to a column affinity
** string for index pIdx. A column affinity string has one character
** for each column in the table, according to the affinity of the column:
................................................................................
*/
static int readsTable(Vdbe *v, int iStartAddr, int iDb, Table *pTab){
  int i;
  int iEnd = sqlite3VdbeCurrentAddr(v);
  for(i=iStartAddr; i<iEnd; i++){
    VdbeOp *pOp = sqlite3VdbeGetOp(v, i);
    assert( pOp!=0 );
    if( pOp->opcode==OP_OpenRead ){
      VdbeOp *pPrior = &pOp[-1];
      int tnum = pOp->p2;
      assert( i>iStartAddr );
      assert( pPrior->opcode==OP_Integer );
      if( pPrior->p1==iDb ){
        Index *pIndex;
        if( tnum==pTab->tnum ){
          return 1;
        }
        for(pIndex=pTab->pIndex; pIndex; pIndex=pIndex->pNext){
          if( tnum==pIndex->tnum ){
            return 1;
          }
        }
      }
    }
#ifndef SQLITE_OMIT_VIRTUALTABLE
    if( pOp->opcode==OP_VOpen && pOp->p4.p==(const char*)pTab->pVtab ){
      assert( pOp->p4.p!=0 );
      assert( pOp->p4type==P4_VTAB );
      return 1;
................................................................................
    int iCur = pParse->nTab;
    int addr;
    assert( v );
    addr = sqlite3VdbeCurrentAddr(v);
    memId = pParse->nMem+1;
    pParse->nMem += 2;
    sqlite3OpenTable(pParse, iCur, iDb, pDb->pSchema->pSeqTab, OP_OpenRead);
    sqlite3VdbeAddOp2(v, OP_Rewind, iCur, addr+13);
    sqlite3VdbeAddOp2(v, OP_Column, iCur, 0);
    sqlite3VdbeAddOp4(v, OP_String8, 0, 0, 0, pTab->zName, 0);
    sqlite3VdbeAddOp2(v, OP_Ne, 0x100, addr+12);
    sqlite3VdbeAddOp2(v, OP_Rowid, iCur, 0);
    sqlite3VdbeAddOp2(v, OP_MemStore, memId-1, 1);
    sqlite3VdbeAddOp2(v, OP_Column, iCur, 1);
    sqlite3VdbeAddOp2(v, OP_MemStore, memId, 1);
    sqlite3VdbeAddOp2(v, OP_Goto, 0, addr+13);
    sqlite3VdbeAddOp2(v, OP_Next, iCur, addr+4);
    sqlite3VdbeAddOp2(v, OP_Close, iCur, 0);
  }
  return memId;
}

/*
** Update the maximum rowid for an autoincrement calculation.
................................................................................
    Vdbe *v = pParse->pVdbe;
    Db *pDb = &pParse->db->aDb[iDb];
    int addr;
    assert( v );
    addr = sqlite3VdbeCurrentAddr(v);
    sqlite3OpenTable(pParse, iCur, iDb, pDb->pSchema->pSeqTab, OP_OpenWrite);
    sqlite3VdbeAddOp2(v, OP_MemLoad, memId-1, 0);
    sqlite3VdbeAddOp2(v, OP_NotNull, -1, addr+7);
    sqlite3VdbeAddOp2(v, OP_Pop, 1, 0);
    sqlite3VdbeAddOp2(v, OP_NewRowid, iCur, 0);
    sqlite3VdbeAddOp4(v, OP_String8, 0, 0, 0, pTab->zName, 0);
    sqlite3VdbeAddOp2(v, OP_MemLoad, memId, 0);
    sqlite3VdbeAddOp2(v, OP_MakeRecord, 2, 0);
    sqlite3VdbeAddOp2(v, OP_Insert, iCur, OPFLAG_APPEND);
    sqlite3VdbeAddOp2(v, OP_Close, iCur, 0);
................................................................................
  iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
  v = sqlite3GetVdbe(pParse);
  assert( v!=0 );
  sqlite3OpenTable(pParse, base, iDb, pTab, op);
  for(i=1, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
    KeyInfo *pKey = sqlite3IndexKeyinfo(pParse, pIdx);
    assert( pIdx->pSchema==pTab->pSchema );
    sqlite3VdbeAddOp2(v, OP_Integer, iDb, 0);
    VdbeComment((v, "%s", pIdx->zName));
    sqlite3VdbeAddOp4(v, op, i+base, pIdx->tnum, 0,
                      (char*)pKey, P4_KEYINFO_HANDOFF);

  }
  if( pParse->nTab<=base+i ){
    pParse->nTab = base+i;
  }
}


................................................................................
  for(pDestIdx=pDest->pIndex; pDestIdx; pDestIdx=pDestIdx->pNext){
    for(pSrcIdx=pSrc->pIndex; pSrcIdx; pSrcIdx=pSrcIdx->pNext){
      if( xferCompatibleIndex(pDestIdx, pSrcIdx) ) break;
    }
    assert( pSrcIdx );
    sqlite3VdbeAddOp2(v, OP_Close, iSrc, 0);
    sqlite3VdbeAddOp2(v, OP_Close, iDest, 0);
    sqlite3VdbeAddOp2(v, OP_Integer, iDbSrc, 0);
    pKey = sqlite3IndexKeyinfo(pParse, pSrcIdx);
    VdbeComment((v, "%s", pSrcIdx->zName));
    sqlite3VdbeAddOp4(v, OP_OpenRead, iSrc, pSrcIdx->tnum, 0,
                      (char*)pKey, P4_KEYINFO_HANDOFF);
    sqlite3VdbeAddOp2(v, OP_Integer, iDbDest, 0);

    pKey = sqlite3IndexKeyinfo(pParse, pDestIdx);
    VdbeComment((v, "%s", pDestIdx->zName));
    sqlite3VdbeAddOp4(v, OP_OpenWrite, iDest, pDestIdx->tnum, 0,
                      (char*)pKey, P4_KEYINFO_HANDOFF);

    addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iSrc, 0);
    sqlite3VdbeAddOp2(v, OP_RowKey, iSrc, 0);
    sqlite3VdbeAddOp2(v, OP_IdxInsert, iDest, 1);
    sqlite3VdbeAddOp2(v, OP_Next, iSrc, addr1+1);
    sqlite3VdbeJumpHere(v, addr1);
  }
  sqlite3VdbeJumpHere(v, emptySrcTest);







|







 







|
|

<
<
<
<
|
|
|
|
|
|
|
<







 







|


|




|
|







 







|







 







<
<
|

>







 







<

<
|

<
>

<
|

>







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
107
108
109
110
111
112
113
114
115
116




117
118
119
120
121
122
123

124
125
126
127
128
129
130
...
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
...
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
....
1273
1274
1275
1276
1277
1278
1279


1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
....
1571
1572
1573
1574
1575
1576
1577

1578

1579
1580

1581
1582

1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
**    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 are called by the parser
** to handle INSERT statements in SQLite.
**
** $Id: insert.c,v 1.203 2008/01/03 07:54:24 danielk1977 Exp $
*/
#include "sqliteInt.h"

/*
** Set P4 of the most recently inserted opcode to a column affinity
** string for index pIdx. A column affinity string has one character
** for each column in the table, according to the affinity of the column:
................................................................................
*/
static int readsTable(Vdbe *v, int iStartAddr, int iDb, Table *pTab){
  int i;
  int iEnd = sqlite3VdbeCurrentAddr(v);
  for(i=iStartAddr; i<iEnd; i++){
    VdbeOp *pOp = sqlite3VdbeGetOp(v, i);
    assert( pOp!=0 );
    if( pOp->opcode==OP_OpenRead && pOp->p3==iDb ){
      Index *pIndex;
      int tnum = pOp->p2;




      if( tnum==pTab->tnum ){
        return 1;
      }
      for(pIndex=pTab->pIndex; pIndex; pIndex=pIndex->pNext){
        if( tnum==pIndex->tnum ){
          return 1;
        }

      }
    }
#ifndef SQLITE_OMIT_VIRTUALTABLE
    if( pOp->opcode==OP_VOpen && pOp->p4.p==(const char*)pTab->pVtab ){
      assert( pOp->p4.p!=0 );
      assert( pOp->p4type==P4_VTAB );
      return 1;
................................................................................
    int iCur = pParse->nTab;
    int addr;
    assert( v );
    addr = sqlite3VdbeCurrentAddr(v);
    memId = pParse->nMem+1;
    pParse->nMem += 2;
    sqlite3OpenTable(pParse, iCur, iDb, pDb->pSchema->pSeqTab, OP_OpenRead);
    sqlite3VdbeAddOp2(v, OP_Rewind, iCur, addr+12);
    sqlite3VdbeAddOp2(v, OP_Column, iCur, 0);
    sqlite3VdbeAddOp4(v, OP_String8, 0, 0, 0, pTab->zName, 0);
    sqlite3VdbeAddOp2(v, OP_Ne, 0x100, addr+11);
    sqlite3VdbeAddOp2(v, OP_Rowid, iCur, 0);
    sqlite3VdbeAddOp2(v, OP_MemStore, memId-1, 1);
    sqlite3VdbeAddOp2(v, OP_Column, iCur, 1);
    sqlite3VdbeAddOp2(v, OP_MemStore, memId, 1);
    sqlite3VdbeAddOp2(v, OP_Goto, 0, addr+12);
    sqlite3VdbeAddOp2(v, OP_Next, iCur, addr+3);
    sqlite3VdbeAddOp2(v, OP_Close, iCur, 0);
  }
  return memId;
}

/*
** Update the maximum rowid for an autoincrement calculation.
................................................................................
    Vdbe *v = pParse->pVdbe;
    Db *pDb = &pParse->db->aDb[iDb];
    int addr;
    assert( v );
    addr = sqlite3VdbeCurrentAddr(v);
    sqlite3OpenTable(pParse, iCur, iDb, pDb->pSchema->pSeqTab, OP_OpenWrite);
    sqlite3VdbeAddOp2(v, OP_MemLoad, memId-1, 0);
    sqlite3VdbeAddOp2(v, OP_NotNull, -1, addr+6);
    sqlite3VdbeAddOp2(v, OP_Pop, 1, 0);
    sqlite3VdbeAddOp2(v, OP_NewRowid, iCur, 0);
    sqlite3VdbeAddOp4(v, OP_String8, 0, 0, 0, pTab->zName, 0);
    sqlite3VdbeAddOp2(v, OP_MemLoad, memId, 0);
    sqlite3VdbeAddOp2(v, OP_MakeRecord, 2, 0);
    sqlite3VdbeAddOp2(v, OP_Insert, iCur, OPFLAG_APPEND);
    sqlite3VdbeAddOp2(v, OP_Close, iCur, 0);
................................................................................
  iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
  v = sqlite3GetVdbe(pParse);
  assert( v!=0 );
  sqlite3OpenTable(pParse, base, iDb, pTab, op);
  for(i=1, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
    KeyInfo *pKey = sqlite3IndexKeyinfo(pParse, pIdx);
    assert( pIdx->pSchema==pTab->pSchema );


    sqlite3VdbeAddOp4(v, op, i+base, pIdx->tnum, iDb,
                      (char*)pKey, P4_KEYINFO_HANDOFF);
    VdbeComment((v, "%s", pIdx->zName));
  }
  if( pParse->nTab<=base+i ){
    pParse->nTab = base+i;
  }
}


................................................................................
  for(pDestIdx=pDest->pIndex; pDestIdx; pDestIdx=pDestIdx->pNext){
    for(pSrcIdx=pSrc->pIndex; pSrcIdx; pSrcIdx=pSrcIdx->pNext){
      if( xferCompatibleIndex(pDestIdx, pSrcIdx) ) break;
    }
    assert( pSrcIdx );
    sqlite3VdbeAddOp2(v, OP_Close, iSrc, 0);
    sqlite3VdbeAddOp2(v, OP_Close, iDest, 0);

    pKey = sqlite3IndexKeyinfo(pParse, pSrcIdx);

    sqlite3VdbeAddOp4(v, OP_OpenRead, iSrc, pSrcIdx->tnum, iDbSrc,
                      (char*)pKey, P4_KEYINFO_HANDOFF);

    VdbeComment((v, "%s", pSrcIdx->zName));
    pKey = sqlite3IndexKeyinfo(pParse, pDestIdx);

    sqlite3VdbeAddOp4(v, OP_OpenWrite, iDest, pDestIdx->tnum, iDbDest,
                      (char*)pKey, P4_KEYINFO_HANDOFF);
    VdbeComment((v, "%s", pDestIdx->zName));
    addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iSrc, 0);
    sqlite3VdbeAddOp2(v, OP_RowKey, iSrc, 0);
    sqlite3VdbeAddOp2(v, OP_IdxInsert, iDest, 1);
    sqlite3VdbeAddOp2(v, OP_Next, iSrc, addr1+1);
    sqlite3VdbeJumpHere(v, addr1);
  }
  sqlite3VdbeJumpHere(v, emptySrcTest);

Changes to src/select.c.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
....
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
**    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 are called by the parser
** to handle SELECT statements in SQLite.
**
** $Id: select.c,v 1.378 2008/01/03 00:01:25 drh Exp $
*/
#include "sqliteInt.h"


/*
** Delete all the content of a Select structure but do not deallocate
** the select structure itself.
................................................................................
    ** reused. This is important for statements of the form 
    ** "INSERT INTO x SELECT max() FROM x".
    */
    int iIdx;
    KeyInfo *pKey = sqlite3IndexKeyinfo(pParse, pIdx);
    iIdx = pParse->nTab++;
    assert( pIdx->pSchema==pTab->pSchema );
    sqlite3VdbeAddOp2(v, OP_Integer, iDb, 0);
    sqlite3VdbeAddOp4(v, OP_OpenRead, iIdx, pIdx->tnum, 0,
        (char*)pKey, P4_KEYINFO_HANDOFF);
    if( seekOp==OP_Rewind ){
      sqlite3VdbeAddOp2(v, OP_Null, 0, 0);
      sqlite3VdbeAddOp2(v, OP_MakeRecord, 1, 0);
      seekOp = OP_MoveGt;
    }
    if( pIdx->aSortOrder[0]==SQLITE_SO_DESC ){







|







 







<
|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
....
2745
2746
2747
2748
2749
2750
2751

2752
2753
2754
2755
2756
2757
2758
2759
**    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 are called by the parser
** to handle SELECT statements in SQLite.
**
** $Id: select.c,v 1.379 2008/01/03 07:54:24 danielk1977 Exp $
*/
#include "sqliteInt.h"


/*
** Delete all the content of a Select structure but do not deallocate
** the select structure itself.
................................................................................
    ** reused. This is important for statements of the form 
    ** "INSERT INTO x SELECT max() FROM x".
    */
    int iIdx;
    KeyInfo *pKey = sqlite3IndexKeyinfo(pParse, pIdx);
    iIdx = pParse->nTab++;
    assert( pIdx->pSchema==pTab->pSchema );

    sqlite3VdbeAddOp4(v, OP_OpenRead, iIdx, pIdx->tnum, iDb,
        (char*)pKey, P4_KEYINFO_HANDOFF);
    if( seekOp==OP_Rewind ){
      sqlite3VdbeAddOp2(v, OP_Null, 0, 0);
      sqlite3VdbeAddOp2(v, OP_MakeRecord, 1, 0);
      seekOp = OP_MoveGt;
    }
    if( pIdx->aSortOrder[0]==SQLITE_SO_DESC ){

Changes to src/update.c.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
**    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 are called by the parser
** to handle UPDATE statements.
**
** $Id: update.c,v 1.149 2008/01/03 00:01:25 drh Exp $
*/
#include "sqliteInt.h"

#ifndef SQLITE_OMIT_VIRTUALTABLE
/* Forward declaration */
static void updateVirtualTable(
  Parse *pParse,       /* The parsing context */
................................................................................
          break;
        }
      }
    }
    for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
      if( openAll || aIdxUsed[i] ){
        KeyInfo *pKey = sqlite3IndexKeyinfo(pParse, pIdx);
        sqlite3VdbeAddOp2(v, OP_Integer, iDb, 0);
        sqlite3VdbeAddOp4(v, OP_OpenWrite, iCur+i+1, pIdx->tnum, 0,
                       (char*)pKey, P4_KEYINFO_HANDOFF);
        assert( pParse->nTab>iCur+i+1 );
      }
    }

  }
  







|







 







<
|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
376
377
378
379
380
381
382

383
384
385
386
387
388
389
390
**    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 are called by the parser
** to handle UPDATE statements.
**
** $Id: update.c,v 1.150 2008/01/03 07:54:24 danielk1977 Exp $
*/
#include "sqliteInt.h"

#ifndef SQLITE_OMIT_VIRTUALTABLE
/* Forward declaration */
static void updateVirtualTable(
  Parse *pParse,       /* The parsing context */
................................................................................
          break;
        }
      }
    }
    for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
      if( openAll || aIdxUsed[i] ){
        KeyInfo *pKey = sqlite3IndexKeyinfo(pParse, pIdx);

        sqlite3VdbeAddOp4(v, OP_OpenWrite, iCur+i+1, pIdx->tnum, iDb,
                       (char*)pKey, P4_KEYINFO_HANDOFF);
        assert( pParse->nTab>iCur+i+1 );
      }
    }

  }
  

Changes to src/vdbe.c.

39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
....
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
....
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
....
2838
2839
2840
2841
2842
2843
2844

2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
....
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
**
** 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.665 2008/01/03 07:09:48 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
#include "vdbeInt.h"

/*
** The following global variable is incremented every time a cursor
................................................................................

    sqlite3ExpirePreparedStatements(db);
    rc = SQLITE_SCHEMA;
  }
  break;
}

/* Opcode: OpenRead P1 P2 P4
**
** Open a read-only cursor for the database table whose root page is
** P2 in a database file.  The database file is determined by an 
** integer from the top of the stack.  0 means the main database and
** 1 means the database used for temporary tables.  Give the new 
** cursor an identifier of P1.  The P1 values need not be contiguous
** but all P1 values should be small integers.  It is an error for
** P1 to be negative.
**
** If P2==0 then take the root page number from the next of the stack.
**
** There will be a read lock on the database whenever there is an
** open cursor.  If the database was unlocked prior to this instruction
** then a read lock is acquired as part of this instruction.  A read
** lock allows other processes to read the database but prohibits
** any other process from modifying the database.  The read lock is
** released when all cursors are closed.  If this instruction attempts
................................................................................
**
** The P4 value is a pointer to a KeyInfo structure that defines the
** content and collating sequence of indices.  P4 is NULL for cursors
** that are not pointing to indices.
**
** See also OpenWrite.
*/
/* Opcode: OpenWrite P1 P2 P4
**
** Open a read/write cursor named P1 on the table or index whose root
** page is P2.  If P2==0 then take the root page number from the stack.
**
** The P4 value is a pointer to a KeyInfo structure that defines the
** content and collating sequence of indices.  P4 is NULL for cursors
** that are not pointing to indices.
................................................................................
**
** See also OpenRead.
*/
case OP_OpenRead:          /* no-push */
case OP_OpenWrite: {       /* no-push */
  int i = pOp->p1;
  int p2 = pOp->p2;

  int wrFlag;
  Btree *pX;
  int iDb;
  Cursor *pCur;
  Db *pDb;
  
  assert( pTos>=p->aStack );
  sqlite3VdbeMemIntegerify(pTos);
  iDb = pTos->u.i;
  assert( (pTos->flags & MEM_Dyn)==0 );
  pTos--;
  assert( iDb>=0 && iDb<db->nDb );
  assert( (p->btreeMask & (1<<iDb))!=0 );
  pDb = &db->aDb[iDb];
  pX = pDb->pBt;
  assert( pX!=0 );
  if( pOp->opcode==OP_OpenWrite ){
    wrFlag = 1;
................................................................................
    pCur->pKeyInfo = 0;
    pCur->pIncrKey = &pCur->bogusIncrKey;
  }
  switch( rc ){
    case SQLITE_BUSY: {
      p->pc = pc;
      p->rc = rc = SQLITE_BUSY;
      p->pTos = &pTos[1 + (pOp->p2<=0)]; /* Operands must remain on stack */
      goto vdbe_return;
    }
    case SQLITE_OK: {
      int flags = sqlite3BtreeFlags(pCur->pCursor);
      /* Sanity checking.  Only the lower four bits of the flags byte should
      ** be used.  Bit 3 (mask 0x08) is unpreditable.  The lower 3 bits
      ** (mask 0x07) should be either 5 (intkey+leafdata for tables) or







|







 







|


|
|
<
|
|
|

|







 







|







 







>


<



<
<
<
<
<







 







|







39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
....
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803

2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
....
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
....
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846

2847
2848
2849





2850
2851
2852
2853
2854
2855
2856
....
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
**
** 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.666 2008/01/03 07:54:24 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
#include "vdbeInt.h"

/*
** The following global variable is incremented every time a cursor
................................................................................

    sqlite3ExpirePreparedStatements(db);
    rc = SQLITE_SCHEMA;
  }
  break;
}

/* Opcode: OpenRead P1 P2 P3 P4 *
**
** Open a read-only cursor for the database table whose root page is
** P2 in a database file.  The database file is determined by P3. 
** 0 means the main database and 1 means the database used for 

** temporary tables.  Give the new cursor an identifier of P1.  The P1
** values need not be contiguous but all P1 values should be small integers.
** It is an error for P1 to be negative.
**
** If P2==0 then take the root page number from the top of the stack.
**
** There will be a read lock on the database whenever there is an
** open cursor.  If the database was unlocked prior to this instruction
** then a read lock is acquired as part of this instruction.  A read
** lock allows other processes to read the database but prohibits
** any other process from modifying the database.  The read lock is
** released when all cursors are closed.  If this instruction attempts
................................................................................
**
** The P4 value is a pointer to a KeyInfo structure that defines the
** content and collating sequence of indices.  P4 is NULL for cursors
** that are not pointing to indices.
**
** See also OpenWrite.
*/
/* Opcode: OpenWrite P1 P2 P3 P4 *
**
** Open a read/write cursor named P1 on the table or index whose root
** page is P2.  If P2==0 then take the root page number from the stack.
**
** The P4 value is a pointer to a KeyInfo structure that defines the
** content and collating sequence of indices.  P4 is NULL for cursors
** that are not pointing to indices.
................................................................................
**
** See also OpenRead.
*/
case OP_OpenRead:          /* no-push */
case OP_OpenWrite: {       /* no-push */
  int i = pOp->p1;
  int p2 = pOp->p2;
  int iDb = pOp->p3;
  int wrFlag;
  Btree *pX;

  Cursor *pCur;
  Db *pDb;
  





  assert( iDb>=0 && iDb<db->nDb );
  assert( (p->btreeMask & (1<<iDb))!=0 );
  pDb = &db->aDb[iDb];
  pX = pDb->pBt;
  assert( pX!=0 );
  if( pOp->opcode==OP_OpenWrite ){
    wrFlag = 1;
................................................................................
    pCur->pKeyInfo = 0;
    pCur->pIncrKey = &pCur->bogusIncrKey;
  }
  switch( rc ){
    case SQLITE_BUSY: {
      p->pc = pc;
      p->rc = rc = SQLITE_BUSY;
      p->pTos = &pTos[(pOp->p2<=0)]; /* Operands must remain on stack */
      goto vdbe_return;
    }
    case SQLITE_OK: {
      int flags = sqlite3BtreeFlags(pCur->pCursor);
      /* Sanity checking.  Only the lower four bits of the flags byte should
      ** be used.  Bit 3 (mask 0x08) is unpreditable.  The lower 3 bits
      ** (mask 0x07) should be either 5 (intkey+leafdata for tables) or

Changes to src/vdbe.h.

11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
...
129
130
131
132
133
134
135

136
137
138
139
140
141
142
*************************************************************************
** Header file for the Virtual DataBase Engine (VDBE)
**
** This header defines the interface to the virtual database engine
** or VDBE.  The VDBE implements an abstract machine that runs a
** simple program to access and modify the underlying database.
**
** $Id: vdbe.h,v 1.119 2008/01/03 01:28:59 drh Exp $
*/
#ifndef _SQLITE_VDBE_H_
#define _SQLITE_VDBE_H_
#include <stdio.h>

/*
** A single VDBE is an opaque structure named "Vdbe".  Only routines
................................................................................
int sqlite3VdbeAddOp1(Vdbe*,int,int);
int sqlite3VdbeAddOp2(Vdbe*,int,int,int);
int sqlite3VdbeAddOp3(Vdbe*,int,int,int,int);
int sqlite3VdbeAddOp4(Vdbe*,int,int,int,int,const char *zP4,int);
int sqlite3VdbeAddOpList(Vdbe*, int nOp, VdbeOpList const *aOp);
void sqlite3VdbeChangeP1(Vdbe*, int addr, int P1);
void sqlite3VdbeChangeP2(Vdbe*, int addr, int P2);

void sqlite3VdbeJumpHere(Vdbe*, int addr);
void sqlite3VdbeChangeToNoop(Vdbe*, int addr, int N);
void sqlite3VdbeChangeP4(Vdbe*, int addr, const char *zP4, int N);
void sqlite3VdbeUsesBtree(Vdbe*, int);
VdbeOp *sqlite3VdbeGetOp(Vdbe*, int);
int sqlite3VdbeMakeLabel(Vdbe*);
void sqlite3VdbeDelete(Vdbe*);







|







 







>







11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
...
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
*************************************************************************
** Header file for the Virtual DataBase Engine (VDBE)
**
** This header defines the interface to the virtual database engine
** or VDBE.  The VDBE implements an abstract machine that runs a
** simple program to access and modify the underlying database.
**
** $Id: vdbe.h,v 1.120 2008/01/03 07:54:24 danielk1977 Exp $
*/
#ifndef _SQLITE_VDBE_H_
#define _SQLITE_VDBE_H_
#include <stdio.h>

/*
** A single VDBE is an opaque structure named "Vdbe".  Only routines
................................................................................
int sqlite3VdbeAddOp1(Vdbe*,int,int);
int sqlite3VdbeAddOp2(Vdbe*,int,int,int);
int sqlite3VdbeAddOp3(Vdbe*,int,int,int,int);
int sqlite3VdbeAddOp4(Vdbe*,int,int,int,int,const char *zP4,int);
int sqlite3VdbeAddOpList(Vdbe*, int nOp, VdbeOpList const *aOp);
void sqlite3VdbeChangeP1(Vdbe*, int addr, int P1);
void sqlite3VdbeChangeP2(Vdbe*, int addr, int P2);
void sqlite3VdbeChangeP3(Vdbe*, int addr, int P2);
void sqlite3VdbeJumpHere(Vdbe*, int addr);
void sqlite3VdbeChangeToNoop(Vdbe*, int addr, int N);
void sqlite3VdbeChangeP4(Vdbe*, int addr, const char *zP4, int N);
void sqlite3VdbeUsesBtree(Vdbe*, int);
VdbeOp *sqlite3VdbeGetOp(Vdbe*, int);
int sqlite3VdbeMakeLabel(Vdbe*);
void sqlite3VdbeDelete(Vdbe*);

Changes to src/vdbeaux.c.

432
433
434
435
436
437
438











439
440
441
442
443
444
445
void sqlite3VdbeChangeP2(Vdbe *p, int addr, int val){
  assert( val>=0 );
  assert( p==0 || p->magic==VDBE_MAGIC_INIT );
  if( p && addr>=0 && p->nOp>addr && p->aOp ){
    p->aOp[addr].p2 = val;
  }
}












/*
** Change the P2 operand of instruction addr so that it points to
** the address of the next instruction to be coded.
*/
void sqlite3VdbeJumpHere(Vdbe *p, int addr){
  sqlite3VdbeChangeP2(p, addr, p->nOp);







>
>
>
>
>
>
>
>
>
>
>







432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
void sqlite3VdbeChangeP2(Vdbe *p, int addr, int val){
  assert( val>=0 );
  assert( p==0 || p->magic==VDBE_MAGIC_INIT );
  if( p && addr>=0 && p->nOp>addr && p->aOp ){
    p->aOp[addr].p2 = val;
  }
}

/*
** Change the value of the P2 operand for a specific instruction.
** This routine is useful for setting a jump destination.
*/
void sqlite3VdbeChangeP3(Vdbe *p, int addr, int val){
  assert( p==0 || p->magic==VDBE_MAGIC_INIT );
  if( p && addr>=0 && p->nOp>addr && p->aOp ){
    p->aOp[addr].p3 = val;
  }
}

/*
** Change the P2 operand of instruction addr so that it points to
** the address of the next instruction to be coded.
*/
void sqlite3VdbeJumpHere(Vdbe *p, int addr){
  sqlite3VdbeChangeP2(p, addr, p->nOp);

Changes to src/vdbeblob.c.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
..
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
...
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176

177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
**
** This file contains code used to implement incremental BLOB I/O.
**
** $Id: vdbeblob.c,v 1.16 2007/08/30 01:19:59 drh Exp $
*/

#include "sqliteInt.h"
#include "vdbeInt.h"

#ifndef SQLITE_OMIT_INCRBLOB

................................................................................
  ** The sqlite3_blob_close() function finalizes the vdbe program,
  ** which closes the b-tree cursor and (possibly) commits the 
  ** transaction.
  */
  static const VdbeOpList openBlob[] = {
    {OP_Transaction, 0, 0, 0},     /* 0: Start a transaction */
    {OP_VerifyCookie, 0, 0, 0},    /* 1: Check the schema cookie */
    {OP_Integer, 0, 0, 0},         /* 2: Database number */

    /* One of the following two instructions is replaced by an
    ** OP_Noop before exection.
    */
    {OP_OpenRead, 0, 0, 0},        /* 3: Open cursor 0 for reading */
    {OP_OpenWrite, 0, 0, 0},       /* 4: Open cursor 0 for read/write */
    {OP_SetNumColumns, 0, 0, 0},   /* 5: Num cols for cursor */

    {OP_Variable, 1, 0, 0},        /* 6: Push the rowid to the stack */
    {OP_NotExists, 0, 10, 0},      /* 7: Seek the cursor */
    {OP_Column, 0, 0, 0},          /* 8  */
    {OP_Callback, 0, 0, 0},        /* 9  */
    {OP_Close, 0, 0, 0},           /* 10 */
    {OP_Halt, 0, 0, 0},            /* 11 */
  };

  Vdbe *v = 0;
  int rc = SQLITE_OK;
  char zErr[128];

  zErr[0] = 0;
................................................................................
      /* Configure the OP_VerifyCookie */
      sqlite3VdbeChangeP1(v, 1, iDb);
      sqlite3VdbeChangeP2(v, 1, pTab->pSchema->schema_cookie);

      /* Make sure a mutex is held on the table to be accessed */
      sqlite3VdbeUsesBtree(v, iDb); 

      /* Configure the db number pushed onto the stack */
      sqlite3VdbeChangeP1(v, 2, iDb);

      /* Remove either the OP_OpenWrite or OpenRead. Set the P2 
      ** parameter of the other to pTab->tnum. 
      */
      sqlite3VdbeChangeToNoop(v, (flags ? 3 : 4), 1);
      sqlite3VdbeChangeP2(v, (flags ? 4 : 3), pTab->tnum);


      /* Configure the OP_SetNumColumns. Configure the cursor to
      ** think that the table has one more column than it really
      ** does. An OP_Column to retrieve this imaginary column will
      ** always return an SQL NULL. This is useful because it means
      ** we can invoke OP_Column to fill in the vdbe cursors type 
      ** and offset cache without causing any IO.
      */
      sqlite3VdbeChangeP2(v, 5, pTab->nCol+1);
      if( !db->mallocFailed ){
        sqlite3VdbeMakeReady(v, 1, 0, 1, 0);
      }
    }
   
    sqlite3BtreeLeaveAll(db);
    rc = sqlite3SafetyOff(db);







|







 







<




|
|
|

|
|
|
|
|
|







 







<
<
<



|
|
>








|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
..
62
63
64
65
66
67
68

69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
...
161
162
163
164
165
166
167



168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
**
** This file contains code used to implement incremental BLOB I/O.
**
** $Id: vdbeblob.c,v 1.17 2008/01/03 07:54:24 danielk1977 Exp $
*/

#include "sqliteInt.h"
#include "vdbeInt.h"

#ifndef SQLITE_OMIT_INCRBLOB

................................................................................
  ** The sqlite3_blob_close() function finalizes the vdbe program,
  ** which closes the b-tree cursor and (possibly) commits the 
  ** transaction.
  */
  static const VdbeOpList openBlob[] = {
    {OP_Transaction, 0, 0, 0},     /* 0: Start a transaction */
    {OP_VerifyCookie, 0, 0, 0},    /* 1: Check the schema cookie */


    /* One of the following two instructions is replaced by an
    ** OP_Noop before exection.
    */
    {OP_OpenRead, 0, 0, 0},        /* 2: Open cursor 0 for reading */
    {OP_OpenWrite, 0, 0, 0},       /* 3: Open cursor 0 for read/write */
    {OP_SetNumColumns, 0, 0, 0},   /* 4: Num cols for cursor */

    {OP_Variable, 1, 0, 0},        /* 5: Push the rowid to the stack */
    {OP_NotExists, 0, 10, 0},      /* 6: Seek the cursor */
    {OP_Column, 0, 0, 0},          /* 7  */
    {OP_Callback, 0, 0, 0},        /* 8  */
    {OP_Close, 0, 0, 0},           /* 9  */
    {OP_Halt, 0, 0, 0},            /* 10 */
  };

  Vdbe *v = 0;
  int rc = SQLITE_OK;
  char zErr[128];

  zErr[0] = 0;
................................................................................
      /* Configure the OP_VerifyCookie */
      sqlite3VdbeChangeP1(v, 1, iDb);
      sqlite3VdbeChangeP2(v, 1, pTab->pSchema->schema_cookie);

      /* Make sure a mutex is held on the table to be accessed */
      sqlite3VdbeUsesBtree(v, iDb); 




      /* Remove either the OP_OpenWrite or OpenRead. Set the P2 
      ** parameter of the other to pTab->tnum. 
      */
      sqlite3VdbeChangeToNoop(v, (flags ? 2 : 3), 1);
      sqlite3VdbeChangeP2(v, (flags ? 3 : 2), pTab->tnum);
      sqlite3VdbeChangeP3(v, (flags ? 3 : 2), iDb);

      /* Configure the OP_SetNumColumns. Configure the cursor to
      ** think that the table has one more column than it really
      ** does. An OP_Column to retrieve this imaginary column will
      ** always return an SQL NULL. This is useful because it means
      ** we can invoke OP_Column to fill in the vdbe cursors type 
      ** and offset cache without causing any IO.
      */
      sqlite3VdbeChangeP2(v, 4, pTab->nCol+1);
      if( !db->mallocFailed ){
        sqlite3VdbeMakeReady(v, 1, 0, 1, 0);
      }
    }
   
    sqlite3BtreeLeaveAll(db);
    rc = sqlite3SafetyOff(db);

Changes to src/where.c.

12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
....
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218

2219
2220
2221
2222
2223
2224
2225
** 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.268 2008/01/03 00:01:26 drh Exp $
*/
#include "sqliteInt.h"

/*
** The number of bits in a Bitmask.  "BMS" means "BitMask Size".
*/
#define BMS  (sizeof(Bitmask)*8)
................................................................................
    }else{
      sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName);
    }
    pLevel->iTabCur = pTabItem->iCursor;
    if( (pIx = pLevel->pIdx)!=0 ){
      KeyInfo *pKey = sqlite3IndexKeyinfo(pParse, pIx);
      assert( pIx->pSchema==pTab->pSchema );
      sqlite3VdbeAddOp2(v, OP_Integer, iDb, 0);
      VdbeComment((v, "%s", pIx->zName));
      sqlite3VdbeAddOp4(v, OP_OpenRead, iIdxCur, pIx->tnum, 0,
                        (char*)pKey, P4_KEYINFO_HANDOFF);

      sqlite3VdbeAddOp2(v, OP_SetNumColumns, iIdxCur, pIx->nColumn+1);
    }
    sqlite3CodeVerifySchema(pParse, iDb);
  }
  pWInfo->iTop = sqlite3VdbeCurrentAddr(v);

  /* Generate the code to do the search.  Each iteration of the for







|







 







<
<
|

>







12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
....
2208
2209
2210
2211
2212
2213
2214


2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
** 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.269 2008/01/03 07:54:24 danielk1977 Exp $
*/
#include "sqliteInt.h"

/*
** The number of bits in a Bitmask.  "BMS" means "BitMask Size".
*/
#define BMS  (sizeof(Bitmask)*8)
................................................................................
    }else{
      sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName);
    }
    pLevel->iTabCur = pTabItem->iCursor;
    if( (pIx = pLevel->pIdx)!=0 ){
      KeyInfo *pKey = sqlite3IndexKeyinfo(pParse, pIx);
      assert( pIx->pSchema==pTab->pSchema );


      sqlite3VdbeAddOp4(v, OP_OpenRead, iIdxCur, pIx->tnum, iDb,
                        (char*)pKey, P4_KEYINFO_HANDOFF);
      VdbeComment((v, "%s", pIx->zName));
      sqlite3VdbeAddOp2(v, OP_SetNumColumns, iIdxCur, pIx->nColumn+1);
    }
    sqlite3CodeVerifySchema(pParse, iDb);
  }
  pWInfo->iTop = sqlite3VdbeCurrentAddr(v);

  /* Generate the code to do the search.  Each iteration of the for