~ubuntu-branches/ubuntu/intrepid/digikam/intrepid

« back to all changes in this revision

Viewing changes to digikam/sqlite/pragma.c

  • Committer: Bazaar Package Importer
  • Author(s): Mark Purcell
  • Date: 2008-07-17 20:25:39 UTC
  • mfrom: (1.3.2 upstream) (37 hardy)
  • mto: This revision was merged to the branch mainline in revision 39.
  • Revision ID: james.westby@ubuntu.com-20080717202539-1bw3w3nrsso7yj4z
* New upstream release
  - digiKam 0.9.4 Release Plan (KDE3) ~ 13 July 08 (Closes: #490144)
* DEB_CONFIGURE_EXTRA_FLAGS := --without-included-sqlite3
* Debhelper compatibility level V7
* Install pixmaps in debian/*.install
* Add debian/digikam.lintian-overrides

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
** 2003 April 6
3
 
**
4
 
** The author disclaims copyright to this source code.  In place of
5
 
** a legal notice, here is a blessing:
6
 
**
7
 
**    May you do good and not evil.
8
 
**    May you find forgiveness for yourself and forgive others.
9
 
**    May you share freely, never taking more than you give.
10
 
**
11
 
*************************************************************************
12
 
** This file contains code used to implement the PRAGMA command.
13
 
**
14
 
** $Id: pragma.c 326789 2004-07-07 21:25:56Z pahlibar $
15
 
*/
16
 
#include "sqliteInt.h"
17
 
#include <ctype.h>
18
 
 
19
 
/*
20
 
** Interpret the given string as a boolean value.
21
 
*/
22
 
static int getBoolean(const char *z){
23
 
  static char *azTrue[] = { "yes", "on", "true" };
24
 
  int i;
25
 
  if( z[0]==0 ) return 0;
26
 
  if( isdigit(z[0]) || (z[0]=='-' && isdigit(z[1])) ){
27
 
    return atoi(z);
28
 
  }
29
 
  for(i=0; i<sizeof(azTrue)/sizeof(azTrue[0]); i++){
30
 
    if( sqliteStrICmp(z,azTrue[i])==0 ) return 1;
31
 
  }
32
 
  return 0;
33
 
}
34
 
 
35
 
/*
36
 
** Interpret the given string as a safety level.  Return 0 for OFF,
37
 
** 1 for ON or NORMAL and 2 for FULL.  Return 1 for an empty or 
38
 
** unrecognized string argument.
39
 
**
40
 
** Note that the values returned are one less that the values that
41
 
** should be passed into sqliteBtreeSetSafetyLevel().  The is done
42
 
** to support legacy SQL code.  The safety level used to be boolean
43
 
** and older scripts may have used numbers 0 for OFF and 1 for ON.
44
 
*/
45
 
static int getSafetyLevel(char *z){
46
 
  static const struct {
47
 
    const char *zWord;
48
 
    int val;
49
 
  } aKey[] = {
50
 
    { "no",    0 },
51
 
    { "off",   0 },
52
 
    { "false", 0 },
53
 
    { "yes",   1 },
54
 
    { "on",    1 },
55
 
    { "true",  1 },
56
 
    { "full",  2 },
57
 
  };
58
 
  int i;
59
 
  if( z[0]==0 ) return 1;
60
 
  if( isdigit(z[0]) || (z[0]=='-' && isdigit(z[1])) ){
61
 
    return atoi(z);
62
 
  }
63
 
  for(i=0; i<sizeof(aKey)/sizeof(aKey[0]); i++){
64
 
    if( sqliteStrICmp(z,aKey[i].zWord)==0 ) return aKey[i].val;
65
 
  }
66
 
  return 1;
67
 
}
68
 
 
69
 
/*
70
 
** Interpret the given string as a temp db location. Return 1 for file
71
 
** backed temporary databases, 2 for the Red-Black tree in memory database
72
 
** and 0 to use the compile-time default.
73
 
*/
74
 
static int getTempStore(const char *z){
75
 
  if( z[0]>='0' && z[0]<='2' ){
76
 
    return z[0] - '0';
77
 
  }else if( sqliteStrICmp(z, "file")==0 ){
78
 
    return 1;
79
 
  }else if( sqliteStrICmp(z, "memory")==0 ){
80
 
    return 2;
81
 
  }else{
82
 
    return 0;
83
 
  }
84
 
}
85
 
 
86
 
/*
87
 
** If the TEMP database is open, close it and mark the database schema
88
 
** as needing reloading.  This must be done when using the TEMP_STORE
89
 
** or DEFAULT_TEMP_STORE pragmas.
90
 
*/
91
 
static int changeTempStorage(Parse *pParse, const char *zStorageType){
92
 
  int ts = getTempStore(zStorageType);
93
 
  sqlite *db = pParse->db;
94
 
  if( db->temp_store==ts ) return SQLITE_OK;
95
 
  if( db->aDb[1].pBt!=0 ){
96
 
    if( db->flags & SQLITE_InTrans ){
97
 
      sqliteErrorMsg(pParse, "temporary storage cannot be changed "
98
 
        "from within a transaction");
99
 
      return SQLITE_ERROR;
100
 
    }
101
 
    sqliteBtreeClose(db->aDb[1].pBt);
102
 
    db->aDb[1].pBt = 0;
103
 
    sqliteResetInternalSchema(db, 0);
104
 
  }
105
 
  db->temp_store = ts;
106
 
  return SQLITE_OK;
107
 
}
108
 
 
109
 
/*
110
 
** Check to see if zRight and zLeft refer to a pragma that queries
111
 
** or changes one of the flags in db->flags.  Return 1 if so and 0 if not.
112
 
** Also, implement the pragma.
113
 
*/
114
 
static int flagPragma(Parse *pParse, const char *zLeft, const char *zRight){
115
 
  static const struct {
116
 
    const char *zName;  /* Name of the pragma */
117
 
    int mask;           /* Mask for the db->flags value */
118
 
  } aPragma[] = {
119
 
    { "vdbe_trace",               SQLITE_VdbeTrace     },
120
 
    { "full_column_names",        SQLITE_FullColNames  },
121
 
    { "short_column_names",       SQLITE_ShortColNames },
122
 
    { "show_datatypes",           SQLITE_ReportTypes   },
123
 
    { "count_changes",            SQLITE_CountRows     },
124
 
    { "empty_result_callbacks",   SQLITE_NullCallback  },
125
 
  };
126
 
  int i;
127
 
  for(i=0; i<sizeof(aPragma)/sizeof(aPragma[0]); i++){
128
 
    if( sqliteStrICmp(zLeft, aPragma[i].zName)==0 ){
129
 
      sqlite *db = pParse->db;
130
 
      Vdbe *v;
131
 
      if( strcmp(zLeft,zRight)==0 && (v = sqliteGetVdbe(pParse))!=0 ){
132
 
        sqliteVdbeOp3(v, OP_ColumnName, 0, 1, aPragma[i].zName, P3_STATIC);
133
 
        sqliteVdbeOp3(v, OP_ColumnName, 1, 0, "boolean", P3_STATIC);
134
 
        sqliteVdbeCode(v, OP_Integer, (db->flags & aPragma[i].mask)!=0, 0,
135
 
                          OP_Callback, 1, 0,
136
 
                          0);
137
 
      }else if( getBoolean(zRight) ){
138
 
        db->flags |= aPragma[i].mask;
139
 
      }else{
140
 
        db->flags &= ~aPragma[i].mask;
141
 
      }
142
 
      return 1;
143
 
    }
144
 
  }
145
 
  return 0;
146
 
}
147
 
 
148
 
/*
149
 
** Process a pragma statement.  
150
 
**
151
 
** Pragmas are of this form:
152
 
**
153
 
**      PRAGMA id = value
154
 
**
155
 
** The identifier might also be a string.  The value is a string, and
156
 
** identifier, or a number.  If minusFlag is true, then the value is
157
 
** a number that was preceded by a minus sign.
158
 
*/
159
 
void sqlitePragma(Parse *pParse, Token *pLeft, Token *pRight, int minusFlag){
160
 
  char *zLeft = 0;
161
 
  char *zRight = 0;
162
 
  sqlite *db = pParse->db;
163
 
  Vdbe *v = sqliteGetVdbe(pParse);
164
 
  if( v==0 ) return;
165
 
 
166
 
  zLeft = sqliteStrNDup(pLeft->z, pLeft->n);
167
 
  sqliteDequote(zLeft);
168
 
  if( minusFlag ){
169
 
    zRight = 0;
170
 
    sqliteSetNString(&zRight, "-", 1, pRight->z, pRight->n, 0);
171
 
  }else{
172
 
    zRight = sqliteStrNDup(pRight->z, pRight->n);
173
 
    sqliteDequote(zRight);
174
 
  }
175
 
  if( sqliteAuthCheck(pParse, SQLITE_PRAGMA, zLeft, zRight, 0) ){
176
 
    sqliteFree(zLeft);
177
 
    sqliteFree(zRight);
178
 
    return;
179
 
  }
180
 
 
181
 
  /*
182
 
  **  PRAGMA default_cache_size
183
 
  **  PRAGMA default_cache_size=N
184
 
  **
185
 
  ** The first form reports the current persistent setting for the
186
 
  ** page cache size.  The value returned is the maximum number of
187
 
  ** pages in the page cache.  The second form sets both the current
188
 
  ** page cache size value and the persistent page cache size value
189
 
  ** stored in the database file.
190
 
  **
191
 
  ** The default cache size is stored in meta-value 2 of page 1 of the
192
 
  ** database file.  The cache size is actually the absolute value of
193
 
  ** this memory location.  The sign of meta-value 2 determines the
194
 
  ** synchronous setting.  A negative value means synchronous is off
195
 
  ** and a positive value means synchronous is on.
196
 
  */
197
 
  if( sqliteStrICmp(zLeft,"default_cache_size")==0 ){
198
 
    static VdbeOpList getCacheSize[] = {
199
 
      { OP_ReadCookie,  0, 2,        0},
200
 
      { OP_AbsValue,    0, 0,        0},
201
 
      { OP_Dup,         0, 0,        0},
202
 
      { OP_Integer,     0, 0,        0},
203
 
      { OP_Ne,          0, 6,        0},
204
 
      { OP_Integer,     0, 0,        0},  /* 5 */
205
 
      { OP_ColumnName,  0, 1,        "cache_size"},
206
 
      { OP_Callback,    1, 0,        0},
207
 
    };
208
 
    int addr;
209
 
    if( pRight->z==pLeft->z ){
210
 
      addr = sqliteVdbeAddOpList(v, ArraySize(getCacheSize), getCacheSize);
211
 
      sqliteVdbeChangeP1(v, addr+5, MAX_PAGES);
212
 
    }else{
213
 
      int size = atoi(zRight);
214
 
      if( size<0 ) size = -size;
215
 
      sqliteBeginWriteOperation(pParse, 0, 0);
216
 
      sqliteVdbeAddOp(v, OP_Integer, size, 0);
217
 
      sqliteVdbeAddOp(v, OP_ReadCookie, 0, 2);
218
 
      addr = sqliteVdbeAddOp(v, OP_Integer, 0, 0);
219
 
      sqliteVdbeAddOp(v, OP_Ge, 0, addr+3);
220
 
      sqliteVdbeAddOp(v, OP_Negative, 0, 0);
221
 
      sqliteVdbeAddOp(v, OP_SetCookie, 0, 2);
222
 
      sqliteEndWriteOperation(pParse);
223
 
      db->cache_size = db->cache_size<0 ? -size : size;
224
 
      sqliteBtreeSetCacheSize(db->aDb[0].pBt, db->cache_size);
225
 
    }
226
 
  }else
227
 
 
228
 
  /*
229
 
  **  PRAGMA cache_size
230
 
  **  PRAGMA cache_size=N
231
 
  **
232
 
  ** The first form reports the current local setting for the
233
 
  ** page cache size.  The local setting can be different from
234
 
  ** the persistent cache size value that is stored in the database
235
 
  ** file itself.  The value returned is the maximum number of
236
 
  ** pages in the page cache.  The second form sets the local
237
 
  ** page cache size value.  It does not change the persistent
238
 
  ** cache size stored on the disk so the cache size will revert
239
 
  ** to its default value when the database is closed and reopened.
240
 
  ** N should be a positive integer.
241
 
  */
242
 
  if( sqliteStrICmp(zLeft,"cache_size")==0 ){
243
 
    static VdbeOpList getCacheSize[] = {
244
 
      { OP_ColumnName,  0, 1,        "cache_size"},
245
 
      { OP_Callback,    1, 0,        0},
246
 
    };
247
 
    if( pRight->z==pLeft->z ){
248
 
      int size = db->cache_size;;
249
 
      if( size<0 ) size = -size;
250
 
      sqliteVdbeAddOp(v, OP_Integer, size, 0);
251
 
      sqliteVdbeAddOpList(v, ArraySize(getCacheSize), getCacheSize);
252
 
    }else{
253
 
      int size = atoi(zRight);
254
 
      if( size<0 ) size = -size;
255
 
      if( db->cache_size<0 ) size = -size;
256
 
      db->cache_size = size;
257
 
      sqliteBtreeSetCacheSize(db->aDb[0].pBt, db->cache_size);
258
 
    }
259
 
  }else
260
 
 
261
 
  /*
262
 
  **  PRAGMA default_synchronous
263
 
  **  PRAGMA default_synchronous=ON|OFF|NORMAL|FULL
264
 
  **
265
 
  ** The first form returns the persistent value of the "synchronous" setting
266
 
  ** that is stored in the database.  This is the synchronous setting that
267
 
  ** is used whenever the database is opened unless overridden by a separate
268
 
  ** "synchronous" pragma.  The second form changes the persistent and the
269
 
  ** local synchronous setting to the value given.
270
 
  **
271
 
  ** If synchronous is OFF, SQLite does not attempt any fsync() systems calls
272
 
  ** to make sure data is committed to disk.  Write operations are very fast,
273
 
  ** but a power failure can leave the database in an inconsistent state.
274
 
  ** If synchronous is ON or NORMAL, SQLite will do an fsync() system call to
275
 
  ** make sure data is being written to disk.  The risk of corruption due to
276
 
  ** a power loss in this mode is negligible but non-zero.  If synchronous
277
 
  ** is FULL, extra fsync()s occur to reduce the risk of corruption to near
278
 
  ** zero, but with a write performance penalty.  The default mode is NORMAL.
279
 
  */
280
 
  if( sqliteStrICmp(zLeft,"default_synchronous")==0 ){
281
 
    static VdbeOpList getSync[] = {
282
 
      { OP_ColumnName,  0, 1,        "synchronous"},
283
 
      { OP_ReadCookie,  0, 3,        0},
284
 
      { OP_Dup,         0, 0,        0},
285
 
      { OP_If,          0, 0,        0},  /* 3 */
286
 
      { OP_ReadCookie,  0, 2,        0},
287
 
      { OP_Integer,     0, 0,        0},
288
 
      { OP_Lt,          0, 5,        0},
289
 
      { OP_AddImm,      1, 0,        0},
290
 
      { OP_Callback,    1, 0,        0},
291
 
      { OP_Halt,        0, 0,        0},
292
 
      { OP_AddImm,     -1, 0,        0},  /* 10 */
293
 
      { OP_Callback,    1, 0,        0}
294
 
    };
295
 
    if( pRight->z==pLeft->z ){
296
 
      int addr = sqliteVdbeAddOpList(v, ArraySize(getSync), getSync);
297
 
      sqliteVdbeChangeP2(v, addr+3, addr+10);
298
 
    }else{
299
 
      int addr;
300
 
      int size = db->cache_size;
301
 
      if( size<0 ) size = -size;
302
 
      sqliteBeginWriteOperation(pParse, 0, 0);
303
 
      sqliteVdbeAddOp(v, OP_ReadCookie, 0, 2);
304
 
      sqliteVdbeAddOp(v, OP_Dup, 0, 0);
305
 
      addr = sqliteVdbeAddOp(v, OP_Integer, 0, 0);
306
 
      sqliteVdbeAddOp(v, OP_Ne, 0, addr+3);
307
 
      sqliteVdbeAddOp(v, OP_AddImm, MAX_PAGES, 0);
308
 
      sqliteVdbeAddOp(v, OP_AbsValue, 0, 0);
309
 
      db->safety_level = getSafetyLevel(zRight)+1;
310
 
      if( db->safety_level==1 ){
311
 
        sqliteVdbeAddOp(v, OP_Negative, 0, 0);
312
 
        size = -size;
313
 
      }
314
 
      sqliteVdbeAddOp(v, OP_SetCookie, 0, 2);
315
 
      sqliteVdbeAddOp(v, OP_Integer, db->safety_level, 0);
316
 
      sqliteVdbeAddOp(v, OP_SetCookie, 0, 3);
317
 
      sqliteEndWriteOperation(pParse);
318
 
      db->cache_size = size;
319
 
      sqliteBtreeSetCacheSize(db->aDb[0].pBt, db->cache_size);
320
 
      sqliteBtreeSetSafetyLevel(db->aDb[0].pBt, db->safety_level);
321
 
    }
322
 
  }else
323
 
 
324
 
  /*
325
 
  **   PRAGMA synchronous
326
 
  **   PRAGMA synchronous=OFF|ON|NORMAL|FULL
327
 
  **
328
 
  ** Return or set the local value of the synchronous flag.  Changing
329
 
  ** the local value does not make changes to the disk file and the
330
 
  ** default value will be restored the next time the database is
331
 
  ** opened.
332
 
  */
333
 
  if( sqliteStrICmp(zLeft,"synchronous")==0 ){
334
 
    static VdbeOpList getSync[] = {
335
 
      { OP_ColumnName,  0, 1,        "synchronous"},
336
 
      { OP_Callback,    1, 0,        0},
337
 
    };
338
 
    if( pRight->z==pLeft->z ){
339
 
      sqliteVdbeAddOp(v, OP_Integer, db->safety_level-1, 0);
340
 
      sqliteVdbeAddOpList(v, ArraySize(getSync), getSync);
341
 
    }else{
342
 
      int size = db->cache_size;
343
 
      if( size<0 ) size = -size;
344
 
      db->safety_level = getSafetyLevel(zRight)+1;
345
 
      if( db->safety_level==1 ) size = -size;
346
 
      db->cache_size = size;
347
 
      sqliteBtreeSetCacheSize(db->aDb[0].pBt, db->cache_size);
348
 
      sqliteBtreeSetSafetyLevel(db->aDb[0].pBt, db->safety_level);
349
 
    }
350
 
  }else
351
 
 
352
 
#ifndef NDEBUG
353
 
  if( sqliteStrICmp(zLeft, "trigger_overhead_test")==0 ){
354
 
    if( getBoolean(zRight) ){
355
 
      always_code_trigger_setup = 1;
356
 
    }else{
357
 
      always_code_trigger_setup = 0;
358
 
    }
359
 
  }else
360
 
#endif
361
 
 
362
 
  if( flagPragma(pParse, zLeft, zRight) ){
363
 
    /* The flagPragma() call also generates any necessary code */
364
 
  }else
365
 
 
366
 
  if( sqliteStrICmp(zLeft, "table_info")==0 ){
367
 
    Table *pTab;
368
 
    pTab = sqliteFindTable(db, zRight, 0);
369
 
    if( pTab ){
370
 
      static VdbeOpList tableInfoPreface[] = {
371
 
        { OP_ColumnName,  0, 0,       "cid"},
372
 
        { OP_ColumnName,  1, 0,       "name"},
373
 
        { OP_ColumnName,  2, 0,       "type"},
374
 
        { OP_ColumnName,  3, 0,       "notnull"},
375
 
        { OP_ColumnName,  4, 0,       "dflt_value"},
376
 
        { OP_ColumnName,  5, 1,       "pk"},
377
 
      };
378
 
      int i;
379
 
      sqliteVdbeAddOpList(v, ArraySize(tableInfoPreface), tableInfoPreface);
380
 
      sqliteViewGetColumnNames(pParse, pTab);
381
 
      for(i=0; i<pTab->nCol; i++){
382
 
        sqliteVdbeAddOp(v, OP_Integer, i, 0);
383
 
        sqliteVdbeOp3(v, OP_String, 0, 0, pTab->aCol[i].zName, 0);
384
 
        sqliteVdbeOp3(v, OP_String, 0, 0,
385
 
           pTab->aCol[i].zType ? pTab->aCol[i].zType : "numeric", 0);
386
 
        sqliteVdbeAddOp(v, OP_Integer, pTab->aCol[i].notNull, 0);
387
 
        sqliteVdbeOp3(v, OP_String, 0, 0,
388
 
           pTab->aCol[i].zDflt, P3_STATIC);
389
 
        sqliteVdbeAddOp(v, OP_Integer, pTab->aCol[i].isPrimKey, 0);
390
 
        sqliteVdbeAddOp(v, OP_Callback, 6, 0);
391
 
      }
392
 
    }
393
 
  }else
394
 
 
395
 
  if( sqliteStrICmp(zLeft, "index_info")==0 ){
396
 
    Index *pIdx;
397
 
    Table *pTab;
398
 
    pIdx = sqliteFindIndex(db, zRight, 0);
399
 
    if( pIdx ){
400
 
      static VdbeOpList tableInfoPreface[] = {
401
 
        { OP_ColumnName,  0, 0,       "seqno"},
402
 
        { OP_ColumnName,  1, 0,       "cid"},
403
 
        { OP_ColumnName,  2, 1,       "name"},
404
 
      };
405
 
      int i;
406
 
      pTab = pIdx->pTable;
407
 
      sqliteVdbeAddOpList(v, ArraySize(tableInfoPreface), tableInfoPreface);
408
 
      for(i=0; i<pIdx->nColumn; i++){
409
 
        int cnum = pIdx->aiColumn[i];
410
 
        sqliteVdbeAddOp(v, OP_Integer, i, 0);
411
 
        sqliteVdbeAddOp(v, OP_Integer, cnum, 0);
412
 
        assert( pTab->nCol>cnum );
413
 
        sqliteVdbeOp3(v, OP_String, 0, 0, pTab->aCol[cnum].zName, 0);
414
 
        sqliteVdbeAddOp(v, OP_Callback, 3, 0);
415
 
      }
416
 
    }
417
 
  }else
418
 
 
419
 
  if( sqliteStrICmp(zLeft, "index_list")==0 ){
420
 
    Index *pIdx;
421
 
    Table *pTab;
422
 
    pTab = sqliteFindTable(db, zRight, 0);
423
 
    if( pTab ){
424
 
      v = sqliteGetVdbe(pParse);
425
 
      pIdx = pTab->pIndex;
426
 
    }
427
 
    if( pTab && pIdx ){
428
 
      int i = 0; 
429
 
      static VdbeOpList indexListPreface[] = {
430
 
        { OP_ColumnName,  0, 0,       "seq"},
431
 
        { OP_ColumnName,  1, 0,       "name"},
432
 
        { OP_ColumnName,  2, 1,       "unique"},
433
 
      };
434
 
 
435
 
      sqliteVdbeAddOpList(v, ArraySize(indexListPreface), indexListPreface);
436
 
      while(pIdx){
437
 
        sqliteVdbeAddOp(v, OP_Integer, i, 0);
438
 
        sqliteVdbeOp3(v, OP_String, 0, 0, pIdx->zName, 0);
439
 
        sqliteVdbeAddOp(v, OP_Integer, pIdx->onError!=OE_None, 0);
440
 
        sqliteVdbeAddOp(v, OP_Callback, 3, 0);
441
 
        ++i;
442
 
        pIdx = pIdx->pNext;
443
 
      }
444
 
    }
445
 
  }else
446
 
 
447
 
  if( sqliteStrICmp(zLeft, "foreign_key_list")==0 ){
448
 
    FKey *pFK;
449
 
    Table *pTab;
450
 
    pTab = sqliteFindTable(db, zRight, 0);
451
 
    if( pTab ){
452
 
      v = sqliteGetVdbe(pParse);
453
 
      pFK = pTab->pFKey;
454
 
    }
455
 
    if( pTab && pFK ){
456
 
      int i = 0; 
457
 
      static VdbeOpList indexListPreface[] = {
458
 
        { OP_ColumnName,  0, 0,       "id"},
459
 
        { OP_ColumnName,  1, 0,       "seq"},
460
 
        { OP_ColumnName,  2, 0,       "table"},
461
 
        { OP_ColumnName,  3, 0,       "from"},
462
 
        { OP_ColumnName,  4, 1,       "to"},
463
 
      };
464
 
 
465
 
      sqliteVdbeAddOpList(v, ArraySize(indexListPreface), indexListPreface);
466
 
      while(pFK){
467
 
        int j;
468
 
        for(j=0; j<pFK->nCol; j++){
469
 
          sqliteVdbeAddOp(v, OP_Integer, i, 0);
470
 
          sqliteVdbeAddOp(v, OP_Integer, j, 0);
471
 
          sqliteVdbeOp3(v, OP_String, 0, 0, pFK->zTo, 0);
472
 
          sqliteVdbeOp3(v, OP_String, 0, 0,
473
 
                           pTab->aCol[pFK->aCol[j].iFrom].zName, 0);
474
 
          sqliteVdbeOp3(v, OP_String, 0, 0, pFK->aCol[j].zCol, 0);
475
 
          sqliteVdbeAddOp(v, OP_Callback, 5, 0);
476
 
        }
477
 
        ++i;
478
 
        pFK = pFK->pNextFrom;
479
 
      }
480
 
    }
481
 
  }else
482
 
 
483
 
  if( sqliteStrICmp(zLeft, "database_list")==0 ){
484
 
    int i;
485
 
    static VdbeOpList indexListPreface[] = {
486
 
      { OP_ColumnName,  0, 0,       "seq"},
487
 
      { OP_ColumnName,  1, 0,       "name"},
488
 
      { OP_ColumnName,  2, 1,       "file"},
489
 
    };
490
 
 
491
 
    sqliteVdbeAddOpList(v, ArraySize(indexListPreface), indexListPreface);
492
 
    for(i=0; i<db->nDb; i++){
493
 
      if( db->aDb[i].pBt==0 ) continue;
494
 
      assert( db->aDb[i].zName!=0 );
495
 
      sqliteVdbeAddOp(v, OP_Integer, i, 0);
496
 
      sqliteVdbeOp3(v, OP_String, 0, 0, db->aDb[i].zName, 0);
497
 
      sqliteVdbeOp3(v, OP_String, 0, 0,
498
 
           sqliteBtreeGetFilename(db->aDb[i].pBt), 0);
499
 
      sqliteVdbeAddOp(v, OP_Callback, 3, 0);
500
 
    }
501
 
  }else
502
 
 
503
 
 
504
 
  /*
505
 
  **   PRAGMA temp_store
506
 
  **   PRAGMA temp_store = "default"|"memory"|"file"
507
 
  **
508
 
  ** Return or set the local value of the temp_store flag.  Changing
509
 
  ** the local value does not make changes to the disk file and the default
510
 
  ** value will be restored the next time the database is opened.
511
 
  **
512
 
  ** Note that it is possible for the library compile-time options to
513
 
  ** override this setting
514
 
  */
515
 
  if( sqliteStrICmp(zLeft, "temp_store")==0 ){
516
 
    static VdbeOpList getTmpDbLoc[] = {
517
 
      { OP_ColumnName,  0, 1,        "temp_store"},
518
 
      { OP_Callback,    1, 0,        0},
519
 
    };
520
 
    if( pRight->z==pLeft->z ){
521
 
      sqliteVdbeAddOp(v, OP_Integer, db->temp_store, 0);
522
 
      sqliteVdbeAddOpList(v, ArraySize(getTmpDbLoc), getTmpDbLoc);
523
 
    }else{
524
 
      changeTempStorage(pParse, zRight);
525
 
    }
526
 
  }else
527
 
 
528
 
  /*
529
 
  **   PRAGMA default_temp_store
530
 
  **   PRAGMA default_temp_store = "default"|"memory"|"file"
531
 
  **
532
 
  ** Return or set the value of the persistent temp_store flag.  Any
533
 
  ** change does not take effect until the next time the database is
534
 
  ** opened.
535
 
  **
536
 
  ** Note that it is possible for the library compile-time options to
537
 
  ** override this setting
538
 
  */
539
 
  if( sqliteStrICmp(zLeft, "default_temp_store")==0 ){
540
 
    static VdbeOpList getTmpDbLoc[] = {
541
 
      { OP_ColumnName,  0, 1,        "temp_store"},
542
 
      { OP_ReadCookie,  0, 5,        0},
543
 
      { OP_Callback,    1, 0,        0}};
544
 
    if( pRight->z==pLeft->z ){
545
 
      sqliteVdbeAddOpList(v, ArraySize(getTmpDbLoc), getTmpDbLoc);
546
 
    }else{
547
 
      sqliteBeginWriteOperation(pParse, 0, 0);
548
 
      sqliteVdbeAddOp(v, OP_Integer, getTempStore(zRight), 0);
549
 
      sqliteVdbeAddOp(v, OP_SetCookie, 0, 5);
550
 
      sqliteEndWriteOperation(pParse);
551
 
    }
552
 
  }else
553
 
 
554
 
#ifndef NDEBUG
555
 
  if( sqliteStrICmp(zLeft, "parser_trace")==0 ){
556
 
    extern void sqliteParserTrace(FILE*, char *);
557
 
    if( getBoolean(zRight) ){
558
 
      sqliteParserTrace(stdout, "parser: ");
559
 
    }else{
560
 
      sqliteParserTrace(0, 0);
561
 
    }
562
 
  }else
563
 
#endif
564
 
 
565
 
  if( sqliteStrICmp(zLeft, "integrity_check")==0 ){
566
 
    int i, j, addr;
567
 
 
568
 
    /* Code that initializes the integrity check program.  Set the
569
 
    ** error count 0
570
 
    */
571
 
    static VdbeOpList initCode[] = {
572
 
      { OP_Integer,     0, 0,        0},
573
 
      { OP_MemStore,    0, 1,        0},
574
 
      { OP_ColumnName,  0, 1,        "integrity_check"},
575
 
    };
576
 
 
577
 
    /* Code to do an BTree integrity check on a single database file.
578
 
    */
579
 
    static VdbeOpList checkDb[] = {
580
 
      { OP_SetInsert,   0, 0,        "2"},
581
 
      { OP_Integer,     0, 0,        0},    /* 1 */
582
 
      { OP_OpenRead,    0, 2,        0},
583
 
      { OP_Rewind,      0, 7,        0},    /* 3 */
584
 
      { OP_Column,      0, 3,        0},    /* 4 */
585
 
      { OP_SetInsert,   0, 0,        0},
586
 
      { OP_Next,        0, 4,        0},    /* 6 */
587
 
      { OP_IntegrityCk, 0, 0,        0},    /* 7 */
588
 
      { OP_Dup,         0, 1,        0},
589
 
      { OP_String,      0, 0,        "ok"},
590
 
      { OP_StrEq,       0, 12,       0},    /* 10 */
591
 
      { OP_MemIncr,     0, 0,        0},
592
 
      { OP_String,      0, 0,        "*** in database "},
593
 
      { OP_String,      0, 0,        0},    /* 13 */
594
 
      { OP_String,      0, 0,        " ***\n"},
595
 
      { OP_Pull,        3, 0,        0},
596
 
      { OP_Concat,      4, 1,        0},
597
 
      { OP_Callback,    1, 0,        0},
598
 
    };
599
 
 
600
 
    /* Code that appears at the end of the integrity check.  If no error
601
 
    ** messages have been generated, output OK.  Otherwise output the
602
 
    ** error message
603
 
    */
604
 
    static VdbeOpList endCode[] = {
605
 
      { OP_MemLoad,     0, 0,        0},
606
 
      { OP_Integer,     0, 0,        0},
607
 
      { OP_Ne,          0, 0,        0},    /* 2 */
608
 
      { OP_String,      0, 0,        "ok"},
609
 
      { OP_Callback,    1, 0,        0},
610
 
    };
611
 
 
612
 
    /* Initialize the VDBE program */
613
 
    sqliteVdbeAddOpList(v, ArraySize(initCode), initCode);
614
 
 
615
 
    /* Do an integrity check on each database file */
616
 
    for(i=0; i<db->nDb; i++){
617
 
      HashElem *x;
618
 
 
619
 
      /* Do an integrity check of the B-Tree
620
 
      */
621
 
      addr = sqliteVdbeAddOpList(v, ArraySize(checkDb), checkDb);
622
 
      sqliteVdbeChangeP1(v, addr+1, i);
623
 
      sqliteVdbeChangeP2(v, addr+3, addr+7);
624
 
      sqliteVdbeChangeP2(v, addr+6, addr+4);
625
 
      sqliteVdbeChangeP2(v, addr+7, i);
626
 
      sqliteVdbeChangeP2(v, addr+10, addr+ArraySize(checkDb));
627
 
      sqliteVdbeChangeP3(v, addr+13, db->aDb[i].zName, P3_STATIC);
628
 
 
629
 
      /* Make sure all the indices are constructed correctly.
630
 
      */
631
 
      sqliteCodeVerifySchema(pParse, i);
632
 
      for(x=sqliteHashFirst(&db->aDb[i].tblHash); x; x=sqliteHashNext(x)){
633
 
        Table *pTab = sqliteHashData(x);
634
 
        Index *pIdx;
635
 
        int loopTop;
636
 
 
637
 
        if( pTab->pIndex==0 ) continue;
638
 
        sqliteVdbeAddOp(v, OP_Integer, i, 0);
639
 
        sqliteVdbeOp3(v, OP_OpenRead, 1, pTab->tnum, pTab->zName, 0);
640
 
        for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
641
 
          if( pIdx->tnum==0 ) continue;
642
 
          sqliteVdbeAddOp(v, OP_Integer, pIdx->iDb, 0);
643
 
          sqliteVdbeOp3(v, OP_OpenRead, j+2, pIdx->tnum, pIdx->zName, 0);
644
 
        }
645
 
        sqliteVdbeAddOp(v, OP_Integer, 0, 0);
646
 
        sqliteVdbeAddOp(v, OP_MemStore, 1, 1);
647
 
        loopTop = sqliteVdbeAddOp(v, OP_Rewind, 1, 0);
648
 
        sqliteVdbeAddOp(v, OP_MemIncr, 1, 0);
649
 
        for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
650
 
          int k, jmp2;
651
 
          static VdbeOpList idxErr[] = {
652
 
            { OP_MemIncr,     0,  0,  0},
653
 
            { OP_String,      0,  0,  "rowid "},
654
 
            { OP_Recno,       1,  0,  0},
655
 
            { OP_String,      0,  0,  " missing from index "},
656
 
            { OP_String,      0,  0,  0},    /* 4 */
657
 
            { OP_Concat,      4,  0,  0},
658
 
            { OP_Callback,    1,  0,  0},
659
 
          };
660
 
          sqliteVdbeAddOp(v, OP_Recno, 1, 0);
661
 
          for(k=0; k<pIdx->nColumn; k++){
662
 
            int idx = pIdx->aiColumn[k];
663
 
            if( idx==pTab->iPKey ){
664
 
              sqliteVdbeAddOp(v, OP_Recno, 1, 0);
665
 
            }else{
666
 
              sqliteVdbeAddOp(v, OP_Column, 1, idx);
667
 
            }
668
 
          }
669
 
          sqliteVdbeAddOp(v, OP_MakeIdxKey, pIdx->nColumn, 0);
670
 
          if( db->file_format>=4 ) sqliteAddIdxKeyType(v, pIdx);
671
 
          jmp2 = sqliteVdbeAddOp(v, OP_Found, j+2, 0);
672
 
          addr = sqliteVdbeAddOpList(v, ArraySize(idxErr), idxErr);
673
 
          sqliteVdbeChangeP3(v, addr+4, pIdx->zName, P3_STATIC);
674
 
          sqliteVdbeChangeP2(v, jmp2, sqliteVdbeCurrentAddr(v));
675
 
        }
676
 
        sqliteVdbeAddOp(v, OP_Next, 1, loopTop+1);
677
 
        sqliteVdbeChangeP2(v, loopTop, sqliteVdbeCurrentAddr(v));
678
 
        for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
679
 
          static VdbeOpList cntIdx[] = {
680
 
             { OP_Integer,      0,  0,  0},
681
 
             { OP_MemStore,     2,  1,  0},
682
 
             { OP_Rewind,       0,  0,  0},  /* 2 */
683
 
             { OP_MemIncr,      2,  0,  0},
684
 
             { OP_Next,         0,  0,  0},  /* 4 */
685
 
             { OP_MemLoad,      1,  0,  0},
686
 
             { OP_MemLoad,      2,  0,  0},
687
 
             { OP_Eq,           0,  0,  0},  /* 7 */
688
 
             { OP_MemIncr,      0,  0,  0},
689
 
             { OP_String,       0,  0,  "wrong # of entries in index "},
690
 
             { OP_String,       0,  0,  0},  /* 10 */
691
 
             { OP_Concat,       2,  0,  0},
692
 
             { OP_Callback,     1,  0,  0},
693
 
          };
694
 
          if( pIdx->tnum==0 ) continue;
695
 
          addr = sqliteVdbeAddOpList(v, ArraySize(cntIdx), cntIdx);
696
 
          sqliteVdbeChangeP1(v, addr+2, j+2);
697
 
          sqliteVdbeChangeP2(v, addr+2, addr+5);
698
 
          sqliteVdbeChangeP1(v, addr+4, j+2);
699
 
          sqliteVdbeChangeP2(v, addr+4, addr+3);
700
 
          sqliteVdbeChangeP2(v, addr+7, addr+ArraySize(cntIdx));
701
 
          sqliteVdbeChangeP3(v, addr+10, pIdx->zName, P3_STATIC);
702
 
        }
703
 
      } 
704
 
    }
705
 
    addr = sqliteVdbeAddOpList(v, ArraySize(endCode), endCode);
706
 
    sqliteVdbeChangeP2(v, addr+2, addr+ArraySize(endCode));
707
 
  }else
708
 
 
709
 
  {}
710
 
  sqliteFree(zLeft);
711
 
  sqliteFree(zRight);
712
 
}