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

Overview
Comment:Factor out methods of sqlite4_env into a separate env.c source file. Add in the sqlite4_mm object. Remove deprecated interfaces.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 1e83e737e42b8074603af9eef931dc653db81cb8
User & Date: drh 2013-02-23 17:39:05.090
Context
2013-02-23
18:36
Fix a bug in the makefile that prevents the building of the amalgamation. check-in: 9e3d29f603 user: drh tags: trunk
17:39
Factor out methods of sqlite4_env into a separate env.c source file. Add in the sqlite4_mm object. Remove deprecated interfaces. check-in: 1e83e737e4 user: drh tags: trunk
16:32
Remove the sqlite4_last_insert_rowid() and related infrastructure, since in SQLite4 we no longer have a rowid. Other cleanup of the sqlite4.h file. check-in: c92e61312f user: drh tags: trunk
Changes
Unified Diff Ignore Whitespace Patch
Changes to main.mk.
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87

TCPPX = g++ -Wall -g -I. -I$(TOP)/src $(OPTS)


LIBOBJ+= vdbe.o parse.o \
         alter.o analyze.o attach.o auth.o \
         build.o \
         callback.o complete.o ctime.o date.o delete.o expr.o fault.o fkey.o \
	 fts5.o fts5func.o \
         func.o global.o hash.o \
         icu.o insert.o kv.o kvlsm.o kvmem.o legacy.o \
         lsm_ckpt.o lsm_file.o lsm_log.o lsm_main.o lsm_mem.o lsm_mutex.o \
         lsm_shared.o lsm_str.o lsm_sorted.o lsm_tree.o \
         lsm_unix.o lsm_varint.o \
         main.o malloc.o math.o mem0.o mem1.o mem2.o mem3.o mem5.o \
         mutex.o mutex_noop.o mutex_unix.o mutex_w32.o \
         opcodes.o os.o \
         pragma.o prepare.o printf.o \
         random.o resolve.o rowset.o rtree.o select.o status.o \
         tokenize.o trigger.o \
         update.o util.o varint.o \
         vdbeapi.o vdbeaux.o vdbecodec.o vdbecursor.o \







|
|





|







66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87

TCPPX = g++ -Wall -g -I. -I$(TOP)/src $(OPTS)


LIBOBJ+= vdbe.o parse.o \
         alter.o analyze.o attach.o auth.o \
         build.o \
         callback.o complete.o ctime.o date.o delete.o env.o expr.o \
         fault.o fkey.o fts5.o fts5func.o \
         func.o global.o hash.o \
         icu.o insert.o kv.o kvlsm.o kvmem.o legacy.o \
         lsm_ckpt.o lsm_file.o lsm_log.o lsm_main.o lsm_mem.o lsm_mutex.o \
         lsm_shared.o lsm_str.o lsm_sorted.o lsm_tree.o \
         lsm_unix.o lsm_varint.o \
         main.o malloc.o math.o mem.o mem0.o mem1.o mem2.o mem3.o mem5.o \
         mutex.o mutex_noop.o mutex_unix.o mutex_w32.o \
         opcodes.o os.o \
         pragma.o prepare.o printf.o \
         random.o resolve.o rowset.o rtree.o select.o status.o \
         tokenize.o trigger.o \
         update.o util.o varint.o \
         vdbeapi.o vdbeaux.o vdbecodec.o vdbecursor.o \
97
98
99
100
101
102
103

104
105
106
107
108
109
110
  $(TOP)/src/auth.c \
  $(TOP)/src/build.c \
  $(TOP)/src/callback.c \
  $(TOP)/src/complete.c \
  $(TOP)/src/ctime.c \
  $(TOP)/src/date.c \
  $(TOP)/src/delete.c \

  $(TOP)/src/expr.c \
  $(TOP)/src/fault.c \
  $(TOP)/src/fkey.c \
  $(TOP)/src/fts5.c \
  $(TOP)/src/fts5func.c \
  $(TOP)/src/func.c \
  $(TOP)/src/global.c \







>







97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
  $(TOP)/src/auth.c \
  $(TOP)/src/build.c \
  $(TOP)/src/callback.c \
  $(TOP)/src/complete.c \
  $(TOP)/src/ctime.c \
  $(TOP)/src/date.c \
  $(TOP)/src/delete.c \
  $(TOP)/src/env.c \
  $(TOP)/src/expr.c \
  $(TOP)/src/fault.c \
  $(TOP)/src/fkey.c \
  $(TOP)/src/fts5.c \
  $(TOP)/src/fts5func.c \
  $(TOP)/src/func.c \
  $(TOP)/src/global.c \
130
131
132
133
134
135
136

137
138
139
140
141
142
143
  $(TOP)/src/lsm_sorted.c \
  $(TOP)/src/lsm_tree.c \
  $(TOP)/src/lsm_unix.c \
  $(TOP)/src/lsm_varint.c \
  $(TOP)/src/main.c \
  $(TOP)/src/malloc.c \
  $(TOP)/src/math.c \

  $(TOP)/src/mem0.c \
  $(TOP)/src/mem1.c \
  $(TOP)/src/mem2.c \
  $(TOP)/src/mem3.c \
  $(TOP)/src/mem5.c \
  $(TOP)/src/mutex.c \
  $(TOP)/src/mutex.h \







>







131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
  $(TOP)/src/lsm_sorted.c \
  $(TOP)/src/lsm_tree.c \
  $(TOP)/src/lsm_unix.c \
  $(TOP)/src/lsm_varint.c \
  $(TOP)/src/main.c \
  $(TOP)/src/malloc.c \
  $(TOP)/src/math.c \
  $(TOP)/src/mem.o \
  $(TOP)/src/mem0.c \
  $(TOP)/src/mem1.c \
  $(TOP)/src/mem2.c \
  $(TOP)/src/mem3.c \
  $(TOP)/src/mem5.c \
  $(TOP)/src/mutex.c \
  $(TOP)/src/mutex.h \
Added src/env.c.




















































































































































































































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
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
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
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
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
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
/*
** 2013 January 7
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** 
** This file contains code used to help implement the sqlite4_env object.
*/
#include "sqliteInt.h"

/*
** Initialize SQLite.  
**
** This routine must be called to initialize the run-time environment
** As long as you do not compile with SQLITE4_OMIT_AUTOINIT
** this routine will be called automatically by key routines such as
** sqlite4_open().  
**
** This routine is a no-op except on its very first call for a given
** sqlite4_env object, or for the first call after a call to sqlite4_shutdown.
**
** This routine is not threadsafe.  It should be called from a single
** thread to initialized the library in a multi-threaded system.  Other
** threads should avoid using the sqlite4_env object until after it has
** completely initialized.
*/
int sqlite4_initialize(sqlite4_env *pEnv){
  MUTEX_LOGIC( sqlite4_mutex *pMaster; )       /* The main static mutex */
  int rc;                                      /* Result code */

  if( pEnv==0 ) pEnv = &sqlite4DefaultEnv;

  /* If SQLite is already completely initialized, then this call
  ** to sqlite4_initialize() should be a no-op.  But the initialization
  ** must be complete.  So isInit must not be set until the very end
  ** of this routine.
  */
  if( pEnv->isInit ) return SQLITE4_OK;

  /* Initialize the mutex subsystem
  */
  rc = sqlite4MutexInit(pEnv);
  if( rc ){
    sqlite4MallocEnd(pEnv);
    return rc;
  }

  /* Initialize the memory allocation subsystem
  */
  rc = sqlite4MallocInit(pEnv);
  if( rc ) return rc;

  /* Create required mutexes
  */
  if( pEnv->bCoreMutex ){
    pEnv->pMemMutex = sqlite4MutexAlloc(pEnv, SQLITE4_MUTEX_FAST);
    pEnv->pPrngMutex = sqlite4MutexAlloc(pEnv, SQLITE4_MUTEX_FAST);
    pEnv->pFactoryMutex = sqlite4MutexAlloc(pEnv, SQLITE4_MUTEX_FAST);
    if( pEnv->pMemMutex==0
     || pEnv->pPrngMutex==0
     || pEnv->pFactoryMutex==0
    ){
      rc = SQLITE4_NOMEM;
    }
  }else{
    pEnv->pMemMutex = 0;
    pEnv->pPrngMutex = 0;
  }
  pEnv->isInit = 1;

  sqlite4OsInit(pEnv);

  /* Register global functions */
  if( rc==SQLITE4_OK ){
    sqlite4RegisterGlobalFunctions(pEnv);
  }

  /* The following is just a sanity check to make sure SQLite has
  ** been compiled correctly.  It is important to run this code, but
  ** we don't want to run it too often and soak up CPU cycles for no
  ** reason.  So we run it once during initialization.
  */
#ifndef NDEBUG
#ifndef SQLITE4_OMIT_FLOATING_POINT
  /* This section of code's only "output" is via assert() statements. */
  if ( rc==SQLITE4_OK ){
    u64 x = (((u64)1)<<63)-1;
    double y;
    assert(sizeof(x)==8);
    assert(sizeof(x)==sizeof(y));
    memcpy(&y, &x, 8);
    assert( sqlite4IsNaN(y) );
  }
#endif
#endif

  return rc;
}

/*
** Undo the effects of sqlite4_initialize().  Must not be called while
** there are outstanding database connections or memory allocations or
** while any part of SQLite is otherwise in use in any thread.  This
** routine is not threadsafe.  But it is safe to invoke this routine
** on when SQLite is already shut down.  If SQLite is already shut down
** when this routine is invoked, then this routine is a harmless no-op.
*/
int sqlite4_shutdown(sqlite4_env *pEnv){
  if( pEnv==0 ) pEnv = &sqlite4DefaultEnv;
  if( pEnv->isInit ){
    KVFactory *pMkr;
    sqlite4_mutex_free(pEnv->pFactoryMutex);
    sqlite4_mutex_free(pEnv->pPrngMutex);
    sqlite4_mutex_free(pEnv->pMemMutex);
    pEnv->pMemMutex = 0;
    while( (pMkr = pEnv->pFactory)!=0 && pMkr->isPerm==0 ){
      KVFactory *pNext = pMkr->pNext;
      sqlite4_free(pEnv, pMkr);
      pMkr = pNext;
    }
    sqlite4MutexEnd(pEnv);
    sqlite4MallocEnd(pEnv);
    pEnv->isInit = 0;
  }
  return SQLITE4_OK;
}

/*
** Return the size of an sqlite4_env object
*/
int sqlite4_env_size(void){ return sizeof(sqlite4_env); }

/*
** This API allows applications to modify the configuration described by
** an sqlite4_env object.
*/
int sqlite4_env_config(sqlite4_env *pEnv, int op, ...){
  va_list ap;
  int rc = SQLITE4_OK;

  if( pEnv==0 ) pEnv = sqlite4_env_default();

  va_start(ap, op);
  switch( op ){
    /*
    ** sqlite4_env_config(pEnv, SQLITE4_ENVCONFIG_INIT, template);
    **
    ** Turn bulk memory into a new sqlite4_env object.  The template is
    ** a prior sqlite4_env that is used as a template in initializing the
    ** new sqlite4_env object.  The size of the bulk memory must be at
    ** least as many bytes as returned from sqlite4_env_size().
    */
    case SQLITE4_ENVCONFIG_INIT: {
      /* Disable all mutexing */
      sqlite4_env *pTemplate = va_arg(ap, sqlite4_env*);
      int n = pTemplate->nByte;
      if( n>sizeof(sqlite4_env) ) n = sizeof(sqlite4_env);
      memcpy(pEnv, pTemplate, n);
      pEnv->pFactory = &sqlite4BuiltinFactory;
      pEnv->isInit = 0;
      break;
    }

    /* Mutex configuration options are only available in a threadsafe
    ** compile. 
    */
#if defined(SQLITE4_THREADSAFE) && SQLITE4_THREADSAFE>0
    /*
    ** sqlite4_env_config(pEnv, SQLITE4_ENVCONFIG_SINGLETHREAD);
    **
    ** Configure this environment for a single-threaded application.
    */
    case SQLITE4_ENVCONFIG_SINGLETHREAD: {
      /* Disable all mutexing */
      if( pEnv->isInit ){ rc = SQLITE4_MISUSE; break; }
      pEnv->bCoreMutex = 0;
      pEnv->bFullMutex = 0;
      break;
    }

    /*
    ** sqlite4_env_config(pEnv, SQLITE4_ENVCONFIG_MULTITHREAD);
    **
    ** Configure this environment for a multi-threaded application where
    ** the same database connection is never used by more than a single
    ** thread at a time.
    */
    case SQLITE4_ENVCONFIG_MULTITHREAD: {
      /* Disable mutexing of database connections */
      /* Enable mutexing of core data structures */
      if( pEnv->isInit ){ rc = SQLITE4_MISUSE; break; }
      pEnv->bCoreMutex = 1;
      pEnv->bFullMutex = 0;
      break;
    }

    /*
    ** sqlite4_env_config(pEnv, SQLITE4_ENVCONFIG_SERIALIZED);
    **
    ** Configure this environment for an unrestricted multi-threaded
    ** application where any thread can do whatever it wants with any
    ** database connection at any time.
    */
    case SQLITE4_ENVCONFIG_SERIALIZED: {
      /* Enable all mutexing */
      if( pEnv->isInit ){ rc = SQLITE4_MISUSE; break; }
      pEnv->bCoreMutex = 1;
      pEnv->bFullMutex = 1;
      break;
    }

    /*
    ** sqlite4_env_config(pEnv, SQLITE4_ENVCONFIG_MUTEXT, sqlite4_mutex_methods*)
    **
    ** Configure this environment to use the mutex routines specified by the
    ** argument.
    */
    case SQLITE4_ENVCONFIG_MUTEX: {
      /* Specify an alternative mutex implementation */
      if( pEnv->isInit ){ rc = SQLITE4_MISUSE; break; }
      pEnv->mutex = *va_arg(ap, sqlite4_mutex_methods*);
      break;
    }

    /*
    ** sqlite4_env_config(p, SQLITE4_ENVCONFIG_GETMUTEX, sqlite4_mutex_methods*)
    **
    ** Copy the mutex routines in use by this environment into the structure
    ** given in the argument.
    */
    case SQLITE4_ENVCONFIG_GETMUTEX: {
      /* Retrieve the current mutex implementation */
      *va_arg(ap, sqlite4_mutex_methods*) = pEnv->mutex;
      break;
    }
#endif


    /*
    ** sqlite4_env_config(p, SQLITE4_ENVCONFIG_MALLOC, sqlite4_mem_methods*)
    **
    ** Set the memory allocation routines to be used by this environment.
    */
    case SQLITE4_ENVCONFIG_MALLOC: {
      /* Specify an alternative malloc implementation */
      if( pEnv->isInit ) return SQLITE4_MISUSE;
      pEnv->m = *va_arg(ap, sqlite4_mem_methods*);
      break;
    }

    /*
    ** sqlite4_env_config(p, SQLITE4_ENVCONFIG_GETMALLOC, sqlite4_mem_methods*)
    **
    ** Copy the memory allocation routines in use by this environment
    ** into the structure given in the argument.
    */
    case SQLITE4_ENVCONFIG_GETMALLOC: {
      /* Retrieve the current malloc() implementation */
      if( pEnv->m.xMalloc==0 ) sqlite4MemSetDefault(pEnv);
      *va_arg(ap, sqlite4_mem_methods*) = pEnv->m;
      break;
    }

    /* sqlite4_env_config(p, SQLITE4_ENVCONFIG_MEMSTAT, int onoff);
    **
    ** Enable or disable collection of memory usage statistics according to
    ** the onoff parameter.  
    */
    case SQLITE4_ENVCONFIG_MEMSTATUS: {
      /* Enable or disable the malloc status collection */
      pEnv->bMemstat = va_arg(ap, int);
      break;
    }

    /*
    ** sqlite4_env_config(p, SQLITE4_ENVCONFIG_LOOKASIDE, size, count);
    **
    ** Set the default lookaside memory settings for all subsequent
    ** database connections constructed in this environment.  The size
    ** parameter is the size of each lookaside memory buffer and the
    ** count parameter is the number of lookaside buffers.  Set both
    ** to zero to disable lookaside memory.
    */
    case SQLITE4_ENVCONFIG_LOOKASIDE: {
      pEnv->szLookaside = va_arg(ap, int);
      pEnv->nLookaside = va_arg(ap, int);
      break;
    }
    
    /*
    ** sqlite4_env_config(p, SQLITE4_ENVCONFIG_LOG, xOutput, pArg);
    **
    ** Set the log function that is called in response to sqlite4_log()
    ** calls.
    */
    case SQLITE4_ENVCONFIG_LOG: {
      /* MSVC is picky about pulling func ptrs from va lists.
      ** http://support.microsoft.com/kb/47961
      ** pEnv->xLog = va_arg(ap, void(*)(void*,int,const char*));
      */
      typedef void(*LOGFUNC_t)(void*,int,const char*);
      pEnv->xLog = va_arg(ap, LOGFUNC_t);
      pEnv->pLogArg = va_arg(ap, void*);
      break;
    }

    /*
    ** sqlite4_env_config(pEnv, SQLITE4_ENVCONFIG_KVSTORE_PUSH, zName,xFactory);
    **
    ** Push a new KVStore factory onto the factory stack.  The new factory
    ** takes priority over prior factories.
    */
    case SQLITE4_ENVCONFIG_KVSTORE_PUSH: {
      const char *zName = va_arg(ap, const char*);
      int nName = sqlite4Strlen30(zName);
      KVFactory *pMkr = sqlite4_malloc(pEnv, sizeof(*pMkr)+nName+1);
      char *z;
      if( pMkr==0 ) return SQLITE4_NOMEM;
      z = (char*)&pMkr[1];
      memcpy(z, zName, nName+1);
      memset(pMkr, 0, sizeof(*pMkr));
      pMkr->zName = z;
      pMkr->xFactory = va_arg(ap, sqlite4_kvfactory);
      sqlite4_mutex_enter(pEnv->pFactoryMutex);
      pMkr->pNext = pEnv->pFactory;
      pEnv->pFactory = pMkr;
      sqlite4_mutex_leave(pEnv->pFactoryMutex);
      break;
    }

    /*
    ** sqlite4_env_config(pEnv, SQLITE4_ENVCONFIG_KVSTORE_POP, zName, &pxFact);
    **
    ** Remove a KVStore factory from the stack.
    */
    /*
    ** sqlite4_env_config(pEnv, SQLITE4_ENVCONFIG_KVSTORE_GET, zName, &pxFact);
    **
    ** Get the current factory pointer with the given name but leave the
    ** factory on the stack.
    */
    case SQLITE4_ENVCONFIG_KVSTORE_POP:
    case SQLITE4_ENVCONFIG_KVSTORE_GET: {
      typedef int (**PxFact)(sqlite4_env*,KVStore**,const char*,unsigned);
      const char *zName = va_arg(ap, const char*);
      KVFactory *pMkr, **ppPrev;
      PxFact pxFact;

      pxFact = va_arg(ap,PxFact);
      *pxFact = 0;
      sqlite4_mutex_enter(pEnv->pFactoryMutex);
      ppPrev = &pEnv->pFactory;
      pMkr = *ppPrev;
      while( pMkr && strcmp(zName, pMkr->zName)!=0 ){
        ppPrev = &pMkr->pNext;
        pMkr = *ppPrev;
      }
      if( pMkr ){
        *pxFact = pMkr->xFactory;
        if( op==SQLITE4_ENVCONFIG_KVSTORE_POP && pMkr->isPerm==0 ){
          *ppPrev = pMkr->pNext;
          sqlite4_free(pEnv, pMkr);
        }
      }
      sqlite4_mutex_leave(pEnv->pFactoryMutex);
      break;
    }


    default: {
      rc = SQLITE4_ERROR;
      break;
    }
  }
  va_end(ap);
  return rc;
}


/*
** Default factory objects
*/
static KVFactory memFactory = {
   0,
   "temp",
   sqlite4KVStoreOpenMem,
   1
};
KVFactory sqlite4BuiltinFactory = {
   &memFactory,
   "main",
   sqlite4KVStoreOpenLsm,
   1
};

/*
** The following singleton contains the global configuration for
** the SQLite library.
*/
struct sqlite4_env sqlite4DefaultEnv = {
   sizeof(sqlite4_env),       /* nByte */
   1,                         /* iVersion */
   SQLITE4_DEFAULT_MEMSTATUS, /* bMemstat */
   1,                         /* bCoreMutex */
   SQLITE4_THREADSAFE==1,     /* bFullMutex */
   0x7ffffffe,                /* mxStrlen */
   128,                       /* szLookaside */
   500,                       /* nLookaside */
   &sqlite4MMSystem,          /* pMM */
   {0,0,0,0,0,0,0,0,0},       /* m */
   {0,0,0,0,0,0,0,0,0,0},     /* mutex */
   (void*)0,                  /* pHeap */
   0,                         /* nHeap */
   0, 0,                      /* mnHeap, mxHeap */
   0,                         /* mxParserStack */
   &sqlite4BuiltinFactory,    /* pFactory */
   sqlite4OsRandomness,       /* xRandomness */
   sqlite4OsCurrentTime,      /* xCurrentTime */
   /* All the rest should always be initialized to zero */
   0,                         /* isInit */
   0,                         /* pFactoryMutex */
   0,                         /* pPrngMutex */
   0, 0,                      /* prngX, prngY */
   0,                         /* xLog */
   0,                         /* pLogArg */
   0,                         /* bLocaltimeFault */
   0,                         /* pMemMutex */
   {0,0,0,0},                 /* nowValue[] */
   {0,0,0,0},                 /* mxValue[] */
   {0,}                       /* hashGlobalFunc */
};

/*
** Return the default environment
*/
sqlite4_env *sqlite4_env_default(void){ return &sqlite4DefaultEnv; }
Changes to src/func.c.
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
*/
static void countStep(sqlite4_context *context, int argc, sqlite4_value **argv){
  CountCtx *p;
  p = sqlite4_aggregate_context(context, sizeof(*p));
  if( (argc==0 || SQLITE4_NULL!=sqlite4_value_type(argv[0])) && p ){
    p->n++;
  }

#ifndef SQLITE4_OMIT_DEPRECATED
  /* The sqlite4_aggregate_count() function is deprecated.  But just to make
  ** sure it still operates correctly, verify that its count agrees with our 
  ** internal count when using count(*) and when the total count can be
  ** expressed as a 32-bit integer. */
  assert( argc==1 || p==0 || p->n>0x7fffffff
          || p->n==sqlite4_aggregate_count(context) );
#endif
}   
static void countFinalize(sqlite4_context *context){
  CountCtx *p;
  p = sqlite4_aggregate_context(context, 0);
  sqlite4_result_int64(context, p ? p->n : 0);
}








<
<
<
<
<
<
<
<
<







1265
1266
1267
1268
1269
1270
1271









1272
1273
1274
1275
1276
1277
1278
*/
static void countStep(sqlite4_context *context, int argc, sqlite4_value **argv){
  CountCtx *p;
  p = sqlite4_aggregate_context(context, sizeof(*p));
  if( (argc==0 || SQLITE4_NULL!=sqlite4_value_type(argv[0])) && p ){
    p->n++;
  }









}   
static void countFinalize(sqlite4_context *context){
  CountCtx *p;
  p = sqlite4_aggregate_context(context, 0);
  sqlite4_result_int64(context, p ? p->n : 0);
}

Changes to src/global.c.
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
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
  0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,  /* e0..e7    ........ */
  0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,  /* e8..ef    ........ */
  0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,  /* f0..f7    ........ */
  0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40   /* f8..ff    ........ */
};
#endif

/*
** Default factory objects
*/
static KVFactory memFactory = {
   0,
   "temp",
   sqlite4KVStoreOpenMem,
   1
};
KVFactory sqlite4BuiltinFactory = {
   &memFactory,
   "main",
   sqlite4KVStoreOpenLsm,
   1
};

/*
** The following singleton contains the global configuration for
** the SQLite library.
*/
struct sqlite4_env sqlite4DefaultEnv = {
   sizeof(sqlite4_env),       /* nByte */
   1,                         /* iVersion */
   SQLITE4_DEFAULT_MEMSTATUS, /* bMemstat */
   1,                         /* bCoreMutex */
   SQLITE4_THREADSAFE==1,     /* bFullMutex */
   0x7ffffffe,                /* mxStrlen */
   128,                       /* szLookaside */
   500,                       /* nLookaside */
   {0,0,0,0,0,0,0,0,0},       /* m */
   {0,0,0,0,0,0,0,0,0,0},     /* mutex */
   (void*)0,                  /* pHeap */
   0,                         /* nHeap */
   0, 0,                      /* mnHeap, mxHeap */
   0,                         /* mxParserStack */
   &sqlite4BuiltinFactory,    /* pFactory */
   sqlite4OsRandomness,       /* xRandomness */
   sqlite4OsCurrentTime,      /* xCurrentTime */
   /* All the rest should always be initialized to zero */
   0,                         /* isInit */
   0,                         /* pFactoryMutex */
   0,                         /* pPrngMutex */
   0, 0,                      /* prngX, prngY */
   0,                         /* xLog */
   0,                         /* pLogArg */
   0,                         /* bLocaltimeFault */
   0,                         /* pMemMutex */
   {0,0,0,0},                 /* nowValue[] */
   {0,0,0,0},                 /* mxValue[] */
   {0,}                       /* hashGlobalFunc */
};

/*
** Return the default environment
*/
sqlite4_env *sqlite4_env_default(void){ return &sqlite4DefaultEnv; }


/*
** Constant tokens for values 0 and 1.
*/
const Token sqlite4IntTokens[] = {
   { "0", 1 },
   { "1", 1 }







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







125
126
127
128
129
130
131

























































132
133
134
135
136
137
138
  0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,  /* e0..e7    ........ */
  0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,  /* e8..ef    ........ */
  0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,  /* f0..f7    ........ */
  0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40   /* f8..ff    ........ */
};
#endif



























































/*
** Constant tokens for values 0 and 1.
*/
const Token sqlite4IntTokens[] = {
   { "0", 1 },
   { "1", 1 }
Changes to src/main.c.
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
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
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
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
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
** SQLITE4_ENABLE_IOTRACE is enabled, then messages describing
** I/O active are written using this function.  These messages
** are intended for debugging activity only.
*/
void (*sqlite4IoTrace)(const char*, ...) = 0;
#endif

/*
** Initialize SQLite.  
**
** This routine must be called to initialize the run-time environment
** As long as you do not compile with SQLITE4_OMIT_AUTOINIT
** this routine will be called automatically by key routines such as
** sqlite4_open().  
**
** This routine is a no-op except on its very first call for a given
** sqlite4_env object, or for the first call after a call to sqlite4_shutdown.
**
** This routine is not threadsafe.  It should be called from a single
** thread to initialized the library in a multi-threaded system.  Other
** threads should avoid using the sqlite4_env object until after it has
** completely initialized.
*/
int sqlite4_initialize(sqlite4_env *pEnv){
  MUTEX_LOGIC( sqlite4_mutex *pMaster; )       /* The main static mutex */
  int rc;                                      /* Result code */

  if( pEnv==0 ) pEnv = &sqlite4DefaultEnv;

  /* If SQLite is already completely initialized, then this call
  ** to sqlite4_initialize() should be a no-op.  But the initialization
  ** must be complete.  So isInit must not be set until the very end
  ** of this routine.
  */
  if( pEnv->isInit ) return SQLITE4_OK;

  /* Initialize the mutex subsystem
  */
  rc = sqlite4MutexInit(pEnv);
  if( rc ){
    sqlite4MallocEnd(pEnv);
    return rc;
  }

  /* Initialize the memory allocation subsystem
  */
  rc = sqlite4MallocInit(pEnv);
  if( rc ) return rc;

  /* Create required mutexes
  */
  if( pEnv->bCoreMutex ){
    pEnv->pMemMutex = sqlite4MutexAlloc(pEnv, SQLITE4_MUTEX_FAST);
    pEnv->pPrngMutex = sqlite4MutexAlloc(pEnv, SQLITE4_MUTEX_FAST);
    pEnv->pFactoryMutex = sqlite4MutexAlloc(pEnv, SQLITE4_MUTEX_FAST);
    if( pEnv->pMemMutex==0
     || pEnv->pPrngMutex==0
     || pEnv->pFactoryMutex==0
    ){
      rc = SQLITE4_NOMEM;
    }
  }else{
    pEnv->pMemMutex = 0;
    pEnv->pPrngMutex = 0;
  }
  pEnv->isInit = 1;

  sqlite4OsInit(pEnv);

  /* Register global functions */
  if( rc==SQLITE4_OK ){
    sqlite4RegisterGlobalFunctions(pEnv);
  }

  /* The following is just a sanity check to make sure SQLite has
  ** been compiled correctly.  It is important to run this code, but
  ** we don't want to run it too often and soak up CPU cycles for no
  ** reason.  So we run it once during initialization.
  */
#ifndef NDEBUG
#ifndef SQLITE4_OMIT_FLOATING_POINT
  /* This section of code's only "output" is via assert() statements. */
  if ( rc==SQLITE4_OK ){
    u64 x = (((u64)1)<<63)-1;
    double y;
    assert(sizeof(x)==8);
    assert(sizeof(x)==sizeof(y));
    memcpy(&y, &x, 8);
    assert( sqlite4IsNaN(y) );
  }
#endif
#endif

  return rc;
}

/*
** Undo the effects of sqlite4_initialize().  Must not be called while
** there are outstanding database connections or memory allocations or
** while any part of SQLite is otherwise in use in any thread.  This
** routine is not threadsafe.  But it is safe to invoke this routine
** on when SQLite is already shut down.  If SQLite is already shut down
** when this routine is invoked, then this routine is a harmless no-op.
*/
int sqlite4_shutdown(sqlite4_env *pEnv){
  if( pEnv==0 ) pEnv = &sqlite4DefaultEnv;
  if( pEnv->isInit ){
    KVFactory *pMkr;
    sqlite4_mutex_free(pEnv->pFactoryMutex);
    sqlite4_mutex_free(pEnv->pPrngMutex);
    sqlite4_mutex_free(pEnv->pMemMutex);
    pEnv->pMemMutex = 0;
    while( (pMkr = pEnv->pFactory)!=0 && pMkr->isPerm==0 ){
      KVFactory *pNext = pMkr->pNext;
      sqlite4_free(pEnv, pMkr);
      pMkr = pNext;
    }
    sqlite4MutexEnd(pEnv);
    sqlite4MallocEnd(pEnv);
    pEnv->isInit = 0;
  }
  return SQLITE4_OK;
}

/*
** Return the size of an sqlite4_env object
*/
int sqlite4_env_size(void){ return sizeof(sqlite4_env); }

/*
** This API allows applications to modify the configuration described by
** an sqlite4_env object.
*/
int sqlite4_env_config(sqlite4_env *pEnv, int op, ...){
  va_list ap;
  int rc = SQLITE4_OK;

  if( pEnv==0 ) pEnv = sqlite4_env_default();

  va_start(ap, op);
  switch( op ){
    /*
    ** sqlite4_env_config(pEnv, SQLITE4_ENVCONFIG_INIT, template);
    **
    ** Turn bulk memory into a new sqlite4_env object.  The template is
    ** a prior sqlite4_env that is used as a template in initializing the
    ** new sqlite4_env object.  The size of the bulk memory must be at
    ** least as many bytes as returned from sqlite4_env_size().
    */
    case SQLITE4_ENVCONFIG_INIT: {
      /* Disable all mutexing */
      sqlite4_env *pTemplate = va_arg(ap, sqlite4_env*);
      int n = pTemplate->nByte;
      if( n>sizeof(sqlite4_env) ) n = sizeof(sqlite4_env);
      memcpy(pEnv, pTemplate, n);
      pEnv->pFactory = &sqlite4BuiltinFactory;
      pEnv->isInit = 0;
      break;
    }

    /* Mutex configuration options are only available in a threadsafe
    ** compile. 
    */
#if defined(SQLITE4_THREADSAFE) && SQLITE4_THREADSAFE>0
    /*
    ** sqlite4_env_config(pEnv, SQLITE4_ENVCONFIG_SINGLETHREAD);
    **
    ** Configure this environment for a single-threaded application.
    */
    case SQLITE4_ENVCONFIG_SINGLETHREAD: {
      /* Disable all mutexing */
      if( pEnv->isInit ){ rc = SQLITE4_MISUSE; break; }
      pEnv->bCoreMutex = 0;
      pEnv->bFullMutex = 0;
      break;
    }

    /*
    ** sqlite4_env_config(pEnv, SQLITE4_ENVCONFIG_MULTITHREAD);
    **
    ** Configure this environment for a multi-threaded application where
    ** the same database connection is never used by more than a single
    ** thread at a time.
    */
    case SQLITE4_ENVCONFIG_MULTITHREAD: {
      /* Disable mutexing of database connections */
      /* Enable mutexing of core data structures */
      if( pEnv->isInit ){ rc = SQLITE4_MISUSE; break; }
      pEnv->bCoreMutex = 1;
      pEnv->bFullMutex = 0;
      break;
    }

    /*
    ** sqlite4_env_config(pEnv, SQLITE4_ENVCONFIG_MULTITHREAD);
    **
    ** Configure this environment for an unrestricted multi-threaded
    ** application where any thread can do whatever it wants with any
    ** database connection at any time.
    */
    case SQLITE4_ENVCONFIG_SERIALIZED: {
      /* Enable all mutexing */
      if( pEnv->isInit ){ rc = SQLITE4_MISUSE; break; }
      pEnv->bCoreMutex = 1;
      pEnv->bFullMutex = 1;
      break;
    }

    /*
    ** sqlite4_env_config(pEnv, SQLITE4_ENVCONFIG_MUTEXT, sqlite4_mutex_methods*)
    **
    ** Configure this environment to use the mutex routines specified by the
    ** argument.
    */
    case SQLITE4_ENVCONFIG_MUTEX: {
      /* Specify an alternative mutex implementation */
      if( pEnv->isInit ){ rc = SQLITE4_MISUSE; break; }
      pEnv->mutex = *va_arg(ap, sqlite4_mutex_methods*);
      break;
    }

    /*
    ** sqlite4_env_config(p, SQLITE4_ENVCONFIG_GETMUTEX, sqlite4_mutex_methods*)
    **
    ** Copy the mutex routines in use by this environment into the structure
    ** given in the argument.
    */
    case SQLITE4_ENVCONFIG_GETMUTEX: {
      /* Retrieve the current mutex implementation */
      *va_arg(ap, sqlite4_mutex_methods*) = pEnv->mutex;
      break;
    }
#endif


    /*
    ** sqlite4_env_config(p, SQLITE4_ENVCONFIG_MALLOC, sqlite4_mem_methods*)
    **
    ** Set the memory allocation routines to be used by this environment.
    */
    case SQLITE4_ENVCONFIG_MALLOC: {
      /* Specify an alternative malloc implementation */
      if( pEnv->isInit ) return SQLITE4_MISUSE;
      pEnv->m = *va_arg(ap, sqlite4_mem_methods*);
      break;
    }

    /*
    ** sqlite4_env_config(p, SQLITE4_ENVCONFIG_GETMALLOC, sqlite4_mem_methods*)
    **
    ** Copy the memory allocation routines in use by this environment
    ** into the structure given in the argument.
    */
    case SQLITE4_ENVCONFIG_GETMALLOC: {
      /* Retrieve the current malloc() implementation */
      if( pEnv->m.xMalloc==0 ) sqlite4MemSetDefault(pEnv);
      *va_arg(ap, sqlite4_mem_methods*) = pEnv->m;
      break;
    }

    /* sqlite4_env_config(p, SQLITE4_ENVCONFIG_MEMSTAT, int onoff);
    **
    ** Enable or disable collection of memory usage statistics according to
    ** the onoff parameter.  
    */
    case SQLITE4_ENVCONFIG_MEMSTATUS: {
      /* Enable or disable the malloc status collection */
      pEnv->bMemstat = va_arg(ap, int);
      break;
    }

    /*
    ** sqlite4_env_config(p, SQLITE4_ENVCONFIG_LOOKASIDE, size, count);
    **
    ** Set the default lookaside memory settings for all subsequent
    ** database connections constructed in this environment.  The size
    ** parameter is the size of each lookaside memory buffer and the
    ** count parameter is the number of lookaside buffers.  Set both
    ** to zero to disable lookaside memory.
    */
    case SQLITE4_ENVCONFIG_LOOKASIDE: {
      pEnv->szLookaside = va_arg(ap, int);
      pEnv->nLookaside = va_arg(ap, int);
      break;
    }
    
    /*
    ** sqlite4_env_config(p, SQLITE4_ENVCONFIG_LOG, xOutput, pArg);
    **
    ** Set the log function that is called in response to sqlite4_log()
    ** calls.
    */
    case SQLITE4_ENVCONFIG_LOG: {
      /* MSVC is picky about pulling func ptrs from va lists.
      ** http://support.microsoft.com/kb/47961
      ** pEnv->xLog = va_arg(ap, void(*)(void*,int,const char*));
      */
      typedef void(*LOGFUNC_t)(void*,int,const char*);
      pEnv->xLog = va_arg(ap, LOGFUNC_t);
      pEnv->pLogArg = va_arg(ap, void*);
      break;
    }

    /*
    ** sqlite4_env_config(pEnv, SQLITE4_ENVCONFIG_KVSTORE_PUSH, zName,xFactory);
    **
    ** Push a new KVStore factory onto the factory stack.  The new factory
    ** takes priority over prior factories.
    */
    case SQLITE4_ENVCONFIG_KVSTORE_PUSH: {
      const char *zName = va_arg(ap, const char*);
      int nName = sqlite4Strlen30(zName);
      KVFactory *pMkr = sqlite4_malloc(pEnv, sizeof(*pMkr)+nName+1);
      char *z;
      if( pMkr==0 ) return SQLITE4_NOMEM;
      z = (char*)&pMkr[1];
      memcpy(z, zName, nName+1);
      memset(pMkr, 0, sizeof(*pMkr));
      pMkr->zName = z;
      pMkr->xFactory = va_arg(ap, sqlite4_kvfactory);
      sqlite4_mutex_enter(pEnv->pFactoryMutex);
      pMkr->pNext = pEnv->pFactory;
      pEnv->pFactory = pMkr;
      sqlite4_mutex_leave(pEnv->pFactoryMutex);
      break;
    }

    /*
    ** sqlite4_env_config(pEnv, SQLITE4_ENVCONFIG_KVSTORE_POP, zName, &pxFact);
    **
    ** Remove a KVStore factory from the stack.
    */
    /*
    ** sqlite4_env_config(pEnv, SQLITE4_ENVCONFIG_KVSTORE_GET, zName, &pxFact);
    **
    ** Get the current factory pointer with the given name but leave the
    ** factory on the stack.
    */
    case SQLITE4_ENVCONFIG_KVSTORE_POP:
    case SQLITE4_ENVCONFIG_KVSTORE_GET: {
      typedef int (**PxFact)(sqlite4_env*,KVStore**,const char*,unsigned);
      const char *zName = va_arg(ap, const char*);
      KVFactory *pMkr, **ppPrev;
      PxFact pxFact;

      pxFact = va_arg(ap,PxFact);
      *pxFact = 0;
      sqlite4_mutex_enter(pEnv->pFactoryMutex);
      ppPrev = &pEnv->pFactory;
      pMkr = *ppPrev;
      while( pMkr && strcmp(zName, pMkr->zName)!=0 ){
        ppPrev = &pMkr->pNext;
        pMkr = *ppPrev;
      }
      if( pMkr ){
        *pxFact = pMkr->xFactory;
        if( op==SQLITE4_ENVCONFIG_KVSTORE_POP && pMkr->isPerm==0 ){
          *ppPrev = pMkr->pNext;
          sqlite4_free(pEnv, pMkr);
        }
      }
      sqlite4_mutex_leave(pEnv->pFactoryMutex);
      break;
    }


    default: {
      rc = SQLITE4_ERROR;
      break;
    }
  }
  va_end(ap);
  return rc;
}

/*
** Set up the lookaside buffers for a database connection.
** Return SQLITE4_OK on success.  
** If lookaside is already active, return SQLITE4_BUSY.
**
** The sz parameter is the number of bytes in each lookaside slot.
** The cnt parameter is the number of slots.  If pStart is NULL the







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







60
61
62
63
64
65
66
















































































































































































































































































































































































67
68
69
70
71
72
73
** SQLITE4_ENABLE_IOTRACE is enabled, then messages describing
** I/O active are written using this function.  These messages
** are intended for debugging activity only.
*/
void (*sqlite4IoTrace)(const char*, ...) = 0;
#endif

















































































































































































































































































































































































/*
** Set up the lookaside buffers for a database connection.
** Return SQLITE4_OK on success.  
** If lookaside is already active, return SQLITE4_BUSY.
**
** The sz parameter is the number of bytes in each lookaside slot.
** The cnt parameter is the number of slots.  If pStart is NULL the
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
  db->xCollNeeded16 = xCollNeeded16;
  db->pCollNeededArg = pCollNeededArg;
  sqlite4_mutex_leave(db->mutex);
  return SQLITE4_OK;
}
#endif /* SQLITE4_OMIT_UTF16 */

#ifndef SQLITE4_OMIT_DEPRECATED
/*
** This function is now an anachronism. It used to be used to recover from a
** malloc() failure, but SQLite now does this automatically.
*/
int sqlite4_global_recover(void){
  return SQLITE4_OK;
}
#endif

/*
** Test to see whether or not the database connection is in autocommit
** mode.  Return TRUE if it is and FALSE if not.  Autocommit mode is on
** by default.  Autocommit is disabled by a BEGIN statement and reenabled
** by the next COMMIT or ROLLBACK.
**
******* THIS IS AN EXPERIMENTAL API AND IS SUBJECT TO CHANGE ******
*/
int sqlite4_get_autocommit(sqlite4 *db){
  return (db->pSavepoint==0);
}

/*
** The following routines are subtitutes for constants SQLITE4_CORRUPT,







<
<
<
<
<
<
<
<
<
<





<
<







1547
1548
1549
1550
1551
1552
1553










1554
1555
1556
1557
1558


1559
1560
1561
1562
1563
1564
1565
  db->xCollNeeded16 = xCollNeeded16;
  db->pCollNeededArg = pCollNeededArg;
  sqlite4_mutex_leave(db->mutex);
  return SQLITE4_OK;
}
#endif /* SQLITE4_OMIT_UTF16 */











/*
** Test to see whether or not the database connection is in autocommit
** mode.  Return TRUE if it is and FALSE if not.  Autocommit mode is on
** by default.  Autocommit is disabled by a BEGIN statement and reenabled
** by the next COMMIT or ROLLBACK.


*/
int sqlite4_get_autocommit(sqlite4 *db){
  return (db->pSavepoint==0);
}

/*
** The following routines are subtitutes for constants SQLITE4_CORRUPT,
Changes to src/mem.c.
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
**
*************************************************************************
**
** This file contains the implementation of the "sqlite4_mm" memory
** allocator object.
*/
#include "sqlite4.h"
#include "mem.h"
#include <stdlib.h>

/*************************************************************************
** The SQLITE4_MM_SYSTEM memory allocator.  This allocator uses the
** malloc/realloc/free from the system library.  It also tries to use
** the memory allocation sizer from the system library if such a routine
** exists.  If there is no msize in the system library, then each allocation







<







10
11
12
13
14
15
16

17
18
19
20
21
22
23
**
*************************************************************************
**
** This file contains the implementation of the "sqlite4_mm" memory
** allocator object.
*/
#include "sqlite4.h"

#include <stdlib.h>

/*************************************************************************
** The SQLITE4_MM_SYSTEM memory allocator.  This allocator uses the
** malloc/realloc/free from the system library.  It also tries to use
** the memory allocation sizer from the system library if such a routine
** exists.  If there is no msize in the system library, then each allocation
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
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
#endif

#endif /* __APPLE__ or not __APPLE__ */

/*
** Implementations of core routines
*/
static void *mmSysMalloc(sqlite4_mm *pMM, sqlite4_int64 iSize){
#ifdef SQLITE4_MALLOCSIZE
  return SQLITE4_MALLOC(iSize);
#else
  unsigned char *pRes = SQLITE4_MALLOC(iSize+8);
  if( pRes ){
    *(sqlite4_int64*)pRes = iSize;
    pRes += 8;
  }
  return pRes;
#endif
}
static void *mmSysRealloc(sqlite4_mm *pMM, void *pOld, sqlite4_int64 iSz){
#ifdef SQLITE4_MALLOCSIZE
  return SQLITE4_REALLOC(pOld, iSz);
#else
  unsigned char *pRes;
  if( pOld==0 ) return mmSysMalloc(pMM, iSz);
  pRes = (unsigned char*)pOld;
  pRes -= 8;
  pRes = SQLITE4_REALLOC(pRes, iSz+8);
  if( pRes ){
    *(sqlite4_int64*)pRes = iSz;
    pRes += 8;
  }
  return pRes;
#endif 
}
static void mmSysFree(sqlite4_mm *pNotUsed, void *pOld){
#ifdef SQLITE4_MALLOCSIZE
  SQLITE4_FREE(pOld);
#else
  unsigned char *pRes;
  if( pOld==0 ) return;
  pRes = (unsigned char *)pOld;
  pRes -= 8;
  SQLITE4_FREE(pRes);
#endif
}
static sqlite4_int64 mmSysMsize(sqlite4_mm *pNotUsed, void *pOld){
#ifdef SQLITE4_MALLOCSIZE
  return SQLITE4_MALLOCSIZE(pOld);
#else
  unsigned char *pX;
  if( pOld==0 ) return 0;
  pX = (unsigned char *)pOld;
  pX -= 8;
  return *(sqlite4_int64*)pX;
#endif
}

static const sqlite4_mm_methods mmSysMethods = {
  /* iVersion */    1,
  /* xMalloc  */    mmSysMalloc,
  /* xRealloc */    mmSysRealloc,
  /* xFree    */    mmSysFree,
  /* xMsize   */    mmSysMsize,
  /* xMember  */    0,
  /* xBenign  */    0,

  /* xFinal   */    0
};
static sqlite4_mm mmSystem =  {
  /* pMethods */    &mmSysMethods
};




/*************************************************************************
** The SQLITE4_MM_OVERFLOW memory allocator.
**
** This memory allocator has two child memory allocators, A and B.  Always
** try to fulfill the request using A first, then overflow to B if the request
** on A fails.  The A allocator must support the xMember method.
*/
struct mmOvfl {
  sqlite4_mm base;    /* Base class - must be first */
  int (*xMemberOfA)(sqlite4_mm*, const void*);
  sqlite4_mm *pA;     /* Primary memory allocator */
  sqlite4_mm *pB;     /* Backup memory allocator in case pA fails */
};

static void *mmOvflMalloc(sqlite4_mm *pMM, sqlite4_int64 iSz){
  const struct mmOvfl *pOvfl = (const struct mmOvfl*)pMM;
  void *pRes;
  pRes = pOvfl->pA->pMethods->xMalloc(pOvfl->pA, iSz);
  if( pRes==0 ){
    pRes = pOvfl->pB->pMethods->xMalloc(pOvfl->pB, iSz);
  }
  return pRes;
}
static void *mmOvflRealloc(sqlite4_mm *pMM, void *pOld, sqlite4_int64 iSz){
  const struct mmOvfl *pOvfl;
  void *pRes;
  if( pOld==0 ) return mmOvflMalloc(pMM, iSz);
  pOvfl = (const struct mmOvfl*)pMM;
  if( pOvfl->xMemberOfA(pOvfl->pA, pOld) ){
    pRes = pOvfl->pA->pMethods->xRealloc(pOvfl->pA, pOld, iSz);
  }else{







|





|





|









|
















|







|











>


|



>
>
>














|








|







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
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
#endif

#endif /* __APPLE__ or not __APPLE__ */

/*
** Implementations of core routines
*/
static void *mmSysMalloc(sqlite4_mm *pMM, sqlite4_size_t iSize){
#ifdef SQLITE4_MALLOCSIZE
  return SQLITE4_MALLOC(iSize);
#else
  unsigned char *pRes = SQLITE4_MALLOC(iSize+8);
  if( pRes ){
    *(sqlite4_size_t*)pRes = iSize;
    pRes += 8;
  }
  return pRes;
#endif
}
static void *mmSysRealloc(sqlite4_mm *pMM, void *pOld, sqlite4_size_t iSz){
#ifdef SQLITE4_MALLOCSIZE
  return SQLITE4_REALLOC(pOld, iSz);
#else
  unsigned char *pRes;
  if( pOld==0 ) return mmSysMalloc(pMM, iSz);
  pRes = (unsigned char*)pOld;
  pRes -= 8;
  pRes = SQLITE4_REALLOC(pRes, iSz+8);
  if( pRes ){
    *(sqlite4_size_t*)pRes = iSz;
    pRes += 8;
  }
  return pRes;
#endif 
}
static void mmSysFree(sqlite4_mm *pNotUsed, void *pOld){
#ifdef SQLITE4_MALLOCSIZE
  SQLITE4_FREE(pOld);
#else
  unsigned char *pRes;
  if( pOld==0 ) return;
  pRes = (unsigned char *)pOld;
  pRes -= 8;
  SQLITE4_FREE(pRes);
#endif
}
static sqlite4_size_t mmSysMsize(sqlite4_mm *pNotUsed, void *pOld){
#ifdef SQLITE4_MALLOCSIZE
  return SQLITE4_MALLOCSIZE(pOld);
#else
  unsigned char *pX;
  if( pOld==0 ) return 0;
  pX = (unsigned char *)pOld;
  pX -= 8;
  return *(sqlite4_size_t*)pX;
#endif
}

static const sqlite4_mm_methods mmSysMethods = {
  /* iVersion */    1,
  /* xMalloc  */    mmSysMalloc,
  /* xRealloc */    mmSysRealloc,
  /* xFree    */    mmSysFree,
  /* xMsize   */    mmSysMsize,
  /* xMember  */    0,
  /* xBenign  */    0,
  /* xStat    */    0,
  /* xFinal   */    0
};
sqlite4_mm sqlite4MMSystem =  {
  /* pMethods */    &mmSysMethods
};

/* The system memory allocator is the default. */
sqlite4_mm *sqlite4_mm_default(void){ return &sqlite4MMSystem; }

/*************************************************************************
** The SQLITE4_MM_OVERFLOW memory allocator.
**
** This memory allocator has two child memory allocators, A and B.  Always
** try to fulfill the request using A first, then overflow to B if the request
** on A fails.  The A allocator must support the xMember method.
*/
struct mmOvfl {
  sqlite4_mm base;    /* Base class - must be first */
  int (*xMemberOfA)(sqlite4_mm*, const void*);
  sqlite4_mm *pA;     /* Primary memory allocator */
  sqlite4_mm *pB;     /* Backup memory allocator in case pA fails */
};

static void *mmOvflMalloc(sqlite4_mm *pMM, sqlite4_size_t iSz){
  const struct mmOvfl *pOvfl = (const struct mmOvfl*)pMM;
  void *pRes;
  pRes = pOvfl->pA->pMethods->xMalloc(pOvfl->pA, iSz);
  if( pRes==0 ){
    pRes = pOvfl->pB->pMethods->xMalloc(pOvfl->pB, iSz);
  }
  return pRes;
}
static void *mmOvflRealloc(sqlite4_mm *pMM, void *pOld, sqlite4_size_t iSz){
  const struct mmOvfl *pOvfl;
  void *pRes;
  if( pOld==0 ) return mmOvflMalloc(pMM, iSz);
  pOvfl = (const struct mmOvfl*)pMM;
  if( pOvfl->xMemberOfA(pOvfl->pA, pOld) ){
    pRes = pOvfl->pA->pMethods->xRealloc(pOvfl->pA, pOld, iSz);
  }else{
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
  pOvfl = (const struct mmOvfl*)pMM;
  if( pOvfl->xMemberOfA(pOvfl->pA, pOld) ){
    pOvfl->pA->pMethods->xFree(pOvfl->pA, pOld);
  }else{
    pOvfl->pB->pMethods->xFree(pOvfl->pB, pOld);
  }
}
static sqlite4_int64 mmOvflMsize(sqlite4_mm *pMM, void *pOld){
  const struct mmOvfl *pOvfl;
  sqlite4_int64 iSz;
  if( pOld==0 ) return 0;
  pOvfl = (const struct mmOvfl*)pMM;
  if( pOvfl->xMemberOfA(pOvfl->pA, pOld) ){
    iSz = sqlite4_mm_msize(pOvfl->pA, pOld);
  }else{
    iSz = sqlite4_mm_msize(pOvfl->pB, pOld);
  }







|

|







209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
  pOvfl = (const struct mmOvfl*)pMM;
  if( pOvfl->xMemberOfA(pOvfl->pA, pOld) ){
    pOvfl->pA->pMethods->xFree(pOvfl->pA, pOld);
  }else{
    pOvfl->pB->pMethods->xFree(pOvfl->pB, pOld);
  }
}
static sqlite4_size_t mmOvflMsize(sqlite4_mm *pMM, void *pOld){
  const struct mmOvfl *pOvfl;
  sqlite4_size_t iSz;
  if( pOld==0 ) return 0;
  pOvfl = (const struct mmOvfl*)pMM;
  if( pOvfl->xMemberOfA(pOvfl->pA, pOld) ){
    iSz = sqlite4_mm_msize(pOvfl->pA, pOld);
  }else{
    iSz = sqlite4_mm_msize(pOvfl->pB, pOld);
  }
251
252
253
254
255
256
257

258
259
260
261
262
263
264
  /* iVersion */    1,
  /* xMalloc  */    mmOvflMalloc,
  /* xRealloc */    mmOvflRealloc,
  /* xFree    */    mmOvflFree,
  /* xMsize   */    mmOvflMsize,
  /* xMember  */    mmOvflMember,
  /* xBenign  */    mmOvflBenign,

  /* xFinal   */    mmOvflFinal
};
static sqlite4_mm *mmOvflNew(sqlite4_mm *pA, sqlite4_mm *pB){
  struct mmOvfl *pOvfl;
  if( pA->pMethods->xMember==0 ) return 0;
  pOvfl = sqlite4_mm_malloc(pA, sizeof(*pOvfl));
  if( pOvfl==0 ){







>







254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
  /* iVersion */    1,
  /* xMalloc  */    mmOvflMalloc,
  /* xRealloc */    mmOvflRealloc,
  /* xFree    */    mmOvflFree,
  /* xMsize   */    mmOvflMsize,
  /* xMember  */    mmOvflMember,
  /* xBenign  */    mmOvflBenign,
  /* xStat    */    0,
  /* xFinal   */    mmOvflFinal
};
static sqlite4_mm *mmOvflNew(sqlite4_mm *pA, sqlite4_mm *pB){
  struct mmOvfl *pOvfl;
  if( pA->pMethods->xMember==0 ) return 0;
  pOvfl = sqlite4_mm_malloc(pA, sizeof(*pOvfl));
  if( pOvfl==0 ){
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342

343
344
345
346
347
348
349
};

/* A free block in the buffer */
struct mmOneszBlock {
  struct mmOneszBlock *pNext;  /* Next on the freelist */
};

static void *mmOneszMalloc(sqlite4_mm *pMM, sqlite4_int64 iSz){
  struct mmOnesz *pOnesz = (struct mmOnesz*)pMM;
  void *pRes;
  if( iSz>pOnesz->sz ) return 0;
  if( pOnesz->pFree==0 ) return 0;
  pRes = pOnesz->pFree;
  pOnesz->pFree = pOnesz->pFree->pNext;
  return pRes;
}
static void mmOneszFree(sqlite4_mm *pMM, void *pOld){
  struct mmOnesz *pOnesz = (struct mmOnesz*)pMM;
  if( pOld ){
    struct mmOneszBlock *pBlock = (struct mmOneszBlock*)pOld;
    pBlock->pNext = pOnesz->pFree;
    pOnesz->pFree = pBlock;
  }
}
static void *mmOneszRealloc(sqlite4_mm *pMM, void *pOld, sqlite4_int64 iSz){
  struct mmOnesz *pOnesz = (struct mmOnesz*)pMM;
  if( pOld==0 ) return mmOneszMalloc(pMM, iSz);
  if( iSz<=0 ){
    mmOneszFree(pMM, pOld);
    return 0;
  }
  if( iSz>pOnesz->sz ) return 0;
  return pOld;
}
static sqlite4_int64 mmOneszMsize(sqlite4_mm *pMM, void *pOld){
  struct mmOnesz *pOnesz = (struct mmOnesz*)pMM;
  return pOld ? pOnesz->sz : 0;  
}
static int mmOneszMember(sqlite4_mm *pMM, const void *pOld){
  struct mmOnesz *pOnesz = (struct mmOnesz*)pMM;
  return pOld && pOld>=pOnesz->pSpace && pOld<=pOnesz->pLast;
}
static const sqlite4_mm_methods mmOneszMethods = {
  /* iVersion */    1,
  /* xMalloc  */    mmOneszMalloc,
  /* xRealloc */    mmOneszRealloc,
  /* xFree    */    mmOneszFree,
  /* xMsize   */    mmOneszMsize,
  /* xMember  */    mmOneszMember,
  /* xBenign  */    0,

  /* xFinal   */    0
};
static sqlite4_mm *mmOneszNew(void *pSpace, int sz, int cnt){
  struct mmOnesz *pOnesz;
  unsigned char *pMem;
  if( sz<sizeof(*pOnesz) ) return 0;
  if( cnt<2 ) return 0;







|
















|









|















>







297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
};

/* A free block in the buffer */
struct mmOneszBlock {
  struct mmOneszBlock *pNext;  /* Next on the freelist */
};

static void *mmOneszMalloc(sqlite4_mm *pMM, sqlite4_size_t iSz){
  struct mmOnesz *pOnesz = (struct mmOnesz*)pMM;
  void *pRes;
  if( iSz>pOnesz->sz ) return 0;
  if( pOnesz->pFree==0 ) return 0;
  pRes = pOnesz->pFree;
  pOnesz->pFree = pOnesz->pFree->pNext;
  return pRes;
}
static void mmOneszFree(sqlite4_mm *pMM, void *pOld){
  struct mmOnesz *pOnesz = (struct mmOnesz*)pMM;
  if( pOld ){
    struct mmOneszBlock *pBlock = (struct mmOneszBlock*)pOld;
    pBlock->pNext = pOnesz->pFree;
    pOnesz->pFree = pBlock;
  }
}
static void *mmOneszRealloc(sqlite4_mm *pMM, void *pOld, sqlite4_size_t iSz){
  struct mmOnesz *pOnesz = (struct mmOnesz*)pMM;
  if( pOld==0 ) return mmOneszMalloc(pMM, iSz);
  if( iSz<=0 ){
    mmOneszFree(pMM, pOld);
    return 0;
  }
  if( iSz>pOnesz->sz ) return 0;
  return pOld;
}
static sqlite4_size_t mmOneszMsize(sqlite4_mm *pMM, void *pOld){
  struct mmOnesz *pOnesz = (struct mmOnesz*)pMM;
  return pOld ? pOnesz->sz : 0;  
}
static int mmOneszMember(sqlite4_mm *pMM, const void *pOld){
  struct mmOnesz *pOnesz = (struct mmOnesz*)pMM;
  return pOld && pOld>=pOnesz->pSpace && pOld<=pOnesz->pLast;
}
static const sqlite4_mm_methods mmOneszMethods = {
  /* iVersion */    1,
  /* xMalloc  */    mmOneszMalloc,
  /* xRealloc */    mmOneszRealloc,
  /* xFree    */    mmOneszFree,
  /* xMsize   */    mmOneszMsize,
  /* xMember  */    mmOneszMember,
  /* xBenign  */    0,
  /* xStat    */    0,
  /* xFinal   */    0
};
static sqlite4_mm *mmOneszNew(void *pSpace, int sz, int cnt){
  struct mmOnesz *pOnesz;
  unsigned char *pMem;
  if( sz<sizeof(*pOnesz) ) return 0;
  if( cnt<2 ) return 0;
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394





395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
  }
  return &pOnesz->base;
}

/*************************************************************************
** Main interfaces.
*/
void *sqlite4_mm_malloc(sqlite4_mm *pMM, sqlite4_int64 iSize){
  if( pMM==0 ) pMM = &mmSystem;
  return pMM->pMethods->xMalloc(pMM,iSize);
}
void *sqlite4_mm_realloc(sqlite4_mm *pMM, void *pOld, sqlite4_int64 iSize){
  if( pMM==0 ) pMM = &mmSystem;
  return pMM->pMethods->xRealloc(pMM,pOld,iSize);
}
void sqlite4_mm_free(sqlite4_mm *pMM, void *pOld){
  if( pMM==0 ) pMM = &mmSystem;
  pMM->pMethods->xFree(pMM,pOld);
}
sqlite4_int64 sqlite4_mm_msize(sqlite4_mm *pMM, void *pOld){
  if( pMM==0 ) pMM = &mmSystem;
  return pMM->pMethods->xMsize(pMM,pOld);
}
int sqlite4_mm_member(sqlite4_mm *pMM, const void *pOld){
  return (pMM && pMM->pMethods->xMember!=0) ?
            pMM->pMethods->xMember(pMM,pOld) : -1;
}
void sqlite4_mm_benign_failure(sqlite4_mm *pMM, int bEnable){
  if( pMM && pMM->pMethods->xBenign ){
    pMM->pMethods->xBenign(pMM, bEnable);
  }





}
void sqlite4_mm_destroy(sqlite4_mm *pMM){
  if( pMM && pMM->pMethods->xFinal ) pMM->pMethods->xFinal(pMM);
}

/*
** Create a new memory allocation object.  eType determines the type of
** memory allocator and the arguments.
*/
sqlite4_mm *sqlite4_mm_new(sqlite4_mm_type eType, ...){
  va_list ap;
  sqlite4_mm *pMM;

  va_start(ap, eType);
  switch( eType ){
    case SQLITE4_MM_SYSTEM: {
      pMM = &mmSystem;
      break;
    }
    case SQLITE4_MM_OVERFLOW: {
      sqlite4_mm *pA = va_arg(ap, sqlite4_mm*);
      sqlite4_mm *pB = va_arg(ap, sqlite4_mm*);
      pMM = mmOvflNew(pA, pB);
      break;







|
|


|
|



|


|
|






|



>
>
>
>
>
















|







369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
  }
  return &pOnesz->base;
}

/*************************************************************************
** Main interfaces.
*/
void *sqlite4_mm_malloc(sqlite4_mm *pMM, sqlite4_size_t iSize){
  if( pMM==0 ) pMM = &sqlite4MMSystem;
  return pMM->pMethods->xMalloc(pMM,iSize);
}
void *sqlite4_mm_realloc(sqlite4_mm *pMM, void *pOld, sqlite4_size_t iSize){
  if( pMM==0 ) pMM = &sqlite4MMSystem;
  return pMM->pMethods->xRealloc(pMM,pOld,iSize);
}
void sqlite4_mm_free(sqlite4_mm *pMM, void *pOld){
  if( pMM==0 ) pMM = &sqlite4MMSystem;
  pMM->pMethods->xFree(pMM,pOld);
}
sqlite4_size_t sqlite4_mm_msize(sqlite4_mm *pMM, void *pOld){
  if( pMM==0 ) pMM = &sqlite4MMSystem;
  return pMM->pMethods->xMsize(pMM,pOld);
}
int sqlite4_mm_member(sqlite4_mm *pMM, const void *pOld){
  return (pMM && pMM->pMethods->xMember!=0) ?
            pMM->pMethods->xMember(pMM,pOld) : -1;
}
void sqlite4_mm_benign_failures(sqlite4_mm *pMM, int bEnable){
  if( pMM && pMM->pMethods->xBenign ){
    pMM->pMethods->xBenign(pMM, bEnable);
  }
}
sqlite4_int64 sqlite4_mm_stat(sqlite4_mm *pMM, int eStatType, unsigned flags){
  if( pMM==0 ) return -1;
  if( pMM->pMethods->xStat==0 ) return -1;
  return pMM->pMethods->xStat(pMM, eStatType, flags);
}
void sqlite4_mm_destroy(sqlite4_mm *pMM){
  if( pMM && pMM->pMethods->xFinal ) pMM->pMethods->xFinal(pMM);
}

/*
** Create a new memory allocation object.  eType determines the type of
** memory allocator and the arguments.
*/
sqlite4_mm *sqlite4_mm_new(sqlite4_mm_type eType, ...){
  va_list ap;
  sqlite4_mm *pMM;

  va_start(ap, eType);
  switch( eType ){
    case SQLITE4_MM_SYSTEM: {
      pMM = &sqlite4MMSystem;
      break;
    }
    case SQLITE4_MM_OVERFLOW: {
      sqlite4_mm *pA = va_arg(ap, sqlite4_mm*);
      sqlite4_mm *pB = va_arg(ap, sqlite4_mm*);
      pMM = mmOvflNew(pA, pB);
      break;
Changes to src/sqlite.h.in.
45
46
47
48
49
50
51








































































































































52
53
54
55
56
57
58
*/
#ifdef SQLITE4_VERSION
# undef SQLITE4_VERSION
#endif
#ifdef SQLITE4_VERSION_NUMBER
# undef SQLITE4_VERSION_NUMBER
#endif









































































































































/*
** CAPIREF: Run-time Environment Object
**
** An instance of the following object defines the run-time environment 
** for an SQLite4 database connection.  This object defines the interface
** to appropriate mutex routines, memory allocation routines, a







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







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
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
*/
#ifdef SQLITE4_VERSION
# undef SQLITE4_VERSION
#endif
#ifdef SQLITE4_VERSION_NUMBER
# undef SQLITE4_VERSION_NUMBER
#endif

/*
** CAPIREF: 64-Bit Integer Types
** KEYWORDS: sqlite4_int64 sqlite4_uint64
**
** Because there is no cross-platform way to specify 64-bit integer types
** SQLite includes typedefs for 64-bit signed and unsigned integers.
**
** ^The sqlite4_int64 and sqlite_int64 types can store integer values
** between -9223372036854775808 and +9223372036854775807 inclusive.  ^The
** sqlite4_uint64 and sqlite_uint64 types can store integer values 
** between 0 and +18446744073709551615 inclusive.
*/
#ifdef SQLITE4_INT64_TYPE
  typedef SQLITE4_INT64_TYPE sqlite4_int64_t;
  typedef unsigned SQLITE4_INT64_TYPE sqlite4_uint64_t;
#elif defined(_MSC_VER) || defined(__BORLANDC__)
  typedef __int64 sqlite4_int64_t;
  typedef unsigned __int64 sqlite4_uint64_t;
#else
  typedef long long int sqlite4_int64_t;
  typedef unsigned long long int sqlite4_uint64_t;
#endif
typedef sqlite4_int64_t sqlite4_int64;
typedef sqlite4_uint64_t sqlite4_uint64;

/*
** CAPIREF: String length type
**
** A type for measuring the length of the string.  Like size_t but
** does not require &lt;stddef.h&gt;
*/
typedef int sqlite4_size_t;

/*
** Available memory allocator object subtypes:
*/
typedef enum {
  SQLITE4_MM_SYSTEM = 1,     /* Use the system malloc() */
  SQLITE4_MM_ONESIZE = 2,    /* All allocations map to a fixed size */
  SQLITE4_MM_OVERFLOW = 3,   /* Two allocators. Use A first; failover to B */
  SQLITE4_MM_COMPACT = 4,    /* Like memsys3 from SQLite3 */
  SQLITE4_MM_ROBSON = 5,     /* Like memsys5 from SQLite3 */
  SQLITE4_MM_LINEAR = 6,     /* Allocate from a fixed buffer w/o free */
  SQLITE4_MM_BESPOKE = 7,    /* Caller-defined implementation */
  SQLITE4_MM_DEBUG,          /* Debugging memory allocator */
  SQLITE4_MM_STATS           /* Keep memory statistics */
} sqlite4_mm_type;

/*
** Base class for the memory allocator object.
**
** Implementations may extend this with additional
** fields specific to its own needs.  This needs to be public so that
** applications can supply their on customized memory allocators.
*/
typedef struct sqlite4_mm sqlite4_mm;
typedef struct sqlite4_mm_methods sqlite4_mm_methods;
struct sqlite4_mm {
  const struct sqlite4_mm_methods *pMethods;
};
struct sqlite4_mm_methods {
  int iVersion;
  void *(*xMalloc)(sqlite4_mm*, sqlite4_size_t);
  void *(*xRealloc)(sqlite4_mm*, void*, sqlite4_size_t);
  void (*xFree)(sqlite4_mm*, void*);
  sqlite4_size_t (*xMsize)(sqlite4_mm*, void*);
  int (*xMember)(sqlite4_mm*, const void*);
  void (*xBenign)(sqlite4_mm*, int);
  sqlite4_int64 (*xStat)(sqlite4_mm*, unsigned eType, unsigned bFlags);
  void (*xFinal)(sqlite4_mm*);
};

/*
** Return a pointer to the default memory allocator, which is basically
** a wrapper around system malloc()/realloc()/free().
*/
sqlite4_mm *sqlite4_mm_default(void);


/*
** Allocate a new memory manager.  Return NULL if unable.
*/
sqlite4_mm *sqlite4_mm_new(sqlite4_mm_type, ...);

/*
** Free the sqlite4_mm object.
**
** All outstanding memory for the allocator must be freed prior to
** invoking this interface, or else the behavior is undefined.
*/
void sqlite4_mm_destroy(sqlite4_mm*);

/*
** Core memory allocation routines:
*/
void *sqlite4_mm_malloc(sqlite4_mm*, sqlite4_size_t);
void *sqlite4_mm_realloc(sqlite4_mm*, void*, sqlite4_size_t);
void sqlite4_mm_free(sqlite4_mm*, void*);

/*
** Return the size of a memory allocation.
**
** All memory allocators in SQLite4 must be able to report their size.
** When using system malloc() on system that lack the malloc_usable_size()
** routine or its equivalent, then the sqlite4_mm object allocates 8 extra
** bytes for each memory allocation and stores the allocation size in those
** initial 8 bytes.
*/
sqlite4_size_t sqlite4_mm_msize(sqlite4_mm*, void*);

/*
** Check to see if pOld is a memory allocation from pMM.  If it is, return
** 1.  If not, return 0.  If we cannot determine an answer, return -1.
**
** If pOld is not a valid memory allocation or is a memory allocation that
** has previously been freed, then the result of this routine is undefined.
*/
int sqlite4_mm_member(sqlite4_mm *pMM, const void *pOld);

/*
** Return statistics or status information about a memory allocator.
** Not all memory allocators provide all stat values.  Some memory
** allocators provides no states at all.  If a particular stat for
** a memory allocator is unavailable, then -1 is returned.
*/
sqlite4_int64 sqlite4_mm_stat(sqlite4_mm *pMM, int eType, unsigned flags);

/*
** Enable or disable benign failure mode.  Benign failure mode can be
** nested.  In benign failure mode, OOM errors do not necessarily propagate
** back out to the application but can be dealt with internally.  Memory
** allocations that occur in benign failure mode are considered "optional".
*/
void sqlite4_mm_benign_failures(sqlite4_mm*, int bEnable);


/*
** CAPIREF: Run-time Environment Object
**
** An instance of the following object defines the run-time environment 
** for an SQLite4 database connection.  This object defines the interface
** to appropriate mutex routines, memory allocation routines, a
225
226
227
228
229
230
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
258
259
260
261
262
263
264
265
266
267
268
269
270
271
** is its destructor.  There are many other interfaces (such as
** [sqlite4_prepare], [sqlite4_create_function()], and
** [sqlite4_busy_timeout()] to name but three) that are methods on an
** sqlite4 object.
*/
typedef struct sqlite4 sqlite4;

/*
** CAPIREF: 64-Bit Integer Types
** KEYWORDS: sqlite4_int64 sqlite4_uint64
**
** Because there is no cross-platform way to specify 64-bit integer types
** SQLite includes typedefs for 64-bit signed and unsigned integers.
**
** ^The sqlite4_int64 and sqlite_int64 types can store integer values
** between -9223372036854775808 and +9223372036854775807 inclusive.  ^The
** sqlite4_uint64 and sqlite_uint64 types can store integer values 
** between 0 and +18446744073709551615 inclusive.
*/
#ifdef SQLITE4_INT64_TYPE
  typedef SQLITE4_INT64_TYPE sqlite4_int64_t;
  typedef unsigned SQLITE4_INT64_TYPE sqlite4_uint64_t;
#elif defined(_MSC_VER) || defined(__BORLANDC__)
  typedef __int64 sqlite4_int64_t;
  typedef unsigned __int64 sqlite4_uint64_t;
#else
  typedef long long int sqlite4_int64_t;
  typedef unsigned long long int sqlite4_uint64_t;
#endif
typedef sqlite4_int64_t sqlite4_int64;
typedef sqlite4_uint64_t sqlite4_uint64;

/*
** CAPIREF: String length type
**
** A type for measuring the length of the string.  Like size_t but
** does not require &lt;stddef.h&gt;
*/
typedef int sqlite4_size_t;

/*
** If compiling for a processor that lacks floating point support,
** substitute integer for floating-point.
*/
#ifdef SQLITE4_OMIT_FLOATING_POINT
# define double sqlite4_int64
#endif







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







361
362
363
364
365
366
367

































368
369
370
371
372
373
374
** is its destructor.  There are many other interfaces (such as
** [sqlite4_prepare], [sqlite4_create_function()], and
** [sqlite4_busy_timeout()] to name but three) that are methods on an
** sqlite4 object.
*/
typedef struct sqlite4 sqlite4;


































/*
** If compiling for a processor that lacks floating point support,
** substitute integer for floating-point.
*/
#ifdef SQLITE4_OMIT_FLOATING_POINT
# define double sqlite4_int64
#endif
Changes to src/sqliteInt.h.
2405
2406
2407
2408
2409
2410
2411

2412
2413
2414
2415
2416
2417
2418
  int iVersion;                     /* Version number of this structure */
  int bMemstat;                     /* True to enable memory status */
  int bCoreMutex;                   /* True to enable core mutexing */
  int bFullMutex;                   /* True to enable full mutexing */
  int mxStrlen;                     /* Maximum string length */
  int szLookaside;                  /* Default lookaside buffer size */
  int nLookaside;                   /* Default lookaside buffer count */

  sqlite4_mem_methods m;            /* Low-level memory allocation interface */
  sqlite4_mutex_methods mutex;      /* Low-level mutex interface */
  void *pHeap;                      /* Heap storage space */
  int nHeap;                        /* Size of pHeap[] */
  int mnReq, mxReq;                 /* Min and max heap requests sizes */
  int mxParserStack;                /* maximum depth of the parser stack */
  KVFactory *pFactory;              /* List of factories */







>







2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
  int iVersion;                     /* Version number of this structure */
  int bMemstat;                     /* True to enable memory status */
  int bCoreMutex;                   /* True to enable core mutexing */
  int bFullMutex;                   /* True to enable full mutexing */
  int mxStrlen;                     /* Maximum string length */
  int szLookaside;                  /* Default lookaside buffer size */
  int nLookaside;                   /* Default lookaside buffer count */
  sqlite4_mm *pMM;                  /* Memory allocator for this environment */
  sqlite4_mem_methods m;            /* Low-level memory allocation interface */
  sqlite4_mutex_methods mutex;      /* Low-level mutex interface */
  void *pHeap;                      /* Heap storage space */
  int nHeap;                        /* Size of pHeap[] */
  int mnReq, mxReq;                 /* Min and max heap requests sizes */
  int mxParserStack;                /* maximum depth of the parser stack */
  KVFactory *pFactory;              /* List of factories */
2480
2481
2482
2483
2484
2485
2486





2487
2488
2489
2490
2491
2492
2493
*/
#define SQLITE4_SKIP_UTF8(zIn) {                        \
  if( (*(zIn++))>=0xc0 ){                              \
    while( (*zIn & 0xc0)==0x80 ){ zIn++; }             \
  }                                                    \
}






/*
** The SQLITE4_*_BKPT macros are substitutes for the error codes with
** the same name but without the _BKPT suffix.  These macros invoke
** routines that report the line-number on which the error originated
** using sqlite4_log().  The routines also provide a convenient place
** to set a debugger breakpoint.
*/







>
>
>
>
>







2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
*/
#define SQLITE4_SKIP_UTF8(zIn) {                        \
  if( (*(zIn++))>=0xc0 ){                              \
    while( (*zIn & 0xc0)==0x80 ){ zIn++; }             \
  }                                                    \
}

/*
** Default memory allocator
*/
extern sqlite4_mm sqlite4MMSystem;

/*
** The SQLITE4_*_BKPT macros are substitutes for the error codes with
** the same name but without the _BKPT suffix.  These macros invoke
** routines that report the line-number on which the error originated
** using sqlite4_log().  The routines also provide a convenient place
** to set a debugger breakpoint.
*/
Changes to src/vdbeapi.c.
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
**
** This file contains code use to implement APIs that are part of the
** VDBE.
*/
#include "sqliteInt.h"
#include "vdbeInt.h"

#ifndef SQLITE4_OMIT_DEPRECATED
/*
** 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 sqlite4_prepare() generates.  For example, if new functions or
** collating sequences are registered or if an authorizer function is
** added or changed.
*/
int sqlite4_expired(sqlite4_stmt *pStmt){
  Vdbe *p = (Vdbe*)pStmt;
  return p==0 || p->expired;
}
#endif

/*
** Check on a Vdbe to make sure it has not been finalized.  Log
** an error and return true if it has been finalized (or is otherwise
** invalid).  Return false if it is ok.
*/
static int vdbeSafety(Vdbe *p){
  if( p->db==0 ){







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







12
13
14
15
16
17
18















19
20
21
22
23
24
25
**
** This file contains code use to implement APIs that are part of the
** VDBE.
*/
#include "sqliteInt.h"
#include "vdbeInt.h"
















/*
** Check on a Vdbe to make sure it has not been finalized.  Log
** an error and return true if it has been finalized (or is otherwise
** invalid).  Return false if it is ok.
*/
static int vdbeSafety(Vdbe *p){
  if( p->db==0 ){
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654

failed:
  if( xDelete ){
    xDelete(pDeleteArg, pAux);
  }
}

#ifndef SQLITE4_OMIT_DEPRECATED
/*
** Return the number of times the Step function of a aggregate has been 
** called.
**
** This function is deprecated.  Do not use it for new code.  It is
** provide only to avoid breaking legacy code.  New aggregate function
** implementations should keep their own counts within their aggregate
** context.
*/
int sqlite4_aggregate_count(sqlite4_context *p){
  assert( p && p->pMem && p->pFunc && p->pFunc->xStep );
  return p->pMem->n;
}
#endif

/*
** Return the number of columns in the result set for the statement pStmt.
*/
int sqlite4_column_count(sqlite4_stmt *pStmt){
  Vdbe *pVm = (Vdbe *)pStmt;
  return pVm ? pVm->nResColumn : 0;
}







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







610
611
612
613
614
615
616
















617
618
619
620
621
622
623

failed:
  if( xDelete ){
    xDelete(pDeleteArg, pAux);
  }
}

















/*
** Return the number of columns in the result set for the statement pStmt.
*/
int sqlite4_column_count(sqlite4_stmt *pStmt){
  Vdbe *pVm = (Vdbe *)pStmt;
  return pVm ? pVm->nResColumn : 0;
}
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
  for(i=0; i<pFrom->nVar; i++){
    sqlite4VdbeMemMove(&pTo->aVar[i], &pFrom->aVar[i]);
  }
  sqlite4_mutex_leave(pTo->db->mutex);
  return SQLITE4_OK;
}

#ifndef SQLITE4_OMIT_DEPRECATED
/*
** Deprecated external interface.  Internal/core SQLite code
** should call sqlite4TransferBindings.
**
** Is is misuse to call this routine with statements from different
** database connections.  But as this is a deprecated interface, we
** will not bother to check for that condition.
**
** If the two statements contain a different number of bindings, then
** an SQLITE4_ERROR is returned.  Nothing else can go wrong, so otherwise
** SQLITE4_OK is returned.
*/
int sqlite4_transfer_bindings(sqlite4_stmt *pFromStmt, sqlite4_stmt *pToStmt){
  Vdbe *pFrom = (Vdbe*)pFromStmt;
  Vdbe *pTo = (Vdbe*)pToStmt;
  if( pFrom->nVar!=pTo->nVar ){
    return SQLITE4_ERROR;
  }
  if( pTo->expmask ){
    pTo->expired = 1;
  }
  if( pFrom->expmask ){
    pFrom->expired = 1;
  }
  return sqlite4TransferBindings(pFromStmt, pToStmt);
}
#endif

/*
** Return the sqlite4* database handle to which the prepared statement given
** in the argument belongs.  This is the same database handle that was
** the first argument to the sqlite4_prepare() that was used to create
** the statement in the first place.
*/
sqlite4 *sqlite4_db_handle(sqlite4_stmt *pStmt){







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







1162
1163
1164
1165
1166
1167
1168





























1169
1170
1171
1172
1173
1174
1175
  for(i=0; i<pFrom->nVar; i++){
    sqlite4VdbeMemMove(&pTo->aVar[i], &pFrom->aVar[i]);
  }
  sqlite4_mutex_leave(pTo->db->mutex);
  return SQLITE4_OK;
}






























/*
** Return the sqlite4* database handle to which the prepared statement given
** in the argument belongs.  This is the same database handle that was
** the first argument to the sqlite4_prepare() that was used to create
** the statement in the first place.
*/
sqlite4 *sqlite4_db_handle(sqlite4_stmt *pStmt){
Deleted test/bindxfer.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
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
# 2005 April 21
#
# 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 regression tests for SQLite library.  The
# focus of this script testing the sqlite_transfer_bindings() API.
#
# $Id: bindxfer.test,v 1.9 2009/04/17 11:56:28 drh Exp $
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl

proc sqlite_step {stmt VALS COLS} {
  upvar #0 $VALS vals
  upvar #0 $COLS cols
  set vals [list]
  set cols [list]

  set rc [sqlite4_step $stmt]
  for {set i 0} {$i < [sqlite4_column_count $stmt]} {incr i} {
    lappend cols [sqlite4_column_name $stmt $i]
  }
  for {set i 0} {$i < [sqlite4_data_count $stmt]} {incr i} {
    lappend vals [sqlite4_column_text $stmt $i]
  }

  return $rc
}

do_test bindxfer-1.1 {
  set DB [sqlite4_connection_pointer db]
  execsql {CREATE TABLE t1(a,b,c);}
  set VM1 [sqlite4_prepare $DB {SELECT ?, ?, ?} -1 TAIL]
  set TAIL
} {}
do_test bindxfer-1.2 {
  sqlite4_bind_parameter_count $VM1
} 3
do_test bindxfer-1.3 {
  set VM2 [sqlite4_prepare $DB {SELECT ?, ?, ?} -1 TAIL]
  set TAIL
} {}
do_test bindxfer-1.4 {
  sqlite4_bind_parameter_count $VM2
} 3
ifcapable deprecated {
  do_test bindxfer-1.5 {
    sqlite_bind $VM1 1 one normal
    set sqlite_static_bind_value two
    sqlite_bind $VM1 2 {} static
    sqlite_bind $VM1 3 {} null
    sqlite4_transfer_bindings $VM1 $VM2
    sqlite_step $VM1 VALUES COLNAMES
  } SQLITE4_ROW
  do_test bindxfer-1.6 {
    set VALUES
  } {{} {} {}}
  do_test bindxfer-1.7 {
    sqlite_step $VM2 VALUES COLNAMES
  } SQLITE4_ROW
  do_test bindxfer-1.8 {
    set VALUES
  } {one two {}}
}
catch {sqlite4_finalize $VM1}
catch {sqlite4_finalize $VM2}


finish_test
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
























































































































































Changes to test/enc4.test.
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
  do_test enc4-$i.1 {
    db eval {PRAGMA encoding}
  } $enc

  set j 1
  foreach init $inits {

    do_test enc4-$i.$j.2 {
      set S [sqlite4_prepare db "SELECT $init+?" -1 dummy]
      sqlite4_expired $S
    } {0}
      
    set k 1
    foreach val $vals {
      for {set x 1} {$x<16} {incr x} {
        set part [expr $init + [string range $val 0 [expr $x-1]]]

        do_realnum_test enc4-$i.$j.$k.3.$x {
          sqlite4_reset $S







<
|
<
<
<







50
51
52
53
54
55
56

57



58
59
60
61
62
63
64
  do_test enc4-$i.1 {
    db eval {PRAGMA encoding}
  } $enc

  set j 1
  foreach init $inits {


    set S [sqlite4_prepare db "SELECT $init+?" -1 dummy]



    set k 1
    foreach val $vals {
      for {set x 1} {$x<16} {incr x} {
        set part [expr $init + [string range $val 0 [expr $x-1]]]

        do_realnum_test enc4-$i.$j.$k.3.$x {
          sqlite4_reset $S
Changes to test/permutations.test.
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
  aggerror.test
  attach.test
  autoindex1.test
  badutf.test
  between.test
  bigrow.test
  bind.test
  bindxfer.test

  boundary1.test boundary4.test
  cast.test
  coalesce.test 
  collate1.test collate2.test collate3.test collate4.test collate5.test
  collate6.test collate7.test collate8.test collate9.test collateA.test
  conflict.test 







<







145
146
147
148
149
150
151

152
153
154
155
156
157
158
  aggerror.test
  attach.test
  autoindex1.test
  badutf.test
  between.test
  bigrow.test
  bind.test


  boundary1.test boundary4.test
  cast.test
  coalesce.test 
  collate1.test collate2.test collate3.test collate4.test collate5.test
  collate6.test collate7.test collate8.test collate9.test collateA.test
  conflict.test 
Changes to test/test_main.c.
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
      sqlite4_result_error(context, "x_count totals to 42", -1);
    }else{
      sqlite4_result_int(context, p ? p->n : 0);
    }
  }
}

#ifndef SQLITE4_OMIT_DEPRECATED
static void legacyCountStep(
  sqlite4_context *context,
  int argc,
  sqlite4_value **argv
){
  /* no-op */
}

static void legacyCountFinalize(sqlite4_context *context){
  sqlite4_result_int(context, sqlite4_aggregate_count(context));
}
#endif

/*
** Usage:  sqlite4_create_aggregate DB
**
** Call the sqlite4_create_function API on the given database in order
** to create a function named "x_count".  This function is similar
** to the built-in count() function, with a few special quirks
** for testing the sqlite4_result_error() APIs.







<
<
<
<
<
<
<
<
<
<
<
<
<
<







1008
1009
1010
1011
1012
1013
1014














1015
1016
1017
1018
1019
1020
1021
      sqlite4_result_error(context, "x_count totals to 42", -1);
    }else{
      sqlite4_result_int(context, p ? p->n : 0);
    }
  }
}















/*
** Usage:  sqlite4_create_aggregate DB
**
** Call the sqlite4_create_function API on the given database in order
** to create a function named "x_count".  This function is similar
** to the built-in count() function, with a few special quirks
** for testing the sqlite4_result_error() APIs.
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
  if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
  rc = sqlite4_create_function(db, "x_count", 0, SQLITE4_UTF8, 0, 0,
      t1CountStep,t1CountFinalize);
  if( rc==SQLITE4_OK ){
    rc = sqlite4_create_function(db, "x_count", 1, SQLITE4_UTF8, 0, 0,
        t1CountStep,t1CountFinalize);
  }
#ifndef SQLITE4_OMIT_DEPRECATED
  if( rc==SQLITE4_OK ){
    rc = sqlite4_create_function(db, "legacy_count", 0, SQLITE4_ANY, 0, 0,
        legacyCountStep, legacyCountFinalize
    );
  }
#endif
  if( sqlite4TestErrCode(interp, db, rc) ) return TCL_ERROR;
  Tcl_SetResult(interp, (char *)t1ErrorName(rc), 0);
  return TCL_OK;
}


/*







<
<
<
<
<
<
<







1047
1048
1049
1050
1051
1052
1053







1054
1055
1056
1057
1058
1059
1060
  if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
  rc = sqlite4_create_function(db, "x_count", 0, SQLITE4_UTF8, 0, 0,
      t1CountStep,t1CountFinalize);
  if( rc==SQLITE4_OK ){
    rc = sqlite4_create_function(db, "x_count", 1, SQLITE4_UTF8, 0, 0,
        t1CountStep,t1CountFinalize);
  }







  if( sqlite4TestErrCode(interp, db, rc) ) return TCL_ERROR;
  Tcl_SetResult(interp, (char *)t1ErrorName(rc), 0);
  return TCL_OK;
}


/*
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
  }
  Tcl_SetResult(interp, (char *)t1ErrorName(rc), TCL_STATIC);
/*
  if( rc ){
    return TCL_ERROR;
  }
*/
  return TCL_OK;
}

/*
** Usage:  sqlite4_expired STMT 
**
** Return TRUE if a recompilation of the statement is recommended.
*/
static int test_expired(
  void * clientData,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
){
#ifndef SQLITE4_OMIT_DEPRECATED
  sqlite4_stmt *pStmt;
  if( objc!=2 ){
    Tcl_AppendResult(interp, "wrong # args: should be \"",
        Tcl_GetStringFromObj(objv[0], 0), " <STMT>", 0);
    return TCL_ERROR;
  }
  if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
  Tcl_SetObjResult(interp, Tcl_NewBooleanObj(sqlite4_expired(pStmt)));
#endif
  return TCL_OK;
}

/*
** Usage:  sqlite4_transfer_bindings FROMSTMT TOSTMT
**
** Transfer all bindings from FROMSTMT over to TOSTMT
*/
static int test_transfer_bind(
  void * clientData,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
){
#ifndef SQLITE4_OMIT_DEPRECATED
  sqlite4_stmt *pStmt1, *pStmt2;
  if( objc!=3 ){
    Tcl_AppendResult(interp, "wrong # args: should be \"",
        Tcl_GetStringFromObj(objv[0], 0), " FROM-STMT TO-STMT", 0);
    return TCL_ERROR;
  }
  if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt1)) return TCL_ERROR;
  if( getStmtPointer(interp, Tcl_GetString(objv[2]), &pStmt2)) return TCL_ERROR;
  Tcl_SetObjResult(interp, 
     Tcl_NewIntObj(sqlite4_transfer_bindings(pStmt1,pStmt2)));
#endif
  return TCL_OK;
}

/*
** Usage:  sqlite4_changes DB
**
** Return the number of changes made to the database by the last SQL







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







1938
1939
1940
1941
1942
1943
1944


















































1945
1946
1947
1948
1949
1950
1951
  }
  Tcl_SetResult(interp, (char *)t1ErrorName(rc), TCL_STATIC);
/*
  if( rc ){
    return TCL_ERROR;
  }
*/


















































  return TCL_OK;
}

/*
** Usage:  sqlite4_changes DB
**
** Return the number of changes made to the database by the last SQL
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
  zRet = xFunc(pStmt, col);
  if( zRet ){
    Tcl_SetResult(interp, (char *)zRet, 0);
  }
  return TCL_OK;
}

static int test_global_recover(
  void * clientData,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
){
#ifndef SQLITE4_OMIT_DEPRECATED
  int rc;
  if( objc!=1 ){
    Tcl_WrongNumArgs(interp, 1, objv, "");
    return TCL_ERROR;
  }
  rc = sqlite4_global_recover();
  Tcl_SetResult(interp, (char *)t1ErrorName(rc), TCL_STATIC);
#endif
  return TCL_OK;
}

/*
** Usage: sqlite4_column_text STMT column
**
** Usage: sqlite4_column_decltype STMT column
**
** Usage: sqlite4_column_name STMT column
*/







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







3417
3418
3419
3420
3421
3422
3423


















3424
3425
3426
3427
3428
3429
3430
  zRet = xFunc(pStmt, col);
  if( zRet ){
    Tcl_SetResult(interp, (char *)zRet, 0);
  }
  return TCL_OK;
}



















/*
** Usage: sqlite4_column_text STMT column
**
** Usage: sqlite4_column_decltype STMT column
**
** Usage: sqlite4_column_name STMT column
*/
4578
4579
4580
4581
4582
4583
4584
4585
4586
4587
4588
4589
4590
4591
4592
4593
     { "sqlite4_open_v2",               test_open_v2       ,0 },

     { "sqlite4_prepare",               test_prepare       ,0 },
     { "sqlite4_prepare_tkt3134",       test_prepare_tkt3134, 0},
     { "sqlite4_finalize",              test_finalize      ,0 },
     { "sqlite4_stmt_status",           test_stmt_status   ,0 },
     { "sqlite4_reset",                 test_reset         ,0 },
     { "sqlite4_expired",               test_expired       ,0 },
     { "sqlite4_transfer_bindings",     test_transfer_bind ,0 },
     { "sqlite4_changes",               test_changes       ,0 },
     { "sqlite4_step",                  test_step          ,0 },
     { "sqlite4_sql",                   test_sql           ,0 },
     { "sqlite4_next_stmt",             test_next_stmt     ,0 },
     { "sqlite4_stmt_readonly",         test_stmt_readonly ,0 },
     { "sqlite4_stmt_busy",             test_stmt_busy     ,0 },
     { "uses_stmt_journal",             uses_stmt_journal ,0 },







<
<







4489
4490
4491
4492
4493
4494
4495


4496
4497
4498
4499
4500
4501
4502
     { "sqlite4_open_v2",               test_open_v2       ,0 },

     { "sqlite4_prepare",               test_prepare       ,0 },
     { "sqlite4_prepare_tkt3134",       test_prepare_tkt3134, 0},
     { "sqlite4_finalize",              test_finalize      ,0 },
     { "sqlite4_stmt_status",           test_stmt_status   ,0 },
     { "sqlite4_reset",                 test_reset         ,0 },


     { "sqlite4_changes",               test_changes       ,0 },
     { "sqlite4_step",                  test_step          ,0 },
     { "sqlite4_sql",                   test_sql           ,0 },
     { "sqlite4_next_stmt",             test_next_stmt     ,0 },
     { "sqlite4_stmt_readonly",         test_stmt_readonly ,0 },
     { "sqlite4_stmt_busy",             test_stmt_busy     ,0 },
     { "uses_stmt_journal",             uses_stmt_journal ,0 },
4634
4635
4636
4637
4638
4639
4640
4641
4642
4643
4644
4645
4646
4647
4648
{"sqlite4_column_database_name16",
  test_stmt_utf16, sqlite4_column_database_name16},
{"sqlite4_column_table_name16", test_stmt_utf16, (void*)sqlite4_column_table_name16},
{"sqlite4_column_origin_name16", test_stmt_utf16, (void*)sqlite4_column_origin_name16},
#endif
#endif
     { "sqlite4_create_collation",   test_create_collation, 0 },
     { "sqlite4_global_recover",     test_global_recover, 0   },
     { "working_64bit_int",          working_64bit_int,   0   },
     { "sqlite4_create_function_v2", test_create_function_v2, 0 },

     /* Functions from os.h */
#ifndef SQLITE4_OMIT_UTF16
     { "add_test_collate",        test_collate, 0            },
     { "add_test_collate_needed", test_collate_needed, 0     },







<







4543
4544
4545
4546
4547
4548
4549

4550
4551
4552
4553
4554
4555
4556
{"sqlite4_column_database_name16",
  test_stmt_utf16, sqlite4_column_database_name16},
{"sqlite4_column_table_name16", test_stmt_utf16, (void*)sqlite4_column_table_name16},
{"sqlite4_column_origin_name16", test_stmt_utf16, (void*)sqlite4_column_origin_name16},
#endif
#endif
     { "sqlite4_create_collation",   test_create_collation, 0 },

     { "working_64bit_int",          working_64bit_int,   0   },
     { "sqlite4_create_function_v2", test_create_function_v2, 0 },

     /* Functions from os.h */
#ifndef SQLITE4_OMIT_UTF16
     { "add_test_collate",        test_collate, 0            },
     { "add_test_collate_needed", test_collate_needed, 0     },