]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
It runs. Simple tables can be created. INSERT and SELECT work. Much more
authordrh <drh@noemail.net>
Thu, 13 Sep 2001 16:18:53 +0000 (16:18 +0000)
committerdrh <drh@noemail.net>
Thu, 13 Sep 2001 16:18:53 +0000 (16:18 +0000)
testing is needed, however. (CVS 241)

FossilOrigin-Name: 9ac8399c99cb996a382f3d49f45b6ca857adc827

manifest
manifest.uuid
src/build.c
src/main.c
src/select.c
src/sqliteInt.h
src/vdbe.c
src/where.c

index adacd193bf0e277a0b861906df9d030e49a77215..11ac4ac099574f693f41db918888fd18e827c91f 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C The\snew\sBtree\scode\sruns,\sbut\sit\sdoes\snot\syet\swork.\s(CVS\s240)
-D 2001-09-13T15:21:32
+C It\sruns.\sSimple\stables\scan\sbe\screated.\sINSERT\sand\sSELECT\swork.\sMuch\smore\ntesting\sis\sneeded,\showever.\s(CVS\s241)
+D 2001-09-13T16:18:54
 F COPYRIGHT 74a8a6531a42e124df07ab5599aad63870fa0bd4
 F Makefile.in 7ecb2370b5cb34d390af1fcb3118ea6d84a253ca
 F README 51f6a4e7408b34afa5bc1c0485f61b6a4efb6958
@@ -15,7 +15,7 @@ F notes/notes3.txt 71e47be517e3d2578b3b9343a45b772d43b7ba16
 F src/TODO f0ea267ab55c4d15127c1ac1667edbf781147438
 F src/btree.c 9f22b51681bcc0026ea300134e4e2f1f40fc0800
 F src/btree.h 2427961c702dd0755ec70f529cf3db32707d689b
-F src/build.c 58020177a1b96455284899774442833a81c5ae9c
+F src/build.c 5839600c9fced909e9d336203b758aeaa541b3b1
 F src/delete.c 769a28cf35ab75df4b2416982d8369520b28f3c5
 F src/ex/README b745b00acce2d892f60c40111dacdfc48e0c1c7a
 F src/ex/db.c f1419ae6c93e40b5ac6e39fe7efd95d868e6f9d7
@@ -27,18 +27,18 @@ F src/ex/pg.h 23a4ac807b0546ec2bb6239ec8bd3e06926572cd
 F src/ex/sizes.tcl f54bad4a2ac567624be59131a6ee42d71b41a3d7
 F src/expr.c 83b6a7ed4cf502249f192b698517e9a9b8f05303
 F src/insert.c 1072c0dd7782c17af735df37f447630d4d577ba1
-F src/main.c c5f8931674ac1fa8e8c6e0062d3c5700e204f3b7
+F src/main.c 1feb8e6681fd7bf5d8da5cbec2f6d15767c26033
 F src/md5.c 52f677bfc590e09f71d07d7e327bd59da738d07c
 F src/pager.c 05a2177c99a835c3efec1e4187556e2e29311d4a
 F src/pager.h 238aa88bafe33911bf9b0b365f35afd0a261cd46
 F src/parse.y 8fc096948994a7ffbf61ba13129cc589f794a9cb
 F src/printf.c b1e22a47be8cdf707815647239991e08e8cb69f9
 F src/random.c b36c3f57dc80c8f354e6bfbf39cf1e1de021d54a
-F src/select.c 391921bcc612e15efecc451e42a93697fb826e46
+F src/select.c 0f7e6652b5a1869f8eb39778ffece5055a909b29
 F src/shell.c 1fcdf8c4180098bcfdee12501e01b4c8eb21d726
 F src/shell.tcl 27ecbd63dd88396ad16d81ab44f73e6c0ea9d20e
 F src/sqlite.h.in 8faa2fed0513d188ced16e5f9094e57694594e70
-F src/sqliteInt.h f8b8417dde95419d2e4ab683ce4ac418f96913bd
+F src/sqliteInt.h 14df6fb9c3bacf546b199396dda28f809ffcd954
 F src/table.c adcaf074f6c1075e86359174e68701fa2acfc4d6
 F src/tclsqlite.c d328970848c028e13e61e173bef79adcc379568a
 F src/test1.c abb3cb427e735ae87e6533f5b3b7164b7da91bc4
@@ -47,9 +47,9 @@ F src/test3.c 147b42ec368a10e9f267e7466d30c46e76d7f278
 F src/tokenize.c 0118b57702cb6550769316e8443b06760b067acf
 F src/update.c ea8f2c0712cd4cd19314a26ef4766866013facda
 F src/util.c c77668fef860cfd2e4e682ef4f3ed8f9e68c551b
-F src/vdbe.c d5f0a2de6427cd4843c13e093b0039e5fac05e0f
+F src/vdbe.c d7d30c19330b6c2452859424d7fd6d452d6dee62
 F src/vdbe.h 6ee941ecd78b7b224607517fd060d6547910dc10
-F src/where.c b9f6d2c029983e9db9521474c876f9a039e7fb6c
+F src/where.c fef978a9a2234b01e30e36833ab63e14bbc626d3
 F test/all.test 21d55a97e39e7ec5776751dc9dd8b1b51ef4a048
 F test/btree.test 5e1eeb03cda22161eec827dc5224ce6c500eaaf9
 F test/btree2.test a3c9ff1e4490357dd15c9a41f8aefd02f6e32fdc
@@ -108,7 +108,7 @@ F www/opcode.tcl cb3a1abf8b7b9be9f3a228d097d6bf8b742c2b6f
 F www/sqlite.tcl cb0d23d8f061a80543928755ec7775da6e4f362f
 F www/tclsqlite.tcl 06f81c401f79a04f2c5ebfb97e7c176225c0aef2
 F www/vdbe.tcl 0c8aaa529dd216ccbf7daaabd80985e413d5f9ad
-P a0a1e701abc52a164d9b09a5426eb12af1fe6a4c
-R 472be17e965b4d5d7fba15c027cd1366
+P 991ce8115052da9395d4bf8ff29f417e3c36dc7f
+R f709a5820bca7397e17a0af30d07e86d
 U drh
-Z d550eba50f66b2bb3dd421288cbb8ffd
+Z c3ae2020eeb73a32f1d2074b9db28833
index 2fdf8e47341028fbd939c08565e9f775a6713dd5..1c42c56827532fff5695d0d35e40a352c604350f 100644 (file)
@@ -1 +1 @@
-991ce8115052da9395d4bf8ff29f417e3c36dc7f
\ No newline at end of file
+9ac8399c99cb996a382f3d49f45b6ca857adc827
\ No newline at end of file
index 2d452d8cebffeddb8104d748a614a51f60eaafde..14d8793fa0ce68973f9817dc3ae7c59b8bf87d2b 100644 (file)
@@ -33,7 +33,7 @@
 **     COPY
 **     VACUUM
 **
-** $Id: build.c,v 1.30 2001/09/13 14:46:10 drh Exp $
+** $Id: build.c,v 1.31 2001/09/13 16:18:54 drh Exp $
 */
 #include "sqliteInt.h"
 
@@ -461,6 +461,14 @@ void sqliteEndTable(Parse *pParse, Token *pEnd){
     db->flags |= SQLITE_InternChanges;
   }
 
+  /* If the initFlag is 1 it means we are reading the SQL off the
+  ** "sqlite_master" table on the disk.  So do not write to the disk
+  ** again.  Extract the table number from the pParse->newTnum field.
+  */
+  if( pParse->initFlag ){
+    p->tnum = pParse->newTnum;
+  }
+
   /* If not initializing, then create the table on disk.
   */
   if( !pParse->initFlag ){
@@ -472,7 +480,7 @@ void sqliteEndTable(Parse *pParse, Token *pEnd){
       { OP_CreateTable, 0, 0, 0},
       { OP_String,      0, 0, 0},            /* 5 */
       { OP_String,      0, 0, 0},            /* 6 */
-      { OP_MakeRecord,  4, 0, 0},
+      { OP_MakeRecord,  5, 0, 0},
       { OP_Put,         0, 0, 0},
     };
     int n, base;
@@ -538,15 +546,16 @@ void sqliteDropTable(Parse *pParse, Token *pName){
   if( v ){
     static VdbeOp dropTable[] = {
       { OP_Open,       0, 2,        0},
-      { OP_String,     0, 0,        0}, /* 1 */
-      { OP_Next,       0, ADDR(9),  0}, /* 2 */
+      { OP_Rewind,     0, 0,        0},
+      { OP_String,     0, 0,        0}, /* 2 */
+      { OP_Next,       0, ADDR(10), 0}, /* 3 */
       { OP_Dup,        0, 0,        0},
       { OP_Column,     0, 3,        0},
-      { OP_Ne,         0, ADDR(2),  0},
+      { OP_Ne,         0, ADDR(3),  0},
       { OP_Recno,      0, 0,        0},
       { OP_Delete,     0, 0,        0},
-      { OP_Goto,       0, ADDR(2),  0},
-      { OP_Destroy,    0, 0,        0}, /* 9 */
+      { OP_Goto,       0, ADDR(3),  0},
+      { OP_Destroy,    0, 0,        0}, /* 10 */
       { OP_Close,      0, 0,        0},
     };
     Index *pIdx;
@@ -554,7 +563,7 @@ void sqliteDropTable(Parse *pParse, Token *pName){
       sqliteVdbeAddOp(v, OP_Transaction, 0, 0, 0, 0);
     }
     base = sqliteVdbeAddOpList(v, ArraySize(dropTable), dropTable);
-    sqliteVdbeChangeP1(v, base+9, pTable->tnum);
+    sqliteVdbeChangeP1(v, base+10, pTable->tnum);
     for(pIdx=pTable->pIndex; pIdx; pIdx=pIdx->pNext){
       sqliteVdbeAddOp(v, OP_Destroy, pIdx->tnum, 0, 0, 0);
     }
@@ -694,6 +703,14 @@ void sqliteCreateIndex(
     db->flags |= SQLITE_InternChanges;
   }
 
+  /* If the initFlag is 1 it means we are reading the SQL off the
+  ** "sqlite_master" table on the disk.  So do not write to the disk
+  ** again.  Extract the table number from the pParse->newTnum field.
+  */
+  if( pParse->initFlag ){
+    pIndex->tnum = pParse->newTnum;
+  }
+
   /* If the initFlag is 0 then create the index on disk.  This
   ** involves writing the index into the master table and filling in the
   ** index with the current table contents.
@@ -740,6 +757,7 @@ void sqliteCreateIndex(
     }
     lbl1 = sqliteVdbeMakeLabel(v);
     lbl2 = sqliteVdbeMakeLabel(v);
+    sqliteVdbeAddOp(v, OP_Rewind, 0, 0, 0, 0);
     sqliteVdbeAddOp(v, OP_Next, 0, lbl2, 0, lbl1);
     sqliteVdbeAddOp(v, OP_Recno, 0, 0, 0, 0);
     for(i=0; i<pIndex->nColumn; i++){
@@ -795,14 +813,15 @@ void sqliteDropIndex(Parse *pParse, Token *pName){
   if( v ){
     static VdbeOp dropIndex[] = {
       { OP_Open,       0, 2,       0},
-      { OP_String,     0, 0,       0}, /* 1 */
-      { OP_Next,       0, ADDR(8), 0}, /* 2 */
+      { OP_Rewind,     0, 0,       0}, 
+      { OP_String,     0, 0,       0}, /* 2 */
+      { OP_Next,       0, ADDR(9), 0}, /* 3 */
       { OP_Dup,        0, 0,       0},
       { OP_Column,     0, 1,       0},
-      { OP_Ne,         0, ADDR(2), 0},
+      { OP_Ne,         0, ADDR(3), 0},
       { OP_Recno,      0, 0,       0},
       { OP_Delete,     0, 0,       0},
-      { OP_Destroy,    0, 0,       0}, /* 8 */
+      { OP_Destroy,    0, 0,       0}, /* 9 */
       { OP_Close,      0, 0,       0},
     };
     int base;
@@ -811,7 +830,7 @@ void sqliteDropIndex(Parse *pParse, Token *pName){
       sqliteVdbeAddOp(v, OP_Transaction, 0, 0, 0, 0);
     }
     base = sqliteVdbeAddOpList(v, ArraySize(dropIndex), dropIndex);
-    sqliteVdbeChangeP1(v, base+8, pIndex->tnum);
+    sqliteVdbeChangeP1(v, base+9, pIndex->tnum);
     if( (db->flags & SQLITE_InTrans)==0 ){
       sqliteVdbeAddOp(v, OP_Commit, 0, 0, 0, 0);
     }
index 2301915f4356e4c19258bcd024388e481802faa9..8704149c992880896b1cc1a4f2c927e29cd9ae03 100644 (file)
@@ -26,7 +26,7 @@
 ** other files are for internal use by SQLite and should not be
 ** accessed by users of the library.
 **
-** $Id: main.c,v 1.32 2001/09/13 15:21:32 drh Exp $
+** $Id: main.c,v 1.33 2001/09/13 16:18:54 drh Exp $
 */
 #include "sqliteInt.h"
 #if defined(HAVE_USLEEP) && HAVE_USLEEP
 
 /*
 ** This is the callback routine for the code that initializes the
-** database.  Each callback contains text of a CREATE TABLE or
-** CREATE INDEX statement that must be parsed to yield the internal
-** structures that describe the tables.
+** database.  Each callback contains the following information:
+**
+**     argv[0] = "meta" or "table" or "index"
+**     argv[1] = table or index name
+**     argv[2] = root page number for table or index
+**     argv[3] = SQL create statement for the table or index
 **
-** This callback is also called with argc==2 when there is meta
-** information in the sqlite_master file.  The meta information is
-** contained in argv[1].  Typical meta information is the file format
-** version.
 */
 static int sqliteOpenCb(void *pDb, int argc, char **argv, char **azColName){
   sqlite *db = (sqlite*)pDb;
   Parse sParse;
-  int nErr;
+  int nErr = 0;
 
-  if( argc==2 ){
-    if( sscanf(argv[1],"file format %d",&db->file_format)==1 ){
-      return 0;
+  assert( argc==4 );
+  switch( argv[0][0] ){
+    case 'm': {  /* Meta information */
+      sscanf(argv[1],"file format %d",&db->file_format);
+      break;
+    }
+    case 'i':
+    case 't': {  /* CREATE TABLE  and CREATE INDEX statements */
+      memset(&sParse, 0, sizeof(sParse));
+      sParse.db = db;
+      sParse.initFlag = 1;
+      sParse.newTnum = atoi(argv[2]);
+      nErr = sqliteRunParser(&sParse, argv[3], 0);
+      break;
+    }
+    default: {
+      /* This can not happen! */
+      nErr = 1;
+      assert( nErr==0 );
     }
-    /* Unknown meta information.  Ignore it. */
-    return 0;
   }
-  if( argc!=1 ) return 0;
-  memset(&sParse, 0, sizeof(sParse));
-  sParse.db = db;
-  sParse.initFlag = 1;
-  nErr = sqliteRunParser(&sParse, argv[0], 0);
   return nErr;
 }
 
@@ -129,31 +137,40 @@ static int sqliteInit(sqlite *db, char **pzErrMsg){
   */
   static VdbeOp initProg[] = {
     { OP_Open,     0, 2,  0},
-    { OP_Next,     0, 9,  0},           /* 1 */
+    { OP_Rewind,   0, 0,  0},
+    { OP_Next,     0, 12, 0},           /* 2 */
     { OP_Column,   0, 0,  0},
     { OP_String,   0, 0,  "meta"},
-    { OP_Ne,       0, 1,  0},
+    { OP_Ne,       0, 2,  0},
     { OP_Column,   0, 0,  0},
+    { OP_Column,   0, 1,  0},
+    { OP_Column,   0, 2,  0},
     { OP_Column,   0, 4,  0},
-    { OP_Callback, 2, 0,  0},
-    { OP_Goto,     0, 1,  0},
-    { OP_Rewind,   0, 0,  0},           /* 9 */
-    { OP_Next,     0, 17, 0},           /* 10 */
+    { OP_Callback, 4, 0,  0},
+    { OP_Goto,     0, 2,  0},
+    { OP_Rewind,   0, 0,  0},           /* 12 */
+    { OP_Next,     0, 23, 0},           /* 13 */
     { OP_Column,   0, 0,  0},
     { OP_String,   0, 0,  "table"},
-    { OP_Ne,       0, 10, 0},
+    { OP_Ne,       0, 13, 0},
+    { OP_Column,   0, 0,  0},
+    { OP_Column,   0, 1,  0},
+    { OP_Column,   0, 2,  0},
     { OP_Column,   0, 4,  0},
-    { OP_Callback, 1, 0,  0},
-    { OP_Goto,     0, 10, 0},
-    { OP_Rewind,   0, 0,  0},           /* 17 */
-    { OP_Next,     0, 25, 0},           /* 18 */
+    { OP_Callback, 4, 0,  0},
+    { OP_Goto,     0, 13, 0},
+    { OP_Rewind,   0, 0,  0},           /* 23 */
+    { OP_Next,     0, 34, 0},           /* 24 */
     { OP_Column,   0, 0,  0},
     { OP_String,   0, 0,  "index"},
-    { OP_Ne,       0, 18, 0},
+    { OP_Ne,       0, 24, 0},
+    { OP_Column,   0, 0,  0},
+    { OP_Column,   0, 1,  0},
+    { OP_Column,   0, 2,  0},
     { OP_Column,   0, 4,  0},
-    { OP_Callback, 1, 0,  0},
-    { OP_Goto,     0, 18, 0},
-    { OP_Close,    2, 0,  0},           /* 25 */
+    { OP_Callback, 4, 0,  0},
+    { OP_Goto,     0, 24, 0},
+    { OP_Close,    0, 0,  0},           /* 34 */
     { OP_Halt,     0, 0,  0},
   };
 
@@ -169,20 +186,22 @@ static int sqliteInit(sqlite *db, char **pzErrMsg){
   rc = sqliteVdbeExec(vdbe, sqliteOpenCb, db, pzErrMsg, 
                       db->pBusyArg, db->xBusyCallback);
   sqliteVdbeDelete(vdbe);
-  if( rc==SQLITE_OK && db->file_format<2 && db->nTable>0 ){
-    sqliteSetString(pzErrMsg, "obsolete file format", 0);
+  if( rc==SQLITE_OK && db->file_format>1 && db->nTable>0 ){
+    sqliteSetString(pzErrMsg, "unsupported file format", 0);
     rc = SQLITE_ERROR;
   }
   if( rc==SQLITE_OK ){
     Table *pTab;
-    char *azArg[2];
-    azArg[0] = master_schema;
-    azArg[1] = 0;
-    sqliteOpenCb(db, 1, azArg, 0);
+    char *azArg[5];
+    azArg[0] = "table";
+    azArg[1] = MASTER_NAME;
+    azArg[2] = "2";
+    azArg[3] = master_schema;
+    azArg[4] = 0;
+    sqliteOpenCb(db, 4, azArg, 0);
     pTab = sqliteFindTable(db, MASTER_NAME);
     if( pTab ){
       pTab->readOnly = 1;
-      pTab->tnum = 2;
     }
     db->flags |= SQLITE_Initialized;
     sqliteCommitInternalChanges(db);
index ea29e12511272f6ac8987a0f62170b1ffb6bf486..e0e38a1e36fd3568b5bf98daa4a7944871b6cd22 100644 (file)
@@ -24,7 +24,7 @@
 ** This file contains C code routines that are called by the parser
 ** to handle SELECT statements.
 **
-** $Id: select.c,v 1.33 2001/09/13 14:46:10 drh Exp $
+** $Id: select.c,v 1.34 2001/09/13 16:18:54 drh Exp $
 */
 #include "sqliteInt.h"
 
@@ -549,6 +549,7 @@ static int multiSelect(Parse *pParse, Select *p, int eDest, int iParm){
         if( p->pOrderBy ){
           sqliteVdbeAddOp(v, OP_SortOpen, 0, 0, 0, 0);
         }
+        sqliteVdbeAddOp(v, OP_Rewind, unionTab, 0, 0, 0);
         iBreak = sqliteVdbeMakeLabel(v);
         iCont = sqliteVdbeAddOp(v, OP_Next, unionTab, iBreak, 0, 0);
         rc = selectInnerLoop(pParse, 0, unionTab, p->pEList->nExpr,
@@ -601,6 +602,7 @@ static int multiSelect(Parse *pParse, Select *p, int eDest, int iParm){
       if( p->pOrderBy ){
         sqliteVdbeAddOp(v, OP_SortOpen, 0, 0, 0, 0);
       }
+      sqliteVdbeAddOp(v, OP_Rewind, tab1, 0, 0, 0);
       iBreak = sqliteVdbeMakeLabel(v);
       iCont = sqliteVdbeAddOp(v, OP_Next, tab1, iBreak, 0, 0);
       sqliteVdbeAddOp(v, OP_FullKey, tab1, 0, 0, 0);
index bc4a1125be283228e47bf88bafa823f64564556f..71d1e0294290212b770d8ae18ca11cdf9f3429b3 100644 (file)
@@ -23,7 +23,7 @@
 *************************************************************************
 ** Internal interface definitions for SQLite.
 **
-** @(#) $Id: sqliteInt.h,v 1.44 2001/09/13 14:46:10 drh Exp $
+** @(#) $Id: sqliteInt.h,v 1.45 2001/09/13 16:18:54 drh Exp $
 */
 #include "sqlite.h"
 #include "vdbe.h"
@@ -359,6 +359,7 @@ struct Parse {
   int colNamesSet;     /* TRUE after OP_ColumnCount has been issued to pVdbe */
   int explain;         /* True if the EXPLAIN flag is found on the query */
   int initFlag;        /* True if reparsing CREATE TABLEs */
+  int newTnum;         /* Table number to use when reparsing CREATE TABLEs */
   int nErr;            /* Number of errors seen */
   int nTab;            /* Number of previously allocated cursors */
   int nMem;            /* Number of memory cells used so far */
index ba47f1b36f3f38455287091f23070ba7cd169aff..1133c18863aa3575edd440408aa01eb2b14f40b7 100644 (file)
@@ -41,7 +41,7 @@
 ** But other routines are also provided to help in building up
 ** a program instruction by instruction.
 **
-** $Id: vdbe.c,v 1.62 2001/09/13 15:21:32 drh Exp $
+** $Id: vdbe.c,v 1.63 2001/09/13 16:18:54 drh Exp $
 */
 #include "sqliteInt.h"
 #include <ctype.h>
@@ -1798,11 +1798,11 @@ case OP_MakeRecord: {
   j = 0;
   addr = sizeof(int)*nField;
   for(i=p->tos-nField+1; i<=p->tos; i++){
+    memcpy(&zNewRecord[j], (char*)&addr, sizeof(int));
+    j += sizeof(int);
     if( (aStack[i].flags & STK_Null)==0 ){
       addr += aStack[i].n;
     }
-    memcpy(&zNewRecord[j], (char*)&addr, sizeof(int));
-    j += sizeof(int);
   }
   for(i=p->tos-nField+1; i<=p->tos; i++){
     if( (aStack[i].flags & STK_Null)==0 ){
@@ -2300,7 +2300,7 @@ case OP_KeyAsData: {
 case OP_Column: {
   int amt, offset, nCol, payloadSize;
   int aHdr[10];
-  const int mxHdr = sizeof(aHdr)/sizeof(aHdr[0]);
+  static const int mxHdr = sizeof(aHdr)/sizeof(aHdr[0]);
   int i = pOp->p1;
   int p2 = pOp->p2;
   int tos = ++p->tos;
@@ -2338,6 +2338,7 @@ case OP_Column: {
     if( p2+1<mxHdr ){
       (*xRead)(pCrsr, 0, sizeof(aHdr[0])*(p2+2), (char*)aHdr);
       nCol = aHdr[0];
+      nCol /= sizeof(int);
       offset = aHdr[p2];
       if( p2 == nCol-1 ){
         amt = payloadSize - offset;
index 33cb3897d702397339ebc1f8dd99c36a7335a565..91ffa143eeff95c98b749bec6faf164cfb807e8a 100644 (file)
@@ -25,7 +25,7 @@
 ** the WHERE clause of SQL statements.  Also found here are subroutines
 ** to generate VDBE code to evaluate expressions.
 **
-** $Id: where.c,v 1.17 2001/09/13 14:46:11 drh Exp $
+** $Id: where.c,v 1.18 2001/09/13 16:18:55 drh Exp $
 */
 #include "sqliteInt.h"
 
@@ -358,6 +358,7 @@ WhereInfo *sqliteWhereBegin(
       /* Case 2:  There was no usable index.  We must do a complete
       ** scan of the table.
       */
+      sqliteVdbeAddOp(v, OP_Rewind, base+idx, 0, 0, 0);
       cont = sqliteVdbeMakeLabel(v);
       sqliteVdbeAddOp(v, OP_Next, base+idx, brk, 0, cont);
       haveKey = 0;