File Coverage

pragma.c
Criterion Covered Total %
statement 32 261 12.2
branch 19 164 11.5
condition n/a
subroutine n/a
pod n/a
total 51 425 12.0


line stmt bran cond sub pod time code
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,v 1.1.1.1 2004/08/08 15:03:57 matt Exp $
15             */
16             #include "sqliteInt.h"
17             #include
18              
19             /*
20             ** Interpret the given string as a boolean value.
21             */
22 50           static int getBoolean(const char *z){
23             static char *azTrue[] = { "yes", "on", "true" };
24             int i;
25 50 50         if( z[0]==0 ) return 0;
26 50 50         if( isdigit(z[0]) || (z[0]=='-' && isdigit(z[1])) ){
    50          
    0          
27 0           return atoi(z);
28             }
29 100 50         for(i=0; i
30 100 100         if( sqliteStrICmp(z,azTrue[i])==0 ) return 1;
31             }
32 0           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 0           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 0 0         if( z[0]==0 ) return 1;
60 0 0         if( isdigit(z[0]) || (z[0]=='-' && isdigit(z[1])) ){
    0          
    0          
61 0           return atoi(z);
62             }
63 0 0         for(i=0; i
64 0 0         if( sqliteStrICmp(z,aKey[i].zWord)==0 ) return aKey[i].val;
65             }
66 0           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 0           static int getTempStore(const char *z){
75 0 0         if( z[0]>='0' && z[0]<='2' ){
    0          
76 0           return z[0] - '0';
77 0 0         }else if( sqliteStrICmp(z, "file")==0 ){
78 0           return 1;
79 0 0         }else if( sqliteStrICmp(z, "memory")==0 ){
80 0           return 2;
81             }else{
82 0           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 0           static int changeTempStorage(Parse *pParse, const char *zStorageType){
92 0           int ts = getTempStore(zStorageType);
93 0           sqlite *db = pParse->db;
94 0 0         if( db->temp_store==ts ) return SQLITE_OK;
95 0 0         if( db->aDb[1].pBt!=0 ){
96 0 0         if( db->flags & SQLITE_InTrans ){
97 0           sqliteErrorMsg(pParse, "temporary storage cannot be changed "
98             "from within a transaction");
99 0           return SQLITE_ERROR;
100             }
101 0           sqliteBtreeClose(db->aDb[1].pBt);
102 0           db->aDb[1].pBt = 0;
103 0           sqliteResetInternalSchema(db, 0);
104             }
105 0           db->temp_store = ts;
106 0           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 50           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 250 50         for(i=0; i
128 250 100         if( sqliteStrICmp(zLeft, aPragma[i].zName)==0 ){
129 50           sqlite *db = pParse->db;
130             Vdbe *v;
131 50 50         if( strcmp(zLeft,zRight)==0 && (v = sqliteGetVdbe(pParse))!=0 ){
    0          
132 0           sqliteVdbeOp3(v, OP_ColumnName, 0, 1, aPragma[i].zName, P3_STATIC);
133 0           sqliteVdbeOp3(v, OP_ColumnName, 1, 0, "boolean", P3_STATIC);
134 0           sqliteVdbeCode(v, OP_Integer, (db->flags & aPragma[i].mask)!=0, 0,
135             OP_Callback, 1, 0,
136             0);
137 50 50         }else if( getBoolean(zRight) ){
138 50           db->flags |= aPragma[i].mask;
139             }else{
140 0           db->flags &= ~aPragma[i].mask;
141             }
142 50           return 1;
143             }
144             }
145 0           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 50           void sqlitePragma(Parse *pParse, Token *pLeft, Token *pRight, int minusFlag){
160 50           char *zLeft = 0;
161 50           char *zRight = 0;
162 50           sqlite *db = pParse->db;
163 50           Vdbe *v = sqliteGetVdbe(pParse);
164 50 50         if( v==0 ) return;
165              
166 50           zLeft = sqliteStrNDup(pLeft->z, pLeft->n);
167 50           sqliteDequote(zLeft);
168 50 50         if( minusFlag ){
169 0           zRight = 0;
170 0           sqliteSetNString(&zRight, "-", 1, pRight->z, pRight->n, 0);
171             }else{
172 50           zRight = sqliteStrNDup(pRight->z, pRight->n);
173 50           sqliteDequote(zRight);
174             }
175 50 50         if( sqliteAuthCheck(pParse, SQLITE_PRAGMA, zLeft, zRight, 0) ){
176 0           sqliteFree(zLeft);
177 0           sqliteFree(zRight);
178 0           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 50 50         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 0 0         if( pRight->z==pLeft->z ){
210 0           addr = sqliteVdbeAddOpList(v, ArraySize(getCacheSize), getCacheSize);
211 0           sqliteVdbeChangeP1(v, addr+5, MAX_PAGES);
212             }else{
213 0           int size = atoi(zRight);
214 0 0         if( size<0 ) size = -size;
215 0           sqliteBeginWriteOperation(pParse, 0, 0);
216 0           sqliteVdbeAddOp(v, OP_Integer, size, 0);
217 0           sqliteVdbeAddOp(v, OP_ReadCookie, 0, 2);
218 0           addr = sqliteVdbeAddOp(v, OP_Integer, 0, 0);
219 0           sqliteVdbeAddOp(v, OP_Ge, 0, addr+3);
220 0           sqliteVdbeAddOp(v, OP_Negative, 0, 0);
221 0           sqliteVdbeAddOp(v, OP_SetCookie, 0, 2);
222 0           sqliteEndWriteOperation(pParse);
223 0 0         db->cache_size = db->cache_size<0 ? -size : size;
224 0           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 50 50         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 0 0         if( pRight->z==pLeft->z ){
248 0           int size = db->cache_size;;
249 0 0         if( size<0 ) size = -size;
250 0           sqliteVdbeAddOp(v, OP_Integer, size, 0);
251 0           sqliteVdbeAddOpList(v, ArraySize(getCacheSize), getCacheSize);
252             }else{
253 0           int size = atoi(zRight);
254 0 0         if( size<0 ) size = -size;
255 0 0         if( db->cache_size<0 ) size = -size;
256 0           db->cache_size = size;
257 0           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 50 50         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 0 0         if( pRight->z==pLeft->z ){
296 0           int addr = sqliteVdbeAddOpList(v, ArraySize(getSync), getSync);
297 0           sqliteVdbeChangeP2(v, addr+3, addr+10);
298             }else{
299             int addr;
300 0           int size = db->cache_size;
301 0 0         if( size<0 ) size = -size;
302 0           sqliteBeginWriteOperation(pParse, 0, 0);
303 0           sqliteVdbeAddOp(v, OP_ReadCookie, 0, 2);
304 0           sqliteVdbeAddOp(v, OP_Dup, 0, 0);
305 0           addr = sqliteVdbeAddOp(v, OP_Integer, 0, 0);
306 0           sqliteVdbeAddOp(v, OP_Ne, 0, addr+3);
307 0           sqliteVdbeAddOp(v, OP_AddImm, MAX_PAGES, 0);
308 0           sqliteVdbeAddOp(v, OP_AbsValue, 0, 0);
309 0           db->safety_level = getSafetyLevel(zRight)+1;
310 0 0         if( db->safety_level==1 ){
311 0           sqliteVdbeAddOp(v, OP_Negative, 0, 0);
312 0           size = -size;
313             }
314 0           sqliteVdbeAddOp(v, OP_SetCookie, 0, 2);
315 0           sqliteVdbeAddOp(v, OP_Integer, db->safety_level, 0);
316 0           sqliteVdbeAddOp(v, OP_SetCookie, 0, 3);
317 0           sqliteEndWriteOperation(pParse);
318 0           db->cache_size = size;
319 0           sqliteBtreeSetCacheSize(db->aDb[0].pBt, db->cache_size);
320 0           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 50 50         if( sqliteStrICmp(zLeft,"synchronous")==0 ){
334             static VdbeOpList getSync[] = {
335             { OP_ColumnName, 0, 1, "synchronous"},
336             { OP_Callback, 1, 0, 0},
337             };
338 0 0         if( pRight->z==pLeft->z ){
339 0           sqliteVdbeAddOp(v, OP_Integer, db->safety_level-1, 0);
340 0           sqliteVdbeAddOpList(v, ArraySize(getSync), getSync);
341             }else{
342 0           int size = db->cache_size;
343 0 0         if( size<0 ) size = -size;
344 0           db->safety_level = getSafetyLevel(zRight)+1;
345 0 0         if( db->safety_level==1 ) size = -size;
346 0           db->cache_size = size;
347 0           sqliteBtreeSetCacheSize(db->aDb[0].pBt, db->cache_size);
348 0           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 50 50         if( flagPragma(pParse, zLeft, zRight) ){
363             /* The flagPragma() call also generates any necessary code */
364             }else
365              
366 0 0         if( sqliteStrICmp(zLeft, "table_info")==0 ){
367             Table *pTab;
368 0           pTab = sqliteFindTable(db, zRight, 0);
369 0 0         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 0           sqliteVdbeAddOpList(v, ArraySize(tableInfoPreface), tableInfoPreface);
380 0           sqliteViewGetColumnNames(pParse, pTab);
381 0 0         for(i=0; inCol; i++){
382 0           sqliteVdbeAddOp(v, OP_Integer, i, 0);
383 0           sqliteVdbeOp3(v, OP_String, 0, 0, pTab->aCol[i].zName, 0);
384 0 0         sqliteVdbeOp3(v, OP_String, 0, 0,
385 0           pTab->aCol[i].zType ? pTab->aCol[i].zType : "numeric", 0);
386 0           sqliteVdbeAddOp(v, OP_Integer, pTab->aCol[i].notNull, 0);
387 0           sqliteVdbeOp3(v, OP_String, 0, 0,
388 0           pTab->aCol[i].zDflt, P3_STATIC);
389 0           sqliteVdbeAddOp(v, OP_Integer, pTab->aCol[i].isPrimKey, 0);
390 0           sqliteVdbeAddOp(v, OP_Callback, 6, 0);
391             }
392             }
393             }else
394              
395 0 0         if( sqliteStrICmp(zLeft, "index_info")==0 ){
396             Index *pIdx;
397             Table *pTab;
398 0           pIdx = sqliteFindIndex(db, zRight, 0);
399 0 0         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 0           pTab = pIdx->pTable;
407 0           sqliteVdbeAddOpList(v, ArraySize(tableInfoPreface), tableInfoPreface);
408 0 0         for(i=0; inColumn; i++){
409 0           int cnum = pIdx->aiColumn[i];
410 0           sqliteVdbeAddOp(v, OP_Integer, i, 0);
411 0           sqliteVdbeAddOp(v, OP_Integer, cnum, 0);
412             assert( pTab->nCol>cnum );
413 0           sqliteVdbeOp3(v, OP_String, 0, 0, pTab->aCol[cnum].zName, 0);
414 0           sqliteVdbeAddOp(v, OP_Callback, 3, 0);
415             }
416             }
417             }else
418              
419 0 0         if( sqliteStrICmp(zLeft, "index_list")==0 ){
420             Index *pIdx;
421             Table *pTab;
422 0           pTab = sqliteFindTable(db, zRight, 0);
423 0 0         if( pTab ){
424 0           v = sqliteGetVdbe(pParse);
425 0           pIdx = pTab->pIndex;
426             }
427 0 0         if( pTab && pIdx ){
    0          
428 0           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 0           sqliteVdbeAddOpList(v, ArraySize(indexListPreface), indexListPreface);
436 0 0         while(pIdx){
437 0           sqliteVdbeAddOp(v, OP_Integer, i, 0);
438 0           sqliteVdbeOp3(v, OP_String, 0, 0, pIdx->zName, 0);
439 0           sqliteVdbeAddOp(v, OP_Integer, pIdx->onError!=OE_None, 0);
440 0           sqliteVdbeAddOp(v, OP_Callback, 3, 0);
441 0           ++i;
442 0           pIdx = pIdx->pNext;
443             }
444             }
445             }else
446              
447 0 0         if( sqliteStrICmp(zLeft, "foreign_key_list")==0 ){
448             FKey *pFK;
449             Table *pTab;
450 0           pTab = sqliteFindTable(db, zRight, 0);
451 0 0         if( pTab ){
452 0           v = sqliteGetVdbe(pParse);
453 0           pFK = pTab->pFKey;
454             }
455 0 0         if( pTab && pFK ){
    0          
456 0           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 0           sqliteVdbeAddOpList(v, ArraySize(indexListPreface), indexListPreface);
466 0 0         while(pFK){
467             int j;
468 0 0         for(j=0; jnCol; j++){
469 0           sqliteVdbeAddOp(v, OP_Integer, i, 0);
470 0           sqliteVdbeAddOp(v, OP_Integer, j, 0);
471 0           sqliteVdbeOp3(v, OP_String, 0, 0, pFK->zTo, 0);
472 0           sqliteVdbeOp3(v, OP_String, 0, 0,
473 0           pTab->aCol[pFK->aCol[j].iFrom].zName, 0);
474 0           sqliteVdbeOp3(v, OP_String, 0, 0, pFK->aCol[j].zCol, 0);
475 0           sqliteVdbeAddOp(v, OP_Callback, 5, 0);
476             }
477 0           ++i;
478 0           pFK = pFK->pNextFrom;
479             }
480             }
481             }else
482              
483 0 0         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 0           sqliteVdbeAddOpList(v, ArraySize(indexListPreface), indexListPreface);
492 0 0         for(i=0; inDb; i++){
493 0 0         if( db->aDb[i].pBt==0 ) continue;
494             assert( db->aDb[i].zName!=0 );
495 0           sqliteVdbeAddOp(v, OP_Integer, i, 0);
496 0           sqliteVdbeOp3(v, OP_String, 0, 0, db->aDb[i].zName, 0);
497 0           sqliteVdbeOp3(v, OP_String, 0, 0,
498 0           sqliteBtreeGetFilename(db->aDb[i].pBt), 0);
499 0           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 0 0         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 0 0         if( pRight->z==pLeft->z ){
521 0           sqliteVdbeAddOp(v, OP_Integer, db->temp_store, 0);
522 0           sqliteVdbeAddOpList(v, ArraySize(getTmpDbLoc), getTmpDbLoc);
523             }else{
524 0           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 0 0         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 0 0         if( pRight->z==pLeft->z ){
545 0           sqliteVdbeAddOpList(v, ArraySize(getTmpDbLoc), getTmpDbLoc);
546             }else{
547 0           sqliteBeginWriteOperation(pParse, 0, 0);
548 0           sqliteVdbeAddOp(v, OP_Integer, getTempStore(zRight), 0);
549 0           sqliteVdbeAddOp(v, OP_SetCookie, 0, 5);
550 0           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 0 0         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 0           sqliteVdbeAddOpList(v, ArraySize(initCode), initCode);
614              
615             /* Do an integrity check on each database file */
616 0 0         for(i=0; inDb; i++){
617             HashElem *x;
618              
619             /* Do an integrity check of the B-Tree
620             */
621 0           addr = sqliteVdbeAddOpList(v, ArraySize(checkDb), checkDb);
622 0           sqliteVdbeChangeP1(v, addr+1, i);
623 0           sqliteVdbeChangeP2(v, addr+3, addr+7);
624 0           sqliteVdbeChangeP2(v, addr+6, addr+4);
625 0           sqliteVdbeChangeP2(v, addr+7, i);
626 0           sqliteVdbeChangeP2(v, addr+10, addr+ArraySize(checkDb));
627 0           sqliteVdbeChangeP3(v, addr+13, db->aDb[i].zName, P3_STATIC);
628              
629             /* Make sure all the indices are constructed correctly.
630             */
631 0           sqliteCodeVerifySchema(pParse, i);
632 0 0         for(x=sqliteHashFirst(&db->aDb[i].tblHash); x; x=sqliteHashNext(x)){
633 0           Table *pTab = sqliteHashData(x);
634             Index *pIdx;
635             int loopTop;
636              
637 0 0         if( pTab->pIndex==0 ) continue;
638 0           sqliteVdbeAddOp(v, OP_Integer, i, 0);
639 0           sqliteVdbeOp3(v, OP_OpenRead, 1, pTab->tnum, pTab->zName, 0);
640 0 0         for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
641 0 0         if( pIdx->tnum==0 ) continue;
642 0           sqliteVdbeAddOp(v, OP_Integer, pIdx->iDb, 0);
643 0           sqliteVdbeOp3(v, OP_OpenRead, j+2, pIdx->tnum, pIdx->zName, 0);
644             }
645 0           sqliteVdbeAddOp(v, OP_Integer, 0, 0);
646 0           sqliteVdbeAddOp(v, OP_MemStore, 1, 1);
647 0           loopTop = sqliteVdbeAddOp(v, OP_Rewind, 1, 0);
648 0           sqliteVdbeAddOp(v, OP_MemIncr, 1, 0);
649 0 0         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 0           sqliteVdbeAddOp(v, OP_Recno, 1, 0);
661 0 0         for(k=0; knColumn; k++){
662 0           int idx = pIdx->aiColumn[k];
663 0 0         if( idx==pTab->iPKey ){
664 0           sqliteVdbeAddOp(v, OP_Recno, 1, 0);
665             }else{
666 0           sqliteVdbeAddOp(v, OP_Column, 1, idx);
667             }
668             }
669 0           sqliteVdbeAddOp(v, OP_MakeIdxKey, pIdx->nColumn, 0);
670 0 0         if( db->file_format>=4 ) sqliteAddIdxKeyType(v, pIdx);
671 0           jmp2 = sqliteVdbeAddOp(v, OP_Found, j+2, 0);
672 0           addr = sqliteVdbeAddOpList(v, ArraySize(idxErr), idxErr);
673 0           sqliteVdbeChangeP3(v, addr+4, pIdx->zName, P3_STATIC);
674 0           sqliteVdbeChangeP2(v, jmp2, sqliteVdbeCurrentAddr(v));
675             }
676 0           sqliteVdbeAddOp(v, OP_Next, 1, loopTop+1);
677 0           sqliteVdbeChangeP2(v, loopTop, sqliteVdbeCurrentAddr(v));
678 0 0         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 0 0         if( pIdx->tnum==0 ) continue;
695 0           addr = sqliteVdbeAddOpList(v, ArraySize(cntIdx), cntIdx);
696 0           sqliteVdbeChangeP1(v, addr+2, j+2);
697 0           sqliteVdbeChangeP2(v, addr+2, addr+5);
698 0           sqliteVdbeChangeP1(v, addr+4, j+2);
699 0           sqliteVdbeChangeP2(v, addr+4, addr+3);
700 0           sqliteVdbeChangeP2(v, addr+7, addr+ArraySize(cntIdx));
701 0           sqliteVdbeChangeP3(v, addr+10, pIdx->zName, P3_STATIC);
702             }
703             }
704             }
705 0           addr = sqliteVdbeAddOpList(v, ArraySize(endCode), endCode);
706 0           sqliteVdbeChangeP2(v, addr+2, addr+ArraySize(endCode));
707             }else
708              
709             {}
710 50           sqliteFree(zLeft);
711 50           sqliteFree(zRight);
712             }