]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Split almost 1300 lines of code out of vdbe.c into separate files
authordrh <drh@noemail.net>
Sat, 6 Sep 2003 20:12:01 +0000 (20:12 +0000)
committerdrh <drh@noemail.net>
Sat, 6 Sep 2003 20:12:01 +0000 (20:12 +0000)
vdbeInt.h and vdbeaux.c. (CVS 1094)

FossilOrigin-Name: bfd69391d3d63675f206ffd8ff0401ea1cbcc073

main.mk
manifest
manifest.uuid
src/vdbe.c
src/vdbeInt.h [new file with mode: 0644]
src/vdbeaux.c [new file with mode: 0644]

diff --git a/main.mk b/main.mk
index b70f591fc21b3b637e8bbf371fd00bc74f0ce181..2aa68497cb18fdb18ce569bcb2e1c6ad23dd5622 100644 (file)
--- a/main.mk
+++ b/main.mk
@@ -58,7 +58,7 @@ LIBOBJ = attach.o auth.o btree.o btree_rb.o build.o copy.o delete.o \
          expr.o func.o hash.o insert.o \
          main.o opcodes.o os.o pager.o parse.o pragma.o printf.o random.o \
          select.o table.o tokenize.o trigger.o update.o util.o \
-         vacuum.o vdbe.o where.o tclsqlite.o
+         vacuum.o vdbe.o vdbeaux.o where.o tclsqlite.o
 
 # All of the source code files.
 #
@@ -97,6 +97,8 @@ SRC = \
   $(TOP)/src/vacuum.c \
   $(TOP)/src/vdbe.c \
   $(TOP)/src/vdbe.h \
+  $(TOP)/src/vdbeaux.c \
+  $(TOP)/src/vdbeInt.h \
   $(TOP)/src/where.c
 
 # Source code to the test files.
@@ -121,9 +123,15 @@ HDR = \
    opcodes.h \
    $(TOP)/src/os.h \
    $(TOP)/src/sqliteInt.h  \
-   $(TOP)/src/vdbe.h  \
+   $(TOP)/src/vdbe.h \
    parse.h
 
+# Header files used by the VDBE submodule
+#
+VDBEHDR = \
+   $(HDR) \
+   $(TOP)/src/vdbeInt.h
+
 # This is the default Makefile target.  The objects listed here
 # are what get build when you type just "make" with no arguments.
 #
@@ -150,10 +158,10 @@ sqlite$(EXE):     $(TOP)/src/shell.c libsqlite.a sqlite.h
 # files are automatically generated.  This target takes care of
 # all that automatic generation.
 #
-target_source: $(SRC) $(HDR) opcodes.c
+target_source: $(SRC) $(VDBEHDR) opcodes.c
        rm -rf tsrc
        mkdir tsrc
-       cp $(SRC) $(HDR) tsrc
+       cp $(SRC) $(VDBEHDR) tsrc
        rm tsrc/sqlite.h.in tsrc/parse.y
        cp parse.c opcodes.c tsrc
 
@@ -239,9 +247,12 @@ util.o:    $(TOP)/src/util.c $(HDR)
 vacuum.o:      $(TOP)/src/vacuum.c $(HDR)
        $(TCCX) -c $(TOP)/src/vacuum.c
 
-vdbe.o:        $(TOP)/src/vdbe.c $(HDR)
+vdbe.o:        $(TOP)/src/vdbe.c $(VDBEHDR)
        $(TCCX) -c $(TOP)/src/vdbe.c
 
+vdbeaux.o:     $(TOP)/src/vdbeaux.c $(VDBEHDR)
+       $(TCCX) -c $(TOP)/src/vdbeaux.c
+
 where.o:       $(TOP)/src/where.c $(HDR)
        $(TCCX) -c $(TOP)/src/where.c
 
index b041b4fb831d37a3e5f799426e1b53cfe8c24f9c..b17a98bdc98c890fde09d2e3e1308b76506aa7b2 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C The\sbeginnings\sof\schanges\sto\ssupport\spre-compiled\sSQL.\s\sMostly\suntested,\nthough\sall\sregression\stests\sto\spass.\s(CVS\s1093)
-D 2003-09-06T01:10:47
+C Split\salmost\s1300\slines\sof\scode\sout\sof\svdbe.c\sinto\sseparate\sfiles\nvdbeInt.h\sand\svdbeaux.c.\s(CVS\s1094)
+D 2003-09-06T20:12:01
 F Makefile.in f7e916ae863393827fa6a4cb292e3398096edcf1
 F Makefile.linux-gcc b86a99c493a5bfb402d1d9178dcdc4bd4b32f906
 F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd
@@ -16,7 +16,7 @@ F doc/report1.txt a031aaf37b185e4fa540223cb516d3bccec7eeac
 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895
 F libtool bbbea7d79c23323e4100103836028e4fad0d9242
 F ltmain.sh abfb9387049fff6996afc6e325736597795baf11
-F main.mk d01843179ed14559adb75f7e2fe093c943d56756
+F main.mk 6af144bac62d83899b71919c738fdf442a4f1c16
 F publish.sh 86b5e8535830a2588f62ce1d5d1ef00e1dede23a
 F spec.template 238f7db425a78dc1bb7682e56e3834c7270a3f5e
 F sqlite.1 83f4a9d37bdf2b7ef079a82d54eaf2e3509ee6ea
@@ -61,8 +61,10 @@ F src/trigger.c 474581eaab388233df01bb019e558af2965decbf
 F src/update.c 24260b4fda00c9726d27699a0561d53c0dccc397
 F src/util.c f16efa2d60bfd4e31ae06b07ed149557e828d294
 F src/vacuum.c e4724eade07e4cf8897060a8cf632dbd92408eeb
-F src/vdbe.c b6a2b0a8eeca95cc29a9e07fb7d2cc3c1eaec468
+F src/vdbe.c 00c547e77d4100b6671c1509df5993ab315a166c
 F src/vdbe.h 3c51cb382316dbf3860e4ece72e658b4bf014501
+F src/vdbeInt.h 15cd01061b2f0acb967bdc5195fe1e891bb707a1
+F src/vdbeaux.c ebf5eab163fa8435e4fc24bcebe4eab4147d871b
 F src/where.c 83b2a2d26d5c3bea33457a83e541bb1dcf7b1248
 F test/all.test 569a92a8ee88f5300c057cc4a8f50fbbc69a3242
 F test/attach.test c26848402e7ac829e043e1fa5e0eb87032e5d81d
@@ -170,7 +172,7 @@ F www/speed.tcl 2f6b1155b99d39adb185f900456d1d592c4832b3
 F www/sqlite.tcl 3c83b08cf9f18aa2d69453ff441a36c40e431604
 F www/tclsqlite.tcl b9271d44dcf147a93c98f8ecf28c927307abd6da
 F www/vdbe.tcl 9b9095d4495f37697fd1935d10e14c6015e80aa1
-P aaa84c6202f6e16828bcd6aff2e424f3dba1f82b
-R 0bb0019009c0a448d322679ad1dd5f73
+P 912f47c72d3597c6d5acff765d94922bd660339a
+R 197956f145d2d77ab02def05dccb6402
 U drh
-Z 42cb329fb1ec590b60ca4f6b47463c49
+Z 7934264d068323cc21204d69f10c800f
index b0c5bbb28cc1200fdd89eccb482df1cf0ebb8e95..f05e5965d62a043fb2915a04defd357c38d31d32 100644 (file)
@@ -1 +1 @@
-912f47c72d3597c6d5acff765d94922bd660339a
\ No newline at end of file
+bfd69391d3d63675f206ffd8ff0401ea1cbcc073
\ No newline at end of file
index de33d162d7e1c2a5d59bfa87bfbf575e450e1a78..305168dfca34a64425f4160698e603eb7c21c440 100644 (file)
@@ -9,7 +9,14 @@
 **    May you share freely, never taking more than you give.
 **
 *************************************************************************
-** The code in this file implements the Virtual Database Engine (VDBE)
+** The code in this file implements execution method of the 
+** Virtual Database Engine (VDBE).  A separate file ("vdbeaux.c")
+** handles housekeeping details such as creating and deleting
+** VDBE instances.  This file is solely interested in executing
+** the VDBE program.
+**
+** In the external interface, an "sqlite_vm*" is an opaque pointer
+** to a VDBE.
 **
 ** The SQL parser generates a program which is then executed by
 ** the VDBE to do the work of the SQL statement.  VDBE programs are 
 ** 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.238 2003/09/06 01:10:48 drh Exp $
+** $Id: vdbe.c,v 1.239 2003/09/06 20:12:01 drh Exp $
 */
 #include "sqliteInt.h"
 #include "os.h"
 #include <ctype.h>
-
-/*
-** The makefile scans this source file and creates the following
-** array of string constants which are the names of all VDBE opcodes.
-** This array is defined in a separate source code file named opcode.c
-** which is automatically generated by the makefile.
-*/
-extern char *sqliteOpcodeNames[];
+#include "vdbeInt.h"
 
 /*
 ** The following global variable is incremented every time a cursor
@@ -59,700 +59,6 @@ extern char *sqliteOpcodeNames[];
 */
 int sqlite_search_count = 0;
 
-/*
-** SQL is translated into a sequence of instructions to be
-** executed by a virtual machine.  Each instruction is an instance
-** of the following structure.
-*/
-typedef struct VdbeOp Op;
-
-/*
-** Boolean values
-*/
-typedef unsigned char Bool;
-
-/*
-** A cursor is a pointer into a single BTree within a database file.
-** The cursor can seek to a BTree entry with a particular key, or
-** loop over all entries of the Btree.  You can also insert new BTree
-** entries or retrieve the key or data from the entry that the cursor
-** is currently pointing to.
-** 
-** Every cursor that the virtual machine has open is represented by an
-** instance of the following structure.
-**
-** If the Cursor.isTriggerRow flag is set it means that this cursor is
-** really a single row that represents the NEW or OLD pseudo-table of
-** a row trigger.  The data for the row is stored in Cursor.pData and
-** the rowid is in Cursor.iKey.
-*/
-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 */
-  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 */
-  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 */
-  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 */
-};
-typedef struct Cursor Cursor;
-
-/*
-** A sorter builds a list of elements to be sorted.  Each element of
-** the list is an instance of the following structure.
-*/
-typedef struct Sorter Sorter;
-struct Sorter {
-  int nKey;           /* Number of bytes in the key */
-  char *zKey;         /* The key by which we will sort */
-  int nData;          /* Number of bytes in the data */
-  char *pData;        /* The data associated with this key */
-  Sorter *pNext;      /* Next in the list */
-};
-
-/* 
-** Number of buckets used for merge-sort.  
-*/
-#define NSORT 30
-
-/*
-** Number of bytes of string storage space available to each stack
-** layer without having to malloc.  NBFS is short for Number of Bytes
-** For Strings.
-*/
-#define NBFS 32
-
-/*
-** A single level of the stack is an instance of the following
-** structure.  Except, string values are stored on a separate
-** list of of pointers to character.  The reason for storing
-** strings separately is so that they can be easily passed
-** to the callback function.
-*/
-struct Stack {
-  int i;         /* Integer value */
-  int n;         /* Number of characters in string value, including '\0' */
-  int flags;     /* Some combination of STK_Null, STK_Str, STK_Dyn, etc. */
-  double r;      /* Real value */
-  char z[NBFS];  /* Space for short strings */
-};
-typedef struct Stack Stack;
-
-/*
-** Memory cells use the same structure as the stack except that space
-** for an arbitrary string is added.
-*/
-struct Mem {
-  Stack s;       /* All values of the memory cell besides string */
-  char *z;       /* String value for this memory cell */
-};
-typedef struct Mem Mem;
-
-/*
-** Allowed values for Stack.flags
-*/
-#define STK_Null      0x0001   /* Value is NULL */
-#define STK_Str       0x0002   /* Value is a string */
-#define STK_Int       0x0004   /* Value is an integer */
-#define STK_Real      0x0008   /* Value is a real number */
-#define STK_Dyn       0x0010   /* Need to call sqliteFree() on zStack[] */
-#define STK_Static    0x0020   /* zStack[] points to a static string */
-#define STK_Ephem     0x0040   /* zStack[] points to an ephemeral string */
-
-/* The following STK_ value appears only in AggElem.aMem.s.flag fields.
-** It indicates that the corresponding AggElem.aMem.z points to a
-** aggregate function context that needs to be finalized.
-*/
-#define STK_AggCtx    0x0040   /* zStack[] points to an agg function context */
-
-/*
-** The "context" argument for a installable function.  A pointer to an
-** instance of this structure is the first argument to the routines used
-** implement the SQL functions.
-**
-** There is a typedef for this structure in sqlite.h.  So all routines,
-** even the public interface to SQLite, can use a pointer to this structure.
-** But this file is the only place where the internal details of this
-** structure are known.
-**
-** This structure is defined inside of vdbe.c because it uses substructures
-** (Stack) which are only defined there.
-*/
-struct sqlite_func {
-  FuncDef *pFunc;   /* Pointer to function information.  MUST BE FIRST */
-  Stack s;          /* Small strings, ints, and double values go here */
-  char *z;          /* Space for holding dynamic string results */
-  void *pAgg;       /* Aggregate context */
-  u8 isError;       /* Set to true for an error */
-  u8 isStep;        /* Current in the step function */
-  int cnt;          /* Number of times that the step function has been called */
-};
-
-/*
-** An Agg structure describes an Aggregator.  Each Agg consists of
-** zero or more Aggregator elements (AggElem).  Each AggElem contains
-** a key and one or more values.  The values are used in processing
-** aggregate functions in a SELECT.  The key is used to implement
-** the GROUP BY clause of a select.
-*/
-typedef struct Agg Agg;
-typedef struct AggElem AggElem;
-struct Agg {
-  int nMem;            /* Number of values stored in each AggElem */
-  AggElem *pCurrent;   /* The AggElem currently in focus */
-  HashElem *pSearch;   /* The hash element for pCurrent */
-  Hash hash;           /* Hash table of all aggregate elements */
-  FuncDef **apFunc;    /* Information about aggregate functions */
-};
-struct AggElem {
-  char *zKey;          /* The key to this AggElem */
-  int nKey;            /* Number of bytes in the key, including '\0' at end */
-  Mem aMem[1];         /* The values for this AggElem */
-};
-
-/*
-** A Set structure is used for quick testing to see if a value
-** is part of a small set.  Sets are used to implement code like
-** this:
-**            x.y IN ('hi','hoo','hum')
-*/
-typedef struct Set Set;
-struct Set {
-  Hash hash;             /* A set is just a hash table */
-  HashElem *prev;        /* Previously accessed hash elemen */
-};
-
-/*
-** A Keylist is a bunch of keys into a table.  The keylist can
-** grow without bound.  The keylist stores the ROWIDs of database
-** records that need to be deleted or updated.
-*/
-typedef struct Keylist Keylist;
-struct Keylist {
-  int nKey;         /* Number of slots in aKey[] */
-  int nUsed;        /* Next unwritten slot in aKey[] */
-  int nRead;        /* Next unread slot in aKey[] */
-  Keylist *pNext;   /* Next block of keys */
-  int aKey[1];      /* One or more keys.  Extra space allocated as needed */
-};
-
-/*
-** An instance of the virtual machine.  This structure contains the complete
-** state of the virtual machine.
-**
-** The "sqlite_vm" structure pointer that is returned by sqlite_compile()
-** is really a pointer to an instance of this structure.
-*/
-struct Vdbe {
-  sqlite *db;         /* The whole database */
-  Vdbe *pPrev,*pNext; /* Linked list of VDBEs with the same Vdbe.db */
-  FILE *trace;        /* Write an execution trace here, if not NULL */
-  int nOp;            /* Number of instructions in the program */
-  int nOpAlloc;       /* Number of slots allocated for aOp[] */
-  Op *aOp;            /* Space to hold the virtual machine's program */
-  int nLabel;         /* Number of labels used */
-  int nLabelAlloc;    /* Number of slots allocated in aLabel[] */
-  int *aLabel;        /* Space to hold the labels */
-  int tos;            /* Index of top of stack */
-  Stack *aStack;      /* The operand stack, except string values */
-  char **zStack;      /* Text or binary values of the stack */
-  char **azColName;   /* Becomes the 4th parameter to callbacks */
-  int nCursor;        /* Number of slots in aCsr[] */
-  Cursor *aCsr;       /* One element of this array for each open cursor */
-  Sorter *pSort;      /* A linked list of objects to be sorted */
-  FILE *pFile;        /* At most one open file handler */
-  int nField;         /* Number of file fields */
-  char **azField;     /* Data for each file field */
-  int nVariable;          /* Number of entries in azVariable[] */
-  char **azVariable;      /* Values for the OP_Variable opcode */
-  char *zLine;            /* A single line from the input file */
-  int nLineAlloc;         /* Number of spaces allocated for zLine */
-  int magic;              /* Magic number for sanity checking */
-  int nMem;               /* Number of memory locations currently allocated */
-  Mem *aMem;              /* The memory locations */
-  Agg agg;                /* Aggregate information */
-  int nSet;               /* Number of sets allocated */
-  Set *aSet;              /* An array of sets */
-  int nCallback;          /* Number of callbacks invoked so far */
-  Keylist *pList;         /* A list of ROWIDs */
-  int keylistStackDepth;  /* The size of the "keylist" stack */
-  Keylist **keylistStack; /* The stack used by opcodes ListPush & ListPop */
-  int pc;                 /* The program counter */
-  int rc;                 /* Value to return */
-  unsigned uniqueCnt;     /* Used by OP_MakeRecord when P2!=0 */
-  int errorAction;        /* Recovery action to do in case of an error */
-  int undoTransOnError;   /* If error, either ROLLBACK or COMMIT */
-  int inTempTrans;        /* True if temp database is transactioned */
-  int returnStack[100];   /* Return address stack for OP_Gosub & OP_Return */
-  int returnDepth;        /* Next unused element in returnStack[] */
-  int nResColumn;         /* Number of columns in one row of the result set */
-  char **azResColumn;                        /* Values for one row of result */ 
-  int (*xCallback)(void*,int,char**,char**); /* Callback for SELECT results */
-  void *pCbArg;                              /* First argument to xCallback() */
-  int popStack;           /* Pop the stack this much on entry to VdbeExec() */
-  char *zErrMsg;          /* Error message written here */
-  u8 explain;             /* True if EXPLAIN present on SQL command */
-};
-
-/*
-** The following are allowed values for Vdbe.magic
-*/
-#define VDBE_MAGIC_INIT     0x26bceaa5    /* Building a VDBE program */
-#define VDBE_MAGIC_RUN      0xbdf20da3    /* VDBE is ready to execute */
-#define VDBE_MAGIC_HALT     0x519c2973    /* VDBE has completed execution */
-#define VDBE_MAGIC_DEAD     0xb606c3c8    /* The VDBE has been deallocated */
-
-/*
-** When debugging the code generator in a symbolic debugger, one can
-** set the sqlite_vdbe_addop_trace to 1 and all opcodes will be printed
-** as they are added to the instruction stream.
-*/
-#ifndef NDEBUG
-int sqlite_vdbe_addop_trace = 0;
-static void vdbePrintOp(FILE*, int, Op*);
-#endif
-
-/*
-** Create a new virtual database engine.
-*/
-Vdbe *sqliteVdbeCreate(sqlite *db){
-  Vdbe *p;
-  p = sqliteMalloc( sizeof(Vdbe) );
-  if( p==0 ) return 0;
-  p->db = db;
-  if( db->pVdbe ){
-    db->pVdbe->pPrev = p;
-  }
-  p->pNext = db->pVdbe;
-  p->pPrev = 0;
-  db->pVdbe = p;
-  p->magic = VDBE_MAGIC_INIT;
-  return p;
-}
-
-/*
-** Turn tracing on or off
-*/
-void sqliteVdbeTrace(Vdbe *p, FILE *trace){
-  p->trace = trace;
-}
-
-/*
-** Add a new instruction to the list of instructions current in the
-** VDBE.  Return the address of the new instruction.
-**
-** Parameters:
-**
-**    p               Pointer to the VDBE
-**
-**    op              The opcode for this instruction
-**
-**    p1, p2          First two of the three possible operands.
-**
-** Use the sqliteVdbeResolveLabel() function to fix an address and
-** the sqliteVdbeChangeP3() function to change the value of the P3
-** operand.
-*/
-int sqliteVdbeAddOp(Vdbe *p, int op, int p1, int p2){
-  int i;
-
-  i = p->nOp;
-  p->nOp++;
-  assert( p->magic==VDBE_MAGIC_INIT );
-  if( i>=p->nOpAlloc ){
-    int oldSize = p->nOpAlloc;
-    Op *aNew;
-    p->nOpAlloc = p->nOpAlloc*2 + 100;
-    aNew = sqliteRealloc(p->aOp, p->nOpAlloc*sizeof(Op));
-    if( aNew==0 ){
-      p->nOpAlloc = oldSize;
-      return 0;
-    }
-    p->aOp = aNew;
-    memset(&p->aOp[oldSize], 0, (p->nOpAlloc-oldSize)*sizeof(Op));
-  }
-  p->aOp[i].opcode = op;
-  p->aOp[i].p1 = p1;
-  if( p2<0 && (-1-p2)<p->nLabel && p->aLabel[-1-p2]>=0 ){
-    p2 = p->aLabel[-1-p2];
-  }
-  p->aOp[i].p2 = p2;
-  p->aOp[i].p3 = 0;
-  p->aOp[i].p3type = P3_NOTUSED;
-#ifndef NDEBUG
-  if( sqlite_vdbe_addop_trace ) vdbePrintOp(0, i, &p->aOp[i]);
-#endif
-  return i;
-}
-
-/*
-** Create a new symbolic label for an instruction that has yet to be
-** coded.  The symbolic label is really just a negative number.  The
-** label can be used as the P2 value of an operation.  Later, when
-** the label is resolved to a specific address, the VDBE will scan
-** through its operation list and change all values of P2 which match
-** the label into the resolved address.
-**
-** The VDBE knows that a P2 value is a label because labels are
-** always negative and P2 values are suppose to be non-negative.
-** Hence, a negative P2 value is a label that has yet to be resolved.
-*/
-int sqliteVdbeMakeLabel(Vdbe *p){
-  int i;
-  i = p->nLabel++;
-  assert( p->magic==VDBE_MAGIC_INIT );
-  if( i>=p->nLabelAlloc ){
-    int *aNew;
-    p->nLabelAlloc = p->nLabelAlloc*2 + 10;
-    aNew = sqliteRealloc( p->aLabel, p->nLabelAlloc*sizeof(p->aLabel[0]));
-    if( aNew==0 ){
-      sqliteFree(p->aLabel);
-    }
-    p->aLabel = aNew;
-  }
-  if( p->aLabel==0 ){
-    p->nLabel = 0;
-    p->nLabelAlloc = 0;
-    return 0;
-  }
-  p->aLabel[i] = -1;
-  return -1-i;
-}
-
-/*
-** Resolve label "x" to be the address of the next instruction to
-** be inserted.  The parameter "x" must have been obtained from
-** a prior call to sqliteVdbeMakeLabel().
-*/
-void sqliteVdbeResolveLabel(Vdbe *p, int x){
-  int j;
-  assert( p->magic==VDBE_MAGIC_INIT );
-  if( x<0 && (-x)<=p->nLabel && p->aOp ){
-    if( p->aLabel[-1-x]==p->nOp ) return;
-    assert( p->aLabel[-1-x]<0 );
-    p->aLabel[-1-x] = p->nOp;
-    for(j=0; j<p->nOp; j++){
-      if( p->aOp[j].p2==x ) p->aOp[j].p2 = p->nOp;
-    }
-  }
-}
-
-/*
-** Return the address of the next instruction to be inserted.
-*/
-int sqliteVdbeCurrentAddr(Vdbe *p){
-  assert( p->magic==VDBE_MAGIC_INIT );
-  return p->nOp;
-}
-
-/*
-** Add a whole list of operations to the operation stack.  Return the
-** address of the first operation added.
-*/
-int sqliteVdbeAddOpList(Vdbe *p, int nOp, VdbeOp const *aOp){
-  int addr;
-  assert( p->magic==VDBE_MAGIC_INIT );
-  if( p->nOp + nOp >= p->nOpAlloc ){
-    int oldSize = p->nOpAlloc;
-    Op *aNew;
-    p->nOpAlloc = p->nOpAlloc*2 + nOp + 10;
-    aNew = sqliteRealloc(p->aOp, p->nOpAlloc*sizeof(Op));
-    if( aNew==0 ){
-      p->nOpAlloc = oldSize;
-      return 0;
-    }
-    p->aOp = aNew;
-    memset(&p->aOp[oldSize], 0, (p->nOpAlloc-oldSize)*sizeof(Op));
-  }
-  addr = p->nOp;
-  if( nOp>0 ){
-    int i;
-    for(i=0; i<nOp; i++){
-      int p2 = aOp[i].p2;
-      p->aOp[i+addr] = aOp[i];
-      if( p2<0 ) p->aOp[i+addr].p2 = addr + ADDR(p2);
-      p->aOp[i+addr].p3type = aOp[i].p3 ? P3_STATIC : P3_NOTUSED;
-#ifndef NDEBUG
-      if( sqlite_vdbe_addop_trace ) vdbePrintOp(0, i+addr, &p->aOp[i+addr]);
-#endif
-    }
-    p->nOp += nOp;
-  }
-  return addr;
-}
-
-/*
-** Change the value of the P1 operand for a specific instruction.
-** This routine is useful when a large program is loaded from a
-** static array using sqliteVdbeAddOpList but we want to make a
-** few minor changes to the program.
-*/
-void sqliteVdbeChangeP1(Vdbe *p, int addr, int val){
-  assert( p->magic==VDBE_MAGIC_INIT );
-  if( p && addr>=0 && p->nOp>addr && p->aOp ){
-    p->aOp[addr].p1 = val;
-  }
-}
-
-/*
-** Change the value of the P2 operand for a specific instruction.
-** This routine is useful for setting a jump destination.
-*/
-void sqliteVdbeChangeP2(Vdbe *p, int addr, int val){
-  assert( val>=0 );
-  assert( p->magic==VDBE_MAGIC_INIT );
-  if( p && addr>=0 && p->nOp>addr && p->aOp ){
-    p->aOp[addr].p2 = val;
-  }
-}
-
-/*
-** Change the value of the P3 operand for a specific instruction.
-** This routine is useful when a large program is loaded from a
-** static array using sqliteVdbeAddOpList but we want to make a
-** few minor changes to the program.
-**
-** If n>=0 then the P3 operand is dynamic, meaning that a copy of
-** the string is made into memory obtained from sqliteMalloc().
-** A value of n==0 means copy bytes of zP3 up to and including the
-** first null byte.  If n>0 then copy n+1 bytes of zP3.
-**
-** If n==P3_STATIC  it means that zP3 is a pointer to a constant static
-** string and we can just copy the pointer.  n==P3_POINTER means zP3 is
-** a pointer to some object other than a string.
-**
-** If addr<0 then change P3 on the most recently inserted instruction.
-*/
-void sqliteVdbeChangeP3(Vdbe *p, int addr, const char *zP3, int n){
-  Op *pOp;
-  assert( p->magic==VDBE_MAGIC_INIT );
-  if( p==0 || p->aOp==0 ) return;
-  if( addr<0 || addr>=p->nOp ){
-    addr = p->nOp - 1;
-    if( addr<0 ) return;
-  }
-  pOp = &p->aOp[addr];
-  if( pOp->p3 && pOp->p3type==P3_DYNAMIC ){
-    sqliteFree(pOp->p3);
-    pOp->p3 = 0;
-  }
-  if( zP3==0 ){
-    pOp->p3 = 0;
-    pOp->p3type = P3_NOTUSED;
-  }else if( n<0 ){
-    pOp->p3 = (char*)zP3;
-    pOp->p3type = n;
-  }else{
-    sqliteSetNString(&pOp->p3, zP3, n, 0);
-    pOp->p3type = P3_DYNAMIC;
-  }
-}
-
-/*
-** If the P3 operand to the specified instruction appears
-** to be a quoted string token, then this procedure removes 
-** the quotes.
-**
-** The quoting operator can be either a grave ascent (ASCII 0x27)
-** or a double quote character (ASCII 0x22).  Two quotes in a row
-** resolve to be a single actual quote character within the string.
-*/
-void sqliteVdbeDequoteP3(Vdbe *p, int addr){
-  Op *pOp;
-  assert( p->magic==VDBE_MAGIC_INIT );
-  if( p->aOp==0 || addr<0 || addr>=p->nOp ) return;
-  pOp = &p->aOp[addr];
-  if( pOp->p3==0 || pOp->p3[0]==0 ) return;
-  if( pOp->p3type==P3_POINTER ) return;
-  if( pOp->p3type!=P3_DYNAMIC ){
-    pOp->p3 = sqliteStrDup(pOp->p3);
-    pOp->p3type = P3_DYNAMIC;
-  }
-  sqliteDequote(pOp->p3);
-}
-
-/*
-** On the P3 argument of the given instruction, change all
-** strings of whitespace characters into a single space and
-** delete leading and trailing whitespace.
-*/
-void sqliteVdbeCompressSpace(Vdbe *p, int addr){
-  unsigned char *z;
-  int i, j;
-  Op *pOp;
-  assert( p->magic==VDBE_MAGIC_INIT );
-  if( p->aOp==0 || addr<0 || addr>=p->nOp ) return;
-  pOp = &p->aOp[addr];
-  if( pOp->p3type==P3_POINTER ){
-    return;
-  }
-  if( pOp->p3type!=P3_DYNAMIC ){
-    pOp->p3 = sqliteStrDup(pOp->p3);
-    pOp->p3type = P3_DYNAMIC;
-  }
-  z = (unsigned char*)pOp->p3;
-  if( z==0 ) return;
-  i = j = 0;
-  while( isspace(z[i]) ){ i++; }
-  while( z[i] ){
-    if( isspace(z[i]) ){
-      z[j++] = ' ';
-      while( isspace(z[++i]) ){}
-    }else{
-      z[j++] = z[i++];
-    }
-  }
-  while( j>0 && isspace(z[j-1]) ){ j--; }
-  z[j] = 0;
-}
-
-/*
-** Search for the current program for the given opcode and P2
-** value.  Return the address plus 1 if found and 0 if not found.
-*/
-int sqliteVdbeFindOp(Vdbe *p, int op, int p2){
-  int i;
-  assert( p->magic==VDBE_MAGIC_INIT );
-  for(i=0; i<p->nOp; i++){
-    if( p->aOp[i].opcode==op && p->aOp[i].p2==p2 ) return i+1;
-  }
-  return 0;
-}
-
-/*
-** Return the opcode for a given address.
-*/
-VdbeOp *sqliteVdbeGetOp(Vdbe *p, int addr){
-  assert( p->magic==VDBE_MAGIC_INIT );
-  assert( addr>=0 && addr<p->nOp );
-  return &p->aOp[addr];
-}
-
-/*
-** The following group or routines are employed by installable functions
-** to return their results.
-**
-** The sqlite_set_result_string() routine can be used to return a string
-** value or to return a NULL.  To return a NULL, pass in NULL for zResult.
-** A copy is made of the string before this routine returns so it is safe
-** to pass in an ephemeral string.
-**
-** sqlite_set_result_error() works like sqlite_set_result_string() except
-** that it signals a fatal error.  The string argument, if any, is the
-** error message.  If the argument is NULL a generic substitute error message
-** is used.
-**
-** The sqlite_set_result_int() and sqlite_set_result_double() set the return
-** value of the user function to an integer or a double.
-**
-** These routines are defined here in vdbe.c because they depend on knowing
-** the internals of the sqlite_func structure which is only defined in 
-** this source file.
-*/
-char *sqlite_set_result_string(sqlite_func *p, const char *zResult, int n){
-  assert( !p->isStep );
-  if( p->s.flags & STK_Dyn ){
-    sqliteFree(p->z);
-  }
-  if( zResult==0 ){
-    p->s.flags = STK_Null;
-    n = 0;
-    p->z = 0;
-    p->s.n = 0;
-  }else{
-    if( n<0 ) n = strlen(zResult);
-    if( n<NBFS-1 ){
-      memcpy(p->s.z, zResult, n);
-      p->s.z[n] = 0;
-      p->s.flags = STK_Str;
-      p->z = p->s.z;
-    }else{
-      p->z = sqliteMallocRaw( n+1 );
-      if( p->z ){
-        memcpy(p->z, zResult, n);
-        p->z[n] = 0;
-      }
-      p->s.flags = STK_Str | STK_Dyn;
-    }
-    p->s.n = n+1;
-  }
-  return p->z;
-}
-void sqlite_set_result_int(sqlite_func *p, int iResult){
-  assert( !p->isStep );
-  if( p->s.flags & STK_Dyn ){
-    sqliteFree(p->z);
-  }
-  p->s.i = iResult;
-  p->s.flags = STK_Int;
-}
-void sqlite_set_result_double(sqlite_func *p, double rResult){
-  assert( !p->isStep );
-  if( p->s.flags & STK_Dyn ){
-    sqliteFree(p->z);
-  }
-  p->s.r = rResult;
-  p->s.flags = STK_Real;
-}
-void sqlite_set_result_error(sqlite_func *p, const char *zMsg, int n){
-  assert( !p->isStep );
-  sqlite_set_result_string(p, zMsg, n);
-  p->isError = 1;
-}
-
-/*
-** Extract the user data from a sqlite_func structure and return a
-** pointer to it.
-**
-** This routine is defined here in vdbe.c because it depends on knowing
-** the internals of the sqlite_func structure which is only defined in 
-** this source file.
-*/
-void *sqlite_user_data(sqlite_func *p){
-  assert( p && p->pFunc );
-  return p->pFunc->pUserData;
-}
-
-/*
-** Allocate or return the aggregate context for a user function.  A new
-** context is allocated on the first call.  Subsequent calls return the
-** same context that was returned on prior calls.
-**
-** This routine is defined here in vdbe.c because it depends on knowing
-** the internals of the sqlite_func structure which is only defined in
-** this source file.
-*/
-void *sqlite_aggregate_context(sqlite_func *p, int nByte){
-  assert( p && p->pFunc && p->pFunc->xStep );
-  if( p->pAgg==0 ){
-    if( nByte<=NBFS ){
-      p->pAgg = (void*)p->z;
-    }else{
-      p->pAgg = sqliteMalloc( nByte );
-    }
-  }
-  return p->pAgg;
-}
-
-/*
-** Return the number of times the Step function of a aggregate has been 
-** called.
-**
-** This routine is defined here in vdbe.c because it depends on knowing
-** the internals of the sqlite_func structure which is only defined in
-** this source file.
-*/
-int sqlite_aggregate_count(sqlite_func *p){
-  assert( p && p->pFunc && p->pFunc->xStep );
-  return p->cnt;
-}
 
 /*
 ** Advance the virtual machine to the next output row.
@@ -831,50 +137,6 @@ int sqlite_step(
   return rc;
 }
 
-/*
-** Reset an Agg structure.  Delete all its contents. 
-**
-** For installable aggregate functions, if the step function has been
-** called, make sure the finalizer function has also been called.  The
-** finalizer might need to free memory that was allocated as part of its
-** private context.  If the finalizer has not been called yet, call it
-** now.
-*/
-static void AggReset(Agg *pAgg){
-  int i;
-  HashElem *p;
-  for(p = sqliteHashFirst(&pAgg->hash); p; p = sqliteHashNext(p)){
-    AggElem *pElem = sqliteHashData(p);
-    assert( pAgg->apFunc!=0 );
-    for(i=0; i<pAgg->nMem; i++){
-      Mem *pMem = &pElem->aMem[i];
-      if( pAgg->apFunc[i] && (pMem->s.flags & STK_AggCtx)!=0 ){
-        sqlite_func ctx;
-        ctx.pFunc = pAgg->apFunc[i];
-        ctx.s.flags = STK_Null;
-        ctx.z = 0;
-        ctx.pAgg = pMem->z;
-        ctx.cnt = pMem->s.i;
-        ctx.isStep = 0;
-        ctx.isError = 0;
-        (*pAgg->apFunc[i]->xFinalize)(&ctx);
-        if( pMem->z!=0 && pMem->z!=pMem->s.z ){
-          sqliteFree(pMem->z);
-        }
-      }else if( pMem->s.flags & STK_Dyn ){
-        sqliteFree(pMem->z);
-      }
-    }
-    sqliteFree(pElem);
-  }
-  sqliteHashClear(&pAgg->hash);
-  sqliteFree(pAgg->apFunc);
-  pAgg->apFunc = 0;
-  pAgg->pCurrent = 0;
-  pAgg->pSearch = 0;
-  pAgg->nMem = 0;
-}
-
 /*
 ** Insert a new aggregate element and make it the element that
 ** has focus.
@@ -1068,257 +330,6 @@ static void hardRealify(Vdbe *p, int i){
   p->aStack[i].flags |= STK_Real;
 }
 
-/*
-** Pop the stack N times.  Free any memory associated with the
-** popped stack elements.
-*/
-static void PopStack(Vdbe *p, int N){
-  assert( N>=0 );
-  if( p->zStack==0 ) return;
-  assert( p->aStack || sqlite_malloc_failed );
-  if( p->aStack==0 ) return;
-  while( N-- > 0 ){
-    if( p->aStack[p->tos].flags & STK_Dyn ){
-      sqliteFree(p->zStack[p->tos]);
-    }
-    p->aStack[p->tos].flags = 0;
-    p->zStack[p->tos] = 0;
-    p->tos--;
-  }
-}
-
-/*
-** Here is a macro to handle the common case of popping the stack
-** once.  This macro only works from within the sqliteVdbeExec()
-** function.
-*/
-#define POPSTACK \
-  assert(p->tos>=0); \
-  if( aStack[p->tos].flags & STK_Dyn ) sqliteFree(zStack[p->tos]); \
-  p->tos--;
-
-/*
-** Delete a keylist
-*/
-static void KeylistFree(Keylist *p){
-  while( p ){
-    Keylist *pNext = p->pNext;
-    sqliteFree(p);
-    p = pNext;
-  }
-}
-
-/*
-** Close a cursor and release all the resources that cursor happens
-** to hold.
-*/
-static void cleanupCursor(Cursor *pCx){
-  if( pCx->pCursor ){
-    sqliteBtreeCloseCursor(pCx->pCursor);
-  }
-  if( pCx->pBt ){
-    sqliteBtreeClose(pCx->pBt);
-  }
-  sqliteFree(pCx->pData);
-  memset(pCx, 0, sizeof(Cursor));
-}
-
-/*
-** Close all cursors
-*/
-static void closeAllCursors(Vdbe *p){
-  int i;
-  for(i=0; i<p->nCursor; i++){
-    cleanupCursor(&p->aCsr[i]);
-  }
-  sqliteFree(p->aCsr);
-  p->aCsr = 0;
-  p->nCursor = 0;
-}
-
-/*
-** Remove any elements that remain on the sorter for the VDBE given.
-*/
-static void SorterReset(Vdbe *p){
-  while( p->pSort ){
-    Sorter *pSorter = p->pSort;
-    p->pSort = pSorter->pNext;
-    sqliteFree(pSorter->zKey);
-    sqliteFree(pSorter->pData);
-    sqliteFree(pSorter);
-  }
-}
-
-/*
-** Delete the variables in p->azVariable[]
-*/
-static void ClearVariableArray(Vdbe *p){
-  sqliteFree(p->azVariable);
-  p->nVariable = 0;
-  p->azVariable = 0;
-}
-
-/*
-** Clean up the VM after execution.
-**
-** This routine will automatically close any cursors, lists, and/or
-** sorters that were left open.  It also deletes the values of
-** variables in the azVariable[] array.
-*/
-static void Cleanup(Vdbe *p){
-  int i;
-  PopStack(p, p->tos+1);
-  closeAllCursors(p);
-  if( p->aMem ){
-    for(i=0; i<p->nMem; i++){
-      if( p->aMem[i].s.flags & STK_Dyn ){
-        sqliteFree(p->aMem[i].z);
-      }
-    }
-  }
-  sqliteFree(p->aMem);
-  p->aMem = 0;
-  p->nMem = 0;
-  if( p->pList ){
-    KeylistFree(p->pList);
-    p->pList = 0;
-  }
-  SorterReset(p);
-  if( p->pFile ){
-    if( p->pFile!=stdin ) fclose(p->pFile);
-    p->pFile = 0;
-  }
-  if( p->azField ){
-    sqliteFree(p->azField);
-    p->azField = 0;
-  }
-  p->nField = 0;
-  if( p->zLine ){
-    sqliteFree(p->zLine);
-    p->zLine = 0;
-  }
-  p->nLineAlloc = 0;
-  AggReset(&p->agg);
-  if( p->aSet ){
-    for(i=0; i<p->nSet; i++){
-      sqliteHashClear(&p->aSet[i].hash);
-    }
-  }
-  sqliteFree(p->aSet);
-  p->aSet = 0;
-  p->nSet = 0;
-  if( p->keylistStack ){
-    int ii;
-    for(ii = 0; ii < p->keylistStackDepth; ii++){
-      KeylistFree(p->keylistStack[ii]);
-    }
-    sqliteFree(p->keylistStack);
-    p->keylistStackDepth = 0;
-    p->keylistStack = 0;
-  }
-  sqliteFree(p->zErrMsg);
-  p->zErrMsg = 0;
-  ClearVariableArray(p);
-}
-
-/*
-** Delete an entire VDBE.
-*/
-void sqliteVdbeDelete(Vdbe *p){
-  int i;
-  if( p==0 ) return;
-  Cleanup(p);
-  if( p->pPrev ){
-    p->pPrev->pNext = p->pNext;
-  }else{
-    assert( p->db->pVdbe==p );
-    p->db->pVdbe = p->pNext;
-  }
-  if( p->pNext ){
-    p->pNext->pPrev = p->pPrev;
-  }
-  p->pPrev = p->pNext = 0;
-  if( p->nOpAlloc==0 ){
-    p->aOp = 0;
-    p->nOp = 0;
-  }
-  for(i=0; i<p->nOp; i++){
-    if( p->aOp[i].p3type==P3_DYNAMIC ){
-      sqliteFree(p->aOp[i].p3);
-    }
-  }
-  sqliteFree(p->aOp);
-  sqliteFree(p->aLabel);
-  sqliteFree(p->aStack);
-  p->magic = VDBE_MAGIC_DEAD;
-  sqliteFree(p);
-}
-
-/*
-** Give a listing of the program in the virtual machine.
-**
-** The interface is the same as sqliteVdbeExec().  But instead of
-** running the code, it invokes the callback once for each instruction.
-** This feature is used to implement "EXPLAIN".
-*/
-int sqliteVdbeList(
-  Vdbe *p                   /* The VDBE */
-){
-  sqlite *db = p->db;
-  int i;
-  static char *azColumnNames[] = {
-     "addr", "opcode", "p1",  "p2",  "p3", 
-     "int",  "text",   "int", "int", "text",
-     0
-  };
-
-  assert( p->popStack==0 );
-  assert( p->explain );
-  p->azColName = azColumnNames;
-  p->azResColumn = p->zStack;
-  for(i=0; i<5; i++) p->zStack[i] = p->aStack[i].z;
-  p->rc = SQLITE_OK;
-  for(i=p->pc; p->rc==SQLITE_OK && i<p->nOp; i++){
-    if( db->flags & SQLITE_Interrupt ){
-      db->flags &= ~SQLITE_Interrupt;
-      if( db->magic!=SQLITE_MAGIC_BUSY ){
-        p->rc = SQLITE_MISUSE;
-      }else{
-        p->rc = SQLITE_INTERRUPT;
-      }
-      sqliteSetString(&p->zErrMsg, sqlite_error_string(p->rc), 0);
-      break;
-    }
-    sprintf(p->zStack[0],"%d",i);
-    sprintf(p->zStack[2],"%d", p->aOp[i].p1);
-    sprintf(p->zStack[3],"%d", p->aOp[i].p2);
-    if( p->aOp[i].p3type==P3_POINTER ){
-      sprintf(p->aStack[4].z, "ptr(%#x)", (int)p->aOp[i].p3);
-      p->zStack[4] = p->aStack[4].z;
-    }else{
-      p->zStack[4] = p->aOp[i].p3;
-    }
-    p->zStack[1] = sqliteOpcodeNames[p->aOp[i].opcode];
-    if( p->xCallback==0 ){
-      p->pc = i+1;
-      p->azResColumn = p->zStack;
-      p->nResColumn = 5;
-      return SQLITE_ROW;
-    }
-    if( sqliteSafetyOff(db) ){
-      p->rc = SQLITE_MISUSE;
-      break;
-    }
-    if( p->xCallback(p->pCbArg, 5, p->zStack, p->azColName) ){
-      p->rc = SQLITE_ABORT;
-    }
-    if( sqliteSafetyOn(db) ){
-      p->rc = SQLITE_MISUSE;
-    }
-  }
-  return p->rc==SQLITE_OK ? SQLITE_DONE : SQLITE_ERROR;
-}
-
 /*
 ** The parameters are pointers to the head of two sorted lists
 ** of Sorter structures.  Merge these two lists together and return
@@ -1424,26 +435,6 @@ static char *vdbe_fgets(char *zBuf, int nBuf, FILE *in){
   return i>0 ? zBuf : 0;
 }
 
-#if !defined(NDEBUG) || defined(VDBE_PROFILE)
-/*
-** Print a single opcode.  This routine is used for debugging only.
-*/
-static void vdbePrintOp(FILE *pOut, int pc, Op *pOp){
-  char *zP3;
-  char zPtr[40];
-  if( pOp->p3type==P3_POINTER ){
-    sprintf(zPtr, "ptr(%#x)", (int)pOp->p3);
-    zP3 = zPtr;
-  }else{
-    zP3 = pOp->p3;
-  }
-  if( pOut==0 ) pOut = stdout;
-  fprintf(pOut,"%4d %-12s %4d %4d %s\n",
-      pc, sqliteOpcodeNames[pOp->opcode], pOp->p1, pOp->p2, zP3 ? zP3 : "");
-  fflush(pOut);
-}
-#endif
-
 /*
 ** Make sure there is space in the Vdbe structure to hold at least
 ** mxCursor cursors.  If there is not currently enough space, then
@@ -1493,77 +484,6 @@ __inline__ unsigned long long int hwtime(void){
    if( db->flags & SQLITE_Interrupt ) goto abort_due_to_interrupt;
 
 
-/*
-** Prepare a virtual machine for execution.  This involves things such
-** as allocating stack space and initializing the program counter.
-** After the VDBE has be prepped, it can be executed by one or more
-** calls to sqliteVdbeExec().  
-**
-** The behavior of sqliteVdbeExec() is influenced by the parameters to
-** this routine.  If xCallback is NULL, then sqliteVdbeExec() will return
-** with SQLITE_ROW whenever there is a row of the result set ready
-** to be delivered.  p->azResColumn will point to the row and 
-** p->nResColumn gives the number of columns in the row.  If xCallback
-** is not NULL, then the xCallback() routine is invoked to process each
-** row in the result set.
-*/
-void sqliteVdbeMakeReady(
-  Vdbe *p,                       /* The VDBE */
-  sqlite_callback xCallback,     /* Result callback */
-  void *pCallbackArg,            /* 1st argument to xCallback() */
-  int isExplain                  /* True if the EXPLAIN keywords is present */
-){
-  int n;
-
-  assert( p!=0 );
-  assert( p->aStack==0 );
-  assert( p->magic==VDBE_MAGIC_INIT );
-
-  /* Add a HALT instruction to the very end of the program.
-  */
-  if( p->nOp==0 || (p->aOp && p->aOp[p->nOp-1].opcode!=OP_Halt) ){
-    sqliteVdbeAddOp(p, OP_Halt, 0, 0);
-  }
-
-  /* No instruction ever pushes more than a single element onto the
-  ** stack.  And the stack never grows on successive executions of the
-  ** same loop.  So the total number of instructions is an upper bound
-  ** on the maximum stack depth required.
-  **
-  ** Allocation all the stack space we will ever need.
-  */
-  n = isExplain ? 10 : p->nOp;
-  p->aStack = sqliteMalloc( n*(sizeof(p->aStack[0]) + 2*sizeof(char*)) );
-  p->zStack = (char**)&p->aStack[n];
-  p->azColName = (char**)&p->zStack[n];
-
-  sqliteHashInit(&p->agg.hash, SQLITE_HASH_BINARY, 0);
-  p->agg.pSearch = 0;
-#ifdef MEMORY_DEBUG
-  if( sqliteOsFileExists("vdbe_trace") ){
-    p->trace = stdout;
-  }
-#endif
-  p->tos = -1;
-  p->pc = 0;
-  p->rc = SQLITE_OK;
-  p->uniqueCnt = 0;
-  p->returnDepth = 0;
-  p->errorAction = OE_Abort;
-  p->undoTransOnError = 0;
-  p->xCallback = xCallback;
-  p->pCbArg = pCallbackArg;
-  p->popStack =  0;
-  p->explain |= isExplain;
-  p->magic = VDBE_MAGIC_RUN;
-#ifdef VDBE_PROFILE
-  for(i=0; i<p->nOp; i++){
-    p->aOp[i].cnt = 0;
-    p->aOp[i].cycles = 0;
-  }
-#endif
-}
-
 /*
 ** Execute as much of a VDBE program as we can then return.
 **
@@ -1617,7 +537,7 @@ int sqliteVdbeExec(
   assert( p->explain==0 );
   if( sqlite_malloc_failed ) goto no_mem;
   if( p->popStack ){
-    PopStack(p, p->popStack);
+    sqliteVdbePopStack(p, p->popStack);
     p->popStack = 0;
   }
   for(pc=p->pc; rc==SQLITE_OK; pc++){
@@ -1632,7 +552,7 @@ int sqliteVdbeExec(
     */
 #ifndef NDEBUG
     if( p->trace ){
-      vdbePrintOp(p->trace, pc, pOp);
+      sqliteVdbePrintOp(p->trace, pc, pOp);
     }
 #endif
 
@@ -1814,7 +734,7 @@ case OP_Variable: {
 */
 case OP_Pop: {
   assert( p->tos+1>=pOp->p1 );
-  PopStack(p, pOp->p1);
+  sqliteVdbePopStack(p, pOp->p1);
   break;
 }
 
@@ -1969,7 +889,7 @@ case OP_Callback: {
   }
   if( sqliteSafetyOn(db) ) goto abort_due_to_misuse;
   p->nCallback++;
-  PopStack(p, pOp->p1);
+  sqliteVdbePopStack(p, pOp->p1);
   if( sqlite_malloc_failed ) goto no_mem;
   break;
 }
@@ -2040,7 +960,7 @@ case OP_Concat: {
     }
   }
   if( nByte<0 ){
-    if( pOp->p2==0 ) PopStack(p, nField);
+    if( pOp->p2==0 ) sqliteVdbePopStack(p, nField);
     p->tos++;
     aStack[p->tos].flags = STK_Null;
     zStack[p->tos] = 0;
@@ -2060,7 +980,7 @@ case OP_Concat: {
     }
   }
   zNew[j] = 0;
-  if( pOp->p2==0 ) PopStack(p, nField);
+  if( pOp->p2==0 ) sqliteVdbePopStack(p, nField);
   p->tos++;
   aStack[p->tos].n = nByte;
   aStack[p->tos].flags = STK_Str|STK_Dyn;
@@ -2180,7 +1100,7 @@ case OP_Remainder: {
   break;
 
 divide_by_zero:
-  PopStack(p, 2);
+  sqliteVdbePopStack(p, 2);
   p->tos = nos;
   aStack[nos].flags = STK_Null;
   break;
@@ -2214,7 +1134,7 @@ case OP_Function: {
   ctx.isError = 0;
   ctx.isStep = 0;
   (*ctx.pFunc->xFunc)(&ctx, n, (const char**)&zStack[p->tos-n+1]);
-  PopStack(p, n);
+  sqliteVdbePopStack(p, n);
   p->tos++;
   aStack[p->tos] = ctx.s;
   if( ctx.s.flags & STK_Dyn ){
@@ -2901,7 +1821,7 @@ case OP_IsNull: {
       break;
     }
   }
-  if( pOp->p1>0 ) PopStack(p, cnt);
+  if( pOp->p1>0 ) sqliteVdbePopStack(p, cnt);
   break;
 }
 
@@ -3030,7 +1950,7 @@ case OP_MakeRecord: {
       j += aStack[i].n;
     }
   }
-  PopStack(p, nField);
+  sqliteVdbePopStack(p, nField);
   p->tos++;
   aStack[p->tos].n = nByte;
   if( nByte<=NBFS ){
@@ -3192,10 +2112,10 @@ case OP_MakeKey: {
     Integerify(p, p->tos-nField);
     iKey = intToKey(aStack[p->tos-nField].i);
     memcpy(&zNewKey[j], &iKey, sizeof(u32));
-    PopStack(p, nField+1);
+    sqliteVdbePopStack(p, nField+1);
     if( pOp->p2 && containsNull ) pc = pOp->p2 - 1;
   }else{
-    if( pOp->p2==0 ) PopStack(p, nField+addRowid);
+    if( pOp->p2==0 ) sqliteVdbePopStack(p, nField+addRowid);
   }
   p->tos++;
   aStack[p->tos].n = nByte;
@@ -3505,7 +2425,7 @@ case OP_OpenWrite: {
   }
   VERIFY( if( i<0 ) goto bad_instruction; )
   if( expandCursorArraySize(p, i) ) goto no_mem;
-  cleanupCursor(&p->aCsr[i]);
+  sqliteVdbeCleanupCursor(&p->aCsr[i]);
   memset(&p->aCsr[i], 0, sizeof(Cursor));
   p->aCsr[i].nullRow = 1;
   if( pX==0 ) break;
@@ -3563,7 +2483,7 @@ case OP_OpenTemp: {
   VERIFY( if( i<0 ) goto bad_instruction; )
   if( expandCursorArraySize(p, i) ) goto no_mem;
   pCx = &p->aCsr[i];
-  cleanupCursor(pCx);
+  sqliteVdbeCleanupCursor(pCx);
   memset(pCx, 0, sizeof(*pCx));
   pCx->nullRow = 1;
   rc = sqliteBtreeFactory(db, 0, 1, TEMP_PAGES, &pCx->pBt);
@@ -3601,7 +2521,7 @@ case OP_OpenPseudo: {
   VERIFY( if( i<0 ) goto bad_instruction; )
   if( expandCursorArraySize(p, i) ) goto no_mem;
   pCx = &p->aCsr[i];
-  cleanupCursor(pCx);
+  sqliteVdbeCleanupCursor(pCx);
   memset(pCx, 0, sizeof(*pCx));
   pCx->nullRow = 1;
   pCx->pseudoTable = 1;
@@ -3616,7 +2536,7 @@ case OP_OpenPseudo: {
 case OP_Close: {
   int i = pOp->p1;
   if( i>=0 && i<p->nCursor ){
-    cleanupCursor(&p->aCsr[i]);
+    sqliteVdbeCleanupCursor(&p->aCsr[i]);
   }
   break;
 }
@@ -4824,7 +3744,7 @@ case OP_ListRead: {
 */
 case OP_ListReset: {
   if( p->pList ){
-    KeylistFree(p->pList);
+    sqliteVdbeKeylistFree(p->pList);
     p->pList = 0;
   }
   break;
@@ -4854,7 +3774,7 @@ case OP_ListPush: {
 case OP_ListPop: {
   assert(p->keylistStackDepth > 0);
   p->keylistStackDepth--;
-  KeylistFree(p->pList);
+  sqliteVdbeKeylistFree(p->pList);
   p->pList = p->keylistStack[p->keylistStackDepth];
   p->keylistStack[p->keylistStackDepth] = 0;
   if( p->keylistStackDepth == 0 ){
@@ -4932,7 +3852,7 @@ case OP_SortMakeRec: {
       z += aStack[i].n;
     }
   }
-  PopStack(p, nField);
+  sqliteVdbePopStack(p, nField);
   p->tos++;
   aStack[p->tos].n = nByte;
   zStack[p->tos] = (char*)azArg;
@@ -4990,7 +3910,7 @@ case OP_SortMakeKey: {
   }
   zNewKey[j] = 0;
   assert( j<nByte );
-  PopStack(p, nField);
+  sqliteVdbePopStack(p, nField);
   p->tos++;
   aStack[p->tos].n = nByte;
   aStack[p->tos].flags = STK_Str|STK_Dyn;
@@ -5093,7 +4013,7 @@ case OP_SortCallback: {
 ** Remove any elements that remain on the sorter.
 */
 case OP_SortReset: {
-  SorterReset(p);
+  sqliteVdbeSorterReset(p);
   break;
 }
 
@@ -5373,7 +4293,7 @@ case OP_MemIncr: {
 ** Future aggregator elements will contain P2 values each.
 */
 case OP_AggReset: {
-  AggReset(&p->agg);
+  sqliteVdbeAggReset(&p->agg);
   p->agg.nMem = pOp->p2;
   p->agg.apFunc = sqliteMalloc( p->agg.nMem*sizeof(p->agg.apFunc[0]) );
   if( p->agg.apFunc==0 ) goto no_mem;
@@ -5432,7 +4352,7 @@ case OP_AggFunc: {
   (ctx.pFunc->xStep)(&ctx, n, (const char**)&zStack[p->tos-n]);
   pMem->z = ctx.pAgg;
   pMem->s.flags = STK_AggCtx;
-  PopStack(p, n+1);
+  sqliteVdbePopStack(p, n+1);
   if( ctx.isError ){
     rc = SQLITE_ERROR;
   }
@@ -5722,7 +4642,7 @@ default: {
       pOp->cnt++;
 #if 0
         fprintf(stdout, "%10lld ", elapse);
-        vdbePrintOp(stdout, origPc, &p->aOp[origPc]);
+        sqliteVdbePrintOp(stdout, origPc, &p->aOp[origPc]);
 #endif
     }
 #endif
@@ -5857,182 +4777,3 @@ bad_instruction:
   goto vdbe_halt;
 )
 }
-
-
-/*
-** Clean up a VDBE after execution but do not delete the VDBE just yet.
-** Write any error messages into *pzErrMsg.  Return the result code.
-**
-** After this routine is run, the VDBE should be ready to be executed
-** again.
-*/
-int sqliteVdbeReset(Vdbe *p, char **pzErrMsg){
-  sqlite *db = p->db;
-  int i;
-
-  if( p->magic!=VDBE_MAGIC_RUN && p->magic!=VDBE_MAGIC_HALT ){
-    sqliteSetString(pzErrMsg, sqlite_error_string(SQLITE_MISUSE), 0);
-    return SQLITE_MISUSE;
-  }
-  if( p->zErrMsg ){
-    if( pzErrMsg && *pzErrMsg==0 ){
-      *pzErrMsg = p->zErrMsg;
-    }else{
-      sqliteFree(p->zErrMsg);
-    }
-    p->zErrMsg = 0;
-  }
-  Cleanup(p);
-  if( p->rc!=SQLITE_OK ){
-    switch( p->errorAction ){
-      case OE_Abort: {
-        if( !p->undoTransOnError ){
-          for(i=0; i<db->nDb; i++){
-            if( db->aDb[i].pBt ){
-              sqliteBtreeRollbackCkpt(db->aDb[i].pBt);
-            }
-          }
-          break;
-        }
-        /* Fall through to ROLLBACK */
-      }
-      case OE_Rollback: {
-        sqliteRollbackAll(db);
-        db->flags &= ~SQLITE_InTrans;
-        db->onError = OE_Default;
-        break;
-      }
-      default: {
-        if( p->undoTransOnError ){
-          sqliteRollbackAll(db);
-          db->flags &= ~SQLITE_InTrans;
-          db->onError = OE_Default;
-        }
-        break;
-      }
-    }
-    sqliteRollbackInternalChanges(db);
-  }
-  for(i=0; i<db->nDb; i++){
-    if( db->aDb[i].pBt && db->aDb[i].inTrans==2 ){
-      sqliteBtreeCommitCkpt(db->aDb[i].pBt);
-      db->aDb[i].inTrans = 1;
-    }
-  }
-  assert( p->tos<p->pc || sqlite_malloc_failed==1 );
-#ifdef VDBE_PROFILE
-  {
-    FILE *out = fopen("vdbe_profile.out", "a");
-    if( out ){
-      int i;
-      fprintf(out, "---- ");
-      for(i=0; i<p->nOp; i++){
-        fprintf(out, "%02x", p->aOp[i].opcode);
-      }
-      fprintf(out, "\n");
-      for(i=0; i<p->nOp; i++){
-        fprintf(out, "%6d %10lld %8lld ",
-           p->aOp[i].cnt,
-           p->aOp[i].cycles,
-           p->aOp[i].cnt>0 ? p->aOp[i].cycles/p->aOp[i].cnt : 0
-        );
-        vdbePrintOp(out, i, &p->aOp[i]);
-      }
-      fclose(out);
-    }
-  }
-#endif
-  p->magic = VDBE_MAGIC_INIT;
-  return p->rc;
-}
-
-/*
-** Clean up and delete a VDBE after execution.  Return an integer which is
-** the result code.  Write any error message text into *pzErrMsg.
-*/
-int sqliteVdbeFinalize(Vdbe *p, char **pzErrMsg){
-  int rc;
-  sqlite *db;
-
-  if( p->magic!=VDBE_MAGIC_RUN && p->magic!=VDBE_MAGIC_HALT ){
-    sqliteSetString(pzErrMsg, sqlite_error_string(SQLITE_MISUSE), 0);
-    return SQLITE_MISUSE;
-  }
-  db = p->db;
-  rc = sqliteVdbeReset(p, pzErrMsg);
-  sqliteVdbeDelete(p);
-  if( db->want_to_close && db->pVdbe==0 ){
-    sqlite_close(db);
-  }
-  return rc;
-}
-
-/*
-** Set the values of all variables.  Variable $1 in the original SQL will
-** be the string azValue[0].  $2 will have the value azValue[1].  And
-** so forth.  If a value is out of range (for example $3 when nValue==2)
-** then its value will be NULL.
-**
-** This routine overrides any prior call.
-*/
-int sqliteVdbeSetVariables(Vdbe *p, int nValue, const char **azValue){
-  int i, n;
-  char *z;
-  if( p->magic!=VDBE_MAGIC_RUN || p->pc!=0 || p->nVariable!=0 ){
-    return SQLITE_MISUSE;
-  }
-  ClearVariableArray(p);
-  if( nValue==0 ){
-    p->nVariable = 0;
-    p->azVariable = 0;
-  }
-  for(i=n=0; i<nValue; i++){
-    if( azValue[i] ) n += strlen(azValue[i]) + 1;
-  }
-  p->azVariable = sqliteMalloc( sizeof(p->azVariable[0])*nValue + n );
-  if( p->azVariable==0 ){
-    p->nVariable = 0;
-    return SQLITE_NOMEM;
-  }
-  z = (char*)&p->azVariable[nValue];
-  for(i=0; i<nValue; i++){
-    if( azValue[i]==0 ){
-      p->azVariable[i] = 0;
-    }else{
-      p->azVariable[i] = z;
-      n = strlen(azValue[i]);
-      memcpy(z, azValue[i], n+1);
-      z += n+1;
-    }
-  }
-  p->nVariable = nValue;
-  return SQLITE_OK;
-}
-
-
-#if 0
-/*
-** Create a new Vdbe in *pOut and populate it with the program from p. Then
-** pass p to sqliteVdbeFinalize().
-*/
-int sqliteVdbeReset(Vdbe *p, char ** pErrMsg, Vdbe** pOut){
-  if( pOut && p->rc != SQLITE_SCHEMA ){
-
-    /* Create a new VDBE and populate it with the program used by the old
-    ** VDBE. Don't copy the last instruction of the program, as this is an 
-    ** OP_Halt coded by sqliteVdbeMakeReady(). 
-    */
-    *pOut = sqliteVdbeCreate( p->db );
-    (*pOut)->aOp = p->aOp;
-    (*pOut)->nOp = p->nOp-1;
-    (*pOut)->nOpAlloc = p->nOpAlloc;
-    sqliteVdbeMakeReady( *pOut, p->xCallback, p->pCbArg, (int)p->explain );
-    p->aOp = 0;
-    p->nOp = 0;
-    p->nOpAlloc = 0;
-  }else if( pOut ){
-    *pOut = NULL;
-  }
-  return sqliteVdbeFinalize(p, pErrMsg);
-}
-#endif
diff --git a/src/vdbeInt.h b/src/vdbeInt.h
new file mode 100644 (file)
index 0000000..20aebdb
--- /dev/null
@@ -0,0 +1,297 @@
+/*
+** 2003 September 6
+**
+** The author disclaims copyright to this source code.  In place of
+** a legal notice, here is a blessing:
+**
+**    May you do good and not evil.
+**    May you find forgiveness for yourself and forgive others.
+**    May you share freely, never taking more than you give.
+**
+*************************************************************************
+** This is the header file for information that is private to the
+** VDBE.  This information used to all be at the top of the single
+** source code file "vdbe.c".  When that file became too big (over
+** 6000 lines long) it was split up into several smaller files and
+** this header information was factored out.
+*/
+
+/*
+** The makefile scans this source file and creates the following
+** array of string constants which are the names of all VDBE opcodes.
+** This array is defined in a separate source code file named opcode.c
+** which is automatically generated by the makefile.
+*/
+extern char *sqliteOpcodeNames[];
+
+/*
+** SQL is translated into a sequence of instructions to be
+** executed by a virtual machine.  Each instruction is an instance
+** of the following structure.
+*/
+typedef struct VdbeOp Op;
+
+/*
+** Boolean values
+*/
+typedef unsigned char Bool;
+
+/*
+** A cursor is a pointer into a single BTree within a database file.
+** The cursor can seek to a BTree entry with a particular key, or
+** loop over all entries of the Btree.  You can also insert new BTree
+** entries or retrieve the key or data from the entry that the cursor
+** is currently pointing to.
+** 
+** Every cursor that the virtual machine has open is represented by an
+** instance of the following structure.
+**
+** If the Cursor.isTriggerRow flag is set it means that this cursor is
+** really a single row that represents the NEW or OLD pseudo-table of
+** a row trigger.  The data for the row is stored in Cursor.pData and
+** the rowid is in Cursor.iKey.
+*/
+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 */
+  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 */
+  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 */
+  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 */
+};
+typedef struct Cursor Cursor;
+
+/*
+** A sorter builds a list of elements to be sorted.  Each element of
+** the list is an instance of the following structure.
+*/
+typedef struct Sorter Sorter;
+struct Sorter {
+  int nKey;           /* Number of bytes in the key */
+  char *zKey;         /* The key by which we will sort */
+  int nData;          /* Number of bytes in the data */
+  char *pData;        /* The data associated with this key */
+  Sorter *pNext;      /* Next in the list */
+};
+
+/* 
+** Number of buckets used for merge-sort.  
+*/
+#define NSORT 30
+
+/*
+** Number of bytes of string storage space available to each stack
+** layer without having to malloc.  NBFS is short for Number of Bytes
+** For Strings.
+*/
+#define NBFS 32
+
+/*
+** A single level of the stack is an instance of the following
+** structure.  Except, string values are stored on a separate
+** list of of pointers to character.  The reason for storing
+** strings separately is so that they can be easily passed
+** to the callback function.
+*/
+struct Stack {
+  int i;         /* Integer value */
+  int n;         /* Number of characters in string value, including '\0' */
+  int flags;     /* Some combination of STK_Null, STK_Str, STK_Dyn, etc. */
+  double r;      /* Real value */
+  char z[NBFS];  /* Space for short strings */
+};
+typedef struct Stack Stack;
+
+/*
+** Memory cells use the same structure as the stack except that space
+** for an arbitrary string is added.
+*/
+struct Mem {
+  Stack s;       /* All values of the memory cell besides string */
+  char *z;       /* String value for this memory cell */
+};
+typedef struct Mem Mem;
+
+/*
+** Allowed values for Stack.flags
+*/
+#define STK_Null      0x0001   /* Value is NULL */
+#define STK_Str       0x0002   /* Value is a string */
+#define STK_Int       0x0004   /* Value is an integer */
+#define STK_Real      0x0008   /* Value is a real number */
+#define STK_Dyn       0x0010   /* Need to call sqliteFree() on zStack[] */
+#define STK_Static    0x0020   /* zStack[] points to a static string */
+#define STK_Ephem     0x0040   /* zStack[] points to an ephemeral string */
+
+/* The following STK_ value appears only in AggElem.aMem.s.flag fields.
+** It indicates that the corresponding AggElem.aMem.z points to a
+** aggregate function context that needs to be finalized.
+*/
+#define STK_AggCtx    0x0040   /* zStack[] points to an agg function context */
+
+/*
+** The "context" argument for a installable function.  A pointer to an
+** instance of this structure is the first argument to the routines used
+** implement the SQL functions.
+**
+** There is a typedef for this structure in sqlite.h.  So all routines,
+** even the public interface to SQLite, can use a pointer to this structure.
+** But this file is the only place where the internal details of this
+** structure are known.
+**
+** This structure is defined inside of vdbe.c because it uses substructures
+** (Stack) which are only defined there.
+*/
+struct sqlite_func {
+  FuncDef *pFunc;   /* Pointer to function information.  MUST BE FIRST */
+  Stack s;          /* Small strings, ints, and double values go here */
+  char *z;          /* Space for holding dynamic string results */
+  void *pAgg;       /* Aggregate context */
+  u8 isError;       /* Set to true for an error */
+  u8 isStep;        /* Current in the step function */
+  int cnt;          /* Number of times that the step function has been called */
+};
+
+/*
+** An Agg structure describes an Aggregator.  Each Agg consists of
+** zero or more Aggregator elements (AggElem).  Each AggElem contains
+** a key and one or more values.  The values are used in processing
+** aggregate functions in a SELECT.  The key is used to implement
+** the GROUP BY clause of a select.
+*/
+typedef struct Agg Agg;
+typedef struct AggElem AggElem;
+struct Agg {
+  int nMem;            /* Number of values stored in each AggElem */
+  AggElem *pCurrent;   /* The AggElem currently in focus */
+  HashElem *pSearch;   /* The hash element for pCurrent */
+  Hash hash;           /* Hash table of all aggregate elements */
+  FuncDef **apFunc;    /* Information about aggregate functions */
+};
+struct AggElem {
+  char *zKey;          /* The key to this AggElem */
+  int nKey;            /* Number of bytes in the key, including '\0' at end */
+  Mem aMem[1];         /* The values for this AggElem */
+};
+
+/*
+** A Set structure is used for quick testing to see if a value
+** is part of a small set.  Sets are used to implement code like
+** this:
+**            x.y IN ('hi','hoo','hum')
+*/
+typedef struct Set Set;
+struct Set {
+  Hash hash;             /* A set is just a hash table */
+  HashElem *prev;        /* Previously accessed hash elemen */
+};
+
+/*
+** A Keylist is a bunch of keys into a table.  The keylist can
+** grow without bound.  The keylist stores the ROWIDs of database
+** records that need to be deleted or updated.
+*/
+typedef struct Keylist Keylist;
+struct Keylist {
+  int nKey;         /* Number of slots in aKey[] */
+  int nUsed;        /* Next unwritten slot in aKey[] */
+  int nRead;        /* Next unread slot in aKey[] */
+  Keylist *pNext;   /* Next block of keys */
+  int aKey[1];      /* One or more keys.  Extra space allocated as needed */
+};
+
+/*
+** An instance of the virtual machine.  This structure contains the complete
+** state of the virtual machine.
+**
+** The "sqlite_vm" structure pointer that is returned by sqlite_compile()
+** is really a pointer to an instance of this structure.
+*/
+struct Vdbe {
+  sqlite *db;         /* The whole database */
+  Vdbe *pPrev,*pNext; /* Linked list of VDBEs with the same Vdbe.db */
+  FILE *trace;        /* Write an execution trace here, if not NULL */
+  int nOp;            /* Number of instructions in the program */
+  int nOpAlloc;       /* Number of slots allocated for aOp[] */
+  Op *aOp;            /* Space to hold the virtual machine's program */
+  int nLabel;         /* Number of labels used */
+  int nLabelAlloc;    /* Number of slots allocated in aLabel[] */
+  int *aLabel;        /* Space to hold the labels */
+  int tos;            /* Index of top of stack */
+  Stack *aStack;      /* The operand stack, except string values */
+  char **zStack;      /* Text or binary values of the stack */
+  char **azColName;   /* Becomes the 4th parameter to callbacks */
+  int nCursor;        /* Number of slots in aCsr[] */
+  Cursor *aCsr;       /* One element of this array for each open cursor */
+  Sorter *pSort;      /* A linked list of objects to be sorted */
+  FILE *pFile;        /* At most one open file handler */
+  int nField;         /* Number of file fields */
+  char **azField;     /* Data for each file field */
+  int nVariable;          /* Number of entries in azVariable[] */
+  char **azVariable;      /* Values for the OP_Variable opcode */
+  char *zLine;            /* A single line from the input file */
+  int nLineAlloc;         /* Number of spaces allocated for zLine */
+  int magic;              /* Magic number for sanity checking */
+  int nMem;               /* Number of memory locations currently allocated */
+  Mem *aMem;              /* The memory locations */
+  Agg agg;                /* Aggregate information */
+  int nSet;               /* Number of sets allocated */
+  Set *aSet;              /* An array of sets */
+  int nCallback;          /* Number of callbacks invoked so far */
+  Keylist *pList;         /* A list of ROWIDs */
+  int keylistStackDepth;  /* The size of the "keylist" stack */
+  Keylist **keylistStack; /* The stack used by opcodes ListPush & ListPop */
+  int pc;                 /* The program counter */
+  int rc;                 /* Value to return */
+  unsigned uniqueCnt;     /* Used by OP_MakeRecord when P2!=0 */
+  int errorAction;        /* Recovery action to do in case of an error */
+  int undoTransOnError;   /* If error, either ROLLBACK or COMMIT */
+  int inTempTrans;        /* True if temp database is transactioned */
+  int returnStack[100];   /* Return address stack for OP_Gosub & OP_Return */
+  int returnDepth;        /* Next unused element in returnStack[] */
+  int nResColumn;         /* Number of columns in one row of the result set */
+  char **azResColumn;                        /* Values for one row of result */ 
+  int (*xCallback)(void*,int,char**,char**); /* Callback for SELECT results */
+  void *pCbArg;                              /* First argument to xCallback() */
+  int popStack;           /* Pop the stack this much on entry to VdbeExec() */
+  char *zErrMsg;          /* Error message written here */
+  u8 explain;             /* True if EXPLAIN present on SQL command */
+};
+
+/*
+** The following are allowed values for Vdbe.magic
+*/
+#define VDBE_MAGIC_INIT     0x26bceaa5    /* Building a VDBE program */
+#define VDBE_MAGIC_RUN      0xbdf20da3    /* VDBE is ready to execute */
+#define VDBE_MAGIC_HALT     0x519c2973    /* VDBE has completed execution */
+#define VDBE_MAGIC_DEAD     0xb606c3c8    /* The VDBE has been deallocated */
+
+/*
+** Here is a macro to handle the common case of popping the stack
+** once.  This macro only works from within the sqliteVdbeExec()
+** function.
+*/
+#define POPSTACK \
+  assert(p->tos>=0); \
+  if( aStack[p->tos].flags & STK_Dyn ) sqliteFree(zStack[p->tos]); \
+  p->tos--;
+
+/*
+** Function prototypes
+*/
+void sqliteVdbeCleanupCursor(Cursor*);
+void sqliteVdbeSorterReset(Vdbe*);
+void sqliteVdbeAggReset(Agg*);
+void sqliteVdbeKeylistFree(Keylist*);
+void sqliteVdbePopStack(Vdbe*,int);
+#if !defined(NDEBUG) || defined(VDBE_PROFILE)
+void sqliteVdbePrintOp(FILE*, int, Op*);
+#endif
diff --git a/src/vdbeaux.c b/src/vdbeaux.c
new file mode 100644 (file)
index 0000000..9fedb8d
--- /dev/null
@@ -0,0 +1,996 @@
+/*
+** 2003 September 6
+**
+** The author disclaims copyright to this source code.  In place of
+** a legal notice, here is a blessing:
+**
+**    May you do good and not evil.
+**    May you find forgiveness for yourself and forgive others.
+**    May you share freely, never taking more than you give.
+**
+*************************************************************************
+** This file contains code used for creating, destroying, and populating
+** a VDBE (or an "sqlite_vm" as it is known to the outside world.)  Prior
+** to version 2.8.7, all this code was combined into the vdbe.c source file.
+** But that file was getting too big so this subroutines were split out.
+*/
+#include "sqliteInt.h"
+#include "os.h"
+#include <ctype.h>
+#include "vdbeInt.h"
+
+
+/*
+** When debugging the code generator in a symbolic debugger, one can
+** set the sqlite_vdbe_addop_trace to 1 and all opcodes will be printed
+** as they are added to the instruction stream.
+*/
+#ifndef NDEBUG
+int sqlite_vdbe_addop_trace = 0;
+#endif
+
+
+/*
+** Create a new virtual database engine.
+*/
+Vdbe *sqliteVdbeCreate(sqlite *db){
+  Vdbe *p;
+  p = sqliteMalloc( sizeof(Vdbe) );
+  if( p==0 ) return 0;
+  p->db = db;
+  if( db->pVdbe ){
+    db->pVdbe->pPrev = p;
+  }
+  p->pNext = db->pVdbe;
+  p->pPrev = 0;
+  db->pVdbe = p;
+  p->magic = VDBE_MAGIC_INIT;
+  return p;
+}
+
+/*
+** Turn tracing on or off
+*/
+void sqliteVdbeTrace(Vdbe *p, FILE *trace){
+  p->trace = trace;
+}
+
+/*
+** Add a new instruction to the list of instructions current in the
+** VDBE.  Return the address of the new instruction.
+**
+** Parameters:
+**
+**    p               Pointer to the VDBE
+**
+**    op              The opcode for this instruction
+**
+**    p1, p2          First two of the three possible operands.
+**
+** Use the sqliteVdbeResolveLabel() function to fix an address and
+** the sqliteVdbeChangeP3() function to change the value of the P3
+** operand.
+*/
+int sqliteVdbeAddOp(Vdbe *p, int op, int p1, int p2){
+  int i;
+
+  i = p->nOp;
+  p->nOp++;
+  assert( p->magic==VDBE_MAGIC_INIT );
+  if( i>=p->nOpAlloc ){
+    int oldSize = p->nOpAlloc;
+    Op *aNew;
+    p->nOpAlloc = p->nOpAlloc*2 + 100;
+    aNew = sqliteRealloc(p->aOp, p->nOpAlloc*sizeof(Op));
+    if( aNew==0 ){
+      p->nOpAlloc = oldSize;
+      return 0;
+    }
+    p->aOp = aNew;
+    memset(&p->aOp[oldSize], 0, (p->nOpAlloc-oldSize)*sizeof(Op));
+  }
+  p->aOp[i].opcode = op;
+  p->aOp[i].p1 = p1;
+  if( p2<0 && (-1-p2)<p->nLabel && p->aLabel[-1-p2]>=0 ){
+    p2 = p->aLabel[-1-p2];
+  }
+  p->aOp[i].p2 = p2;
+  p->aOp[i].p3 = 0;
+  p->aOp[i].p3type = P3_NOTUSED;
+#ifndef NDEBUG
+  if( sqlite_vdbe_addop_trace ) sqliteVdbePrintOp(0, i, &p->aOp[i]);
+#endif
+  return i;
+}
+
+/*
+** Create a new symbolic label for an instruction that has yet to be
+** coded.  The symbolic label is really just a negative number.  The
+** label can be used as the P2 value of an operation.  Later, when
+** the label is resolved to a specific address, the VDBE will scan
+** through its operation list and change all values of P2 which match
+** the label into the resolved address.
+**
+** The VDBE knows that a P2 value is a label because labels are
+** always negative and P2 values are suppose to be non-negative.
+** Hence, a negative P2 value is a label that has yet to be resolved.
+*/
+int sqliteVdbeMakeLabel(Vdbe *p){
+  int i;
+  i = p->nLabel++;
+  assert( p->magic==VDBE_MAGIC_INIT );
+  if( i>=p->nLabelAlloc ){
+    int *aNew;
+    p->nLabelAlloc = p->nLabelAlloc*2 + 10;
+    aNew = sqliteRealloc( p->aLabel, p->nLabelAlloc*sizeof(p->aLabel[0]));
+    if( aNew==0 ){
+      sqliteFree(p->aLabel);
+    }
+    p->aLabel = aNew;
+  }
+  if( p->aLabel==0 ){
+    p->nLabel = 0;
+    p->nLabelAlloc = 0;
+    return 0;
+  }
+  p->aLabel[i] = -1;
+  return -1-i;
+}
+
+/*
+** Resolve label "x" to be the address of the next instruction to
+** be inserted.  The parameter "x" must have been obtained from
+** a prior call to sqliteVdbeMakeLabel().
+*/
+void sqliteVdbeResolveLabel(Vdbe *p, int x){
+  int j;
+  assert( p->magic==VDBE_MAGIC_INIT );
+  if( x<0 && (-x)<=p->nLabel && p->aOp ){
+    if( p->aLabel[-1-x]==p->nOp ) return;
+    assert( p->aLabel[-1-x]<0 );
+    p->aLabel[-1-x] = p->nOp;
+    for(j=0; j<p->nOp; j++){
+      if( p->aOp[j].p2==x ) p->aOp[j].p2 = p->nOp;
+    }
+  }
+}
+
+/*
+** Return the address of the next instruction to be inserted.
+*/
+int sqliteVdbeCurrentAddr(Vdbe *p){
+  assert( p->magic==VDBE_MAGIC_INIT );
+  return p->nOp;
+}
+
+/*
+** Add a whole list of operations to the operation stack.  Return the
+** address of the first operation added.
+*/
+int sqliteVdbeAddOpList(Vdbe *p, int nOp, VdbeOp const *aOp){
+  int addr;
+  assert( p->magic==VDBE_MAGIC_INIT );
+  if( p->nOp + nOp >= p->nOpAlloc ){
+    int oldSize = p->nOpAlloc;
+    Op *aNew;
+    p->nOpAlloc = p->nOpAlloc*2 + nOp + 10;
+    aNew = sqliteRealloc(p->aOp, p->nOpAlloc*sizeof(Op));
+    if( aNew==0 ){
+      p->nOpAlloc = oldSize;
+      return 0;
+    }
+    p->aOp = aNew;
+    memset(&p->aOp[oldSize], 0, (p->nOpAlloc-oldSize)*sizeof(Op));
+  }
+  addr = p->nOp;
+  if( nOp>0 ){
+    int i;
+    for(i=0; i<nOp; i++){
+      int p2 = aOp[i].p2;
+      p->aOp[i+addr] = aOp[i];
+      if( p2<0 ) p->aOp[i+addr].p2 = addr + ADDR(p2);
+      p->aOp[i+addr].p3type = aOp[i].p3 ? P3_STATIC : P3_NOTUSED;
+#ifndef NDEBUG
+      if( sqlite_vdbe_addop_trace ){
+        sqliteVdbePrintOp(0, i+addr, &p->aOp[i+addr]);
+      }
+#endif
+    }
+    p->nOp += nOp;
+  }
+  return addr;
+}
+
+/*
+** Change the value of the P1 operand for a specific instruction.
+** This routine is useful when a large program is loaded from a
+** static array using sqliteVdbeAddOpList but we want to make a
+** few minor changes to the program.
+*/
+void sqliteVdbeChangeP1(Vdbe *p, int addr, int val){
+  assert( p->magic==VDBE_MAGIC_INIT );
+  if( p && addr>=0 && p->nOp>addr && p->aOp ){
+    p->aOp[addr].p1 = val;
+  }
+}
+
+/*
+** Change the value of the P2 operand for a specific instruction.
+** This routine is useful for setting a jump destination.
+*/
+void sqliteVdbeChangeP2(Vdbe *p, int addr, int val){
+  assert( val>=0 );
+  assert( p->magic==VDBE_MAGIC_INIT );
+  if( p && addr>=0 && p->nOp>addr && p->aOp ){
+    p->aOp[addr].p2 = val;
+  }
+}
+
+/*
+** Change the value of the P3 operand for a specific instruction.
+** This routine is useful when a large program is loaded from a
+** static array using sqliteVdbeAddOpList but we want to make a
+** few minor changes to the program.
+**
+** If n>=0 then the P3 operand is dynamic, meaning that a copy of
+** the string is made into memory obtained from sqliteMalloc().
+** A value of n==0 means copy bytes of zP3 up to and including the
+** first null byte.  If n>0 then copy n+1 bytes of zP3.
+**
+** If n==P3_STATIC  it means that zP3 is a pointer to a constant static
+** string and we can just copy the pointer.  n==P3_POINTER means zP3 is
+** a pointer to some object other than a string.
+**
+** If addr<0 then change P3 on the most recently inserted instruction.
+*/
+void sqliteVdbeChangeP3(Vdbe *p, int addr, const char *zP3, int n){
+  Op *pOp;
+  assert( p->magic==VDBE_MAGIC_INIT );
+  if( p==0 || p->aOp==0 ) return;
+  if( addr<0 || addr>=p->nOp ){
+    addr = p->nOp - 1;
+    if( addr<0 ) return;
+  }
+  pOp = &p->aOp[addr];
+  if( pOp->p3 && pOp->p3type==P3_DYNAMIC ){
+    sqliteFree(pOp->p3);
+    pOp->p3 = 0;
+  }
+  if( zP3==0 ){
+    pOp->p3 = 0;
+    pOp->p3type = P3_NOTUSED;
+  }else if( n<0 ){
+    pOp->p3 = (char*)zP3;
+    pOp->p3type = n;
+  }else{
+    sqliteSetNString(&pOp->p3, zP3, n, 0);
+    pOp->p3type = P3_DYNAMIC;
+  }
+}
+
+/*
+** If the P3 operand to the specified instruction appears
+** to be a quoted string token, then this procedure removes 
+** the quotes.
+**
+** The quoting operator can be either a grave ascent (ASCII 0x27)
+** or a double quote character (ASCII 0x22).  Two quotes in a row
+** resolve to be a single actual quote character within the string.
+*/
+void sqliteVdbeDequoteP3(Vdbe *p, int addr){
+  Op *pOp;
+  assert( p->magic==VDBE_MAGIC_INIT );
+  if( p->aOp==0 || addr<0 || addr>=p->nOp ) return;
+  pOp = &p->aOp[addr];
+  if( pOp->p3==0 || pOp->p3[0]==0 ) return;
+  if( pOp->p3type==P3_POINTER ) return;
+  if( pOp->p3type!=P3_DYNAMIC ){
+    pOp->p3 = sqliteStrDup(pOp->p3);
+    pOp->p3type = P3_DYNAMIC;
+  }
+  sqliteDequote(pOp->p3);
+}
+
+/*
+** On the P3 argument of the given instruction, change all
+** strings of whitespace characters into a single space and
+** delete leading and trailing whitespace.
+*/
+void sqliteVdbeCompressSpace(Vdbe *p, int addr){
+  unsigned char *z;
+  int i, j;
+  Op *pOp;
+  assert( p->magic==VDBE_MAGIC_INIT );
+  if( p->aOp==0 || addr<0 || addr>=p->nOp ) return;
+  pOp = &p->aOp[addr];
+  if( pOp->p3type==P3_POINTER ){
+    return;
+  }
+  if( pOp->p3type!=P3_DYNAMIC ){
+    pOp->p3 = sqliteStrDup(pOp->p3);
+    pOp->p3type = P3_DYNAMIC;
+  }
+  z = (unsigned char*)pOp->p3;
+  if( z==0 ) return;
+  i = j = 0;
+  while( isspace(z[i]) ){ i++; }
+  while( z[i] ){
+    if( isspace(z[i]) ){
+      z[j++] = ' ';
+      while( isspace(z[++i]) ){}
+    }else{
+      z[j++] = z[i++];
+    }
+  }
+  while( j>0 && isspace(z[j-1]) ){ j--; }
+  z[j] = 0;
+}
+
+/*
+** Search for the current program for the given opcode and P2
+** value.  Return the address plus 1 if found and 0 if not found.
+*/
+int sqliteVdbeFindOp(Vdbe *p, int op, int p2){
+  int i;
+  assert( p->magic==VDBE_MAGIC_INIT );
+  for(i=0; i<p->nOp; i++){
+    if( p->aOp[i].opcode==op && p->aOp[i].p2==p2 ) return i+1;
+  }
+  return 0;
+}
+
+/*
+** Return the opcode for a given address.
+*/
+VdbeOp *sqliteVdbeGetOp(Vdbe *p, int addr){
+  assert( p->magic==VDBE_MAGIC_INIT );
+  assert( addr>=0 && addr<p->nOp );
+  return &p->aOp[addr];
+}
+
+/*
+** The following group or routines are employed by installable functions
+** to return their results.
+**
+** The sqlite_set_result_string() routine can be used to return a string
+** value or to return a NULL.  To return a NULL, pass in NULL for zResult.
+** A copy is made of the string before this routine returns so it is safe
+** to pass in an ephemeral string.
+**
+** sqlite_set_result_error() works like sqlite_set_result_string() except
+** that it signals a fatal error.  The string argument, if any, is the
+** error message.  If the argument is NULL a generic substitute error message
+** is used.
+**
+** The sqlite_set_result_int() and sqlite_set_result_double() set the return
+** value of the user function to an integer or a double.
+**
+** These routines are defined here in vdbe.c because they depend on knowing
+** the internals of the sqlite_func structure which is only defined in 
+** this source file.
+*/
+char *sqlite_set_result_string(sqlite_func *p, const char *zResult, int n){
+  assert( !p->isStep );
+  if( p->s.flags & STK_Dyn ){
+    sqliteFree(p->z);
+  }
+  if( zResult==0 ){
+    p->s.flags = STK_Null;
+    n = 0;
+    p->z = 0;
+    p->s.n = 0;
+  }else{
+    if( n<0 ) n = strlen(zResult);
+    if( n<NBFS-1 ){
+      memcpy(p->s.z, zResult, n);
+      p->s.z[n] = 0;
+      p->s.flags = STK_Str;
+      p->z = p->s.z;
+    }else{
+      p->z = sqliteMallocRaw( n+1 );
+      if( p->z ){
+        memcpy(p->z, zResult, n);
+        p->z[n] = 0;
+      }
+      p->s.flags = STK_Str | STK_Dyn;
+    }
+    p->s.n = n+1;
+  }
+  return p->z;
+}
+void sqlite_set_result_int(sqlite_func *p, int iResult){
+  assert( !p->isStep );
+  if( p->s.flags & STK_Dyn ){
+    sqliteFree(p->z);
+  }
+  p->s.i = iResult;
+  p->s.flags = STK_Int;
+}
+void sqlite_set_result_double(sqlite_func *p, double rResult){
+  assert( !p->isStep );
+  if( p->s.flags & STK_Dyn ){
+    sqliteFree(p->z);
+  }
+  p->s.r = rResult;
+  p->s.flags = STK_Real;
+}
+void sqlite_set_result_error(sqlite_func *p, const char *zMsg, int n){
+  assert( !p->isStep );
+  sqlite_set_result_string(p, zMsg, n);
+  p->isError = 1;
+}
+
+/*
+** Extract the user data from a sqlite_func structure and return a
+** pointer to it.
+**
+** This routine is defined here in vdbe.c because it depends on knowing
+** the internals of the sqlite_func structure which is only defined in 
+** this source file.
+*/
+void *sqlite_user_data(sqlite_func *p){
+  assert( p && p->pFunc );
+  return p->pFunc->pUserData;
+}
+
+/*
+** Allocate or return the aggregate context for a user function.  A new
+** context is allocated on the first call.  Subsequent calls return the
+** same context that was returned on prior calls.
+**
+** This routine is defined here in vdbe.c because it depends on knowing
+** the internals of the sqlite_func structure which is only defined in
+** this source file.
+*/
+void *sqlite_aggregate_context(sqlite_func *p, int nByte){
+  assert( p && p->pFunc && p->pFunc->xStep );
+  if( p->pAgg==0 ){
+    if( nByte<=NBFS ){
+      p->pAgg = (void*)p->z;
+    }else{
+      p->pAgg = sqliteMalloc( nByte );
+    }
+  }
+  return p->pAgg;
+}
+
+/*
+** Return the number of times the Step function of a aggregate has been 
+** called.
+**
+** This routine is defined here in vdbe.c because it depends on knowing
+** the internals of the sqlite_func structure which is only defined in
+** this source file.
+*/
+int sqlite_aggregate_count(sqlite_func *p){
+  assert( p && p->pFunc && p->pFunc->xStep );
+  return p->cnt;
+}
+
+#if !defined(NDEBUG) || defined(VDBE_PROFILE)
+/*
+** Print a single opcode.  This routine is used for debugging only.
+*/
+void sqliteVdbePrintOp(FILE *pOut, int pc, Op *pOp){
+  char *zP3;
+  char zPtr[40];
+  if( pOp->p3type==P3_POINTER ){
+    sprintf(zPtr, "ptr(%#x)", (int)pOp->p3);
+    zP3 = zPtr;
+  }else{
+    zP3 = pOp->p3;
+  }
+  if( pOut==0 ) pOut = stdout;
+  fprintf(pOut,"%4d %-12s %4d %4d %s\n",
+      pc, sqliteOpcodeNames[pOp->opcode], pOp->p1, pOp->p2, zP3 ? zP3 : "");
+  fflush(pOut);
+}
+#endif
+
+/*
+** Give a listing of the program in the virtual machine.
+**
+** The interface is the same as sqliteVdbeExec().  But instead of
+** running the code, it invokes the callback once for each instruction.
+** This feature is used to implement "EXPLAIN".
+*/
+int sqliteVdbeList(
+  Vdbe *p                   /* The VDBE */
+){
+  sqlite *db = p->db;
+  int i;
+  static char *azColumnNames[] = {
+     "addr", "opcode", "p1",  "p2",  "p3", 
+     "int",  "text",   "int", "int", "text",
+     0
+  };
+
+  assert( p->popStack==0 );
+  assert( p->explain );
+  p->azColName = azColumnNames;
+  p->azResColumn = p->zStack;
+  for(i=0; i<5; i++) p->zStack[i] = p->aStack[i].z;
+  p->rc = SQLITE_OK;
+  for(i=p->pc; p->rc==SQLITE_OK && i<p->nOp; i++){
+    if( db->flags & SQLITE_Interrupt ){
+      db->flags &= ~SQLITE_Interrupt;
+      if( db->magic!=SQLITE_MAGIC_BUSY ){
+        p->rc = SQLITE_MISUSE;
+      }else{
+        p->rc = SQLITE_INTERRUPT;
+      }
+      sqliteSetString(&p->zErrMsg, sqlite_error_string(p->rc), 0);
+      break;
+    }
+    sprintf(p->zStack[0],"%d",i);
+    sprintf(p->zStack[2],"%d", p->aOp[i].p1);
+    sprintf(p->zStack[3],"%d", p->aOp[i].p2);
+    if( p->aOp[i].p3type==P3_POINTER ){
+      sprintf(p->aStack[4].z, "ptr(%#x)", (int)p->aOp[i].p3);
+      p->zStack[4] = p->aStack[4].z;
+    }else{
+      p->zStack[4] = p->aOp[i].p3;
+    }
+    p->zStack[1] = sqliteOpcodeNames[p->aOp[i].opcode];
+    if( p->xCallback==0 ){
+      p->pc = i+1;
+      p->azResColumn = p->zStack;
+      p->nResColumn = 5;
+      return SQLITE_ROW;
+    }
+    if( sqliteSafetyOff(db) ){
+      p->rc = SQLITE_MISUSE;
+      break;
+    }
+    if( p->xCallback(p->pCbArg, 5, p->zStack, p->azColName) ){
+      p->rc = SQLITE_ABORT;
+    }
+    if( sqliteSafetyOn(db) ){
+      p->rc = SQLITE_MISUSE;
+    }
+  }
+  return p->rc==SQLITE_OK ? SQLITE_DONE : SQLITE_ERROR;
+}
+
+/*
+** Prepare a virtual machine for execution.  This involves things such
+** as allocating stack space and initializing the program counter.
+** After the VDBE has be prepped, it can be executed by one or more
+** calls to sqliteVdbeExec().  
+**
+** The behavior of sqliteVdbeExec() is influenced by the parameters to
+** this routine.  If xCallback is NULL, then sqliteVdbeExec() will return
+** with SQLITE_ROW whenever there is a row of the result set ready
+** to be delivered.  p->azResColumn will point to the row and 
+** p->nResColumn gives the number of columns in the row.  If xCallback
+** is not NULL, then the xCallback() routine is invoked to process each
+** row in the result set.
+*/
+void sqliteVdbeMakeReady(
+  Vdbe *p,                       /* The VDBE */
+  sqlite_callback xCallback,     /* Result callback */
+  void *pCallbackArg,            /* 1st argument to xCallback() */
+  int isExplain                  /* True if the EXPLAIN keywords is present */
+){
+  int n;
+
+  assert( p!=0 );
+  assert( p->aStack==0 );
+  assert( p->magic==VDBE_MAGIC_INIT );
+
+  /* Add a HALT instruction to the very end of the program.
+  */
+  if( p->nOp==0 || (p->aOp && p->aOp[p->nOp-1].opcode!=OP_Halt) ){
+    sqliteVdbeAddOp(p, OP_Halt, 0, 0);
+  }
+
+  /* No instruction ever pushes more than a single element onto the
+  ** stack.  And the stack never grows on successive executions of the
+  ** same loop.  So the total number of instructions is an upper bound
+  ** on the maximum stack depth required.
+  **
+  ** Allocation all the stack space we will ever need.
+  */
+  n = isExplain ? 10 : p->nOp;
+  p->aStack = sqliteMalloc( n*(sizeof(p->aStack[0]) + 2*sizeof(char*)) );
+  p->zStack = (char**)&p->aStack[n];
+  p->azColName = (char**)&p->zStack[n];
+
+  sqliteHashInit(&p->agg.hash, SQLITE_HASH_BINARY, 0);
+  p->agg.pSearch = 0;
+#ifdef MEMORY_DEBUG
+  if( sqliteOsFileExists("vdbe_trace") ){
+    p->trace = stdout;
+  }
+#endif
+  p->tos = -1;
+  p->pc = 0;
+  p->rc = SQLITE_OK;
+  p->uniqueCnt = 0;
+  p->returnDepth = 0;
+  p->errorAction = OE_Abort;
+  p->undoTransOnError = 0;
+  p->xCallback = xCallback;
+  p->pCbArg = pCallbackArg;
+  p->popStack =  0;
+  p->explain |= isExplain;
+  p->magic = VDBE_MAGIC_RUN;
+#ifdef VDBE_PROFILE
+  for(i=0; i<p->nOp; i++){
+    p->aOp[i].cnt = 0;
+    p->aOp[i].cycles = 0;
+  }
+#endif
+}
+
+
+/*
+** Remove any elements that remain on the sorter for the VDBE given.
+*/
+void sqliteVdbeSorterReset(Vdbe *p){
+  while( p->pSort ){
+    Sorter *pSorter = p->pSort;
+    p->pSort = pSorter->pNext;
+    sqliteFree(pSorter->zKey);
+    sqliteFree(pSorter->pData);
+    sqliteFree(pSorter);
+  }
+}
+
+/*
+** Pop the stack N times.  Free any memory associated with the
+** popped stack elements.
+*/
+void sqliteVdbePopStack(Vdbe *p, int N){
+  assert( N>=0 );
+  if( p->zStack==0 ) return;
+  assert( p->aStack || sqlite_malloc_failed );
+  if( p->aStack==0 ) return;
+  while( N-- > 0 ){
+    if( p->aStack[p->tos].flags & STK_Dyn ){
+      sqliteFree(p->zStack[p->tos]);
+    }
+    p->aStack[p->tos].flags = 0;
+    p->zStack[p->tos] = 0;
+    p->tos--;
+  }
+}
+
+/*
+** Reset an Agg structure.  Delete all its contents. 
+**
+** For installable aggregate functions, if the step function has been
+** called, make sure the finalizer function has also been called.  The
+** finalizer might need to free memory that was allocated as part of its
+** private context.  If the finalizer has not been called yet, call it
+** now.
+*/
+void sqliteVdbeAggReset(Agg *pAgg){
+  int i;
+  HashElem *p;
+  for(p = sqliteHashFirst(&pAgg->hash); p; p = sqliteHashNext(p)){
+    AggElem *pElem = sqliteHashData(p);
+    assert( pAgg->apFunc!=0 );
+    for(i=0; i<pAgg->nMem; i++){
+      Mem *pMem = &pElem->aMem[i];
+      if( pAgg->apFunc[i] && (pMem->s.flags & STK_AggCtx)!=0 ){
+        sqlite_func ctx;
+        ctx.pFunc = pAgg->apFunc[i];
+        ctx.s.flags = STK_Null;
+        ctx.z = 0;
+        ctx.pAgg = pMem->z;
+        ctx.cnt = pMem->s.i;
+        ctx.isStep = 0;
+        ctx.isError = 0;
+        (*pAgg->apFunc[i]->xFinalize)(&ctx);
+        if( pMem->z!=0 && pMem->z!=pMem->s.z ){
+          sqliteFree(pMem->z);
+        }
+      }else if( pMem->s.flags & STK_Dyn ){
+        sqliteFree(pMem->z);
+      }
+    }
+    sqliteFree(pElem);
+  }
+  sqliteHashClear(&pAgg->hash);
+  sqliteFree(pAgg->apFunc);
+  pAgg->apFunc = 0;
+  pAgg->pCurrent = 0;
+  pAgg->pSearch = 0;
+  pAgg->nMem = 0;
+}
+
+/*
+** Delete a keylist
+*/
+void sqliteVdbeKeylistFree(Keylist *p){
+  while( p ){
+    Keylist *pNext = p->pNext;
+    sqliteFree(p);
+    p = pNext;
+  }
+}
+
+/*
+** Close a cursor and release all the resources that cursor happens
+** to hold.
+*/
+void sqliteVdbeCleanupCursor(Cursor *pCx){
+  if( pCx->pCursor ){
+    sqliteBtreeCloseCursor(pCx->pCursor);
+  }
+  if( pCx->pBt ){
+    sqliteBtreeClose(pCx->pBt);
+  }
+  sqliteFree(pCx->pData);
+  memset(pCx, 0, sizeof(Cursor));
+}
+
+/*
+** Close all cursors
+*/
+static void closeAllCursors(Vdbe *p){
+  int i;
+  for(i=0; i<p->nCursor; i++){
+    sqliteVdbeCleanupCursor(&p->aCsr[i]);
+  }
+  sqliteFree(p->aCsr);
+  p->aCsr = 0;
+  p->nCursor = 0;
+}
+
+/*
+** Delete the variables in p->azVariable[]
+*/
+static void ClearVariableArray(Vdbe *p){
+  sqliteFree(p->azVariable);
+  p->nVariable = 0;
+  p->azVariable = 0;
+}
+
+/*
+** Clean up the VM after execution.
+**
+** This routine will automatically close any cursors, lists, and/or
+** sorters that were left open.  It also deletes the values of
+** variables in the azVariable[] array.
+*/
+static void Cleanup(Vdbe *p){
+  int i;
+  sqliteVdbePopStack(p, p->tos+1);
+  closeAllCursors(p);
+  if( p->aMem ){
+    for(i=0; i<p->nMem; i++){
+      if( p->aMem[i].s.flags & STK_Dyn ){
+        sqliteFree(p->aMem[i].z);
+      }
+    }
+  }
+  sqliteFree(p->aMem);
+  p->aMem = 0;
+  p->nMem = 0;
+  if( p->pList ){
+    sqliteVdbeKeylistFree(p->pList);
+    p->pList = 0;
+  }
+  sqliteVdbeSorterReset(p);
+  if( p->pFile ){
+    if( p->pFile!=stdin ) fclose(p->pFile);
+    p->pFile = 0;
+  }
+  if( p->azField ){
+    sqliteFree(p->azField);
+    p->azField = 0;
+  }
+  p->nField = 0;
+  if( p->zLine ){
+    sqliteFree(p->zLine);
+    p->zLine = 0;
+  }
+  p->nLineAlloc = 0;
+  sqliteVdbeAggReset(&p->agg);
+  if( p->aSet ){
+    for(i=0; i<p->nSet; i++){
+      sqliteHashClear(&p->aSet[i].hash);
+    }
+  }
+  sqliteFree(p->aSet);
+  p->aSet = 0;
+  p->nSet = 0;
+  if( p->keylistStack ){
+    int ii;
+    for(ii = 0; ii < p->keylistStackDepth; ii++){
+      sqliteVdbeKeylistFree(p->keylistStack[ii]);
+    }
+    sqliteFree(p->keylistStack);
+    p->keylistStackDepth = 0;
+    p->keylistStack = 0;
+  }
+  sqliteFree(p->zErrMsg);
+  p->zErrMsg = 0;
+  ClearVariableArray(p);
+}
+
+/*
+** Clean up a VDBE after execution but do not delete the VDBE just yet.
+** Write any error messages into *pzErrMsg.  Return the result code.
+**
+** After this routine is run, the VDBE should be ready to be executed
+** again.
+*/
+int sqliteVdbeReset(Vdbe *p, char **pzErrMsg){
+  sqlite *db = p->db;
+  int i;
+
+  if( p->magic!=VDBE_MAGIC_RUN && p->magic!=VDBE_MAGIC_HALT ){
+    sqliteSetString(pzErrMsg, sqlite_error_string(SQLITE_MISUSE), 0);
+    return SQLITE_MISUSE;
+  }
+  if( p->zErrMsg ){
+    if( pzErrMsg && *pzErrMsg==0 ){
+      *pzErrMsg = p->zErrMsg;
+    }else{
+      sqliteFree(p->zErrMsg);
+    }
+    p->zErrMsg = 0;
+  }
+  Cleanup(p);
+  if( p->rc!=SQLITE_OK ){
+    switch( p->errorAction ){
+      case OE_Abort: {
+        if( !p->undoTransOnError ){
+          for(i=0; i<db->nDb; i++){
+            if( db->aDb[i].pBt ){
+              sqliteBtreeRollbackCkpt(db->aDb[i].pBt);
+            }
+          }
+          break;
+        }
+        /* Fall through to ROLLBACK */
+      }
+      case OE_Rollback: {
+        sqliteRollbackAll(db);
+        db->flags &= ~SQLITE_InTrans;
+        db->onError = OE_Default;
+        break;
+      }
+      default: {
+        if( p->undoTransOnError ){
+          sqliteRollbackAll(db);
+          db->flags &= ~SQLITE_InTrans;
+          db->onError = OE_Default;
+        }
+        break;
+      }
+    }
+    sqliteRollbackInternalChanges(db);
+  }
+  for(i=0; i<db->nDb; i++){
+    if( db->aDb[i].pBt && db->aDb[i].inTrans==2 ){
+      sqliteBtreeCommitCkpt(db->aDb[i].pBt);
+      db->aDb[i].inTrans = 1;
+    }
+  }
+  assert( p->tos<p->pc || sqlite_malloc_failed==1 );
+#ifdef VDBE_PROFILE
+  {
+    FILE *out = fopen("vdbe_profile.out", "a");
+    if( out ){
+      int i;
+      fprintf(out, "---- ");
+      for(i=0; i<p->nOp; i++){
+        fprintf(out, "%02x", p->aOp[i].opcode);
+      }
+      fprintf(out, "\n");
+      for(i=0; i<p->nOp; i++){
+        fprintf(out, "%6d %10lld %8lld ",
+           p->aOp[i].cnt,
+           p->aOp[i].cycles,
+           p->aOp[i].cnt>0 ? p->aOp[i].cycles/p->aOp[i].cnt : 0
+        );
+        sqliteVdbePrintOp(out, i, &p->aOp[i]);
+      }
+      fclose(out);
+    }
+  }
+#endif
+  p->magic = VDBE_MAGIC_INIT;
+  return p->rc;
+}
+
+/*
+** Clean up and delete a VDBE after execution.  Return an integer which is
+** the result code.  Write any error message text into *pzErrMsg.
+*/
+int sqliteVdbeFinalize(Vdbe *p, char **pzErrMsg){
+  int rc;
+  sqlite *db;
+
+  if( p->magic!=VDBE_MAGIC_RUN && p->magic!=VDBE_MAGIC_HALT ){
+    sqliteSetString(pzErrMsg, sqlite_error_string(SQLITE_MISUSE), 0);
+    return SQLITE_MISUSE;
+  }
+  db = p->db;
+  rc = sqliteVdbeReset(p, pzErrMsg);
+  sqliteVdbeDelete(p);
+  if( db->want_to_close && db->pVdbe==0 ){
+    sqlite_close(db);
+  }
+  return rc;
+}
+
+/*
+** Set the values of all variables.  Variable $1 in the original SQL will
+** be the string azValue[0].  $2 will have the value azValue[1].  And
+** so forth.  If a value is out of range (for example $3 when nValue==2)
+** then its value will be NULL.
+**
+** This routine overrides any prior call.
+*/
+int sqliteVdbeSetVariables(Vdbe *p, int nValue, const char **azValue){
+  int i, n;
+  char *z;
+  if( p->magic!=VDBE_MAGIC_RUN || p->pc!=0 || p->nVariable!=0 ){
+    return SQLITE_MISUSE;
+  }
+  ClearVariableArray(p);
+  if( nValue==0 ){
+    p->nVariable = 0;
+    p->azVariable = 0;
+  }
+  for(i=n=0; i<nValue; i++){
+    if( azValue[i] ) n += strlen(azValue[i]) + 1;
+  }
+  p->azVariable = sqliteMalloc( sizeof(p->azVariable[0])*nValue + n );
+  if( p->azVariable==0 ){
+    p->nVariable = 0;
+    return SQLITE_NOMEM;
+  }
+  z = (char*)&p->azVariable[nValue];
+  for(i=0; i<nValue; i++){
+    if( azValue[i]==0 ){
+      p->azVariable[i] = 0;
+    }else{
+      p->azVariable[i] = z;
+      n = strlen(azValue[i]);
+      memcpy(z, azValue[i], n+1);
+      z += n+1;
+    }
+  }
+  p->nVariable = nValue;
+  return SQLITE_OK;
+}
+
+
+/*
+** Delete an entire VDBE.
+*/
+void sqliteVdbeDelete(Vdbe *p){
+  int i;
+  if( p==0 ) return;
+  Cleanup(p);
+  if( p->pPrev ){
+    p->pPrev->pNext = p->pNext;
+  }else{
+    assert( p->db->pVdbe==p );
+    p->db->pVdbe = p->pNext;
+  }
+  if( p->pNext ){
+    p->pNext->pPrev = p->pPrev;
+  }
+  p->pPrev = p->pNext = 0;
+  if( p->nOpAlloc==0 ){
+    p->aOp = 0;
+    p->nOp = 0;
+  }
+  for(i=0; i<p->nOp; i++){
+    if( p->aOp[i].p3type==P3_DYNAMIC ){
+      sqliteFree(p->aOp[i].p3);
+    }
+  }
+  sqliteFree(p->aOp);
+  sqliteFree(p->aLabel);
+  sqliteFree(p->aStack);
+  p->magic = VDBE_MAGIC_DEAD;
+  sqliteFree(p);
+}