SQLite

Check-in [539e4f6617]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Fixes for platforms with 32-bit pointers that require 64-bit values to be aligned.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 539e4f661767ef90aef8d995f1f75fd5f550703bba1517cd3caff84a4afe2b37
User & Date: dan 2024-07-17 18:38:34.280
References
2024-08-16
15:35
Ensure that memory allocations in ANALYZE are always 8-byte aligned in order to satisfy a new assert() added by [539e4f661767ef90]. (check-in: a1915cbdec user: drh tags: trunk)
Context
2024-07-18
18:44
Fix a problem in FTS5 where it reports the wrong error code following an OOM. (check-in: 0c1cc4071e user: drh tags: trunk)
2024-07-17
18:38
Fixes for platforms with 32-bit pointers that require 64-bit values to be aligned. (check-in: 539e4f6617 user: dan tags: trunk)
16:27
Add extra assert() statements to the fixes on this branch. (Closed-Leaf check-in: 81b6360050 user: dan tags: alignment-fixes)
2024-07-15
10:11
Slight doc touchup for [af41a1e6fc8b36e9bf65] based on feedback. No code changes. (check-in: be7b1fc0c5 user: stephan tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to ext/fts3/fts3_term.c.
74
75
76
77
78
79
80


81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103






104
105
106
107
108
109
110
  int iIndex = 0;

  UNUSED_PARAMETER(pCtx);
  if( argc==5 ){
    iIndex = atoi(argv[4]);
    argc--;
  }



  /* The user should specify a single argument - the name of an fts3 table. */
  if( argc!=4 ){
    sqlite3Fts3ErrMsg(pzErr,
        "wrong number of arguments to fts4term constructor"
    );
    return SQLITE_ERROR;
  }

  zDb = argv[1]; 
  nDb = (int)strlen(zDb);
  zFts3 = argv[3];
  nFts3 = (int)strlen(zFts3);

  rc = sqlite3_declare_vtab(db, FTS3_TERMS_SCHEMA);
  if( rc!=SQLITE_OK ) return rc;

  nByte = sizeof(Fts3termTable) + sizeof(Fts3Table) + nDb + nFts3 + 2;
  p = (Fts3termTable *)sqlite3_malloc64(nByte);
  if( !p ) return SQLITE_NOMEM;
  memset(p, 0, (size_t)nByte);

  p->pFts3Tab = (Fts3Table *)&p[1];






  p->pFts3Tab->zDb = (char *)&p->pFts3Tab[1];
  p->pFts3Tab->zName = &p->pFts3Tab->zDb[nDb+1];
  p->pFts3Tab->db = db;
  p->pFts3Tab->nIndex = iIndex+1;
  p->iIndex = iIndex;

  memcpy((char *)p->pFts3Tab->zDb, zDb, nDb);







>
>

















|
|

<

|
>
>
>
>
>
>







74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102

103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
  int iIndex = 0;

  UNUSED_PARAMETER(pCtx);
  if( argc==5 ){
    iIndex = atoi(argv[4]);
    argc--;
  }
  
  *ppVtab = 0;

  /* The user should specify a single argument - the name of an fts3 table. */
  if( argc!=4 ){
    sqlite3Fts3ErrMsg(pzErr,
        "wrong number of arguments to fts4term constructor"
    );
    return SQLITE_ERROR;
  }

  zDb = argv[1]; 
  nDb = (int)strlen(zDb);
  zFts3 = argv[3];
  nFts3 = (int)strlen(zFts3);

  rc = sqlite3_declare_vtab(db, FTS3_TERMS_SCHEMA);
  if( rc!=SQLITE_OK ) return rc;

  nByte = sizeof(Fts3termTable);
  p = (Fts3termTable *)sqlite3Fts3MallocZero(nByte);
  if( !p ) return SQLITE_NOMEM;


  p->pFts3Tab = (Fts3Table*)sqlite3Fts3MallocZero(
      sizeof(Fts3Table) + nDb + nFts3 + 2
  );
  if( p->pFts3Tab==0 ){
    sqlite3_free(p);
    return SQLITE_NOMEM;
  }
  p->pFts3Tab->zDb = (char *)&p->pFts3Tab[1];
  p->pFts3Tab->zName = &p->pFts3Tab->zDb[nDb+1];
  p->pFts3Tab->db = db;
  p->pFts3Tab->nIndex = iIndex+1;
  p->iIndex = iIndex;

  memcpy((char *)p->pFts3Tab->zDb, zDb, nDb);
126
127
128
129
130
131
132

133
134
135
136
137
138
139
  int i;

  /* Free any prepared statements held */
  for(i=0; i<SizeofArray(pFts3->aStmt); i++){
    sqlite3_finalize(pFts3->aStmt[i]);
  }
  sqlite3_free(pFts3->zSegmentsTbl);

  sqlite3_free(p);
  return SQLITE_OK;
}

#define FTS4AUX_EQ_CONSTRAINT 1
#define FTS4AUX_GE_CONSTRAINT 2
#define FTS4AUX_LE_CONSTRAINT 4







>







133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
  int i;

  /* Free any prepared statements held */
  for(i=0; i<SizeofArray(pFts3->aStmt); i++){
    sqlite3_finalize(pFts3->aStmt[i]);
  }
  sqlite3_free(pFts3->zSegmentsTbl);
  sqlite3_free(pFts3);
  sqlite3_free(p);
  return SQLITE_OK;
}

#define FTS4AUX_EQ_CONSTRAINT 1
#define FTS4AUX_GE_CONSTRAINT 2
#define FTS4AUX_LE_CONSTRAINT 4
Changes to ext/fts5/fts5Int.h.
54
55
56
57
58
59
60
















61
62
63
64
65
66
67
#define MAX(x,y) (((x) > (y)) ? (x) : (y))

/*
** Constants for the largest and smallest possible 64-bit signed integers.
*/
# define LARGEST_INT64  (0xffffffff|(((i64)0x7fffffff)<<32))
# define SMALLEST_INT64 (((i64)-1) - LARGEST_INT64)

















#endif

/* Truncate very long tokens to this many bytes. Hard limit is 
** (65536-1-1-4-9)==65521 bytes. The limiting factor is the 16-bit offset
** field that occurs at the start of each leaf page (see fts5_index.c). */
#define FTS5_MAX_TOKEN_SIZE 32768







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
#define MAX(x,y) (((x) > (y)) ? (x) : (y))

/*
** Constants for the largest and smallest possible 64-bit signed integers.
*/
# define LARGEST_INT64  (0xffffffff|(((i64)0x7fffffff)<<32))
# define SMALLEST_INT64 (((i64)-1) - LARGEST_INT64)

/* The uptr type is an unsigned integer large enough to hold a pointer
*/
#if defined(HAVE_STDINT_H)
  typedef uintptr_t uptr;
#elif SQLITE_PTRSIZE==4
  typedef u32 uptr;
#else
  typedef u64 uptr;
#endif

#ifdef SQLITE_4_BYTE_ALIGNED_MALLOC
# define EIGHT_BYTE_ALIGNMENT(X)   ((((uptr)(X) - (uptr)0)&3)==0)
#else
# define EIGHT_BYTE_ALIGNMENT(X)   ((((uptr)(X) - (uptr)0)&7)==0)
#endif

#endif

/* Truncate very long tokens to this many bytes. Hard limit is 
** (65536-1-1-4-9)==65521 bytes. The limiting factor is the 16-bit offset
** field that occurs at the start of each leaf page (see fts5_index.c). */
#define FTS5_MAX_TOKEN_SIZE 32768
Changes to ext/fts5/fts5_index.c.
827
828
829
830
831
832
833

834
835
836
837
838
839
840
841
842
843
844
845
    ** table, missing row, non-blob/text in block column - indicate 
    ** backing store corruption.  */
    if( rc==SQLITE_ERROR ) rc = FTS5_CORRUPT;

    if( rc==SQLITE_OK ){
      u8 *aOut = 0;               /* Read blob data into this buffer */
      int nByte = sqlite3_blob_bytes(p->pReader);

      sqlite3_int64 nAlloc = sizeof(Fts5Data) + nByte + FTS5_DATA_PADDING;
      pRet = (Fts5Data*)sqlite3_malloc64(nAlloc);
      if( pRet ){
        pRet->nn = nByte;
        aOut = pRet->p = (u8*)&pRet[1];
      }else{
        rc = SQLITE_NOMEM;
      }

      if( rc==SQLITE_OK ){
        rc = sqlite3_blob_read(p->pReader, aOut, nByte, 0);
      }







>
|



|







827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
    ** table, missing row, non-blob/text in block column - indicate 
    ** backing store corruption.  */
    if( rc==SQLITE_ERROR ) rc = FTS5_CORRUPT;

    if( rc==SQLITE_OK ){
      u8 *aOut = 0;               /* Read blob data into this buffer */
      int nByte = sqlite3_blob_bytes(p->pReader);
      int szData = (sizeof(Fts5Data) + 7) & ~7;
      sqlite3_int64 nAlloc = szData + nByte + FTS5_DATA_PADDING;
      pRet = (Fts5Data*)sqlite3_malloc64(nAlloc);
      if( pRet ){
        pRet->nn = nByte;
        aOut = pRet->p = (u8*)pRet + szData;
      }else{
        rc = SQLITE_NOMEM;
      }

      if( rc==SQLITE_OK ){
        rc = sqlite3_blob_read(p->pReader, aOut, nByte, 0);
      }
854
855
856
857
858
859
860

861
862
863
864
865
866
867
      }
    }
    p->rc = rc;
    p->nRead++;
  }

  assert( (pRet==0)==(p->rc!=SQLITE_OK) );

  return pRet;
}


/*
** Release a reference to data record returned by an earlier call to
** fts5DataRead().







>







855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
      }
    }
    p->rc = rc;
    p->nRead++;
  }

  assert( (pRet==0)==(p->rc!=SQLITE_OK) );
  assert( pRet==0 || EIGHT_BYTE_ALIGNMENT( pRet->p ) );
  return pRet;
}


/*
** Release a reference to data record returned by an earlier call to
** fts5DataRead().
Changes to src/analyze.c.
1828
1829
1830
1831
1832
1833
1834

1835
1836
1837
1838
1839
1840
1841

    pIdx->aSample = sqlite3DbMallocZero(db, nByte);
    if( pIdx->aSample==0 ){
      sqlite3_finalize(pStmt);
      return SQLITE_NOMEM_BKPT;
    }
    pSpace = (tRowcnt*)&pIdx->aSample[nSample];

    pIdx->aAvgEq = pSpace; pSpace += nIdxCol;
    pIdx->pTable->tabFlags |= TF_HasStat4;
    for(i=0; i<nSample; i++){
      pIdx->aSample[i].anEq = pSpace; pSpace += nIdxCol;
      pIdx->aSample[i].anLt = pSpace; pSpace += nIdxCol;
      pIdx->aSample[i].anDLt = pSpace; pSpace += nIdxCol;
    }







>







1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842

    pIdx->aSample = sqlite3DbMallocZero(db, nByte);
    if( pIdx->aSample==0 ){
      sqlite3_finalize(pStmt);
      return SQLITE_NOMEM_BKPT;
    }
    pSpace = (tRowcnt*)&pIdx->aSample[nSample];
    assert( EIGHT_BYTE_ALIGNMENT( pSpace ) );
    pIdx->aAvgEq = pSpace; pSpace += nIdxCol;
    pIdx->pTable->tabFlags |= TF_HasStat4;
    for(i=0; i<nSample; i++){
      pIdx->aSample[i].anEq = pSpace; pSpace += nIdxCol;
      pIdx->aSample[i].anLt = pSpace; pSpace += nIdxCol;
      pIdx->aSample[i].anDLt = pSpace; pSpace += nIdxCol;
    }
Changes to src/pager.c.
4060
4061
4062
4063
4064
4065
4066

4067
4068
4069
4070
4071
4072
4073
  }else{
    *ppPage = p = (PgHdr *)sqlite3MallocZero(sizeof(PgHdr) + pPager->nExtra);
    if( p==0 ){
      sqlite3OsUnfetch(pPager->fd, (i64)(pgno-1) * pPager->pageSize, pData);
      return SQLITE_NOMEM_BKPT;
    }
    p->pExtra = (void *)&p[1];

    p->flags = PGHDR_MMAP;
    p->nRef = 1;
    p->pPager = pPager;
  }

  assert( p->pExtra==(void *)&p[1] );
  assert( p->pPage==0 );







>







4060
4061
4062
4063
4064
4065
4066
4067
4068
4069
4070
4071
4072
4073
4074
  }else{
    *ppPage = p = (PgHdr *)sqlite3MallocZero(sizeof(PgHdr) + pPager->nExtra);
    if( p==0 ){
      sqlite3OsUnfetch(pPager->fd, (i64)(pgno-1) * pPager->pageSize, pData);
      return SQLITE_NOMEM_BKPT;
    }
    p->pExtra = (void *)&p[1];
    assert( EIGHT_BYTE_ALIGNMENT( p->pExtra ) );
    p->flags = PGHDR_MMAP;
    p->nRef = 1;
    p->pPager = pPager;
  }

  assert( p->pExtra==(void *)&p[1] );
  assert( p->pPage==0 );
Changes to src/pcache.c.
508
509
510
511
512
513
514

515
516
517
518
519
520
521
  pPgHdr = (PgHdr*)pPage->pExtra;
  assert( pPgHdr->pPage==0 );
  memset(&pPgHdr->pDirty, 0, sizeof(PgHdr) - offsetof(PgHdr,pDirty));
  pPgHdr->pPage = pPage;
  pPgHdr->pData = pPage->pBuf;
  pPgHdr->pExtra = (void *)&pPgHdr[1];
  memset(pPgHdr->pExtra, 0, 8);

  pPgHdr->pCache = pCache;
  pPgHdr->pgno = pgno;
  pPgHdr->flags = PGHDR_CLEAN;
  return sqlite3PcacheFetchFinish(pCache,pgno,pPage);
}

/*







>







508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
  pPgHdr = (PgHdr*)pPage->pExtra;
  assert( pPgHdr->pPage==0 );
  memset(&pPgHdr->pDirty, 0, sizeof(PgHdr) - offsetof(PgHdr,pDirty));
  pPgHdr->pPage = pPage;
  pPgHdr->pData = pPage->pBuf;
  pPgHdr->pExtra = (void *)&pPgHdr[1];
  memset(pPgHdr->pExtra, 0, 8);
  assert( EIGHT_BYTE_ALIGNMENT( pPgHdr->pExtra ) );
  pPgHdr->pCache = pCache;
  pPgHdr->pgno = pgno;
  pPgHdr->flags = PGHDR_CLEAN;
  return sqlite3PcacheFetchFinish(pCache,pgno,pPage);
}

/*
Changes to src/pcache1.c.
316
317
318
319
320
321
322
323

324
325
326
327
328
329
330
  zBulk = pCache->pBulk = sqlite3Malloc( szBulk );
  sqlite3EndBenignMalloc();
  if( zBulk ){
    int nBulk = sqlite3MallocSize(zBulk)/pCache->szAlloc;
    do{
      PgHdr1 *pX = (PgHdr1*)&zBulk[pCache->szPage];
      pX->page.pBuf = zBulk;
      pX->page.pExtra = &pX[1];

      pX->isBulkLocal = 1;
      pX->isAnchor = 0;
      pX->pNext = pCache->pFree;
      pX->pLruPrev = 0;           /* Initializing this saves a valgrind error */
      pCache->pFree = pX;
      zBulk += pCache->szAlloc;
    }while( --nBulk );







|
>







316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
  zBulk = pCache->pBulk = sqlite3Malloc( szBulk );
  sqlite3EndBenignMalloc();
  if( zBulk ){
    int nBulk = sqlite3MallocSize(zBulk)/pCache->szAlloc;
    do{
      PgHdr1 *pX = (PgHdr1*)&zBulk[pCache->szPage];
      pX->page.pBuf = zBulk;
      pX->page.pExtra = (u8*)pX + ROUND8(sizeof(*pX));
      assert( EIGHT_BYTE_ALIGNMENT( pX->page.pExtra ) );
      pX->isBulkLocal = 1;
      pX->isAnchor = 0;
      pX->pNext = pCache->pFree;
      pX->pLruPrev = 0;           /* Initializing this saves a valgrind error */
      pCache->pFree = pX;
      zBulk += pCache->szAlloc;
    }while( --nBulk );
453
454
455
456
457
458
459
460

461
462
463
464
465
466
467
    if( benignMalloc ){ sqlite3EndBenignMalloc(); }
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
    pcache1EnterMutex(pCache->pGroup);
#endif
    if( pPg==0 ) return 0;
    p = (PgHdr1 *)&((u8 *)pPg)[pCache->szPage];
    p->page.pBuf = pPg;
    p->page.pExtra = &p[1];

    p->isBulkLocal = 0;
    p->isAnchor = 0;
    p->pLruPrev = 0;           /* Initializing this saves a valgrind error */
  }
  (*pCache->pnPurgeable)++;
  return p;
}







|
>







454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
    if( benignMalloc ){ sqlite3EndBenignMalloc(); }
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
    pcache1EnterMutex(pCache->pGroup);
#endif
    if( pPg==0 ) return 0;
    p = (PgHdr1 *)&((u8 *)pPg)[pCache->szPage];
    p->page.pBuf = pPg;
    p->page.pExtra = (u8*)p + ROUND8(sizeof(*p));
    assert( EIGHT_BYTE_ALIGNMENT( p->page.pExtra ) );
    p->isBulkLocal = 0;
    p->isAnchor = 0;
    p->pLruPrev = 0;           /* Initializing this saves a valgrind error */
  }
  (*pCache->pnPurgeable)++;
  return p;
}
Changes to src/test_pcache.c.
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
#define TESTPCACHE_CLEAR  0xd42670d4

/*
** Private implementation of a page cache.
*/
typedef struct testpcache testpcache;
struct testpcache {
  int szPage;               /* Size of each page.  Multiple of 8. */
  int szExtra;              /* Size of extra data that accompanies each page */
  int bPurgeable;           /* True if the page cache is purgeable */
  int nFree;                /* Number of unused slots in a[] */
  int nPinned;              /* Number of pinned slots in a[] */
  unsigned iRand;           /* State of the PRNG */
  unsigned iMagic;          /* Magic number for sanity checking */
  struct testpcachePage {







|







95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
#define TESTPCACHE_CLEAR  0xd42670d4

/*
** Private implementation of a page cache.
*/
typedef struct testpcache testpcache;
struct testpcache {
  sqlite3_int64 szPage;     /* Size of each page.  Multiple of 8. */
  int szExtra;              /* Size of extra data that accompanies each page */
  int bPurgeable;           /* True if the page cache is purgeable */
  int nFree;                /* Number of unused slots in a[] */
  int nPinned;              /* Number of pinned slots in a[] */
  unsigned iRand;           /* State of the PRNG */
  unsigned iMagic;          /* Magic number for sanity checking */
  struct testpcachePage {
137
138
139
140
141
142
143

144
145
146
147
148
149
150
){
  int nMem;
  char *x;
  testpcache *p;
  int i;
  assert( testpcacheGlobal.pDummy!=0 );
  szPage = (szPage+7)&~7;

  nMem = sizeof(testpcache) + TESTPCACHE_NPAGE*(szPage+szExtra);
  p = sqlite3_malloc( nMem );
  if( p==0 ) return 0;
  x = (char*)&p[1];
  p->szPage = szPage;
  p->szExtra = szExtra;
  p->nFree = TESTPCACHE_NPAGE;







>







137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
){
  int nMem;
  char *x;
  testpcache *p;
  int i;
  assert( testpcacheGlobal.pDummy!=0 );
  szPage = (szPage+7)&~7;
  szExtra = (szPage+7)&~7;
  nMem = sizeof(testpcache) + TESTPCACHE_NPAGE*(szPage+szExtra);
  p = sqlite3_malloc( nMem );
  if( p==0 ) return 0;
  x = (char*)&p[1];
  p->szPage = szPage;
  p->szExtra = szExtra;
  p->nFree = TESTPCACHE_NPAGE;
Changes to src/vdbe.c.
7667
7668
7669
7670
7671
7672
7673

7674
7675
7676
7677
7678
7679









7680
7681
7682
7683
7684


7685

7686
7687
7688
7689
7690
7691
7692
** sqlite3_context only happens once, instead of on each call to the
** step function.
*/
case OP_AggInverse:
case OP_AggStep: {
  int n;
  sqlite3_context *pCtx;


  assert( pOp->p4type==P4_FUNCDEF );
  n = pOp->p5;
  assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) );
  assert( n==0 || (pOp->p2>0 && pOp->p2+n<=(p->nMem+1 - p->nCursor)+1) );
  assert( pOp->p3<pOp->p2 || pOp->p3>=pOp->p2+n );









  pCtx = sqlite3DbMallocRawNN(db, n*sizeof(sqlite3_value*) +
               (sizeof(pCtx[0]) + sizeof(Mem) - sizeof(sqlite3_value*)));
  if( pCtx==0 ) goto no_mem;
  pCtx->pMem = 0;
  pCtx->pOut = (Mem*)&(pCtx->argv[n]);


  sqlite3VdbeMemInit(pCtx->pOut, db, MEM_Null);

  pCtx->pFunc = pOp->p4.pFunc;
  pCtx->iOp = (int)(pOp - aOp);
  pCtx->pVdbe = p;
  pCtx->skipFlag = 0;
  pCtx->isError = 0;
  pCtx->enc = encoding;
  pCtx->argc = n;







>






>
>
>
>
>
>
>
>
>
|
<

<
|
>
>

>







7667
7668
7669
7670
7671
7672
7673
7674
7675
7676
7677
7678
7679
7680
7681
7682
7683
7684
7685
7686
7687
7688
7689
7690

7691

7692
7693
7694
7695
7696
7697
7698
7699
7700
7701
7702
7703
** sqlite3_context only happens once, instead of on each call to the
** step function.
*/
case OP_AggInverse:
case OP_AggStep: {
  int n;
  sqlite3_context *pCtx;
  u64 nAlloc;

  assert( pOp->p4type==P4_FUNCDEF );
  n = pOp->p5;
  assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) );
  assert( n==0 || (pOp->p2>0 && pOp->p2+n<=(p->nMem+1 - p->nCursor)+1) );
  assert( pOp->p3<pOp->p2 || pOp->p3>=pOp->p2+n );

  /* Allocate space for (a) the context object and (n-1) extra pointers
  ** to append to the sqlite3_context.argv[1] array, and (b) a memory
  ** cell in which to store the accumulation. Be careful that the memory
  ** cell is 8-byte aligned, even on platforms where a pointer is 32-bits.
  **
  ** Note: We could avoid this by using a regular memory cell from aMem[] for 
  ** the accumulator, instead of allocating one here. */
  nAlloc = ROUND8P( sizeof(pCtx[0]) + (n-1)*sizeof(sqlite3_value*) );
  pCtx = sqlite3DbMallocRawNN(db, nAlloc + sizeof(Mem));

  if( pCtx==0 ) goto no_mem;

  pCtx->pOut = (Mem*)((u8*)pCtx + nAlloc);
  assert( EIGHT_BYTE_ALIGNMENT(pCtx->pOut) );

  sqlite3VdbeMemInit(pCtx->pOut, db, MEM_Null);
  pCtx->pMem = 0;
  pCtx->pFunc = pOp->p4.pFunc;
  pCtx->iOp = (int)(pOp - aOp);
  pCtx->pVdbe = p;
  pCtx->skipFlag = 0;
  pCtx->isError = 0;
  pCtx->enc = encoding;
  pCtx->argc = n;