Work toward getting the new btree.c integrated with vdbe.c. (CVS 1345)

FossilOrigin-Name: bc5a2dafa1df74ba6403b4751ac1c33b0fee2884
diff --git a/src/btree.c b/src/btree.c
index 9947e0e..7daab2a 100644
--- a/src/btree.c
+++ b/src/btree.c
@@ -9,7 +9,7 @@
 **    May you share freely, never taking more than you give.
 **
 *************************************************************************
-** $Id: btree.c,v 1.123 2004/05/10 18:45:10 drh Exp $
+** $Id: btree.c,v 1.124 2004/05/10 23:29:49 drh Exp $
 **
 ** This file implements a external (disk-based) database using BTrees.
 ** For a detailed discussion of BTrees, refer to
@@ -1894,6 +1894,7 @@
   assert( pCur->pPage );
   assert( pCur->pPage->isInit );
   if( pCur->isValid==0 ){
+    *pRes = -1;
     assert( pCur->pPage->nCell==0 );
     return SQLITE_OK;
   }
@@ -3160,7 +3161,7 @@
   if( rc ) return rc;
   assert( szNew==cellSize(pPage, newCell) );
   assert( szNew<=sizeof(newCell) );
-  if( loc==0 ){
+  if( loc==0 && pCur->isValid ){
     int szOld;
     assert( pCur->idx>=0 && pCur->idx<pPage->nCell );
     oldCell = pPage->aCell[pCur->idx];
@@ -3425,6 +3426,15 @@
   return SQLITE_OK;
 }
 
+/*
+** Return the flag byte at the beginning of the page that the cursor
+** is currently pointing to.
+*/
+int sqlite3BtreeFlags(BtCursor *pCur){
+  MemPage *pPage = pCur->pPage;
+  return pPage ? pPage->aData[pPage->hdrOffset] : 0;
+}
+
 /******************************************************************************
 ** The complete implementation of the BTree subsystem is above this line.
 ** All the code the follows is for testing and troubleshooting the BTree
@@ -3532,16 +3542,6 @@
 
 #ifdef SQLITE_TEST
 /*
-** Return the flag byte at the beginning of the page that the cursor
-** is currently pointing to.
-*/
-int sqlite3BtreeFlags(BtCursor *pCur){
-  return pCur->pPage->aData[pCur->pPage->hdrOffset];
-}
-#endif
-
-#ifdef SQLITE_TEST
-/*
 ** Fill aResult[] with information about the entry and page that the
 ** cursor is pointing to.
 ** 
diff --git a/src/btree.h b/src/btree.h
index c0904c0..625084f 100644
--- a/src/btree.h
+++ b/src/btree.h
@@ -13,7 +13,7 @@
 ** subsystem.  See comments in the source code for a detailed description
 ** of what each interface routine does.
 **
-** @(#) $Id: btree.h,v 1.43 2004/05/09 23:23:57 danielk1977 Exp $
+** @(#) $Id: btree.h,v 1.44 2004/05/10 23:29:50 drh Exp $
 */
 #ifndef _BTREE_H_
 #define _BTREE_H_
@@ -81,6 +81,7 @@
 int sqlite3BtreeLast(BtCursor*, int *pRes);
 int sqlite3BtreeNext(BtCursor*, int *pRes);
 int sqlite3BtreeEof(BtCursor*);
+int sqlite3BtreeFlags(BtCursor*);
 int sqlite3BtreePrevious(BtCursor*, int *pRes);
 int sqlite3BtreeKeySize(BtCursor*, u64 *pSize);
 int sqlite3BtreeKey(BtCursor*, u32 offset, u32 amt, void*);
@@ -91,10 +92,10 @@
 char *sqlite3BtreeIntegrityCheck(Btree*, int *aRoot, int nRoot);
 struct Pager *sqlite3BtreePager(Btree*);
 
+
 #ifdef SQLITE_TEST
 int sqlite3BtreeCursorInfo(BtCursor*, int*);
 void sqlite3BtreeCursorList(Btree*);
-int sqlite3BtreeFlags(BtCursor*);
 int sqlite3BtreePageDump(Btree*, int, int recursive);
 #endif
 
diff --git a/src/main.c b/src/main.c
index 7355428..bcb9b13 100644
--- a/src/main.c
+++ b/src/main.c
@@ -14,7 +14,7 @@
 ** other files are for internal use by SQLite and should not be
 ** accessed by users of the library.
 **
-** $Id: main.c,v 1.168 2004/05/10 10:34:43 danielk1977 Exp $
+** $Id: main.c,v 1.169 2004/05/10 23:29:50 drh Exp $
 */
 #include "sqliteInt.h"
 #include "os.h"
@@ -217,34 +217,11 @@
   ;
 
   /* The following SQL will read the schema from the master tables.
-  ** The first version works with SQLite file formats 2 or greater.
-  ** The second version is for format 1 files.
-  **
-  ** Beginning with file format 2, the rowid for new table entries
-  ** (including entries in sqlite_master) is an increasing integer.
-  ** So for file format 2 and later, we can play back sqlite_master
-  ** and all the CREATE statements will appear in the right order.
-  ** But with file format 1, table entries were random and so we
-  ** have to make sure the CREATE TABLEs occur before their corresponding
-  ** CREATE INDEXs.  (We don't have to deal with CREATE VIEW or
-  ** CREATE TRIGGER in file format 1 because those constructs did
-  ** not exist then.) 
   */
   static char init_script[] = 
-/****** FIX ME
      "SELECT type, name, rootpage, sql, 1 FROM sqlite_temp_master "
      "UNION ALL "
-*/
      "SELECT type, name, rootpage, sql, 0 FROM sqlite_master";
-  static char older_init_script[] = 
-     "SELECT type, name, rootpage, sql, 1 FROM sqlite_temp_master "
-     "UNION ALL "
-     "SELECT type, name, rootpage, sql, 0 FROM sqlite_master "
-     "WHERE type='table' "
-     "UNION ALL "
-     "SELECT type, name, rootpage, sql, 0 FROM sqlite_master "
-     "WHERE type='index'";
-
 
   assert( iDb>=0 && iDb!=1 && iDb<db->nDb );
 
@@ -281,23 +258,25 @@
   */
   if( db->aDb[iDb].pBt==0 ) return SQLITE_OK;
   rc = sqlite3BtreeCursor(db->aDb[iDb].pBt, MASTER_ROOT, 0, 0, 0, &curMain);
-  if( rc ){
+  if( rc!=SQLITE_OK && rc!=SQLITE_EMPTY ){
     sqlite3SetString(pzErrMsg, sqlite3_error_string(rc), (char*)0);
     return rc;
   }
 
   /* Get the database meta information
   */
-  {
-    int ii;
-    for(ii=0; rc==SQLITE_OK && ii<SQLITE_N_BTREE_META; ii++){
-      rc = sqlite3BtreeGetMeta(db->aDb[iDb].pBt, ii+1, &meta[ii]);
+  if( rc==SQLITE_OK ){
+    int i;
+    for(i=0; rc==SQLITE_OK && i<SQLITE_N_BTREE_META; i++){
+      rc = sqlite3BtreeGetMeta(db->aDb[iDb].pBt, i+1, &meta[i]);
     }
-  }
-  if( rc ){
-    sqlite3SetString(pzErrMsg, sqlite3_error_string(rc), (char*)0);
-    sqlite3BtreeCloseCursor(curMain);
-    return rc;
+    if( rc ){
+      sqlite3SetString(pzErrMsg, sqlite3_error_string(rc), (char*)0);
+      sqlite3BtreeCloseCursor(curMain);
+      return rc;
+    }
+  }else{
+    memset(meta, 0, sizeof(meta));
   }
   db->aDb[iDb].schema_cookie = meta[1];
   if( iDb==0 ){
@@ -313,22 +292,17 @@
     if( db->safety_level==0 ) db->safety_level = 2;
 
     /*
-    **  file_format==1    Version 2.1.0.
-    **  file_format==2    Version 2.2.0. Add support for INTEGER PRIMARY KEY.
-    **  file_format==3    Version 2.6.0. Fix empty-string index bug.
-    **  file_format==4    Version 2.7.0. Add support for separate numeric and
-    **                    text datatypes.
+    **  file_format==1    Version 3.0.0.
     */
     if( db->file_format==0 ){
       /* This happens if the database was initially empty */
-      db->file_format = 4;
-    }else if( db->file_format>4 ){
+      db->file_format = 1;
+    }else if( db->file_format>1 ){
       sqlite3BtreeCloseCursor(curMain);
       sqlite3SetString(pzErrMsg, "unsupported file format", (char*)0);
       return SQLITE_ERROR;
     }
-  }else if( db->file_format!=meta[2] || db->file_format<4 ){
-    assert( db->file_format>=4 );
+  }else if( db->file_format!=meta[2] ){
     if( meta[2]==0 ){
       sqlite3SetString(pzErrMsg, "cannot attach empty database: ",
          db->aDb[iDb].zName, (char*)0);
@@ -347,20 +321,23 @@
   */
   assert( db->init.busy );
   sqlite3SafetyOff(db);
-  if( iDb==0 ){
-    rc = sqlite3_exec(db, 
-        db->file_format>=2 ? init_script : older_init_script,
-        sqlite3InitCallback, &initData, 0);
+  if( rc==SQLITE_EMPTY ){
+    /* For an empty database, there is nothing to read */
+    rc = SQLITE_OK;
   }else{
-    char *zSql = 0;
-    sqlite3SetString(&zSql, 
-       "SELECT type, name, rootpage, sql, ", zDbNum, " FROM \"",
-       db->aDb[iDb].zName, "\".sqlite_master", (char*)0);
-    rc = sqlite3_exec(db, zSql, sqlite3InitCallback, &initData, 0);
-    sqliteFree(zSql);
+    if( iDb==0 ){
+      rc = sqlite3_exec(db, init_script, sqlite3InitCallback, &initData, 0);
+    }else{
+      char *zSql = 0;
+      sqlite3SetString(&zSql, 
+         "SELECT type, name, rootpage, sql, ", zDbNum, " FROM \"",
+         db->aDb[iDb].zName, "\".sqlite_master", (char*)0);
+      rc = sqlite3_exec(db, zSql, sqlite3InitCallback, &initData, 0);
+      sqliteFree(zSql);
+    }
+    sqlite3SafetyOn(db);
+    sqlite3BtreeCloseCursor(curMain);
   }
-  sqlite3SafetyOn(db);
-  sqlite3BtreeCloseCursor(curMain);
   if( sqlite3_malloc_failed ){
     sqlite3SetString(pzErrMsg, "out of memory", (char*)0);
     rc = SQLITE_NOMEM;
diff --git a/src/sqliteInt.h b/src/sqliteInt.h
index a04fb2c..1176887 100644
--- a/src/sqliteInt.h
+++ b/src/sqliteInt.h
@@ -11,7 +11,7 @@
 *************************************************************************
 ** Internal interface definitions for SQLite.
 **
-** @(#) $Id: sqliteInt.h,v 1.228 2004/05/10 10:34:52 danielk1977 Exp $
+** @(#) $Id: sqliteInt.h,v 1.229 2004/05/10 23:29:50 drh Exp $
 */
 #include "config.h"
 #include "sqlite.h"
@@ -120,6 +120,7 @@
 #   define INTPTR_TYPE long long
 # endif
 #endif
+typedef INT64_TYPE i64;            /* 8-byte signed integer */
 typedef UINT64_TYPE u64;           /* 8-byte unsigned integer */
 typedef UINT32_TYPE u32;           /* 4-byte unsigned integer */
 typedef UINT16_TYPE u16;           /* 2-byte unsigned integer */
@@ -367,8 +368,8 @@
   void *pCommitArg;             /* Argument to xCommitCallback() */   
   int (*xCommitCallback)(void*);/* Invoked at every commit. */
   Hash aFunc;                   /* All functions that can be in SQL exprs */
-  int lastRowid;                /* ROWID of most recent insert (see above) */
-  int priorNewRowid;            /* Last randomly generated ROWID */
+  i64 lastRowid;                /* ROWID of most recent insert (see above) */
+  i64 priorNewRowid;            /* Last randomly generated ROWID */
   int magic;                    /* Magic number for detect library misuse */
   int nChange;                  /* Number of rows changed (see above) */
   int lsChange;                 /* Last statement change count (see above) */
@@ -1287,4 +1288,3 @@
 int sqlite3PutVarint(unsigned char *, u64);
 int sqlite3GetVarint(const unsigned char *, u64 *);
 int sqlite3VarintLen(u64 v);
-
diff --git a/src/vdbe.c b/src/vdbe.c
index 4193a9b..a963205 100644
--- a/src/vdbe.c
+++ b/src/vdbe.c
@@ -43,7 +43,7 @@
 ** 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.273 2004/05/10 10:35:00 danielk1977 Exp $
+** $Id: vdbe.c,v 1.274 2004/05/10 23:29:50 drh Exp $
 */
 #include "sqliteInt.h"
 #include "os.h"
@@ -2528,18 +2528,13 @@
 ** executing this instruction.
 */
 case OP_ReadCookie: {
-  int aMeta[SQLITE_N_BTREE_META];
+  int iMeta;
   assert( pOp->p2<SQLITE_N_BTREE_META );
   assert( pOp->p1>=0 && pOp->p1<db->nDb );
   assert( db->aDb[pOp->p1].pBt!=0 );
-  {
-    int ii;
-    for(ii=0; rc==SQLITE_OK && ii<SQLITE_N_BTREE_META; ii++){
-      rc = sqlite3BtreeGetMeta(db->aDb[pOp->p1].pBt, ii+1, &aMeta[ii]);
-    }
-  }
+  rc = sqlite3BtreeGetMeta(db->aDb[pOp->p1].pBt, pOp->p2+1, &iMeta);
   pTos++;
-  pTos->i = aMeta[1+pOp->p2];
+  pTos->i = iMeta;
   pTos->flags = MEM_Int;
   break;
 }
@@ -2555,27 +2550,12 @@
 ** A transaction must be started before executing this opcode.
 */
 case OP_SetCookie: {
-  int aMeta[SQLITE_N_BTREE_META];
   assert( pOp->p2<SQLITE_N_BTREE_META );
   assert( pOp->p1>=0 && pOp->p1<db->nDb );
   assert( db->aDb[pOp->p1].pBt!=0 );
   assert( pTos>=p->aStack );
-  Integerify(pTos)
-  {
-    int ii;
-    for(ii=0; rc==SQLITE_OK && ii<SQLITE_N_BTREE_META; ii++){
-      rc = sqlite3BtreeGetMeta(db->aDb[pOp->p1].pBt, ii+1, &aMeta[ii]);
-    }
-  }
-  if( rc==SQLITE_OK ){
-    aMeta[1+pOp->p2] = pTos->i;
-    {
-      int ii;
-      for(ii=0; rc==SQLITE_OK && ii<SQLITE_N_BTREE_META; ii++){
-        rc = sqlite3BtreeUpdateMeta(db->aDb[pOp->p1].pBt, ii+1, aMeta[ii]);
-      }
-    }
-  }
+  Integerify(pTos);
+  rc = sqlite3BtreeUpdateMeta(db->aDb[pOp->p1].pBt, 1+pOp->p2, (int)pTos->i);
   Release(pTos);
   pTos--;
   break;
@@ -2598,15 +2578,10 @@
 ** invoked.
 */
 case OP_VerifyCookie: {
-  int aMeta[SQLITE_N_BTREE_META];
+  int iMeta;
   assert( pOp->p1>=0 && pOp->p1<db->nDb );
-  {
-    int ii;
-    for(ii=0; rc==SQLITE_OK && ii<SQLITE_N_BTREE_META; ii++){
-      rc = sqlite3BtreeGetMeta(db->aDb[pOp->p1].pBt, ii+1, &aMeta[ii]);
-    }
-  }
-  if( rc==SQLITE_OK && aMeta[1]!=pOp->p2 ){
+  rc = sqlite3BtreeGetMeta(db->aDb[pOp->p1].pBt, 1, &iMeta);
+  if( rc==SQLITE_OK && iMeta!=pOp->p2 ){
     sqlite3SetString(&p->zErrMsg, "database schema has changed", (char*)0);
     rc = SQLITE_SCHEMA;
   }
@@ -2665,6 +2640,7 @@
   int wrFlag;
   Btree *pX;
   int iDb;
+  Cursor *pCur;
   
   assert( pTos>=p->aStack );
   Integerify(pTos);
@@ -2687,12 +2663,13 @@
   }
   assert( i>=0 );
   if( expandCursorArraySize(p, i) ) goto no_mem;
-  sqlite3VdbeCleanupCursor(&p->aCsr[i]);
-  memset(&p->aCsr[i], 0, sizeof(Cursor));
-  p->aCsr[i].nullRow = 1;
+  pCur = &p->aCsr[i];
+  sqlite3VdbeCleanupCursor(pCur);
+  memset(pCur, 0, sizeof(Cursor));
+  pCur->nullRow = 1;
   if( pX==0 ) break;
   do{
-    rc = sqlite3BtreeCursor(pX, p2, wrFlag, 0, 0, &p->aCsr[i].pCursor);
+    rc = sqlite3BtreeCursor(pX, p2, wrFlag, 0, 0, &pCur->pCursor);
     switch( rc ){
       case SQLITE_BUSY: {
         if( db->xBusyCallback==0 ){
@@ -2707,6 +2684,9 @@
         break;
       }
       case SQLITE_OK: {
+        int flags = sqlite3BtreeFlags(pCur->pCursor);
+        pCur->intKey = (flags & BTREE_INTKEY)!=0;
+        pCur->zeroData = (flags & BTREE_ZERODATA)!=0;
         busy = 0;
         break;
       }
@@ -2754,16 +2734,17 @@
     /* If a transient index is required, create it by calling
     ** sqlite3BtreeCreateTable() with the BTREE_ZERODATA flag before
     ** opening it. If a transient table is required, just use the
-    ** automatically created table with root-page 2.
+    ** automatically created table with root-page 1.
     */
     if( pOp->p2 ){
       int pgno;
       rc = sqlite3BtreeCreateTable(pCx->pBt, &pgno, BTREE_ZERODATA); 
       if( rc==SQLITE_OK ){
+        assert( pgno==MASTER_ROOT+1 );
         rc = sqlite3BtreeCursor(pCx->pBt, pgno, 1, 0, 0, &pCx->pCursor);
       }
     }else{
-      rc = sqlite3BtreeCursor(pCx->pBt, 2, 1, 0, 0, &pCx->pCursor);
+      rc = sqlite3BtreeCursor(pCx->pBt, MASTER_ROOT, 1, 0, 0, &pCx->pCursor);
     }
   }
   break;
@@ -2837,8 +2818,10 @@
   if( pC->pCursor!=0 ){
     int res, oc;
     pC->nullRow = 0;
-    if( pTos->flags & MEM_Int ){
-      int iKey = intToKey(pTos->i);
+    if( pC->intKey ){
+      i64 iKey;
+      assert( pTos->flags & MEM_Int );
+      iKey = intToKey(pTos->i);
       if( pOp->p2==0 && pOp->opcode==OP_MoveTo ){
         pC->movetoTarget = iKey;
         pC->deferredMoveto = 1;
@@ -2846,7 +2829,7 @@
         pTos--;
         break;
       }
-      sqlite3BtreeMoveto(pC->pCursor, (char*)&iKey, sizeof(int), &res);
+      sqlite3BtreeMoveto(pC->pCursor, 0, (u64)iKey, &res);
       pC->lastRecno = pTos->i;
       pC->recnoIsValid = res==0;
     }else{
@@ -2871,8 +2854,7 @@
         /* res might be negative because the table is empty.  Check to
         ** see if this is the case.
         */
-        int keysize;
-        /* TODO: res = sqlite3BtreeKeySize(pC->pCursor,&keysize)!=0 || * keysize==0; */
+        res = sqlite3BtreeEof(pC->pCursor);
       }
       if( res && pOp->p2>0 ){
         pc = pOp->p2 - 1;
@@ -2927,6 +2909,7 @@
   assert( i>=0 && i<p->nCursor );
   if( (pC = &p->aCsr[i])->pCursor!=0 ){
     int res, rx;
+    assert( pC->intKey==0 );
     Stringify(pTos);
     rx = sqlite3BtreeMoveto(pC->pCursor, pTos->z, pTos->n, &res);
     alreadyExists = rx==SQLITE_OK && res==0;
@@ -2967,6 +2950,7 @@
 case OP_IsUnique: {
   int i = pOp->p1;
   Mem *pNos = &pTos[-1];
+  Cursor *pCx;
   BtCursor *pCrsr;
   int R;
 
@@ -2977,7 +2961,9 @@
   R = pTos->i;
   pTos--;
   assert( i>=0 && i<=p->nCursor );
-  if( (pCrsr = p->aCsr[i].pCursor)!=0 ){
+  pCx = &p->aCsr[i];
+  pCrsr = pCx->pCursor;
+  if( pCrsr!=0 ){
     int res, rc;
     int v;         /* The record number on the P1 entry that matches K */
     char *zKey;    /* The value of K */
@@ -3080,11 +3066,11 @@
 */
 case OP_NewRecno: {
   int i = pOp->p1;
-  int v = 0;
+  i64 v = 0;
   Cursor *pC;
   assert( i>=0 && i<p->nCursor );
   if( (pC = &p->aCsr[i])->pCursor==0 ){
-    v = 0;
+    /* The zero initialization above is all that is needed */
   }else{
     /* The next rowid or record number (different terms for the same
     ** thing) is obtained in a two-step algorithm.
@@ -3117,8 +3103,11 @@
     ** larger than the previous rowid.  This has been shown experimentally
     ** to double the speed of the COPY operation.
     */
-    int res, rx, cnt, x;
+    int res, rx, cnt;
+    i64 x;
     cnt = 0;
+    assert( (sqlite3BtreeFlags(pC->pCursor) & BTREE_INTKEY)!=0 );
+    assert( (sqlite3BtreeFlags(pC->pCursor) & BTREE_ZERODATA)==0 );
     if( !pC->useRandomRowid ){
       if( pC->nextRowidValid ){
         v = pC->nextRowid;
@@ -3127,16 +3116,16 @@
         if( res ){
           v = 1;
         }else{
-          sqlite3BtreeKey(pC->pCursor, 0, sizeof(v), (void*)&v);
+          sqlite3BtreeKeySize(pC->pCursor, (u64*)&v);
           v = keyToInt(v);
-          if( v==0x7fffffff ){
+          if( v==0x7fffffffffffffff ){
             pC->useRandomRowid = 1;
           }else{
             v++;
           }
         }
       }
-      if( v<0x7fffffff ){
+      if( v<0x7fffffffffffffff ){
         pC->nextRowidValid = 1;
         pC->nextRowid = v+1;
       }else{
@@ -3157,7 +3146,7 @@
         }
         if( v==0 ) continue;
         x = intToKey(v);
-        rx = sqlite3BtreeMoveto(pC->pCursor, &x, sizeof(int), &res);
+        rx = sqlite3BtreeMoveto(pC->pCursor, 0, (u64)x, &res);
         cnt++;
       }while( cnt<1000 && rx==SQLITE_OK && res==0 );
       db->priorNewRowid = v;
@@ -3517,7 +3506,7 @@
 case OP_Recno: {
   int i = pOp->p1;
   Cursor *pC;
-  int v;
+  i64 v;
 
   assert( i>=0 && i<p->nCursor );
   pC = &p->aCsr[i];
@@ -3532,7 +3521,7 @@
     break;
   }else{
     assert( pC->pCursor!=0 );
-    sqlite3BtreeKey(pC->pCursor, 0, sizeof(u32), (char*)&v);
+    sqlite3BtreeKeySize(pC->pCursor, (u64*)&v);
     v = keyToInt(v);
   }
   pTos->i = v;
@@ -3965,14 +3954,16 @@
 case OP_CreateIndex:
 case OP_CreateTable: {
   int pgno;
+  int flags;
   assert( pOp->p3!=0 && pOp->p3type==P3_POINTER );
   assert( pOp->p2>=0 && pOp->p2<db->nDb );
   assert( db->aDb[pOp->p2].pBt!=0 );
   if( pOp->opcode==OP_CreateTable ){
-    rc = sqlite3BtreeCreateTable(db->aDb[pOp->p2].pBt, &pgno, BTREE_INTKEY);
+    flags = BTREE_INTKEY;
   }else{
-    rc = sqlite3BtreeCreateTable(db->aDb[pOp->p2].pBt, &pgno, BTREE_ZERODATA);
+    flags = BTREE_ZERODATA;
   }
+  rc = sqlite3BtreeCreateTable(db->aDb[pOp->p2].pBt, &pgno, flags);
   pTos++;
   if( rc==SQLITE_OK ){
     pTos->i = pgno;
diff --git a/src/vdbeInt.h b/src/vdbeInt.h
index 9d254f8..2e52ce9 100644
--- a/src/vdbeInt.h
+++ b/src/vdbeInt.h
@@ -17,13 +17,12 @@
 */
 
 /*
-** When converting from the native format to the key format and back
-** again, in addition to changing the byte order we invert the high-order
-** bit of the most significant byte.  This causes negative numbers to
-** sort before positive numbers in the memcmp() function.
+** In the btree layer, a rowid is an unsigned 64-bit integer.  In the
+** schema layer, a rowid is a signed 64-bit integer.  The following macros
+** convert between the two in such a way as to preserve sort order.
 */
-#define keyToInt(X)   (sqlite3VdbeByteSwap(X) ^ 0x80000000)
-#define intToKey(X)   (sqlite3VdbeByteSwap((X) ^ 0x80000000))
+#define keyToInt(X)   (X ^ 0x8000000000000000)
+#define intToKey(X)   (X ^ 0x8000000000000000)
 
 /*
 ** The makefile scans this source file and creates the following
@@ -62,8 +61,8 @@
 */
 struct Cursor {
   BtCursor *pCursor;    /* The cursor structure of the backend */
-  int lastRecno;        /* Last recno from a Next or NextIdx operation */
-  int nextRowid;        /* Next rowid returned by OP_NewRowid */
+  i64 lastRecno;        /* Last recno from a Next or NextIdx operation */
+  i64 nextRowid;        /* Next rowid returned by OP_NewRowid */
   Bool recnoIsValid;    /* True if lastRecno is valid */
   Bool keyAsData;       /* The OP_Column command works on key instead of data */
   Bool atFirst;         /* True if pointing to first entry */
@@ -72,11 +71,13 @@
   Bool nextRowidValid;  /* True if the nextRowid field is valid */
   Bool pseudoTable;     /* This is a NEW or OLD pseudo-tables of a trigger */
   Bool deferredMoveto;  /* A call to sqlite3BtreeMoveto() is needed */
-  int movetoTarget;     /* Argument to the deferred sqlite3BtreeMoveto() */
+  Bool intKey;          /* True if the table requires integer keys */
+  Bool zeroData;        /* True if table contains keys only - no data */
+  i64 movetoTarget;     /* Argument to the deferred sqlite3BtreeMoveto() */
   Btree *pBt;           /* Separate file holding temporary table */
   int nData;            /* Number of bytes in pData */
   char *pData;          /* Data for a NEW or OLD pseudo-table */
-  int iKey;             /* Key for the NEW or OLD pseudo-table row */
+  i64 iKey;             /* Key for the NEW or OLD pseudo-table row */
 };
 typedef struct Cursor Cursor;
 
@@ -110,7 +111,7 @@
 ** is an instance of the following structure. 
 */
 struct Mem {
-  int i;              /* Integer value */
+  i64 i;              /* Integer value */
   int n;              /* Number of characters in string value, including '\0' */
   int flags;          /* Some combination of MEM_Null, MEM_Str, MEM_Dyn, etc. */
   double r;           /* Real value */