xref: /PHP-5.3/ext/sqlite/libsqlite/src/pragma.c (revision e563b4ea)
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$
15 */
16 #include "sqliteInt.h"
17 #include <ctype.h>
18 
19 /*
20 ** Interpret the given string as a boolean value.
21 */
getBoolean(const char * z)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 */
getSafetyLevel(char * z)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 */
getTempStore(const char * z)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 */
changeTempStorage(Parse * pParse,const char * zStorageType)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 */
flagPragma(Parse * pParse,const char * zLeft,const char * zRight)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 */
sqlitePragma(Parse * pParse,Token * pLeft,Token * pRight,int minusFlag)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 }
713