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