SQLite

Check-in [d0bf73d814]
Login

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

Overview
Comment:Changes to the Mem structure to reduce the frequency of freeing and reallocating the dynamic buffer. (CVS 4928)
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: d0bf73d81453da1d8e602e0445064d9f5e348063
User & Date: danielk1977 2008-03-28 15:44:10.000
Context
2008-03-28
17:41
Change the pager's sector size algorithm to the maximum of the size reported by xSectorSize() from the VFS and 512. It was using the maximum of xSectorSize() and the current page size, but that was adding an extra 512 bytes to the size of the journal file in the common case. (CVS 4929) (check-in: 17ea0c97a8 user: drh tags: trunk)
15:44
Changes to the Mem structure to reduce the frequency of freeing and reallocating the dynamic buffer. (CVS 4928) (check-in: d0bf73d814 user: danielk1977 tags: trunk)
12:53
Patch to the new memory tracing logic that allows it to build even if memory debugging is turned off. (CVS 4927) (check-in: 0a9c63b227 user: drh tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/test_malloc.c.
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
**    May you share freely, never taking more than you give.
**
*************************************************************************
**
** This file contains code used to implement test interfaces to the
** memory allocation subsystem.
**
** $Id: test_malloc.c,v 1.21 2008/03/28 12:53:38 drh Exp $
*/
#include "sqliteInt.h"
#include "tcl.h"
#include <stdlib.h>
#include <string.h>
#include <assert.h>








|







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
**    May you share freely, never taking more than you give.
**
*************************************************************************
**
** This file contains code used to implement test interfaces to the
** memory allocation subsystem.
**
** $Id: test_malloc.c,v 1.22 2008/03/28 15:44:10 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "tcl.h"
#include <stdlib.h>
#include <string.h>
#include <assert.h>

542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
    }

    pLog->nCall++;
    pLog->nByte += nByte;
  }
}

static int test_memdebug_log_clear(){
  Tcl_HashSearch search;
  Tcl_HashEntry *pEntry;
  for(
    pEntry=Tcl_FirstHashEntry(&aMallocLog, &search);
    pEntry;
    pEntry=Tcl_NextHashEntry(&search)
  ){







|







542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
    }

    pLog->nCall++;
    pLog->nByte += nByte;
  }
}

static void test_memdebug_log_clear(){
  Tcl_HashSearch search;
  Tcl_HashEntry *pEntry;
  for(
    pEntry=Tcl_FirstHashEntry(&aMallocLog, &search);
    pEntry;
    pEntry=Tcl_NextHashEntry(&search)
  ){
Changes to src/utf.c.
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains routines used to translate between UTF-8, 
** UTF-16, UTF-16BE, and UTF-16LE.
**
** $Id: utf.c,v 1.60 2008/02/13 18:25:27 danielk1977 Exp $
**
** Notes on UTF-8:
**
**   Byte-0    Byte-1    Byte-2    Byte-3    Value
**  0xxxxxxx                                 00000000 00000000 0xxxxxxx
**  110yyyyy  10xxxxxx                       00000000 00000yyy yyxxxxxx
**  1110zzzz  10yyyyyy  10xxxxxx             00000000 zzzzyyyy yyxxxxxx







|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains routines used to translate between UTF-8, 
** UTF-16, UTF-16BE, and UTF-16LE.
**
** $Id: utf.c,v 1.61 2008/03/28 15:44:10 danielk1977 Exp $
**
** Notes on UTF-8:
**
**   Byte-0    Byte-1    Byte-2    Byte-3    Value
**  0xxxxxxx                                 00000000 00000000 0xxxxxxx
**  110yyyyy  10xxxxxx                       00000000 00000yyy yyxxxxxx
**  1110zzzz  10yyyyyy  10xxxxxx             00000000 zzzzyyyy yyxxxxxx
302
303
304
305
306
307
308

309
310
311
312
313
314
315
  assert( (pMem->n+(desiredEnc==SQLITE_UTF8?1:2))<=len );

  sqlite3VdbeMemRelease(pMem);
  pMem->flags &= ~(MEM_Static|MEM_Dyn|MEM_Ephem);
  pMem->enc = desiredEnc;
  pMem->flags |= (MEM_Term|MEM_Dyn);
  pMem->z = (char*)zOut;


translate_out:
#if defined(TRANSLATE_TRACE) && defined(SQLITE_DEBUG)
  {
    char zBuf[100];
    sqlite3VdbeMemPrettyPrint(pMem, zBuf);
    fprintf(stderr, "OUTPUT: %s\n", zBuf);







>







302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
  assert( (pMem->n+(desiredEnc==SQLITE_UTF8?1:2))<=len );

  sqlite3VdbeMemRelease(pMem);
  pMem->flags &= ~(MEM_Static|MEM_Dyn|MEM_Ephem);
  pMem->enc = desiredEnc;
  pMem->flags |= (MEM_Term|MEM_Dyn);
  pMem->z = (char*)zOut;
  pMem->zMalloc = pMem->z;

translate_out:
#if defined(TRANSLATE_TRACE) && defined(SQLITE_DEBUG)
  {
    char zBuf[100];
    sqlite3VdbeMemPrettyPrint(pMem, zBuf);
    fprintf(stderr, "OUTPUT: %s\n", zBuf);
Changes to src/vdbe.c.
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
**
** Various scripts scan this source file in order to generate HTML
** documentation, headers files, or other derived files.  The formatting
** of the code in this file is, therefore, important.  See other comments
** 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.720 2008/03/27 22:42:52 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
#include "vdbeInt.h"

/*
** The following global variable is incremented every time a cursor







|







39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
**
** Various scripts scan this source file in order to generate HTML
** documentation, headers files, or other derived files.  The formatting
** of the code in this file is, therefore, important.  See other comments
** 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.721 2008/03/28 15:44:10 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
#include "vdbeInt.h"

/*
** The following global variable is incremented every time a cursor
231
232
233
234
235
236
237

238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
  **
  ** Memory cells for cursors are allocated at the top of the address
  ** space. Memory cell (p->nMem) corresponds to cursor 0. Space for
  ** cursor 1 is managed by memory cell (p->nMem-1), etc.
  */
  Mem *pMem = &p->aMem[p->nMem-iCur];


  Cursor *pCx = 0;
  /* If the opcode of pOp is OP_SetNumColumns, then pOp->p2 contains
  ** the number of fields in the records contained in the table or
  ** index being opened. Use this to reserve space for the 
  ** Cursor.aType[] array.
  */
  int nField = 0;
  if( pOp->opcode==OP_SetNumColumns || pOp->opcode==OP_OpenEphemeral ){
    nField = pOp->p2;
  }


  int nByte = 
      sizeof(Cursor) + 
      (isBtreeCursor?sqlite3BtreeCursorSize():0) + 
      2*nField*sizeof(u32);

  assert( iCur<p->nCursor );
  if( p->apCsr[iCur] ){
    sqlite3VdbeFreeCursor(p, p->apCsr[iCur]);







>










<
<
|







231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248


249
250
251
252
253
254
255
256
  **
  ** Memory cells for cursors are allocated at the top of the address
  ** space. Memory cell (p->nMem) corresponds to cursor 0. Space for
  ** cursor 1 is managed by memory cell (p->nMem-1), etc.
  */
  Mem *pMem = &p->aMem[p->nMem-iCur];

  int nByte;
  Cursor *pCx = 0;
  /* If the opcode of pOp is OP_SetNumColumns, then pOp->p2 contains
  ** the number of fields in the records contained in the table or
  ** index being opened. Use this to reserve space for the 
  ** Cursor.aType[] array.
  */
  int nField = 0;
  if( pOp->opcode==OP_SetNumColumns || pOp->opcode==OP_OpenEphemeral ){
    nField = pOp->p2;
  }


  nByte = 
      sizeof(Cursor) + 
      (isBtreeCursor?sqlite3BtreeCursorSize():0) + 
      2*nField*sizeof(u32);

  assert( iCur<p->nCursor );
  if( p->apCsr[iCur] ){
    sqlite3VdbeFreeCursor(p, p->apCsr[iCur]);
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
    ** is initialized to a NULL.
    */
    opProperty = opcodeProperty[pOp->opcode];
    if( (opProperty & OPFLG_OUT2_PRERELEASE)!=0 ){
      assert( pOp->p2>0 );
      assert( pOp->p2<=p->nMem );
      pOut = &p->aMem[pOp->p2];
      sqlite3VdbeMemRelease(pOut);
      pOut->flags = MEM_Null;
    }else
 
    /* Do common setup for opcodes marked with one of the following
    ** combinations of properties.
    **
    **           in1







|







663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
    ** is initialized to a NULL.
    */
    opProperty = opcodeProperty[pOp->opcode];
    if( (opProperty & OPFLG_OUT2_PRERELEASE)!=0 ){
      assert( pOp->p2>0 );
      assert( pOp->p2<=p->nMem );
      pOut = &p->aMem[pOp->p2];
      sqlite3VdbeMemReleaseExternal(pOut);
      pOut->flags = MEM_Null;
    }else
 
    /* Do common setup for opcodes marked with one of the following
    ** combinations of properties.
    **
    **           in1
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
  pOp->p1 = strlen(pOp->p4.z);

#ifndef SQLITE_OMIT_UTF16
  if( encoding!=SQLITE_UTF8 ){
    sqlite3VdbeMemSetStr(pOut, pOp->p4.z, -1, SQLITE_UTF8, SQLITE_STATIC);
    if( SQLITE_OK!=sqlite3VdbeChangeEncoding(pOut, encoding) ) goto no_mem;
    if( SQLITE_OK!=sqlite3VdbeMemDynamicify(pOut) ) goto no_mem;
    pOut->flags &= ~(MEM_Dyn);
    pOut->flags |= MEM_Static;
    if( pOp->p4type==P4_DYNAMIC ){
      sqlite3_free(pOp->p4.z);
    }
    pOp->p4type = P4_DYNAMIC;
    pOp->p4.z = pOut->z;
    pOp->p1 = pOut->n;







|







875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
  pOp->p1 = strlen(pOp->p4.z);

#ifndef SQLITE_OMIT_UTF16
  if( encoding!=SQLITE_UTF8 ){
    sqlite3VdbeMemSetStr(pOut, pOp->p4.z, -1, SQLITE_UTF8, SQLITE_STATIC);
    if( SQLITE_OK!=sqlite3VdbeChangeEncoding(pOut, encoding) ) goto no_mem;
    if( SQLITE_OK!=sqlite3VdbeMemDynamicify(pOut) ) goto no_mem;
    pOut->zMalloc = 0;
    pOut->flags |= MEM_Static;
    if( pOp->p4type==P4_DYNAMIC ){
      sqlite3_free(pOp->p4.z);
    }
    pOp->p4type = P4_DYNAMIC;
    pOp->p4.z = pOut->z;
    pOp->p1 = pOut->n;
999
1000
1001
1002
1003
1004
1005


1006

1007
1008
1009
1010
1011
1012
1013
  pIn1 = &p->aMem[pOp->p1];
  REGISTER_TRACE(pOp->p1, pIn1);
  assert( pOp->p2>0 );
  assert( pOp->p2<=p->nMem );
  pOut = &p->aMem[pOp->p2];
  assert( pOut!=pIn1 );
  if( pOp->opcode==OP_Move ){


    sqlite3VdbeMemMove(pOut, pIn1);

  }else{
    sqlite3VdbeMemShallowCopy(pOut, pIn1, MEM_Ephem);
    if( pOp->opcode==OP_Copy ){
      Deephemeralize(pOut);
    }
  }
  REGISTER_TRACE(pOp->p2, pOut);







>
>

>







998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
  pIn1 = &p->aMem[pOp->p1];
  REGISTER_TRACE(pOp->p1, pIn1);
  assert( pOp->p2>0 );
  assert( pOp->p2<=p->nMem );
  pOut = &p->aMem[pOp->p2];
  assert( pOut!=pIn1 );
  if( pOp->opcode==OP_Move ){
    char *zMalloc = pOut->zMalloc;
    pOut->zMalloc = 0;
    sqlite3VdbeMemMove(pOut, pIn1);
    pIn1->zMalloc = zMalloc;
  }else{
    sqlite3VdbeMemShallowCopy(pOut, pIn1, MEM_Ephem);
    if( pOp->opcode==OP_Copy ){
      Deephemeralize(pOut);
    }
  }
  REGISTER_TRACE(pOp->p2, pOut);
1265
1266
1267
1268
1269
1270
1271


1272
1273
1274
1275
1276
1277
1278
    ctx.pFunc = ctx.pVdbeFunc->pFunc;
  }

  assert( pOp->p3>0 && pOp->p3<=p->nMem );
  pOut = &p->aMem[pOp->p3];
  ctx.s.flags = MEM_Null;
  ctx.s.db = db;



  /* The output cell may already have a buffer allocated. Move
  ** the pointer to ctx.s so in case the user-function can use
  ** the already allocated buffer instead of allocating a new one.
  */
  sqlite3VdbeMemMove(&ctx.s, pOut);
  MemSetTypeFlag(&ctx.s, MEM_Null);







>
>







1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
    ctx.pFunc = ctx.pVdbeFunc->pFunc;
  }

  assert( pOp->p3>0 && pOp->p3<=p->nMem );
  pOut = &p->aMem[pOp->p3];
  ctx.s.flags = MEM_Null;
  ctx.s.db = db;
  ctx.s.xDel = 0;
  ctx.s.zMalloc = 0;

  /* The output cell may already have a buffer allocated. Move
  ** the pointer to ctx.s so in case the user-function can use
  ** the already allocated buffer instead of allocating a new one.
  */
  sqlite3VdbeMemMove(&ctx.s, pOut);
  MemSetTypeFlag(&ctx.s, MEM_Null);
1880
1881
1882
1883
1884
1885
1886

1887
1888
1889
1890
1891
1892
1893
  int i;             /* Loop counter */
  char *zData;       /* Part of the record being decoded */
  Mem *pDest;        /* Where to write the extracted value */
  Mem sMem;          /* For storing the record being decoded */

  sMem.flags = 0;
  sMem.db = 0;

  assert( p1<p->nCursor );
  assert( pOp->p3>0 && pOp->p3<=p->nMem );
  pDest = &p->aMem[pOp->p3];
  MemSetTypeFlag(pDest, MEM_Null);

  /* This block sets the variable payloadSize to be the total number of
  ** bytes in the record.







>







1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
  int i;             /* Loop counter */
  char *zData;       /* Part of the record being decoded */
  Mem *pDest;        /* Where to write the extracted value */
  Mem sMem;          /* For storing the record being decoded */

  sMem.flags = 0;
  sMem.db = 0;
  sMem.zMalloc = 0;
  assert( p1<p->nCursor );
  assert( pOp->p3>0 && pOp->p3<=p->nMem );
  pDest = &p->aMem[pOp->p3];
  MemSetTypeFlag(pDest, MEM_Null);

  /* This block sets the variable payloadSize to be the total number of
  ** bytes in the record.
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
        ** table. Set the offset for any extra columns not present in
        ** the record to 0. This tells code below to store a NULL
        ** instead of deserializing a value from the record.
        */
        aOffset[i] = 0;
      }
    }
    Release(&sMem);
    sMem.flags = MEM_Null;

    /* If we have read more header data than was contained in the header,
    ** or if the end of the last field appears to be past the end of the
    ** record, then we must be dealing with a corrupt database.
    */
    if( zIdx>zEndHdr || offset>payloadSize ){







|







2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
        ** table. Set the offset for any extra columns not present in
        ** the record to 0. This tells code below to store a NULL
        ** instead of deserializing a value from the record.
        */
        aOffset[i] = 0;
      }
    }
    sqlite3VdbeMemRelease(&sMem);
    sMem.flags = MEM_Null;

    /* If we have read more header data than was contained in the header,
    ** or if the end of the last field appears to be past the end of the
    ** record, then we must be dealing with a corrupt database.
    */
    if( zIdx>zEndHdr || offset>payloadSize ){
2050
2051
2052
2053
2054
2055
2056
2057
2058



2059
2060
2061
2062
2063
2064
2065
  */
  if( aOffset[p2] ){
    assert( rc==SQLITE_OK );
    if( zRec ){
      if( pDest->flags&MEM_Dyn ){
        sqlite3VdbeSerialGet((u8 *)&zRec[aOffset[p2]], aType[p2], &sMem);
        sMem.db = db; 
        sqlite3VdbeMemCopy(pDest, &sMem);
        assert( !(sMem.flags&MEM_Dyn) );



      }else{
        sqlite3VdbeSerialGet((u8 *)&zRec[aOffset[p2]], aType[p2], pDest);
      }
    }else{
      len = sqlite3VdbeSerialTypeLen(aType[p2]);
      sqlite3VdbeMemMove(&sMem, pDest);
      rc = sqlite3VdbeMemFromBtree(pCrsr, aOffset[p2], len, pC->isIndex, &sMem);







|

>
>
>







2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
  */
  if( aOffset[p2] ){
    assert( rc==SQLITE_OK );
    if( zRec ){
      if( pDest->flags&MEM_Dyn ){
        sqlite3VdbeSerialGet((u8 *)&zRec[aOffset[p2]], aType[p2], &sMem);
        sMem.db = db; 
        rc = sqlite3VdbeMemCopy(pDest, &sMem);
        assert( !(sMem.flags&MEM_Dyn) );
        if( rc!=SQLITE_OK ){
          goto op_column_out;
        }
      }else{
        sqlite3VdbeSerialGet((u8 *)&zRec[aOffset[p2]], aType[p2], pDest);
      }
    }else{
      len = sqlite3VdbeSerialTypeLen(aType[p2]);
      sqlite3VdbeMemMove(&sMem, pDest);
      rc = sqlite3VdbeMemFromBtree(pCrsr, aOffset[p2], len, pC->isIndex, &sMem);
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092

2093
2094
2095
2096
2097
2098
2099
  }

  /* If we dynamically allocated space to hold the data (in the
  ** sqlite3VdbeMemFromBtree() call above) then transfer control of that
  ** dynamically allocated space over to the pDest structure.
  ** This prevents a memory copy.
  */
  if( (sMem.flags & MEM_Dyn)!=0 ){
    assert( !sMem.xDel );
    assert( !(pDest->flags & MEM_Dyn) );
    assert( !(pDest->flags & (MEM_Blob|MEM_Str)) || pDest->z==sMem.z );
    pDest->flags &= ~(MEM_Ephem|MEM_Static);
    pDest->flags |= MEM_Dyn|MEM_Term;
    pDest->z = sMem.z;

  }

  rc = sqlite3VdbeMemMakeWriteable(pDest);

op_column_out:
  UPDATE_MAX_BLOBSIZE(pDest);
  REGISTER_TRACE(pOp->p3, pDest);







|
|



|

>







2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
  }

  /* If we dynamically allocated space to hold the data (in the
  ** sqlite3VdbeMemFromBtree() call above) then transfer control of that
  ** dynamically allocated space over to the pDest structure.
  ** This prevents a memory copy.
  */
  if( sMem.zMalloc ){
    assert( sMem.z==sMem.zMalloc );
    assert( !(pDest->flags & MEM_Dyn) );
    assert( !(pDest->flags & (MEM_Blob|MEM_Str)) || pDest->z==sMem.z );
    pDest->flags &= ~(MEM_Ephem|MEM_Static);
    pDest->flags |= MEM_Term;
    pDest->z = sMem.z;
    pDest->zMalloc = sMem.zMalloc;
  }

  rc = sqlite3VdbeMemMakeWriteable(pDest);

op_column_out:
  UPDATE_MAX_BLOBSIZE(pDest);
  REGISTER_TRACE(pOp->p3, pDest);
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302

3303
3304
3305
3306
3307
3308
3309
  }
  if( pC->pseudoTable ){
    if( !pC->ephemPseudoTable ){
      sqlite3_free(pC->pData);
    }
    pC->iKey = iKey;
    pC->nData = pData->n;
    if( pData->flags & MEM_Dyn ){
      pC->pData = pData->z;
      if( !pC->ephemPseudoTable ){
        pData->flags &= ~MEM_Dyn;
        pData->flags |= MEM_Ephem;

      }
    }else{
      pC->pData = sqlite3_malloc( pC->nData+2 );
      if( !pC->pData ) goto no_mem;
      memcpy(pC->pData, pData->z, pC->nData);
      pC->pData[pC->nData] = 0;
      pC->pData[pC->nData+1] = 0;







|




>







3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
  }
  if( pC->pseudoTable ){
    if( !pC->ephemPseudoTable ){
      sqlite3_free(pC->pData);
    }
    pC->iKey = iKey;
    pC->nData = pData->n;
    if( pData->z==pData->zMalloc || pC->ephemPseudoTable ){
      pC->pData = pData->z;
      if( !pC->ephemPseudoTable ){
        pData->flags &= ~MEM_Dyn;
        pData->flags |= MEM_Ephem;
        pData->zMalloc = 0;
      }
    }else{
      pC->pData = sqlite3_malloc( pC->nData+2 );
      if( !pC->pData ) goto no_mem;
      memcpy(pC->pData, pData->z, pC->nData);
      pC->pData[pC->nData] = 0;
      pC->pData[pC->nData+1] = 0;
4258
4259
4260
4261
4262
4263
4264

4265
4266
4267
4268
4269
4270
4271
  }
  ctx.pFunc = pOp->p4.pFunc;
  assert( pOp->p3>0 && pOp->p3<=p->nMem );
  ctx.pMem = pMem = &p->aMem[pOp->p3];
  pMem->n++;
  ctx.s.flags = MEM_Null;
  ctx.s.z = 0;

  ctx.s.xDel = 0;
  ctx.s.db = db;
  ctx.isError = 0;
  ctx.pColl = 0;
  if( ctx.pFunc->needCollSeq ){
    assert( pOp>p->aOp );
    assert( pOp[-1].p4type==P4_COLLSEQ );







>







4268
4269
4270
4271
4272
4273
4274
4275
4276
4277
4278
4279
4280
4281
4282
  }
  ctx.pFunc = pOp->p4.pFunc;
  assert( pOp->p3>0 && pOp->p3<=p->nMem );
  ctx.pMem = pMem = &p->aMem[pOp->p3];
  pMem->n++;
  ctx.s.flags = MEM_Null;
  ctx.s.z = 0;
  ctx.s.zMalloc = 0;
  ctx.s.xDel = 0;
  ctx.s.db = db;
  ctx.isError = 0;
  ctx.pColl = 0;
  if( ctx.pFunc->needCollSeq ){
    assert( pOp>p->aOp );
    assert( pOp[-1].p4type==P4_COLLSEQ );
Changes to src/vdbeInt.h.
120
121
122
123
124
125
126

127
128
129
130
131
132
133
  sqlite3 *db;        /* The associated database connection */
  char *z;            /* String or BLOB value */
  int n;              /* Number of characters in string value, excluding '\0' */
  u16 flags;          /* Some combination of MEM_Null, MEM_Str, MEM_Dyn, etc. */
  u8  type;           /* One of SQLITE_NULL, SQLITE_TEXT, SQLITE_INTEGER, etc */
  u8  enc;            /* SQLITE_UTF8, SQLITE_UTF16BE, SQLITE_UTF16LE */
  void (*xDel)(void *);  /* If not null, call this function to delete Mem.z */

};

/* One or more of the following flags are set to indicate the validOK
** representations of the value stored in the Mem struct.
**
** If the MEM_Null flag is set, then the value is an SQL NULL value.
** No other flags may be set in this case.







>







120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
  sqlite3 *db;        /* The associated database connection */
  char *z;            /* String or BLOB value */
  int n;              /* Number of characters in string value, excluding '\0' */
  u16 flags;          /* Some combination of MEM_Null, MEM_Str, MEM_Dyn, etc. */
  u8  type;           /* One of SQLITE_NULL, SQLITE_TEXT, SQLITE_INTEGER, etc */
  u8  enc;            /* SQLITE_UTF8, SQLITE_UTF16BE, SQLITE_UTF16LE */
  void (*xDel)(void *);  /* If not null, call this function to delete Mem.z */
  char *zMalloc;      /* Dynamic buffer allocated by sqlite3_malloc() */
};

/* One or more of the following flags are set to indicate the validOK
** representations of the value stored in the Mem struct.
**
** If the MEM_Null flag is set, then the value is an SQL NULL value.
** No other flags may be set in this case.
411
412
413
414
415
416
417

418
419
420
421
422
423
424
int sqlite3VdbeMemIntegerify(Mem*);
double sqlite3VdbeRealValue(Mem*);
void sqlite3VdbeIntegerAffinity(Mem*);
int sqlite3VdbeMemRealify(Mem*);
int sqlite3VdbeMemNumerify(Mem*);
int sqlite3VdbeMemFromBtree(BtCursor*,int,int,int,Mem*);
void sqlite3VdbeMemRelease(Mem *p);

int sqlite3VdbeMemFinalize(Mem*, FuncDef*);
const char *sqlite3OpcodeName(int);
int sqlite3VdbeOpcodeHasProperty(int, int);
int sqlite3VdbeMemGrow(Mem *pMem, int n, int preserve);
int sqlite3VdbeReleaseBuffers(Vdbe *p);

#ifndef NDEBUG







>







412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
int sqlite3VdbeMemIntegerify(Mem*);
double sqlite3VdbeRealValue(Mem*);
void sqlite3VdbeIntegerAffinity(Mem*);
int sqlite3VdbeMemRealify(Mem*);
int sqlite3VdbeMemNumerify(Mem*);
int sqlite3VdbeMemFromBtree(BtCursor*,int,int,int,Mem*);
void sqlite3VdbeMemRelease(Mem *p);
void sqlite3VdbeMemReleaseExternal(Mem *p);
int sqlite3VdbeMemFinalize(Mem*, FuncDef*);
const char *sqlite3OpcodeName(int);
int sqlite3VdbeOpcodeHasProperty(int, int);
int sqlite3VdbeMemGrow(Mem *pMem, int n, int preserve);
int sqlite3VdbeReleaseBuffers(Vdbe *p);

#ifndef NDEBUG
Changes to src/vdbeapi.c.
610
611
612
613
614
615
616

617
618
619

620
621
622
623


624
625
626
627
628
629
630
void *sqlite3_aggregate_context(sqlite3_context *p, int nByte){
  Mem *pMem;
  assert( p && p->pFunc && p->pFunc->xStep );
  assert( sqlite3_mutex_held(p->s.db->mutex) );
  pMem = p->pMem;
  if( (pMem->flags & MEM_Agg)==0 ){
    if( nByte==0 ){

      assert( pMem->flags==MEM_Null );
      pMem->z = 0;
    }else{

      pMem->flags = MEM_Agg;
      pMem->xDel = sqlite3_free;
      pMem->u.pDef = p->pFunc;
      pMem->z = sqlite3DbMallocZero(p->s.db, nByte);


    }
  }
  return (void*)pMem->z;
}

/*
** Return the auxilary data pointer, if any, for the iArg'th argument to







>
|


>

<

|
>
>







610
611
612
613
614
615
616
617
618
619
620
621
622

623
624
625
626
627
628
629
630
631
632
633
void *sqlite3_aggregate_context(sqlite3_context *p, int nByte){
  Mem *pMem;
  assert( p && p->pFunc && p->pFunc->xStep );
  assert( sqlite3_mutex_held(p->s.db->mutex) );
  pMem = p->pMem;
  if( (pMem->flags & MEM_Agg)==0 ){
    if( nByte==0 ){
      sqlite3VdbeMemReleaseExternal(pMem);
      pMem->flags = MEM_Null;
      pMem->z = 0;
    }else{
      sqlite3VdbeMemGrow(pMem, nByte, 0);
      pMem->flags = MEM_Agg;

      pMem->u.pDef = p->pFunc;
      if( pMem->z ){
        memset(pMem->z, 0, nByte);
      }
    }
  }
  return (void*)pMem->z;
}

/*
** Return the auxilary data pointer, if any, for the iArg'th argument to
Changes to src/vdbeaux.c.
739
740
741
742
743
744
745
746
747
748

749

750
751
752
753
754
755
756
*/
static void releaseMemArray(Mem *p, int N, int freebuffers){
  if( p && N ){
    sqlite3 *db = p->db;
    int malloc_failed = db->mallocFailed;
    while( N-->0 ){
      assert( N<2 || p[0].db==p[1].db );
      if( freebuffers || p->xDel ){
        sqlite3VdbeMemRelease(p);
        p->flags = MEM_Null;

      }

      p++;
    }
    db->mallocFailed = malloc_failed;
  }
}

#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT







|

|
>

>







739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
*/
static void releaseMemArray(Mem *p, int N, int freebuffers){
  if( p && N ){
    sqlite3 *db = p->db;
    int malloc_failed = db->mallocFailed;
    while( N-->0 ){
      assert( N<2 || p[0].db==p[1].db );
      if( freebuffers ){
        sqlite3VdbeMemRelease(p);
      }else{
        sqlite3VdbeMemReleaseExternal(p);
      }
      p->flags = MEM_Null;
      p++;
    }
    db->mallocFailed = malloc_failed;
  }
}

#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
        p->aMem[n].db = db;
      }
    }
  }
#ifdef SQLITE_DEBUG
  for(n=1; n<p->nMem; n++){
    assert( p->aMem[n].db==db );
    //assert( p->aMem[n].flags==MEM_Null );
  }
#endif

  p->pc = -1;
  p->rc = SQLITE_OK;
  p->uniqueCnt = 0;
  p->returnDepth = 0;







<







1028
1029
1030
1031
1032
1033
1034

1035
1036
1037
1038
1039
1040
1041
        p->aMem[n].db = db;
      }
    }
  }
#ifdef SQLITE_DEBUG
  for(n=1; n<p->nMem; n++){
    assert( p->aMem[n].db==db );

  }
#endif

  p->pc = -1;
  p->rc = SQLITE_OK;
  p->uniqueCnt = 0;
  p->returnDepth = 0;
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
  pColName = &(p->aColName[idx+var*p->nResColumn]);
  if( N==P4_DYNAMIC || N==P4_STATIC ){
    rc = sqlite3VdbeMemSetStr(pColName, zName, -1, SQLITE_UTF8, SQLITE_STATIC);
  }else{
    rc = sqlite3VdbeMemSetStr(pColName, zName, N, SQLITE_UTF8,SQLITE_TRANSIENT);
  }
  if( rc==SQLITE_OK && N==P4_DYNAMIC ){
    pColName->flags = (pColName->flags&(~MEM_Static))|MEM_Dyn;
    pColName->xDel = 0;
  }
  return rc;
}

/*
** A read or write transaction may or may not be active on database handle
** db. If a transaction is active, commit it. If there is a







|
|







1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
  pColName = &(p->aColName[idx+var*p->nResColumn]);
  if( N==P4_DYNAMIC || N==P4_STATIC ){
    rc = sqlite3VdbeMemSetStr(pColName, zName, -1, SQLITE_UTF8, SQLITE_STATIC);
  }else{
    rc = sqlite3VdbeMemSetStr(pColName, zName, N, SQLITE_UTF8,SQLITE_TRANSIENT);
  }
  if( rc==SQLITE_OK && N==P4_DYNAMIC ){
    pColName->flags &= (~MEM_Static);
    pColName->zMalloc = pColName->z;
  }
  return rc;
}

/*
** A read or write transaction may or may not be active on database handle
** db. If a transaction is active, commit it. If there is a
2216
2217
2218
2219
2220
2221
2222

2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
    u32 serial_type;

    idx += GetVarint( aKey+idx, serial_type);
    if( d>=nKey && sqlite3VdbeSerialTypeLen(serial_type)>0 ) break;
    pMem->enc = pKeyInfo->enc;
    pMem->db = pKeyInfo->db;
    pMem->flags = 0;

    d += sqlite3VdbeSerialGet(&aKey[d], serial_type, pMem);
    pMem++;
    i++;
  }
  p->nField = i;
  return (void*)p;
}

/*
** This routine destroys a UnpackedRecord object
*/
void sqlite3VdbeDeleteUnpackedRecord(UnpackedRecord *p){
  if( p ){
    if( p->needDestroy ){
      int i;
      Mem *pMem;
      for(i=0, pMem=p->aMem; i<p->nField; i++, pMem++){
        if( pMem->flags & MEM_Dyn ){
          sqlite3VdbeMemRelease(pMem);
        }
      }
    }
    if( p->needFree ){
      sqlite3_free(p);
    }







>

















|







2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
    u32 serial_type;

    idx += GetVarint( aKey+idx, serial_type);
    if( d>=nKey && sqlite3VdbeSerialTypeLen(serial_type)>0 ) break;
    pMem->enc = pKeyInfo->enc;
    pMem->db = pKeyInfo->db;
    pMem->flags = 0;
    pMem->zMalloc = 0;
    d += sqlite3VdbeSerialGet(&aKey[d], serial_type, pMem);
    pMem++;
    i++;
  }
  p->nField = i;
  return (void*)p;
}

/*
** This routine destroys a UnpackedRecord object
*/
void sqlite3VdbeDeleteUnpackedRecord(UnpackedRecord *p){
  if( p ){
    if( p->needDestroy ){
      int i;
      Mem *pMem;
      for(i=0, pMem=p->aMem; i<p->nField; i++, pMem++){
        if( pMem->zMalloc ){
          sqlite3VdbeMemRelease(pMem);
        }
      }
    }
    if( p->needFree ){
      sqlite3_free(p);
    }
2281
2282
2283
2284
2285
2286
2287

2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312

2313
2314
2315
2316
2317
2318
2319
  KeyInfo *pKeyInfo;
  Mem mem1;

  pKeyInfo = pPKey2->pKeyInfo;
  mem1.enc = pKeyInfo->enc;
  mem1.db = pKeyInfo->db;
  mem1.flags = 0;

  
  idx1 = GetVarint(aKey1, szHdr1);
  d1 = szHdr1;
  nField = pKeyInfo->nField;
  while( idx1<szHdr1 && i<pPKey2->nField ){
    u32 serial_type1;

    /* Read the serial types for the next element in each key. */
    idx1 += GetVarint( aKey1+idx1, serial_type1 );
    if( d1>=nKey1 && sqlite3VdbeSerialTypeLen(serial_type1)>0 ) break;

    /* Extract the values to be compared.
    */
    d1 += sqlite3VdbeSerialGet(&aKey1[d1], serial_type1, &mem1);

    /* Do the comparison
    */
    rc = sqlite3MemCompare(&mem1, &pPKey2->aMem[i],
                           i<nField ? pKeyInfo->aColl[i] : 0);
    if( mem1.flags&MEM_Dyn ) sqlite3VdbeMemRelease(&mem1);
    if( rc!=0 ){
      break;
    }
    i++;
  }


  /* One of the keys ran out of fields, but all the fields up to that point
  ** were equal. If the incrKey flag is true, then the second key is
  ** treated as larger.
  */
  if( rc==0 ){
    if( pKeyInfo->incrKey ){







>



















<





>







2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309

2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
  KeyInfo *pKeyInfo;
  Mem mem1;

  pKeyInfo = pPKey2->pKeyInfo;
  mem1.enc = pKeyInfo->enc;
  mem1.db = pKeyInfo->db;
  mem1.flags = 0;
  mem1.zMalloc = 0;
  
  idx1 = GetVarint(aKey1, szHdr1);
  d1 = szHdr1;
  nField = pKeyInfo->nField;
  while( idx1<szHdr1 && i<pPKey2->nField ){
    u32 serial_type1;

    /* Read the serial types for the next element in each key. */
    idx1 += GetVarint( aKey1+idx1, serial_type1 );
    if( d1>=nKey1 && sqlite3VdbeSerialTypeLen(serial_type1)>0 ) break;

    /* Extract the values to be compared.
    */
    d1 += sqlite3VdbeSerialGet(&aKey1[d1], serial_type1, &mem1);

    /* Do the comparison
    */
    rc = sqlite3MemCompare(&mem1, &pPKey2->aMem[i],
                           i<nField ? pKeyInfo->aColl[i] : 0);

    if( rc!=0 ){
      break;
    }
    i++;
  }
  if( mem1.zMalloc ) sqlite3VdbeMemRelease(&mem1);

  /* One of the keys ran out of fields, but all the fields up to that point
  ** were equal. If the incrKey flag is true, then the second key is
  ** treated as larger.
  */
  if( rc==0 ){
    if( pKeyInfo->incrKey ){
2362
2363
2364
2365
2366
2367
2368

2369
2370
2371
2372
2373
2374
2375

  sqlite3BtreeKeySize(pCur, &nCellKey);
  if( nCellKey<=0 ){
    return SQLITE_CORRUPT_BKPT;
  }
  m.flags = 0;
  m.db = 0;

  rc = sqlite3VdbeMemFromBtree(pCur, 0, nCellKey, 1, &m);
  if( rc ){
    return rc;
  }
  sqlite3GetVarint32((u8*)m.z, &szHdr);
  sqlite3GetVarint32((u8*)&m.z[szHdr-1], &typeRowid);
  lenRowid = sqlite3VdbeSerialTypeLen(typeRowid);







>







2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379

  sqlite3BtreeKeySize(pCur, &nCellKey);
  if( nCellKey<=0 ){
    return SQLITE_CORRUPT_BKPT;
  }
  m.flags = 0;
  m.db = 0;
  m.zMalloc = 0;
  rc = sqlite3VdbeMemFromBtree(pCur, 0, nCellKey, 1, &m);
  if( rc ){
    return rc;
  }
  sqlite3GetVarint32((u8*)m.z, &szHdr);
  sqlite3GetVarint32((u8*)&m.z[szHdr-1], &typeRowid);
  lenRowid = sqlite3VdbeSerialTypeLen(typeRowid);
2405
2406
2407
2408
2409
2410
2411

2412
2413
2414
2415
2416
2417
2418
  sqlite3BtreeKeySize(pCur, &nCellKey);
  if( nCellKey<=0 ){
    *res = 0;
    return SQLITE_OK;
  }
  m.db = 0;
  m.flags = 0;

  rc = sqlite3VdbeMemFromBtree(pC->pCursor, 0, nCellKey, 1, &m);
  if( rc ){
    return rc;
  }
  lenRowid = sqlite3VdbeIdxRowidLen((u8*)m.z);
  pRec = sqlite3VdbeRecordUnpack(pC->pKeyInfo, nKey, pKey,
                                zSpace, sizeof(zSpace));







>







2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
  sqlite3BtreeKeySize(pCur, &nCellKey);
  if( nCellKey<=0 ){
    *res = 0;
    return SQLITE_OK;
  }
  m.db = 0;
  m.flags = 0;
  m.zMalloc = 0;
  rc = sqlite3VdbeMemFromBtree(pC->pCursor, 0, nCellKey, 1, &m);
  if( rc ){
    return rc;
  }
  lenRowid = sqlite3VdbeIdxRowidLen((u8*)m.z);
  pRec = sqlite3VdbeRecordUnpack(pC->pKeyInfo, nKey, pKey,
                                zSpace, sizeof(zSpace));
Changes to src/vdbemem.c.
69
70
71
72
73
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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
** be discarded.  
**
** This function sets the MEM_Dyn flag and clears any xDel callback.
** It also clears MEM_Ephem and MEM_Static. If the preserve flag is 
** not set, Mem.n is zeroed.
*/
int sqlite3VdbeMemGrow(Mem *pMem, int n, int preserve){
  int f = pMem->flags;

  assert( (f & (MEM_Dyn|MEM_Static|MEM_Ephem))==0 

       || (f & (MEM_Dyn|MEM_Static|MEM_Ephem))==MEM_Dyn 
       || (f & (MEM_Dyn|MEM_Static|MEM_Ephem))==MEM_Ephem 
       || (f & (MEM_Dyn|MEM_Static|MEM_Ephem))==MEM_Static 
  );

  if( (f&MEM_Dyn)==0 || pMem->xDel || sqlite3MallocSize(pMem->z)<n ){

    /* Allocate the new buffer. The minimum allocation size is 32 bytes. */
    char *z = 0;
    if( n>0 ){
      if( preserve && (f&MEM_Dyn) && !pMem->xDel ){
        z = sqlite3DbReallocOrFree(pMem->db, pMem->z, n);
        pMem->z = 0;
        preserve = 0;
      }else{

        z = sqlite3DbMallocRaw(pMem->db, (n>32?n:32));
      }
      if( !z ){
        sqlite3VdbeMemRelease(pMem);
        pMem->flags = MEM_Null;
        return SQLITE_NOMEM;
      }
    }

    /* If the value is currently a string or blob and the preserve flag
    ** is true, copy the content to the new buffer. 
    */
    if( pMem->flags&(MEM_Blob|MEM_Str) && preserve ){
      int nCopy = (pMem->n>n?n:pMem->n);
      memcpy(z, pMem->z, nCopy);
    }


 
    /* Release the old buffer. */
    sqlite3VdbeMemRelease(pMem);

    pMem->z = z;
    pMem->flags |= MEM_Dyn;
    pMem->flags &= ~(MEM_Ephem|MEM_Static);
    pMem->xDel = 0;
  }
  return SQLITE_OK;
}

/*
** Make the given Mem object MEM_Dyn.
**
** Return SQLITE_OK on success or SQLITE_NOMEM if malloc fails.
*/
int sqlite3VdbeMemDynamicify(Mem *pMem){
  int f;
  assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
  expandBlob(pMem);
  f = pMem->flags;
  if( (f&(MEM_Str|MEM_Blob)) && ((f&MEM_Dyn)==0 || pMem->xDel) ){
    if( sqlite3VdbeMemGrow(pMem, pMem->n + 2, 1) ){
      return SQLITE_NOMEM;
    }
    pMem->z[pMem->n] = 0;
    pMem->z[pMem->n+1] = 0;
    pMem->flags |= MEM_Term;
  }







<
<
|
>
|
|
|


|
|
<
<
<
|
|
<
|
|
>
|
|
<
<
<
<
|
|
|
<
<
<
<
<
|
|
>
>
|
<
<

|
<
|
|
<
|












|







69
70
71
72
73
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
118
119
120
121
122
123
124
** be discarded.  
**
** This function sets the MEM_Dyn flag and clears any xDel callback.
** It also clears MEM_Ephem and MEM_Static. If the preserve flag is 
** not set, Mem.n is zeroed.
*/
int sqlite3VdbeMemGrow(Mem *pMem, int n, int preserve){


  assert( 1 >=
    ((pMem->zMalloc && pMem->zMalloc==pMem->z) ? 1 : 0) +
    (((pMem->flags&MEM_Dyn)&&pMem->xDel) ? 1 : 0) + 
    ((pMem->flags&MEM_Ephem) ? 1 : 0) + 
    ((pMem->flags&MEM_Static) ? 1 : 0)
  );

  if( sqlite3MallocSize(pMem->zMalloc)<n ){
    n = (n>32?n:32);



    if( preserve && pMem->z==pMem->zMalloc ){
      pMem->z = pMem->zMalloc = sqlite3DbReallocOrFree(pMem->db, pMem->z, n);

      preserve = 0;
    }else{
      sqlite3_free(pMem->zMalloc);
      pMem->zMalloc = sqlite3DbMallocRaw(pMem->db, n);
    }




  }

  if( preserve && pMem->z && pMem->zMalloc && pMem->z!=pMem->zMalloc ){





    memcpy(pMem->zMalloc, pMem->z, pMem->n);
  }
  if( pMem->xDel && pMem->flags&MEM_Dyn){
    pMem->xDel((void *)(pMem->z));
  }



  pMem->z = pMem->zMalloc;

  pMem->flags &= ~(MEM_Ephem|MEM_Static);
  pMem->xDel = 0;

  return (pMem->z ? SQLITE_OK : SQLITE_NOMEM);
}

/*
** Make the given Mem object MEM_Dyn.
**
** Return SQLITE_OK on success or SQLITE_NOMEM if malloc fails.
*/
int sqlite3VdbeMemDynamicify(Mem *pMem){
  int f;
  assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
  expandBlob(pMem);
  f = pMem->flags;
  if( (f&(MEM_Str|MEM_Blob)) && pMem->z!=pMem->zMalloc ){
    if( sqlite3VdbeMemGrow(pMem, pMem->n + 2, 1) ){
      return SQLITE_NOMEM;
    }
    pMem->z[pMem->n] = 0;
    pMem->z[pMem->n+1] = 0;
    pMem->flags |= MEM_Term;
  }
255
256
257
258
259
260
261

262
263
264
265
266
267
268
269
270
271
272
273

















274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294

295
296
297
298
299
300
301
302
303
  int rc = SQLITE_OK;
  if( pFunc && pFunc->xFinalize ){
    sqlite3_context ctx;
    assert( (pMem->flags & MEM_Null)!=0 || pFunc==pMem->u.pDef );
    assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
    ctx.s.flags = MEM_Null;
    ctx.s.db = pMem->db;

    ctx.pMem = pMem;
    ctx.pFunc = pFunc;
    ctx.isError = 0;
    pFunc->xFinalize(&ctx);
    if( pMem->z ){
      sqlite3_free( pMem->z );
    }
    *pMem = ctx.s;
    rc = (ctx.isError?SQLITE_ERROR:SQLITE_OK);
  }
  return rc;
}


















/*
** Release any memory held by the Mem. This may leave the Mem in an
** inconsistent state, for example with (Mem.z==0) and
** (Mem.type==SQLITE_TEXT).
*/
void sqlite3VdbeMemRelease(Mem *p){
  assert( p->db==0 || sqlite3_mutex_held(p->db->mutex) );
  if( p->flags & (MEM_Dyn|MEM_Agg) ){
    if( p->xDel ){
      if( p->flags & MEM_Agg ){
        sqlite3VdbeMemFinalize(p, p->u.pDef);
        assert( (p->flags & MEM_Agg)==0 );
        sqlite3VdbeMemRelease(p);
      }else{
        p->xDel((void *)p->z);
      }
    }else{
      sqlite3_free(p->z);
    }
    p->z = 0;

    p->xDel = 0;
  }
}

/*
** Convert a 64-bit IEEE double into a 64-bit signed integer.
** If the double is too large, return 0x8000000000000000.
**
** Most systems appear to do this simply by assigning







>




|
|
<





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







<
<
<
<
<
<
|
<
<
<
<
|
<
|
>
|
<







240
241
242
243
244
245
246
247
248
249
250
251
252
253

254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282






283




284

285
286
287

288
289
290
291
292
293
294
  int rc = SQLITE_OK;
  if( pFunc && pFunc->xFinalize ){
    sqlite3_context ctx;
    assert( (pMem->flags & MEM_Null)!=0 || pFunc==pMem->u.pDef );
    assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
    ctx.s.flags = MEM_Null;
    ctx.s.db = pMem->db;
    ctx.s.zMalloc = 0;
    ctx.pMem = pMem;
    ctx.pFunc = pFunc;
    ctx.isError = 0;
    pFunc->xFinalize(&ctx);
    assert( !pMem->xDel || 0==(pMem->flags&MEM_Dyn) );
    sqlite3_free(pMem->zMalloc);

    *pMem = ctx.s;
    rc = (ctx.isError?SQLITE_ERROR:SQLITE_OK);
  }
  return rc;
}

/*
** If the memory cell contains a string value that must be freed by
** invoking an external callback, free it now. Calling this function
** does not free any Mem.zMalloc buffer.
*/
void sqlite3VdbeMemReleaseExternal(Mem *p){
  assert( p->db==0 || sqlite3_mutex_held(p->db->mutex) );
  if( p->flags&MEM_Agg ){
    sqlite3VdbeMemFinalize(p, p->u.pDef);
    assert( (p->flags & MEM_Agg)==0 );
    sqlite3VdbeMemRelease(p);
  }else if( p->xDel && p->flags&MEM_Dyn ){
    p->xDel((void *)p->z);
    p->xDel = 0;
  }
}

/*
** Release any memory held by the Mem. This may leave the Mem in an
** inconsistent state, for example with (Mem.z==0) and
** (Mem.type==SQLITE_TEXT).
*/
void sqlite3VdbeMemRelease(Mem *p){






  sqlite3VdbeMemReleaseExternal(p);




  sqlite3_free(p->zMalloc);

  p->z = 0;
  p->zMalloc = 0;
  p->xDel = 0;

}

/*
** Convert a 64-bit IEEE double into a 64-bit signed integer.
** If the double is too large, return 0x8000000000000000.
**
** Most systems appear to do this simply by assigning
510
511
512
513
514
515
516


517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578

579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600

601
602
603
604
605
606
607
      n += p->u.i;
    }
    return n>p->db->aLimit[SQLITE_LIMIT_LENGTH];
  }
  return 0; 
}



/*
** Make an shallow copy of pFrom into pTo.  Prior contents of
** pTo are freed.  The pFrom->z field is not duplicated.  If
** pFrom->z is used, then pTo->z points to the same thing as pFrom->z
** and flags gets srcType (either MEM_Ephem or MEM_Static).
*/
void sqlite3VdbeMemShallowCopy(Mem *pTo, const Mem *pFrom, int srcType){
  sqlite3VdbeMemRelease(pTo);
  memcpy(pTo, pFrom, sizeof(*pFrom));
  pTo->xDel = 0;
  if( pTo->flags&MEM_Dyn ){
    pTo->flags &= ~(MEM_Dyn|MEM_Static|MEM_Ephem);
    assert( srcType==MEM_Ephem || srcType==MEM_Static );
    pTo->flags |= srcType;
  }
}

/*
** Make a full copy of pFrom into pTo.  Prior contents of pTo are
** freed before the copy is made.
*/
int sqlite3VdbeMemCopy(Mem *pTo, const Mem *pFrom){
  int rc = SQLITE_OK;
  char *zBuf = 0;

  /* If cell pTo currently has a reusable buffer, save a pointer to it
  ** in local variable zBuf. This function attempts to avoid freeing
  ** this buffer.
  */
  if( pTo->flags&MEM_Dyn ){
    if( pTo->xDel ){
      sqlite3VdbeMemRelease(pTo);
    }else{
      zBuf = pTo->z;
    }
  }

  /* Copy the contents of *pFrom to *pTo */
  memcpy(pTo, pFrom, sizeof(*pFrom));

  if( pTo->flags&(MEM_Str|MEM_Blob) && pTo->flags&MEM_Static ){
    /* pFrom contained a pointer to a static string. In this case,
    ** free any dynamically allocated buffer associated with pTo.
    */
    sqlite3_free(zBuf);
  }else{
    char *zData = pTo->z;

    pTo->z = zBuf;
    pTo->flags &= ~(MEM_Static|MEM_Ephem);
    pTo->flags |= MEM_Dyn;
    pTo->xDel = 0;
 
    if( pTo->flags&(MEM_Str|MEM_Blob) ){
      if( sqlite3VdbeMemGrow(pTo, pTo->n+2, 0) ){
        pTo->n = 0;
        rc = SQLITE_NOMEM;
      }else{
        memcpy(pTo->z, zData, pTo->n);
        pTo->z[pTo->n] = '\0';
        pTo->z[pTo->n+1] = '\0';
        pTo->flags |= MEM_Term;

      }
    }
  }
  return rc;
}

/*
** Transfer the contents of pFrom to pTo. Any existing value in pTo is
** freed. If pFrom contains ephemeral data, a copy is made.
**
** pFrom contains an SQL NULL when this routine returns.
*/
void sqlite3VdbeMemMove(Mem *pTo, Mem *pFrom){
  assert( pFrom->db==0 || sqlite3_mutex_held(pFrom->db->mutex) );
  assert( pTo->db==0 || sqlite3_mutex_held(pTo->db->mutex) );
  assert( pFrom->db==0 || pTo->db==0 || pFrom->db==pTo->db );
  if( pTo->flags & MEM_Dyn ){
    sqlite3VdbeMemRelease(pTo);
  }
  memcpy(pTo, pFrom, sizeof(Mem));
  pFrom->flags = MEM_Null;
  pFrom->xDel = 0;

}

/*
** Change the value of a Mem to be a string or a BLOB.
**
** The memory management strategy depends on the value of the xDel
** parameter. If the value passed is SQLITE_TRANSIENT, then the 







>
>







|
|

|












<

<
<
<
<
<
<
|
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
|
<
<
|
|
<
<
|
<
<
<
<
|
>
|
|
|













|
|
<



>







501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532

533






534






535










536


537
538


539




540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559

560
561
562
563
564
565
566
567
568
569
570
      n += p->u.i;
    }
    return n>p->db->aLimit[SQLITE_LIMIT_LENGTH];
  }
  return 0; 
}

#define MEMCELLSIZE (int)(&(((Mem *)0)->zMalloc))

/*
** Make an shallow copy of pFrom into pTo.  Prior contents of
** pTo are freed.  The pFrom->z field is not duplicated.  If
** pFrom->z is used, then pTo->z points to the same thing as pFrom->z
** and flags gets srcType (either MEM_Ephem or MEM_Static).
*/
void sqlite3VdbeMemShallowCopy(Mem *pTo, const Mem *pFrom, int srcType){
  sqlite3VdbeMemReleaseExternal(pTo);
  memcpy(pTo, pFrom, MEMCELLSIZE);
  pTo->xDel = 0;
  if( pFrom->xDel || pFrom->z==pFrom->zMalloc ){
    pTo->flags &= ~(MEM_Dyn|MEM_Static|MEM_Ephem);
    assert( srcType==MEM_Ephem || srcType==MEM_Static );
    pTo->flags |= srcType;
  }
}

/*
** Make a full copy of pFrom into pTo.  Prior contents of pTo are
** freed before the copy is made.
*/
int sqlite3VdbeMemCopy(Mem *pTo, const Mem *pFrom){
  int rc = SQLITE_OK;








  sqlite3VdbeMemReleaseExternal(pTo);






  memcpy(pTo, pFrom, MEMCELLSIZE);










  pTo->flags &= ~MEM_Dyn;



  if( pTo->flags&(MEM_Str|MEM_Blob) ){


    if( 0==(pFrom->flags&MEM_Static) ){




      pTo->flags |= MEM_Ephem;
      rc = sqlite3VdbeMemMakeWriteable(pTo);
    }
  }

  return rc;
}

/*
** Transfer the contents of pFrom to pTo. Any existing value in pTo is
** freed. If pFrom contains ephemeral data, a copy is made.
**
** pFrom contains an SQL NULL when this routine returns.
*/
void sqlite3VdbeMemMove(Mem *pTo, Mem *pFrom){
  assert( pFrom->db==0 || sqlite3_mutex_held(pFrom->db->mutex) );
  assert( pTo->db==0 || sqlite3_mutex_held(pTo->db->mutex) );
  assert( pFrom->db==0 || pTo->db==0 || pFrom->db==pTo->db );

  sqlite3VdbeMemRelease(pTo);

  memcpy(pTo, pFrom, sizeof(Mem));
  pFrom->flags = MEM_Null;
  pFrom->xDel = 0;
  pFrom->zMalloc = 0;
}

/*
** Change the value of a Mem to be a string or a BLOB.
**
** The memory management strategy depends on the value of the xDel
** parameter. If the value passed is SQLITE_TRANSIENT, then the 
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
    if( flags&MEM_Term ){
      nAlloc += (enc==SQLITE_UTF8?1:2);
    }
    if( sqlite3VdbeMemGrow(pMem, nAlloc, 0) ){
      return SQLITE_NOMEM;
    }
    memcpy(pMem->z, z, nAlloc);
    flags |= MEM_Dyn;
  }else{
    sqlite3VdbeMemRelease(pMem);
    pMem->z = (char *)z;
    pMem->xDel = xDel;
    flags |= ((xDel==SQLITE_STATIC)?MEM_Static:MEM_Dyn);
  }








<







618
619
620
621
622
623
624

625
626
627
628
629
630
631
    if( flags&MEM_Term ){
      nAlloc += (enc==SQLITE_UTF8?1:2);
    }
    if( sqlite3VdbeMemGrow(pMem, nAlloc, 0) ){
      return SQLITE_NOMEM;
    }
    memcpy(pMem->z, z, nAlloc);

  }else{
    sqlite3VdbeMemRelease(pMem);
    pMem->z = (char *)z;
    pMem->xDel = xDel;
    flags |= ((xDel==SQLITE_STATIC)?MEM_Static:MEM_Dyn);
  }

Changes to test/quick.test.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24



25
26
27
28
29
30
31
#
#    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 runs all tests.
#
# $Id: quick.test,v 1.74 2008/03/27 15:07:05 drh Exp $

proc lshift {lvar} {
  upvar $lvar l
  set ret [lindex $l 0]
  set l [lrange $l 1 end]
  return $ret
}
while {[set arg [lshift argv]] != ""} {
  switch -- $arg {
    -sharedpagercache {
      sqlite3_enable_shared_cache 1
    }
    -soak {
       set SOAKTEST 1
    }



    default {
      set argv [linsert $argv 0 $arg]
      break
    }
  }
}









|















>
>
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#
#    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 runs all tests.
#
# $Id: quick.test,v 1.75 2008/03/28 15:44:10 danielk1977 Exp $

proc lshift {lvar} {
  upvar $lvar l
  set ret [lindex $l 0]
  set l [lrange $l 1 end]
  return $ret
}
while {[set arg [lshift argv]] != ""} {
  switch -- $arg {
    -sharedpagercache {
      sqlite3_enable_shared_cache 1
    }
    -soak {
       set SOAKTEST 1
    }
    -start {
       set STARTAT "[lshift argv]*"
    }
    default {
      set argv [linsert $argv 0 $arg]
      break
    }
  }
}

93
94
95
96
97
98
99


100
101
102
103
104
105
106
107
108
109
110
111
112
set INCLUDE {
}

foreach testfile [lsort -dictionary [glob $testdir/*.test]] {
  set tail [file tail $testfile]
  if {[lsearch -exact $EXCLUDE $tail]>=0} continue
  if {[llength $INCLUDE]>0 && [lsearch -exact $INCLUDE $tail]<0} continue


  source $testfile
  catch {db close}
  if {$sqlite_open_file_count>0} {
    puts "$tail did not close all files: $sqlite_open_file_count"
    incr nErr
    lappend ::failList $tail
    set sqlite_open_file_count 0
  }
}
source $testdir/misuse.test

set sqlite_open_file_count 0
really_finish_test







>
>













96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
set INCLUDE {
}

foreach testfile [lsort -dictionary [glob $testdir/*.test]] {
  set tail [file tail $testfile]
  if {[lsearch -exact $EXCLUDE $tail]>=0} continue
  if {[llength $INCLUDE]>0 && [lsearch -exact $INCLUDE $tail]<0} continue
  if {[info exists STARTAT] && [string match $STARTAT $tail]} {unset STARTAT}
  if {[info exists STARTAT]} continue
  source $testfile
  catch {db close}
  if {$sqlite_open_file_count>0} {
    puts "$tail did not close all files: $sqlite_open_file_count"
    incr nErr
    lappend ::failList $tail
    set sqlite_open_file_count 0
  }
}
source $testdir/misuse.test

set sqlite_open_file_count 0
really_finish_test
Changes to test/tester.tcl.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 2001 September 15
#
# 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 implements some common TCL routines used for regression
# testing the SQLite library
#
# $Id: tester.tcl,v 1.111 2008/03/28 07:42:54 danielk1977 Exp $


set tcl_precision 15
set sqlite_pending_byte 0x0010000

# 
# Check the command-line arguments for a default soft-heap-limit.













|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 2001 September 15
#
# 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 implements some common TCL routines used for regression
# testing the SQLite library
#
# $Id: tester.tcl,v 1.112 2008/03/28 15:44:10 danielk1977 Exp $


set tcl_precision 15
set sqlite_pending_byte 0x0010000

# 
# Check the command-line arguments for a default soft-heap-limit.
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#
# See the sqlite3_memdebug_backtrace() function in mem2.c or
# test_malloc.c for additional information.
#
for {set i 0} {$i<[llength $argv]} {incr i} {
  if {[lindex $argv $i] eq "--malloctrace"} {
    set argv [lreplace $argv $i $i]
    sqlite3_memdebug_backtrace 5
    sqlite3_memdebug_log start
    set argv [lreplace $argv $i $i]
    set tester_do_malloctrace 1
  }
}
for {set i 0} {$i<[llength $argv]} {incr i} {
  if {[regexp {^--backtrace=(\d+)$} [lindex $argv $i] all value]} {







|







43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#
# See the sqlite3_memdebug_backtrace() function in mem2.c or
# test_malloc.c for additional information.
#
for {set i 0} {$i<[llength $argv]} {incr i} {
  if {[lindex $argv $i] eq "--malloctrace"} {
    set argv [lreplace $argv $i $i]
    sqlite3_memdebug_backtrace 10
    sqlite3_memdebug_log start
    set argv [lreplace $argv $i $i]
    set tester_do_malloctrace 1
  }
}
for {set i 0} {$i<[llength $argv]} {incr i} {
  if {[regexp {^--backtrace=(\d+)$} [lindex $argv $i] all value]} {