/ Check-in [212de3ce]
Login

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

Overview
Comment:Remove default_synchronous and temp_store pragmas. Allow the safety-level and cache-size to be set for attached databases. (CVS 1735)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 212de3ce66f746036cb2267a9f924fd55fa2f37a
User & Date: danielk1977 2004-06-26 06:37:06
Original Comment: Remove default_synchronous and temp_store pragmas. Allow the safety-level and cache-size to be set for attached databases. (CVS 1735)
Original User & Date: danielk1977 2004-06-26 06:37:07
Context
2004-06-26
06:37
Remove default_synchronous and temp_store pragmas. Allow the safety-level and cache-size to be set for attached databases. (CVS 1736) check-in: 76da457b user: danielk1977 tags: trunk
06:37
Remove default_synchronous and temp_store pragmas. Allow the safety-level and cache-size to be set for attached databases. (CVS 1735) check-in: 212de3ce user: danielk1977 tags: trunk
01:48
Fix a bug in the new full-sync journal format. (CVS 1733) check-in: 02bd3acd user: danielk1977 tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/attach.c.

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

87
88
89
90
91
92
93
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains code used to implement the ATTACH and DETACH commands.
**
** $Id: attach.c,v 1.17 2004/06/19 16:06:11 drh Exp $
*/
#include "sqliteInt.h"

/*
** This routine is called by the parser to process an ATTACH statement:
**
**     ATTACH DATABASE filename AS dbname
................................................................................
  aNew = &db->aDb[db->nDb++];
  memset(aNew, 0, sizeof(*aNew));
  sqlite3HashInit(&aNew->tblHash, SQLITE_HASH_STRING, 0);
  sqlite3HashInit(&aNew->idxHash, SQLITE_HASH_STRING, 0);
  sqlite3HashInit(&aNew->trigHash, SQLITE_HASH_STRING, 0);
  sqlite3HashInit(&aNew->aFKey, SQLITE_HASH_STRING, 1);
  aNew->zName = zName;

  rc = sqlite3BtreeFactory(db, zFile, 0, MAX_PAGES, &aNew->pBt);
  if( rc ){
    sqlite3ErrorMsg(pParse, "unable to open database: %s", zFile);
  }
#if SQLITE_HAS_CODEC
  {
    extern int sqliteCodecAttach(sqlite*, int, void*, int);







|







 







>







7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
..
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains code used to implement the ATTACH and DETACH commands.
**
** $Id: attach.c,v 1.18 2004/06/26 06:37:07 danielk1977 Exp $
*/
#include "sqliteInt.h"

/*
** This routine is called by the parser to process an ATTACH statement:
**
**     ATTACH DATABASE filename AS dbname
................................................................................
  aNew = &db->aDb[db->nDb++];
  memset(aNew, 0, sizeof(*aNew));
  sqlite3HashInit(&aNew->tblHash, SQLITE_HASH_STRING, 0);
  sqlite3HashInit(&aNew->idxHash, SQLITE_HASH_STRING, 0);
  sqlite3HashInit(&aNew->trigHash, SQLITE_HASH_STRING, 0);
  sqlite3HashInit(&aNew->aFKey, SQLITE_HASH_STRING, 1);
  aNew->zName = zName;
  aNew->safety_level = 3;
  rc = sqlite3BtreeFactory(db, zFile, 0, MAX_PAGES, &aNew->pBt);
  if( rc ){
    sqlite3ErrorMsg(pParse, "unable to open database: %s", zFile);
  }
#if SQLITE_HAS_CODEC
  {
    extern int sqliteCodecAttach(sqlite*, int, void*, int);

Changes to src/main.c.

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
...
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
...
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277

278
279
280
281
282
283
284
...
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
...
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
...
833
834
835
836
837
838
839
840



841
842
843
844
845
846
847
....
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143





1144
1145
1146
1147
1148
1149
1150
**
*************************************************************************
** 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.233 2004/06/22 12:13:55 drh Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>

/*
** A pointer to this structure is used to communicate information
................................................................................

  /* Get the database meta information.
  **
  ** Meta values are as follows:
  **    meta[0]   Schema cookie.  Changes with each schema change.
  **    meta[1]   File format of schema layer.
  **    meta[2]   Size of the page cache.
  **    meta[3]   Synchronous setting.  1:off, 2:normal, 3:full
  **    meta[4]   Db text encoding. 1:UTF-8 3:UTF-16 LE 4:UTF-16 BE
  **    meta[5]   Pragma temp_store value.  See comments on BtreeFactory
  **    meta[6]   
  **    meta[7]
  **    meta[8]
  **    meta[9]
  **
  ** Note: The hash defined SQLITE_UTF* symbols in sqliteInt.h correspond to
  ** the possible values of meta[4].
................................................................................
        sqlite3SetString(pzErrMsg, "attached databases must use the same"
            " text encoding as main database", (char*)0);
        return SQLITE_ERROR;
      }
    }
  }

  if( iDb==0 ){
    size = meta[2];
    if( size==0 ){ size = MAX_PAGES; }
    db->cache_size = size;
    db->safety_level = meta[3];
    if( meta[5]>0 && meta[5]<=2 && db->temp_store==0 ){
      db->temp_store = meta[5];
    }
    if( db->safety_level==0 ) db->safety_level = 2;


    db->file_format = meta[1];
    if( db->file_format==0 ){
      /* This happens if the database was initially empty */
      db->file_format = 1;
    }
  }

................................................................................
  */
  if( meta[1]>1 ){
    sqlite3BtreeCloseCursor(curMain);
    sqlite3SetString(pzErrMsg, "unsupported file format", (char*)0);
    return SQLITE_ERROR;
  }

  sqlite3BtreeSetCacheSize(db->aDb[iDb].pBt, db->cache_size);
  sqlite3BtreeSetSafetyLevel(db->aDb[iDb].pBt, meta[3]==0 ? 2 : meta[3]);

  /* Read the schema information out of the schema tables
  */
  assert( db->init.busy );
  if( rc==SQLITE_EMPTY ){
    /* For an empty database, there is nothing to read */
    rc = SQLITE_OK;
................................................................................
** This routine is called to create a connection to a database BTree
** driver.  If zFilename is the name of a file, then that file is
** opened and used.  If zFilename is the magic name ":memory:" then
** the database is stored in memory (and is thus forgotten as soon as
** the connection is closed.)  If zFilename is NULL then the database
** is for temporary use only and is deleted as soon as the connection
** is closed.
**
** A temporary database can be either a disk file (that is automatically
** deleted when the file is closed) or a set of red-black trees held in memory,
** depending on the values of the TEMP_STORE compile-time macro and the
** db->temp_store variable, according to the following chart:
**
**       TEMP_STORE     db->temp_store     Location of temporary database
**       ----------     --------------     ------------------------------
**           0               any             file
**           1                1              file
**           1                2              memory
**           1                0              file
**           2                1              file
**           2                2              memory
**           2                0              memory
**           3               any             memory
*/
int sqlite3BtreeFactory(
  const sqlite *db,	    /* Main database when opening aux otherwise 0 */
  const char *zFilename,    /* Name of the file containing the BTree database */
  int omitJournal,          /* if TRUE then do not journal this file */
  int nCache,               /* How many pages in the page cache */
  Btree **ppBtree           /* Pointer to new Btree object written here */
................................................................................
){
  int btree_flags = 0;
  
  assert( ppBtree != 0);
  if( omitJournal ){
    btree_flags |= BTREE_OMIT_JOURNAL;
  }
  if( !zFilename ){



    btree_flags |= BTREE_MEMORY;
  }

  return sqlite3BtreeOpen(zFilename, ppBtree, nCache, btree_flags,
      (void *)&db->busyHandler);
}

................................................................................
    goto opendb_out;
  }

  /* Also add a UTF-8 case-insensitive collation sequence. */
  sqlite3_create_collation(db, "NOCASE", SQLITE_UTF8, 0, nocaseCollatingFunc);

  /* Open the backend database driver */
  if( zFilename[0]==':' && strcmp(zFilename,":memory:")==0 ){
    db->temp_store = 2;
    db->nMaster = 0;    /* Disable atomic multi-file commit for :memory: */
  }else{
    db->nMaster = -1;   /* Size of master journal filename initially unknown */
  }
  rc = sqlite3BtreeFactory(db, zFilename, 0, MAX_PAGES, &db->aDb[0].pBt);
  if( rc!=SQLITE_OK ){
    sqlite3Error(db, rc, 0);
    db->magic = SQLITE_MAGIC_CLOSED;
    goto opendb_out;
  }
  db->aDb[0].zName = "main";
  db->aDb[1].zName = "temp";






  /* Register all built-in functions, but do not attempt to read the
  ** database schema yet. This is delayed until the first time the database
  ** is accessed.
  */
  sqlite3RegisterBuiltinFunctions(db);
  if( rc==SQLITE_OK ){







|







 







|

|







 







<
|
|
|
<
<
<
|
<
<
>







 







|
<







 







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







 







|
>
>
>







 







<
<
<
<
<
<








>
>
>
>
>







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
...
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
...
261
262
263
264
265
266
267

268
269
270



271


272
273
274
275
276
277
278
279
...
282
283
284
285
286
287
288
289

290
291
292
293
294
295
296
...
797
798
799
800
801
802
803
















804
805
806
807
808
809
810
...
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
....
1104
1105
1106
1107
1108
1109
1110






1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
**
*************************************************************************
** 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.234 2004/06/26 06:37:07 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>

/*
** A pointer to this structure is used to communicate information
................................................................................

  /* Get the database meta information.
  **
  ** Meta values are as follows:
  **    meta[0]   Schema cookie.  Changes with each schema change.
  **    meta[1]   File format of schema layer.
  **    meta[2]   Size of the page cache.
  **    meta[3]
  **    meta[4]   Db text encoding. 1:UTF-8 3:UTF-16 LE 4:UTF-16 BE
  **    meta[5]
  **    meta[6]   
  **    meta[7]
  **    meta[8]
  **    meta[9]
  **
  ** Note: The hash defined SQLITE_UTF* symbols in sqliteInt.h correspond to
  ** the possible values of meta[4].
................................................................................
        sqlite3SetString(pzErrMsg, "attached databases must use the same"
            " text encoding as main database", (char*)0);
        return SQLITE_ERROR;
      }
    }
  }


  size = meta[2];
  if( size==0 ){ size = MAX_PAGES; }
  db->aDb[iDb].cache_size = size;






  if( iDb==0 ){
    db->file_format = meta[1];
    if( db->file_format==0 ){
      /* This happens if the database was initially empty */
      db->file_format = 1;
    }
  }

................................................................................
  */
  if( meta[1]>1 ){
    sqlite3BtreeCloseCursor(curMain);
    sqlite3SetString(pzErrMsg, "unsupported file format", (char*)0);
    return SQLITE_ERROR;
  }

  sqlite3BtreeSetCacheSize(db->aDb[iDb].pBt, db->aDb[iDb].cache_size);


  /* Read the schema information out of the schema tables
  */
  assert( db->init.busy );
  if( rc==SQLITE_EMPTY ){
    /* For an empty database, there is nothing to read */
    rc = SQLITE_OK;
................................................................................
** This routine is called to create a connection to a database BTree
** driver.  If zFilename is the name of a file, then that file is
** opened and used.  If zFilename is the magic name ":memory:" then
** the database is stored in memory (and is thus forgotten as soon as
** the connection is closed.)  If zFilename is NULL then the database
** is for temporary use only and is deleted as soon as the connection
** is closed.
















*/
int sqlite3BtreeFactory(
  const sqlite *db,	    /* Main database when opening aux otherwise 0 */
  const char *zFilename,    /* Name of the file containing the BTree database */
  int omitJournal,          /* if TRUE then do not journal this file */
  int nCache,               /* How many pages in the page cache */
  Btree **ppBtree           /* Pointer to new Btree object written here */
................................................................................
){
  int btree_flags = 0;
  
  assert( ppBtree != 0);
  if( omitJournal ){
    btree_flags |= BTREE_OMIT_JOURNAL;
  }
  if( !zFilename || !strcmp(zFilename, ":memory:") ){
    /* If zFilename is NULL or the magic string ":memory:" then the
    ** new btree storest data in main memory, not a file.
    */
    btree_flags |= BTREE_MEMORY;
  }

  return sqlite3BtreeOpen(zFilename, ppBtree, nCache, btree_flags,
      (void *)&db->busyHandler);
}

................................................................................
    goto opendb_out;
  }

  /* Also add a UTF-8 case-insensitive collation sequence. */
  sqlite3_create_collation(db, "NOCASE", SQLITE_UTF8, 0, nocaseCollatingFunc);

  /* Open the backend database driver */






  rc = sqlite3BtreeFactory(db, zFilename, 0, MAX_PAGES, &db->aDb[0].pBt);
  if( rc!=SQLITE_OK ){
    sqlite3Error(db, rc, 0);
    db->magic = SQLITE_MAGIC_CLOSED;
    goto opendb_out;
  }
  db->aDb[0].zName = "main";
  db->aDb[1].zName = "temp";

  /* The default safety_level for the main database is 'full' for the temp
  ** database it is 'NONE'. This matches the pager layer defaults.  */
  db->aDb[0].safety_level = 3;
  db->aDb[1].safety_level = 1;

  /* Register all built-in functions, but do not attempt to read the
  ** database schema yet. This is delayed until the first time the database
  ** is accessed.
  */
  sqlite3RegisterBuiltinFunctions(db);
  if( rc==SQLITE_OK ){

Changes to src/parse.y.

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
...
778
779
780
781
782
783
784
785
786
787
788
789


790
791
792
793
794
795
796
797
**
*************************************************************************
** This file contains SQLite's grammar for SQL.  Process this file
** using the lemon parser generator to generate C code that runs
** the parser.  Lemon will also generate a header file containing
** numeric codes for all of the tokens.
**
** @(#) $Id: parse.y,v 1.127 2004/06/09 09:55:18 danielk1977 Exp $
*/
%token_prefix TK_
%token_type {Token}
%default_type {Token}
%extra_argument {Parse *pParse}
%syntax_error {
  if( pParse->zErrMsg==0 ){
................................................................................
///////////////////////////// The VACUUM command /////////////////////////////
//
cmd ::= VACUUM.                {sqlite3Vacuum(pParse,0);}
cmd ::= VACUUM nm(X).         {sqlite3Vacuum(pParse,&X);}

///////////////////////////// The PRAGMA command /////////////////////////////
//
cmd ::= PRAGMA ids(X) EQ nm(Y).         {sqlite3Pragma(pParse,&X,&Y,0);}
cmd ::= PRAGMA ids(X) EQ ON(Y).          {sqlite3Pragma(pParse,&X,&Y,0);}
cmd ::= PRAGMA ids(X) EQ plus_num(Y).    {sqlite3Pragma(pParse,&X,&Y,0);}
cmd ::= PRAGMA ids(X) EQ minus_num(Y).   {sqlite3Pragma(pParse,&X,&Y,1);}
cmd ::= PRAGMA ids(X) LP nm(Y) RP.      {sqlite3Pragma(pParse,&X,&Y,0);}


cmd ::= PRAGMA ids(X).                   {sqlite3Pragma(pParse,&X,&X,0);}
plus_num(A) ::= plus_opt number(X).   {A = X;}
minus_num(A) ::= MINUS number(X).     {A = X;}
number(A) ::= INTEGER(X).  {A = X;}
number(A) ::= FLOAT(X).    {A = X;}
plus_opt ::= PLUS.
plus_opt ::= .








|







 







|
|
|
|
|
>
>
|







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
...
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
**
*************************************************************************
** This file contains SQLite's grammar for SQL.  Process this file
** using the lemon parser generator to generate C code that runs
** the parser.  Lemon will also generate a header file containing
** numeric codes for all of the tokens.
**
** @(#) $Id: parse.y,v 1.128 2004/06/26 06:37:07 danielk1977 Exp $
*/
%token_prefix TK_
%token_type {Token}
%default_type {Token}
%extra_argument {Parse *pParse}
%syntax_error {
  if( pParse->zErrMsg==0 ){
................................................................................
///////////////////////////// The VACUUM command /////////////////////////////
//
cmd ::= VACUUM.                {sqlite3Vacuum(pParse,0);}
cmd ::= VACUUM nm(X).         {sqlite3Vacuum(pParse,&X);}

///////////////////////////// The PRAGMA command /////////////////////////////
//
cmd ::= PRAGMA nm(X) dbnm(Z) EQ nm(Y).  {sqlite3Pragma(pParse,&X,&Z,&Y,0);}
cmd ::= PRAGMA nm(X) dbnm(Z) EQ ON(Y).  {sqlite3Pragma(pParse,&X,&Z,&Y,0);}
cmd ::= PRAGMA nm(X) dbnm(Z) EQ plus_num(Y). {sqlite3Pragma(pParse,&X,&Z,&Y,0);}
cmd ::= PRAGMA nm(X) dbnm(Z) EQ minus_num(Y). {
  sqlite3Pragma(pParse,&X,&Z,&Y,1);
}
cmd ::= PRAGMA nm(X) dbnm(Z) LP nm(Y) RP. {sqlite3Pragma(pParse,&X,&Z,&Y,0);}
cmd ::= PRAGMA nm(X) dbnm(Z).  {sqlite3Pragma(pParse,&X,&Z,0,0);}
plus_num(A) ::= plus_opt number(X).   {A = X;}
minus_num(A) ::= MINUS number(X).     {A = X;}
number(A) ::= INTEGER(X).  {A = X;}
number(A) ::= FLOAT(X).    {A = X;}
plus_opt ::= PLUS.
plus_opt ::= .

Changes to src/pragma.c.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
..
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
...
153
154
155
156
157
158
159
160
161
162
163
164
165
166






167
168



169
170
171
172





173
174
175
176
177
178
179


180
181
182
183
184
185
186
187
...
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218

219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
...
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
...
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366


367
368
369
370
371

372
373
374
375
376
377
378
...
382
383
384
385
386
387
388












389
390
391
392
393
394
395
...
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
...
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains code used to implement the PRAGMA command.
**
** $Id: pragma.c,v 1.52 2004/06/21 09:06:42 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
# include "pager.h"
# include "btree.h"
................................................................................
  }
  for(i=0; i<sizeof(aKey)/sizeof(aKey[0]); i++){
    if( sqlite3StrICmp(z,aKey[i].zWord)==0 ) return aKey[i].val;
  }
  return 1;
}

/*
** Interpret the given string as a temp db location. Return 1 for file
** backed temporary databases, 2 for the Red-Black tree in memory database
** and 0 to use the compile-time default.
*/
static int getTempStore(const char *z){
  if( z[0]>='0' && z[0]<='2' ){
    return z[0] - '0';
  }else if( sqlite3StrICmp(z, "file")==0 ){
    return 1;
  }else if( sqlite3StrICmp(z, "memory")==0 ){
    return 2;
  }else{
    return 0;
  }
}

/*
** If the TEMP database is open, close it and mark the database schema
** as needing reloading.  This must be done when using the TEMP_STORE
** or DEFAULT_TEMP_STORE pragmas.
*/
static int changeTempStorage(Parse *pParse, const char *zStorageType){
  int ts = getTempStore(zStorageType);
  sqlite *db = pParse->db;
  if( db->temp_store==ts ) return SQLITE_OK;
  if( db->aDb[1].pBt!=0 ){
    if( !db->autoCommit ){
      sqlite3ErrorMsg(pParse, "temporary storage cannot be changed "
        "from within a transaction");
      return SQLITE_ERROR;
    }
    sqlite3BtreeClose(db->aDb[1].pBt);
    db->aDb[1].pBt = 0;
    sqlite3ResetInternalSchema(db, 0);
  }
  db->temp_store = ts;
  return SQLITE_OK;
}

/*
** Check to see if zRight and zLeft refer to a pragma that queries
** or changes one of the flags in db->flags.  Return 1 if so and 0 if not.
** Also, implement the pragma.
*/
static int flagPragma(Parse *pParse, const char *zLeft, const char *zRight){
  static const struct {
................................................................................
}

/*
** Process a pragma statement.  
**
** Pragmas are of this form:
**
**      PRAGMA id = value
**
** The identifier might also be a string.  The value is a string, and
** identifier, or a number.  If minusFlag is true, then the value is
** a number that was preceded by a minus sign.
*/
void sqlite3Pragma(Parse *pParse, Token *pLeft, Token *pRight, int minusFlag){






  char *zLeft = 0;
  char *zRight = 0;



  sqlite *db = pParse->db;
  Vdbe *v = sqlite3GetVdbe(pParse);
  if( v==0 ) return;






  zLeft = sqlite3NameFromToken(pLeft);
  if( minusFlag ){
    zRight = 0;
    sqlite3SetNString(&zRight, "-", 1, pRight->z, pRight->n, 0);
  }else{
    zRight = sqlite3NameFromToken(pRight);
  }


  if( sqlite3AuthCheck(pParse, SQLITE_PRAGMA, zLeft, zRight, 0) ){
    goto pragma_out;
  }
 
  /*
  **  PRAGMA default_cache_size
  **  PRAGMA default_cache_size=N
  **
................................................................................
  ** database file.  The cache size is actually the absolute value of
  ** this memory location.  The sign of meta-value 2 determines the
  ** synchronous setting.  A negative value means synchronous is off
  ** and a positive value means synchronous is on.
  */
  if( sqlite3StrICmp(zLeft,"default_cache_size")==0 ){
    static VdbeOpList getCacheSize[] = {
      { OP_ReadCookie,  0, 2,        0},
      { OP_AbsValue,    0, 0,        0},
      { OP_Dup,         0, 0,        0},
      { OP_Integer,     0, 0,        0},
      { OP_Ne,          0, 6,        0},
      { OP_Integer,     0, 0,        0},  /* 5 */
      { OP_Callback,    1, 0,        0},
    };
    int addr;
    if( SQLITE_OK!=sqlite3ReadSchema(pParse->db, &pParse->zErrMsg) ){
      pParse->nErr++;
      goto pragma_out;
    }
    if( pRight->z==pLeft->z ){
      sqlite3VdbeSetNumCols(v, 1);
      sqlite3VdbeSetColName(v, 0, "cache_size", P3_STATIC);
      addr = sqlite3VdbeAddOpList(v, ArraySize(getCacheSize), getCacheSize);

      sqlite3VdbeChangeP1(v, addr+5, MAX_PAGES);
    }else{
      int size = atoi(zRight);
      if( size<0 ) size = -size;
      sqlite3BeginWriteOperation(pParse, 0, 0);
      sqlite3VdbeAddOp(v, OP_Integer, size, 0);
      sqlite3VdbeAddOp(v, OP_ReadCookie, 0, 2);
      addr = sqlite3VdbeAddOp(v, OP_Integer, 0, 0);
      sqlite3VdbeAddOp(v, OP_Ge, 0, addr+3);
      sqlite3VdbeAddOp(v, OP_Negative, 0, 0);
      sqlite3VdbeAddOp(v, OP_SetCookie, 0, 2);
      sqlite3EndWriteOperation(pParse);
      db->cache_size = db->cache_size<0 ? -size : size;
      sqlite3BtreeSetCacheSize(db->aDb[0].pBt, db->cache_size);
    }
  }else

  /*
  **  PRAGMA cache_size
  **  PRAGMA cache_size=N
  **
................................................................................
    static VdbeOpList getCacheSize[] = {
      { OP_Callback,    1, 0,        0},
    };
    if( SQLITE_OK!=sqlite3ReadSchema(pParse->db, &pParse->zErrMsg) ){
      pParse->nErr++;
      goto pragma_out;
    }
    if( pRight->z==pLeft->z ){
      int size = db->cache_size;;
      if( size<0 ) size = -size;
      sqlite3VdbeAddOp(v, OP_Integer, size, 0);
      sqlite3VdbeSetNumCols(v, 1);
      sqlite3VdbeSetColName(v, 0, "cache_size", P3_STATIC);
      sqlite3VdbeAddOpList(v, ArraySize(getCacheSize), getCacheSize);
    }else{
      int size = atoi(zRight);
      if( size<0 ) size = -size;
      if( db->cache_size<0 ) size = -size;
      db->cache_size = size;
      sqlite3BtreeSetCacheSize(db->aDb[0].pBt, db->cache_size);
    }
  }else

  /*
  **  PRAGMA default_synchronous
  **  PRAGMA default_synchronous=ON|OFF|NORMAL|FULL
  **
  ** The first form returns the persistent value of the "synchronous" setting
  ** that is stored in the database.  This is the synchronous setting that
  ** is used whenever the database is opened unless overridden by a separate
  ** "synchronous" pragma.  The second form changes the persistent and the
  ** local synchronous setting to the value given.
  **
  ** If synchronous is OFF, SQLite does not attempt any fsync() systems calls
  ** to make sure data is committed to disk.  Write operations are very fast,
  ** but a power failure can leave the database in an inconsistent state.
  ** If synchronous is ON or NORMAL, SQLite will do an fsync() system call to
  ** make sure data is being written to disk.  The risk of corruption due to
  ** a power loss in this mode is negligible but non-zero.  If synchronous
  ** is FULL, extra fsync()s occur to reduce the risk of corruption to near
  ** zero, but with a write performance penalty.  The default mode is NORMAL.
  */
  if( sqlite3StrICmp(zLeft,"default_synchronous")==0 ){
    static VdbeOpList getSync[] = {
      { OP_ReadCookie,  0, 3,        0},
      { OP_Dup,         0, 0,        0},
      { OP_If,          0, 0,        0},  /* 2 */
      { OP_ReadCookie,  0, 2,        0},
      { OP_Integer,     0, 0,        0},
      { OP_Lt,          0, 5,        0},
      { OP_AddImm,      1, 0,        0},
      { OP_Callback,    1, 0,        0},
      { OP_Halt,        0, 0,        0},
      { OP_AddImm,     -1, 0,        0},  /* 9 */
      { OP_Callback,    1, 0,        0}
    };
    int addr;
    if( SQLITE_OK!=sqlite3ReadSchema(pParse->db, &pParse->zErrMsg) ){
      pParse->nErr++;
      goto pragma_out;
    }
    if( pRight->z==pLeft->z ){
      sqlite3VdbeSetNumCols(v, 1);
      sqlite3VdbeSetColName(v, 0, "synchronous", P3_STATIC);
      addr = sqlite3VdbeAddOpList(v, ArraySize(getSync), getSync);
      sqlite3VdbeChangeP2(v, addr+2, addr+9);
    }else{
      int size = db->cache_size;
      if( size<0 ) size = -size;
      sqlite3BeginWriteOperation(pParse, 0, 0);
      sqlite3VdbeAddOp(v, OP_ReadCookie, 0, 2);
      sqlite3VdbeAddOp(v, OP_Dup, 0, 0);
      addr = sqlite3VdbeAddOp(v, OP_Integer, 0, 0);
      sqlite3VdbeAddOp(v, OP_Ne, 0, addr+3);
      sqlite3VdbeAddOp(v, OP_AddImm, MAX_PAGES, 0);
      sqlite3VdbeAddOp(v, OP_AbsValue, 0, 0);
      db->safety_level = getSafetyLevel(zRight)+1;
      if( db->safety_level==1 ){
        sqlite3VdbeAddOp(v, OP_Negative, 0, 0);
        size = -size;
      }
      sqlite3VdbeAddOp(v, OP_SetCookie, 0, 2);
      sqlite3VdbeAddOp(v, OP_Integer, db->safety_level, 0);
      sqlite3VdbeAddOp(v, OP_SetCookie, 0, 3);
      sqlite3EndWriteOperation(pParse);
      db->cache_size = size;
      sqlite3BtreeSetCacheSize(db->aDb[0].pBt, db->cache_size);
      sqlite3BtreeSetSafetyLevel(db->aDb[0].pBt, db->safety_level);
    }
  }else

  /*
  **   PRAGMA synchronous
  **   PRAGMA synchronous=OFF|ON|NORMAL|FULL
  **
................................................................................
    static VdbeOpList getSync[] = {
      { OP_Callback,    1, 0,        0},
    };
    if( SQLITE_OK!=sqlite3ReadSchema(pParse->db, &pParse->zErrMsg) ){
      pParse->nErr++;
      goto pragma_out;
    }
    if( pRight->z==pLeft->z ){
      sqlite3VdbeSetNumCols(v, 1);
      sqlite3VdbeSetColName(v, 0, "synchronous", P3_STATIC);
      sqlite3VdbeAddOp(v, OP_Integer, db->safety_level-1, 0);
      sqlite3VdbeAddOpList(v, ArraySize(getSync), getSync);
    }else{
      int size = db->cache_size;
      if( size<0 ) size = -size;


      db->safety_level = getSafetyLevel(zRight)+1;
      if( db->safety_level==1 ) size = -size;
      db->cache_size = size;
      sqlite3BtreeSetCacheSize(db->aDb[0].pBt, db->cache_size);
      sqlite3BtreeSetSafetyLevel(db->aDb[0].pBt, db->safety_level);

    }
  }else

#ifndef NDEBUG
  if( sqlite3StrICmp(zLeft, "trigger_overhead_test")==0 ){
    if( getBoolean(zRight) ){
      sqlite3_always_code_trigger_setup = 1;
................................................................................
  }else
#endif

  if( flagPragma(pParse, zLeft, zRight) ){
    /* The flagPragma() call also generates any necessary code */
  }else













  if( sqlite3StrICmp(zLeft, "table_info")==0 ){
    Table *pTab;
    if( SQLITE_OK!=sqlite3ReadSchema(pParse->db, &pParse->zErrMsg) ){
      pParse->nErr++;
      goto pragma_out;
    }
    pTab = sqlite3FindTable(db, zRight, 0);
................................................................................
      assert( db->aDb[i].zName!=0 );
      sqlite3VdbeAddOp(v, OP_Integer, i, 0);
      sqlite3VdbeOp3(v, OP_String8, 0, 0, db->aDb[i].zName, 0);
      sqlite3VdbeOp3(v, OP_String8, 0, 0,
           sqlite3BtreeGetFilename(db->aDb[i].pBt), 0);
      sqlite3VdbeAddOp(v, OP_Callback, 3, 0);
    }
  }else


  /*
  **   PRAGMA temp_store
  **   PRAGMA temp_store = "default"|"memory"|"file"
  **
  ** Return or set the local value of the temp_store flag.  Changing
  ** the local value does not make changes to the disk file and the default
  ** value will be restored the next time the database is opened.
  **
  ** Note that it is possible for the library compile-time options to
  ** override this setting
  */
  if( sqlite3StrICmp(zLeft, "temp_store")==0 ){
    static VdbeOpList getTmpDbLoc[] = {
      { OP_Callback,    1, 0,        0},
    };
    if( SQLITE_OK!=sqlite3ReadSchema(pParse->db, &pParse->zErrMsg) ){
      pParse->nErr++;
      goto pragma_out;
    }
    if( pRight->z==pLeft->z ){
      sqlite3VdbeAddOp(v, OP_Integer, db->temp_store, 0);
      sqlite3VdbeSetNumCols(v, 1);
      sqlite3VdbeSetColName(v, 0, "temp_store", P3_STATIC);
      sqlite3VdbeAddOpList(v, ArraySize(getTmpDbLoc), getTmpDbLoc);
    }else{
      changeTempStorage(pParse, zRight);
    }
  }else

  /*
  **   PRAGMA default_temp_store
  **   PRAGMA default_temp_store = "default"|"memory"|"file"
  **
  ** Return or set the value of the persistent temp_store flag.  Any
  ** change does not take effect until the next time the database is
  ** opened.
  **
  ** Note that it is possible for the library compile-time options to
  ** override this setting
  */
  if( sqlite3StrICmp(zLeft, "default_temp_store")==0 ){
    static VdbeOpList getTmpDbLoc[] = {
      { OP_ReadCookie,  0, 5,        0},
      { OP_Callback,    1, 0,        0}};
    if( SQLITE_OK!=sqlite3ReadSchema(pParse->db, &pParse->zErrMsg) ){
      pParse->nErr++;
      goto pragma_out;
    }
    if( pRight->z==pLeft->z ){
      sqlite3VdbeSetNumCols(v, 1);
      sqlite3VdbeSetColName(v, 0, "temp_store", P3_STATIC);
      sqlite3VdbeAddOpList(v, ArraySize(getTmpDbLoc), getTmpDbLoc);
    }else{
      sqlite3BeginWriteOperation(pParse, 0, 0);
      sqlite3VdbeAddOp(v, OP_Integer, getTempStore(zRight), 0);
      sqlite3VdbeAddOp(v, OP_SetCookie, 0, 5);
      sqlite3EndWriteOperation(pParse);
    }
  }else

#ifndef NDEBUG
  if( sqlite3StrICmp(zLeft, "parser_trace")==0 ){
    extern void sqlite3ParserTrace(FILE*, char *);
    if( SQLITE_OK!=sqlite3ReadSchema(pParse->db, &pParse->zErrMsg) ){
      pParse->nErr++;
................................................................................
      { "UTF16be",  SQLITE_UTF16BE     },
      { "UTF-16",   0 /* Filled in at run-time */ },
      { "UTF16",    0 /* Filled in at run-time */ },
      { 0, 0 }
    };
    struct EncName *pEnc;
    encnames[6].enc = encnames[7].enc = SQLITE_UTF16NATIVE;
    if( pRight->z==pLeft->z ){    /* "PRAGMA encoding" */
      if( SQLITE_OK!=sqlite3ReadSchema(pParse->db, &pParse->zErrMsg) ){
        pParse->nErr++;
        goto pragma_out;
      }
      sqlite3VdbeSetNumCols(v, 1);
      sqlite3VdbeSetColName(v, 0, "encoding", P3_STATIC);
      sqlite3VdbeAddOp(v, OP_String8, 0, 0);







|







 







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







 







|





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




>
>
>
>
>
|


|

|

>
>
|







 







|












|



>




|

|



|

|
|







 







|
|
|







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







 







|


|


|
|
>
>
|
<
<
<
|
>







 







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







 







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







 







|







7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
..
67
68
69
70
71
72
73








































74
75
76
77
78
79
80
...
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
...
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
...
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244

245
246




































































247
248
249
250
251
252
253
...
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277



278
279
280
281
282
283
284
285
286
...
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
...
444
445
446
447
448
449
450





























































451
452
453
454
455
456
457
...
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains code used to implement the PRAGMA command.
**
** $Id: pragma.c,v 1.53 2004/06/26 06:37:07 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
# include "pager.h"
# include "btree.h"
................................................................................
  }
  for(i=0; i<sizeof(aKey)/sizeof(aKey[0]); i++){
    if( sqlite3StrICmp(z,aKey[i].zWord)==0 ) return aKey[i].val;
  }
  return 1;
}









































/*
** Check to see if zRight and zLeft refer to a pragma that queries
** or changes one of the flags in db->flags.  Return 1 if so and 0 if not.
** Also, implement the pragma.
*/
static int flagPragma(Parse *pParse, const char *zLeft, const char *zRight){
  static const struct {
................................................................................
}

/*
** Process a pragma statement.  
**
** Pragmas are of this form:
**
**      PRAGMA [database.]id [= value]
**
** The identifier might also be a string.  The value is a string, and
** identifier, or a number.  If minusFlag is true, then the value is
** a number that was preceded by a minus sign.
*/
void sqlite3Pragma(
  Parse *pParse, 
  Token *pId1,        /* First part of [database.]id field */
  Token *pId2,        /* Second part of [database.]id field, or NULL */
  Token *pValue,      /* Token for <value>, or NULL */
  int minusFlag       /* True if a '-' sign preceded <value> */
){
  char *zLeft = 0;       /* Nul-terminated UTF-8 string <id> */
  char *zRight = 0;      /* Nul-terminated UTF-8 string <value>, or NULL */
  const char *zDb = 0;   /* The database name */
  Token *pId;            /* Pointer to <id> token */
  int iDb;               /* Database index for <database> */
  sqlite *db = pParse->db;
  Vdbe *v = sqlite3GetVdbe(pParse);
  if( v==0 ) return;

  /* Interpret the [database.] part of the pragma statement. iDb is the
  ** index of the database this pragma is being applied to in db.aDb[]. */
  iDb = sqlite3TwoPartName(pParse, pId1, pId2, &pId);
  if( iDb<0 ) return;

  zLeft = sqlite3NameFromToken(pId);
  if( minusFlag ){
    zRight = 0;
    sqlite3SetNString(&zRight, "-", 1, pValue->z, pValue->n, 0);
  }else{
    zRight = sqlite3NameFromToken(pValue);
  }

  zDb = ((iDb>0)?db->aDb[iDb].zName:0);
  if( sqlite3AuthCheck(pParse, SQLITE_PRAGMA, zLeft, zRight, zDb) ){
    goto pragma_out;
  }
 
  /*
  **  PRAGMA default_cache_size
  **  PRAGMA default_cache_size=N
  **
................................................................................
  ** database file.  The cache size is actually the absolute value of
  ** this memory location.  The sign of meta-value 2 determines the
  ** synchronous setting.  A negative value means synchronous is off
  ** and a positive value means synchronous is on.
  */
  if( sqlite3StrICmp(zLeft,"default_cache_size")==0 ){
    static VdbeOpList getCacheSize[] = {
      { OP_ReadCookie,  0, 2,        0},  /* 0 */
      { OP_AbsValue,    0, 0,        0},
      { OP_Dup,         0, 0,        0},
      { OP_Integer,     0, 0,        0},
      { OP_Ne,          0, 6,        0},
      { OP_Integer,     0, 0,        0},  /* 5 */
      { OP_Callback,    1, 0,        0},
    };
    int addr;
    if( SQLITE_OK!=sqlite3ReadSchema(pParse->db, &pParse->zErrMsg) ){
      pParse->nErr++;
      goto pragma_out;
    }
    if( !zRight ){
      sqlite3VdbeSetNumCols(v, 1);
      sqlite3VdbeSetColName(v, 0, "cache_size", P3_STATIC);
      addr = sqlite3VdbeAddOpList(v, ArraySize(getCacheSize), getCacheSize);
      sqlite3VdbeChangeP1(v, addr, iDb);
      sqlite3VdbeChangeP1(v, addr+5, MAX_PAGES);
    }else{
      int size = atoi(zRight);
      if( size<0 ) size = -size;
      sqlite3BeginWriteOperation(pParse, 0, iDb);
      sqlite3VdbeAddOp(v, OP_Integer, size, 0);
      sqlite3VdbeAddOp(v, OP_ReadCookie, iDb, 2);
      addr = sqlite3VdbeAddOp(v, OP_Integer, 0, 0);
      sqlite3VdbeAddOp(v, OP_Ge, 0, addr+3);
      sqlite3VdbeAddOp(v, OP_Negative, 0, 0);
      sqlite3VdbeAddOp(v, OP_SetCookie, iDb, 2);
      sqlite3EndWriteOperation(pParse);
      db->aDb[iDb].cache_size = size;
      sqlite3BtreeSetCacheSize(db->aDb[iDb].pBt, db->aDb[iDb].cache_size);
    }
  }else

  /*
  **  PRAGMA cache_size
  **  PRAGMA cache_size=N
  **
................................................................................
    static VdbeOpList getCacheSize[] = {
      { OP_Callback,    1, 0,        0},
    };
    if( SQLITE_OK!=sqlite3ReadSchema(pParse->db, &pParse->zErrMsg) ){
      pParse->nErr++;
      goto pragma_out;
    }
    if( !zRight ){
      int size = db->aDb[iDb].cache_size;
      assert( size>0 );
      sqlite3VdbeAddOp(v, OP_Integer, size, 0);
      sqlite3VdbeSetNumCols(v, 1);
      sqlite3VdbeSetColName(v, 0, "cache_size", P3_STATIC);
      sqlite3VdbeAddOpList(v, ArraySize(getCacheSize), getCacheSize);
    }else{
      int size = atoi(zRight);
      if( size<0 ) size = -size;

      db->aDb[iDb].cache_size = size;
      sqlite3BtreeSetCacheSize(db->aDb[iDb].pBt, db->aDb[iDb].cache_size);




































































    }
  }else

  /*
  **   PRAGMA synchronous
  **   PRAGMA synchronous=OFF|ON|NORMAL|FULL
  **
................................................................................
    static VdbeOpList getSync[] = {
      { OP_Callback,    1, 0,        0},
    };
    if( SQLITE_OK!=sqlite3ReadSchema(pParse->db, &pParse->zErrMsg) ){
      pParse->nErr++;
      goto pragma_out;
    }
    if( !zRight ){
      sqlite3VdbeSetNumCols(v, 1);
      sqlite3VdbeSetColName(v, 0, "synchronous", P3_STATIC);
      sqlite3VdbeAddOp(v, OP_Integer, db->aDb[iDb].safety_level-1, 0);
      sqlite3VdbeAddOpList(v, ArraySize(getSync), getSync);
    }else{
      if( !db->autoCommit ){
        sqlite3ErrorMsg(pParse, 
            "Safety level may not be changed inside a transaction");
      }else{
        db->aDb[iDb].safety_level = getSafetyLevel(zRight)+1;



        sqlite3BtreeSetSafetyLevel(db->aDb[iDb].pBt,db->aDb[iDb].safety_level);
      }
    }
  }else

#ifndef NDEBUG
  if( sqlite3StrICmp(zLeft, "trigger_overhead_test")==0 ){
    if( getBoolean(zRight) ){
      sqlite3_always_code_trigger_setup = 1;
................................................................................
  }else
#endif

  if( flagPragma(pParse, zLeft, zRight) ){
    /* The flagPragma() call also generates any necessary code */
  }else

  /*
  **   PRAGMA table_info(<table>)
  **
  ** Return a single row for each column of the named table. The columns of
  ** the returned data set are:
  **
  ** cid:        Column id (numbered from left to right, starting at 0)
  ** name:       Column name
  ** type:       Column declaration type.
  ** notnull:    True if 'NOT NULL' is part of column declaration
  ** dflt_value: The default value for the column, if any.
  */
  if( sqlite3StrICmp(zLeft, "table_info")==0 ){
    Table *pTab;
    if( SQLITE_OK!=sqlite3ReadSchema(pParse->db, &pParse->zErrMsg) ){
      pParse->nErr++;
      goto pragma_out;
    }
    pTab = sqlite3FindTable(db, zRight, 0);
................................................................................
      assert( db->aDb[i].zName!=0 );
      sqlite3VdbeAddOp(v, OP_Integer, i, 0);
      sqlite3VdbeOp3(v, OP_String8, 0, 0, db->aDb[i].zName, 0);
      sqlite3VdbeOp3(v, OP_String8, 0, 0,
           sqlite3BtreeGetFilename(db->aDb[i].pBt), 0);
      sqlite3VdbeAddOp(v, OP_Callback, 3, 0);
    }





























































  }else

#ifndef NDEBUG
  if( sqlite3StrICmp(zLeft, "parser_trace")==0 ){
    extern void sqlite3ParserTrace(FILE*, char *);
    if( SQLITE_OK!=sqlite3ReadSchema(pParse->db, &pParse->zErrMsg) ){
      pParse->nErr++;
................................................................................
      { "UTF16be",  SQLITE_UTF16BE     },
      { "UTF-16",   0 /* Filled in at run-time */ },
      { "UTF16",    0 /* Filled in at run-time */ },
      { 0, 0 }
    };
    struct EncName *pEnc;
    encnames[6].enc = encnames[7].enc = SQLITE_UTF16NATIVE;
    if( !zRight ){    /* "PRAGMA encoding" */
      if( SQLITE_OK!=sqlite3ReadSchema(pParse->db, &pParse->zErrMsg) ){
        pParse->nErr++;
        goto pragma_out;
      }
      sqlite3VdbeSetNumCols(v, 1);
      sqlite3VdbeSetColName(v, 0, "encoding", P3_STATIC);
      sqlite3VdbeAddOp(v, OP_String8, 0, 0);

Changes to src/sqliteInt.h.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
..
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
...
286
287
288
289
290
291
292


293
294
295
296
297
298
299
...
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
...
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
....
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
**    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.
**
*************************************************************************
** Internal interface definitions for SQLite.
**
** @(#) $Id: sqliteInt.h,v 1.299 2004/06/22 12:13:55 drh Exp $
*/
#ifndef _SQLITEINT_H_
#define _SQLITEINT_H_

#include "config.h"
#include "sqlite3.h"
#include "hash.h"
................................................................................
** in order to support the main database file (0) and the file used to
** hold temporary tables (1).  And it must be less than 32 because
** we use a bitmask of databases with a u32 in places (for example
** the Parse.cookieMask field).
*/
#define MAX_ATTACHED 10

/*
** The next macro is used to determine where TEMP tables and indices
** are stored.  Possible values:
**
**   0    Always use a temporary files
**   1    Use a file unless overridden by "PRAGMA temp_store"
**   2    Use memory unless overridden by "PRAGMA temp_store"
**   3    Always use memory
*/
#ifndef TEMP_STORE
# define TEMP_STORE 1
#endif

/*
** When building SQLite for embedded systems where memory is scarce,
** you can define one or more of the following macros to omit extra
** features of the library and thus keep the size of the library to
** a minimum.
*/
/* #define SQLITE_OMIT_AUTHORIZATION  1 */
................................................................................
  int schema_cookie;   /* Database schema version number for this file */
  Hash tblHash;        /* All tables indexed by name */
  Hash idxHash;        /* All (named) indices indexed by name */
  Hash trigHash;       /* All triggers indexed by name */
  Hash aFKey;          /* Foreign keys indexed by to-table */
  u8 inTrans;          /* 0: not writable.  1: Transaction.  2: Checkpoint */
  u16 flags;           /* Flags associated with this database */


  void *pAux;          /* Auxiliary data.  Usually NULL */
  void (*xFreeAux)(void*);  /* Routine to free pAux */
};

/*
** These macros can be used to test, set, or clear bits in the 
** Db.flags field.
................................................................................
  int (*xFunc)(void *,int);  /* The busy callback */
  void *pArg;                /* First arg to busy callback */
};

/*
** Each database is an instance of the following structure.
**
** The sqlite.temp_store determines where temporary database files
** are stored.  If 1, then a file is created to hold those tables.  If
** 2, then they are held in memory.  0 means use the default value in
** the TEMP_STORE macro.
**
** The sqlite.lastRowid records the last insert rowid generated by an
** insert statement.  Inserts on views do not affect its value.  Each
** trigger has its own context, so that lastRowid can be updated inside
** triggers as usual.  The previous value will be restored once the trigger
** exits.  Upon entering a before or instead of trigger, lastRowid is no
** longer (since after version 2.8.12) reset to -1.
**
................................................................................
*/
struct sqlite {
  int nDb;                      /* Number of backends currently in use */
  Db *aDb;                      /* All backends */
  Db aDbStatic[2];              /* Static space for the 2 default backends */
  int flags;                    /* Miscellanous flags. See below */
  u8 file_format;               /* What file format version is this database? */
  u8 safety_level;              /* How aggressive at synching data to disk */
  u8 temp_store;                /* 1=file, 2=memory, 0=compile-time default */
  int cache_size;               /* Number of pages to use in the cache */
  int nTable;                   /* Number of tables in the database */
  BusyHandler busyHandler;      /* Busy callback */
  void *pCommitArg;             /* Argument to xCommitCallback() */   
  int (*xCommitCallback)(void*);/* Invoked at every commit. */
  Hash aFunc;                   /* All functions that can be in SQL exprs */
  Hash aCollSeq;                /* All collating sequences */
  CollSeq *pDfltColl;           /* The default collating sequence (BINARY) */
................................................................................
Expr *sqlite3Expr(int, Expr*, Expr*, Token*);
void sqlite3ExprSpan(Expr*,Token*,Token*);
Expr *sqlite3ExprFunction(ExprList*, Token*);
void sqlite3ExprDelete(Expr*);
ExprList *sqlite3ExprListAppend(ExprList*,Expr*,Token*);
void sqlite3ExprListDelete(ExprList*);
int sqlite3Init(sqlite*, char**);
void sqlite3Pragma(Parse*,Token*,Token*,int);
void sqlite3ResetInternalSchema(sqlite*, int);
void sqlite3BeginParse(Parse*,int);
void sqlite3RollbackInternalChanges(sqlite*);
void sqlite3CommitInternalChanges(sqlite*);
Table *sqlite3ResultSetOfSelect(Parse*,char*,Select*);
void sqlite3OpenMasterTable(Vdbe *v, int);
void sqlite3StartTable(Parse*,Token*,Token*,Token*,int,int);







|







 







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







 







>
>







 







<
<
<
<
<







 







<
<
<







 







|







7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
..
63
64
65
66
67
68
69













70
71
72
73
74
75
76
...
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
...
320
321
322
323
324
325
326





327
328
329
330
331
332
333
...
349
350
351
352
353
354
355



356
357
358
359
360
361
362
....
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
**    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.
**
*************************************************************************
** Internal interface definitions for SQLite.
**
** @(#) $Id: sqliteInt.h,v 1.300 2004/06/26 06:37:07 danielk1977 Exp $
*/
#ifndef _SQLITEINT_H_
#define _SQLITEINT_H_

#include "config.h"
#include "sqlite3.h"
#include "hash.h"
................................................................................
** in order to support the main database file (0) and the file used to
** hold temporary tables (1).  And it must be less than 32 because
** we use a bitmask of databases with a u32 in places (for example
** the Parse.cookieMask field).
*/
#define MAX_ATTACHED 10














/*
** When building SQLite for embedded systems where memory is scarce,
** you can define one or more of the following macros to omit extra
** features of the library and thus keep the size of the library to
** a minimum.
*/
/* #define SQLITE_OMIT_AUTHORIZATION  1 */
................................................................................
  int schema_cookie;   /* Database schema version number for this file */
  Hash tblHash;        /* All tables indexed by name */
  Hash idxHash;        /* All (named) indices indexed by name */
  Hash trigHash;       /* All triggers indexed by name */
  Hash aFKey;          /* Foreign keys indexed by to-table */
  u8 inTrans;          /* 0: not writable.  1: Transaction.  2: Checkpoint */
  u16 flags;           /* Flags associated with this database */
  u8 safety_level;     /* How aggressive at synching data to disk */
  int cache_size;      /* Number of pages to use in the cache */
  void *pAux;          /* Auxiliary data.  Usually NULL */
  void (*xFreeAux)(void*);  /* Routine to free pAux */
};

/*
** These macros can be used to test, set, or clear bits in the 
** Db.flags field.
................................................................................
  int (*xFunc)(void *,int);  /* The busy callback */
  void *pArg;                /* First arg to busy callback */
};

/*
** Each database is an instance of the following structure.
**





** The sqlite.lastRowid records the last insert rowid generated by an
** insert statement.  Inserts on views do not affect its value.  Each
** trigger has its own context, so that lastRowid can be updated inside
** triggers as usual.  The previous value will be restored once the trigger
** exits.  Upon entering a before or instead of trigger, lastRowid is no
** longer (since after version 2.8.12) reset to -1.
**
................................................................................
*/
struct sqlite {
  int nDb;                      /* Number of backends currently in use */
  Db *aDb;                      /* All backends */
  Db aDbStatic[2];              /* Static space for the 2 default backends */
  int flags;                    /* Miscellanous flags. See below */
  u8 file_format;               /* What file format version is this database? */



  int nTable;                   /* Number of tables in the database */
  BusyHandler busyHandler;      /* Busy callback */
  void *pCommitArg;             /* Argument to xCommitCallback() */   
  int (*xCommitCallback)(void*);/* Invoked at every commit. */
  Hash aFunc;                   /* All functions that can be in SQL exprs */
  Hash aCollSeq;                /* All collating sequences */
  CollSeq *pDfltColl;           /* The default collating sequence (BINARY) */
................................................................................
Expr *sqlite3Expr(int, Expr*, Expr*, Token*);
void sqlite3ExprSpan(Expr*,Token*,Token*);
Expr *sqlite3ExprFunction(ExprList*, Token*);
void sqlite3ExprDelete(Expr*);
ExprList *sqlite3ExprListAppend(ExprList*,Expr*,Token*);
void sqlite3ExprListDelete(ExprList*);
int sqlite3Init(sqlite*, char**);
void sqlite3Pragma(Parse*,Token*,Token*,Token*,int);
void sqlite3ResetInternalSchema(sqlite*, int);
void sqlite3BeginParse(Parse*,int);
void sqlite3RollbackInternalChanges(sqlite*);
void sqlite3CommitInternalChanges(sqlite*);
Table *sqlite3ResultSetOfSelect(Parse*,char*,Select*);
void sqlite3OpenMasterTable(Vdbe *v, int);
void sqlite3StartTable(Parse*,Token*,Token*,Token*,int,int);

Changes to test/pragma.test.

8
9
10
11
12
13
14
15
16
17
18










19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105







106

107
108
109
















110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127

128


129
130
131
132
133
134

135
136

137
138
139
140
141
142
143
144
145
146

147
148
149
150
151
152
153
154
155

156
157
158
159
160
161

162
163
164
165

166
167
168
169
170
171
172
...
188
189
190
191
192
193
194
195
196
197
198
199
200

201
202
203
204
205
206
207
208

209
210
211
212


213
214
215
216
217
218



219
220
221
222
223



224
225
226
227
228
229
230


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




247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269




270
271
272
273
274
275
276
277
278


279
280
281

282
283
284
285
286
287


288
289

290
291
292

293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.
#
# This file implements tests for the PRAGMA command.
#
# $Id: pragma.test,v 1.13 2004/06/19 00:16:31 drh Exp $

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











# Delete the preexisting database to avoid the special setup
# that the "all.test" script does.
#
db close
file delete test.db
set DB [sqlite3 db test.db]

do_test pragma-1.1 {
  execsql {
    PRAGMA cache_size;
    PRAGMA default_cache_size;
    PRAGMA synchronous;
    PRAGMA default_synchronous;
  }
} {2000 2000 1 1}
do_test pragma-1.2 {
  execsql {
    PRAGMA cache_size=1234;
    PRAGMA cache_size;
    PRAGMA default_cache_size;
    PRAGMA synchronous;
    PRAGMA default_synchronous;
  }
} {1234 2000 1 1}
do_test pragma-1.3 {
  db close
  sqlite3 db test.db
  execsql {
    PRAGMA cache_size;
    PRAGMA default_cache_size;
    PRAGMA synchronous;
    PRAGMA default_synchronous;
  }
} {2000 2000 1 1}
do_test pragma-1.4 {
  execsql {
    PRAGMA synchronous=OFF;
    PRAGMA cache_size;
    PRAGMA default_cache_size;
    PRAGMA synchronous;
    PRAGMA default_synchronous;
  }
} {2000 2000 0 1}
do_test pragma-1.5 {
  execsql {
    PRAGMA cache_size=4321;
    PRAGMA cache_size;
    PRAGMA default_cache_size;
    PRAGMA synchronous;
    PRAGMA default_synchronous;
  }
} {4321 2000 0 1}
do_test pragma-1.6 {
  execsql {
    PRAGMA synchronous=ON;
    PRAGMA cache_size;
    PRAGMA default_cache_size;
    PRAGMA synchronous;
    PRAGMA default_synchronous;
  }
} {4321 2000 1 1}
do_test pragma-1.7 {
  db close
  sqlite3 db test.db
  execsql {
    PRAGMA cache_size;
    PRAGMA default_cache_size;
    PRAGMA synchronous;
    PRAGMA default_synchronous;
  }
} {2000 2000 1 1}
do_test pragma-1.8 {
  execsql {
    PRAGMA default_synchronous=OFF;
    PRAGMA cache_size;
    PRAGMA default_cache_size;
    PRAGMA synchronous;
    PRAGMA default_synchronous;
  }
} {2000 2000 0 0}
do_test pragma-1.9 {
  execsql {
    PRAGMA default_cache_size=123;
    PRAGMA cache_size;
    PRAGMA default_cache_size;
    PRAGMA synchronous;







    PRAGMA default_synchronous;

  }
} {123 123 0 0}
do_test pragma-1.10 {
















  db close
  set ::DB [sqlite3 db test.db]
  execsql {
    PRAGMA cache_size;
    PRAGMA default_cache_size;
    PRAGMA synchronous;
    PRAGMA default_synchronous;
  }
} {123 123 0 0}
do_test pragma-1.11 {
  execsql {
    PRAGMA synchronous=NORMAL;
    PRAGMA cache_size;
    PRAGMA default_cache_size;
    PRAGMA synchronous;
    PRAGMA default_synchronous;
  }
} {123 123 1 0}

do_test pragma-1.12 {


  execsql {
    PRAGMA synchronous=FULL;
    PRAGMA cache_size;
    PRAGMA default_cache_size;
    PRAGMA synchronous;
    PRAGMA default_synchronous;

  }
} {123 123 2 0}

do_test pragma-1.13 {
  db close
  set ::DB [sqlite3 db test.db]
  execsql {
    PRAGMA cache_size;
    PRAGMA default_cache_size;
    PRAGMA synchronous;
    PRAGMA default_synchronous;
  }
} {123 123 0 0}

do_test pragma-1.14 {
  execsql {
    PRAGMA default_synchronous=FULL;
    PRAGMA cache_size;
    PRAGMA default_cache_size;
    PRAGMA synchronous;
    PRAGMA default_synchronous;
  }
} {123 123 2 2}

do_test pragma-1.15 {
  db close
  set ::DB [sqlite3 db test.db]
  execsql {
    PRAGMA cache_size;
    PRAGMA default_cache_size;

    PRAGMA synchronous;
    PRAGMA default_synchronous;
  }
} {123 123 2 2}


# Construct a corrupted index and make sure the integrity_check
# pragma finds it.
#
if {![sqlite3 -has-codec]} {
do_test pragma-3.1 {
  execsql {
................................................................................
  btree_delete $c
  btree_commit $db
  btree_close $db
  execsql {PRAGMA integrity_check}
} {{rowid 1 missing from index i2} {wrong # of entries in index i2}}
}; # endif has-codec

# Test the temp_store and default_temp_store pragmas
#
do_test pragma-4.2 {
  execsql {
    PRAGMA temp_store='default';
    PRAGMA temp_store;

  }
} {0}
do_test pragma-4.3 {
  execsql {
    PRAGMA temp_store='file';
    PRAGMA temp_store;
  }
} {1}

do_test pragma-4.4 {
  execsql {
    PRAGMA temp_store='memory';
    PRAGMA temp_store;


  }
} {2}
do_test pragma-4.5 {
  execsql {
    PRAGMA default_temp_store='default';
    PRAGMA default_temp_store;



  }
} {0}
do_test pragma-4.6 {
  execsql {
    PRAGMA temp_store;



  }
} {2}
do_test pragma-4.7 {
  db close
  sqlite3 db test.db
  execsql {
    PRAGMA temp_store;


  }
} {0}
do_test pragma-4.8 {
  execsql {
    PRAGMA default_temp_store;
  }
} {0}
do_test pragma-4.9 {
  execsql {
    PRAGMA default_temp_store='file';
    PRAGMA default_temp_store;
  }
} {1}
do_test pragma-4.10 {
  execsql {
    PRAGMA temp_store;




  }
} {0}
do_test pragma-4.11 {
  db close
  sqlite3 db test.db
  execsql {
    PRAGMA temp_store;
  }
} {1}
do_test pragma-4.12 {
  execsql {
    PRAGMA default_temp_store;
  }
} {1}
do_test pragma-4.13 {
  execsql {
    PRAGMA default_temp_store='memory';
    PRAGMA default_temp_store;
  }
} {2}
do_test pragma-4.14 {
  execsql {
    PRAGMA temp_store;




  }
} {1}
do_test pragma-4.15 {
  db close
  sqlite3 db test.db
  execsql {
    PRAGMA temp_store;
  }
} {2}


do_test pragma-4.16 {
  execsql {
    PRAGMA default_temp_store;

  }
} {2}
do_test pragma-4.17 {
  execsql {
    PRAGMA temp_store='file';
    PRAGMA temp_store


  }
} {1}

do_test pragma-4.18 {
  execsql {
    PRAGMA default_temp_store

  }
} {2}
do_test pragma-4.19 {
  db close
  sqlite3 db test.db
  execsql {
    PRAGMA temp_store
  }
} {2}

# Changing the TEMP_STORE deletes any existing temporary tables
#
do_test pragma-4.20 {
  execsql {SELECT name FROM sqlite_temp_master}
} {}
do_test pragma-4.21 {
  execsql {
    CREATE TEMP TABLE test1(a,b,c);
    SELECT name FROM sqlite_temp_master;
  }
} {test1}
do_test pragma-4.22 {
  execsql {
    PRAGMA temp_store='file';
    SELECT name FROM sqlite_temp_master;
  }
} {}
do_test pragma-4.23 {
  execsql {
    CREATE TEMP TABLE test1(a,b,c);
    SELECT name FROM sqlite_temp_master;
  }
} {test1}
do_test pragma-4.24 {
  execsql {
    PRAGMA temp_store='memory';
    SELECT name FROM sqlite_temp_master;
  }
} {}
do_test pragma-4.25 {
  catchsql {
    BEGIN;
    PRAGMA temp_store='default';
    COMMIT;
  }
} {1 {temporary storage cannot be changed from within a transaction}}
catchsql {COMMIT}

finish_test







|



>
>
>
>
>
>
>
>
>
>













<

|






<

|







<

|






<

|






<

|






<

|







<

|


<
<
<
<
<
<
<
<
<




>
>
>
>
>
>
>
|
>

|

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






<

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

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

<
<
|
<
|
<
>
|

|
<
<
|
|
|
<
>
|
<
<

<
<
>
|
|
|
<
>







 







<
<
|

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

<
<
>
>
|
|
|

<
<
>
>
>
|
|
|

<
>
>
>
|
|
|
<
<

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

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

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

<
>
|

|
|
<
<
>
>
|
<
>
|

<
>
|

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

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41

42
43
44
45
46
47
48
49

50
51
52
53
54
55
56
57
58

59
60
61
62
63
64
65
66

67
68
69
70
71
72
73
74

75
76
77
78
79
80
81
82

83
84
85
86
87
88
89
90
91

92
93
94
95









96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133

134
135







136

137
138
139
140
141





142
143

144
145


146


147

148

149
150
151
152


153
154
155

156
157


158


159
160
161
162

163
164
165
166
167
168
169
170
...
186
187
188
189
190
191
192


193
194


195
196
197




198

199
200
201


202
203
204
205
206
207


208
209
210
211
212
213
214

215
216
217
218
219
220


221

222
223
224











225
226
227

228
229
230
231
232


















233
234
235

236
237
238
239
240
241





242

243
244
245
246

247
248
249
250
251


252
253
254

255
256
257

258
259
260





261








































262
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.
#
# This file implements tests for the PRAGMA command.
#
# $Id: pragma.test,v 1.14 2004/06/26 06:37:07 danielk1977 Exp $

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

# Test organization:
#
# pragma-1.*: Test cache_size, default_cache_size and synchronous on main db.
# pragma-2.*: Test synchronous on attached db.
# pragma-3.*: Test detection of table/index inconsistency by integrity_check.
# pragma-4.*: Test cache_size and default_cache_size on attached db.
# pragma-5.*: Test that pragma synchronous may not be used inside of a
#             transaction.
#

# Delete the preexisting database to avoid the special setup
# that the "all.test" script does.
#
db close
file delete test.db
set DB [sqlite3 db test.db]

do_test pragma-1.1 {
  execsql {
    PRAGMA cache_size;
    PRAGMA default_cache_size;
    PRAGMA synchronous;

  }
} {2000 2000 2}
do_test pragma-1.2 {
  execsql {
    PRAGMA cache_size=1234;
    PRAGMA cache_size;
    PRAGMA default_cache_size;
    PRAGMA synchronous;

  }
} {1234 2000 2}
do_test pragma-1.3 {
  db close
  sqlite3 db test.db
  execsql {
    PRAGMA cache_size;
    PRAGMA default_cache_size;
    PRAGMA synchronous;

  }
} {2000 2000 2}
do_test pragma-1.4 {
  execsql {
    PRAGMA synchronous=OFF;
    PRAGMA cache_size;
    PRAGMA default_cache_size;
    PRAGMA synchronous;

  }
} {2000 2000 0}
do_test pragma-1.5 {
  execsql {
    PRAGMA cache_size=4321;
    PRAGMA cache_size;
    PRAGMA default_cache_size;
    PRAGMA synchronous;

  }
} {4321 2000 0}
do_test pragma-1.6 {
  execsql {
    PRAGMA synchronous=ON;
    PRAGMA cache_size;
    PRAGMA default_cache_size;
    PRAGMA synchronous;

  }
} {4321 2000 1}
do_test pragma-1.7 {
  db close
  sqlite3 db test.db
  execsql {
    PRAGMA cache_size;
    PRAGMA default_cache_size;
    PRAGMA synchronous;

  }
} {2000 2000 2}
do_test pragma-1.8 {
  execsql {









    PRAGMA default_cache_size=123;
    PRAGMA cache_size;
    PRAGMA default_cache_size;
    PRAGMA synchronous;
  }
} {123 123 2}
do_test pragma-1.9 {
  db close
  set ::DB [sqlite3 db test.db]
  execsql {
    PRAGMA cache_size;
    PRAGMA default_cache_size;
    PRAGMA synchronous;
  }
} {123 123 2}
do_test pragma-1.10 {
  execsql {
    PRAGMA synchronous=NORMAL;
    PRAGMA cache_size;
    PRAGMA default_cache_size;
    PRAGMA synchronous;
  }
} {123 123 1}
do_test pragma-1.11 {
  execsql {
    PRAGMA synchronous=FULL;
    PRAGMA cache_size;
    PRAGMA default_cache_size;
    PRAGMA synchronous;
  }
} {123 123 2}
do_test pragma-1.12 {
  db close
  set ::DB [sqlite3 db test.db]
  execsql {
    PRAGMA cache_size;
    PRAGMA default_cache_size;
    PRAGMA synchronous;

  }
} {123 123 2}









# Test modifying the safety_level of an attached database.
do_test pragma-2.1 {
  file delete -force test2.db
  file delete -force test2.db-journal
  execsql {





    ATTACH 'test2.db' AS aux;
  } 

} {}
do_test pragma-2.2 {


  execsql {


    pragma aux.synchronous;

  } 

} {2}
do_test pragma-2.3 {
  execsql {
    pragma aux.synchronous = OFF;


    pragma aux.synchronous;
    pragma synchronous;
  } 

} {0 2}
do_test pragma-2.4 {


  execsql {


    pragma aux.synchronous = ON;
    pragma synchronous;
    pragma aux.synchronous;
  } 

} {2 1}

# Construct a corrupted index and make sure the integrity_check
# pragma finds it.
#
if {![sqlite3 -has-codec]} {
do_test pragma-3.1 {
  execsql {
................................................................................
  btree_delete $c
  btree_commit $db
  btree_close $db
  execsql {PRAGMA integrity_check}
} {{rowid 1 missing from index i2} {wrong # of entries in index i2}}
}; # endif has-codec



do_test pragma-3.3 {
  execsql {


    DROP INDEX i2;
  } 
} {}






# Test modifying the cache_size of an attached database.
do_test pragma-4.1 {
  execsql {


    pragma aux.cache_size;
    pragma aux.default_cache_size;
  } 
} {2000 2000}
do_test pragma-4.2 {
  execsql {


    pragma aux.cache_size = 50;
    pragma aux.cache_size;
    pragma aux.default_cache_size;
  } 
} {50 2000}
do_test pragma-4.3 {
  execsql {

    pragma aux.default_cache_size = 456;
    pragma aux.cache_size;
    pragma aux.default_cache_size;
  } 
} {456 456}
do_test pragma-4.4 {


  execsql {

    pragma cache_size;
    pragma default_cache_size;
  } 











} {123 123}
do_test pragma-4.5 {
  execsql {

    DETACH aux;
    ATTACH 'test3.db' AS aux;
    pragma aux.cache_size;
    pragma aux.default_cache_size;
  } 


















} {2000 2000}
do_test pragma-4.6 {
  execsql {

    DETACH aux;
    ATTACH 'test2.db' AS aux;
    pragma aux.cache_size;
    pragma aux.default_cache_size;
  } 
} {456 456}







# Test that modifying the sync-level in the middle of a transaction is
# disallowed.
do_test pragma-5.0 {
  execsql {

    pragma synchronous;
  } 
} {2}
do_test pragma-5.1 {
  catchsql {


    BEGIN;
    pragma synchronous = OFF;
  } 

} {1 {Safety level may not be changed inside a transaction}}
do_test pragma-5.2 {
  execsql {

    pragma synchronous;
  } 
} {2}














































finish_test