/ Check-in [8c2f6952]
Login

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

Overview
Comment:Changes to delay freeing buffers associated with vdbe memory cells until either sqlite3_finalize() or sqlite3_release_memory() is called. (CVS 4922)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 8c2f69521f13bc24cf005520efbe0589eeadd763
User & Date: danielk1977 2008-03-26 18:34:43
Context
2008-03-27
15:07
Added the speed4p.test script for testing performance of views and triggers. (CVS 4923) check-in: adf7645f user: drh tags: trunk
2008-03-26
18:34
Changes to delay freeing buffers associated with vdbe memory cells until either sqlite3_finalize() or sqlite3_release_memory() is called. (CVS 4922) check-in: 8c2f6952 user: danielk1977 tags: trunk
17:18
Work around problems with compilers that do not allow C preprocessor macros with empty arguments. (CVS 4921) check-in: afe1963e user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/malloc.c.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
..
55
56
57
58
59
60
61

62

63
64
65
66
67
68
69
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** Memory allocation functions used throughout sqlite.
**
**
** $Id: malloc.c,v 1.14 2007/10/20 16:36:31 drh Exp $
*/
#include "sqliteInt.h"
#include <stdarg.h>
#include <ctype.h>

/*
** This routine runs when the memory allocator sees that the
................................................................................
}

/*
** Release memory held by SQLite instances created by the current thread.
*/
int sqlite3_release_memory(int n){
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT

  return sqlite3PagerReleaseMemory(n);

#else
  return SQLITE_OK;
#endif
}


/*







|







 







>
|
>







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
..
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** Memory allocation functions used throughout sqlite.
**
**
** $Id: malloc.c,v 1.15 2008/03/26 18:34:43 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include <stdarg.h>
#include <ctype.h>

/*
** This routine runs when the memory allocator sees that the
................................................................................
}

/*
** Release memory held by SQLite instances created by the current thread.
*/
int sqlite3_release_memory(int n){
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
  int nRet = sqlite3VdbeReleaseMemory(n);
  nRet += sqlite3PagerReleaseMemory(n-nRet);
  return nRet;
#else
  return SQLITE_OK;
#endif
}


/*

Changes to src/mutex.c.

15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
..
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
** exclusion and is thus suitable for use only in applications
** that use SQLite in a single thread.  But this implementation
** does do a lot of error checking on mutexes to make sure they
** are called correctly and at appropriate times.  Hence, this
** implementation is suitable for testing.
** debugging purposes
**
** $Id: mutex.c,v 1.16 2007/09/10 16:13:00 danielk1977 Exp $
*/
#include "sqliteInt.h"

#ifdef SQLITE_MUTEX_NOOP_DEBUG
/*
** In this implementation, mutexes do not provide any mutual exclusion.
** But the error checking is provided.  This implementation is useful
................................................................................

/*
** The sqlite3_mutex_alloc() routine allocates a new
** mutex and returns a pointer to it.  If it returns NULL
** that means that a mutex could not be allocated. 
*/
sqlite3_mutex *sqlite3_mutex_alloc(int id){
  static sqlite3_mutex aStatic[5];
  sqlite3_mutex *pNew = 0;
  switch( id ){
    case SQLITE_MUTEX_FAST:
    case SQLITE_MUTEX_RECURSIVE: {
      pNew = sqlite3_malloc(sizeof(*pNew));
      if( pNew ){
        pNew->id = id;







|







 







|







15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
..
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
** exclusion and is thus suitable for use only in applications
** that use SQLite in a single thread.  But this implementation
** does do a lot of error checking on mutexes to make sure they
** are called correctly and at appropriate times.  Hence, this
** implementation is suitable for testing.
** debugging purposes
**
** $Id: mutex.c,v 1.17 2008/03/26 18:34:43 danielk1977 Exp $
*/
#include "sqliteInt.h"

#ifdef SQLITE_MUTEX_NOOP_DEBUG
/*
** In this implementation, mutexes do not provide any mutual exclusion.
** But the error checking is provided.  This implementation is useful
................................................................................

/*
** The sqlite3_mutex_alloc() routine allocates a new
** mutex and returns a pointer to it.  If it returns NULL
** that means that a mutex could not be allocated. 
*/
sqlite3_mutex *sqlite3_mutex_alloc(int id){
  static sqlite3_mutex aStatic[6];
  sqlite3_mutex *pNew = 0;
  switch( id ){
    case SQLITE_MUTEX_FAST:
    case SQLITE_MUTEX_RECURSIVE: {
      pNew = sqlite3_malloc(sizeof(*pNew));
      if( pNew ){
        pNew->id = id;

Changes to src/mutex_os2.c.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
..
92
93
94
95
96
97
98

99
100
101
102
103
104
105
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains the C functions that implement mutexes for OS/2
**
** $Id: mutex_os2.c,v 1.5 2008/02/01 19:42:38 pweilbacher Exp $
*/
#include "sqliteInt.h"

/*
** The code in this file is only used if SQLITE_MUTEX_OS2 is defined.
** See the mutex.h file for details.
*/
................................................................................
        }
      }
      break;
    }
    default: {
      static volatile int isInit = 0;
      static sqlite3_mutex staticMutexes[] = {

        { OS2_MUTEX_INITIALIZER, },
        { OS2_MUTEX_INITIALIZER, },
        { OS2_MUTEX_INITIALIZER, },
        { OS2_MUTEX_INITIALIZER, },
        { OS2_MUTEX_INITIALIZER, },
      };
      if ( !isInit ){







|







 







>







7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
..
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains the C functions that implement mutexes for OS/2
**
** $Id: mutex_os2.c,v 1.6 2008/03/26 18:34:43 danielk1977 Exp $
*/
#include "sqliteInt.h"

/*
** The code in this file is only used if SQLITE_MUTEX_OS2 is defined.
** See the mutex.h file for details.
*/
................................................................................
        }
      }
      break;
    }
    default: {
      static volatile int isInit = 0;
      static sqlite3_mutex staticMutexes[] = {
        { OS2_MUTEX_INITIALIZER, },
        { OS2_MUTEX_INITIALIZER, },
        { OS2_MUTEX_INITIALIZER, },
        { OS2_MUTEX_INITIALIZER, },
        { OS2_MUTEX_INITIALIZER, },
        { OS2_MUTEX_INITIALIZER, },
      };
      if ( !isInit ){

Changes to src/mutex_unix.c.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
..
79
80
81
82
83
84
85

86
87
88
89
90
91
92
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains the C functions that implement mutexes for pthreads
**
** $Id: mutex_unix.c,v 1.5 2007/11/28 14:04:57 drh Exp $
*/
#include "sqliteInt.h"

/*
** The code in this file is only used if we are compiling threadsafe
** under unix with pthreads.
**
................................................................................
** or SQLITE_MUTEX_RECURSIVE) is used then sqlite3_mutex_alloc()
** returns a different mutex on every call.  But for the static 
** mutex types, the same mutex is returned on every call that has
** the same type number.
*/
sqlite3_mutex *sqlite3_mutex_alloc(int iType){
  static sqlite3_mutex staticMutexes[] = {

    { PTHREAD_MUTEX_INITIALIZER, },
    { PTHREAD_MUTEX_INITIALIZER, },
    { PTHREAD_MUTEX_INITIALIZER, },
    { PTHREAD_MUTEX_INITIALIZER, },
    { PTHREAD_MUTEX_INITIALIZER, },
  };
  sqlite3_mutex *p;







|







 







>







7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
..
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains the C functions that implement mutexes for pthreads
**
** $Id: mutex_unix.c,v 1.6 2008/03/26 18:34:43 danielk1977 Exp $
*/
#include "sqliteInt.h"

/*
** The code in this file is only used if we are compiling threadsafe
** under unix with pthreads.
**
................................................................................
** or SQLITE_MUTEX_RECURSIVE) is used then sqlite3_mutex_alloc()
** returns a different mutex on every call.  But for the static 
** mutex types, the same mutex is returned on every call that has
** the same type number.
*/
sqlite3_mutex *sqlite3_mutex_alloc(int iType){
  static sqlite3_mutex staticMutexes[] = {
    { PTHREAD_MUTEX_INITIALIZER, },
    { PTHREAD_MUTEX_INITIALIZER, },
    { PTHREAD_MUTEX_INITIALIZER, },
    { PTHREAD_MUTEX_INITIALIZER, },
    { PTHREAD_MUTEX_INITIALIZER, },
    { PTHREAD_MUTEX_INITIALIZER, },
  };
  sqlite3_mutex *p;

Changes to src/mutex_w32.c.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains the C functions that implement mutexes for win32
**
** $Id: mutex_w32.c,v 1.5 2007/10/05 15:08:01 drh Exp $
*/
#include "sqliteInt.h"

/*
** The code in this file is only used if we are compiling multithreaded
** on a win32 system.
*/
................................................................................
      if( p ){
        p->id = iType;
        InitializeCriticalSection(&p->mutex);
      }
      break;
    }
    default: {
      static sqlite3_mutex staticMutexes[5];
      static int isInit = 0;
      while( !isInit ){
        static long lock = 0;
        if( InterlockedIncrement(&lock)==1 ){
          int i;
          for(i=0; i<sizeof(staticMutexes)/sizeof(staticMutexes[0]); i++){
            InitializeCriticalSection(&staticMutexes[i].mutex);







|







 







|







7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains the C functions that implement mutexes for win32
**
** $Id: mutex_w32.c,v 1.6 2008/03/26 18:34:43 danielk1977 Exp $
*/
#include "sqliteInt.h"

/*
** The code in this file is only used if we are compiling multithreaded
** on a win32 system.
*/
................................................................................
      if( p ){
        p->id = iType;
        InitializeCriticalSection(&p->mutex);
      }
      break;
    }
    default: {
      static sqlite3_mutex staticMutexes[6];
      static int isInit = 0;
      while( !isInit ){
        static long lock = 0;
        if( InterlockedIncrement(&lock)==1 ){
          int i;
          for(i=0; i<sizeof(staticMutexes)/sizeof(staticMutexes[0]); i++){
            InitializeCriticalSection(&staticMutexes[i].mutex);

Changes to src/sqlite.h.in.

26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
....
5436
5437
5438
5439
5440
5441
5442

5443
5444
5445
5446
5447
5448
5449
....
5548
5549
5550
5551
5552
5553
5554

5555
5556
5557
5558
5559
5560
5561
** on how SQLite interfaces are suppose to operate.
**
** The name of this file under configuration management is "sqlite.h.in".
** The makefile makes some minor changes to this file (such as inserting
** the version number) and changes its name to "sqlite3.h" as
** part of the build process.
**
** @(#) $Id: sqlite.h.in,v 1.300 2008/03/24 12:51:46 drh Exp $
*/
#ifndef _SQLITE3_H_
#define _SQLITE3_H_
#include <stdarg.h>     /* Needed for the definition of va_list */

/*
** Make sure we can call this stuff from C++.
................................................................................
** <li>  SQLITE_MUTEX_FAST
** <li>  SQLITE_MUTEX_RECURSIVE
** <li>  SQLITE_MUTEX_STATIC_MASTER
** <li>  SQLITE_MUTEX_STATIC_MEM
** <li>  SQLITE_MUTEX_STATIC_MEM2
** <li>  SQLITE_MUTEX_STATIC_PRNG
** <li>  SQLITE_MUTEX_STATIC_LRU

** </ul> {END}
**
** {F17015} The first two constants cause sqlite3_mutex_alloc() to create
** a new mutex.  The new mutex is recursive when SQLITE_MUTEX_RECURSIVE
** is used but not necessarily so when SQLITE_MUTEX_FAST is used. {END}
** The mutex implementation does not need to make a distinction
** between SQLITE_MUTEX_RECURSIVE and SQLITE_MUTEX_FAST if it does
................................................................................
#define SQLITE_MUTEX_FAST             0
#define SQLITE_MUTEX_RECURSIVE        1
#define SQLITE_MUTEX_STATIC_MASTER    2
#define SQLITE_MUTEX_STATIC_MEM       3  /* sqlite3_malloc() */
#define SQLITE_MUTEX_STATIC_MEM2      4  /* sqlite3_release_memory() */
#define SQLITE_MUTEX_STATIC_PRNG      5  /* sqlite3_random() */
#define SQLITE_MUTEX_STATIC_LRU       6  /* lru page list */


/*
** CAPI3REF: Low-Level Control Of Database Files {F11300}
**
** {F11301} The [sqlite3_file_control()] interface makes a direct call to the
** xFileControl method for the [sqlite3_io_methods] object associated
** with a particular database identified by the second argument. {F11302} The







|







 







>







 







>







26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
....
5436
5437
5438
5439
5440
5441
5442
5443
5444
5445
5446
5447
5448
5449
5450
....
5549
5550
5551
5552
5553
5554
5555
5556
5557
5558
5559
5560
5561
5562
5563
** on how SQLite interfaces are suppose to operate.
**
** The name of this file under configuration management is "sqlite.h.in".
** The makefile makes some minor changes to this file (such as inserting
** the version number) and changes its name to "sqlite3.h" as
** part of the build process.
**
** @(#) $Id: sqlite.h.in,v 1.301 2008/03/26 18:34:43 danielk1977 Exp $
*/
#ifndef _SQLITE3_H_
#define _SQLITE3_H_
#include <stdarg.h>     /* Needed for the definition of va_list */

/*
** Make sure we can call this stuff from C++.
................................................................................
** <li>  SQLITE_MUTEX_FAST
** <li>  SQLITE_MUTEX_RECURSIVE
** <li>  SQLITE_MUTEX_STATIC_MASTER
** <li>  SQLITE_MUTEX_STATIC_MEM
** <li>  SQLITE_MUTEX_STATIC_MEM2
** <li>  SQLITE_MUTEX_STATIC_PRNG
** <li>  SQLITE_MUTEX_STATIC_LRU
** <li>  SQLITE_MUTEX_STATIC_LRU2
** </ul> {END}
**
** {F17015} The first two constants cause sqlite3_mutex_alloc() to create
** a new mutex.  The new mutex is recursive when SQLITE_MUTEX_RECURSIVE
** is used but not necessarily so when SQLITE_MUTEX_FAST is used. {END}
** The mutex implementation does not need to make a distinction
** between SQLITE_MUTEX_RECURSIVE and SQLITE_MUTEX_FAST if it does
................................................................................
#define SQLITE_MUTEX_FAST             0
#define SQLITE_MUTEX_RECURSIVE        1
#define SQLITE_MUTEX_STATIC_MASTER    2
#define SQLITE_MUTEX_STATIC_MEM       3  /* sqlite3_malloc() */
#define SQLITE_MUTEX_STATIC_MEM2      4  /* sqlite3_release_memory() */
#define SQLITE_MUTEX_STATIC_PRNG      5  /* sqlite3_random() */
#define SQLITE_MUTEX_STATIC_LRU       6  /* lru page list */
#define SQLITE_MUTEX_STATIC_LRU2      7  /* lru page list */

/*
** CAPI3REF: Low-Level Control Of Database Files {F11300}
**
** {F11301} The [sqlite3_file_control()] interface makes a direct call to the
** xFileControl method for the [sqlite3_io_methods] object associated
** with a particular database identified by the second argument. {F11302} The

Changes to src/vdbe.h.

11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
...
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184

185
186
187
188
189
190
191
192
193
194
195
196
197
*************************************************************************
** Header file for the Virtual DataBase Engine (VDBE)
**
** This header defines the interface to the virtual database engine
** 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.128 2008/03/25 17:23:34 drh Exp $
*/
#ifndef _SQLITE_VDBE_H_
#define _SQLITE_VDBE_H_
#include <stdio.h>

/*
** A single VDBE is an opaque structure named "Vdbe".  Only routines
................................................................................
int sqlite3VdbeFinalize(Vdbe*);
void sqlite3VdbeResolveLabel(Vdbe*, int);
int sqlite3VdbeCurrentAddr(Vdbe*);
#ifdef SQLITE_DEBUG
  void sqlite3VdbeTrace(Vdbe*,FILE*);
#endif
void sqlite3VdbeResetStepResult(Vdbe*);
int sqlite3VdbeReset(Vdbe*);
void sqlite3VdbeSetNumCols(Vdbe*,int);
int sqlite3VdbeSetColName(Vdbe*, int, int, const char *, int);
void sqlite3VdbeCountChanges(Vdbe*);
sqlite3 *sqlite3VdbeDb(Vdbe*);
void sqlite3VdbeSetSql(Vdbe*, const char *z, int n);
void sqlite3VdbeSwap(Vdbe*,Vdbe*);


UnpackedRecord *sqlite3VdbeRecordUnpack(KeyInfo*,int,const void*,void*,int);
void sqlite3VdbeDeleteUnpackedRecord(UnpackedRecord*);
int sqlite3VdbeRecordCompare(int,const void*,UnpackedRecord*);


#ifndef NDEBUG
  void sqlite3VdbeComment(Vdbe*, const char*, ...);
# define VdbeComment(X)  sqlite3VdbeComment X
#else
# define VdbeComment(X)
#endif

#endif







|







 







|







>













11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
...
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
*************************************************************************
** Header file for the Virtual DataBase Engine (VDBE)
**
** This header defines the interface to the virtual database engine
** 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.129 2008/03/26 18:34:43 danielk1977 Exp $
*/
#ifndef _SQLITE_VDBE_H_
#define _SQLITE_VDBE_H_
#include <stdio.h>

/*
** A single VDBE is an opaque structure named "Vdbe".  Only routines
................................................................................
int sqlite3VdbeFinalize(Vdbe*);
void sqlite3VdbeResolveLabel(Vdbe*, int);
int sqlite3VdbeCurrentAddr(Vdbe*);
#ifdef SQLITE_DEBUG
  void sqlite3VdbeTrace(Vdbe*,FILE*);
#endif
void sqlite3VdbeResetStepResult(Vdbe*);
int sqlite3VdbeReset(Vdbe*, int);
void sqlite3VdbeSetNumCols(Vdbe*,int);
int sqlite3VdbeSetColName(Vdbe*, int, int, const char *, int);
void sqlite3VdbeCountChanges(Vdbe*);
sqlite3 *sqlite3VdbeDb(Vdbe*);
void sqlite3VdbeSetSql(Vdbe*, const char *z, int n);
void sqlite3VdbeSwap(Vdbe*,Vdbe*);

int sqlite3VdbeReleaseMemory(int);
UnpackedRecord *sqlite3VdbeRecordUnpack(KeyInfo*,int,const void*,void*,int);
void sqlite3VdbeDeleteUnpackedRecord(UnpackedRecord*);
int sqlite3VdbeRecordCompare(int,const void*,UnpackedRecord*);


#ifndef NDEBUG
  void sqlite3VdbeComment(Vdbe*, const char*, ...);
# define VdbeComment(X)  sqlite3VdbeComment X
#else
# define VdbeComment(X)
#endif

#endif

Changes to src/vdbeInt.h.

329
330
331
332
333
334
335




336
337
338
339
340
341
342
...
410
411
412
413
414
415
416

417
418
419
420
421
422
423
  FILE *trace;        /* Write an execution trace here, if not NULL */
#endif
  int openedStatement;  /* True if this VM has opened a statement journal */
#ifdef SQLITE_SSE
  int fetchId;          /* Statement number used by sqlite3_fetch_statement */
  int lru;              /* Counter used for LRU cache replacement */
#endif




};

/*
** An instance of the following structure holds information about a
** single index record that has already been parsed out into individual
** values.
**
................................................................................
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);


#ifndef NDEBUG
  void sqlite3VdbeMemSanity(Mem*);
#endif
int sqlite3VdbeMemTranslate(Mem*, u8);
#ifdef SQLITE_DEBUG
  void sqlite3VdbePrintSql(Vdbe*);







>
>
>
>







 







>







329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
...
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
  FILE *trace;        /* Write an execution trace here, if not NULL */
#endif
  int openedStatement;  /* True if this VM has opened a statement journal */
#ifdef SQLITE_SSE
  int fetchId;          /* Statement number used by sqlite3_fetch_statement */
  int lru;              /* Counter used for LRU cache replacement */
#endif
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
  Vdbe *pLruPrev;
  Vdbe *pLruNext;
#endif
};

/*
** An instance of the following structure holds information about a
** single index record that has already been parsed out into individual
** values.
**
................................................................................
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
  void sqlite3VdbeMemSanity(Mem*);
#endif
int sqlite3VdbeMemTranslate(Mem*, u8);
#ifdef SQLITE_DEBUG
  void sqlite3VdbePrintSql(Vdbe*);

Changes to src/vdbeapi.c.

11
12
13
14
15
16
17


























































































































































18
19
20
21
22
23
24
..
44
45
46
47
48
49
50

51
52
53
54
55
56
57
..
65
66
67
68
69
70
71
72

73
74
75
76
77
78
79
...
302
303
304
305
306
307
308

309
310
311
312
313
314
315
...
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
*************************************************************************
**
** This file contains code use to implement APIs that are part of the
** VDBE.
*/
#include "sqliteInt.h"
#include "vdbeInt.h"



























































































































































/*
** Return TRUE (non-zero) of the statement supplied as an argument needs
** to be recompiled.  A statement needs to be recompiled whenever the
** execution environment changes in a way that would alter the program
** that sqlite3_prepare() generates.  For example, if new functions or
** collating sequences are registered or if an authorizer function is
................................................................................
    rc = SQLITE_OK;
  }else{
    Vdbe *v = (Vdbe*)pStmt;
#ifndef SQLITE_MUTEX_NOOP
    sqlite3_mutex *mutex = v->db->mutex;
#endif
    sqlite3_mutex_enter(mutex);

    rc = sqlite3VdbeFinalize(v);
    sqlite3_mutex_leave(mutex);
  }
  return rc;
}

/*
................................................................................
int sqlite3_reset(sqlite3_stmt *pStmt){
  int rc;
  if( pStmt==0 ){
    rc = SQLITE_OK;
  }else{
    Vdbe *v = (Vdbe*)pStmt;
    sqlite3_mutex_enter(v->db->mutex);
    rc = sqlite3VdbeReset(v);

    sqlite3VdbeMakeReady(v, -1, 0, 0, 0);
    assert( (rc & (v->db->errMask))==rc );
    sqlite3_mutex_leave(v->db->mutex);
  }
  return rc;
}

................................................................................
      sqlite3OsCurrentTime(db->pVfs, &rNow);
      p->startTime = (rNow - (int)rNow)*3600.0*24.0*1000000000.0;
    }
#endif

    db->activeVdbeCnt++;
    p->pc = 0;

  }
#ifndef SQLITE_OMIT_EXPLAIN
  if( p->explain ){
    rc = sqlite3VdbeList(p);
  }else
#endif /* SQLITE_OMIT_EXPLAIN */
  {
................................................................................
  if( pStmt ){
    int cnt = 0;
    Vdbe *v = (Vdbe*)pStmt;
    sqlite3 *db = v->db;
    sqlite3_mutex_enter(db->mutex);
    while( (rc = sqlite3Step(v))==SQLITE_SCHEMA
           && cnt++ < 5
           && sqlite3Reprepare(v) ){
      sqlite3_reset(pStmt);
      v->expired = 0;
    }
    if( rc==SQLITE_SCHEMA && v->zSql && db->pErr ){
      /* This case occurs after failing to recompile an sql statement. 
      ** The error message from the SQL compiler has already been loaded 
      ** into the database handle. This block copies the error message 







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







 







>







 







|
>







 







>







 







|







11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
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
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
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
...
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
...
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
...
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
...
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
*************************************************************************
**
** This file contains code use to implement APIs that are part of the
** VDBE.
*/
#include "sqliteInt.h"
#include "vdbeInt.h"

#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
/*
** The following structure contains pointers to the end points of a
** doubly-linked list of all compiled SQL statements that may be holding
** buffers eligible for release when the sqlite3_release_memory() interface is
** invoked. Access to this list is protected by the SQLITE_MUTEX_STATIC_LRU2
** mutex.
**
** Statements are added to the end of this list when sqlite3_reset() is
** called. They are removed either when sqlite3_step() or sqlite3_finalize()
** is called. When statements are added to this list, the associated 
** register array (p->aMem[1..p->nMem]) may contain dynamic buffers that
** can be freed using sqlite3VdbeReleaseMemory().
**
** When statements are added or removed from this list, the mutex
** associated with the Vdbe being added or removed (Vdbe.db->mutex) is
** already held. The LRU2 mutex is then obtained, blocking if necessary,
** the linked-list pointers manipulated and the LRU2 mutex relinquished.
*/
struct StatementLruList {
  Vdbe *pFirst;
  Vdbe *pLast;
};
static struct StatementLruList sqlite3LruStatements;

/*
** Check that the list looks to be internally consistent. This is used
** as part of an assert() statement as follows:
**
**   assert( stmtLruCheck() );
*/
static int stmtLruCheck(){
  Vdbe *p;
  for(p=sqlite3LruStatements.pFirst; p; p=p->pLruNext){
    assert(p->pLruNext || p==sqlite3LruStatements.pLast);
    assert(!p->pLruNext || p->pLruNext->pLruPrev==p);
    assert(p->pLruPrev || p==sqlite3LruStatements.pFirst);
    assert(!p->pLruPrev || p->pLruPrev->pLruNext==p);
  }
  return 1;
}

/*
** Add vdbe p to the end of the statement lru list. It is assumed that
** p is not already part of the list when this is called. The lru list
** is protected by the SQLITE_MUTEX_STATIC_LRU mutex.
*/
static void stmtLruAdd(Vdbe *p){
  sqlite3_mutex_enter(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_LRU2));

  if( p->pLruPrev || p->pLruNext || sqlite3LruStatements.pFirst==p ){
    sqlite3_mutex_leave(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_LRU2));
    return;
  }

  assert( stmtLruCheck() );

  if( !sqlite3LruStatements.pFirst ){
    assert( !sqlite3LruStatements.pLast );
    sqlite3LruStatements.pFirst = p;
    sqlite3LruStatements.pLast = p;
  }else{
    assert( !sqlite3LruStatements.pLast->pLruNext );
    p->pLruPrev = sqlite3LruStatements.pLast;
    sqlite3LruStatements.pLast->pLruNext = p;
    sqlite3LruStatements.pLast = p;
  }

  assert( stmtLruCheck() );

  sqlite3_mutex_leave(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_LRU2));
}

/*
** Assuming the SQLITE_MUTEX_STATIC_LRU2 mutext is already held, remove
** statement p from the least-recently-used statement list. If the 
** statement is not currently part of the list, this call is a no-op.
*/
static void stmtLruRemoveNomutex(Vdbe *p){
  if( p->pLruPrev || p->pLruNext || p==sqlite3LruStatements.pFirst ){
    assert( stmtLruCheck() );
    if( p->pLruNext ){
      p->pLruNext->pLruPrev = p->pLruPrev;
    }else{
      sqlite3LruStatements.pLast = p->pLruPrev;
    }
    if( p->pLruPrev ){
      p->pLruPrev->pLruNext = p->pLruNext;
    }else{
      sqlite3LruStatements.pFirst = p->pLruNext;
    }
    p->pLruNext = 0;
    p->pLruPrev = 0;
    assert( stmtLruCheck() );
  }
}

/*
** Assuming the SQLITE_MUTEX_STATIC_LRU2 mutext is not held, remove
** statement p from the least-recently-used statement list. If the 
** statement is not currently part of the list, this call is a no-op.
*/
static void stmtLruRemove(Vdbe *p){
  sqlite3_mutex_enter(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_LRU2));
  stmtLruRemoveNomutex(p);
  sqlite3_mutex_leave(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_LRU2));
}

/*
** Try to release n bytes of memory by freeing buffers associated 
** with the memory registers of currently unused vdbes.
*/
int sqlite3VdbeReleaseMemory(int n){
  Vdbe *p;
  Vdbe *pNext;
  int nFree = 0;

  sqlite3_mutex_enter(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_LRU2));
  for(p=sqlite3LruStatements.pFirst; p && nFree<n; p=pNext){
    pNext = p->pLruNext;

    /* For each statement handle in the lru list, attempt to obtain the
    ** associated database mutex. If it cannot be obtained, continue
    ** to the next statement handle. It is not possible to block on
    ** the database mutex - that could cause deadlock.
    */
    if( SQLITE_OK==sqlite3_mutex_try(p->db->mutex) ){
      nFree += sqlite3VdbeReleaseBuffers(p);
      stmtLruRemoveNomutex(p);
      sqlite3_mutex_leave(p->db->mutex);
    }
  }
  sqlite3_mutex_leave(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_LRU2));

  return nFree;
}

/*
** Call sqlite3Reprepare() on the statement. Remove it from the
** lru list before doing so, as Reprepare() will free all the
** memory register buffers anyway.
*/
int vdbeReprepare(Vdbe *p){
  stmtLruRemove(p);
  return sqlite3Reprepare(p);
}

#else       /* !SQLITE_ENABLE_MEMORY_MANAGEMENT */
  #define stmtLruRemove(x)
  #define stmtLruAdd(x)
  #define vdbeReprepare(x) sqlite3Reprepare(x)
#endif


/*
** Return TRUE (non-zero) of the statement supplied as an argument needs
** to be recompiled.  A statement needs to be recompiled whenever the
** execution environment changes in a way that would alter the program
** that sqlite3_prepare() generates.  For example, if new functions or
** collating sequences are registered or if an authorizer function is
................................................................................
    rc = SQLITE_OK;
  }else{
    Vdbe *v = (Vdbe*)pStmt;
#ifndef SQLITE_MUTEX_NOOP
    sqlite3_mutex *mutex = v->db->mutex;
#endif
    sqlite3_mutex_enter(mutex);
    stmtLruRemove(v);
    rc = sqlite3VdbeFinalize(v);
    sqlite3_mutex_leave(mutex);
  }
  return rc;
}

/*
................................................................................
int sqlite3_reset(sqlite3_stmt *pStmt){
  int rc;
  if( pStmt==0 ){
    rc = SQLITE_OK;
  }else{
    Vdbe *v = (Vdbe*)pStmt;
    sqlite3_mutex_enter(v->db->mutex);
    rc = sqlite3VdbeReset(v, 0);
    stmtLruAdd(v);
    sqlite3VdbeMakeReady(v, -1, 0, 0, 0);
    assert( (rc & (v->db->errMask))==rc );
    sqlite3_mutex_leave(v->db->mutex);
  }
  return rc;
}

................................................................................
      sqlite3OsCurrentTime(db->pVfs, &rNow);
      p->startTime = (rNow - (int)rNow)*3600.0*24.0*1000000000.0;
    }
#endif

    db->activeVdbeCnt++;
    p->pc = 0;
    stmtLruRemove(p);
  }
#ifndef SQLITE_OMIT_EXPLAIN
  if( p->explain ){
    rc = sqlite3VdbeList(p);
  }else
#endif /* SQLITE_OMIT_EXPLAIN */
  {
................................................................................
  if( pStmt ){
    int cnt = 0;
    Vdbe *v = (Vdbe*)pStmt;
    sqlite3 *db = v->db;
    sqlite3_mutex_enter(db->mutex);
    while( (rc = sqlite3Step(v))==SQLITE_SCHEMA
           && cnt++ < 5
           && vdbeReprepare(v) ){
      sqlite3_reset(pStmt);
      v->expired = 0;
    }
    if( rc==SQLITE_SCHEMA && v->zSql && db->pErr ){
      /* This case occurs after failing to recompile an sql statement. 
      ** The error message from the SQL compiler has already been loaded 
      ** into the database handle. This block copies the error message 

Changes to src/vdbeaux.c.

733
734
735
736
737
738
739
740
741
742
743
744
745

746
747


748
749
750
751

















752
753
754
755
756
757
758
...
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
....
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
....
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
....
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
....
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
....
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
....
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732

1733
1734
1735
1736
1737
1738
1739
....
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
....
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
  fflush(pOut);
}
#endif

/*
** Release an array of N Mem elements
*/
static void releaseMemArray(Mem *p, int N){
  if( p && N ){
    sqlite3 *db = p->db;
    int malloc_failed = db->mallocFailed;
    while( N-->0 ){
      assert( N<2 || p[0].db==p[1].db );

      sqlite3VdbeMemRelease(p);
      p++->flags = MEM_Null;


    }
    db->mallocFailed = malloc_failed;
  }
}


















#ifndef SQLITE_OMIT_EXPLAIN
/*
** Give a listing of the program in the virtual machine.
**
** The interface is the same as sqlite3VdbeExec().  But instead of
** running the code, it invokes the callback once for each instruction.
................................................................................
  assert( db->magic==SQLITE_MAGIC_BUSY );
  assert( p->rc==SQLITE_OK || p->rc==SQLITE_BUSY );

  /* Even though this opcode does not use dynamic strings for
  ** the result, result columns may become dynamic if the user calls
  ** sqlite3_column_text16(), causing a translation to UTF-16 encoding.
  */
  releaseMemArray(pMem, p->nMem);

  do{
    i = p->pc++;
  }while( i<p->nOp && p->explain==2 && p->aOp[i].opcode!=OP_Explain );
  if( i>=p->nOp ){
    p->rc = SQLITE_OK;
    rc = SQLITE_DONE;
................................................................................
        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;
................................................................................
/*
** Clean up the VM after execution.
**
** This routine will automatically close any cursors, lists, and/or
** sorters that were left open.  It also deletes the values of
** variables in the aVar[] array.
*/
static void Cleanup(Vdbe *p){
  int i;
  closeAllCursorsExceptActiveVtabs(p);
  for(i=1; i<=p->nMem; i++){
    MemSetTypeFlag(&p->aMem[i], MEM_Null);
  }

  releaseMemArray(&p->aMem[1], p->nMem);
  sqlite3VdbeFifoClear(&p->sFifo);
  if( p->contextStack ){
    for(i=0; i<p->contextStackTop; i++){
      sqlite3VdbeFifoClear(&p->contextStack[i].sFifo);
    }
    sqlite3_free(p->contextStack);
  }
................................................................................
** execution of the vdbe program so that sqlite3_column_count() can
** be called on an SQL statement before sqlite3_step().
*/
void sqlite3VdbeSetNumCols(Vdbe *p, int nResColumn){
  Mem *pColName;
  int n;

  releaseMemArray(p->aColName, p->nResColumn*COLNAME_N);
  sqlite3_free(p->aColName);
  n = nResColumn*COLNAME_N;
  p->nResColumn = nResColumn;
  p->aColName = pColName = (Mem*)sqlite3DbMallocZero(p->db, sizeof(Mem)*n );
  if( p->aColName==0 ) return;
  while( n-- > 0 ){
    pColName->flags = MEM_Null;
................................................................................
** After this routine is run, the VDBE should be ready to be executed
** again.
**
** To look at it another way, this routine resets the state of the
** virtual machine from VDBE_MAGIC_RUN or VDBE_MAGIC_HALT back to
** VDBE_MAGIC_INIT.
*/
int sqlite3VdbeReset(Vdbe *p){
  sqlite3 *db;
  db = p->db;

  /* If the VM did not run to completion or if it encountered an
  ** error, then it might not have been halted properly.  So halt
  ** it now.
  */
................................................................................
    sqlite3Error(db, p->rc, 0);
    sqlite3ValueSetStr(db->pErr, -1, p->zErrMsg, SQLITE_UTF8, sqlite3_free);
    p->zErrMsg = 0;
  }

  /* Reclaim all memory used by the VDBE
  */
  Cleanup(p);

  /* Save profiling information from this VDBE run.
  */
#ifdef VDBE_PROFILE
  {
    FILE *out = fopen("vdbe_profile.out", "a");
    if( out ){
................................................................................
/*
** Clean up and delete a VDBE after execution.  Return an integer which is
** the result code.  Write any error message text into *pzErrMsg.
*/
int sqlite3VdbeFinalize(Vdbe *p){
  int rc = SQLITE_OK;
  if( p->magic==VDBE_MAGIC_RUN || p->magic==VDBE_MAGIC_HALT ){
    rc = sqlite3VdbeReset(p);
    assert( (rc & p->db->errMask)==rc );
  }else if( p->magic!=VDBE_MAGIC_INIT ){
    return SQLITE_MISUSE;
  }

  sqlite3VdbeDelete(p);
  return rc;
}

/*
** Call the destructor for each auxdata entry in pVdbeFunc for which
** the corresponding bit in mask is clear.  Auxdata entries beyond 31
................................................................................

/*
** Delete an entire VDBE.
*/
void sqlite3VdbeDelete(Vdbe *p){
  int i;
  if( p==0 ) return;
  Cleanup(p);
  if( p->pPrev ){
    p->pPrev->pNext = p->pNext;
  }else{
    assert( p->db->pVdbe==p );
    p->db->pVdbe = p->pNext;
  }
  if( p->pNext ){
................................................................................
      freeP4(pOp->p4type, pOp->p4.p);
#ifdef SQLITE_DEBUG
      sqlite3_free(pOp->zComment);
#endif     
    }
    sqlite3_free(p->aOp);
  }
  releaseMemArray(p->aVar, p->nVar);
  sqlite3_free(p->aLabel);
  if( p->aMem ){
    sqlite3_free(&p->aMem[1]);
  }
  releaseMemArray(p->aColName, p->nResColumn*COLNAME_N);
  sqlite3_free(p->aColName);
  sqlite3_free(p->zSql);
  p->magic = VDBE_MAGIC_DEAD;
  sqlite3_free(p);
}

/*







|





>
|
|
>
>




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







 







|







 







|







 







|





<
|







 







|







 







|







 







|







 







|




>







 







|







 







|




|







733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
...
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
....
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
....
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118

1119
1120
1121
1122
1123
1124
1125
1126
....
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
....
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
....
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
....
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
....
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
....
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
  fflush(pOut);
}
#endif

/*
** Release an array of N Mem elements
*/
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
int sqlite3VdbeReleaseBuffers(Vdbe *p){
  int ii;
  int nFree = 0;
  assert( sqlite3_mutex_held(p->db->mutex) );
  for(ii=1; ii<=p->nMem; ii++){
    Mem *pMem = &p->aMem[ii];
    if( pMem->z && pMem->flags&MEM_Dyn ){
      assert( !pMem->xDel );
      nFree += sqlite3MallocSize(pMem->z);
      sqlite3VdbeMemRelease(pMem);
    }
  }
  return nFree;
}
#endif

#ifndef SQLITE_OMIT_EXPLAIN
/*
** Give a listing of the program in the virtual machine.
**
** The interface is the same as sqlite3VdbeExec().  But instead of
** running the code, it invokes the callback once for each instruction.
................................................................................
  assert( db->magic==SQLITE_MAGIC_BUSY );
  assert( p->rc==SQLITE_OK || p->rc==SQLITE_BUSY );

  /* Even though this opcode does not use dynamic strings for
  ** the result, result columns may become dynamic if the user calls
  ** sqlite3_column_text16(), causing a translation to UTF-16 encoding.
  */
  releaseMemArray(pMem, p->nMem, 1);

  do{
    i = p->pc++;
  }while( i<p->nOp && p->explain==2 && p->aOp[i].opcode!=OP_Explain );
  if( i>=p->nOp ){
    p->rc = SQLITE_OK;
    rc = SQLITE_DONE;
................................................................................
        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;
................................................................................
/*
** Clean up the VM after execution.
**
** This routine will automatically close any cursors, lists, and/or
** sorters that were left open.  It also deletes the values of
** variables in the aVar[] array.
*/
static void Cleanup(Vdbe *p, int freebuffers){
  int i;
  closeAllCursorsExceptActiveVtabs(p);
  for(i=1; i<=p->nMem; i++){
    MemSetTypeFlag(&p->aMem[i], MEM_Null);
  }

  releaseMemArray(&p->aMem[1], p->nMem, freebuffers);
  sqlite3VdbeFifoClear(&p->sFifo);
  if( p->contextStack ){
    for(i=0; i<p->contextStackTop; i++){
      sqlite3VdbeFifoClear(&p->contextStack[i].sFifo);
    }
    sqlite3_free(p->contextStack);
  }
................................................................................
** execution of the vdbe program so that sqlite3_column_count() can
** be called on an SQL statement before sqlite3_step().
*/
void sqlite3VdbeSetNumCols(Vdbe *p, int nResColumn){
  Mem *pColName;
  int n;

  releaseMemArray(p->aColName, p->nResColumn*COLNAME_N, 1);
  sqlite3_free(p->aColName);
  n = nResColumn*COLNAME_N;
  p->nResColumn = nResColumn;
  p->aColName = pColName = (Mem*)sqlite3DbMallocZero(p->db, sizeof(Mem)*n );
  if( p->aColName==0 ) return;
  while( n-- > 0 ){
    pColName->flags = MEM_Null;
................................................................................
** After this routine is run, the VDBE should be ready to be executed
** again.
**
** To look at it another way, this routine resets the state of the
** virtual machine from VDBE_MAGIC_RUN or VDBE_MAGIC_HALT back to
** VDBE_MAGIC_INIT.
*/
int sqlite3VdbeReset(Vdbe *p, int freebuffers){
  sqlite3 *db;
  db = p->db;

  /* If the VM did not run to completion or if it encountered an
  ** error, then it might not have been halted properly.  So halt
  ** it now.
  */
................................................................................
    sqlite3Error(db, p->rc, 0);
    sqlite3ValueSetStr(db->pErr, -1, p->zErrMsg, SQLITE_UTF8, sqlite3_free);
    p->zErrMsg = 0;
  }

  /* Reclaim all memory used by the VDBE
  */
  Cleanup(p, freebuffers);

  /* Save profiling information from this VDBE run.
  */
#ifdef VDBE_PROFILE
  {
    FILE *out = fopen("vdbe_profile.out", "a");
    if( out ){
................................................................................
/*
** Clean up and delete a VDBE after execution.  Return an integer which is
** the result code.  Write any error message text into *pzErrMsg.
*/
int sqlite3VdbeFinalize(Vdbe *p){
  int rc = SQLITE_OK;
  if( p->magic==VDBE_MAGIC_RUN || p->magic==VDBE_MAGIC_HALT ){
    rc = sqlite3VdbeReset(p, 1);
    assert( (rc & p->db->errMask)==rc );
  }else if( p->magic!=VDBE_MAGIC_INIT ){
    return SQLITE_MISUSE;
  }
  releaseMemArray(&p->aMem[1], p->nMem, 1);
  sqlite3VdbeDelete(p);
  return rc;
}

/*
** Call the destructor for each auxdata entry in pVdbeFunc for which
** the corresponding bit in mask is clear.  Auxdata entries beyond 31
................................................................................

/*
** Delete an entire VDBE.
*/
void sqlite3VdbeDelete(Vdbe *p){
  int i;
  if( p==0 ) return;
  Cleanup(p, 1);
  if( p->pPrev ){
    p->pPrev->pNext = p->pNext;
  }else{
    assert( p->db->pVdbe==p );
    p->db->pVdbe = p->pNext;
  }
  if( p->pNext ){
................................................................................
      freeP4(pOp->p4type, pOp->p4.p);
#ifdef SQLITE_DEBUG
      sqlite3_free(pOp->zComment);
#endif     
    }
    sqlite3_free(p->aOp);
  }
  releaseMemArray(p->aVar, p->nVar, 1);
  sqlite3_free(p->aLabel);
  if( p->aMem ){
    sqlite3_free(&p->aMem[1]);
  }
  releaseMemArray(p->aColName, p->nResColumn*COLNAME_N, 1);
  sqlite3_free(p->aColName);
  sqlite3_free(p->zSql);
  p->magic = VDBE_MAGIC_DEAD;
  sqlite3_free(p);
}

/*