Update older opcode names to be more meaningful in light of the latest
code design. (CVS 2506)

FossilOrigin-Name: 36f2da1f8d8d434f861ecad55c9d86549751c954
diff --git a/src/build.c b/src/build.c
index a948e28..ae21902 100644
--- a/src/build.c
+++ b/src/build.c
@@ -22,7 +22,7 @@
 **     COMMIT
 **     ROLLBACK
 **
-** $Id: build.c,v 1.325 2005/06/06 21:19:57 drh Exp $
+** $Id: build.c,v 1.326 2005/06/12 21:35:52 drh Exp $
 */
 #include "sqliteInt.h"
 #include <ctype.h>
@@ -791,10 +791,10 @@
       sqlite3VdbeAddOp(v, OP_CreateTable, iDb, 0);
     }
     sqlite3OpenMasterTable(v, iDb);
-    sqlite3VdbeAddOp(v, OP_NewRecno, 0, 0);
+    sqlite3VdbeAddOp(v, OP_NewRowid, 0, 0);
     sqlite3VdbeAddOp(v, OP_Dup, 0, 0);
-    sqlite3VdbeAddOp(v, OP_String8, 0, 0);
-    sqlite3VdbeAddOp(v, OP_PutIntKey, 0, 0);
+    sqlite3VdbeAddOp(v, OP_Null, 0, 0);
+    sqlite3VdbeAddOp(v, OP_Insert, 0, 0);
     sqlite3VdbeAddOp(v, OP_Close, 0, 0);
     sqlite3VdbeAddOp(v, OP_Pull, 1, 0);
   }
@@ -2008,7 +2008,7 @@
   addr1 = sqlite3VdbeAddOp(v, OP_Rewind, iTab, 0);
   sqlite3GenerateIndexKey(v, pIndex, iTab);
   isUnique = pIndex->onError!=OE_None;
-  sqlite3VdbeAddOp(v, OP_IdxPut, iIdx, isUnique);
+  sqlite3VdbeAddOp(v, OP_IdxInsert, iIdx, isUnique);
   if( isUnique ){
     sqlite3VdbeChangeP3(v, -1, "indexed columns are not unique", P3_STATIC);
   }
diff --git a/src/delete.c b/src/delete.c
index 515842c..bf66c75 100644
--- a/src/delete.c
+++ b/src/delete.c
@@ -12,7 +12,7 @@
 ** 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.105 2005/06/06 21:19:57 drh Exp $
+** $Id: delete.c,v 1.106 2005/06/12 21:35:52 drh Exp $
 */
 #include "sqliteInt.h"
 
@@ -239,7 +239,7 @@
 
     /* Remember the rowid of every item to be deleted.
     */
-    sqlite3VdbeAddOp(v, OP_Recno, iCur, 0);
+    sqlite3VdbeAddOp(v, OP_Rowid, iCur, 0);
     sqlite3VdbeAddOp(v, OP_ListWrite, 0, 0);
     if( db->flags & SQLITE_CountRows ){
       sqlite3VdbeAddOp(v, OP_AddImm, 1, 0);
@@ -273,9 +273,9 @@
         sqlite3OpenTableForReading(v, iCur, pTab);
       }
       sqlite3VdbeAddOp(v, OP_MoveGe, iCur, 0);
-      sqlite3VdbeAddOp(v, OP_Recno, iCur, 0);
+      sqlite3VdbeAddOp(v, OP_Rowid, iCur, 0);
       sqlite3VdbeAddOp(v, OP_RowData, iCur, 0);
-      sqlite3VdbeAddOp(v, OP_PutIntKey, oldIdx, 0);
+      sqlite3VdbeAddOp(v, OP_Insert, oldIdx, 0);
       if( !isView ){
         sqlite3VdbeAddOp(v, OP_Close, iCur, 0);
       }
@@ -432,7 +432,7 @@
   int j;
   Table *pTab = pIdx->pTable;
 
-  sqlite3VdbeAddOp(v, OP_Recno, iCur, 0);
+  sqlite3VdbeAddOp(v, OP_Rowid, iCur, 0);
   for(j=0; j<pIdx->nColumn; j++){
     int idx = pIdx->aiColumn[j];
     if( idx==pTab->iPKey ){
diff --git a/src/expr.c b/src/expr.c
index 39d928a..edba81a 100644
--- a/src/expr.c
+++ b/src/expr.c
@@ -12,7 +12,7 @@
 ** This file contains routines used for analyzing expressions and
 ** for generating VDBE code that evaluates expressions in SQLite.
 **
-** $Id: expr.c,v 1.205 2005/06/06 21:19:57 drh Exp $
+** $Id: expr.c,v 1.206 2005/06/12 21:35:52 drh Exp $
 */
 #include "sqliteInt.h"
 #include <ctype.h>
@@ -138,7 +138,7 @@
 */
 static int binaryCompareP1(Expr *pExpr1, Expr *pExpr2, int jumpIfNull){
   char aff = sqlite3ExprAffinity(pExpr2);
-  return (((int)sqlite3CompareAffinity(pExpr1, aff))<<8)+(jumpIfNull?1:0);
+  return ((int)sqlite3CompareAffinity(pExpr1, aff))+(jumpIfNull?0x100:0);
 }
 
 /*
@@ -1309,8 +1309,7 @@
           /* Evaluate the expression and insert it into the temp table */
           sqlite3ExprCode(pParse, pE2);
           sqlite3VdbeOp3(v, OP_MakeRecord, 1, 0, &affinity, 1);
-          sqlite3VdbeAddOp(v, OP_String8, 0, 0);
-          sqlite3VdbeAddOp(v, OP_PutStrKey, pExpr->iTable, 0);
+          sqlite3VdbeAddOp(v, OP_IdxInsert, pExpr->iTable, 0);
         }
       }
       sqlite3VdbeChangeP3(v, addr, (void *)&keyInfo, P3_KEYINFO);
@@ -1382,7 +1381,7 @@
   int op;
   if( v==0 ) return;
   if( pExpr==0 ){
-    sqlite3VdbeAddOp(v, OP_String8, 0, 0);  /* Empty expression evals to NULL */
+    sqlite3VdbeAddOp(v, OP_Null, 0, 0);
     return;
   }
   op = pExpr->op;
@@ -1394,7 +1393,7 @@
         sqlite3VdbeAddOp(v, OP_Column, pExpr->iTable, pExpr->iColumn);
         sqlite3ColumnDefault(v, pExpr->pTab, pExpr->iColumn);
       }else{
-        sqlite3VdbeAddOp(v, OP_Recno, pExpr->iTable, 0);
+        sqlite3VdbeAddOp(v, OP_Rowid, pExpr->iTable, 0);
       }
       break;
     }
@@ -1410,6 +1409,10 @@
       sqlite3VdbeDequoteP3(v, -1);
       break;
     }
+    case TK_NULL: {
+      sqlite3VdbeAddOp(v, OP_Null, 0, 0);
+      break;
+    }
 #ifndef SQLITE_OMIT_BLOB_LITERAL
     case TK_BLOB: {
       assert( TK_BLOB==OP_HexBlob );
@@ -1418,10 +1421,6 @@
       break;
     }
 #endif
-    case TK_NULL: {
-      sqlite3VdbeAddOp(v, OP_String8, 0, 0);
-      break;
-    }
     case TK_VARIABLE: {
       sqlite3VdbeAddOp(v, OP_Variable, pExpr->iTable, 0);
       if( pExpr->token.n>1 ){
@@ -1578,7 +1577,7 @@
       addr = sqlite3VdbeCurrentAddr(v);
       sqlite3VdbeAddOp(v, OP_NotNull, -1, addr+4);            /* addr + 0 */
       sqlite3VdbeAddOp(v, OP_Pop, 2, 0);
-      sqlite3VdbeAddOp(v, OP_String8, 0, 0);
+      sqlite3VdbeAddOp(v, OP_Null, 0, 0);
       sqlite3VdbeAddOp(v, OP_Goto, 0, addr+7);
       sqlite3VdbeOp3(v, OP_MakeRecord, 1, 0, &affinity, 1);   /* addr + 4 */
       sqlite3VdbeAddOp(v, OP_Found, pExpr->iTable, addr+7);
@@ -1648,7 +1647,7 @@
       if( pExpr->pRight ){
         sqlite3ExprCode(pParse, pExpr->pRight);
       }else{
-        sqlite3VdbeAddOp(v, OP_String8, 0, 0);
+        sqlite3VdbeAddOp(v, OP_Null, 0, 0);
       }
       sqlite3VdbeResolveLabel(v, expr_end_label);
       break;
diff --git a/src/insert.c b/src/insert.c
index f96184d..36a0244 100644
--- a/src/insert.c
+++ b/src/insert.c
@@ -12,7 +12,7 @@
 ** This file contains C code routines that are called by the parser
 ** to handle INSERT statements in SQLite.
 **
-** $Id: insert.c,v 1.138 2005/03/21 01:20:58 drh Exp $
+** $Id: insert.c,v 1.139 2005/06/12 21:35:52 drh Exp $
 */
 #include "sqliteInt.h"
 
@@ -308,7 +308,7 @@
     sqlite3VdbeAddOp(v, OP_Column, iCur, 0);
     sqlite3VdbeOp3(v, OP_String8, 0, 0, pTab->zName, 0);
     sqlite3VdbeAddOp(v, OP_Ne, 28417, base+12);
-    sqlite3VdbeAddOp(v, OP_Recno, iCur, 0);
+    sqlite3VdbeAddOp(v, OP_Rowid, iCur, 0);
     sqlite3VdbeAddOp(v, OP_MemStore, counterRowid, 1);
     sqlite3VdbeAddOp(v, OP_Column, iCur, 1);
     sqlite3VdbeAddOp(v, OP_MemStore, counterMem, 1);
@@ -363,9 +363,9 @@
       sqlite3VdbeResolveLabel(v, iInsertBlock);
       sqlite3VdbeAddOp(v, OP_MakeRecord, nColumn, 0);
       sqlite3TableAffinityStr(v, pTab);
-      sqlite3VdbeAddOp(v, OP_NewRecno, srcTab, 0);
+      sqlite3VdbeAddOp(v, OP_NewRowid, srcTab, 0);
       sqlite3VdbeAddOp(v, OP_Pull, 1, 0);
-      sqlite3VdbeAddOp(v, OP_PutIntKey, srcTab, 0);
+      sqlite3VdbeAddOp(v, OP_Insert, srcTab, 0);
       sqlite3VdbeAddOp(v, OP_Return, 0, 0);
 
       /* The following code runs first because the GOTO at the very top
@@ -547,7 +547,7 @@
     if( !isView ){
       sqlite3TableAffinityStr(v, pTab);
     }
-    sqlite3VdbeAddOp(v, OP_PutIntKey, newIdx, 0);
+    sqlite3VdbeAddOp(v, OP_Insert, newIdx, 0);
 
     /* Fire BEFORE or INSTEAD OF triggers */
     if( sqlite3CodeRowTrigger(pParse, TK_INSERT, 0, TRIGGER_BEFORE, pTab, 
@@ -565,7 +565,7 @@
   }
 
   /* Push the record number for the new entry onto the stack.  The
-  ** record number is a randomly generate integer created by NewRecno
+  ** record number is a randomly generate integer created by NewRowid
   ** except when the table has an INTEGER PRIMARY KEY column, in which
   ** case the record number is the same as that column. 
   */
@@ -578,15 +578,15 @@
       }else{
         sqlite3ExprCode(pParse, pList->a[keyColumn].pExpr);
       }
-      /* If the PRIMARY KEY expression is NULL, then use OP_NewRecno
+      /* If the PRIMARY KEY expression is NULL, then use OP_NewRowid
       ** to generate a unique primary key value.
       */
       sqlite3VdbeAddOp(v, OP_NotNull, -1, sqlite3VdbeCurrentAddr(v)+3);
       sqlite3VdbeAddOp(v, OP_Pop, 1, 0);
-      sqlite3VdbeAddOp(v, OP_NewRecno, base, counterMem);
+      sqlite3VdbeAddOp(v, OP_NewRowid, base, counterMem);
       sqlite3VdbeAddOp(v, OP_MustBeInt, 0, 0);
     }else{
-      sqlite3VdbeAddOp(v, OP_NewRecno, base, counterMem);
+      sqlite3VdbeAddOp(v, OP_NewRowid, base, counterMem);
     }
 #ifndef SQLITE_OMIT_AUTOINCREMENT
     if( pTab->autoInc ){
@@ -603,7 +603,7 @@
         ** Whenever this column is read, the record number will be substituted
         ** in its place.  So will fill this column with a NULL to avoid
         ** taking up data space with information that will never be used. */
-        sqlite3VdbeAddOp(v, OP_String8, 0, 0);
+        sqlite3VdbeAddOp(v, OP_Null, 0, 0);
         continue;
       }
       if( pColumn==0 ){
@@ -690,11 +690,11 @@
     sqlite3VdbeAddOp(v, OP_MemLoad, counterRowid, 0);
     sqlite3VdbeAddOp(v, OP_NotNull, -1, base+7);
     sqlite3VdbeAddOp(v, OP_Pop, 1, 0);
-    sqlite3VdbeAddOp(v, OP_NewRecno, iCur, 0);
+    sqlite3VdbeAddOp(v, OP_NewRowid, iCur, 0);
     sqlite3VdbeOp3(v, OP_String8, 0, 0, pTab->zName, 0);
     sqlite3VdbeAddOp(v, OP_MemLoad, counterMem, 0);
     sqlite3VdbeAddOp(v, OP_MakeRecord, 2, 0);
-    sqlite3VdbeAddOp(v, OP_PutIntKey, iCur, 0);
+    sqlite3VdbeAddOp(v, OP_Insert, iCur, 0);
     sqlite3VdbeAddOp(v, OP_Close, iCur, 0);
   }
 #endif
@@ -724,11 +724,11 @@
 ** When this routine is called, the stack contains (from bottom to top)
 ** the following values:
 **
-**    1.  The recno of the row to be updated before the update.  This
+**    1.  The rowid of the row to be updated before the update.  This
 **        value is omitted unless we are doing an UPDATE that involves a
 **        change to the record number.
 **
-**    2.  The recno of the row after the update.
+**    2.  The rowid of the row after the update.
 **
 **    3.  The data in the first column of the entry after the update.
 **
@@ -736,9 +736,9 @@
 **
 **    N.  The data in the last column of the entry after the update.
 **
-** The old recno shown as entry (1) above is omitted unless both isUpdate
-** and recnoChng are 1.  isUpdate is true for UPDATEs and false for
-** INSERTs and recnoChng is true if the record number is being changed.
+** The old rowid shown as entry (1) above is omitted unless both isUpdate
+** and rowidChng are 1.  isUpdate is true for UPDATEs and false for
+** INSERTs and rowidChng is true if the record number is being changed.
 **
 ** The code generated by this routine pushes additional entries onto
 ** the stack which are the keys for new index entries for the new record.
@@ -802,7 +802,7 @@
   Table *pTab,        /* the table into which we are inserting */
   int base,           /* Index of a read/write cursor pointing at pTab */
   char *aIdxUsed,     /* Which indices are used.  NULL means all are used */
-  int recnoChng,      /* True if the record number will change */
+  int rowidChng,      /* True if the record number will change */
   int isUpdate,       /* True for UPDATE, False for INSERT */
   int overrideError,  /* Override onError to this if not OE_Default */
   int ignoreDest      /* Jump to this label on an OE_Ignore resolution */
@@ -818,7 +818,7 @@
   int seenReplace = 0;
   int jumpInst1=0, jumpInst2;
   int contAddr;
-  int hasTwoRecnos = (isUpdate && recnoChng);
+  int hasTwoRowids = (isUpdate && rowidChng);
 
   v = sqlite3GetVdbe(pParse);
   assert( v!=0 );
@@ -857,7 +857,7 @@
         break;
       }
       case OE_Ignore: {
-        sqlite3VdbeAddOp(v, OP_Pop, nCol+1+hasTwoRecnos, 0);
+        sqlite3VdbeAddOp(v, OP_Pop, nCol+1+hasTwoRowids, 0);
         sqlite3VdbeAddOp(v, OP_Goto, 0, ignoreDest);
         break;
       }
@@ -878,7 +878,7 @@
   ** of the new record does not previously exist.  Except, if this
   ** is an UPDATE and the primary key is not changing, that is OK.
   */
-  if( recnoChng ){
+  if( rowidChng ){
     onError = pTab->keyConf;
     if( overrideError!=OE_Default ){
       onError = overrideError;
@@ -908,7 +908,7 @@
       case OE_Replace: {
         sqlite3GenerateRowIndexDelete(pParse->db, v, pTab, base, 0);
         if( isUpdate ){
-          sqlite3VdbeAddOp(v, OP_Dup, nCol+hasTwoRecnos, 1);
+          sqlite3VdbeAddOp(v, OP_Dup, nCol+hasTwoRowids, 1);
           sqlite3VdbeAddOp(v, OP_MoveGe, base, 0);
         }
         seenReplace = 1;
@@ -916,7 +916,7 @@
       }
       case OE_Ignore: {
         assert( seenReplace==0 );
-        sqlite3VdbeAddOp(v, OP_Pop, nCol+1+hasTwoRecnos, 0);
+        sqlite3VdbeAddOp(v, OP_Pop, nCol+1+hasTwoRowids, 0);
         sqlite3VdbeAddOp(v, OP_Goto, 0, ignoreDest);
         break;
       }
@@ -967,7 +967,7 @@
     
 
     /* Check to see if the new index entry will be unique */
-    sqlite3VdbeAddOp(v, OP_Dup, extra+nCol+1+hasTwoRecnos, 1);
+    sqlite3VdbeAddOp(v, OP_Dup, extra+nCol+1+hasTwoRowids, 1);
     jumpInst2 = sqlite3VdbeAddOp(v, OP_IsUnique, base+iCur+1, 0);
 
     /* Generate code that executes if the new index entry is not unique */
@@ -1004,14 +1004,14 @@
       }
       case OE_Ignore: {
         assert( seenReplace==0 );
-        sqlite3VdbeAddOp(v, OP_Pop, nCol+extra+3+hasTwoRecnos, 0);
+        sqlite3VdbeAddOp(v, OP_Pop, nCol+extra+3+hasTwoRowids, 0);
         sqlite3VdbeAddOp(v, OP_Goto, 0, ignoreDest);
         break;
       }
       case OE_Replace: {
         sqlite3GenerateRowDelete(pParse->db, v, pTab, base, 0);
         if( isUpdate ){
-          sqlite3VdbeAddOp(v, OP_Dup, nCol+extra+1+hasTwoRecnos, 1);
+          sqlite3VdbeAddOp(v, OP_Dup, nCol+extra+1+hasTwoRowids, 1);
           sqlite3VdbeAddOp(v, OP_MoveGe, base, 0);
         }
         seenReplace = 1;
@@ -1031,7 +1031,7 @@
 ** This routine generates code to finish the INSERT or UPDATE operation
 ** that was started by a prior call to sqlite3GenerateConstraintChecks.
 ** The stack must contain keys for all active indices followed by data
-** and the recno for the new entry.  This routine creates the new
+** and the rowid for the new entry.  This routine creates the new
 ** entries in all indices and in the main table.
 **
 ** The arguments to this routine should be the same as the first six
@@ -1042,7 +1042,7 @@
   Table *pTab,        /* the table into which we are inserting */
   int base,           /* Index of a read/write cursor pointing at pTab */
   char *aIdxUsed,     /* Which indices are used.  NULL means all are used */
-  int recnoChng,      /* True if the record number will change */
+  int rowidChng,      /* True if the record number will change */
   int isUpdate,       /* True for UPDATE, False for INSERT */
   int newIdx          /* Index of NEW table for triggers.  -1 if none */
 ){
@@ -1058,7 +1058,7 @@
   for(nIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nIdx++){}
   for(i=nIdx-1; i>=0; i--){
     if( aIdxUsed && aIdxUsed[i]==0 ) continue;
-    sqlite3VdbeAddOp(v, OP_IdxPut, base+i+1, 0);
+    sqlite3VdbeAddOp(v, OP_IdxInsert, base+i+1, 0);
   }
   sqlite3VdbeAddOp(v, OP_MakeRecord, pTab->nCol, 0);
   sqlite3TableAffinityStr(v, pTab);
@@ -1066,7 +1066,7 @@
   if( newIdx>=0 ){
     sqlite3VdbeAddOp(v, OP_Dup, 1, 0);
     sqlite3VdbeAddOp(v, OP_Dup, 1, 0);
-    sqlite3VdbeAddOp(v, OP_PutIntKey, newIdx, 0);
+    sqlite3VdbeAddOp(v, OP_Insert, newIdx, 0);
   }
 #endif
   if( pParse->nested ){
@@ -1074,9 +1074,9 @@
   }else{
     pik_flags = (OPFLAG_NCHANGE|(isUpdate?0:OPFLAG_LASTROWID));
   }
-  sqlite3VdbeAddOp(v, OP_PutIntKey, base, pik_flags);
+  sqlite3VdbeAddOp(v, OP_Insert, base, pik_flags);
   
-  if( isUpdate && recnoChng ){
+  if( isUpdate && rowidChng ){
     sqlite3VdbeAddOp(v, OP_Pop, 1, 0);
   }
 }
diff --git a/src/pragma.c b/src/pragma.c
index d2116dd..a1aab2e 100644
--- a/src/pragma.c
+++ b/src/pragma.c
@@ -11,7 +11,7 @@
 *************************************************************************
 ** This file contains code used to implement the PRAGMA command.
 **
-** $Id: pragma.c,v 1.94 2005/06/07 22:22:51 drh Exp $
+** $Id: pragma.c,v 1.95 2005/06/12 21:35:52 drh Exp $
 */
 #include "sqliteInt.h"
 #include "os.h"
@@ -693,7 +693,7 @@
           static const VdbeOpList idxErr[] = {
             { OP_MemIncr,     0,  0,  0},
             { OP_String8,     0,  0,  "rowid "},
-            { OP_Recno,       1,  0,  0},
+            { OP_Rowid,       1,  0,  0},
             { OP_String8,     0,  0,  " missing from index "},
             { OP_String8,     0,  0,  0},    /* 4 */
             { OP_Concat,      2,  0,  0},
diff --git a/src/random.c b/src/random.c
index e7d518d..3d0903b 100644
--- a/src/random.c
+++ b/src/random.c
@@ -15,7 +15,7 @@
 ** Random numbers are used by some of the database backends in order
 ** to generate random integer keys for tables or random filenames.
 **
-** $Id: random.c,v 1.12 2004/05/08 08:23:32 danielk1977 Exp $
+** $Id: random.c,v 1.13 2005/06/12 21:35:52 drh Exp $
 */
 #include "sqliteInt.h"
 #include "os.h"
@@ -26,13 +26,16 @@
 ** must be held while executing this routine.
 **
 ** Why not just use a library random generator like lrand48() for this?
-** Because the OP_NewRecno opcode in the VDBE depends on having a very
+** Because the OP_NewRowid opcode in the VDBE depends on having a very
 ** good source of random numbers.  The lrand48() library function may
 ** well be good enough.  But maybe not.  Or maybe lrand48() has some
 ** subtle problems on some systems that could cause problems.  It is hard
 ** to know.  To minimize the risk of problems due to bad lrand48()
 ** implementations, SQLite uses this random number generator based
 ** on RC4, which we know works very well.
+**
+** (Later):  Actually, OP_NewRowid does not depend on a good source of
+** randomness any more.  But we will leave this code in all the same.
 */
 static int randomByte(){
   unsigned char t;
@@ -95,6 +98,3 @@
   }
   sqlite3OsLeaveMutex();
 }
-
-
-
diff --git a/src/select.c b/src/select.c
index 5985c4a..8588235 100644
--- a/src/select.c
+++ b/src/select.c
@@ -12,7 +12,7 @@
 ** This file contains C code routines that are called by the parser
 ** to handle SELECT statements in SQLite.
 **
-** $Id: select.c,v 1.251 2005/06/12 12:01:19 drh Exp $
+** $Id: select.c,v 1.252 2005/06/12 21:35:52 drh Exp $
 */
 #include "sqliteInt.h"
 
@@ -326,7 +326,7 @@
     sqlite3ExprCode(pParse, pOrderBy->a[i].pExpr);
   }
   sqlite3VdbeAddOp(v, OP_MakeRecord, pOrderBy->nExpr, 0);
-  sqlite3VdbeAddOp(v, OP_SortPut, 0, 0);
+  sqlite3VdbeAddOp(v, OP_SortInsert, 0, 0);
 }
 
 /*
@@ -422,8 +422,7 @@
     sqlite3VdbeAddOp(v, OP_Pop, pEList->nExpr+1, 0);
     sqlite3VdbeAddOp(v, OP_Goto, 0, iContinue);
     VdbeComment((v, "# skip indistinct records"));
-    sqlite3VdbeAddOp(v, OP_String8, 0, 0);
-    sqlite3VdbeAddOp(v, OP_PutStrKey, distinct, 0);
+    sqlite3VdbeAddOp(v, OP_IdxInsert, distinct, 0);
     if( pOrderBy==0 ){
       codeLimiter(v, p, iContinue, iBreak, nColumn);
     }
@@ -437,8 +436,7 @@
     case SRT_Union: {
       sqlite3VdbeAddOp(v, OP_MakeRecord, nColumn, NULL_ALWAYS_DISTINCT);
       sqlite3VdbeChangeP3(v, -1, aff, P3_STATIC);
-      sqlite3VdbeAddOp(v, OP_String8, 0, 0);
-      sqlite3VdbeAddOp(v, OP_PutStrKey, iParm, 0);
+      sqlite3VdbeAddOp(v, OP_IdxInsert, iParm, 0);
       break;
     }
 
@@ -464,9 +462,9 @@
       if( pOrderBy ){
         pushOntoSorter(pParse, v, pOrderBy);
       }else{
-        sqlite3VdbeAddOp(v, OP_NewRecno, iParm, 0);
+        sqlite3VdbeAddOp(v, OP_NewRowid, iParm, 0);
         sqlite3VdbeAddOp(v, OP_Pull, 1, 0);
-        sqlite3VdbeAddOp(v, OP_PutIntKey, iParm, 0);
+        sqlite3VdbeAddOp(v, OP_Insert, iParm, 0);
       }
       break;
     }
@@ -490,8 +488,7 @@
         char aff = (iParm>>16)&0xFF;
         aff = sqlite3CompareAffinity(pEList->a[0].pExpr, aff);
         sqlite3VdbeOp3(v, OP_MakeRecord, 1, 0, &aff, 1);
-        sqlite3VdbeAddOp(v, OP_String8, 0, 0);
-        sqlite3VdbeAddOp(v, OP_PutStrKey, (iParm&0x0000FFFF), 0);
+        sqlite3VdbeAddOp(v, OP_IdxInsert, (iParm&0x0000FFFF), 0);
       }
       sqlite3VdbeChangeP2(v, addr2, sqlite3VdbeCurrentAddr(v));
       break;
@@ -603,9 +600,9 @@
   switch( eDest ){
     case SRT_Table:
     case SRT_TempTable: {
-      sqlite3VdbeAddOp(v, OP_NewRecno, iParm, 0);
+      sqlite3VdbeAddOp(v, OP_NewRowid, iParm, 0);
       sqlite3VdbeAddOp(v, OP_Pull, 1, 0);
-      sqlite3VdbeAddOp(v, OP_PutIntKey, iParm, 0);
+      sqlite3VdbeAddOp(v, OP_Insert, iParm, 0);
       break;
     }
 #ifndef SQLITE_OMIT_SUBQUERY
@@ -615,8 +612,7 @@
       sqlite3VdbeAddOp(v, OP_Pop, 1, 0);
       sqlite3VdbeAddOp(v, OP_Goto, 0, sqlite3VdbeCurrentAddr(v)+3);
       sqlite3VdbeOp3(v, OP_MakeRecord, 1, 0, "n", P3_STATIC);
-      sqlite3VdbeAddOp(v, OP_String8, 0, 0);
-      sqlite3VdbeAddOp(v, OP_PutStrKey, (iParm&0x0000FFFF), 0);
+      sqlite3VdbeAddOp(v, OP_IdxInsert, (iParm&0x0000FFFF), 0);
       break;
     }
     case SRT_Exists:
@@ -1326,11 +1322,9 @@
 ** DISTINCT, UNION, INTERSECT and EXCEPT select statements (but not 
 ** UNION ALL).
 **
-** Make the new table a KeyAsData table if keyAsData is true.
-**
 ** The value returned is the address of the OP_OpenTemp instruction.
 */
-static int openTempIndex(Parse *pParse, Select *p, int iTab, int keyAsData){
+static int openTempIndex(Parse *pParse, Select *p, int iTab){
   KeyInfo *pKeyInfo;
   int nColumn;
   sqlite3 *db = pParse->db;
@@ -1354,9 +1348,6 @@
   }
   addr = sqlite3VdbeOp3(v, OP_OpenTemp, iTab, 0, 
       (char*)pKeyInfo, P3_KEYINFO_HANDOFF);
-  if( keyAsData ){
-    sqlite3VdbeAddOp(v, OP_KeyAsData, iTab, 1);
-  }
   return addr;
 }
 
@@ -1551,7 +1542,6 @@
           if( rc!=SQLITE_OK ){
             goto multi_select_end;
           }
-          sqlite3VdbeAddOp(v, OP_KeyAsData, unionTab, 1);
         }
 	assert( nAddr<sizeof(aAddr)/sizeof(aAddr[0]) );
         aAddr[nAddr++] = sqlite3VdbeAddOp(v, OP_SetNumColumns, unionTab, 0);
@@ -1643,7 +1633,6 @@
       if( rc!=SQLITE_OK ){
         goto multi_select_end;
       }
-      sqlite3VdbeAddOp(v, OP_KeyAsData, tab1, 1);
       assert( nAddr<sizeof(aAddr)/sizeof(aAddr[0]) );
       aAddr[nAddr++] = sqlite3VdbeAddOp(v, OP_SetNumColumns, tab1, 0);
       assert( p->pEList );
@@ -1662,7 +1651,6 @@
       if( rc!=SQLITE_OK ){
         goto multi_select_end;
       }
-      sqlite3VdbeAddOp(v, OP_KeyAsData, tab2, 1);
       assert( nAddr<sizeof(aAddr)/sizeof(aAddr[0]) );
       aAddr[nAddr++] = sqlite3VdbeAddOp(v, OP_SetNumColumns, tab2, 0);
       p->pPrior = 0;
@@ -2226,12 +2214,12 @@
     sqlite3VdbeOp3(v, OP_OpenRead, iIdx, pIdx->tnum,
                    (char*)&pIdx->keyInfo, P3_KEYINFO);
     if( seekOp==OP_Rewind ){
-      sqlite3VdbeAddOp(v, OP_String, 0, 0);
+      sqlite3VdbeAddOp(v, OP_Null, 0, 0);
       sqlite3VdbeAddOp(v, OP_MakeRecord, 1, 0);
       seekOp = OP_MoveGt;
     }
     sqlite3VdbeAddOp(v, seekOp, iIdx, 0);
-    sqlite3VdbeAddOp(v, OP_IdxRecno, iIdx, 0);
+    sqlite3VdbeAddOp(v, OP_IdxRowid, iIdx, 0);
     sqlite3VdbeAddOp(v, OP_Close, iIdx, 0);
     sqlite3VdbeAddOp(v, OP_MoveGe, base, 0);
   }
@@ -2741,7 +2729,7 @@
   /* Initialize the memory cell to NULL for SRT_Mem or 0 for SRT_Exists
   */
   if( eDest==SRT_Mem || eDest==SRT_Exists ){
-    sqlite3VdbeAddOp(v, eDest==SRT_Mem ? OP_String8 : OP_Integer, 0, 0);
+    sqlite3VdbeAddOp(v, eDest==SRT_Mem ? OP_Null : OP_Integer, 0, 0);
     sqlite3VdbeAddOp(v, OP_MemStore, iParm, 1);
   }
 
@@ -2749,7 +2737,7 @@
   */
   if( isDistinct ){
     distinct = pParse->nTab++;
-    openTempIndex(pParse, p, distinct, 0);
+    openTempIndex(pParse, p, distinct);
   }else{
     distinct = -1;
   }
diff --git a/src/sqliteInt.h b/src/sqliteInt.h
index 86a54d1..966090d 100644
--- a/src/sqliteInt.h
+++ b/src/sqliteInt.h
@@ -11,7 +11,7 @@
 *************************************************************************
 ** Internal interface definitions for SQLite.
 **
-** @(#) $Id: sqliteInt.h,v 1.386 2005/06/06 21:19:57 drh Exp $
+** @(#) $Id: sqliteInt.h,v 1.387 2005/06/12 21:35:52 drh Exp $
 */
 #ifndef _SQLITEINT_H_
 #define _SQLITEINT_H_
@@ -1141,7 +1141,7 @@
 };
 
 /*
-** Bitfield flags for P2 value in OP_PutIntKey and OP_Delete
+** Bitfield flags for P2 value in OP_Insert and OP_Delete
 */
 #define OPFLAG_NCHANGE   1    /* Set to update db->nChange */
 #define OPFLAG_LASTROWID 2    /* Set to update db->lastRowid */
diff --git a/src/trigger.c b/src/trigger.c
index 29cbc37..f39d2bd 100644
--- a/src/trigger.c
+++ b/src/trigger.c
@@ -215,7 +215,7 @@
   */
   if( !db->init.busy ){
     static const VdbeOpList insertTrig[] = {
-      { OP_NewRecno,   0, 0,  0          },
+      { OP_NewRowid,   0, 0,  0          },
       { OP_String8,    0, 0,  "trigger"  },
       { OP_String8,    0, 0,  0          },  /* 2: trigger name */
       { OP_String8,    0, 0,  0          },  /* 3: table name */
@@ -224,7 +224,7 @@
       { OP_String8,    0, 0,  0          },  /* 6: SQL */
       { OP_Concat,     0, 0,  0          }, 
       { OP_MakeRecord, 5, 0,  "tttit"    },
-      { OP_PutIntKey,  0, 0,  0          },
+      { OP_Insert,     0, 0,  0          },
     };
     int addr;
     Vdbe *v;
diff --git a/src/update.c b/src/update.c
index b70f639..0002d2f 100644
--- a/src/update.c
+++ b/src/update.c
@@ -12,7 +12,7 @@
 ** This file contains C code routines that are called by the parser
 ** to handle UPDATE statements.
 **
-** $Id: update.c,v 1.107 2005/04/22 02:38:38 drh Exp $
+** $Id: update.c,v 1.108 2005/06/12 21:35:53 drh Exp $
 */
 #include "sqliteInt.h"
 
@@ -80,8 +80,8 @@
   int *aXRef = 0;        /* aXRef[i] is the index in pChanges->a[] of the
                          ** an expression for the i-th column of the table.
                          ** aXRef[i]==-1 if the i-th column is not changed. */
-  int chngRecno;         /* True if the record number is being changed */
-  Expr *pRecnoExpr = 0;  /* Expression defining the new record number */
+  int chngRowid;         /* True if the record number is being changed */
+  Expr *pRowidExpr = 0;  /* Expression defining the new record number */
   int openAll = 0;       /* True if all indices need to be opened */
   AuthContext sContext;  /* The authorization context */
   NameContext sNC;       /* The name-context to resolve expressions in */
@@ -160,7 +160,7 @@
   ** column to be updated, make sure we have authorization to change
   ** that column.
   */
-  chngRecno = 0;
+  chngRowid = 0;
   for(i=0; i<pChanges->nExpr; i++){
     if( sqlite3ExprResolveNames(&sNC, pChanges->a[i].pExpr) ){
       goto update_cleanup;
@@ -168,8 +168,8 @@
     for(j=0; j<pTab->nCol; j++){
       if( sqlite3StrICmp(pTab->aCol[j].zName, pChanges->a[i].zName)==0 ){
         if( j==pTab->iPKey ){
-          chngRecno = 1;
-          pRecnoExpr = pChanges->a[i].pExpr;
+          chngRowid = 1;
+          pRowidExpr = pChanges->a[i].pExpr;
         }
         aXRef[j] = i;
         break;
@@ -177,8 +177,8 @@
     }
     if( j>=pTab->nCol ){
       if( sqlite3IsRowid(pChanges->a[i].zName) ){
-        chngRecno = 1;
-        pRecnoExpr = pChanges->a[i].pExpr;
+        chngRowid = 1;
+        pRowidExpr = pChanges->a[i].pExpr;
       }else{
         sqlite3ErrorMsg(pParse, "no such column: %s", pChanges->a[i].zName);
         goto update_cleanup;
@@ -204,7 +204,7 @@
   ** number of the original table entry is changing.
   */
   for(nIdx=nIdxTotal=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nIdxTotal++){
-    if( chngRecno ){
+    if( chngRowid ){
       i = 0;
     }else {
       for(i=0; i<pIdx->nColumn; i++){
@@ -219,7 +219,7 @@
     aIdxUsed = (char*)&apIdx[nIdx];
   }
   for(nIdx=j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
-    if( chngRecno ){
+    if( chngRowid ){
       i = 0;
     }else{
       for(i=0; i<pIdx->nColumn; i++){
@@ -272,7 +272,7 @@
 
   /* Remember the index of every item to be updated.
   */
-  sqlite3VdbeAddOp(v, OP_Recno, iCur, 0);
+  sqlite3VdbeAddOp(v, OP_Rowid, iCur, 0);
   sqlite3VdbeAddOp(v, OP_ListWrite, 0, 0);
 
   /* End the database scan loop.
@@ -310,20 +310,20 @@
 
     /* Generate the OLD table
     */
-    sqlite3VdbeAddOp(v, OP_Recno, iCur, 0);
+    sqlite3VdbeAddOp(v, OP_Rowid, iCur, 0);
     sqlite3VdbeAddOp(v, OP_RowData, iCur, 0);
-    sqlite3VdbeAddOp(v, OP_PutIntKey, oldIdx, 0);
+    sqlite3VdbeAddOp(v, OP_Insert, oldIdx, 0);
 
     /* Generate the NEW table
     */
-    if( chngRecno ){
-      sqlite3ExprCodeAndCache(pParse, pRecnoExpr);
+    if( chngRowid ){
+      sqlite3ExprCodeAndCache(pParse, pRowidExpr);
     }else{
-      sqlite3VdbeAddOp(v, OP_Recno, iCur, 0);
+      sqlite3VdbeAddOp(v, OP_Rowid, iCur, 0);
     }
     for(i=0; i<pTab->nCol; i++){
       if( i==pTab->iPKey ){
-        sqlite3VdbeAddOp(v, OP_String8, 0, 0);
+        sqlite3VdbeAddOp(v, OP_Null, 0, 0);
         continue;
       }
       j = aXRef[i];
@@ -339,7 +339,7 @@
       sqlite3TableAffinityStr(v, pTab);
     }
     if( pParse->nErr ) goto update_cleanup;
-    sqlite3VdbeAddOp(v, OP_PutIntKey, newIdx, 0);
+    sqlite3VdbeAddOp(v, OP_Insert, newIdx, 0);
     if( !isView ){
       sqlite3VdbeAddOp(v, OP_Close, iCur, 0);
     }
@@ -399,8 +399,8 @@
     ** will be after the update. (The old record number is currently
     ** on top of the stack.)
     */
-    if( chngRecno ){
-      sqlite3ExprCode(pParse, pRecnoExpr);
+    if( chngRowid ){
+      sqlite3ExprCode(pParse, pRowidExpr);
       sqlite3VdbeAddOp(v, OP_MustBeInt, 0, 0);
     }
 
@@ -408,7 +408,7 @@
     */
     for(i=0; i<pTab->nCol; i++){
       if( i==pTab->iPKey ){
-        sqlite3VdbeAddOp(v, OP_String8, 0, 0);
+        sqlite3VdbeAddOp(v, OP_Null, 0, 0);
         continue;
       }
       j = aXRef[i];
@@ -422,7 +422,7 @@
 
     /* Do constraint checks
     */
-    sqlite3GenerateConstraintChecks(pParse, pTab, iCur, aIdxUsed, chngRecno, 1,
+    sqlite3GenerateConstraintChecks(pParse, pTab, iCur, aIdxUsed, chngRowid, 1,
                                    onError, addr);
 
     /* Delete the old indices for the current record.
@@ -431,13 +431,13 @@
 
     /* If changing the record number, delete the old record.
     */
-    if( chngRecno ){
+    if( chngRowid ){
       sqlite3VdbeAddOp(v, OP_Delete, iCur, 0);
     }
 
     /* Create the new index entries and the new record.
     */
-    sqlite3CompleteInsertion(pParse, pTab, iCur, aIdxUsed, chngRecno, 1, -1);
+    sqlite3CompleteInsertion(pParse, pTab, iCur, aIdxUsed, chngRowid, 1, -1);
   }
 
   /* Increment the row counter 
diff --git a/src/vdbe.c b/src/vdbe.c
index 2653205..e2377c8 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.468 2005/06/12 12:01:19 drh Exp $
+** $Id: vdbe.c,v 1.469 2005/06/12 21:35:53 drh Exp $
 */
 #include "sqliteInt.h"
 #include "os.h"
@@ -717,7 +717,8 @@
 #ifndef SQLITE_OMIT_UTF16
   pOp->opcode = OP_String;
 
-  if( db->enc!=SQLITE_UTF8 && pOp->p3 ){
+  assert( pOp->p3!=0 );
+  if( db->enc!=SQLITE_UTF8 ){
     pTos++;
     sqlite3VdbeMemSetStr(pTos, pOp->p3, -1, SQLITE_UTF8, SQLITE_STATIC);
     if( SQLITE_OK!=sqlite3VdbeChangeEncoding(pTos, db->enc) ) goto no_mem;
@@ -743,26 +744,34 @@
 */
 case OP_String: {
   pTos++;
-  if( pOp->p3 ){
-    pTos->flags = MEM_Str|MEM_Static|MEM_Term;
-    pTos->z = pOp->p3;
+  assert( pOp->p3!=0 );
+  pTos->flags = MEM_Str|MEM_Static|MEM_Term;
+  pTos->z = pOp->p3;
 #ifndef SQLITE_OMIT_UTF16
-    if( db->enc==SQLITE_UTF8 ){
-      pTos->n = strlen(pTos->z);
-    }else{
-      pTos->n  = sqlite3utf16ByteLen(pTos->z, -1);
-    }
-#else
-    assert( db->enc==SQLITE_UTF8 );
+  if( db->enc==SQLITE_UTF8 ){
     pTos->n = strlen(pTos->z);
-#endif
-    pTos->enc = db->enc;
   }else{
-    pTos->flags = MEM_Null;
+    pTos->n  = sqlite3utf16ByteLen(pTos->z, -1);
   }
+#else
+  assert( db->enc==SQLITE_UTF8 );
+  pTos->n = strlen(pTos->z);
+#endif
+  pTos->enc = db->enc;
   break;
 }
 
+/* Opcode: Null * * *
+**
+** Push a NULL onto the stack.
+*/
+case OP_Null: {
+  pTos++;
+  pTos->flags = MEM_Null;
+  break;
+}
+
+
 #ifndef SQLITE_OMIT_BLOB_LITERAL
 /* Opcode: HexBlob * * P3
 **
@@ -1373,11 +1382,11 @@
 ** Pop the top two elements from the stack.  If they are equal, then
 ** jump to instruction P2.  Otherwise, continue to the next instruction.
 **
-** The least significant byte of P1 may be either 0x00 or 0x01. If either
-** operand is NULL (and thus if the result is unknown) then take the jump
-** only if the least significant byte of P1 is 0x01.
+** If the 0x100 bit of P1 is true and either operand is NULL then take the
+** jump.  If the 0x100 bit of P1 is false then fall thru if either operand
+** is NULL.
 **
-** The second least significant byte of P1 must be an affinity character -
+** The least significant byte of P1 (mask 0xff) must be an affinity character -
 ** 'n', 't', 'i' or 'o' - or 0x00. An attempt is made to coerce both values
 ** according to the affinity before the comparison is made. If the byte is
 ** 0x00, then numeric affinity is used.
@@ -1446,7 +1455,7 @@
   if( flags&MEM_Null ){
     popStack(&pTos, 2);
     if( pOp->p2 ){
-      if( (pOp->p1&0xFF) ) pc = pOp->p2-1;
+      if( pOp->p1 & 0x100 ) pc = pOp->p2-1;
     }else{
       pTos++;
       pTos->flags = MEM_Null;
@@ -1454,7 +1463,7 @@
     break;
   }
 
-  affinity = (pOp->p1>>8)&0xFF;
+  affinity = pOp->p1 & 0xFF;
   if( affinity ){
     applyAffinity(pNos, affinity, db->enc);
     applyAffinity(pTos, affinity, db->enc);
@@ -1708,10 +1717,6 @@
   assert( p->apCsr[pOp->p1]!=0 );
   pC = p->apCsr[pOp->p1];
   pC->nField = pOp->p2;
-  if( (!pC->keyAsData && pC->zeroData) || (pC->keyAsData && pC->intKey) ){
-    rc = SQLITE_CORRUPT;
-    goto abort_due_to_error;
-  }
   break;
 }
 
@@ -1795,7 +1800,7 @@
     }else if( pC->cacheValid ){
       payloadSize = pC->payloadSize;
       zRec = pC->aRow;
-    }else if( pC->keyAsData ){
+    }else if( pC->isIndex ){
       i64 payloadSize64;
       sqlite3BtreeKeySize(pCrsr, &payloadSize64);
       payloadSize = payloadSize64;
@@ -1850,7 +1855,7 @@
     if( zRec ){
       zData = zRec;
     }else{
-      if( pC->keyAsData ){
+      if( pC->isIndex ){
         zData = (char*)sqlite3BtreeKeyFetch(pCrsr, &avail);
       }else{
         zData = (char*)sqlite3BtreeDataFetch(pCrsr, &avail);
@@ -1876,7 +1881,7 @@
     ** acquire the complete header text.
     */
     if( !zRec && avail<szHdr ){
-      rc = sqlite3VdbeMemFromBtree(pCrsr, 0, szHdr, pC->keyAsData, &sMem);
+      rc = sqlite3VdbeMemFromBtree(pCrsr, 0, szHdr, pC->isIndex, &sMem);
       if( rc!=SQLITE_OK ){
         goto op_column_out;
       }
@@ -1940,7 +1945,7 @@
       zData = &zRec[aOffset[p2]];
     }else{
       len = sqlite3VdbeSerialTypeLen(aType[p2]);
-      rc = sqlite3VdbeMemFromBtree(pCrsr, aOffset[p2], len,pC->keyAsData,&sMem);
+      rc = sqlite3VdbeMemFromBtree(pCrsr, aOffset[p2], len, pC->isIndex,&sMem);
       if( rc!=SQLITE_OK ){
         goto op_column_out;
       }
@@ -2440,11 +2445,12 @@
   rc = sqlite3BtreeCursor(pX, p2, wrFlag,
            sqlite3VdbeRecordCompare, pOp->p3,
            &pCur->pCursor);
-  pCur->pKeyInfo = (KeyInfo*)pOp->p3;
-  if( pCur->pKeyInfo ){
+  if( pOp->p3type==P3_KEYINFO ){
+    pCur->pKeyInfo = (KeyInfo*)pOp->p3;
     pCur->pIncrKey = &pCur->pKeyInfo->incrKey;
     pCur->pKeyInfo->enc = p->db->enc;
   }else{
+    pCur->pKeyInfo = 0;
     pCur->pIncrKey = &pCur->bogusIncrKey;
   }
   switch( rc ){
@@ -2456,11 +2462,32 @@
     }
     case SQLITE_OK: {
       int flags = sqlite3BtreeFlags(pCur->pCursor);
-      pCur->intKey = (flags & BTREE_INTKEY)!=0;
-      pCur->zeroData = (flags & BTREE_ZERODATA)!=0;
+      /* 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
+      ** 2 (zerodata for indices).  If these conditions are not met it can
+      ** only mean that we are dealing with a corrupt database file
+      */
+      if( (flags & 0xf0)!=0 || ((flags & 0x07)!=5 && (flags & 0x07)!=2) ){
+        rc = SQLITE_CORRUPT;
+        goto abort_due_to_error;
+      }
+      pCur->isTable = (flags & BTREE_INTKEY)!=0;
+      pCur->isIndex = (flags & BTREE_ZERODATA)!=0;
+      /* If P3==0 it means we are expected to open a table.  If P3!=0 then
+      ** we expect to be opening an index.  If this is not what happened,
+      ** then the database is corrupt
+      */
+      if( (pCur->isTable && pOp->p3type==P3_KEYINFO)
+       || (pCur->isIndex && pOp->p3type!=P3_KEYINFO) ){
+        rc = SQLITE_CORRUPT;
+        goto abort_due_to_error;
+      }
       break;
     }
     case SQLITE_EMPTY: {
+      pCur->isTable = pOp->p3type!=P3_KEYINFO;
+      pCur->isIndex = !pCur->isTable;
       rc = SQLITE_OK;
       break;
     }
@@ -2518,12 +2545,14 @@
         pCx->pKeyInfo->enc = p->db->enc;
         pCx->pIncrKey = &pCx->pKeyInfo->incrKey;
       }
+      pCx->isTable = 0;
     }else{
       rc = sqlite3BtreeCursor(pCx->pBt, MASTER_ROOT, 1, 0, 0, &pCx->pCursor);
-      pCx->intKey = 1;
+      pCx->isTable = 1;
       pCx->pIncrKey = &pCx->bogusIncrKey;
     }
   }
+  pCx->isIndex = !pCx->isTable;
   break;
 }
 
@@ -2547,6 +2576,8 @@
   pCx->nullRow = 1;
   pCx->pseudoTable = 1;
   pCx->pIncrKey = &pCx->bogusIncrKey;
+  pCx->isTable = 1;
+  pCx->isIndex = 0;
   break;
 }
 #endif
@@ -2621,7 +2652,7 @@
     oc = pOp->opcode;
     pC->nullRow = 0;
     *pC->pIncrKey = oc==OP_MoveGt || oc==OP_MoveLe;
-    if( pC->intKey ){
+    if( pC->isTable ){
       i64 iKey;
       Integerify(pTos);
       iKey = intToKey(pTos->i);
@@ -2636,15 +2667,15 @@
       if( rc!=SQLITE_OK ){
         goto abort_due_to_error;
       }
-      pC->lastRecno = pTos->i;
-      pC->recnoIsValid = res==0;
+      pC->lastRowid = pTos->i;
+      pC->rowidIsValid = res==0;
     }else{
       Stringify(pTos, db->enc);
       rc = sqlite3BtreeMoveto(pC->pCursor, pTos->z, pTos->n, &res);
       if( rc!=SQLITE_OK ){
         goto abort_due_to_error;
       }
-      pC->recnoIsValid = 0;
+      pC->rowidIsValid = 0;
     }
     pC->deferredMoveto = 0;
     pC->cacheValid = 0;
@@ -2654,7 +2685,7 @@
       if( res<0 ){
         rc = sqlite3BtreeNext(pC->pCursor, &res);
         if( rc!=SQLITE_OK ) goto abort_due_to_error;
-        pC->recnoIsValid = 0;
+        pC->rowidIsValid = 0;
       }else{
         res = 0;
       }
@@ -2663,7 +2694,7 @@
       if( res>=0 ){
         rc = sqlite3BtreePrevious(pC->pCursor, &res);
         if( rc!=SQLITE_OK ) goto abort_due_to_error;
-        pC->recnoIsValid = 0;
+        pC->rowidIsValid = 0;
       }else{
         /* res might be negative because the table is empty.  Check to
         ** see if this is the case.
@@ -2686,31 +2717,46 @@
 
 /* Opcode: Distinct P1 P2 *
 **
-** Use the top of the stack as a string key.  If a record with that key does
-** not exist in the table of cursor P1, then jump to P2.  If the record
-** does already exist, then fall thru.  The cursor is left pointing
-** at the record if it exists. The key is not popped from the stack.
+** Use the top of the stack as a record created using MakeRecord.  P1 is a
+** cursor on a table that declared as an index.  If that table contains an
+** entry that matches the top of the stack fall thru.  If the top of the stack
+** matches no entry in P1 then jump to P2.
 **
-** This operation is similar to NotFound except that this operation
+** The cursor is left pointing at the matching entry if it exists.  The
+** record on the top of the stack is not popped.
+**
+** This instruction is similar to NotFound except that this operation
 ** does not pop the key from the stack.
 **
+** The instruction is used to implement the DISTINCT operator on SELECT
+** statements.  The P1 table is not a true index but rather a record of
+** all results that have produced so far.  
+**
 ** See also: Found, NotFound, MoveTo, IsUnique, NotExists
 */
 /* Opcode: Found P1 P2 *
 **
-** Use the top of the stack as a string key.  If a record with that key
-** does exist in table of P1, then jump to P2.  If the record
-** does not exist, then fall thru.  The cursor is left pointing
-** to the record if it exists.  The key is popped from the stack.
+** Top of the stack holds a blob constructed by MakeRecord.  P1 is an index.
+** If an entry that matches the top of the stack exists in P1 then
+** jump to P2.  If the top of the stack does not match any entry in P1
+** then fall thru.  The P1 cursor is left pointing at the matching entry
+** if it exists.  The blob is popped off the top of the stack.
+**
+** This instruction is used to implement the IN operator where the
+** left-hand side is a SELECT statement.  P1 is not a true index but
+** is instead a temporary index that holds the results of the SELECT
+** statement.  This instruction just checks to see if the left-hand side
+** of the IN operator (stored on the top of the stack) exists in the
+** result of the SELECT statement.
 **
 ** See also: Distinct, NotFound, MoveTo, IsUnique, NotExists
 */
 /* Opcode: NotFound P1 P2 *
 **
-** Use the top of the stack as a string key.  If a record with that key
-** does not exist in table of P1, then jump to P2.  If the record
-** does exist, then fall thru.  The cursor is left pointing to the
-** record if it exists.  The key is popped from the stack.
+** The top of the stack holds a blob constructed by MakeRecord.  P1 is
+** an index.  If no entry exists in P1 that matches the blob then jump
+** to P1.  If an entry does existing, fall through.  The cursor is left
+** pointing to the entry that matches.  The blob is popped from the stack.
 **
 ** The difference between this operation and Distinct is that
 ** Distinct does not pop the key from the stack.
@@ -2728,7 +2774,7 @@
   assert( p->apCsr[i]!=0 );
   if( (pC = p->apCsr[i])->pCursor!=0 ){
     int res, rx;
-    assert( pC->intKey==0 );
+    assert( pC->isTable==0 );
     Stringify(pTos, db->enc);
     rx = sqlite3BtreeMoveto(pC->pCursor, pTos->z, pTos->n, &res);
     alreadyExists = rx==SQLITE_OK && res==0;
@@ -2755,8 +2801,8 @@
 ** stack but it leaves K unchanged.
 **
 ** P1 is an index.  So it has no data and its key consists of a
-** record generated by OP_MakeIdxKey.  This key contains one or more
-** fields followed by a ROWID field.
+** record generated by OP_MakeRecord where the last field is the 
+** rowid of the entry that the index refers to.
 ** 
 ** This instruction asks if there is an entry in P1 where the
 ** fields matches K but the rowid is different from R.
@@ -2857,8 +2903,9 @@
 ** record if it exists.  The integer key is popped from the stack.
 **
 ** The difference between this operation and NotFound is that this
-** operation assumes the key is an integer and NotFound assumes it
-** is a string.
+** operation assumes the key is an integer and that P1 is a table whereas
+** NotFound assumes key is a blob constructed from MakeRecord and
+** P1 is an index.
 **
 ** See also: Distinct, Found, MoveTo, NotFound, IsUnique
 */
@@ -2873,16 +2920,16 @@
     int res;
     u64 iKey;
     assert( pTos->flags & MEM_Int );
-    assert( p->apCsr[i]->intKey );
+    assert( p->apCsr[i]->isTable );
     iKey = intToKey(pTos->i);
     rc = sqlite3BtreeMoveto(pCrsr, 0, iKey, &res);
-    pC->lastRecno = pTos->i;
-    pC->recnoIsValid = res==0;
+    pC->lastRowid = pTos->i;
+    pC->rowidIsValid = res==0;
     pC->nullRow = 0;
     pC->cacheValid = 0;
     if( res!=0 ){
       pc = pOp->p2 - 1;
-      pC->recnoIsValid = 0;
+      pC->rowidIsValid = 0;
     }
   }
   Release(pTos);
@@ -2890,9 +2937,9 @@
   break;
 }
 
-/* Opcode: NewRecno P1 P2 *
+/* Opcode: NewRowid P1 P2 *
 **
-** Get a new integer record number used as the key to a table.
+** Get a new integer record number (a.k.a "rowid") used as the key to a table.
 ** The record number is not previously used as a key in the database
 ** table that cursor P1 points to.  The new record number is pushed 
 ** onto the stack.
@@ -2904,7 +2951,7 @@
 ** record number.  This P2 mechanism is used to help implement the
 ** AUTOINCREMENT feature.
 */
-case OP_NewRecno: {
+case OP_NewRowid: {
   int i = pOp->p1;
   i64 v = 0;
   Cursor *pC;
@@ -3032,7 +3079,7 @@
         goto abort_due_to_error;
       }
     }
-    pC->recnoIsValid = 0;
+    pC->rowidIsValid = 0;
     pC->deferredMoveto = 0;
     pC->cacheValid = 0;
   }
@@ -3042,7 +3089,7 @@
   break;
 }
 
-/* Opcode: PutIntKey P1 P2 *
+/* Opcode: Insert P1 P2 *
 **
 ** Write an entry into the table of cursor P1.  A new entry is
 ** created if it doesn't already exist or the data for an existing
@@ -3054,19 +3101,11 @@
 ** incremented (otherwise not).  If the OPFLAG_LASTROWID flag of P2 is set,
 ** then rowid is stored for subsequent return by the
 ** sqlite3_last_insert_rowid() function (otherwise it's unmodified).
-*/
-/* Opcode: PutStrKey P1 * *
 **
-** Write an entry into the table of cursor P1.  A new entry is
-** created if it doesn't already exist or the data for an existing
-** entry is overwritten.  The data is the value on the top of the
-** stack.  The key is the next value down on the stack.  The key must
-** be a string.  The stack is popped twice by this instruction.
-**
-** P1 may not be a pseudo-table opened using the OpenPseudo opcode.
+** This instruction only works on tables.  The equivalent instruction
+** for indices is OP_IdxInsert.
 */
-case OP_PutIntKey:          /* no-push */
-case OP_PutStrKey: {        /* no-push */
+case OP_Insert: {         /* no-push */
   Mem *pNos = &pTos[-1];
   int i = pOp->p1;
   Cursor *pC;
@@ -3074,36 +3113,16 @@
   assert( i>=0 && i<p->nCursor );
   assert( p->apCsr[i]!=0 );
   if( ((pC = p->apCsr[i])->pCursor!=0 || pC->pseudoTable) ){
-    char *zKey;
-    i64 nKey; 
-    i64 iKey;
-    if( pOp->opcode==OP_PutStrKey ){
-assert( pNos->flags & MEM_Blob );
-      Stringify(pNos, db->enc);
-      nKey = pNos->n;
-      zKey = pNos->z;
-    }else{
-      assert( pNos->flags & MEM_Int );
+    i64 iKey;   /* The integer ROWID or key for the record to be inserted */
 
-      /* If the table is an INTKEY table, set nKey to the value of
-      ** the integer key, and zKey to NULL. Otherwise, set nKey to
-      ** sizeof(i64) and point zKey at iKey. iKey contains the integer
-      ** key in the on-disk byte order.
-      */
-      iKey = intToKey(pNos->i);
-      if( pC->intKey ){
-        nKey = intToKey(pNos->i);
-        zKey = 0;
-      }else{
-        nKey = sizeof(i64);
-        zKey = (char*)&iKey;
-      }
+    assert( pNos->flags & MEM_Int );
+    assert( pC->isTable );
+    iKey = intToKey(pNos->i);
 
-      if( pOp->p2 & OPFLAG_NCHANGE ) p->nChange++;
-      if( pOp->p2 & OPFLAG_LASTROWID ) db->lastRowid = pNos->i;
-      if( pC->nextRowidValid && pTos->i>=pC->nextRowid ){
-        pC->nextRowidValid = 0;
-      }
+    if( pOp->p2 & OPFLAG_NCHANGE ) p->nChange++;
+    if( pOp->p2 & OPFLAG_LASTROWID ) db->lastRowid = pNos->i;
+    if( pC->nextRowidValid && pTos->i>=pC->nextRowid ){
+      pC->nextRowidValid = 0;
     }
     if( pTos->flags & MEM_Null ){
       pTos->z = 0;
@@ -3113,11 +3132,6 @@
     }
 #ifndef SQLITE_OMIT_TRIGGER
     if( pC->pseudoTable ){
-      /* PutStrKey does not work for pseudo-tables.
-      ** The following assert makes sure we are not trying to use
-      ** PutStrKey on a pseudo-table
-      */
-      assert( pOp->opcode==OP_PutIntKey );
       sqliteFree(pC->pData);
       pC->iKey = iKey;
       pC->nData = pTos->n;
@@ -3134,12 +3148,12 @@
       pC->nullRow = 0;
     }else{
 #endif
-      rc = sqlite3BtreeInsert(pC->pCursor, zKey, nKey, pTos->z, pTos->n);
+      rc = sqlite3BtreeInsert(pC->pCursor, 0, iKey, pTos->z, pTos->n);
 #ifndef SQLITE_OMIT_TRIGGER
     }
 #endif
     
-    pC->recnoIsValid = 0;
+    pC->rowidIsValid = 0;
     pC->deferredMoveto = 0;
     pC->cacheValid = 0;
   }
@@ -3193,23 +3207,6 @@
   break;
 }
 
-/* Opcode: KeyAsData P1 P2 *
-**
-** Turn the key-as-data mode for cursor P1 either on (if P2==1) or
-** off (if P2==0).  In key-as-data mode, the OP_Column opcode pulls
-** data off of the key rather than the data.  This is used for
-** processing compound selects.
-*/
-case OP_KeyAsData: {        /* no-push */
-  int i = pOp->p1;
-  Cursor *pC;
-  assert( i>=0 && i<p->nCursor );
-  pC = p->apCsr[i];
-  assert( pC!=0 );
-  pC->keyAsData = pOp->p2;
-  break;
-}
-
 /* Opcode: RowData P1 * *
 **
 ** Push onto the stack the complete row data for cursor P1.
@@ -3234,9 +3231,12 @@
   Cursor *pC;
   u32 n;
 
+  /* Note that RowKey and RowData are really exactly the same instruction */
   pTos++;
   assert( i>=0 && i<p->nCursor );
   pC = p->apCsr[i];
+  assert( pC->isTable || pOp->opcode==OP_RowKey );
+  assert( pC->isIndex || pOp->opcode==OP_RowData );
   assert( pC!=0 );
   if( pC->nullRow ){
     pTos->flags = MEM_Null;
@@ -3247,13 +3247,12 @@
     if( pC->nullRow ){
       pTos->flags = MEM_Null;
       break;
-    }else if( pC->keyAsData || pOp->opcode==OP_RowKey ){
+    }else if( pC->isIndex ){
       i64 n64;
-      assert( !pC->intKey );
+      assert( !pC->isTable );
       sqlite3BtreeKeySize(pCrsr, &n64);
       n = n64;
     }else{
-assert( pC->intKey );
       sqlite3BtreeDataSize(pCrsr, &n);
     }
     pTos->n = n;
@@ -3267,11 +3266,9 @@
       pTos->xDel = 0;
       pTos->z = z;
     }
-    if( pC->keyAsData || pOp->opcode==OP_RowKey ){
-assert( !pC->intKey );
+    if( pC->isIndex ){
       sqlite3BtreeKey(pCrsr, 0, n, pTos->z);
     }else{
-assert( pC->intKey );
       sqlite3BtreeData(pCrsr, 0, n, pTos->z);
     }
 #ifndef SQLITE_OMIT_TRIGGER
@@ -3286,14 +3283,12 @@
   break;
 }
 
-/* Opcode: Recno P1 * *
+/* Opcode: Rowid P1 * *
 **
-** Push onto the stack an integer which is the first 4 bytes of the
-** the key to the current entry in a sequential scan of the database
-** file P1.  The sequential scan should have been started using the 
-** Next opcode.
+** Push onto the stack an integer which is the key of the table entry that
+** P1 is currently point to.
 */
-case OP_Recno: {
+case OP_Rowid: {
   int i = pOp->p1;
   Cursor *pC;
   i64 v;
@@ -3304,8 +3299,8 @@
   rc = sqlite3VdbeCursorMoveto(pC);
   if( rc ) goto abort_due_to_error;
   pTos++;
-  if( pC->recnoIsValid ){
-    v = pC->lastRecno;
+  if( pC->rowidIsValid ){
+    v = pC->lastRowid;
   }else if( pC->pseudoTable ){
     v = keyToInt(pC->iKey);
   }else if( pC->nullRow || pC->pCursor==0 ){
@@ -3335,13 +3330,13 @@
   pC = p->apCsr[i];
   assert( pC!=0 );
   pC->nullRow = 1;
-  pC->recnoIsValid = 0;
+  pC->rowidIsValid = 0;
   break;
 }
 
 /* Opcode: Last P1 P2 *
 **
-** The next use of the Recno or Column or Next instruction for P1 
+** The next use of the Rowid or Column or Next instruction for P1 
 ** will refer to the last entry in the database table or index.
 ** If the table or index is empty and P2>0, then jump immediately to P2.
 ** If P2 is 0 or if the table or index is not empty, fall through
@@ -3372,7 +3367,7 @@
 
 /* Opcode: Rewind P1 P2 *
 **
-** The next use of the Recno or Column or Next instruction for P1 
+** The next use of the Rowid or Column or Next instruction for P1 
 ** will refer to the first entry in the database table or index.
 ** If the table or index is empty and P2>0, then jump immediately to P2.
 ** If P2 is 0 or if the table or index is not empty, fall through
@@ -3445,11 +3440,11 @@
   }else{
     pC->nullRow = 1;
   }
-  pC->recnoIsValid = 0;
+  pC->rowidIsValid = 0;
   break;
 }
 
-/* Opcode: IdxPut P1 P2 P3
+/* Opcode: IdxInsert P1 P2 P3
 **
 ** The top of the stack holds a SQL index key made using the
 ** MakeIdxKey instruction.  This opcode writes that key into the
@@ -3459,8 +3454,11 @@
 ** the program aborts with a SQLITE_CONSTRAINT error and the database
 ** is rolled back.  If P3 is not null, then it becomes part of the
 ** error message returned with the SQLITE_CONSTRAINT.
+**
+** This instruction only works for indices.  The equivalent instruction
+** for tables is OP_Insert.
 */
-case OP_IdxPut: {        /* no-push */
+case OP_IdxInsert: {        /* no-push */
   int i = pOp->p1;
   Cursor *pC;
   BtCursor *pCrsr;
@@ -3497,7 +3495,7 @@
         }
       }
     }
-    assert( pC->intKey==0 );
+    assert( pC->isTable==0 );
     rc = sqlite3BtreeInsert(pCrsr, zKey, nKey, "", 0);
     assert( pC->deferredMoveto==0 );
     pC->cacheValid = 0;
@@ -3534,15 +3532,15 @@
   break;
 }
 
-/* Opcode: IdxRecno P1 * *
+/* Opcode: IdxRowid P1 * *
 **
-** Push onto the stack an integer which is the varint located at the
-** end of the index key pointed to by cursor P1.  This integer should be
-** the record number of the table entry to which this index entry points.
+** Push onto the stack an integer which is the last entry in the record at
+** the end of the index key pointed to by cursor P1.  This integer should be
+** the rowid of the table entry to which this index entry points.
 **
-** See also: Recno, MakeIdxKey.
+** See also: Rowid, MakeIdxKey.
 */
-case OP_IdxRecno: {
+case OP_IdxRowid: {
   int i = pOp->p1;
   BtCursor *pCrsr;
   Cursor *pC;
@@ -3555,7 +3553,7 @@
     i64 rowid;
 
     assert( pC->deferredMoveto==0 );
-    assert( pC->intKey==0 );
+    assert( pC->isTable==0 );
     if( pC->nullRow ){
       pTos->flags = MEM_Null;
     }else{
@@ -4060,13 +4058,13 @@
 }
 #endif /* #ifndef SQLITE_OMIT_TRIGGER */
 
-/* Opcode: SortPut * * *
+/* Opcode: SortInsert * * *
 **
 ** The TOS is the key and the NOS is the data.  Pop both from the stack
 ** and put them on the sorter.  The key and data should have been
 ** made using the MakeRecord opcode.
 */
-case OP_SortPut: {        /* no-push */
+case OP_SortInsert: {        /* no-push */
   Mem *pNos = &pTos[-1];
   Sorter *pSorter;
   assert( pNos>=p->aStack );
diff --git a/src/vdbeInt.h b/src/vdbeInt.h
index 23a6506..1feb9ba 100644
--- a/src/vdbeInt.h
+++ b/src/vdbeInt.h
@@ -60,19 +60,18 @@
 */
 struct Cursor {
   BtCursor *pCursor;    /* The cursor structure of the backend */
-  i64 lastRecno;        /* Last recno from a Next or NextIdx operation */
+  i64 lastRowid;        /* Last rowid from a Next or NextIdx operation */
   i64 nextRowid;        /* Next rowid returned by OP_NewRowid */
   Bool zeroed;          /* True if zeroed out and ready for reuse */
-  Bool recnoIsValid;    /* True if lastRecno is valid */
-  Bool keyAsData;       /* The OP_Column command works on key instead of data */
+  Bool rowidIsValid;    /* True if lastRowid is valid */
   Bool atFirst;         /* True if pointing to first entry */
   Bool useRandomRowid;  /* Generate new record numbers semi-randomly */
   Bool nullRow;         /* True if pointing to a row with no data */
   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 */
-  Bool intKey;          /* True if the table requires integer keys */
-  Bool zeroData;        /* True if table contains keys only - no data */
+  Bool isTable;         /* True if a table requiring integer keys */
+  Bool isIndex;         /* True if an index containing keys only - no data */
   u8 bogusIncrKey;      /* Something for pIncrKey to point to if pKeyInfo==0 */
   i64 movetoTarget;     /* Argument to the deferred sqlite3BtreeMoveto() */
   Btree *pBt;           /* Separate file holding temporary table */
diff --git a/src/vdbeaux.c b/src/vdbeaux.c
index 6ca240b..e64831e 100644
--- a/src/vdbeaux.c
+++ b/src/vdbeaux.c
@@ -223,7 +223,7 @@
 **
 ** This routine also does the following optimization:  It scans for
 ** Halt instructions where P1==SQLITE_CONSTRAINT or P2==OE_Abort or for
-** IdxPut instructions where P2!=0.  If no such instruction is
+** IdxInsert instructions where P2!=0.  If no such instruction is
 ** found, then every Statement instruction is changed to a Noop.  In
 ** this way, we avoid creating the statement journal file unnecessarily.
 */
@@ -249,7 +249,7 @@
       if( pOp->p1==SQLITE_CONSTRAINT && pOp->p2==OE_Abort ){
         doesStatementRollback = 1;
       }
-    }else if( opcode==OP_IdxPut ){
+    }else if( opcode==OP_IdxInsert ){
       if( pOp->p2 ){
         doesStatementRollback = 1;
       }
@@ -1572,8 +1572,8 @@
   if( p->deferredMoveto ){
     int res, rc;
     extern int sqlite3_search_count;
-    assert( p->intKey );
-    if( p->intKey ){
+    assert( p->isTable );
+    if( p->isTable ){
       rc = sqlite3BtreeMoveto(p->pCursor, 0, p->movetoTarget, &res);
     }else{
       rc = sqlite3BtreeMoveto(p->pCursor,(char*)&p->movetoTarget,
@@ -1581,8 +1581,8 @@
     }
     if( rc ) return rc;
     *p->pIncrKey = 0;
-    p->lastRecno = keyToInt(p->movetoTarget);
-    p->recnoIsValid = res==0;
+    p->lastRowid = keyToInt(p->movetoTarget);
+    p->rowidIsValid = res==0;
     if( res<0 ){
       rc = sqlite3BtreeNext(p->pCursor, &res);
       if( rc ) return rc;
diff --git a/src/where.c b/src/where.c
index 3987d17..4cb9ef0 100644
--- a/src/where.c
+++ b/src/where.c
@@ -16,7 +16,7 @@
 ** 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.138 2005/05/19 01:26:14 drh Exp $
+** $Id: where.c,v 1.139 2005/06/12 21:35:53 drh Exp $
 */
 #include "sqliteInt.h"
 
@@ -497,7 +497,6 @@
     sqlite3CodeSubselect(pParse, pX);
     iTab = pX->iTable;
     sqlite3VdbeAddOp(v, OP_Rewind, iTab, brk);
-    sqlite3VdbeAddOp(v, OP_KeyAsData, iTab, 1);
     VdbeComment((v, "# %.*s", pX->span.n, pX->span.z));
     pLevel->inP2 = sqlite3VdbeAddOp(v, OP_Column, iTab, 0);
     pLevel->inOp = OP_Next;
@@ -546,7 +545,7 @@
 **
 ** The code that sqlite3WhereBegin() generates leaves the cursors named
 ** in pTabList pointing at their appropriate entries.  The [...] code
-** can use OP_Column and OP_Recno opcodes on these cursors to extract
+** can use OP_Column and OP_Rowid opcodes on these cursors to extract
 ** data from the various tables of the loop.
 **
 ** If the WHERE clause is empty, the foreach loops must each scan their
@@ -949,7 +948,6 @@
                      (char*)&pIx->keyInfo, P3_KEYINFO);
     }
     if( (pLevel->score & 1)!=0 ){
-      sqlite3VdbeAddOp(v, OP_KeyAsData, iIdxCur, 1);
       sqlite3VdbeAddOp(v, OP_SetNumColumns, iIdxCur, pIx->nColumn+1);
     }
     sqlite3CodeVerifySchema(pParse, pTab->iDb);
@@ -984,7 +982,7 @@
     if( i>0 && (pTabList->a[i-1].jointype & JT_LEFT)!=0 ){
       if( !pParse->nMem ) pParse->nMem++;
       pLevel->iLeftJoin = pParse->nMem++;
-      sqlite3VdbeAddOp(v, OP_String8, 0, 0);
+      sqlite3VdbeAddOp(v, OP_Null, 0, 0);
       sqlite3VdbeAddOp(v, OP_MemStore, pLevel->iLeftJoin, 1);
       VdbeComment((v, "# init LEFT JOIN no-match flag"));
     }
@@ -1061,7 +1059,7 @@
       sqlite3VdbeAddOp(v, OP_RowKey, iIdxCur, 0);
       sqlite3VdbeAddOp(v, OP_IdxIsNull, nColumn, cont);
       if( !omitTable ){
-        sqlite3VdbeAddOp(v, OP_IdxRecno, iIdxCur, 0);
+        sqlite3VdbeAddOp(v, OP_IdxRowid, iIdxCur, 0);
         sqlite3VdbeAddOp(v, OP_MoveGe, iCur, 0);
       }
       pLevel->p1 = iIdxCur;
@@ -1120,9 +1118,9 @@
       pLevel->p1 = iCur;
       pLevel->p2 = start;
       if( testOp!=OP_Noop ){
-        sqlite3VdbeAddOp(v, OP_Recno, iCur, 0);
+        sqlite3VdbeAddOp(v, OP_Rowid, iCur, 0);
         sqlite3VdbeAddOp(v, OP_MemLoad, pLevel->iMem, 0);
-        sqlite3VdbeAddOp(v, testOp, (int)(('n'<<8)&0x0000FF00), brk);
+        sqlite3VdbeAddOp(v, testOp, 'n', brk);
       }
     }else if( pIdx==0 ){
       /* Case 4:  There is no usable index.  We must do a complete
@@ -1295,7 +1293,7 @@
       sqlite3VdbeAddOp(v, OP_RowKey, iIdxCur, 0);
       sqlite3VdbeAddOp(v, OP_IdxIsNull, nEqColumn + ((score&4)!=0), cont);
       if( !omitTable ){
-        sqlite3VdbeAddOp(v, OP_IdxRecno, iIdxCur, 0);
+        sqlite3VdbeAddOp(v, OP_IdxRowid, iIdxCur, 0);
         sqlite3VdbeAddOp(v, OP_MoveGe, iCur, 0);
       }
 
@@ -1424,9 +1422,9 @@
               break;
             }
           }
-        }else if( pOp->opcode==OP_Recno ){
+        }else if( pOp->opcode==OP_Rowid ){
           pOp->p1 = pLevel->iIdxCur;
-          pOp->opcode = OP_IdxRecno;
+          pOp->opcode = OP_IdxRowid;
         }else if( pOp->opcode==OP_NullRow ){
           pOp->opcode = OP_Noop;
         }