Change the VdbeOp.p4 union to include specific pointer types for the various values of VdbeOp.p4type. (CVS 4667)

FossilOrigin-Name: 7e8330c8044dc7718e720dbd33f6e2fe970ead77
diff --git a/src/insert.c b/src/insert.c
index 871cb70..5ef9295 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.204 2008/01/03 09:51:55 danielk1977 Exp $
+** $Id: insert.c,v 1.205 2008/01/03 11:50:30 danielk1977 Exp $
 */
 #include "sqliteInt.h"
 
@@ -124,8 +124,8 @@
       }
     }
 #ifndef SQLITE_OMIT_VIRTUALTABLE
-    if( pOp->opcode==OP_VOpen && pOp->p4.p==(const char*)pTab->pVtab ){
-      assert( pOp->p4.p!=0 );
+    if( pOp->opcode==OP_VOpen && pOp->p4.pVtab==pTab->pVtab ){
+      assert( pOp->p4.pVtab!=0 );
       assert( pOp->p4type==P4_VTAB );
       return 1;
     }
diff --git a/src/sqliteInt.h b/src/sqliteInt.h
index 4537932..912a318 100644
--- a/src/sqliteInt.h
+++ b/src/sqliteInt.h
@@ -11,7 +11,7 @@
 *************************************************************************
 ** Internal interface definitions for SQLite.
 **
-** @(#) $Id: sqliteInt.h,v 1.632 2008/01/03 09:51:55 danielk1977 Exp $
+** @(#) $Id: sqliteInt.h,v 1.633 2008/01/03 11:50:30 danielk1977 Exp $
 */
 #ifndef _SQLITEINT_H_
 #define _SQLITEINT_H_
@@ -309,15 +309,6 @@
 };
 
 /*
-** Defer sourcing vdbe.h and btree.h until after the "u8" and 
-** "BusyHandler typedefs.
-*/
-#include "btree.h"
-#include "vdbe.h"
-#include "pager.h"
-
-
-/*
 ** Name of the master database table.  The master database table
 ** is a special table that holds the names and attributes of all
 ** user tables and indices.
@@ -373,6 +364,15 @@
 typedef struct WhereInfo WhereInfo;
 typedef struct WhereLevel WhereLevel;
 
+/*
+** Defer sourcing vdbe.h and btree.h until after the "u8" and 
+** "BusyHandler" typedefs. vdbe.h also requires a few of the opaque
+** pointer types (i.e. FuncDef) defined above.
+*/
+#include "btree.h"
+#include "vdbe.h"
+#include "pager.h"
+
 #include "os.h"
 #include "mutex.h"
 
diff --git a/src/vdbe.c b/src/vdbe.c
index c748b70..0ecee75 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.668 2008/01/03 09:51:55 danielk1977 Exp $
+** $Id: vdbe.c,v 1.669 2008/01/03 11:50:30 danielk1977 Exp $
 */
 #include "sqliteInt.h"
 #include <ctype.h>
@@ -679,8 +679,8 @@
   p->rc = pOp->p1;
   p->pc = pc;
   p->errorAction = pOp->p2;
-  if( pOp->p4.p ){
-    sqlite3SetString(&p->zErrMsg, pOp->p4.p, (char*)0);
+  if( pOp->p4.z ){
+    sqlite3SetString(&p->zErrMsg, pOp->p4.z, (char*)0);
   }
   rc = sqlite3VdbeHalt(p);
   assert( rc==SQLITE_BUSY || rc==SQLITE_OK );
@@ -733,9 +733,9 @@
 */
 case OP_Int64: {
   pTos++;
-  assert( pOp->p4.p!=0 );
+  assert( pOp->p4.pI64!=0 );
   pTos->flags = MEM_Int;
-  memcpy(&pTos->u.i, pOp->p4.p, 8);
+  memcpy(&pTos->u.i, pOp->p4.pI64, 8);
   break;
 }
 
@@ -747,7 +747,7 @@
 case OP_Real: {            /* same as TK_FLOAT, */
   pTos++;
   pTos->flags = MEM_Real;
-  memcpy(&pTos->r, pOp->p4.p, 8);
+  memcpy(&pTos->r, pOp->p4.pReal, 8);
   break;
 }
 
@@ -757,23 +757,23 @@
 ** into an OP_String before it is executed for the first time.
 */
 case OP_String8: {         /* same as TK_STRING */
-  assert( pOp->p4.p!=0 );
+  assert( pOp->p4.z!=0 );
   pOp->opcode = OP_String;
-  pOp->p1 = strlen(pOp->p4.p);
+  pOp->p1 = strlen(pOp->p4.z);
 
 #ifndef SQLITE_OMIT_UTF16
   if( encoding!=SQLITE_UTF8 ){
     pTos++;
-    sqlite3VdbeMemSetStr(pTos, pOp->p4.p, -1, SQLITE_UTF8, SQLITE_STATIC);
+    sqlite3VdbeMemSetStr(pTos, pOp->p4.z, -1, SQLITE_UTF8, SQLITE_STATIC);
     if( SQLITE_OK!=sqlite3VdbeChangeEncoding(pTos, encoding) ) goto no_mem;
     if( SQLITE_OK!=sqlite3VdbeMemDynamicify(pTos) ) goto no_mem;
     pTos->flags &= ~(MEM_Dyn);
     pTos->flags |= MEM_Static;
     if( pOp->p4type==P4_DYNAMIC ){
-      sqlite3_free(pOp->p4.p);
+      sqlite3_free(pOp->p4.z);
     }
     pOp->p4type = P4_DYNAMIC;
-    pOp->p4.p = pTos->z;
+    pOp->p4.z = pTos->z;
     pOp->p1 = pTos->n;
     if( pOp->p1>SQLITE_MAX_LENGTH ){
       goto too_big;
@@ -793,9 +793,9 @@
 */
 case OP_String: {
   pTos++;
-  assert( pOp->p4.p!=0 );
+  assert( pOp->p4.z!=0 );
   pTos->flags = MEM_Str|MEM_Static|MEM_Term;
-  pTos->z = pOp->p4.p;
+  pTos->z = pOp->p4.z;
   pTos->n = pOp->p1;
   pTos->enc = encoding;
   break;
@@ -824,24 +824,24 @@
 */
 case OP_HexBlob: {            /* same as TK_BLOB */
   pOp->opcode = OP_Blob;
-  pOp->p1 = strlen(pOp->p4.p)/2;
+  pOp->p1 = strlen(pOp->p4.z)/2;
   if( pOp->p1>SQLITE_MAX_LENGTH ){
     goto too_big;
   }
   if( pOp->p1 ){
-    char *zBlob = sqlite3HexToBlob(db, pOp->p4.p);
+    char *zBlob = sqlite3HexToBlob(db, pOp->p4.z);
     if( !zBlob ) goto no_mem;
     if( pOp->p4type==P4_DYNAMIC ){
-      sqlite3_free(pOp->p4.p);
+      sqlite3_free(pOp->p4.z);
     }
-    pOp->p4.p = zBlob;
+    pOp->p4.z = zBlob;
     pOp->p4type = P4_DYNAMIC;
   }else{
     if( pOp->p4type==P4_DYNAMIC ){
-      sqlite3_free(pOp->p4.p);
+      sqlite3_free(pOp->p4.z);
     }
     pOp->p4type = P4_STATIC;
-    pOp->p4.p = "";
+    pOp->p4.z = "";
   }
 
   /* Fall through to the next case, OP_Blob. */
@@ -859,7 +859,7 @@
 case OP_Blob: {
   pTos++;
   assert( pOp->p1 <= SQLITE_MAX_LENGTH );
-  sqlite3VdbeMemSetStr(pTos, pOp->p4.p, pOp->p1, 0, 0);
+  sqlite3VdbeMemSetStr(pTos, pOp->p4.z, pOp->p1, 0, 0);
   pTos->enc = encoding;
   break;
 }
@@ -1338,10 +1338,10 @@
 
   assert( pOp->p4type==P4_FUNCDEF || pOp->p4type==P4_VDBEFUNC );
   if( pOp->p4type==P4_FUNCDEF ){
-    ctx.pFunc = (FuncDef*)pOp->p4.p;
+    ctx.pFunc = pOp->p4.pFunc;
     ctx.pVdbeFunc = 0;
   }else{
-    ctx.pVdbeFunc = (VdbeFunc*)pOp->p4.p;
+    ctx.pVdbeFunc = (VdbeFunc*)pOp->p4.pVdbeFunc;
     ctx.pFunc = ctx.pVdbeFunc->pFunc;
   }
 
@@ -1354,7 +1354,7 @@
     assert( pOp>p->aOp );
     assert( pOp[-1].p4type==P4_COLLSEQ );
     assert( pOp[-1].opcode==OP_CollSeq );
-    ctx.pColl = (CollSeq *)pOp[-1].p4.p;
+    ctx.pColl = pOp[-1].p4.pColl;
   }
   if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
   (*ctx.pFunc->xFunc)(&ctx, n, apVal);
@@ -1379,7 +1379,7 @@
   */
   if( ctx.pVdbeFunc ){
     sqlite3VdbeDeleteAuxData(ctx.pVdbeFunc, pOp->p1);
-    pOp->p4.p = (char *)ctx.pVdbeFunc;
+    pOp->p4.pVdbeFunc = ctx.pVdbeFunc;
     pOp->p4type = P4_VDBEFUNC;
   }
 
@@ -1774,10 +1774,10 @@
     applyAffinity(pTos, affinity, encoding);
   }
 
-  assert( pOp->p4type==P4_COLLSEQ || pOp->p4.p==0 );
+  assert( pOp->p4type==P4_COLLSEQ || pOp->p4.pColl==0 );
   ExpandBlob(pNos);
   ExpandBlob(pTos);
-  res = sqlite3MemCompare(pNos, pTos, (CollSeq*)pOp->p4.p);
+  res = sqlite3MemCompare(pNos, pTos, pOp->p4.pColl);
   switch( pOp->opcode ){
     case OP_Eq:    res = res==0;     break;
     case OP_Ne:    res = res!=0;     break;
@@ -2257,7 +2257,7 @@
     pDest->enc = encoding;
   }else{
     if( pOp->p4type==P4_MEM ){
-      sqlite3VdbeMemShallowCopy(pDest, (Mem *)(pOp->p4.p), MEM_Static);
+      sqlite3VdbeMemShallowCopy(pDest, pOp->p4.pMem, MEM_Static);
     }else{
       assert( pDest->flags==MEM_Null );
     }
@@ -2387,7 +2387,7 @@
   }
   jumpIfNull = pOp->p2;
   addRowid = pOp->opcode==OP_MakeIdxRec || pOp->opcode==OP_RegMakeIRec;
-  zAffinity = pOp->p4.p;
+  zAffinity = pOp->p4.z;
 
   if( pOp->opcode==OP_RegMakeRec || pOp->opcode==OP_RegMakeIRec ){
     Mem *pCount;
@@ -2862,7 +2862,7 @@
            sqlite3VdbeRecordCompare, pOp->p4.p,
            &pCur->pCursor);
   if( pOp->p4type==P4_KEYINFO ){
-    pCur->pKeyInfo = (KeyInfo*)pOp->p4.p;
+    pCur->pKeyInfo = pOp->p4.pKeyInfo;
     pCur->pIncrKey = &pCur->pKeyInfo->incrKey;
     pCur->pKeyInfo->enc = ENC(p->db);
   }else{
@@ -2957,15 +2957,15 @@
     ** opening it. If a transient table is required, just use the
     ** automatically created table with root-page 1 (an INTKEY table).
     */
-    if( pOp->p4.p ){
+    if( pOp->p4.pKeyInfo ){
       int pgno;
       assert( pOp->p4type==P4_KEYINFO );
       rc = sqlite3BtreeCreateTable(pCx->pBt, &pgno, BTREE_ZERODATA); 
       if( rc==SQLITE_OK ){
         assert( pgno==MASTER_ROOT+1 );
         rc = sqlite3BtreeCursor(pCx->pBt, pgno, 1, sqlite3VdbeRecordCompare,
-            pOp->p4.p, &pCx->pCursor);
-        pCx->pKeyInfo = (KeyInfo*)pOp->p4.p;
+            pOp->p4.z, &pCx->pCursor);
+        pCx->pKeyInfo = pOp->p4.pKeyInfo;
         pCx->pKeyInfo->enc = ENC(p->db);
         pCx->pIncrKey = &pCx->pKeyInfo->incrKey;
       }
@@ -3635,9 +3635,9 @@
     pC->cacheStatus = CACHE_STALE;
 
     /* Invoke the update-hook if required. */
-    if( rc==SQLITE_OK && db->xUpdateCallback && pOp->p4.p ){
+    if( rc==SQLITE_OK && db->xUpdateCallback && pOp->p4.z ){
       const char *zDb = db->aDb[pC->iDb].zName;
-      const char *zTbl = pOp->p4.p;
+      const char *zTbl = pOp->p4.z;
       int op = ((pOp->p5 & OPFLAG_ISUPDATE) ? SQLITE_UPDATE : SQLITE_INSERT);
       assert( pC->isTable );
       db->xUpdateCallback(db->pUpdateArg, op, zDb, zTbl, iKey);
@@ -3674,7 +3674,7 @@
     /* If the update-hook will be invoked, set iKey to the rowid of the
     ** row being deleted.
     */
-    if( db->xUpdateCallback && pOp->p4.p ){
+    if( db->xUpdateCallback && pOp->p4.z ){
       assert( pC->isTable );
       if( pC->rowidIsValid ){
         iKey = pC->lastRowid;
@@ -3694,9 +3694,9 @@
     pC->cacheStatus = CACHE_STALE;
 
     /* Invoke the update-hook if required. */
-    if( rc==SQLITE_OK && db->xUpdateCallback && pOp->p4.p ){
+    if( rc==SQLITE_OK && db->xUpdateCallback && pOp->p4.z ){
       const char *zDb = db->aDb[pC->iDb].zName;
-      const char *zTbl = pOp->p4.p;
+      const char *zTbl = pOp->p4.z;
       db->xUpdateCallback(db->pUpdateArg, SQLITE_DELETE, zDb, zTbl, iKey);
       assert( pC->iDb>=0 );
     }
@@ -4146,8 +4146,8 @@
     assert( pTos->flags & MEM_Blob );  /* Created using OP_MakeRecord */
     assert( pC->deferredMoveto==0 );
     ExpandBlob(pTos);
-    *pC->pIncrKey = pOp->p4.p!=0;
-    assert( pOp->p4.p==0 || pOp->opcode!=OP_IdxGT );
+    *pC->pIncrKey = pOp->p4.z!=0;
+    assert( pOp->p4.z==0 || pOp->opcode!=OP_IdxGT );
     rc = sqlite3VdbeIdxKeyCompare(pC, pTos->n, (u8*)pTos->z, &res);
     *pC->pIncrKey = 0;
     if( rc!=SQLITE_OK ){
@@ -4347,7 +4347,7 @@
   initData.pzErrMsg = &p->zErrMsg;
   zSql = sqlite3MPrintf(db,
      "SELECT name, rootpage, sql FROM '%q'.%s WHERE %s",
-     db->aDb[iDb].zName, zMaster, pOp->p4.p);
+     db->aDb[iDb].zName, zMaster, pOp->p4.z);
   if( zSql==0 ) goto no_mem;
   sqlite3SafetyOff(db);
   assert( db->init.busy==0 );
@@ -4387,7 +4387,7 @@
 ** schema consistent with what is on disk.
 */
 case OP_DropTable: {        /* no-push */
-  sqlite3UnlinkAndDeleteTable(db, pOp->p1, pOp->p4.p);
+  sqlite3UnlinkAndDeleteTable(db, pOp->p1, pOp->p4.z);
   break;
 }
 
@@ -4399,7 +4399,7 @@
 ** schema consistent with what is on disk.
 */
 case OP_DropIndex: {        /* no-push */
-  sqlite3UnlinkAndDeleteIndex(db, pOp->p1, pOp->p4.p);
+  sqlite3UnlinkAndDeleteIndex(db, pOp->p1, pOp->p4.z);
   break;
 }
 
@@ -4411,7 +4411,7 @@
 ** schema consistent with what is on disk.
 */
 case OP_DropTrigger: {        /* no-push */
-  sqlite3UnlinkAndDeleteTrigger(db, pOp->p1, pOp->p4.p);
+  sqlite3UnlinkAndDeleteTrigger(db, pOp->p1, pOp->p4.z);
   break;
 }
 
@@ -4770,7 +4770,7 @@
     apVal[i] = pRec;
     storeTypeInfo(pRec, encoding);
   }
-  ctx.pFunc = (FuncDef*)pOp->p4.p;
+  ctx.pFunc = pOp->p4.pFunc;
   assert( pOp->p1>=0 && pOp->p1<p->nMem );
   ctx.pMem = pMem = &p->aMem[pOp->p1];
   pMem->n++;
@@ -4784,7 +4784,7 @@
     assert( pOp>p->aOp );
     assert( pOp[-1].p4type==P4_COLLSEQ );
     assert( pOp[-1].opcode==OP_CollSeq );
-    ctx.pColl = (CollSeq *)pOp[-1].p4.p;
+    ctx.pColl = pOp[-1].p4.pColl;
   }
   (ctx.pFunc->xStep)(&ctx, n, apVal);
   popStack(&pTos, n);
@@ -4813,7 +4813,7 @@
   assert( pOp->p1>=0 && pOp->p1<p->nMem );
   pMem = &p->aMem[pOp->p1];
   assert( (pMem->flags & ~(MEM_Null|MEM_Agg))==0 );
-  rc = sqlite3VdbeMemFinalize(pMem, (FuncDef*)pOp->p4.p);
+  rc = sqlite3VdbeMemFinalize(pMem, pOp->p4.pFunc);
   if( rc==SQLITE_ERROR ){
     sqlite3SetString(&p->zErrMsg, sqlite3_value_text(pMem), (char*)0);
   }
@@ -4906,7 +4906,7 @@
   assert( (p->btreeMask & (1<<p1))!=0 );
   rc = sqlite3BtreeLockTable(db->aDb[p1].pBt, pOp->p2, isWriteLock);
   if( rc==SQLITE_LOCKED ){
-    const char *z = (const char *)pOp->p4.p;
+    const char *z = pOp->p4.z;
     sqlite3SetString(&p->zErrMsg, "database table is locked: ", z, (char*)0);
   }
   break;
@@ -4920,7 +4920,7 @@
 ** for that table.
 */
 case OP_VBegin: {   /* no-push */
-  rc = sqlite3VtabBegin(db, (sqlite3_vtab *)pOp->p4.p);
+  rc = sqlite3VtabBegin(db, pOp->p4.pVtab);
   break;
 }
 #endif /* SQLITE_OMIT_VIRTUALTABLE */
@@ -4932,7 +4932,7 @@
 ** for that table.
 */
 case OP_VCreate: {   /* no-push */
-  rc = sqlite3VtabCallCreate(db, pOp->p1, pOp->p4.p, &p->zErrMsg);
+  rc = sqlite3VtabCallCreate(db, pOp->p1, pOp->p4.z, &p->zErrMsg);
   break;
 }
 #endif /* SQLITE_OMIT_VIRTUALTABLE */
@@ -4945,7 +4945,7 @@
 */
 case OP_VDestroy: {   /* no-push */
   p->inVtabMethod = 2;
-  rc = sqlite3VtabCallDestroy(db, pOp->p1, pOp->p4.p);
+  rc = sqlite3VtabCallDestroy(db, pOp->p1, pOp->p4.z);
   p->inVtabMethod = 0;
   break;
 }
@@ -4962,7 +4962,7 @@
   Cursor *pCur = 0;
   sqlite3_vtab_cursor *pVtabCursor = 0;
 
-  sqlite3_vtab *pVtab = (sqlite3_vtab *)(pOp->p4.p);
+  sqlite3_vtab *pVtab = pOp->p4.pVtab;
   sqlite3_module *pModule = (sqlite3_module *)pVtab->pModule;
 
   assert(pVtab && pModule);
@@ -5036,7 +5036,7 @@
 
     if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
     p->inVtabMethod = 1;
-    rc = pModule->xFilter(pCur->pVtabCursor, pTos->u.i, pOp->p4.p, nArg, apArg);
+    rc = pModule->xFilter(pCur->pVtabCursor, pTos->u.i, pOp->p4.z, nArg, apArg);
     p->inVtabMethod = 0;
     if( rc==SQLITE_OK ){
       res = pModule->xEof(pCur->pVtabCursor);
@@ -5181,7 +5181,7 @@
 ** to the xRename method.
 */
 case OP_VRename: {   /* no-push */
-  sqlite3_vtab *pVtab = (sqlite3_vtab *)(pOp->p4.p);
+  sqlite3_vtab *pVtab = pOp->p4.pVtab;
   assert( pVtab->pModule->xRename );
 
   Stringify(pTos, encoding);
@@ -5222,7 +5222,7 @@
 ** is set to the value of the rowid for the row just inserted.
 */
 case OP_VUpdate: {   /* no-push */
-  sqlite3_vtab *pVtab = (sqlite3_vtab *)(pOp->p4.p);
+  sqlite3_vtab *pVtab = pOp->p4.pVtab;
   sqlite3_module *pModule = (sqlite3_module *)pVtab->pModule;
   int nArg = pOp->p2;
   assert( pOp->p4type==P4_VTAB );
diff --git a/src/vdbe.h b/src/vdbe.h
index bf221ca..33f091d 100644
--- a/src/vdbe.h
+++ b/src/vdbe.h
@@ -15,7 +15,7 @@
 ** or VDBE.  The VDBE implements an abstract machine that runs a
 ** simple program to access and modify the underlying database.
 **
-** $Id: vdbe.h,v 1.121 2008/01/03 09:51:55 danielk1977 Exp $
+** $Id: vdbe.h,v 1.122 2008/01/03 11:50:30 danielk1977 Exp $
 */
 #ifndef _SQLITE_VDBE_H_
 #define _SQLITE_VDBE_H_
@@ -29,6 +29,13 @@
 typedef struct Vdbe Vdbe;
 
 /*
+** The names of the following types declared in vdbeInt.h are required
+** for the VdbeOp definition.
+*/
+typedef struct VdbeFunc VdbeFunc;
+typedef struct Mem Mem;
+
+/*
 ** A single instruction of the virtual machine has an opcode
 ** and as many as three operands.  The instruction is recorded
 ** as an instance of the following structure:
@@ -42,8 +49,17 @@
   int p2;             /* Second parameter (often the jump destination) */
   int p3;             /* The third parameter */
   union {             /* forth parameter */
-    int i;              /* Integer value if p3type==P4_INT32 */
-    char *p;            /* A pointer for all other value sof p3type */
+    int i;                 /* Integer value if p4type==P4_INT32 */
+    void *p;               /* Generic pointer */
+    char *z;               /* Pointer to data for string (char array) types */
+    i64 *pI64;             /* Used when p4type is P4_INT64 */
+    double *pReal;         /* Used when p4type is P4_REAL */
+    FuncDef *pFunc;        /* Used when p4type is P4_FUNCDEF */
+    VdbeFunc *pVdbeFunc;   /* Used when p4type is P4_VDBEFUNC */
+    CollSeq *pColl;        /* Used when p4type is P4_COLLSEQ */
+    Mem *pMem;             /* Used when p4type is P4_MEM */
+    sqlite3_vtab *pVtab;   /* Used when p4type is P4_VTAB */
+    KeyInfo *pKeyInfo;     /* Used when p4type is P4_KEYINFO */
   } p4;
 #ifdef SQLITE_DEBUG
   char *zComment;     /* Comment to improve readability */
diff --git a/src/vdbeInt.h b/src/vdbeInt.h
index 4c4111f..988c85b 100644
--- a/src/vdbeInt.h
+++ b/src/vdbeInt.h
@@ -132,7 +132,6 @@
   void (*xDel)(void *);  /* If not null, call this function to delete Mem.z */
   char zShort[NBFS];  /* Space for short strings */
 };
-typedef struct Mem Mem;
 
 /* One or more of the following flags are set to indicate the validOK
 ** representations of the value stored in the Mem struct.
@@ -191,7 +190,6 @@
     void (*xDelete)(void *);      /* Destructor for the aux data */
   } apAux[1];                   /* One slot for each function argument */
 };
-typedef struct VdbeFunc VdbeFunc;
 
 /*
 ** The "context" argument for a installable function.  A pointer to an
diff --git a/src/vdbeapi.c b/src/vdbeapi.c
index 8e274da..05a8718 100644
--- a/src/vdbeapi.c
+++ b/src/vdbeapi.c
@@ -293,10 +293,10 @@
     if( db->xTrace && !db->init.busy ){
       assert( p->nOp>0 );
       assert( p->aOp[p->nOp-1].opcode==OP_Noop );
-      assert( p->aOp[p->nOp-1].p4.p!=0 );
+      assert( p->aOp[p->nOp-1].p4.z!=0 );
       assert( p->aOp[p->nOp-1].p4type==P4_DYNAMIC );
       sqlite3SafetyOff(db);
-      db->xTrace(db->pTraceArg, p->aOp[p->nOp-1].p4.p);
+      db->xTrace(db->pTraceArg, p->aOp[p->nOp-1].p4.z);
       if( sqlite3SafetyOn(db) ){
         p->rc = SQLITE_MISUSE;
         return SQLITE_MISUSE;
@@ -314,7 +314,7 @@
     */
 #ifdef SQLITE_DEBUG
     if( (db->flags & SQLITE_SqlTrace)!=0 ){
-      sqlite3DebugPrintf("SQL-trace: %s\n", p->aOp[p->nOp-1].p4.p);
+      sqlite3DebugPrintf("SQL-trace: %s\n", p->aOp[p->nOp-1].p4.z);
     }
 #endif /* SQLITE_DEBUG */
 
@@ -345,9 +345,9 @@
     elapseTime = (rNow - (int)rNow)*3600.0*24.0*1000000000.0 - p->startTime;
     assert( p->nOp>0 );
     assert( p->aOp[p->nOp-1].opcode==OP_Noop );
-    assert( p->aOp[p->nOp-1].p4.p!=0 );
+    assert( p->aOp[p->nOp-1].p4.z!=0 );
     assert( p->aOp[p->nOp-1].p4type==P4_DYNAMIC );
-    db->xProfile(db->pProfileArg, p->aOp[p->nOp-1].p4.p, elapseTime);
+    db->xProfile(db->pProfileArg, p->aOp[p->nOp-1].p4.z, elapseTime);
   }
 #endif
 
@@ -1001,7 +1001,7 @@
       for(j=0, pOp=p->aOp; j<p->nOp; j++, pOp++){
         if( pOp->opcode==OP_Variable ){
           assert( pOp->p1>0 && pOp->p1<=p->nVar );
-          p->azVar[pOp->p1-1] = pOp->p4.p;
+          p->azVar[pOp->p1-1] = pOp->p4.z;
         }
       }
       p->okVar = 1;
diff --git a/src/vdbeaux.c b/src/vdbeaux.c
index c7c98f5..94032b4 100644
--- a/src/vdbeaux.c
+++ b/src/vdbeaux.c
@@ -577,7 +577,7 @@
     nField = ((KeyInfo*)zP4)->nField;
     nByte = sizeof(*pKeyInfo) + (nField-1)*sizeof(pKeyInfo->aColl[0]) + nField;
     pKeyInfo = sqlite3_malloc( nByte );
-    pOp->p4.p = (char*)pKeyInfo;
+    pOp->p4.pKeyInfo = pKeyInfo;
     if( pKeyInfo ){
       unsigned char *aSortOrder;
       memcpy(pKeyInfo, zP4, nByte);
@@ -592,14 +592,14 @@
       pOp->p4type = P4_NOTUSED;
     }
   }else if( n==P4_KEYINFO_HANDOFF ){
-    pOp->p4.p = (char*)zP4;
+    pOp->p4.p = (void*)zP4;
     pOp->p4type = P4_KEYINFO;
   }else if( n<0 ){
-    pOp->p4.p = (char*)zP4;
+    pOp->p4.p = (void*)zP4;
     pOp->p4type = n;
   }else{
     if( n==0 ) n = strlen(zP4);
-    pOp->p4.p = sqlite3DbStrNDup(p->db, zP4, n);
+    pOp->p4.z = sqlite3DbStrNDup(p->db, zP4, n);
     pOp->p4type = P4_DYNAMIC;
   }
 }
@@ -639,7 +639,7 @@
   switch( pOp->p4type ){
     case P4_KEYINFO: {
       int i, j;
-      KeyInfo *pKeyInfo = (KeyInfo*)pOp->p4.p;
+      KeyInfo *pKeyInfo = pOp->p4.pKeyInfo;
       sqlite3_snprintf(nTemp, zTemp, "keyinfo(%d", pKeyInfo->nField);
       i = strlen(zTemp);
       for(j=0; j<pKeyInfo->nField; j++){
@@ -667,17 +667,17 @@
       break;
     }
     case P4_COLLSEQ: {
-      CollSeq *pColl = (CollSeq*)pOp->p4.p;
+      CollSeq *pColl = pOp->p4.pColl;
       sqlite3_snprintf(nTemp, zTemp, "collseq(%.20s)", pColl->zName);
       break;
     }
     case P4_FUNCDEF: {
-      FuncDef *pDef = (FuncDef*)pOp->p4.p;
+      FuncDef *pDef = pOp->p4.pFunc;
       sqlite3_snprintf(nTemp, zTemp, "%s(%d)", pDef->zName, pDef->nArg);
       break;
     }
     case P4_INT64: {
-      sqlite3_snprintf(nTemp, zTemp, "%lld", *(sqlite3_int64*)pOp->p4.p);
+      sqlite3_snprintf(nTemp, zTemp, "%lld", *pOp->p4.pI64);
       break;
     }
     case P4_INT32: {
@@ -685,11 +685,11 @@
       break;
     }
     case P4_REAL: {
-      sqlite3_snprintf(nTemp, zTemp, "%.16g", *(double*)pOp->p4.p);
+      sqlite3_snprintf(nTemp, zTemp, "%.16g", *pOp->p4.pReal);
       break;
     }
     case P4_MEM: {
-      Mem *pMem = (Mem*)pOp->p4.p;
+      Mem *pMem = pOp->p4.pMem;
       if( pMem->flags & MEM_Str ){
         zP4 = pMem->z;
       }else if( pMem->flags & MEM_Int ){
@@ -703,13 +703,13 @@
     }
 #ifndef SQLITE_OMIT_VIRTUALTABLE
     case P4_VTAB: {
-      sqlite3_vtab *pVtab = (sqlite3_vtab*)pOp->p4.p;
+      sqlite3_vtab *pVtab = pOp->p4.pVtab;
       sqlite3_snprintf(nTemp, zTemp, "vtab:%p:%p", pVtab, pVtab->pModule);
       break;
     }
 #endif
     default: {
-      zP4 = pOp->p4.p;
+      zP4 = pOp->p4.z;
       if( zP4==0 || pOp->opcode==OP_Noop ){
         zP4 = zTemp;
         zTemp[0] = 0;
@@ -882,8 +882,8 @@
   VdbeOp *pOp;
   if( nOp<1 ) return;
   pOp = &p->aOp[nOp-1];
-  if( pOp->opcode==OP_Noop && pOp->p4.p!=0 ){
-    const char *z = pOp->p4.p;
+  if( pOp->opcode==OP_Noop && pOp->p4.z!=0 ){
+    const char *z = pOp->p4.z;
     while( isspace(*(u8*)z) ) z++;
     printf("SQL: [%s]\n", z);
   }