/ Check-in [1914044b]
Login

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

Overview
Comment:Reenable the memory management logic. The quick.test script now runs with SQLITE_MEMDEBUG and SQLITE_ENABLE_MEMORY_MANAGEMENT. 7 minor errors. (CVS 4265)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 1914044b8832041f13b20ead613bd13725425d7a
User & Date: drh 2007-08-22 00:39:20
Context
2007-08-22
02:56
A complete run of quick.test with mutex debugging enabled. (CVS 4266) check-in: 783e07d5 user: drh tags: trunk
00:39
Reenable the memory management logic. The quick.test script now runs with SQLITE_MEMDEBUG and SQLITE_ENABLE_MEMORY_MANAGEMENT. 7 minor errors. (CVS 4265) check-in: 1914044b user: drh tags: trunk
2007-08-21
20:25
All mutexing and locking appears to be in place. Now we just have to test it and make it all work. (CVS 4264) check-in: 0f7941ae user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/btree.c.

5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
..
26
27
28
29
30
31
32


33
34
35
36
37
38
39
40
41
42
43
44
45
46
** 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.
**
*************************************************************************
** $Id: btree.c,v 1.406 2007/08/21 19:33:56 drh Exp $
**
** This file implements a external (disk-based) database using BTrees.
** See the header comment on "btreeInt.h" for additional information.
** Including a description of file format and an overview of operation.
*/
#include "btreeInt.h"

................................................................................
/*
** Set this global variable to 1 to enable tracing using the TRACE
** macro.
*/
#if SQLITE_TEST
int sqlite3_btree_trace=0;  /* True to enable tracing */
#endif



#ifndef SQLITE_OMIT_SHARED_CACHE
/*
** A flag to indicate whether or not shared cache is enabled.  Also,
** a list of BtShared objects that are eligible for participation
** in shared cache.  The variables have file scope during normal builds,
** but the test harness needs to access these variables so make them
** global for test builds.
*/
#ifdef SQLITE_TEST
BtShared *sqlite3SharedCacheList = 0;
int sqlite3SharedCacheEnabled = 0;
#else
static BtShared *sqlite3SharedCacheList = 0;







|







 







>
>






|







5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
..
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
** 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.
**
*************************************************************************
** $Id: btree.c,v 1.407 2007/08/22 00:39:20 drh Exp $
**
** This file implements a external (disk-based) database using BTrees.
** See the header comment on "btreeInt.h" for additional information.
** Including a description of file format and an overview of operation.
*/
#include "btreeInt.h"

................................................................................
/*
** Set this global variable to 1 to enable tracing using the TRACE
** macro.
*/
#if SQLITE_TEST
int sqlite3_btree_trace=0;  /* True to enable tracing */
#endif



#ifndef SQLITE_OMIT_SHARED_CACHE
/*
** A flag to indicate whether or not shared cache is enabled.  Also,
** a list of BtShared objects that are eligible for participation
** in shared cache.  The variables have file scope during normal builds,
** but the test harness needs to access these variables so we make them
** global for test builds.
*/
#ifdef SQLITE_TEST
BtShared *sqlite3SharedCacheList = 0;
int sqlite3SharedCacheEnabled = 0;
#else
static BtShared *sqlite3SharedCacheList = 0;

Changes to src/btreeInt.h.

5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
...
378
379
380
381
382
383
384

385
386
387
388
389
390
391
392
393
394
395
** 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.
**
*************************************************************************
** $Id: btreeInt.h,v 1.8 2007/08/20 22:48:42 drh Exp $
**
** This file implements a external (disk-based) database using BTrees.
** For a detailed discussion of BTrees, refer to
**
**     Donald E. Knuth, THE ART OF COMPUTER PROGRAMMING, Volume 3:
**     "Sorting And Searching", pages 473-480. Addison-Wesley
**     Publishing Company, Reading, Massachusetts.
................................................................................
  int maxLeaf;          /* Maximum local payload in a LEAFDATA table */
  int minLeaf;          /* Minimum local payload in a LEAFDATA table */
  BusyHandler *pBusyHandler;   /* Callback for when there is lock contention */
  u8 inTransaction;     /* Transaction state */
  int nTransaction;     /* Number of open transactions (read + write) */
  void *pSchema;        /* Pointer to space allocated by sqlite3BtreeSchema() */
  void (*xFreeSchema)(void*);  /* Destructor for BtShared.pSchema */

#ifndef SQLITE_OMIT_SHARED_CACHE
  int nRef;             /* Number of references to this structure */
  BtShared *pNext;      /* Next on a list of sharable BtShared structs */
  sqlite3_mutex *mutex; /* Non-recursive mutex required to access this struct */
  BtLock *pLock;        /* List of locks held on this shared-btree struct */
#endif
};

/*
** An instance of the following structure is used to hold information
** about a cell.  The parseCellPtr() function fills in this structure







|







 







>



<







5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
...
378
379
380
381
382
383
384
385
386
387
388

389
390
391
392
393
394
395
** 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.
**
*************************************************************************
** $Id: btreeInt.h,v 1.9 2007/08/22 00:39:20 drh Exp $
**
** This file implements a external (disk-based) database using BTrees.
** For a detailed discussion of BTrees, refer to
**
**     Donald E. Knuth, THE ART OF COMPUTER PROGRAMMING, Volume 3:
**     "Sorting And Searching", pages 473-480. Addison-Wesley
**     Publishing Company, Reading, Massachusetts.
................................................................................
  int maxLeaf;          /* Maximum local payload in a LEAFDATA table */
  int minLeaf;          /* Minimum local payload in a LEAFDATA table */
  BusyHandler *pBusyHandler;   /* Callback for when there is lock contention */
  u8 inTransaction;     /* Transaction state */
  int nTransaction;     /* Number of open transactions (read + write) */
  void *pSchema;        /* Pointer to space allocated by sqlite3BtreeSchema() */
  void (*xFreeSchema)(void*);  /* Destructor for BtShared.pSchema */
  sqlite3_mutex *mutex; /* Non-recursive mutex required to access this struct */
#ifndef SQLITE_OMIT_SHARED_CACHE
  int nRef;             /* Number of references to this structure */
  BtShared *pNext;      /* Next on a list of sharable BtShared structs */

  BtLock *pLock;        /* List of locks held on this shared-btree struct */
#endif
};

/*
** An instance of the following structure is used to hold information
** about a cell.  The parseCellPtr() function fills in this structure

Changes to src/main.c.

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
...
767
768
769
770
771
772
773
774
775
776
777

778
779
780
781
782
783
784
**
*************************************************************************
** Main file for the SQLite library.  The routines in this file
** implement the programmer interface to the library.  Routines in
** other files are for internal use by SQLite and should not be
** accessed by users of the library.
**
** $Id: main.c,v 1.393 2007/08/21 19:33:56 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

/*
** The version of the library
*/
................................................................................
*/
const char *sqlite3_errmsg(sqlite3 *db){
  const char *z;
  if( !db ){
    return sqlite3ErrStr(SQLITE_NOMEM);
  }
  sqlite3_mutex_enter(db->mutex);
  assert( !db->mallocFailed );
  if( sqlite3SafetyCheck(db) || db->errCode==SQLITE_MISUSE ){
    return sqlite3ErrStr(SQLITE_MISUSE);
  }

  z = (char*)sqlite3_value_text(db->pErr);
  if( z==0 ){
    z = sqlite3ErrStr(db->errCode);
  }
  sqlite3_mutex_leave(db->mutex);
  return z;
}







|







 







<



>







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
...
767
768
769
770
771
772
773

774
775
776
777
778
779
780
781
782
783
784
**
*************************************************************************
** Main file for the SQLite library.  The routines in this file
** implement the programmer interface to the library.  Routines in
** other files are for internal use by SQLite and should not be
** accessed by users of the library.
**
** $Id: main.c,v 1.394 2007/08/22 00:39:20 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

/*
** The version of the library
*/
................................................................................
*/
const char *sqlite3_errmsg(sqlite3 *db){
  const char *z;
  if( !db ){
    return sqlite3ErrStr(SQLITE_NOMEM);
  }
  sqlite3_mutex_enter(db->mutex);

  if( sqlite3SafetyCheck(db) || db->errCode==SQLITE_MISUSE ){
    return sqlite3ErrStr(SQLITE_MISUSE);
  }
  assert( !db->mallocFailed );
  z = (char*)sqlite3_value_text(db->pErr);
  if( z==0 ){
    z = sqlite3ErrStr(db->errCode);
  }
  sqlite3_mutex_leave(db->mutex);
  return z;
}

Changes to src/malloc.c.

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

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

/*
** Release memory held by SQLite instances created by the current thread.
*/
int sqlite3_release_memory(int n){
#if defined(SQLITE_ENABLE_MEMORY_MANAGEMENT) && !defined(SQLITE_OMIT_DISKIO)
  return sqlite3PagerReleaseMemory(n);
#else
  return SQLITE_OK;
#endif
}









|







 







|







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

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

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


Changes to src/mutex.c.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
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
...
265
266
267
268
269
270
271

272
273
274
275
276
277
278
...
287
288
289
290
291
292
293


294
295
296
297
298
299
300
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains the C functions that implement mutexes for
** use by the SQLite core.
**
** $Id: mutex.c,v 1.6 2007/08/21 10:44:16 drh Exp $
*/
/*
** If SQLITE_MUTEX_APPDEF is defined, then this whole module is
** omitted and equivalent functionality must be provided by the
** application that links against the SQLite library.
*/
#ifndef SQLITE_MUTEX_APPDEF
................................................................................

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


      pNew = &aStatic[id-SQLITE_MUTEX_STATIC_MASTER];
      pNew->id = id;
      break;
    }
  }
  return pNew;
}
................................................................................
** the same type number.
*/
sqlite3_mutex *sqlite3_mutex_alloc(int iType){
  static sqlite3_mutex staticMutexes[] = {
    { PTHREAD_MUTEX_INITIALIZER, },
    { PTHREAD_MUTEX_INITIALIZER, },
    { PTHREAD_MUTEX_INITIALIZER, },

  };
  sqlite3_mutex *p;
  switch( iType ){
    case SQLITE_MUTEX_FAST: {
      p = sqlite3MallocZero( sizeof(*p) );
      if( p ){
        p->id = iType;
................................................................................
        pthread_mutex_init(&px->auxMutex, 0);
        pthread_mutex_init(&px->mainMutex, 0);
        px->nRef = 0;
      }
      break;
    }
    default: {


      p = &staticMutexes[iType-2];
      p->id = iType;
      break;
    }
  }
  return p;
}







|







 







|












>
>







 







>







 







>
>







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
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
...
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
...
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains the C functions that implement mutexes for
** use by the SQLite core.
**
** $Id: mutex.c,v 1.7 2007/08/22 00:39:20 drh Exp $
*/
/*
** If SQLITE_MUTEX_APPDEF is defined, then this whole module is
** omitted and equivalent functionality must be provided by the
** application that links against the SQLite library.
*/
#ifndef SQLITE_MUTEX_APPDEF
................................................................................

/*
** The sqlite3_mutex_alloc() routine allocates a new
** mutex and returns a pointer to it.  If it returns NULL
** that means that a mutex could not be allocated. 
*/
sqlite3_mutex *sqlite3_mutex_alloc(int id){
  static sqlite3_mutex aStatic[4];
  sqlite3_mutex *pNew = 0;
  switch( id ){
    case SQLITE_MUTEX_FAST:
    case SQLITE_MUTEX_RECURSIVE: {
      pNew = sqlite3_malloc(sizeof(*pNew));
      if( pNew ){
        pNew->id = id;
        pNew->cnt = 0;
      }
      break;
    }
    default: {
      assert( id-SQLITE_MUTEX_STATIC_MASTER >= 0 );
      assert( id-SQLITE_MUTEX_STATIC_MASTER < count(aStatic) );
      pNew = &aStatic[id-SQLITE_MUTEX_STATIC_MASTER];
      pNew->id = id;
      break;
    }
  }
  return pNew;
}
................................................................................
** the same type number.
*/
sqlite3_mutex *sqlite3_mutex_alloc(int iType){
  static sqlite3_mutex staticMutexes[] = {
    { PTHREAD_MUTEX_INITIALIZER, },
    { PTHREAD_MUTEX_INITIALIZER, },
    { PTHREAD_MUTEX_INITIALIZER, },
    { PTHREAD_MUTEX_INITIALIZER, },
  };
  sqlite3_mutex *p;
  switch( iType ){
    case SQLITE_MUTEX_FAST: {
      p = sqlite3MallocZero( sizeof(*p) );
      if( p ){
        p->id = iType;
................................................................................
        pthread_mutex_init(&px->auxMutex, 0);
        pthread_mutex_init(&px->mainMutex, 0);
        px->nRef = 0;
      }
      break;
    }
    default: {
      assert( iType-2 >= 0 );
      assert( iType-2 < count(staticMutexes) );
      p = &staticMutexes[iType-2];
      p->id = iType;
      break;
    }
  }
  return p;
}

Changes to src/pager.c.

14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
...
358
359
360
361
362
363
364
365



366
367
368
369
370
371
372
...
379
380
381
382
383
384
385









386
387
388
389
390
391
392
...
448
449
450
451
452
453
454
































455
456
457
458
459
460
461
....
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
....
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
....
1911
1912
1913
1914
1915
1916
1917





1918





1919


1920
1921
1922
1923
1924
1925
1926
....
1955
1956
1957
1958
1959
1960
1961

1962
1963

1964
1965
1966
1967
1968
1969
1970
....
2238
2239
2240
2241
2242
2243
2244

2245

2246
2247
2248
2249
2250

2251

2252
2253
2254
2255
2256
2257
2258
....
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280

2281


2282
2283




2284
2285
2286
2287
2288
2289
2290
....
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
....
2379
2380
2381
2382
2383
2384
2385

2386

2387
2388
2389
2390
2391
2392
2393
....
2752
2753
2754
2755
2756
2757
2758

2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799

2800
2801
2802


2803
2804
2805
2806
2807
2808
2809
....
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
....
2850
2851
2852
2853
2854
2855
2856









2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
....
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
....
3283
3284
3285
3286
3287
3288
3289













3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307

3308
3309
3310
3311
3312
3313
3314

3315
3316
3317


3318
3319
3320
3321
3322
3323
3324
....
3327
3328
3329
3330
3331
3332
3333

3334
3335
3336
3337
3338
3339
3340
....
3362
3363
3364
3365
3366
3367
3368

3369
3370
3371
3372
3373
3374
3375
....
3465
3466
3467
3468
3469
3470
3471

3472
3473
3474
3475
3476
3477
3478
....
3481
3482
3483
3484
3485
3486
3487

3488
3489
3490
3491
3492
3493
3494
....
3508
3509
3510
3511
3512
3513
3514

3515
3516
3517
3518
3519
3520
3521
....
3752
3753
3754
3755
3756
3757
3758

3759
3760
3761
3762
3763
3764
3765
....
3803
3804
3805
3806
3807
3808
3809

3810
3811
3812
3813
3814
3815
3816
....
3826
3827
3828
3829
3830
3831
3832

3833
3834
3835
3836
3837
3838
3839
3840

3841
3842
3843
3844
3845
3846
3847
....
3867
3868
3869
3870
3871
3872
3873

3874
3875
3876
3877
3878
3879
3880
....
3888
3889
3890
3891
3892
3893
3894

3895
3896
3897
3898
3899
3900
3901
....
3904
3905
3906
3907
3908
3909
3910

3911
3912
3913
3914
3915
3916
3917
....
3926
3927
3928
3929
3930
3931
3932

3933
3934
3935
3936
3937
3938
3939
....
3978
3979
3980
3981
3982
3983
3984

3985
3986
3987
3988
3989
3990
3991
....
4053
4054
4055
4056
4057
4058
4059

4060
4061
4062
4063
4064
4065
4066
....
4074
4075
4076
4077
4078
4079
4080

4081
4082
4083
4084
4085
4086
4087
....
4103
4104
4105
4106
4107
4108
4109
4110


4111
4112
4113
4114
4115
4116
4117
....
4157
4158
4159
4160
4161
4162
4163

4164
4165

4166
4167
4168
4169
4170
4171
4172

4173
4174
4175
4176
4177
4178
4179
....
4185
4186
4187
4188
4189
4190
4191
4192


4193
4194
4195
4196
4197
4198
4199
....
4231
4232
4233
4234
4235
4236
4237
4238
4239
4240
4241
4242
4243
4244
4245
....
4277
4278
4279
4280
4281
4282
4283







4284
4285
4286
4287
4288

4289
4290
4291
4292
4293
4294
4295
....
4305
4306
4307
4308
4309
4310
4311

4312
4313
4314
4315
4316
4317
4318
4319

4320
4321
4322
4323
4324
4325
4326
....
4337
4338
4339
4340
4341
4342
4343

4344
4345
4346
4347
4348
4349
4350
....
4406
4407
4408
4409
4410
4411
4412

4413
4414
4415
4416
4417
4418
4419
....
4482
4483
4484
4485
4486
4487
4488

4489
4490
4491
4492
4493
4494
4495
** The pager is used to access a database disk file.  It implements
** atomic commit and rollback through the use of a journal file that
** is separate from the database file.  The pager also implements file
** locking to prevent two processes from writing the same database
** file simultaneously, or one process from reading the database while
** another is writing.
**
** @(#) $Id: pager.c,v 1.364 2007/08/21 14:27:02 danielk1977 Exp $
*/
#ifndef SQLITE_OMIT_DISKIO
#include "sqliteInt.h"
#include <assert.h>
#include <string.h>

/*
................................................................................
#ifdef SQLITE_HAS_CODEC
  void *(*xCodec)(void*,void*,Pgno,int); /* Routine for en/decoding data */
  void *pCodecArg;            /* First argument to xCodec() */
#endif
  int nHash;                  /* Size of the pager hash table */
  PgHdr **aHash;              /* Hash table to map page number to PgHdr */
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
  Pager *pNext;               /* Linked list of pagers in this thread */



#endif
  char *pTmpSpace;            /* Pager.pageSize bytes of space for tmp use */
  char dbFileVers[16];        /* Changes whenever database file changes */
};

/*
** The following global variables hold counters used for
................................................................................
int sqlite3_pager_writej_count = 0;    /* Number of pages written to journal */
int sqlite3_pager_pgfree_count = 0;    /* Number of cache pages freed */
# define PAGER_INCR(v)  v++
#else
# define PAGER_INCR(v)
#endif












/*
** Journal files begin with the following magic string.  The data
** was obtained from /dev/random.  It is used only as a sanity check.
**
** Since version 2.8.0, the journal format contains additional sanity
................................................................................
#define PAGER_MJ_PGNO(x) ((PENDING_BYTE/((x)->pageSize))+1)

/*
** The maximum legal page number is (2^31 - 1).
*/
#define PAGER_MAX_PGNO 2147483647

































/*
** Enable reference count tracking (for debugging) here:
*/
#ifdef SQLITE_DEBUG
  int pager3_refinfo_enable = 0;
  static void pager_refinfo(PgHdr *p){
    static int cnt = 0;
................................................................................
** automatically when it is closed.
**
** If zFilename is ":memory:" then all information is held in cache.
** It is never written to disk.  This can be used to implement an
** in-memory database.
*/
int sqlite3PagerOpen(
  sqlite3_vfs *pVfs,
  Pager **ppPager,         /* Return the Pager structure here */
  const char *zFilename,   /* Name of the database file to open */
  int nExtra,              /* Extra bytes append to each in-memory page */
  int flags                /* flags controlling this file */
){
  u8 *pPtr;
  Pager *pPager = 0;
................................................................................
  int i;
  int tempFile = 0;
  int memDb = 0;
  int readOnly = 0;
  int useJournal = (flags & PAGER_OMIT_JOURNAL)==0;
  int noReadlock = (flags & PAGER_NO_READLOCK)!=0;

#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
  /* A malloc() cannot fail in sqlite3ThreadData() as one or more calls to 
  ** malloc() must have already been made by this thread before it gets
  ** to this point. This means the ThreadData must have been allocated already
  ** so that ThreadData.nAlloc can be set. It would be nice to assert
  ** that ThreadData.nAlloc is non-zero, but alas this breaks test cases 
  ** written to invoke the pager directly.
  */
  ThreadData *pTsd = sqlite3ThreadData();
  assert( pTsd );
#endif

  /* We used to test if malloc() had already failed before proceeding. 
  ** But the way this function is used in SQLite means that can never
  ** happen. Furthermore, if the malloc-failed flag is already set, 
  ** either the call to sqlite3StrDup() or sqlite3_malloc() below will
  ** fail shortly and SQLITE_NOMEM returned anyway.
  */
  *ppPager = 0;

  /* Allocate memory for the pager structure */
  pPager = sqlite3MallocZero(
    sizeof(*pPager) +           /* Pager structure */
    pVfs->szOsFile * 3 +        /* The db, journal and stmt journal files */ 
    pVfs->mxPathname * 3 + 30   /* zFilename, zDirectory, zJournal */
................................................................................
  if( !memDb ){
    setSectorSize(pPager);
  }
  /* pPager->pBusyHandler = 0; */
  /* memset(pPager->aHash, 0, sizeof(pPager->aHash)); */
  *ppPager = pPager;
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT





  pPager->pNext = pTsd->pPager;





  pTsd->pPager = pPager;


#endif
  return SQLITE_OK;
}

/*
** Set the busy handler function.
*/
................................................................................
** Set the page size.  Return the new size.  If the suggest new page
** size is inappropriate, then an alternative page size is selected
** and returned.
*/
int sqlite3PagerSetPagesize(Pager *pPager, int pageSize){
  assert( pageSize>=512 && pageSize<=SQLITE_MAX_PAGE_SIZE );
  if( !pPager->memDb && pPager->nRef==0 ){

    pager_reset(pPager);
    pPager->pageSize = pageSize;

    sqlite3_free(pPager->pTmpSpace);
    pPager->pTmpSpace = sqlite3_malloc(pageSize);
  }
  return pPager->pageSize;
}

/*
................................................................................
    return SQLITE_OK;
  }
  if( MEMDB ){
    pPager->dbSize = nPage;
    pager_truncate_cache(pPager);
    return SQLITE_OK;
  }

  rc = syncJournal(pPager);

  if( rc!=SQLITE_OK ){
    return rc;
  }

  /* Get an exclusive lock on the database before truncating. */

  rc = pager_wait_on_lock(pPager, EXCLUSIVE_LOCK);

  if( rc!=SQLITE_OK ){
    return rc;
  }

  rc = pager_truncate(pPager, nPage);
  return rc;
}
................................................................................
** This function always succeeds. If a transaction is active an attempt
** is made to roll it back. If an error occurs during the rollback 
** a hot journal may be left in the filesystem but no error is returned
** to the caller.
*/
int sqlite3PagerClose(Pager *pPager){
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
  /* A malloc() cannot fail in sqlite3ThreadData() as one or more calls to 
  ** malloc() must have already been made by this thread before it gets
  ** to this point. This means the ThreadData must have been allocated already
  ** so that ThreadData.nAlloc can be set.
  */

  ThreadData *pTsd = sqlite3ThreadData();


  assert( pPager );
  assert( pTsd && pTsd->nAlloc );




#endif

  disable_simulated_io_errors();
  pPager->errCode = 0;
  pPager->exclusiveMode = 0;
  pager_reset(pPager);
  pagerUnlockAndRollback(pPager);
................................................................................
  sqlite3OsClose(pPager->fd);
  /* Temp files are automatically deleted by the OS
  ** if( pPager->tempFile ){
  **   sqlite3OsDelete(pPager->zFilename);
  ** }
  */

#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
  /* Remove the pager from the linked list of pagers starting at 
  ** ThreadData.pPager if memory-management is enabled.
  */
  if( pPager==pTsd->pPager ){
    pTsd->pPager = pPager->pNext;
  }else{
    Pager *pTmp;
    for(pTmp = pTsd->pPager; pTmp->pNext!=pPager; pTmp=pTmp->pNext){}
    pTmp->pNext = pPager->pNext;
  }
#endif
  sqlite3_free(pPager->aHash);
  sqlite3_free(pPager->pTmpSpace);
  sqlite3_free(pPager);
  return SQLITE_OK;
}

#if !defined(NDEBUG) || defined(SQLITE_TEST)
................................................................................
#endif

/*
** Increment the reference count for a page.  The input pointer is
** a reference to the page data.
*/
int sqlite3PagerRef(DbPage *pPg){

  page_ref(pPg);

  return SQLITE_OK;
}

/*
** Sync the journal.  In other words, make sure all the pages that have
** been written to the journal have actually reached the surface of the
** disk.  It is not safe to modify the original database file until after
................................................................................
  unlinkPage(pPg);
  assert( pPg->pgno==0 );

  *ppPg = pPg;
  return SQLITE_OK;
}


/*
** This function is called to free superfluous dynamically allocated memory
** held by the pager system. Memory in use by any SQLite pager allocated
** by the current thread may be sqlite3_free()ed.
**
** nReq is the number of bytes of memory required. Once this much has
** been released, the function returns. A negative value for nReq means
** free as much memory as possible. The return value is the total number 
** of bytes of memory released.
*/
#if defined(SQLITE_ENABLE_MEMORY_MANAGEMENT) && !defined(SQLITE_OMIT_DISKIO)
int sqlite3PagerReleaseMemory(int nReq){
  const ThreadData *pTsdro = sqlite3ThreadDataReadOnly();
  int nReleased = 0;
  int i;

  /* If the the global mutex is held, this subroutine becomes a
  ** o-op; zero bytes of memory are freed.  This is because
  ** some of the code invoked by this function may also
  ** try to obtain the mutex, resulting in a deadlock.
  */
#if 0
  if( sqlite3OsInMutex(0) ){
    return 0;
  }
#endif

  /* Outermost loop runs for at most two iterations. First iteration we
  ** try to find memory that can be released without calling fsync(). Second
  ** iteration (which only runs if the first failed to free nReq bytes of
  ** memory) is permitted to call fsync(). This is of course much more 
  ** expensive.
  */
  for(i=0; i<=1; i++){

    /* Loop through all the SQLite pagers opened by the current thread. */
    Pager *pPager = pTsdro->pPager;
    for( ; pPager && (nReq<0 || nReleased<nReq); pPager=pPager->pNext){
      PgHdr *pPg;
      int rc;


      if( MEMDB ){
        continue;
      }



      /* For each pager, try to free as many pages as possible (without 
      ** calling fsync() if this is the first iteration of the outermost 
      ** loop).
      */
      while( SQLITE_OK==(rc = pager_recycle(pPager, i, &pPg)) && pPg) {
        /* We've found a page to free. At this point the page has been 
................................................................................
        assert( pPg );
        if( pPg==pPager->pAll ){
           pPager->pAll = pPg->pNextAll;
        }else{
          for( pTmp=pPager->pAll; pTmp->pNextAll!=pPg; pTmp=pTmp->pNextAll ){}
          pTmp->pNextAll = pPg->pNextAll;
        }
#if 0
        nReleased += sqliteAllocSize(pPg);
#else
        nReleased += (
            sizeof(*pPg) + pPager->pageSize
            + sizeof(u32) + pPager->nExtra
            + MEMDB*sizeof(PgHistory) 
        );
#endif
        IOTRACE(("PGFREE %p %d *\n", pPager, pPg->pgno));
        PAGER_INCR(sqlite3_pager_pgfree_count);
        sqlite3_free(pPg);
      }

      if( rc!=SQLITE_OK ){
        /* An error occured whilst writing to the database file or 
................................................................................
        );
        assert( pPager->state>=PAGER_RESERVED );
        pager_error(pPager, rc);
      }
    }
  }










  return nReleased;
}
#endif /* SQLITE_ENABLE_MEMORY_MANAGEMENT && !SQLITE_OMIT_DISKIO */

/*
** Read the content of page pPg out of the database file.
*/
static int readDbPage(Pager *pPager, PgHdr *pPg, Pgno pgno){
  int rc;
  i64 offset;
................................................................................
** of the page at this time, so do not do a disk read.  Just fill in the
** page content with zeros.  But mark the fact that we have not read the
** content by setting the PgHdr.needRead flag.  Later on, if 
** sqlite3PagerWrite() is called on this page or if this routine is
** called again with noContent==0, that means that the content is needed
** and the disk read should occur at that point.
*/
int sqlite3PagerAcquire(
  Pager *pPager,      /* The pager open on the database file */
  Pgno pgno,          /* Page number to fetch */
  DbPage **ppPage,    /* Write a pointer to the page here */
  int noContent       /* Do not bother reading content from disk if true */
){
  PgHdr *pPg;
  int rc;
................................................................................
      }
    }
    page_ref(pPg);
  }
  *ppPage = pPg;
  return SQLITE_OK;
}














/*
** Acquire a page if it is already in the in-memory cache.  Do
** not read the page from disk.  Return a pointer to the page,
** or 0 if the page is not in cache.
**
** See also sqlite3PagerGet().  The difference between this routine
** and sqlite3PagerGet() is that _get() will go to the disk and read
** in the page if the page is not already in cache.  This routine
** returns NULL if the page is not in cache or if a disk I/O error 
** has ever happened.
*/
DbPage *sqlite3PagerLookup(Pager *pPager, Pgno pgno){
  PgHdr *pPg;

  assert( pPager!=0 );
  assert( pgno!=0 );


  if( pPager->state==PAGER_UNLOCK ){
    assert( !pPager->pAll || pPager->exclusiveMode );
    return 0;
  }
  if( pPager->errCode && pPager->errCode!=SQLITE_FULL ){
    return 0;
  }

  pPg = pager_lookup(pPager, pgno);
  if( pPg==0 ) return 0;
  page_ref(pPg);


  return pPg;
}

/*
** Release a page.
**
** If the number of references to the page drop to zero, then the
................................................................................
** removed.
*/
int sqlite3PagerUnref(DbPage *pPg){

  /* Decrement the reference count for this page
  */
  assert( pPg->nRef>0 );

  pPg->nRef--;
  REFINFO(pPg);

  CHECK_PAGE(pPg);

  /* When the number of references to a page reach 0, call the
  ** destructor and add the page to the freelist.
................................................................................
    */
    pPager->nRef--;
    assert( pPager->nRef>=0 );
    if( pPager->nRef==0 && (!pPager->exclusiveMode || pPager->journalOff>0) ){
      pagerUnlockAndRollback(pPager);
    }
  }

  return SQLITE_OK;
}

/*
** Create a journal file for pPager.  There should already be a RESERVED
** or EXCLUSIVE lock on the database file when this routine is called.
**
................................................................................
** If exFlag is true, go ahead and get an EXCLUSIVE lock on the file
** immediately instead of waiting until we try to flush the cache.  The
** exFlag is ignored if a transaction is already active.
*/
int sqlite3PagerBegin(DbPage *pPg, int exFlag){
  Pager *pPager = pPg->pPager;
  int rc = SQLITE_OK;

  assert( pPg->nRef>0 );
  assert( pPager->state!=PAGER_UNLOCK );
  if( pPager->state==PAGER_SHARED ){
    assert( pPager->aInJournal==0 );
    if( MEMDB ){
      pPager->state = PAGER_EXCLUSIVE;
      pPager->origDbSize = pPager->dbSize;
................................................................................
      if( rc==SQLITE_OK ){
        pPager->state = PAGER_RESERVED;
        if( exFlag ){
          rc = pager_wait_on_lock(pPager, EXCLUSIVE_LOCK);
        }
      }
      if( rc!=SQLITE_OK ){

        return rc;
      }
      pPager->dirtyCache = 0;
      PAGERTRACE2("TRANSACTION %d\n", PAGERID(pPager));
      if( pPager->useJournal && !pPager->tempFile ){
        rc = pager_open_journal(pPager);
      }
................................................................................
      rc = SQLITE_NOMEM;
    }else{
      pPager->origDbSize = pPager->dbSize;
      rc = writeJournalHdr(pPager);
    }
  }
  assert( !pPager->journalOpen || pPager->journalOff>0 || rc!=SQLITE_OK );

  return rc;
}

/*
** Make a page dirty.  Set its dirty flag and add it to the dirty
** page list.
*/
................................................................................
int sqlite3PagerWrite(DbPage *pDbPage){
  int rc = SQLITE_OK;

  PgHdr *pPg = pDbPage;
  Pager *pPager = pPg->pPager;
  Pgno nPagePerSector = (pPager->sectorSize/pPager->pageSize);


  if( !MEMDB && nPagePerSector>1 ){
    Pgno nPageCount;          /* Total number of pages in database file */
    Pgno pg1;                 /* First page of the sector pPg is located on. */
    int nPage;                /* Number of pages starting at pg1 to journal */
    int ii;

    /* Set the doNotSync flag to 1. This is because we cannot allow a journal
................................................................................
    }

    assert( pPager->doNotSync==1 );
    pPager->doNotSync = 0;
  }else{
    rc = pager_write(pDbPage);
  }

  return rc;
}

/*
** Return TRUE if the page given in the argument was previously passed
** to sqlite3PagerWrite().  In other words, return TRUE if it is ok
** to change the content of the page.
................................................................................
** Replace the content of a single page with the information in the third
** argument.
*/
int sqlite3PagerOverwrite(Pager *pPager, Pgno pgno, void *pData){
  PgHdr *pPg;
  int rc;


  rc = sqlite3PagerGet(pPager, pgno, &pPg);
  if( rc==SQLITE_OK ){
    rc = sqlite3PagerWrite(pPg);
    if( rc==SQLITE_OK ){
      memcpy(sqlite3PagerGetData(pPg), pData, pPager->pageSize);
    }
    sqlite3PagerUnref(pPg);
  }

  return rc;
}
#endif

/*
** A call to this routine tells the pager that it is not necessary to
** write the information on page pPg back to the disk, even though
................................................................................
** rolled back in spite of the sqlite3PagerDontRollback() call.
*/
void sqlite3PagerDontWrite(DbPage *pDbPage){
  PgHdr *pPg = pDbPage;
  Pager *pPager = pPg->pPager;

  if( MEMDB ) return;

  pPg->alwaysRollback = 1;
  if( pPg->dirty && !pPager->stmtInUse ){
    assert( pPager->state>=PAGER_SHARED );
    if( pPager->dbSize==(int)pPg->pgno && pPager->origDbSize<pPager->dbSize ){
      /* If this pages is the last page in the file and the file has grown
      ** during the current transaction, then do NOT mark the page as clean.
      ** When the database file grows, we must make sure that the last page
................................................................................
      IOTRACE(("CLEAN %p %d\n", pPager, pPg->pgno))
      makeClean(pPg);
#ifdef SQLITE_CHECK_PAGES
      pPg->pageHash = pager_pagehash(pPg);
#endif
    }
  }

}

/*
** A call to this routine tells the pager that if a rollback occurs,
** it is not necessary to restore the data on the given page.  This
** means that the pager does not have to record the given page in the
** rollback journal.
................................................................................
** the PgHdr.needRead flag is set) then this routine acts as a promise
** that we will never need to read the page content in the future.
** so the needRead flag can be cleared at this point.
*/
void sqlite3PagerDontRollback(DbPage *pPg){
  Pager *pPager = pPg->pPager;


  assert( pPager->state>=PAGER_RESERVED );
  if( pPager->journalOpen==0 ) return;
  if( pPg->alwaysRollback || pPager->alwaysRollback || MEMDB ) return;
  if( !pPg->inJournal && (int)pPg->pgno <= pPager->origDbSize ){
    assert( pPager->aInJournal!=0 );
    pPager->aInJournal[pPg->pgno/8] |= 1<<(pPg->pgno&7);
    pPg->inJournal = 1;
................................................................................
   && !pageInStatement(pPg) 
   && (int)pPg->pgno<=pPager->stmtSize 
  ){
    assert( pPg->inJournal || (int)pPg->pgno>pPager->origDbSize );
    assert( pPager->aInStmt!=0 );
    pPager->aInStmt[pPg->pgno/8] |= 1<<(pPg->pgno&7);
  }

}


/*
** This routine is called to increment the database file change-counter,
** stored at byte 24 of the pager file.
*/
................................................................................
** nTrunc pages (this is used by auto-vacuum databases).
*/
int sqlite3PagerCommitPhaseOne(Pager *pPager, const char *zMaster, Pgno nTrunc){
  int rc = SQLITE_OK;

  PAGERTRACE4("DATABASE SYNC: File=%s zMaster=%s nTrunc=%d\n", 
      pPager->zFilename, zMaster, nTrunc);


  /* If this is an in-memory db, or no pages have been written to, or this
  ** function has already been called, it is a no-op.
  */
  if( pPager->state!=PAGER_SYNCED && !MEMDB && pPager->dirtyCache ){
    PgHdr *pPg;
    assert( pPager->journalOpen );
................................................................................
    /* pager_incr_changecounter() may attempt to obtain an exclusive
     * lock to spill the cache and return IOERR_BLOCKED. But since 
     * there is no chance the cache is inconsistent, it's
     * better to return SQLITE_BUSY.
     */
    rc = SQLITE_BUSY;
  }

  return rc;
}


/*
** Commit all changes to the database and release the write lock.
**
................................................................................

  if( pPager->errCode ){
    return pPager->errCode;
  }
  if( pPager->state<PAGER_RESERVED ){
    return SQLITE_ERROR;
  }

  PAGERTRACE2("COMMIT %d\n", PAGERID(pPager));
  if( MEMDB ){
    pPg = pager_get_all_dirty_pages(pPager);
    while( pPg ){
      PgHistory *pHist = PGHDR_TO_HIST(pPg, pPager);
      clearHistory(pHist);
      pPg->dirty = 0;
................................................................................
    pPager->pStmt = 0;
    pPager->state = PAGER_SHARED;
    return SQLITE_OK;
  }
  assert( pPager->journalOpen || !pPager->dirtyCache );
  assert( pPager->state==PAGER_SYNCED || !pPager->dirtyCache );
  rc = pager_end_transaction(pPager);
  return pager_error(pPager, rc);


}

/*
** Rollback all changes.  The database falls back to PAGER_SHARED mode.
** All in-memory cache pages revert to their original data contents.
** The journal is deleted.
**
................................................................................
    pPager->dbSize = pPager->origDbSize;
    pager_truncate_cache(pPager);
    pPager->stmtInUse = 0;
    pPager->state = PAGER_SHARED;
    return SQLITE_OK;
  }


  if( !pPager->dirtyCache || !pPager->journalOpen ){
    rc = pager_end_transaction(pPager);

    return rc;
  }

  if( pPager->errCode && pPager->errCode!=SQLITE_FULL ){
    if( pPager->state>=PAGER_EXCLUSIVE ){
      pager_playback(pPager, 0);
    }

    return pPager->errCode;
  }
  if( pPager->state==PAGER_RESERVED ){
    int rc2;
    rc = pager_playback(pPager, 0);
    rc2 = pager_end_transaction(pPager);
    if( rc==SQLITE_OK ){
................................................................................
  /* pager_reset(pPager); */
  pPager->dbSize = -1;

  /* If an error occurs during a ROLLBACK, we can no longer trust the pager
  ** cache. So call pager_error() on the way out to make any error 
  ** persistent.
  */
  return pager_error(pPager, rc);


}

/*
** Return TRUE if the database file is opened read-only.  Return FALSE
** if the database is (in theory) writable.
*/
int sqlite3PagerIsreadonly(Pager *pPager){
................................................................................
/*
** Set the statement rollback point.
**
** This routine should be called with the transaction journal already
** open.  A new statement journal is created that can be used to rollback
** changes of a single SQL command within a larger transaction.
*/
int sqlite3PagerStmtBegin(Pager *pPager){
  int rc;
  assert( !pPager->stmtInUse );
  assert( pPager->state>=PAGER_SHARED );
  assert( pPager->dbSize>=0 );
  PAGERTRACE2("STMT-BEGIN %d\n", PAGERID(pPager));
  if( MEMDB ){
    pPager->stmtInUse = 1;
................................................................................
stmt_begin_failed:
  if( pPager->aInStmt ){
    sqlite3_free(pPager->aInStmt);
    pPager->aInStmt = 0;
  }
  return rc;
}








/*
** Commit a statement.
*/
int sqlite3PagerStmtCommit(Pager *pPager){

  if( pPager->stmtInUse ){
    PgHdr *pPg, *pNext;
    PAGERTRACE2("STMT-COMMIT %d\n", PAGERID(pPager));
    if( !MEMDB ){
      /* sqlite3OsTruncate(pPager->stfd, 0); */
      sqlite3_free( pPager->aInStmt );
      pPager->aInStmt = 0;
................................................................................
      }
    }
    pPager->stmtNRec = 0;
    pPager->stmtInUse = 0;
    pPager->pStmt = 0;
  }
  pPager->stmtAutoopen = 0;

  return SQLITE_OK;
}

/*
** Rollback a statement.
*/
int sqlite3PagerStmtRollback(Pager *pPager){
  int rc;

  if( pPager->stmtInUse ){
    PAGERTRACE2("STMT-ROLLBACK %d\n", PAGERID(pPager));
    if( MEMDB ){
      PgHdr *pPg;
      PgHistory *pHist;
      for(pPg=pPager->pStmt; pPg; pPg=pHist->pNextStmt){
        pHist = PGHDR_TO_HIST(pPg, pPager);
................................................................................
      rc = pager_stmt_playback(pPager);
    }
    sqlite3PagerStmtCommit(pPager);
  }else{
    rc = SQLITE_OK;
  }
  pPager->stmtAutoopen = 0;

  return rc;
}

/*
** Return the full pathname of the database file.
*/
const char *sqlite3PagerFilename(Pager *pPager){
................................................................................
** transaction is active).
*/
int sqlite3PagerMovepage(Pager *pPager, DbPage *pPg, Pgno pgno){
  PgHdr *pPgOld;  /* The page being overwritten. */
  int h;
  Pgno needSyncPgno = 0;


  assert( pPg->nRef>0 );

  PAGERTRACE5("MOVE %d page %d (needSync=%d) moves to %d\n", 
      PAGERID(pPager), pPg->pgno, pPg->needSync, pgno);
  IOTRACE(("MOVE %p %d %d\n", pPager, pPg->pgno, pgno))

  pager_get_content(pPg);
................................................................................
    pPager->needSync = 1;
    pPgHdr->needSync = 1;
    pPgHdr->inJournal = 1;
    makeDirty(pPgHdr);
    sqlite3PagerUnref(pPgHdr);
  }


  return SQLITE_OK;
}
#endif

/*
** Return a pointer to the data for the specified page.
*/







|







 







|
>
>
>







 







>
>
>
>
>
>
>
>
>







 







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







 







|







 







|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







 







>
>
>
>
>
|
>
>
>
>
>
|
>
>







 







>


>







 







>

>





>

>







 







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







 







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







 







>

>







 







>






|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|










|




>
|
<
|
>
>







 







<
<
<





<







 







>
>
>
>
>
>
>
>
>


|







 







|







 







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













|




>


<
<
|
<
<
>
|
<
|
>
>







 







>







 







>







 







>







 







>







 







>







 







>







 







>







 







>








>







 







>







 







>







 







>







 







>







 







>







 







>







 







>







 







|
>
>







 







>


>







>







 







|
>
>







 







|







 







>
>
>
>
>
>
>





>







 







>








>







 







>







 







>







 







>







14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
...
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
...
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
...
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
....
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
....
1817
1818
1819
1820
1821
1822
1823
1824

















1825
1826
1827
1828
1829
1830
1831
....
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
....
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
....
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
....
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324

2325
2326
2327
2328
2329

2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
....
2352
2353
2354
2355
2356
2357
2358












2359
2360
2361
2362
2363
2364
2365
....
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
....
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842

2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
....
2861
2862
2863
2864
2865
2866
2867



2868
2869
2870
2871
2872

2873
2874
2875
2876
2877
2878
2879
....
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
....
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
....
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371


3372


3373
3374

3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
....
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
....
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
....
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
....
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
....
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
....
3817
3818
3819
3820
3821
3822
3823
3824
3825
3826
3827
3828
3829
3830
3831
....
3869
3870
3871
3872
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
....
3893
3894
3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
....
3936
3937
3938
3939
3940
3941
3942
3943
3944
3945
3946
3947
3948
3949
3950
....
3958
3959
3960
3961
3962
3963
3964
3965
3966
3967
3968
3969
3970
3971
3972
....
3975
3976
3977
3978
3979
3980
3981
3982
3983
3984
3985
3986
3987
3988
3989
....
3998
3999
4000
4001
4002
4003
4004
4005
4006
4007
4008
4009
4010
4011
4012
....
4051
4052
4053
4054
4055
4056
4057
4058
4059
4060
4061
4062
4063
4064
4065
....
4127
4128
4129
4130
4131
4132
4133
4134
4135
4136
4137
4138
4139
4140
4141
....
4149
4150
4151
4152
4153
4154
4155
4156
4157
4158
4159
4160
4161
4162
4163
....
4179
4180
4181
4182
4183
4184
4185
4186
4187
4188
4189
4190
4191
4192
4193
4194
4195
....
4235
4236
4237
4238
4239
4240
4241
4242
4243
4244
4245
4246
4247
4248
4249
4250
4251
4252
4253
4254
4255
4256
4257
4258
4259
4260
....
4266
4267
4268
4269
4270
4271
4272
4273
4274
4275
4276
4277
4278
4279
4280
4281
4282
....
4314
4315
4316
4317
4318
4319
4320
4321
4322
4323
4324
4325
4326
4327
4328
....
4360
4361
4362
4363
4364
4365
4366
4367
4368
4369
4370
4371
4372
4373
4374
4375
4376
4377
4378
4379
4380
4381
4382
4383
4384
4385
4386
....
4396
4397
4398
4399
4400
4401
4402
4403
4404
4405
4406
4407
4408
4409
4410
4411
4412
4413
4414
4415
4416
4417
4418
4419
....
4430
4431
4432
4433
4434
4435
4436
4437
4438
4439
4440
4441
4442
4443
4444
....
4500
4501
4502
4503
4504
4505
4506
4507
4508
4509
4510
4511
4512
4513
4514
....
4577
4578
4579
4580
4581
4582
4583
4584
4585
4586
4587
4588
4589
4590
4591
** The pager is used to access a database disk file.  It implements
** atomic commit and rollback through the use of a journal file that
** is separate from the database file.  The pager also implements file
** locking to prevent two processes from writing the same database
** file simultaneously, or one process from reading the database while
** another is writing.
**
** @(#) $Id: pager.c,v 1.365 2007/08/22 00:39:20 drh Exp $
*/
#ifndef SQLITE_OMIT_DISKIO
#include "sqliteInt.h"
#include <assert.h>
#include <string.h>

/*
................................................................................
#ifdef SQLITE_HAS_CODEC
  void *(*xCodec)(void*,void*,Pgno,int); /* Routine for en/decoding data */
  void *pCodecArg;            /* First argument to xCodec() */
#endif
  int nHash;                  /* Size of the pager hash table */
  PgHdr **aHash;              /* Hash table to map page number to PgHdr */
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
  Pager *pNext;               /* Doubly linked list of pagers on which */
  Pager *pPrev;               /* sqlite3_release_memory() will work */
  int iInUseMM;               /* Non-zero if unavailable to MM */
  int iInUseDB;               /* Non-zero if in sqlite3_release_memory() */
#endif
  char *pTmpSpace;            /* Pager.pageSize bytes of space for tmp use */
  char dbFileVers[16];        /* Changes whenever database file changes */
};

/*
** The following global variables hold counters used for
................................................................................
int sqlite3_pager_writej_count = 0;    /* Number of pages written to journal */
int sqlite3_pager_pgfree_count = 0;    /* Number of cache pages freed */
# define PAGER_INCR(v)  v++
#else
# define PAGER_INCR(v)
#endif

/*
** The following variable points to the head of a double-linked list
** of all pagers that are eligible for page stealing by the
** sqlite3_release_memory() interface.  Access to this list is
** protected by the SQLITE_MUTEX_STATIC_MEM2 mutex.
*/
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
static Pager *sqlite3PagerList = 0;
#endif


/*
** Journal files begin with the following magic string.  The data
** was obtained from /dev/random.  It is used only as a sanity check.
**
** Since version 2.8.0, the journal format contains additional sanity
................................................................................
#define PAGER_MJ_PGNO(x) ((PENDING_BYTE/((x)->pageSize))+1)

/*
** The maximum legal page number is (2^31 - 1).
*/
#define PAGER_MAX_PGNO 2147483647

/*
** The pagerEnter() and pagerLeave() routines acquire and release
** a mutex on each pager.  The mutex is recursive.
**
** This is a special-purpose mutex.  It only provides mutual exclusion
** between the Btree and the Memory Management sqlite3_release_memory()
** function.  It does not prevent, for example, two Btrees from accessing
** the same pager at the same time.  Other general-purpose mutexes in
** the btree layer handle that chore.
*/
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
  static void pagerEnter(Pager *p){
    p->iInUseDB++;
    if( p->iInUseMM && p->iInUseDB==1 ){
      sqlite3_mutex *mutex;
      mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MEM2);
      p->iInUseDB = 0;
      sqlite3_mutex_enter(mutex);
      p->iInUseDB = 1;
      sqlite3_mutex_leave(mutex);
    }
    assert( p->iInUseMM==0 );
  }
  static void pagerLeave(Pager *p){
    p->iInUseDB--;
    assert( p->iInUseDB>=0 );
  }
#else
# define pagerEnter(X)
# define pagerLeave(X)
#endif

/*
** Enable reference count tracking (for debugging) here:
*/
#ifdef SQLITE_DEBUG
  int pager3_refinfo_enable = 0;
  static void pager_refinfo(PgHdr *p){
    static int cnt = 0;
................................................................................
** automatically when it is closed.
**
** If zFilename is ":memory:" then all information is held in cache.
** It is never written to disk.  This can be used to implement an
** in-memory database.
*/
int sqlite3PagerOpen(
  sqlite3_vfs *pVfs,       /* The virtual file system to use */
  Pager **ppPager,         /* Return the Pager structure here */
  const char *zFilename,   /* Name of the database file to open */
  int nExtra,              /* Extra bytes append to each in-memory page */
  int flags                /* flags controlling this file */
){
  u8 *pPtr;
  Pager *pPager = 0;
................................................................................
  int i;
  int tempFile = 0;
  int memDb = 0;
  int readOnly = 0;
  int useJournal = (flags & PAGER_OMIT_JOURNAL)==0;
  int noReadlock = (flags & PAGER_NO_READLOCK)!=0;

  /* The default return is a NULL pointer */

















  *ppPager = 0;

  /* Allocate memory for the pager structure */
  pPager = sqlite3MallocZero(
    sizeof(*pPager) +           /* Pager structure */
    pVfs->szOsFile * 3 +        /* The db, journal and stmt journal files */ 
    pVfs->mxPathname * 3 + 30   /* zFilename, zDirectory, zJournal */
................................................................................
  if( !memDb ){
    setSectorSize(pPager);
  }
  /* pPager->pBusyHandler = 0; */
  /* memset(pPager->aHash, 0, sizeof(pPager->aHash)); */
  *ppPager = pPager;
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
  pPager->iInUseMM = 0;
  pPager->iInUseDB = 0;
  if( !memDb ){
    sqlite3_mutex *mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MEM2);
    sqlite3_mutex_enter(mutex);
    pPager->pNext = sqlite3PagerList;
    if( sqlite3PagerList ){
      assert( sqlite3PagerList->pPrev==0 );
      sqlite3PagerList->pPrev = pPager;
    }
    pPager->pPrev = 0;
    sqlite3PagerList = pPager;
    sqlite3_mutex_leave(mutex);
  }
#endif
  return SQLITE_OK;
}

/*
** Set the busy handler function.
*/
................................................................................
** Set the page size.  Return the new size.  If the suggest new page
** size is inappropriate, then an alternative page size is selected
** and returned.
*/
int sqlite3PagerSetPagesize(Pager *pPager, int pageSize){
  assert( pageSize>=512 && pageSize<=SQLITE_MAX_PAGE_SIZE );
  if( !pPager->memDb && pPager->nRef==0 ){
    pagerEnter(pPager);
    pager_reset(pPager);
    pPager->pageSize = pageSize;
    pagerLeave(pPager);
    sqlite3_free(pPager->pTmpSpace);
    pPager->pTmpSpace = sqlite3_malloc(pageSize);
  }
  return pPager->pageSize;
}

/*
................................................................................
    return SQLITE_OK;
  }
  if( MEMDB ){
    pPager->dbSize = nPage;
    pager_truncate_cache(pPager);
    return SQLITE_OK;
  }
  pagerEnter(pPager);
  rc = syncJournal(pPager);
  pagerLeave(pPager);
  if( rc!=SQLITE_OK ){
    return rc;
  }

  /* Get an exclusive lock on the database before truncating. */
  pagerEnter(pPager);
  rc = pager_wait_on_lock(pPager, EXCLUSIVE_LOCK);
  pagerLeave(pPager);
  if( rc!=SQLITE_OK ){
    return rc;
  }

  rc = pager_truncate(pPager, nPage);
  return rc;
}
................................................................................
** This function always succeeds. If a transaction is active an attempt
** is made to roll it back. If an error occurs during the rollback 
** a hot journal may be left in the filesystem but no error is returned
** to the caller.
*/
int sqlite3PagerClose(Pager *pPager){
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
  if( !MEMDB ){
    sqlite3_mutex *mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MEM2);
    sqlite3_mutex_enter(mutex);
    if( pPager->pPrev ){

      pPager->pPrev->pNext = pPager->pNext;
    }else{
      sqlite3PagerList = pPager->pNext;
    }
    if( pPager->pNext ){

      pPager->pNext->pPrev = pPager->pPrev;
    }
    sqlite3_mutex_leave(mutex);
  }
#endif

  disable_simulated_io_errors();
  pPager->errCode = 0;
  pPager->exclusiveMode = 0;
  pager_reset(pPager);
  pagerUnlockAndRollback(pPager);
................................................................................
  sqlite3OsClose(pPager->fd);
  /* Temp files are automatically deleted by the OS
  ** if( pPager->tempFile ){
  **   sqlite3OsDelete(pPager->zFilename);
  ** }
  */













  sqlite3_free(pPager->aHash);
  sqlite3_free(pPager->pTmpSpace);
  sqlite3_free(pPager);
  return SQLITE_OK;
}

#if !defined(NDEBUG) || defined(SQLITE_TEST)
................................................................................
#endif

/*
** Increment the reference count for a page.  The input pointer is
** a reference to the page data.
*/
int sqlite3PagerRef(DbPage *pPg){
  pagerEnter(pPg->pPager);
  page_ref(pPg);
  pagerLeave(pPg->pPager);
  return SQLITE_OK;
}

/*
** Sync the journal.  In other words, make sure all the pages that have
** been written to the journal have actually reached the surface of the
** disk.  It is not safe to modify the original database file until after
................................................................................
  unlinkPage(pPg);
  assert( pPg->pgno==0 );

  *ppPg = pPg;
  return SQLITE_OK;
}

#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
/*
** This function is called to free superfluous dynamically allocated memory
** held by the pager system. Memory in use by any SQLite pager allocated
** by the current thread may be sqlite3_free()ed.
**
** nReq is the number of bytes of memory required. Once this much has
** been released, the function returns. The return value is the total number 
** of bytes of memory released.
*/
int sqlite3PagerReleaseMemory(int nReq){
  int nReleased = 0;          /* Bytes of memory released so far */
  sqlite3_mutex *mutex;       /* The MEM2 mutex */
  Pager *pPager;              /* For looping over pagers */
  int i;                      /* Passes over pagers */

  /* Acquire the memory-management mutex
  */
  mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MEM2);
  sqlite3_mutex_enter(mutex);

  /* Signal all database connections that memory management wants
  ** to have access to the pagers.
  */
  for(pPager=sqlite3PagerList; pPager; pPager=pPager->pNext){
     pPager->iInUseMM = 1;
  }

  /* Outermost loop runs for at most two iterations. First iteration we
  ** try to find memory that can be released without calling fsync(). Second
  ** iteration (which only runs if the first failed to free nReq bytes of
  ** memory) is permitted to call fsync(). This is of course much more 
  ** expensive.
  */
  for(i=0; i<=1; i++){

    /* Loop through all the SQLite pagers opened by the current thread. */
    Pager *pPager = sqlite3PagerList;
    for( ; pPager && (nReq<0 || nReleased<nReq); pPager=pPager->pNext){
      PgHdr *pPg;
      int rc;

      /* In-memory databases should not appear on the pager list */
      assert( !MEMDB );


      /* Skip pagers that are currently in use by the b-tree layer */
      if( pPager->iInUseDB ) continue;

      /* For each pager, try to free as many pages as possible (without 
      ** calling fsync() if this is the first iteration of the outermost 
      ** loop).
      */
      while( SQLITE_OK==(rc = pager_recycle(pPager, i, &pPg)) && pPg) {
        /* We've found a page to free. At this point the page has been 
................................................................................
        assert( pPg );
        if( pPg==pPager->pAll ){
           pPager->pAll = pPg->pNextAll;
        }else{
          for( pTmp=pPager->pAll; pTmp->pNextAll!=pPg; pTmp=pTmp->pNextAll ){}
          pTmp->pNextAll = pPg->pNextAll;
        }



        nReleased += (
            sizeof(*pPg) + pPager->pageSize
            + sizeof(u32) + pPager->nExtra
            + MEMDB*sizeof(PgHistory) 
        );

        IOTRACE(("PGFREE %p %d *\n", pPager, pPg->pgno));
        PAGER_INCR(sqlite3_pager_pgfree_count);
        sqlite3_free(pPg);
      }

      if( rc!=SQLITE_OK ){
        /* An error occured whilst writing to the database file or 
................................................................................
        );
        assert( pPager->state>=PAGER_RESERVED );
        pager_error(pPager, rc);
      }
    }
  }

  /* Clear the memory management flags and release the mutex
  */
  for(pPager=sqlite3PagerList; pPager; pPager=pPager->pNext){
     pPager->iInUseMM = 0;
  }
  sqlite3_mutex_leave(mutex);

  /* Return the number of bytes released
  */
  return nReleased;
}
#endif /* SQLITE_ENABLE_MEMORY_MANAGEMENT */

/*
** Read the content of page pPg out of the database file.
*/
static int readDbPage(Pager *pPager, PgHdr *pPg, Pgno pgno){
  int rc;
  i64 offset;
................................................................................
** of the page at this time, so do not do a disk read.  Just fill in the
** page content with zeros.  But mark the fact that we have not read the
** content by setting the PgHdr.needRead flag.  Later on, if 
** sqlite3PagerWrite() is called on this page or if this routine is
** called again with noContent==0, that means that the content is needed
** and the disk read should occur at that point.
*/
static int pagerAcquire(
  Pager *pPager,      /* The pager open on the database file */
  Pgno pgno,          /* Page number to fetch */
  DbPage **ppPage,    /* Write a pointer to the page here */
  int noContent       /* Do not bother reading content from disk if true */
){
  PgHdr *pPg;
  int rc;
................................................................................
      }
    }
    page_ref(pPg);
  }
  *ppPage = pPg;
  return SQLITE_OK;
}
int sqlite3PagerAcquire(
  Pager *pPager,      /* The pager open on the database file */
  Pgno pgno,          /* Page number to fetch */
  DbPage **ppPage,    /* Write a pointer to the page here */
  int noContent       /* Do not bother reading content from disk if true */
){
  int rc;
  pagerEnter(pPager);
  rc = pagerAcquire(pPager, pgno, ppPage, noContent);
  pagerLeave(pPager);
  return rc;
}


/*
** Acquire a page if it is already in the in-memory cache.  Do
** not read the page from disk.  Return a pointer to the page,
** or 0 if the page is not in cache.
**
** See also sqlite3PagerGet().  The difference between this routine
** and sqlite3PagerGet() is that _get() will go to the disk and read
** in the page if the page is not already in cache.  This routine
** returns NULL if the page is not in cache or if a disk I/O error 
** has ever happened.
*/
DbPage *sqlite3PagerLookup(Pager *pPager, Pgno pgno){
  PgHdr *pPg = 0;

  assert( pPager!=0 );
  assert( pgno!=0 );

  pagerEnter(pPager);
  if( pPager->state==PAGER_UNLOCK ){
    assert( !pPager->pAll || pPager->exclusiveMode );


  }else if( pPager->errCode && pPager->errCode!=SQLITE_FULL ){


    /* Do nothing */
  }else if( (pPg = pager_lookup(pPager, pgno))!=0 ){

    page_ref(pPg);
  }
  pagerLeave(pPager);
  return pPg;
}

/*
** Release a page.
**
** If the number of references to the page drop to zero, then the
................................................................................
** removed.
*/
int sqlite3PagerUnref(DbPage *pPg){

  /* Decrement the reference count for this page
  */
  assert( pPg->nRef>0 );
  pagerEnter(pPg->pPager);
  pPg->nRef--;
  REFINFO(pPg);

  CHECK_PAGE(pPg);

  /* When the number of references to a page reach 0, call the
  ** destructor and add the page to the freelist.
................................................................................
    */
    pPager->nRef--;
    assert( pPager->nRef>=0 );
    if( pPager->nRef==0 && (!pPager->exclusiveMode || pPager->journalOff>0) ){
      pagerUnlockAndRollback(pPager);
    }
  }
  pagerLeave(pPg->pPager);
  return SQLITE_OK;
}

/*
** Create a journal file for pPager.  There should already be a RESERVED
** or EXCLUSIVE lock on the database file when this routine is called.
**
................................................................................
** If exFlag is true, go ahead and get an EXCLUSIVE lock on the file
** immediately instead of waiting until we try to flush the cache.  The
** exFlag is ignored if a transaction is already active.
*/
int sqlite3PagerBegin(DbPage *pPg, int exFlag){
  Pager *pPager = pPg->pPager;
  int rc = SQLITE_OK;
  pagerEnter(pPager);
  assert( pPg->nRef>0 );
  assert( pPager->state!=PAGER_UNLOCK );
  if( pPager->state==PAGER_SHARED ){
    assert( pPager->aInJournal==0 );
    if( MEMDB ){
      pPager->state = PAGER_EXCLUSIVE;
      pPager->origDbSize = pPager->dbSize;
................................................................................
      if( rc==SQLITE_OK ){
        pPager->state = PAGER_RESERVED;
        if( exFlag ){
          rc = pager_wait_on_lock(pPager, EXCLUSIVE_LOCK);
        }
      }
      if( rc!=SQLITE_OK ){
        pagerLeave(pPager);
        return rc;
      }
      pPager->dirtyCache = 0;
      PAGERTRACE2("TRANSACTION %d\n", PAGERID(pPager));
      if( pPager->useJournal && !pPager->tempFile ){
        rc = pager_open_journal(pPager);
      }
................................................................................
      rc = SQLITE_NOMEM;
    }else{
      pPager->origDbSize = pPager->dbSize;
      rc = writeJournalHdr(pPager);
    }
  }
  assert( !pPager->journalOpen || pPager->journalOff>0 || rc!=SQLITE_OK );
  pagerLeave(pPager);
  return rc;
}

/*
** Make a page dirty.  Set its dirty flag and add it to the dirty
** page list.
*/
................................................................................
int sqlite3PagerWrite(DbPage *pDbPage){
  int rc = SQLITE_OK;

  PgHdr *pPg = pDbPage;
  Pager *pPager = pPg->pPager;
  Pgno nPagePerSector = (pPager->sectorSize/pPager->pageSize);

  pagerEnter(pPager);
  if( !MEMDB && nPagePerSector>1 ){
    Pgno nPageCount;          /* Total number of pages in database file */
    Pgno pg1;                 /* First page of the sector pPg is located on. */
    int nPage;                /* Number of pages starting at pg1 to journal */
    int ii;

    /* Set the doNotSync flag to 1. This is because we cannot allow a journal
................................................................................
    }

    assert( pPager->doNotSync==1 );
    pPager->doNotSync = 0;
  }else{
    rc = pager_write(pDbPage);
  }
  pagerLeave(pPager);
  return rc;
}

/*
** Return TRUE if the page given in the argument was previously passed
** to sqlite3PagerWrite().  In other words, return TRUE if it is ok
** to change the content of the page.
................................................................................
** Replace the content of a single page with the information in the third
** argument.
*/
int sqlite3PagerOverwrite(Pager *pPager, Pgno pgno, void *pData){
  PgHdr *pPg;
  int rc;

  pagerEnter(pPager);
  rc = sqlite3PagerGet(pPager, pgno, &pPg);
  if( rc==SQLITE_OK ){
    rc = sqlite3PagerWrite(pPg);
    if( rc==SQLITE_OK ){
      memcpy(sqlite3PagerGetData(pPg), pData, pPager->pageSize);
    }
    sqlite3PagerUnref(pPg);
  }
  pagerLeave(pPager);
  return rc;
}
#endif

/*
** A call to this routine tells the pager that it is not necessary to
** write the information on page pPg back to the disk, even though
................................................................................
** rolled back in spite of the sqlite3PagerDontRollback() call.
*/
void sqlite3PagerDontWrite(DbPage *pDbPage){
  PgHdr *pPg = pDbPage;
  Pager *pPager = pPg->pPager;

  if( MEMDB ) return;
  pagerEnter(pPager);
  pPg->alwaysRollback = 1;
  if( pPg->dirty && !pPager->stmtInUse ){
    assert( pPager->state>=PAGER_SHARED );
    if( pPager->dbSize==(int)pPg->pgno && pPager->origDbSize<pPager->dbSize ){
      /* If this pages is the last page in the file and the file has grown
      ** during the current transaction, then do NOT mark the page as clean.
      ** When the database file grows, we must make sure that the last page
................................................................................
      IOTRACE(("CLEAN %p %d\n", pPager, pPg->pgno))
      makeClean(pPg);
#ifdef SQLITE_CHECK_PAGES
      pPg->pageHash = pager_pagehash(pPg);
#endif
    }
  }
  pagerLeave(pPager);
}

/*
** A call to this routine tells the pager that if a rollback occurs,
** it is not necessary to restore the data on the given page.  This
** means that the pager does not have to record the given page in the
** rollback journal.
................................................................................
** the PgHdr.needRead flag is set) then this routine acts as a promise
** that we will never need to read the page content in the future.
** so the needRead flag can be cleared at this point.
*/
void sqlite3PagerDontRollback(DbPage *pPg){
  Pager *pPager = pPg->pPager;

  pagerEnter(pPager);
  assert( pPager->state>=PAGER_RESERVED );
  if( pPager->journalOpen==0 ) return;
  if( pPg->alwaysRollback || pPager->alwaysRollback || MEMDB ) return;
  if( !pPg->inJournal && (int)pPg->pgno <= pPager->origDbSize ){
    assert( pPager->aInJournal!=0 );
    pPager->aInJournal[pPg->pgno/8] |= 1<<(pPg->pgno&7);
    pPg->inJournal = 1;
................................................................................
   && !pageInStatement(pPg) 
   && (int)pPg->pgno<=pPager->stmtSize 
  ){
    assert( pPg->inJournal || (int)pPg->pgno>pPager->origDbSize );
    assert( pPager->aInStmt!=0 );
    pPager->aInStmt[pPg->pgno/8] |= 1<<(pPg->pgno&7);
  }
  pagerLeave(pPager);
}


/*
** This routine is called to increment the database file change-counter,
** stored at byte 24 of the pager file.
*/
................................................................................
** nTrunc pages (this is used by auto-vacuum databases).
*/
int sqlite3PagerCommitPhaseOne(Pager *pPager, const char *zMaster, Pgno nTrunc){
  int rc = SQLITE_OK;

  PAGERTRACE4("DATABASE SYNC: File=%s zMaster=%s nTrunc=%d\n", 
      pPager->zFilename, zMaster, nTrunc);
  pagerEnter(pPager);

  /* If this is an in-memory db, or no pages have been written to, or this
  ** function has already been called, it is a no-op.
  */
  if( pPager->state!=PAGER_SYNCED && !MEMDB && pPager->dirtyCache ){
    PgHdr *pPg;
    assert( pPager->journalOpen );
................................................................................
    /* pager_incr_changecounter() may attempt to obtain an exclusive
     * lock to spill the cache and return IOERR_BLOCKED. But since 
     * there is no chance the cache is inconsistent, it's
     * better to return SQLITE_BUSY.
     */
    rc = SQLITE_BUSY;
  }
  pagerLeave(pPager);
  return rc;
}


/*
** Commit all changes to the database and release the write lock.
**
................................................................................

  if( pPager->errCode ){
    return pPager->errCode;
  }
  if( pPager->state<PAGER_RESERVED ){
    return SQLITE_ERROR;
  }
  pagerEnter(pPager);
  PAGERTRACE2("COMMIT %d\n", PAGERID(pPager));
  if( MEMDB ){
    pPg = pager_get_all_dirty_pages(pPager);
    while( pPg ){
      PgHistory *pHist = PGHDR_TO_HIST(pPg, pPager);
      clearHistory(pHist);
      pPg->dirty = 0;
................................................................................
    pPager->pStmt = 0;
    pPager->state = PAGER_SHARED;
    return SQLITE_OK;
  }
  assert( pPager->journalOpen || !pPager->dirtyCache );
  assert( pPager->state==PAGER_SYNCED || !pPager->dirtyCache );
  rc = pager_end_transaction(pPager);
  rc = pager_error(pPager, rc);
  pagerLeave(pPager);
  return rc;
}

/*
** Rollback all changes.  The database falls back to PAGER_SHARED mode.
** All in-memory cache pages revert to their original data contents.
** The journal is deleted.
**
................................................................................
    pPager->dbSize = pPager->origDbSize;
    pager_truncate_cache(pPager);
    pPager->stmtInUse = 0;
    pPager->state = PAGER_SHARED;
    return SQLITE_OK;
  }

  pagerEnter(pPager);
  if( !pPager->dirtyCache || !pPager->journalOpen ){
    rc = pager_end_transaction(pPager);
    pagerLeave(pPager);
    return rc;
  }

  if( pPager->errCode && pPager->errCode!=SQLITE_FULL ){
    if( pPager->state>=PAGER_EXCLUSIVE ){
      pager_playback(pPager, 0);
    }
    pagerLeave(pPager);
    return pPager->errCode;
  }
  if( pPager->state==PAGER_RESERVED ){
    int rc2;
    rc = pager_playback(pPager, 0);
    rc2 = pager_end_transaction(pPager);
    if( rc==SQLITE_OK ){
................................................................................
  /* pager_reset(pPager); */
  pPager->dbSize = -1;

  /* If an error occurs during a ROLLBACK, we can no longer trust the pager
  ** cache. So call pager_error() on the way out to make any error 
  ** persistent.
  */
  rc = pager_error(pPager, rc);
  pagerLeave(pPager);
  return rc;
}

/*
** Return TRUE if the database file is opened read-only.  Return FALSE
** if the database is (in theory) writable.
*/
int sqlite3PagerIsreadonly(Pager *pPager){
................................................................................
/*
** Set the statement rollback point.
**
** This routine should be called with the transaction journal already
** open.  A new statement journal is created that can be used to rollback
** changes of a single SQL command within a larger transaction.
*/
static int pagerStmtBegin(Pager *pPager){
  int rc;
  assert( !pPager->stmtInUse );
  assert( pPager->state>=PAGER_SHARED );
  assert( pPager->dbSize>=0 );
  PAGERTRACE2("STMT-BEGIN %d\n", PAGERID(pPager));
  if( MEMDB ){
    pPager->stmtInUse = 1;
................................................................................
stmt_begin_failed:
  if( pPager->aInStmt ){
    sqlite3_free(pPager->aInStmt);
    pPager->aInStmt = 0;
  }
  return rc;
}
int sqlite3PagerStmtBegin(Pager *pPager){
  int rc;
  pagerEnter(pPager);
  rc = pagerStmtBegin(pPager);
  pagerLeave(pPager);
  return rc;
}

/*
** Commit a statement.
*/
int sqlite3PagerStmtCommit(Pager *pPager){
  pagerEnter(pPager);
  if( pPager->stmtInUse ){
    PgHdr *pPg, *pNext;
    PAGERTRACE2("STMT-COMMIT %d\n", PAGERID(pPager));
    if( !MEMDB ){
      /* sqlite3OsTruncate(pPager->stfd, 0); */
      sqlite3_free( pPager->aInStmt );
      pPager->aInStmt = 0;
................................................................................
      }
    }
    pPager->stmtNRec = 0;
    pPager->stmtInUse = 0;
    pPager->pStmt = 0;
  }
  pPager->stmtAutoopen = 0;
  pagerLeave(pPager);
  return SQLITE_OK;
}

/*
** Rollback a statement.
*/
int sqlite3PagerStmtRollback(Pager *pPager){
  int rc;
  pagerEnter(pPager);
  if( pPager->stmtInUse ){
    PAGERTRACE2("STMT-ROLLBACK %d\n", PAGERID(pPager));
    if( MEMDB ){
      PgHdr *pPg;
      PgHistory *pHist;
      for(pPg=pPager->pStmt; pPg; pPg=pHist->pNextStmt){
        pHist = PGHDR_TO_HIST(pPg, pPager);
................................................................................
      rc = pager_stmt_playback(pPager);
    }
    sqlite3PagerStmtCommit(pPager);
  }else{
    rc = SQLITE_OK;
  }
  pPager->stmtAutoopen = 0;
  pagerLeave(pPager);
  return rc;
}

/*
** Return the full pathname of the database file.
*/
const char *sqlite3PagerFilename(Pager *pPager){
................................................................................
** transaction is active).
*/
int sqlite3PagerMovepage(Pager *pPager, DbPage *pPg, Pgno pgno){
  PgHdr *pPgOld;  /* The page being overwritten. */
  int h;
  Pgno needSyncPgno = 0;

  pagerEnter(pPager);
  assert( pPg->nRef>0 );

  PAGERTRACE5("MOVE %d page %d (needSync=%d) moves to %d\n", 
      PAGERID(pPager), pPg->pgno, pPg->needSync, pgno);
  IOTRACE(("MOVE %p %d %d\n", pPager, pPg->pgno, pgno))

  pager_get_content(pPg);
................................................................................
    pPager->needSync = 1;
    pPgHdr->needSync = 1;
    pPgHdr->inJournal = 1;
    makeDirty(pPgHdr);
    sqlite3PagerUnref(pPgHdr);
  }

  pagerLeave(pPager);
  return SQLITE_OK;
}
#endif

/*
** Return a pointer to the data for the specified page.
*/

Changes to src/prepare.c.

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
...
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472

473
474
475
476
477
478
479
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains the implementation of the sqlite3_prepare()
** interface, and routines that contribute to loading the database schema
** from disk.
**
** $Id: prepare.c,v 1.56 2007/08/21 19:33:56 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

/*
** Fill the InitData structure with an error message that indicates
** that the database is corrupt.
................................................................................
  const char **pzTail       /* OUT: End of parsed string */
){
  Parse sParse;
  char *zErrMsg = 0;
  int rc = SQLITE_OK;
  int i;

  /* Assert that malloc() has not failed */
  assert( !db->mallocFailed );

  assert( ppStmt );
  *ppStmt = 0;
  if( sqlite3SafetyOn(db) ){
    return SQLITE_MISUSE;
  }

  assert( sqlite3_mutex_held(db->mutex) );

  /* If any attached database schemas are locked, do not proceed with
  ** compilation. Instead return SQLITE_LOCKED immediately.
  */
  for(i=0; i<db->nDb; i++) {
    Btree *pBt = db->aDb[i].pBt;







|







 







<
<
<





>







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
...
458
459
460
461
462
463
464



465
466
467
468
469
470
471
472
473
474
475
476
477
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains the implementation of the sqlite3_prepare()
** interface, and routines that contribute to loading the database schema
** from disk.
**
** $Id: prepare.c,v 1.57 2007/08/22 00:39:20 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

/*
** Fill the InitData structure with an error message that indicates
** that the database is corrupt.
................................................................................
  const char **pzTail       /* OUT: End of parsed string */
){
  Parse sParse;
  char *zErrMsg = 0;
  int rc = SQLITE_OK;
  int i;




  assert( ppStmt );
  *ppStmt = 0;
  if( sqlite3SafetyOn(db) ){
    return SQLITE_MISUSE;
  }
  assert( !db->mallocFailed );
  assert( sqlite3_mutex_held(db->mutex) );

  /* If any attached database schemas are locked, do not proceed with
  ** compilation. Instead return SQLITE_LOCKED immediately.
  */
  for(i=0; i<db->nDb; i++) {
    Btree *pBt = db->aDb[i].pBt;

Changes to src/sqlite.h.in.

26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
....
3255
3256
3257
3258
3259
3260
3261

3262
3263
3264
3265
3266
3267
3268
....
3341
3342
3343
3344
3345
3346
3347
3348

3349
3350
3351
3352
3353
3354
3355
3356
** on how SQLite interfaces are suppose to operate.
**
** The name of this file under configuration management is "sqlite.h.in".
** The makefile makes some minor changes to this file (such as inserting
** the version number) and changes its name to "sqlite3.h" as
** part of the build process.
**
** @(#) $Id: sqlite.h.in,v 1.235 2007/08/21 20:25:40 drh Exp $
*/
#ifndef _SQLITE3_H_
#define _SQLITE3_H_
#include <stdarg.h>     /* Needed for the definition of va_list */

/*
** Make sure we can call this stuff from C++.
................................................................................
** to sqlite3_mutex_alloc() is one of these integer constants:
**
** <ul>
** <li>  SQLITE_MUTEX_FAST
** <li>  SQLITE_MUTEX_RECURSIVE
** <li>  SQLITE_MUTEX_STATIC_MASTER
** <li>  SQLITE_MUTEX_STATIC_MEM

** <li>  SQLITE_MUTEX_STATIC_PRNG
** </ul>
**
** The first two constants cause sqlite3_mutex_alloc() to create
** a new mutex.  The new mutex is recursive when SQLITE_MUTEX_RECURSIVE
** is used but not necessarily so when SQLITE_MUTEX_FAST is used.
** The mutex implementation does not need to make a distinction
................................................................................
**
** The [sqlite3_mutex_alloc()] interface takes a single argument
** which is one of these integer constants.
*/
#define SQLITE_MUTEX_FAST             0
#define SQLITE_MUTEX_RECURSIVE        1
#define SQLITE_MUTEX_STATIC_MASTER    2
#define SQLITE_MUTEX_STATIC_MEM       3

#define SQLITE_MUTEX_STATIC_PRNG      4


/*
** Undo the hack that converts floating point types to integer for
** builds on processors without floating point support.
*/
#ifdef SQLITE_OMIT_FLOATING_POINT







|







 







>







 







|
>
|







26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
....
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
....
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
** on how SQLite interfaces are suppose to operate.
**
** The name of this file under configuration management is "sqlite.h.in".
** The makefile makes some minor changes to this file (such as inserting
** the version number) and changes its name to "sqlite3.h" as
** part of the build process.
**
** @(#) $Id: sqlite.h.in,v 1.236 2007/08/22 00:39:20 drh Exp $
*/
#ifndef _SQLITE3_H_
#define _SQLITE3_H_
#include <stdarg.h>     /* Needed for the definition of va_list */

/*
** Make sure we can call this stuff from C++.
................................................................................
** to sqlite3_mutex_alloc() is one of these integer constants:
**
** <ul>
** <li>  SQLITE_MUTEX_FAST
** <li>  SQLITE_MUTEX_RECURSIVE
** <li>  SQLITE_MUTEX_STATIC_MASTER
** <li>  SQLITE_MUTEX_STATIC_MEM
** <li>  SQLITE_MUTEX_STATIC_MEM2
** <li>  SQLITE_MUTEX_STATIC_PRNG
** </ul>
**
** The first two constants cause sqlite3_mutex_alloc() to create
** a new mutex.  The new mutex is recursive when SQLITE_MUTEX_RECURSIVE
** is used but not necessarily so when SQLITE_MUTEX_FAST is used.
** The mutex implementation does not need to make a distinction
................................................................................
**
** The [sqlite3_mutex_alloc()] interface takes a single argument
** which is one of these integer constants.
*/
#define SQLITE_MUTEX_FAST             0
#define SQLITE_MUTEX_RECURSIVE        1
#define SQLITE_MUTEX_STATIC_MASTER    2
#define SQLITE_MUTEX_STATIC_MEM       3  /* sqlite3_malloc() */
#define SQLITE_MUTEX_STATIC_MEM2      4  /* sqlite3_release_memory() */
#define SQLITE_MUTEX_STATIC_PRNG      5  /* sqlite3_random() */


/*
** Undo the hack that converts floating point types to integer for
** builds on processors without floating point support.
*/
#ifdef SQLITE_OMIT_FLOATING_POINT

Changes to src/tclsqlite.c.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
....
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** A TCL Interface to SQLite.  Append this file to sqlite3.c and
** compile the whole thing to build a TCL-enabled version of SQLite.
**
** $Id: tclsqlite.c,v 1.196 2007/08/21 10:44:16 drh Exp $
*/
#include "tcl.h"
#include <errno.h>

/*
** Some additional include files are needed if this file is not
** appended to the amalgamation.
................................................................................

  /* If compiled with SQLITE_TEST turned on, then register the "md5sum"
  ** SQL function.
  */
#ifdef SQLITE_TEST
  {
    extern void Md5_Register(sqlite3*);
#ifdef SQLITE_MEMDEBUG
    int mallocfail = sqlite3_iMallocFail;
    sqlite3_iMallocFail = 0;
#endif
    Md5_Register(p->db);
#ifdef SQLITE_MEMDEBUG
    sqlite3_iMallocFail = mallocfail;
#endif
  }
#endif  
  return TCL_OK;
}








|







 







|




|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
....
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** A TCL Interface to SQLite.  Append this file to sqlite3.c and
** compile the whole thing to build a TCL-enabled version of SQLite.
**
** $Id: tclsqlite.c,v 1.197 2007/08/22 00:39:21 drh Exp $
*/
#include "tcl.h"
#include <errno.h>

/*
** Some additional include files are needed if this file is not
** appended to the amalgamation.
................................................................................

  /* If compiled with SQLITE_TEST turned on, then register the "md5sum"
  ** SQL function.
  */
#ifdef SQLITE_TEST
  {
    extern void Md5_Register(sqlite3*);
#if 0
    int mallocfail = sqlite3_iMallocFail;
    sqlite3_iMallocFail = 0;
#endif
    Md5_Register(p->db);
#if 0
    sqlite3_iMallocFail = mallocfail;
#endif
  }
#endif  
  return TCL_OK;
}

Changes to src/test1.c.

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
...
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
....
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
....
4014
4015
4016
4017
4018
4019
4020
4021
4022
4023
4024
4025
4026
4027
4028
4029
4030
4031

4032
4033
4034
4035
4036
4037
4038
4039
4040
4041
....
4057
4058
4059
4060
4061
4062
4063
4064
4065
4066
4067
4068
4069
4070
4071
4072
4073
....
4317
4318
4319
4320
4321
4322
4323
4324
4325
4326
4327
4328
4329
4330
4331
4332
....
4399
4400
4401
4402
4403
4404
4405
4406
4407
4408
4409
4410
4411
4412
4413
4414
4415
4416
4417
4418
**    May you share freely, never taking more than you give.
**
*************************************************************************
** Code for testing all sorts of SQLite interfaces.  This code
** is not included in the SQLite library.  It is used for automated
** testing of the SQLite library.
**
** $Id: test1.c,v 1.267 2007/08/21 19:33:57 drh Exp $
*/
#include "sqliteInt.h"
#include "tcl.h"
#include <stdlib.h>
#include <string.h>

/*
................................................................................
  }

#ifndef SQLITE_OMIT_UTF16
  /* Use the sqlite3_create_function16() API here. Mainly for fun, but also 
  ** because it is not tested anywhere else. */
  if( rc==SQLITE_OK ){
    sqlite3_value *pVal;
#if 0
    if( sqlite3_iMallocFail>0 ){
      sqlite3_iMallocFail++;
    }
#endif 
    pVal = sqlite3ValueNew(db);
    sqlite3ValueSetStr(pVal, -1, "x_sqlite_exec", SQLITE_UTF8, SQLITE_STATIC);
    rc = sqlite3_create_function16(db, 
              sqlite3ValueText(pVal, SQLITE_UTF16NATIVE),
              1, SQLITE_UTF16, db, sqlite3ExecFunc, 0, 0);
    sqlite3ValueFree(pVal);
  }
................................................................................
          (void *)SQLITE_UTF8, val?test_collate_func:0);
  if( rc==SQLITE_OK ){
    if( TCL_OK!=Tcl_GetBooleanFromObj(interp, objv[3], &val) ) return TCL_ERROR;
    rc = sqlite3_create_collation(db, "test_collate", SQLITE_UTF16LE, 
            (void *)SQLITE_UTF16LE, val?test_collate_func:0);
    if( TCL_OK!=Tcl_GetBooleanFromObj(interp, objv[4], &val) ) return TCL_ERROR;

#ifdef SQLITE_MEMDEBUG
    if( sqlite3_iMallocFail>0 ){
      sqlite3_iMallocFail++;
    }
#endif
    pVal = sqlite3ValueNew(0);
    sqlite3ValueSetStr(pVal, -1, "test_collate", SQLITE_UTF8, SQLITE_STATIC);
    rc = sqlite3_create_collation16(db, 
................................................................................
*/
static int test_soft_heap_limit(
  void * clientData,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
){
#if defined(SQLITE_ENABLE_MEMORY_MANAGEMENT) && !defined(SQLITE_OMIT_DISKIO)
  int amt;
  if( objc!=1 && objc!=2 ){
    Tcl_WrongNumArgs(interp, 1, objv, "?N?");
    return TCL_ERROR;
  }
  amt = sqlite3ThreadDataReadOnly()->nSoftHeapLimit;
  if( objc==2 ){
    int N;
    if( Tcl_GetIntFromObj(interp, objv[1], &N) ) return TCL_ERROR;
    sqlite3_soft_heap_limit(N);

  }
  Tcl_SetObjResult(interp, Tcl_NewIntObj(amt));
#endif
  return TCL_OK;
}

/*
** Usage:   sqlite3_clear_tsd_memdebug
**
** Clear all of the MEMDEBUG information out of thread-specific data.
................................................................................
*/
static int test_tsd_release(
  void * clientData,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
){
#if defined(SQLITE_MEMDEBUG)
  sqlite3ReleaseThreadData();
#endif
  return TCL_OK;
}

/*
** Usage:   sqlite3_thread_cleanup
**
** Call the sqlite3_thread_cleanup API.
................................................................................
#endif
  };
  static int bitmask_size = sizeof(Bitmask)*8;
  int i;
  extern int sqlite3_where_trace;
  extern int sqlite3_sync_count, sqlite3_fullsync_count;
  extern int sqlite3_opentemp_count;
  extern int sqlite3_memUsed;
  extern int sqlite3_memMax;
  extern int sqlite3_like_count;
  extern int sqlite3_xferopt_count;
  extern int sqlite3_pager_readdb_count;
  extern int sqlite3_pager_writedb_count;
  extern int sqlite3_pager_writej_count;
  extern int sqlite3_pager_pgfree_count;
#if OS_UNIX && defined(SQLITE_TEST) && SQLITE_THREADSAFE
................................................................................
  Tcl_LinkVar(interp, "sqlite_addop_trace",
      (char*)&sqlite3_vdbe_addop_trace, TCL_LINK_INT);
  Tcl_LinkVar(interp, "sqlite_where_trace",
      (char*)&sqlite3_where_trace, TCL_LINK_INT);
  Tcl_LinkVar(interp, "sqlite_os_trace",
      (char*)&sqlite3_os_trace, TCL_LINK_INT);
#endif
#ifdef SQLITE_MEMDEBUG
  Tcl_LinkVar(interp, "sqlite_memused",
      (char*)&sqlite3_memUsed, TCL_LINK_INT | TCL_LINK_READ_ONLY);
  Tcl_LinkVar(interp, "sqlite_memmax",
      (char*)&sqlite3_memMax, TCL_LINK_INT | TCL_LINK_READ_ONLY);
#endif
#ifndef SQLITE_OMIT_DISKIO
  Tcl_LinkVar(interp, "sqlite_opentemp_count",
      (char*)&sqlite3_opentemp_count, TCL_LINK_INT);
#endif
  Tcl_LinkVar(interp, "sqlite_static_bind_value",
      (char*)&sqlite_static_bind_value, TCL_LINK_STRING);
  Tcl_LinkVar(interp, "sqlite_static_bind_nbyte",







|







 







<
<
<
<
<







 







|







 







|





|




>


<







 







<
<
<







 







<
<







 







<
<
<
<
<
<







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
...
912
913
914
915
916
917
918





919
920
921
922
923
924
925
....
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
....
4009
4010
4011
4012
4013
4014
4015
4016
4017
4018
4019
4020
4021
4022
4023
4024
4025
4026
4027
4028
4029

4030
4031
4032
4033
4034
4035
4036
....
4052
4053
4054
4055
4056
4057
4058



4059
4060
4061
4062
4063
4064
4065
....
4309
4310
4311
4312
4313
4314
4315


4316
4317
4318
4319
4320
4321
4322
....
4389
4390
4391
4392
4393
4394
4395






4396
4397
4398
4399
4400
4401
4402
**    May you share freely, never taking more than you give.
**
*************************************************************************
** Code for testing all sorts of SQLite interfaces.  This code
** is not included in the SQLite library.  It is used for automated
** testing of the SQLite library.
**
** $Id: test1.c,v 1.268 2007/08/22 00:39:21 drh Exp $
*/
#include "sqliteInt.h"
#include "tcl.h"
#include <stdlib.h>
#include <string.h>

/*
................................................................................
  }

#ifndef SQLITE_OMIT_UTF16
  /* Use the sqlite3_create_function16() API here. Mainly for fun, but also 
  ** because it is not tested anywhere else. */
  if( rc==SQLITE_OK ){
    sqlite3_value *pVal;





    pVal = sqlite3ValueNew(db);
    sqlite3ValueSetStr(pVal, -1, "x_sqlite_exec", SQLITE_UTF8, SQLITE_STATIC);
    rc = sqlite3_create_function16(db, 
              sqlite3ValueText(pVal, SQLITE_UTF16NATIVE),
              1, SQLITE_UTF16, db, sqlite3ExecFunc, 0, 0);
    sqlite3ValueFree(pVal);
  }
................................................................................
          (void *)SQLITE_UTF8, val?test_collate_func:0);
  if( rc==SQLITE_OK ){
    if( TCL_OK!=Tcl_GetBooleanFromObj(interp, objv[3], &val) ) return TCL_ERROR;
    rc = sqlite3_create_collation(db, "test_collate", SQLITE_UTF16LE, 
            (void *)SQLITE_UTF16LE, val?test_collate_func:0);
    if( TCL_OK!=Tcl_GetBooleanFromObj(interp, objv[4], &val) ) return TCL_ERROR;

#if 0
    if( sqlite3_iMallocFail>0 ){
      sqlite3_iMallocFail++;
    }
#endif
    pVal = sqlite3ValueNew(0);
    sqlite3ValueSetStr(pVal, -1, "test_collate", SQLITE_UTF8, SQLITE_STATIC);
    rc = sqlite3_create_collation16(db, 
................................................................................
*/
static int test_soft_heap_limit(
  void * clientData,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
){
  static int softHeapLimit = 0;
  int amt;
  if( objc!=1 && objc!=2 ){
    Tcl_WrongNumArgs(interp, 1, objv, "?N?");
    return TCL_ERROR;
  }
  amt = softHeapLimit;
  if( objc==2 ){
    int N;
    if( Tcl_GetIntFromObj(interp, objv[1], &N) ) return TCL_ERROR;
    sqlite3_soft_heap_limit(N);
    softHeapLimit = N;
  }
  Tcl_SetObjResult(interp, Tcl_NewIntObj(amt));

  return TCL_OK;
}

/*
** Usage:   sqlite3_clear_tsd_memdebug
**
** Clear all of the MEMDEBUG information out of thread-specific data.
................................................................................
*/
static int test_tsd_release(
  void * clientData,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
){



  return TCL_OK;
}

/*
** Usage:   sqlite3_thread_cleanup
**
** Call the sqlite3_thread_cleanup API.
................................................................................
#endif
  };
  static int bitmask_size = sizeof(Bitmask)*8;
  int i;
  extern int sqlite3_where_trace;
  extern int sqlite3_sync_count, sqlite3_fullsync_count;
  extern int sqlite3_opentemp_count;


  extern int sqlite3_like_count;
  extern int sqlite3_xferopt_count;
  extern int sqlite3_pager_readdb_count;
  extern int sqlite3_pager_writedb_count;
  extern int sqlite3_pager_writej_count;
  extern int sqlite3_pager_pgfree_count;
#if OS_UNIX && defined(SQLITE_TEST) && SQLITE_THREADSAFE
................................................................................
  Tcl_LinkVar(interp, "sqlite_addop_trace",
      (char*)&sqlite3_vdbe_addop_trace, TCL_LINK_INT);
  Tcl_LinkVar(interp, "sqlite_where_trace",
      (char*)&sqlite3_where_trace, TCL_LINK_INT);
  Tcl_LinkVar(interp, "sqlite_os_trace",
      (char*)&sqlite3_os_trace, TCL_LINK_INT);
#endif






#ifndef SQLITE_OMIT_DISKIO
  Tcl_LinkVar(interp, "sqlite_opentemp_count",
      (char*)&sqlite3_opentemp_count, TCL_LINK_INT);
#endif
  Tcl_LinkVar(interp, "sqlite_static_bind_value",
      (char*)&sqlite_static_bind_value, TCL_LINK_STRING);
  Tcl_LinkVar(interp, "sqlite_static_bind_nbyte",

Changes to src/vdbeapi.c.

40
41
42
43
44
45
46

47
48
49
50
51
52
53
54
55
56
*/
int sqlite3_finalize(sqlite3_stmt *pStmt){
  int rc;
  if( pStmt==0 ){
    rc = SQLITE_OK;
  }else{
    Vdbe *v = (Vdbe*)pStmt;

    sqlite3_mutex_enter(v->db->mutex);
    rc = sqlite3VdbeFinalize(v);
    sqlite3_mutex_leave(v->db->mutex);
  }
  return rc;
}

/*
** Terminate the current execution of an SQL statement and reset it
** back to its starting state so that it can be reused. A success code from







>
|

|







40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
*/
int sqlite3_finalize(sqlite3_stmt *pStmt){
  int rc;
  if( pStmt==0 ){
    rc = SQLITE_OK;
  }else{
    Vdbe *v = (Vdbe*)pStmt;
    sqlite3_mutex *mutex = v->db->mutex;
    sqlite3_mutex_enter(mutex);
    rc = sqlite3VdbeFinalize(v);
    sqlite3_mutex_leave(mutex);
  }
  return rc;
}

/*
** Terminate the current execution of an SQL statement and reset it
** back to its starting state so that it can be reused. A success code from

Changes to test/capi2.test.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
#    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 callback-free C/C++ API.
#
# $Id: capi2.test,v 1.33 2007/01/03 23:37:29 drh Exp $
#

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

# Return the text values from the current row pointed at by STMT as a list.
proc get_row_values {STMT} {
................................................................................
# finalized. Is this going to cause trouble for anyone? Lee Nelson maybe?
# (Later:) The change now happens just before SQLITE_DONE is returned.
do_test capi2-3.10b {db changes} {1}
do_test capi2-3.11 {
  sqlite3_finalize $VM
} {SQLITE_OK}
do_test capi2-3.11b {db changes} {1}
do_test capi2-3.12-misuse {
  sqlite3_finalize $VM
} {SQLITE_MISUSE}
do_test capi2-3.13 {
  set VM [sqlite3_prepare $DB {INSERT INTO t1 VALUES(1,3,4)} -1 TAIL]
  list [sqlite3_step $VM] \
       [sqlite3_column_count $VM] \
       [get_row_values $VM] \
       [get_column_names $VM]
} {SQLITE_ERROR 0 {} {}}







|







 







|
|
|







7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
#    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 callback-free C/C++ API.
#
# $Id: capi2.test,v 1.34 2007/08/22 00:39:21 drh Exp $
#

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

# Return the text values from the current row pointed at by STMT as a list.
proc get_row_values {STMT} {
................................................................................
# finalized. Is this going to cause trouble for anyone? Lee Nelson maybe?
# (Later:) The change now happens just before SQLITE_DONE is returned.
do_test capi2-3.10b {db changes} {1}
do_test capi2-3.11 {
  sqlite3_finalize $VM
} {SQLITE_OK}
do_test capi2-3.11b {db changes} {1}
#do_test capi2-3.12-misuse {
#  sqlite3_finalize $VM
#} {SQLITE_MISUSE}
do_test capi2-3.13 {
  set VM [sqlite3_prepare $DB {INSERT INTO t1 VALUES(1,3,4)} -1 TAIL]
  list [sqlite3_step $VM] \
       [sqlite3_column_count $VM] \
       [get_row_values $VM] \
       [get_column_names $VM]
} {SQLITE_ERROR 0 {} {}}