blob: d9cf6354aeedd90849754fe80345e430426e0d7b [file] [log] [blame]
drhc11d4f92003-04-06 21:08:24 +00001/*
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**
drh701a0ae2004-02-22 20:05:00 +000014** $Id: pragma.c,v 1.18 2004/02/22 20:05:01 drh Exp $
drhc11d4f92003-04-06 21:08:24 +000015*/
16#include "sqliteInt.h"
drh13bff812003-04-15 01:19:47 +000017#include <ctype.h>
drhc11d4f92003-04-06 21:08:24 +000018
19/*
20** Interpret the given string as a boolean value.
21*/
drh87223182004-02-21 14:00:29 +000022static int getBoolean(const char *z){
drhc11d4f92003-04-06 21:08:24 +000023 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,
jplyonb1639ff2004-01-19 04:52:29 +000037** 1 for ON or NORMAL and 2 for FULL. Return 1 for an empty or
38** unrecognized string argument.
drhc11d4f92003-04-06 21:08:24 +000039**
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*/
45static 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/*
paulb0208cc2003-04-13 18:26:49 +000070** 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*/
drh13bff812003-04-15 01:19:47 +000074static int getTempStore(char *z){
drh45a304e2003-04-25 02:43:08 +000075 if( z[0]>='0' || z[0]<='2' ){
76 return z[0] - '0';
77 }else if( sqliteStrICmp(z, "file")==0 ){
drh13bff812003-04-15 01:19:47 +000078 return 1;
drh45a304e2003-04-25 02:43:08 +000079 }else if( sqliteStrICmp(z, "memory")==0 ){
drh13bff812003-04-15 01:19:47 +000080 return 2;
81 }else{
82 return 0;
83 }
paulb0208cc2003-04-13 18:26:49 +000084}
85
86/*
drh87223182004-02-21 14:00:29 +000087** Check to see if zRight and zLeft refer to a pragma that queries
88** or changes one of the flags in db->flags. Return 1 if so and 0 if not.
89** Also, implement the pragma.
90*/
91static int flagPragma(Parse *pParse, const char *zLeft, const char *zRight){
92 static const struct {
93 const char *zName; /* Name of the pragma */
94 int mask; /* Mask for the db->flags value */
95 } aPragma[] = {
96 { "vdbe_trace", SQLITE_VdbeTrace },
97 { "full_column_names", SQLITE_FullColNames },
98 { "short_column_names", SQLITE_ShortColNames },
99 { "show_datatypes", SQLITE_ReportTypes },
100 { "count_changes", SQLITE_CountRows },
101 { "empty_result_callbacks", SQLITE_NullCallback },
102 };
103 int i;
104 for(i=0; i<sizeof(aPragma)/sizeof(aPragma[0]); i++){
105 if( sqliteStrICmp(zLeft, aPragma[i].zName)==0 ){
106 sqlite *db = pParse->db;
107 Vdbe *v;
108 if( strcmp(zLeft,zRight)==0 && (v = sqliteGetVdbe(pParse))!=0 ){
drh701a0ae2004-02-22 20:05:00 +0000109 sqliteVdbeOp3(v, OP_ColumnName, 0, 1, aPragma[i].zName, P3_STATIC);
110 sqliteVdbeOp3(v, OP_ColumnName, 1, 0, "boolean", P3_STATIC);
111 sqliteVdbeCode(v, OP_Integer, (db->flags & aPragma[i].mask)!=0, 0,
112 OP_Callback, 1, 0,
113 0);
drh87223182004-02-21 14:00:29 +0000114 }else if( getBoolean(zRight) ){
115 db->flags |= aPragma[i].mask;
116 }else{
117 db->flags &= ~aPragma[i].mask;
118 }
119 return 1;
120 }
121 }
122 return 0;
123}
124
125/*
drhc11d4f92003-04-06 21:08:24 +0000126** Process a pragma statement.
127**
128** Pragmas are of this form:
129**
130** PRAGMA id = value
131**
132** The identifier might also be a string. The value is a string, and
133** identifier, or a number. If minusFlag is true, then the value is
134** a number that was preceded by a minus sign.
135*/
136void sqlitePragma(Parse *pParse, Token *pLeft, Token *pRight, int minusFlag){
137 char *zLeft = 0;
138 char *zRight = 0;
139 sqlite *db = pParse->db;
140 Vdbe *v = sqliteGetVdbe(pParse);
141 if( v==0 ) return;
142
143 zLeft = sqliteStrNDup(pLeft->z, pLeft->n);
144 sqliteDequote(zLeft);
145 if( minusFlag ){
146 zRight = 0;
147 sqliteSetNString(&zRight, "-", 1, pRight->z, pRight->n, 0);
148 }else{
149 zRight = sqliteStrNDup(pRight->z, pRight->n);
150 sqliteDequote(zRight);
151 }
drhe22a3342003-04-22 20:30:37 +0000152 if( sqliteAuthCheck(pParse, SQLITE_PRAGMA, zLeft, zRight, 0) ){
drhc11d4f92003-04-06 21:08:24 +0000153 sqliteFree(zLeft);
154 sqliteFree(zRight);
155 return;
156 }
157
158 /*
159 ** PRAGMA default_cache_size
160 ** PRAGMA default_cache_size=N
161 **
162 ** The first form reports the current persistent setting for the
163 ** page cache size. The value returned is the maximum number of
164 ** pages in the page cache. The second form sets both the current
165 ** page cache size value and the persistent page cache size value
166 ** stored in the database file.
167 **
168 ** The default cache size is stored in meta-value 2 of page 1 of the
169 ** database file. The cache size is actually the absolute value of
170 ** this memory location. The sign of meta-value 2 determines the
171 ** synchronous setting. A negative value means synchronous is off
172 ** and a positive value means synchronous is on.
173 */
174 if( sqliteStrICmp(zLeft,"default_cache_size")==0 ){
drh905793e2004-02-21 13:31:09 +0000175 static VdbeOpList getCacheSize[] = {
drhc11d4f92003-04-06 21:08:24 +0000176 { OP_ReadCookie, 0, 2, 0},
177 { OP_AbsValue, 0, 0, 0},
178 { OP_Dup, 0, 0, 0},
179 { OP_Integer, 0, 0, 0},
180 { OP_Ne, 0, 6, 0},
drh905793e2004-02-21 13:31:09 +0000181 { OP_Integer, 0, 0, 0}, /* 5 */
drhd6502752004-02-16 03:44:01 +0000182 { OP_ColumnName, 0, 1, "cache_size"},
drhc11d4f92003-04-06 21:08:24 +0000183 { OP_Callback, 1, 0, 0},
184 };
drh905793e2004-02-21 13:31:09 +0000185 int addr;
drhc11d4f92003-04-06 21:08:24 +0000186 if( pRight->z==pLeft->z ){
drh905793e2004-02-21 13:31:09 +0000187 addr = sqliteVdbeAddOpList(v, ArraySize(getCacheSize), getCacheSize);
188 sqliteVdbeChangeP1(v, addr+5, MAX_PAGES);
drhc11d4f92003-04-06 21:08:24 +0000189 }else{
drhc11d4f92003-04-06 21:08:24 +0000190 int size = atoi(zRight);
191 if( size<0 ) size = -size;
192 sqliteBeginWriteOperation(pParse, 0, 0);
193 sqliteVdbeAddOp(v, OP_Integer, size, 0);
194 sqliteVdbeAddOp(v, OP_ReadCookie, 0, 2);
195 addr = sqliteVdbeAddOp(v, OP_Integer, 0, 0);
196 sqliteVdbeAddOp(v, OP_Ge, 0, addr+3);
197 sqliteVdbeAddOp(v, OP_Negative, 0, 0);
198 sqliteVdbeAddOp(v, OP_SetCookie, 0, 2);
199 sqliteEndWriteOperation(pParse);
200 db->cache_size = db->cache_size<0 ? -size : size;
201 sqliteBtreeSetCacheSize(db->aDb[0].pBt, db->cache_size);
202 }
203 }else
204
205 /*
206 ** PRAGMA cache_size
207 ** PRAGMA cache_size=N
208 **
209 ** The first form reports the current local setting for the
210 ** page cache size. The local setting can be different from
211 ** the persistent cache size value that is stored in the database
212 ** file itself. The value returned is the maximum number of
213 ** pages in the page cache. The second form sets the local
214 ** page cache size value. It does not change the persistent
215 ** cache size stored on the disk so the cache size will revert
216 ** to its default value when the database is closed and reopened.
217 ** N should be a positive integer.
218 */
219 if( sqliteStrICmp(zLeft,"cache_size")==0 ){
drh905793e2004-02-21 13:31:09 +0000220 static VdbeOpList getCacheSize[] = {
drhd6502752004-02-16 03:44:01 +0000221 { OP_ColumnName, 0, 1, "cache_size"},
drhc11d4f92003-04-06 21:08:24 +0000222 { OP_Callback, 1, 0, 0},
223 };
224 if( pRight->z==pLeft->z ){
225 int size = db->cache_size;;
226 if( size<0 ) size = -size;
227 sqliteVdbeAddOp(v, OP_Integer, size, 0);
228 sqliteVdbeAddOpList(v, ArraySize(getCacheSize), getCacheSize);
229 }else{
230 int size = atoi(zRight);
231 if( size<0 ) size = -size;
232 if( db->cache_size<0 ) size = -size;
233 db->cache_size = size;
234 sqliteBtreeSetCacheSize(db->aDb[0].pBt, db->cache_size);
235 }
236 }else
237
238 /*
239 ** PRAGMA default_synchronous
240 ** PRAGMA default_synchronous=ON|OFF|NORMAL|FULL
241 **
242 ** The first form returns the persistent value of the "synchronous" setting
243 ** that is stored in the database. This is the synchronous setting that
244 ** is used whenever the database is opened unless overridden by a separate
245 ** "synchronous" pragma. The second form changes the persistent and the
246 ** local synchronous setting to the value given.
247 **
248 ** If synchronous is OFF, SQLite does not attempt any fsync() systems calls
249 ** to make sure data is committed to disk. Write operations are very fast,
250 ** but a power failure can leave the database in an inconsistent state.
251 ** If synchronous is ON or NORMAL, SQLite will do an fsync() system call to
252 ** make sure data is being written to disk. The risk of corruption due to
253 ** a power loss in this mode is negligible but non-zero. If synchronous
254 ** is FULL, extra fsync()s occur to reduce the risk of corruption to near
255 ** zero, but with a write performance penalty. The default mode is NORMAL.
256 */
257 if( sqliteStrICmp(zLeft,"default_synchronous")==0 ){
drh905793e2004-02-21 13:31:09 +0000258 static VdbeOpList getSync[] = {
drhd6502752004-02-16 03:44:01 +0000259 { OP_ColumnName, 0, 1, "synchronous"},
drhc11d4f92003-04-06 21:08:24 +0000260 { OP_ReadCookie, 0, 3, 0},
261 { OP_Dup, 0, 0, 0},
262 { OP_If, 0, 0, 0}, /* 3 */
263 { OP_ReadCookie, 0, 2, 0},
264 { OP_Integer, 0, 0, 0},
265 { OP_Lt, 0, 5, 0},
266 { OP_AddImm, 1, 0, 0},
267 { OP_Callback, 1, 0, 0},
268 { OP_Halt, 0, 0, 0},
269 { OP_AddImm, -1, 0, 0}, /* 10 */
270 { OP_Callback, 1, 0, 0}
271 };
272 if( pRight->z==pLeft->z ){
273 int addr = sqliteVdbeAddOpList(v, ArraySize(getSync), getSync);
274 sqliteVdbeChangeP2(v, addr+3, addr+10);
275 }else{
276 int addr;
277 int size = db->cache_size;
278 if( size<0 ) size = -size;
279 sqliteBeginWriteOperation(pParse, 0, 0);
280 sqliteVdbeAddOp(v, OP_ReadCookie, 0, 2);
281 sqliteVdbeAddOp(v, OP_Dup, 0, 0);
282 addr = sqliteVdbeAddOp(v, OP_Integer, 0, 0);
283 sqliteVdbeAddOp(v, OP_Ne, 0, addr+3);
284 sqliteVdbeAddOp(v, OP_AddImm, MAX_PAGES, 0);
285 sqliteVdbeAddOp(v, OP_AbsValue, 0, 0);
286 db->safety_level = getSafetyLevel(zRight)+1;
287 if( db->safety_level==1 ){
288 sqliteVdbeAddOp(v, OP_Negative, 0, 0);
289 size = -size;
290 }
291 sqliteVdbeAddOp(v, OP_SetCookie, 0, 2);
292 sqliteVdbeAddOp(v, OP_Integer, db->safety_level, 0);
293 sqliteVdbeAddOp(v, OP_SetCookie, 0, 3);
294 sqliteEndWriteOperation(pParse);
295 db->cache_size = size;
296 sqliteBtreeSetCacheSize(db->aDb[0].pBt, db->cache_size);
297 sqliteBtreeSetSafetyLevel(db->aDb[0].pBt, db->safety_level);
298 }
299 }else
300
301 /*
302 ** PRAGMA synchronous
303 ** PRAGMA synchronous=OFF|ON|NORMAL|FULL
304 **
305 ** Return or set the local value of the synchronous flag. Changing
306 ** the local value does not make changes to the disk file and the
307 ** default value will be restored the next time the database is
308 ** opened.
309 */
310 if( sqliteStrICmp(zLeft,"synchronous")==0 ){
drh905793e2004-02-21 13:31:09 +0000311 static VdbeOpList getSync[] = {
drhd6502752004-02-16 03:44:01 +0000312 { OP_ColumnName, 0, 1, "synchronous"},
drhc11d4f92003-04-06 21:08:24 +0000313 { OP_Callback, 1, 0, 0},
314 };
315 if( pRight->z==pLeft->z ){
316 sqliteVdbeAddOp(v, OP_Integer, db->safety_level-1, 0);
317 sqliteVdbeAddOpList(v, ArraySize(getSync), getSync);
318 }else{
319 int size = db->cache_size;
320 if( size<0 ) size = -size;
321 db->safety_level = getSafetyLevel(zRight)+1;
322 if( db->safety_level==1 ) size = -size;
323 db->cache_size = size;
324 sqliteBtreeSetCacheSize(db->aDb[0].pBt, db->cache_size);
325 sqliteBtreeSetSafetyLevel(db->aDb[0].pBt, db->safety_level);
326 }
327 }else
328
drh87223182004-02-21 14:00:29 +0000329#ifndef NDEBUG
drhc11d4f92003-04-06 21:08:24 +0000330 if( sqliteStrICmp(zLeft, "trigger_overhead_test")==0 ){
331 if( getBoolean(zRight) ){
332 always_code_trigger_setup = 1;
333 }else{
334 always_code_trigger_setup = 0;
335 }
336 }else
drh87223182004-02-21 14:00:29 +0000337#endif
drhc11d4f92003-04-06 21:08:24 +0000338
drh87223182004-02-21 14:00:29 +0000339 if( flagPragma(pParse, zLeft, zRight) ){
340 /* The flagPragma() call also generates any necessary code */
drhc11d4f92003-04-06 21:08:24 +0000341 }else
342
343 if( sqliteStrICmp(zLeft, "table_info")==0 ){
344 Table *pTab;
345 pTab = sqliteFindTable(db, zRight, 0);
346 if( pTab ){
drh905793e2004-02-21 13:31:09 +0000347 static VdbeOpList tableInfoPreface[] = {
drhc11d4f92003-04-06 21:08:24 +0000348 { OP_ColumnName, 0, 0, "cid"},
349 { OP_ColumnName, 1, 0, "name"},
350 { OP_ColumnName, 2, 0, "type"},
351 { OP_ColumnName, 3, 0, "notnull"},
352 { OP_ColumnName, 4, 0, "dflt_value"},
drhd6502752004-02-16 03:44:01 +0000353 { OP_ColumnName, 5, 1, "pk"},
drhc11d4f92003-04-06 21:08:24 +0000354 };
355 int i;
356 sqliteVdbeAddOpList(v, ArraySize(tableInfoPreface), tableInfoPreface);
357 sqliteViewGetColumnNames(pParse, pTab);
358 for(i=0; i<pTab->nCol; i++){
359 sqliteVdbeAddOp(v, OP_Integer, i, 0);
drh701a0ae2004-02-22 20:05:00 +0000360 sqliteVdbeOp3(v, OP_String, 0, 0, pTab->aCol[i].zName, 0);
361 sqliteVdbeOp3(v, OP_String, 0, 0,
362 pTab->aCol[i].zType ? pTab->aCol[i].zType : "numeric", 0);
drhc11d4f92003-04-06 21:08:24 +0000363 sqliteVdbeAddOp(v, OP_Integer, pTab->aCol[i].notNull, 0);
drh701a0ae2004-02-22 20:05:00 +0000364 sqliteVdbeOp3(v, OP_String, 0, 0,
365 pTab->aCol[i].zDflt, P3_STATIC);
drh78100cc2003-08-23 22:40:53 +0000366 sqliteVdbeAddOp(v, OP_Integer, pTab->aCol[i].isPrimKey, 0);
367 sqliteVdbeAddOp(v, OP_Callback, 6, 0);
drhc11d4f92003-04-06 21:08:24 +0000368 }
369 }
370 }else
371
372 if( sqliteStrICmp(zLeft, "index_info")==0 ){
373 Index *pIdx;
374 Table *pTab;
375 pIdx = sqliteFindIndex(db, zRight, 0);
376 if( pIdx ){
drh905793e2004-02-21 13:31:09 +0000377 static VdbeOpList tableInfoPreface[] = {
drhc11d4f92003-04-06 21:08:24 +0000378 { OP_ColumnName, 0, 0, "seqno"},
379 { OP_ColumnName, 1, 0, "cid"},
drhd6502752004-02-16 03:44:01 +0000380 { OP_ColumnName, 2, 1, "name"},
drhc11d4f92003-04-06 21:08:24 +0000381 };
382 int i;
383 pTab = pIdx->pTable;
384 sqliteVdbeAddOpList(v, ArraySize(tableInfoPreface), tableInfoPreface);
385 for(i=0; i<pIdx->nColumn; i++){
386 int cnum = pIdx->aiColumn[i];
387 sqliteVdbeAddOp(v, OP_Integer, i, 0);
388 sqliteVdbeAddOp(v, OP_Integer, cnum, 0);
drhc11d4f92003-04-06 21:08:24 +0000389 assert( pTab->nCol>cnum );
drh701a0ae2004-02-22 20:05:00 +0000390 sqliteVdbeOp3(v, OP_String, 0, 0, pTab->aCol[cnum].zName, 0);
drhc11d4f92003-04-06 21:08:24 +0000391 sqliteVdbeAddOp(v, OP_Callback, 3, 0);
392 }
393 }
394 }else
395
396 if( sqliteStrICmp(zLeft, "index_list")==0 ){
397 Index *pIdx;
398 Table *pTab;
399 pTab = sqliteFindTable(db, zRight, 0);
400 if( pTab ){
401 v = sqliteGetVdbe(pParse);
402 pIdx = pTab->pIndex;
403 }
404 if( pTab && pIdx ){
405 int i = 0;
drh905793e2004-02-21 13:31:09 +0000406 static VdbeOpList indexListPreface[] = {
drhc11d4f92003-04-06 21:08:24 +0000407 { OP_ColumnName, 0, 0, "seq"},
408 { OP_ColumnName, 1, 0, "name"},
drhd6502752004-02-16 03:44:01 +0000409 { OP_ColumnName, 2, 1, "unique"},
drhc11d4f92003-04-06 21:08:24 +0000410 };
411
412 sqliteVdbeAddOpList(v, ArraySize(indexListPreface), indexListPreface);
413 while(pIdx){
414 sqliteVdbeAddOp(v, OP_Integer, i, 0);
drh701a0ae2004-02-22 20:05:00 +0000415 sqliteVdbeOp3(v, OP_String, 0, 0, pIdx->zName, 0);
drhc11d4f92003-04-06 21:08:24 +0000416 sqliteVdbeAddOp(v, OP_Integer, pIdx->onError!=OE_None, 0);
417 sqliteVdbeAddOp(v, OP_Callback, 3, 0);
418 ++i;
419 pIdx = pIdx->pNext;
420 }
421 }
422 }else
423
drh78100cc2003-08-23 22:40:53 +0000424 if( sqliteStrICmp(zLeft, "foreign_key_list")==0 ){
425 FKey *pFK;
426 Table *pTab;
427 pTab = sqliteFindTable(db, zRight, 0);
428 if( pTab ){
429 v = sqliteGetVdbe(pParse);
430 pFK = pTab->pFKey;
431 }
432 if( pTab && pFK ){
433 int i = 0;
drh905793e2004-02-21 13:31:09 +0000434 static VdbeOpList indexListPreface[] = {
drh78100cc2003-08-23 22:40:53 +0000435 { OP_ColumnName, 0, 0, "id"},
436 { OP_ColumnName, 1, 0, "seq"},
437 { OP_ColumnName, 2, 0, "table"},
438 { OP_ColumnName, 3, 0, "from"},
drhd6502752004-02-16 03:44:01 +0000439 { OP_ColumnName, 4, 1, "to"},
drh78100cc2003-08-23 22:40:53 +0000440 };
441
442 sqliteVdbeAddOpList(v, ArraySize(indexListPreface), indexListPreface);
443 while(pFK){
444 int j;
445 for(j=0; j<pFK->nCol; j++){
446 sqliteVdbeAddOp(v, OP_Integer, i, 0);
447 sqliteVdbeAddOp(v, OP_Integer, j, 0);
drh701a0ae2004-02-22 20:05:00 +0000448 sqliteVdbeOp3(v, OP_String, 0, 0, pFK->zTo, 0);
449 sqliteVdbeOp3(v, OP_String, 0, 0,
450 pTab->aCol[pFK->aCol[j].iFrom].zName, 0);
451 sqliteVdbeOp3(v, OP_String, 0, 0, pFK->aCol[j].zCol, 0);
drh78100cc2003-08-23 22:40:53 +0000452 sqliteVdbeAddOp(v, OP_Callback, 5, 0);
453 }
454 ++i;
455 pFK = pFK->pNextFrom;
456 }
457 }
458 }else
459
drhc11d4f92003-04-06 21:08:24 +0000460 if( sqliteStrICmp(zLeft, "database_list")==0 ){
461 int i;
drh905793e2004-02-21 13:31:09 +0000462 static VdbeOpList indexListPreface[] = {
drhc11d4f92003-04-06 21:08:24 +0000463 { OP_ColumnName, 0, 0, "seq"},
464 { OP_ColumnName, 1, 0, "name"},
drhd6502752004-02-16 03:44:01 +0000465 { OP_ColumnName, 2, 1, "file"},
drhc11d4f92003-04-06 21:08:24 +0000466 };
467
468 sqliteVdbeAddOpList(v, ArraySize(indexListPreface), indexListPreface);
469 for(i=0; i<db->nDb; i++){
470 if( db->aDb[i].pBt==0 ) continue;
471 assert( db->aDb[i].zName!=0 );
472 sqliteVdbeAddOp(v, OP_Integer, i, 0);
drh701a0ae2004-02-22 20:05:00 +0000473 sqliteVdbeOp3(v, OP_String, 0, 0, db->aDb[i].zName, 0);
474 sqliteVdbeOp3(v, OP_String, 0, 0,
475 sqliteBtreeGetFilename(db->aDb[i].pBt), 0);
drh5e8e1982003-06-04 15:48:33 +0000476 sqliteVdbeAddOp(v, OP_Callback, 3, 0);
drhc11d4f92003-04-06 21:08:24 +0000477 }
478 }else
drh78100cc2003-08-23 22:40:53 +0000479
480
paulb0208cc2003-04-13 18:26:49 +0000481 /*
drh13bff812003-04-15 01:19:47 +0000482 ** PRAGMA temp_store
483 ** PRAGMA temp_store = "default"|"memory"|"file"
paulb0208cc2003-04-13 18:26:49 +0000484 **
drh13bff812003-04-15 01:19:47 +0000485 ** Return or set the local value of the temp_store flag. Changing
paulb0208cc2003-04-13 18:26:49 +0000486 ** the local value does not make changes to the disk file and the default
487 ** value will be restored the next time the database is opened.
488 **
489 ** Note that it is possible for the library compile-time options to
490 ** override this setting
491 */
drh13bff812003-04-15 01:19:47 +0000492 if( sqliteStrICmp(zLeft, "temp_store")==0 ){
drh905793e2004-02-21 13:31:09 +0000493 static VdbeOpList getTmpDbLoc[] = {
drhd6502752004-02-16 03:44:01 +0000494 { OP_ColumnName, 0, 1, "temp_store"},
paulb0208cc2003-04-13 18:26:49 +0000495 { OP_Callback, 1, 0, 0},
496 };
497 if( pRight->z==pLeft->z ){
drh13bff812003-04-15 01:19:47 +0000498 sqliteVdbeAddOp(v, OP_Integer, db->temp_store, 0);
paulb0208cc2003-04-13 18:26:49 +0000499 sqliteVdbeAddOpList(v, ArraySize(getTmpDbLoc), getTmpDbLoc);
500 }else{
501 if (&db->aDb[1].pBt != 0) {
drh13bff812003-04-15 01:19:47 +0000502 sqliteErrorMsg(pParse, "The temporary database already exists - "
503 "its location cannot now be changed");
paulb0208cc2003-04-13 18:26:49 +0000504 } else {
drh13bff812003-04-15 01:19:47 +0000505 db->temp_store = getTempStore(zRight);
paulb0208cc2003-04-13 18:26:49 +0000506 }
507 }
508 }else
drh13bff812003-04-15 01:19:47 +0000509
paulb0208cc2003-04-13 18:26:49 +0000510 /*
drh13bff812003-04-15 01:19:47 +0000511 ** PRAGMA default_temp_store
512 ** PRAGMA default_temp_store = "default"|"memory"|"file"
paulb0208cc2003-04-13 18:26:49 +0000513 **
drh13bff812003-04-15 01:19:47 +0000514 ** Return or set the value of the persistent temp_store flag (as
paulb0208cc2003-04-13 18:26:49 +0000515 ** well as the value currently in force).
516 **
517 ** Note that it is possible for the library compile-time options to
518 ** override this setting
519 */
drh13bff812003-04-15 01:19:47 +0000520 if( sqliteStrICmp(zLeft, "default_temp_store")==0 ){
drh905793e2004-02-21 13:31:09 +0000521 static VdbeOpList getTmpDbLoc[] = {
drhd6502752004-02-16 03:44:01 +0000522 { OP_ColumnName, 0, 1, "temp_store"},
paulb0208cc2003-04-13 18:26:49 +0000523 { OP_ReadCookie, 0, 5, 0},
524 { OP_Callback, 1, 0, 0}};
525 if( pRight->z==pLeft->z ){
526 sqliteVdbeAddOpList(v, ArraySize(getTmpDbLoc), getTmpDbLoc);
527 }else{
528 if (&db->aDb[1].pBt != 0) {
drh13bff812003-04-15 01:19:47 +0000529 sqliteErrorMsg(pParse, "The temporary database already exists - "
530 "its location cannot now be changed");
paulb0208cc2003-04-13 18:26:49 +0000531 } else {
532 sqliteBeginWriteOperation(pParse, 0, 0);
drh13bff812003-04-15 01:19:47 +0000533 db->temp_store = getTempStore(zRight);
534 sqliteVdbeAddOp(v, OP_Integer, db->temp_store, 0);
paulb0208cc2003-04-13 18:26:49 +0000535 sqliteVdbeAddOp(v, OP_SetCookie, 0, 5);
536 sqliteEndWriteOperation(pParse);
537 }
538 }
539 }else
drhc11d4f92003-04-06 21:08:24 +0000540
541#ifndef NDEBUG
542 if( sqliteStrICmp(zLeft, "parser_trace")==0 ){
543 extern void sqliteParserTrace(FILE*, char *);
544 if( getBoolean(zRight) ){
545 sqliteParserTrace(stdout, "parser: ");
546 }else{
547 sqliteParserTrace(0, 0);
548 }
549 }else
550#endif
551
552 if( sqliteStrICmp(zLeft, "integrity_check")==0 ){
drhed717fe2003-06-15 23:42:24 +0000553 int i, j, addr;
554
555 /* Code that initializes the integrity check program. Set the
drh4be295b2003-12-16 03:44:47 +0000556 ** error count 0
drhed717fe2003-06-15 23:42:24 +0000557 */
drh905793e2004-02-21 13:31:09 +0000558 static VdbeOpList initCode[] = {
drh4be295b2003-12-16 03:44:47 +0000559 { OP_Integer, 0, 0, 0},
drhed717fe2003-06-15 23:42:24 +0000560 { OP_MemStore, 0, 1, 0},
drhd6502752004-02-16 03:44:01 +0000561 { OP_ColumnName, 0, 1, "integrity_check"},
drhed717fe2003-06-15 23:42:24 +0000562 };
563
564 /* Code to do an BTree integrity check on a single database file.
565 */
drh905793e2004-02-21 13:31:09 +0000566 static VdbeOpList checkDb[] = {
drhc11d4f92003-04-06 21:08:24 +0000567 { OP_SetInsert, 0, 0, "2"},
drhed717fe2003-06-15 23:42:24 +0000568 { OP_Integer, 0, 0, 0}, /* 1 */
drhc11d4f92003-04-06 21:08:24 +0000569 { OP_OpenRead, 0, 2, 0},
drhed717fe2003-06-15 23:42:24 +0000570 { OP_Rewind, 0, 7, 0}, /* 3 */
drhc11d4f92003-04-06 21:08:24 +0000571 { OP_Column, 0, 3, 0}, /* 4 */
572 { OP_SetInsert, 0, 0, 0},
drhed717fe2003-06-15 23:42:24 +0000573 { OP_Next, 0, 4, 0}, /* 6 */
drhc11d4f92003-04-06 21:08:24 +0000574 { OP_IntegrityCk, 0, 0, 0}, /* 7 */
drhed717fe2003-06-15 23:42:24 +0000575 { OP_Dup, 0, 1, 0},
576 { OP_String, 0, 0, "ok"},
577 { OP_StrEq, 0, 12, 0}, /* 10 */
drh4be295b2003-12-16 03:44:47 +0000578 { OP_MemIncr, 0, 0, 0},
drhed717fe2003-06-15 23:42:24 +0000579 { OP_String, 0, 0, "*** in database "},
580 { OP_String, 0, 0, 0}, /* 13 */
581 { OP_String, 0, 0, " ***\n"},
drh4be295b2003-12-16 03:44:47 +0000582 { OP_Pull, 3, 0, 0},
583 { OP_Concat, 4, 1, 0},
584 { OP_Callback, 1, 0, 0},
drhed717fe2003-06-15 23:42:24 +0000585 };
586
587 /* Code that appears at the end of the integrity check. If no error
588 ** messages have been generated, output OK. Otherwise output the
589 ** error message
590 */
drh905793e2004-02-21 13:31:09 +0000591 static VdbeOpList endCode[] = {
drhed717fe2003-06-15 23:42:24 +0000592 { OP_MemLoad, 0, 0, 0},
drh4be295b2003-12-16 03:44:47 +0000593 { OP_Integer, 0, 0, 0},
594 { OP_Ne, 0, 0, 0}, /* 2 */
drhed717fe2003-06-15 23:42:24 +0000595 { OP_String, 0, 0, "ok"},
drhc11d4f92003-04-06 21:08:24 +0000596 { OP_Callback, 1, 0, 0},
597 };
drhed717fe2003-06-15 23:42:24 +0000598
599 /* Initialize the VDBE program */
600 sqliteVdbeAddOpList(v, ArraySize(initCode), initCode);
601
602 /* Do an integrity check on each database file */
603 for(i=0; i<db->nDb; i++){
604 HashElem *x;
605
606 /* Do an integrity check of the B-Tree
607 */
608 addr = sqliteVdbeAddOpList(v, ArraySize(checkDb), checkDb);
609 sqliteVdbeChangeP1(v, addr+1, i);
610 sqliteVdbeChangeP2(v, addr+3, addr+7);
611 sqliteVdbeChangeP2(v, addr+6, addr+4);
612 sqliteVdbeChangeP2(v, addr+7, i);
drh4be295b2003-12-16 03:44:47 +0000613 sqliteVdbeChangeP2(v, addr+10, addr+ArraySize(checkDb));
drhed717fe2003-06-15 23:42:24 +0000614 sqliteVdbeChangeP3(v, addr+13, db->aDb[i].zName, P3_STATIC);
615
616 /* Make sure all the indices are constructed correctly.
617 */
618 sqliteCodeVerifySchema(pParse, i);
619 for(x=sqliteHashFirst(&db->aDb[i].tblHash); x; x=sqliteHashNext(x)){
620 Table *pTab = sqliteHashData(x);
621 Index *pIdx;
622 int loopTop;
623
624 if( pTab->pIndex==0 ) continue;
625 sqliteVdbeAddOp(v, OP_Integer, i, 0);
drh701a0ae2004-02-22 20:05:00 +0000626 sqliteVdbeOp3(v, OP_OpenRead, 1, pTab->tnum, pTab->zName, 0);
drhed717fe2003-06-15 23:42:24 +0000627 for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
628 if( pIdx->tnum==0 ) continue;
629 sqliteVdbeAddOp(v, OP_Integer, pIdx->iDb, 0);
drh701a0ae2004-02-22 20:05:00 +0000630 sqliteVdbeOp3(v, OP_OpenRead, j+2, pIdx->tnum, pIdx->zName, 0);
drhed717fe2003-06-15 23:42:24 +0000631 }
632 sqliteVdbeAddOp(v, OP_Integer, 0, 0);
633 sqliteVdbeAddOp(v, OP_MemStore, 1, 1);
634 loopTop = sqliteVdbeAddOp(v, OP_Rewind, 1, 0);
635 sqliteVdbeAddOp(v, OP_MemIncr, 1, 0);
636 for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
637 int k, jmp2;
drh905793e2004-02-21 13:31:09 +0000638 static VdbeOpList idxErr[] = {
drh4be295b2003-12-16 03:44:47 +0000639 { OP_MemIncr, 0, 0, 0},
drhed717fe2003-06-15 23:42:24 +0000640 { OP_String, 0, 0, "rowid "},
641 { OP_Recno, 1, 0, 0},
642 { OP_String, 0, 0, " missing from index "},
643 { OP_String, 0, 0, 0}, /* 4 */
drh4be295b2003-12-16 03:44:47 +0000644 { OP_Concat, 4, 0, 0},
645 { OP_Callback, 1, 0, 0},
drhed717fe2003-06-15 23:42:24 +0000646 };
647 sqliteVdbeAddOp(v, OP_Recno, 1, 0);
648 for(k=0; k<pIdx->nColumn; k++){
649 int idx = pIdx->aiColumn[k];
650 if( idx==pTab->iPKey ){
651 sqliteVdbeAddOp(v, OP_Recno, 1, 0);
652 }else{
653 sqliteVdbeAddOp(v, OP_Column, 1, idx);
654 }
655 }
656 sqliteVdbeAddOp(v, OP_MakeIdxKey, pIdx->nColumn, 0);
657 if( db->file_format>=4 ) sqliteAddIdxKeyType(v, pIdx);
658 jmp2 = sqliteVdbeAddOp(v, OP_Found, j+2, 0);
659 addr = sqliteVdbeAddOpList(v, ArraySize(idxErr), idxErr);
660 sqliteVdbeChangeP3(v, addr+4, pIdx->zName, P3_STATIC);
661 sqliteVdbeChangeP2(v, jmp2, sqliteVdbeCurrentAddr(v));
662 }
663 sqliteVdbeAddOp(v, OP_Next, 1, loopTop+1);
664 sqliteVdbeChangeP2(v, loopTop, sqliteVdbeCurrentAddr(v));
665 for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
drh905793e2004-02-21 13:31:09 +0000666 static VdbeOpList cntIdx[] = {
drhed717fe2003-06-15 23:42:24 +0000667 { OP_Integer, 0, 0, 0},
668 { OP_MemStore, 2, 1, 0},
669 { OP_Rewind, 0, 0, 0}, /* 2 */
670 { OP_MemIncr, 2, 0, 0},
671 { OP_Next, 0, 0, 0}, /* 4 */
672 { OP_MemLoad, 1, 0, 0},
673 { OP_MemLoad, 2, 0, 0},
674 { OP_Eq, 0, 0, 0}, /* 7 */
drh4be295b2003-12-16 03:44:47 +0000675 { OP_MemIncr, 0, 0, 0},
drhed717fe2003-06-15 23:42:24 +0000676 { OP_String, 0, 0, "wrong # of entries in index "},
677 { OP_String, 0, 0, 0}, /* 10 */
drh4be295b2003-12-16 03:44:47 +0000678 { OP_Concat, 2, 0, 0},
679 { OP_Callback, 1, 0, 0},
drhed717fe2003-06-15 23:42:24 +0000680 };
681 if( pIdx->tnum==0 ) continue;
682 addr = sqliteVdbeAddOpList(v, ArraySize(cntIdx), cntIdx);
683 sqliteVdbeChangeP1(v, addr+2, j+2);
684 sqliteVdbeChangeP2(v, addr+2, addr+5);
685 sqliteVdbeChangeP1(v, addr+4, j+2);
686 sqliteVdbeChangeP2(v, addr+4, addr+3);
687 sqliteVdbeChangeP2(v, addr+7, addr+ArraySize(cntIdx));
688 sqliteVdbeChangeP3(v, addr+10, pIdx->zName, P3_STATIC);
689 }
690 }
691 }
692 addr = sqliteVdbeAddOpList(v, ArraySize(endCode), endCode);
drh4be295b2003-12-16 03:44:47 +0000693 sqliteVdbeChangeP2(v, addr+2, addr+ArraySize(endCode));
drhc11d4f92003-04-06 21:08:24 +0000694 }else
695
696 {}
697 sqliteFree(zLeft);
698 sqliteFree(zRight);
699}