diff options
Diffstat (limited to '')
-rwxr-xr-x | libraries/sqlite/win32/pragma.c | 1186 |
1 files changed, 1186 insertions, 0 deletions
diff --git a/libraries/sqlite/win32/pragma.c b/libraries/sqlite/win32/pragma.c new file mode 100755 index 0000000..b4d9774 --- /dev/null +++ b/libraries/sqlite/win32/pragma.c | |||
@@ -0,0 +1,1186 @@ | |||
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.149 2007/08/31 18:34:59 drh Exp $ | ||
15 | */ | ||
16 | #include "sqliteInt.h" | ||
17 | #include <ctype.h> | ||
18 | |||
19 | /* Ignore this whole file if pragmas are disabled | ||
20 | */ | ||
21 | #if !defined(SQLITE_OMIT_PRAGMA) && !defined(SQLITE_OMIT_PARSER) | ||
22 | |||
23 | /* | ||
24 | ** Interpret the given string as a safety level. Return 0 for OFF, | ||
25 | ** 1 for ON or NORMAL and 2 for FULL. Return 1 for an empty or | ||
26 | ** unrecognized string argument. | ||
27 | ** | ||
28 | ** Note that the values returned are one less that the values that | ||
29 | ** should be passed into sqlite3BtreeSetSafetyLevel(). The is done | ||
30 | ** to support legacy SQL code. The safety level used to be boolean | ||
31 | ** and older scripts may have used numbers 0 for OFF and 1 for ON. | ||
32 | */ | ||
33 | static int getSafetyLevel(const char *z){ | ||
34 | /* 123456789 123456789 */ | ||
35 | static const char zText[] = "onoffalseyestruefull"; | ||
36 | static const u8 iOffset[] = {0, 1, 2, 4, 9, 12, 16}; | ||
37 | static const u8 iLength[] = {2, 2, 3, 5, 3, 4, 4}; | ||
38 | static const u8 iValue[] = {1, 0, 0, 0, 1, 1, 2}; | ||
39 | int i, n; | ||
40 | if( isdigit(*z) ){ | ||
41 | return atoi(z); | ||
42 | } | ||
43 | n = strlen(z); | ||
44 | for(i=0; i<sizeof(iLength); i++){ | ||
45 | if( iLength[i]==n && sqlite3StrNICmp(&zText[iOffset[i]],z,n)==0 ){ | ||
46 | return iValue[i]; | ||
47 | } | ||
48 | } | ||
49 | return 1; | ||
50 | } | ||
51 | |||
52 | /* | ||
53 | ** Interpret the given string as a boolean value. | ||
54 | */ | ||
55 | static int getBoolean(const char *z){ | ||
56 | return getSafetyLevel(z)&1; | ||
57 | } | ||
58 | |||
59 | /* | ||
60 | ** Interpret the given string as a locking mode value. | ||
61 | */ | ||
62 | static int getLockingMode(const char *z){ | ||
63 | if( z ){ | ||
64 | if( 0==sqlite3StrICmp(z, "exclusive") ) return PAGER_LOCKINGMODE_EXCLUSIVE; | ||
65 | if( 0==sqlite3StrICmp(z, "normal") ) return PAGER_LOCKINGMODE_NORMAL; | ||
66 | } | ||
67 | return PAGER_LOCKINGMODE_QUERY; | ||
68 | } | ||
69 | |||
70 | #ifndef SQLITE_OMIT_AUTOVACUUM | ||
71 | /* | ||
72 | ** Interpret the given string as an auto-vacuum mode value. | ||
73 | ** | ||
74 | ** The following strings, "none", "full" and "incremental" are | ||
75 | ** acceptable, as are their numeric equivalents: 0, 1 and 2 respectively. | ||
76 | */ | ||
77 | static int getAutoVacuum(const char *z){ | ||
78 | int i; | ||
79 | if( 0==sqlite3StrICmp(z, "none") ) return BTREE_AUTOVACUUM_NONE; | ||
80 | if( 0==sqlite3StrICmp(z, "full") ) return BTREE_AUTOVACUUM_FULL; | ||
81 | if( 0==sqlite3StrICmp(z, "incremental") ) return BTREE_AUTOVACUUM_INCR; | ||
82 | i = atoi(z); | ||
83 | return ((i>=0&&i<=2)?i:0); | ||
84 | } | ||
85 | #endif /* ifndef SQLITE_OMIT_AUTOVACUUM */ | ||
86 | |||
87 | #ifndef SQLITE_OMIT_PAGER_PRAGMAS | ||
88 | /* | ||
89 | ** Interpret the given string as a temp db location. Return 1 for file | ||
90 | ** backed temporary databases, 2 for the Red-Black tree in memory database | ||
91 | ** and 0 to use the compile-time default. | ||
92 | */ | ||
93 | static int getTempStore(const char *z){ | ||
94 | if( z[0]>='0' && z[0]<='2' ){ | ||
95 | return z[0] - '0'; | ||
96 | }else if( sqlite3StrICmp(z, "file")==0 ){ | ||
97 | return 1; | ||
98 | }else if( sqlite3StrICmp(z, "memory")==0 ){ | ||
99 | return 2; | ||
100 | }else{ | ||
101 | return 0; | ||
102 | } | ||
103 | } | ||
104 | #endif /* SQLITE_PAGER_PRAGMAS */ | ||
105 | |||
106 | #ifndef SQLITE_OMIT_PAGER_PRAGMAS | ||
107 | /* | ||
108 | ** Invalidate temp storage, either when the temp storage is changed | ||
109 | ** from default, or when 'file' and the temp_store_directory has changed | ||
110 | */ | ||
111 | static int invalidateTempStorage(Parse *pParse){ | ||
112 | sqlite3 *db = pParse->db; | ||
113 | if( db->aDb[1].pBt!=0 ){ | ||
114 | if( !db->autoCommit ){ | ||
115 | sqlite3ErrorMsg(pParse, "temporary storage cannot be changed " | ||
116 | "from within a transaction"); | ||
117 | return SQLITE_ERROR; | ||
118 | } | ||
119 | sqlite3BtreeClose(db->aDb[1].pBt); | ||
120 | db->aDb[1].pBt = 0; | ||
121 | sqlite3ResetInternalSchema(db, 0); | ||
122 | } | ||
123 | return SQLITE_OK; | ||
124 | } | ||
125 | #endif /* SQLITE_PAGER_PRAGMAS */ | ||
126 | |||
127 | #ifndef SQLITE_OMIT_PAGER_PRAGMAS | ||
128 | /* | ||
129 | ** If the TEMP database is open, close it and mark the database schema | ||
130 | ** as needing reloading. This must be done when using the TEMP_STORE | ||
131 | ** or DEFAULT_TEMP_STORE pragmas. | ||
132 | */ | ||
133 | static int changeTempStorage(Parse *pParse, const char *zStorageType){ | ||
134 | int ts = getTempStore(zStorageType); | ||
135 | sqlite3 *db = pParse->db; | ||
136 | if( db->temp_store==ts ) return SQLITE_OK; | ||
137 | if( invalidateTempStorage( pParse ) != SQLITE_OK ){ | ||
138 | return SQLITE_ERROR; | ||
139 | } | ||
140 | db->temp_store = ts; | ||
141 | return SQLITE_OK; | ||
142 | } | ||
143 | #endif /* SQLITE_PAGER_PRAGMAS */ | ||
144 | |||
145 | /* | ||
146 | ** Generate code to return a single integer value. | ||
147 | */ | ||
148 | static void returnSingleInt(Parse *pParse, const char *zLabel, int value){ | ||
149 | Vdbe *v = sqlite3GetVdbe(pParse); | ||
150 | sqlite3VdbeAddOp(v, OP_Integer, value, 0); | ||
151 | if( pParse->explain==0 ){ | ||
152 | sqlite3VdbeSetNumCols(v, 1); | ||
153 | sqlite3VdbeSetColName(v, 0, COLNAME_NAME, zLabel, P3_STATIC); | ||
154 | } | ||
155 | sqlite3VdbeAddOp(v, OP_Callback, 1, 0); | ||
156 | } | ||
157 | |||
158 | #ifndef SQLITE_OMIT_FLAG_PRAGMAS | ||
159 | /* | ||
160 | ** Check to see if zRight and zLeft refer to a pragma that queries | ||
161 | ** or changes one of the flags in db->flags. Return 1 if so and 0 if not. | ||
162 | ** Also, implement the pragma. | ||
163 | */ | ||
164 | static int flagPragma(Parse *pParse, const char *zLeft, const char *zRight){ | ||
165 | static const struct sPragmaType { | ||
166 | const char *zName; /* Name of the pragma */ | ||
167 | int mask; /* Mask for the db->flags value */ | ||
168 | } aPragma[] = { | ||
169 | { "full_column_names", SQLITE_FullColNames }, | ||
170 | { "short_column_names", SQLITE_ShortColNames }, | ||
171 | { "count_changes", SQLITE_CountRows }, | ||
172 | { "empty_result_callbacks", SQLITE_NullCallback }, | ||
173 | { "legacy_file_format", SQLITE_LegacyFileFmt }, | ||
174 | { "fullfsync", SQLITE_FullFSync }, | ||
175 | #ifdef SQLITE_DEBUG | ||
176 | { "sql_trace", SQLITE_SqlTrace }, | ||
177 | { "vdbe_listing", SQLITE_VdbeListing }, | ||
178 | { "vdbe_trace", SQLITE_VdbeTrace }, | ||
179 | #endif | ||
180 | #ifndef SQLITE_OMIT_CHECK | ||
181 | { "ignore_check_constraints", SQLITE_IgnoreChecks }, | ||
182 | #endif | ||
183 | /* The following is VERY experimental */ | ||
184 | { "writable_schema", SQLITE_WriteSchema|SQLITE_RecoveryMode }, | ||
185 | { "omit_readlock", SQLITE_NoReadlock }, | ||
186 | |||
187 | /* TODO: Maybe it shouldn't be possible to change the ReadUncommitted | ||
188 | ** flag if there are any active statements. */ | ||
189 | { "read_uncommitted", SQLITE_ReadUncommitted }, | ||
190 | }; | ||
191 | int i; | ||
192 | const struct sPragmaType *p; | ||
193 | for(i=0, p=aPragma; i<sizeof(aPragma)/sizeof(aPragma[0]); i++, p++){ | ||
194 | if( sqlite3StrICmp(zLeft, p->zName)==0 ){ | ||
195 | sqlite3 *db = pParse->db; | ||
196 | Vdbe *v; | ||
197 | v = sqlite3GetVdbe(pParse); | ||
198 | if( v ){ | ||
199 | if( zRight==0 ){ | ||
200 | returnSingleInt(pParse, p->zName, (db->flags & p->mask)!=0 ); | ||
201 | }else{ | ||
202 | if( getBoolean(zRight) ){ | ||
203 | db->flags |= p->mask; | ||
204 | }else{ | ||
205 | db->flags &= ~p->mask; | ||
206 | } | ||
207 | } | ||
208 | } | ||
209 | return 1; | ||
210 | } | ||
211 | } | ||
212 | return 0; | ||
213 | } | ||
214 | #endif /* SQLITE_OMIT_FLAG_PRAGMAS */ | ||
215 | |||
216 | /* | ||
217 | ** Process a pragma statement. | ||
218 | ** | ||
219 | ** Pragmas are of this form: | ||
220 | ** | ||
221 | ** PRAGMA [database.]id [= value] | ||
222 | ** | ||
223 | ** The identifier might also be a string. The value is a string, and | ||
224 | ** identifier, or a number. If minusFlag is true, then the value is | ||
225 | ** a number that was preceded by a minus sign. | ||
226 | ** | ||
227 | ** If the left side is "database.id" then pId1 is the database name | ||
228 | ** and pId2 is the id. If the left side is just "id" then pId1 is the | ||
229 | ** id and pId2 is any empty string. | ||
230 | */ | ||
231 | void sqlite3Pragma( | ||
232 | Parse *pParse, | ||
233 | Token *pId1, /* First part of [database.]id field */ | ||
234 | Token *pId2, /* Second part of [database.]id field, or NULL */ | ||
235 | Token *pValue, /* Token for <value>, or NULL */ | ||
236 | int minusFlag /* True if a '-' sign preceded <value> */ | ||
237 | ){ | ||
238 | char *zLeft = 0; /* Nul-terminated UTF-8 string <id> */ | ||
239 | char *zRight = 0; /* Nul-terminated UTF-8 string <value>, or NULL */ | ||
240 | const char *zDb = 0; /* The database name */ | ||
241 | Token *pId; /* Pointer to <id> token */ | ||
242 | int iDb; /* Database index for <database> */ | ||
243 | sqlite3 *db = pParse->db; | ||
244 | Db *pDb; | ||
245 | Vdbe *v = sqlite3GetVdbe(pParse); | ||
246 | if( v==0 ) return; | ||
247 | |||
248 | /* Interpret the [database.] part of the pragma statement. iDb is the | ||
249 | ** index of the database this pragma is being applied to in db.aDb[]. */ | ||
250 | iDb = sqlite3TwoPartName(pParse, pId1, pId2, &pId); | ||
251 | if( iDb<0 ) return; | ||
252 | pDb = &db->aDb[iDb]; | ||
253 | |||
254 | /* If the temp database has been explicitly named as part of the | ||
255 | ** pragma, make sure it is open. | ||
256 | */ | ||
257 | if( iDb==1 && sqlite3OpenTempDatabase(pParse) ){ | ||
258 | return; | ||
259 | } | ||
260 | |||
261 | zLeft = sqlite3NameFromToken(db, pId); | ||
262 | if( !zLeft ) return; | ||
263 | if( minusFlag ){ | ||
264 | zRight = sqlite3MPrintf(db, "-%T", pValue); | ||
265 | }else{ | ||
266 | zRight = sqlite3NameFromToken(db, pValue); | ||
267 | } | ||
268 | |||
269 | zDb = ((iDb>0)?pDb->zName:0); | ||
270 | if( sqlite3AuthCheck(pParse, SQLITE_PRAGMA, zLeft, zRight, zDb) ){ | ||
271 | goto pragma_out; | ||
272 | } | ||
273 | |||
274 | #ifndef SQLITE_OMIT_PAGER_PRAGMAS | ||
275 | /* | ||
276 | ** PRAGMA [database.]default_cache_size | ||
277 | ** PRAGMA [database.]default_cache_size=N | ||
278 | ** | ||
279 | ** The first form reports the current persistent setting for the | ||
280 | ** page cache size. The value returned is the maximum number of | ||
281 | ** pages in the page cache. The second form sets both the current | ||
282 | ** page cache size value and the persistent page cache size value | ||
283 | ** stored in the database file. | ||
284 | ** | ||
285 | ** The default cache size is stored in meta-value 2 of page 1 of the | ||
286 | ** database file. The cache size is actually the absolute value of | ||
287 | ** this memory location. The sign of meta-value 2 determines the | ||
288 | ** synchronous setting. A negative value means synchronous is off | ||
289 | ** and a positive value means synchronous is on. | ||
290 | */ | ||
291 | if( sqlite3StrICmp(zLeft,"default_cache_size")==0 ){ | ||
292 | static const VdbeOpList getCacheSize[] = { | ||
293 | { OP_ReadCookie, 0, 2, 0}, /* 0 */ | ||
294 | { OP_AbsValue, 0, 0, 0}, | ||
295 | { OP_Dup, 0, 0, 0}, | ||
296 | { OP_Integer, 0, 0, 0}, | ||
297 | { OP_Ne, 0, 6, 0}, | ||
298 | { OP_Integer, 0, 0, 0}, /* 5 */ | ||
299 | { OP_Callback, 1, 0, 0}, | ||
300 | }; | ||
301 | int addr; | ||
302 | if( sqlite3ReadSchema(pParse) ) goto pragma_out; | ||
303 | sqlite3VdbeUsesBtree(v, iDb); | ||
304 | if( !zRight ){ | ||
305 | sqlite3VdbeSetNumCols(v, 1); | ||
306 | sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "cache_size", P3_STATIC); | ||
307 | addr = sqlite3VdbeAddOpList(v, ArraySize(getCacheSize), getCacheSize); | ||
308 | sqlite3VdbeChangeP1(v, addr, iDb); | ||
309 | sqlite3VdbeChangeP1(v, addr+5, SQLITE_DEFAULT_CACHE_SIZE); | ||
310 | }else{ | ||
311 | int size = atoi(zRight); | ||
312 | if( size<0 ) size = -size; | ||
313 | sqlite3BeginWriteOperation(pParse, 0, iDb); | ||
314 | sqlite3VdbeAddOp(v, OP_Integer, size, 0); | ||
315 | sqlite3VdbeAddOp(v, OP_ReadCookie, iDb, 2); | ||
316 | addr = sqlite3VdbeAddOp(v, OP_Integer, 0, 0); | ||
317 | sqlite3VdbeAddOp(v, OP_Ge, 0, addr+3); | ||
318 | sqlite3VdbeAddOp(v, OP_Negative, 0, 0); | ||
319 | sqlite3VdbeAddOp(v, OP_SetCookie, iDb, 2); | ||
320 | pDb->pSchema->cache_size = size; | ||
321 | sqlite3BtreeSetCacheSize(pDb->pBt, pDb->pSchema->cache_size); | ||
322 | } | ||
323 | }else | ||
324 | |||
325 | /* | ||
326 | ** PRAGMA [database.]page_size | ||
327 | ** PRAGMA [database.]page_size=N | ||
328 | ** | ||
329 | ** The first form reports the current setting for the | ||
330 | ** database page size in bytes. The second form sets the | ||
331 | ** database page size value. The value can only be set if | ||
332 | ** the database has not yet been created. | ||
333 | */ | ||
334 | if( sqlite3StrICmp(zLeft,"page_size")==0 ){ | ||
335 | Btree *pBt = pDb->pBt; | ||
336 | if( !zRight ){ | ||
337 | int size = pBt ? sqlite3BtreeGetPageSize(pBt) : 0; | ||
338 | returnSingleInt(pParse, "page_size", size); | ||
339 | }else{ | ||
340 | /* Malloc may fail when setting the page-size, as there is an internal | ||
341 | ** buffer that the pager module resizes using sqlite3_realloc(). | ||
342 | */ | ||
343 | if( SQLITE_NOMEM==sqlite3BtreeSetPageSize(pBt, atoi(zRight), -1) ){ | ||
344 | db->mallocFailed = 1; | ||
345 | } | ||
346 | } | ||
347 | }else | ||
348 | |||
349 | /* | ||
350 | ** PRAGMA [database.]max_page_count | ||
351 | ** PRAGMA [database.]max_page_count=N | ||
352 | ** | ||
353 | ** The first form reports the current setting for the | ||
354 | ** maximum number of pages in the database file. The | ||
355 | ** second form attempts to change this setting. Both | ||
356 | ** forms return the current setting. | ||
357 | */ | ||
358 | if( sqlite3StrICmp(zLeft,"max_page_count")==0 ){ | ||
359 | Btree *pBt = pDb->pBt; | ||
360 | int newMax = 0; | ||
361 | if( zRight ){ | ||
362 | newMax = atoi(zRight); | ||
363 | } | ||
364 | if( pBt ){ | ||
365 | newMax = sqlite3BtreeMaxPageCount(pBt, newMax); | ||
366 | } | ||
367 | returnSingleInt(pParse, "max_page_count", newMax); | ||
368 | }else | ||
369 | |||
370 | /* | ||
371 | ** PRAGMA [database.]locking_mode | ||
372 | ** PRAGMA [database.]locking_mode = (normal|exclusive) | ||
373 | */ | ||
374 | if( sqlite3StrICmp(zLeft,"locking_mode")==0 ){ | ||
375 | const char *zRet = "normal"; | ||
376 | int eMode = getLockingMode(zRight); | ||
377 | |||
378 | if( pId2->n==0 && eMode==PAGER_LOCKINGMODE_QUERY ){ | ||
379 | /* Simple "PRAGMA locking_mode;" statement. This is a query for | ||
380 | ** the current default locking mode (which may be different to | ||
381 | ** the locking-mode of the main database). | ||
382 | */ | ||
383 | eMode = db->dfltLockMode; | ||
384 | }else{ | ||
385 | Pager *pPager; | ||
386 | if( pId2->n==0 ){ | ||
387 | /* This indicates that no database name was specified as part | ||
388 | ** of the PRAGMA command. In this case the locking-mode must be | ||
389 | ** set on all attached databases, as well as the main db file. | ||
390 | ** | ||
391 | ** Also, the sqlite3.dfltLockMode variable is set so that | ||
392 | ** any subsequently attached databases also use the specified | ||
393 | ** locking mode. | ||
394 | */ | ||
395 | int ii; | ||
396 | assert(pDb==&db->aDb[0]); | ||
397 | for(ii=2; ii<db->nDb; ii++){ | ||
398 | pPager = sqlite3BtreePager(db->aDb[ii].pBt); | ||
399 | sqlite3PagerLockingMode(pPager, eMode); | ||
400 | } | ||
401 | db->dfltLockMode = eMode; | ||
402 | } | ||
403 | pPager = sqlite3BtreePager(pDb->pBt); | ||
404 | eMode = sqlite3PagerLockingMode(pPager, eMode); | ||
405 | } | ||
406 | |||
407 | assert(eMode==PAGER_LOCKINGMODE_NORMAL||eMode==PAGER_LOCKINGMODE_EXCLUSIVE); | ||
408 | if( eMode==PAGER_LOCKINGMODE_EXCLUSIVE ){ | ||
409 | zRet = "exclusive"; | ||
410 | } | ||
411 | sqlite3VdbeSetNumCols(v, 1); | ||
412 | sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "locking_mode", P3_STATIC); | ||
413 | sqlite3VdbeOp3(v, OP_String8, 0, 0, zRet, 0); | ||
414 | sqlite3VdbeAddOp(v, OP_Callback, 1, 0); | ||
415 | }else | ||
416 | #endif /* SQLITE_OMIT_PAGER_PRAGMAS */ | ||
417 | |||
418 | /* | ||
419 | ** PRAGMA [database.]auto_vacuum | ||
420 | ** PRAGMA [database.]auto_vacuum=N | ||
421 | ** | ||
422 | ** Get or set the (boolean) value of the database 'auto-vacuum' parameter. | ||
423 | */ | ||
424 | #ifndef SQLITE_OMIT_AUTOVACUUM | ||
425 | if( sqlite3StrICmp(zLeft,"auto_vacuum")==0 ){ | ||
426 | Btree *pBt = pDb->pBt; | ||
427 | if( sqlite3ReadSchema(pParse) ){ | ||
428 | goto pragma_out; | ||
429 | } | ||
430 | if( !zRight ){ | ||
431 | int auto_vacuum = | ||
432 | pBt ? sqlite3BtreeGetAutoVacuum(pBt) : SQLITE_DEFAULT_AUTOVACUUM; | ||
433 | returnSingleInt(pParse, "auto_vacuum", auto_vacuum); | ||
434 | }else{ | ||
435 | int eAuto = getAutoVacuum(zRight); | ||
436 | if( eAuto>=0 ){ | ||
437 | /* Call SetAutoVacuum() to set initialize the internal auto and | ||
438 | ** incr-vacuum flags. This is required in case this connection | ||
439 | ** creates the database file. It is important that it is created | ||
440 | ** as an auto-vacuum capable db. | ||
441 | */ | ||
442 | int rc = sqlite3BtreeSetAutoVacuum(pBt, eAuto); | ||
443 | if( rc==SQLITE_OK && (eAuto==1 || eAuto==2) ){ | ||
444 | /* When setting the auto_vacuum mode to either "full" or | ||
445 | ** "incremental", write the value of meta[6] in the database | ||
446 | ** file. Before writing to meta[6], check that meta[3] indicates | ||
447 | ** that this really is an auto-vacuum capable database. | ||
448 | */ | ||
449 | static const VdbeOpList setMeta6[] = { | ||
450 | { OP_Transaction, 0, 1, 0}, /* 0 */ | ||
451 | { OP_ReadCookie, 0, 3, 0}, /* 1 */ | ||
452 | { OP_If, 0, 0, 0}, /* 2 */ | ||
453 | { OP_Halt, SQLITE_OK, OE_Abort, 0}, /* 3 */ | ||
454 | { OP_Integer, 0, 0, 0}, /* 4 */ | ||
455 | { OP_SetCookie, 0, 6, 0}, /* 5 */ | ||
456 | }; | ||
457 | int iAddr; | ||
458 | iAddr = sqlite3VdbeAddOpList(v, ArraySize(setMeta6), setMeta6); | ||
459 | sqlite3VdbeChangeP1(v, iAddr, iDb); | ||
460 | sqlite3VdbeChangeP1(v, iAddr+1, iDb); | ||
461 | sqlite3VdbeChangeP2(v, iAddr+2, iAddr+4); | ||
462 | sqlite3VdbeChangeP1(v, iAddr+4, eAuto-1); | ||
463 | sqlite3VdbeChangeP1(v, iAddr+5, iDb); | ||
464 | sqlite3VdbeUsesBtree(v, iDb); | ||
465 | } | ||
466 | } | ||
467 | } | ||
468 | }else | ||
469 | #endif | ||
470 | |||
471 | /* | ||
472 | ** PRAGMA [database.]incremental_vacuum(N) | ||
473 | ** | ||
474 | ** Do N steps of incremental vacuuming on a database. | ||
475 | */ | ||
476 | #ifndef SQLITE_OMIT_AUTOVACUUM | ||
477 | if( sqlite3StrICmp(zLeft,"incremental_vacuum")==0 ){ | ||
478 | int iLimit, addr; | ||
479 | if( sqlite3ReadSchema(pParse) ){ | ||
480 | goto pragma_out; | ||
481 | } | ||
482 | if( zRight==0 || !sqlite3GetInt32(zRight, &iLimit) || iLimit<=0 ){ | ||
483 | iLimit = 0x7fffffff; | ||
484 | } | ||
485 | sqlite3BeginWriteOperation(pParse, 0, iDb); | ||
486 | sqlite3VdbeAddOp(v, OP_MemInt, iLimit, 0); | ||
487 | addr = sqlite3VdbeAddOp(v, OP_IncrVacuum, iDb, 0); | ||
488 | sqlite3VdbeAddOp(v, OP_Callback, 0, 0); | ||
489 | sqlite3VdbeAddOp(v, OP_MemIncr, -1, 0); | ||
490 | sqlite3VdbeAddOp(v, OP_IfMemPos, 0, addr); | ||
491 | sqlite3VdbeJumpHere(v, addr); | ||
492 | }else | ||
493 | #endif | ||
494 | |||
495 | #ifndef SQLITE_OMIT_PAGER_PRAGMAS | ||
496 | /* | ||
497 | ** PRAGMA [database.]cache_size | ||
498 | ** PRAGMA [database.]cache_size=N | ||
499 | ** | ||
500 | ** The first form reports the current local setting for the | ||
501 | ** page cache size. The local setting can be different from | ||
502 | ** the persistent cache size value that is stored in the database | ||
503 | ** file itself. The value returned is the maximum number of | ||
504 | ** pages in the page cache. The second form sets the local | ||
505 | ** page cache size value. It does not change the persistent | ||
506 | ** cache size stored on the disk so the cache size will revert | ||
507 | ** to its default value when the database is closed and reopened. | ||
508 | ** N should be a positive integer. | ||
509 | */ | ||
510 | if( sqlite3StrICmp(zLeft,"cache_size")==0 ){ | ||
511 | if( sqlite3ReadSchema(pParse) ) goto pragma_out; | ||
512 | if( !zRight ){ | ||
513 | returnSingleInt(pParse, "cache_size", pDb->pSchema->cache_size); | ||
514 | }else{ | ||
515 | int size = atoi(zRight); | ||
516 | if( size<0 ) size = -size; | ||
517 | pDb->pSchema->cache_size = size; | ||
518 | sqlite3BtreeSetCacheSize(pDb->pBt, pDb->pSchema->cache_size); | ||
519 | } | ||
520 | }else | ||
521 | |||
522 | /* | ||
523 | ** PRAGMA temp_store | ||
524 | ** PRAGMA temp_store = "default"|"memory"|"file" | ||
525 | ** | ||
526 | ** Return or set the local value of the temp_store flag. Changing | ||
527 | ** the local value does not make changes to the disk file and the default | ||
528 | ** value will be restored the next time the database is opened. | ||
529 | ** | ||
530 | ** Note that it is possible for the library compile-time options to | ||
531 | ** override this setting | ||
532 | */ | ||
533 | if( sqlite3StrICmp(zLeft, "temp_store")==0 ){ | ||
534 | if( !zRight ){ | ||
535 | returnSingleInt(pParse, "temp_store", db->temp_store); | ||
536 | }else{ | ||
537 | changeTempStorage(pParse, zRight); | ||
538 | } | ||
539 | }else | ||
540 | |||
541 | /* | ||
542 | ** PRAGMA temp_store_directory | ||
543 | ** PRAGMA temp_store_directory = ""|"directory_name" | ||
544 | ** | ||
545 | ** Return or set the local value of the temp_store_directory flag. Changing | ||
546 | ** the value sets a specific directory to be used for temporary files. | ||
547 | ** Setting to a null string reverts to the default temporary directory search. | ||
548 | ** If temporary directory is changed, then invalidateTempStorage. | ||
549 | ** | ||
550 | */ | ||
551 | if( sqlite3StrICmp(zLeft, "temp_store_directory")==0 ){ | ||
552 | if( !zRight ){ | ||
553 | if( sqlite3_temp_directory ){ | ||
554 | sqlite3VdbeSetNumCols(v, 1); | ||
555 | sqlite3VdbeSetColName(v, 0, COLNAME_NAME, | ||
556 | "temp_store_directory", P3_STATIC); | ||
557 | sqlite3VdbeOp3(v, OP_String8, 0, 0, sqlite3_temp_directory, 0); | ||
558 | sqlite3VdbeAddOp(v, OP_Callback, 1, 0); | ||
559 | } | ||
560 | }else{ | ||
561 | if( zRight[0] | ||
562 | && !sqlite3OsAccess(db->pVfs, zRight, SQLITE_ACCESS_READWRITE) | ||
563 | ){ | ||
564 | sqlite3ErrorMsg(pParse, "not a writable directory"); | ||
565 | goto pragma_out; | ||
566 | } | ||
567 | if( TEMP_STORE==0 | ||
568 | || (TEMP_STORE==1 && db->temp_store<=1) | ||
569 | || (TEMP_STORE==2 && db->temp_store==1) | ||
570 | ){ | ||
571 | invalidateTempStorage(pParse); | ||
572 | } | ||
573 | sqlite3_free(sqlite3_temp_directory); | ||
574 | if( zRight[0] ){ | ||
575 | sqlite3_temp_directory = zRight; | ||
576 | zRight = 0; | ||
577 | }else{ | ||
578 | sqlite3_temp_directory = 0; | ||
579 | } | ||
580 | } | ||
581 | }else | ||
582 | |||
583 | /* | ||
584 | ** PRAGMA [database.]synchronous | ||
585 | ** PRAGMA [database.]synchronous=OFF|ON|NORMAL|FULL | ||
586 | ** | ||
587 | ** Return or set the local value of the synchronous flag. Changing | ||
588 | ** the local value does not make changes to the disk file and the | ||
589 | ** default value will be restored the next time the database is | ||
590 | ** opened. | ||
591 | */ | ||
592 | if( sqlite3StrICmp(zLeft,"synchronous")==0 ){ | ||
593 | if( sqlite3ReadSchema(pParse) ) goto pragma_out; | ||
594 | if( !zRight ){ | ||
595 | returnSingleInt(pParse, "synchronous", pDb->safety_level-1); | ||
596 | }else{ | ||
597 | if( !db->autoCommit ){ | ||
598 | sqlite3ErrorMsg(pParse, | ||
599 | "Safety level may not be changed inside a transaction"); | ||
600 | }else{ | ||
601 | pDb->safety_level = getSafetyLevel(zRight)+1; | ||
602 | } | ||
603 | } | ||
604 | }else | ||
605 | #endif /* SQLITE_OMIT_PAGER_PRAGMAS */ | ||
606 | |||
607 | #ifndef SQLITE_OMIT_FLAG_PRAGMAS | ||
608 | if( flagPragma(pParse, zLeft, zRight) ){ | ||
609 | /* The flagPragma() subroutine also generates any necessary code | ||
610 | ** there is nothing more to do here */ | ||
611 | }else | ||
612 | #endif /* SQLITE_OMIT_FLAG_PRAGMAS */ | ||
613 | |||
614 | #ifndef SQLITE_OMIT_SCHEMA_PRAGMAS | ||
615 | /* | ||
616 | ** PRAGMA table_info(<table>) | ||
617 | ** | ||
618 | ** Return a single row for each column of the named table. The columns of | ||
619 | ** the returned data set are: | ||
620 | ** | ||
621 | ** cid: Column id (numbered from left to right, starting at 0) | ||
622 | ** name: Column name | ||
623 | ** type: Column declaration type. | ||
624 | ** notnull: True if 'NOT NULL' is part of column declaration | ||
625 | ** dflt_value: The default value for the column, if any. | ||
626 | */ | ||
627 | if( sqlite3StrICmp(zLeft, "table_info")==0 && zRight ){ | ||
628 | Table *pTab; | ||
629 | if( sqlite3ReadSchema(pParse) ) goto pragma_out; | ||
630 | pTab = sqlite3FindTable(db, zRight, zDb); | ||
631 | if( pTab ){ | ||
632 | int i; | ||
633 | int nHidden = 0; | ||
634 | Column *pCol; | ||
635 | sqlite3VdbeSetNumCols(v, 6); | ||
636 | sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "cid", P3_STATIC); | ||
637 | sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "name", P3_STATIC); | ||
638 | sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "type", P3_STATIC); | ||
639 | sqlite3VdbeSetColName(v, 3, COLNAME_NAME, "notnull", P3_STATIC); | ||
640 | sqlite3VdbeSetColName(v, 4, COLNAME_NAME, "dflt_value", P3_STATIC); | ||
641 | sqlite3VdbeSetColName(v, 5, COLNAME_NAME, "pk", P3_STATIC); | ||
642 | sqlite3ViewGetColumnNames(pParse, pTab); | ||
643 | for(i=0, pCol=pTab->aCol; i<pTab->nCol; i++, pCol++){ | ||
644 | const Token *pDflt; | ||
645 | if( IsHiddenColumn(pCol) ){ | ||
646 | nHidden++; | ||
647 | continue; | ||
648 | } | ||
649 | sqlite3VdbeAddOp(v, OP_Integer, i-nHidden, 0); | ||
650 | sqlite3VdbeOp3(v, OP_String8, 0, 0, pCol->zName, 0); | ||
651 | sqlite3VdbeOp3(v, OP_String8, 0, 0, | ||
652 | pCol->zType ? pCol->zType : "", 0); | ||
653 | sqlite3VdbeAddOp(v, OP_Integer, pCol->notNull, 0); | ||
654 | if( pCol->pDflt && (pDflt = &pCol->pDflt->span)->z ){ | ||
655 | sqlite3VdbeOp3(v, OP_String8, 0, 0, (char*)pDflt->z, pDflt->n); | ||
656 | }else{ | ||
657 | sqlite3VdbeAddOp(v, OP_Null, 0, 0); | ||
658 | } | ||
659 | sqlite3VdbeAddOp(v, OP_Integer, pCol->isPrimKey, 0); | ||
660 | sqlite3VdbeAddOp(v, OP_Callback, 6, 0); | ||
661 | } | ||
662 | } | ||
663 | }else | ||
664 | |||
665 | if( sqlite3StrICmp(zLeft, "index_info")==0 && zRight ){ | ||
666 | Index *pIdx; | ||
667 | Table *pTab; | ||
668 | if( sqlite3ReadSchema(pParse) ) goto pragma_out; | ||
669 | pIdx = sqlite3FindIndex(db, zRight, zDb); | ||
670 | if( pIdx ){ | ||
671 | int i; | ||
672 | pTab = pIdx->pTable; | ||
673 | sqlite3VdbeSetNumCols(v, 3); | ||
674 | sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "seqno", P3_STATIC); | ||
675 | sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "cid", P3_STATIC); | ||
676 | sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "name", P3_STATIC); | ||
677 | for(i=0; i<pIdx->nColumn; i++){ | ||
678 | int cnum = pIdx->aiColumn[i]; | ||
679 | sqlite3VdbeAddOp(v, OP_Integer, i, 0); | ||
680 | sqlite3VdbeAddOp(v, OP_Integer, cnum, 0); | ||
681 | assert( pTab->nCol>cnum ); | ||
682 | sqlite3VdbeOp3(v, OP_String8, 0, 0, pTab->aCol[cnum].zName, 0); | ||
683 | sqlite3VdbeAddOp(v, OP_Callback, 3, 0); | ||
684 | } | ||
685 | } | ||
686 | }else | ||
687 | |||
688 | if( sqlite3StrICmp(zLeft, "index_list")==0 && zRight ){ | ||
689 | Index *pIdx; | ||
690 | Table *pTab; | ||
691 | if( sqlite3ReadSchema(pParse) ) goto pragma_out; | ||
692 | pTab = sqlite3FindTable(db, zRight, zDb); | ||
693 | if( pTab ){ | ||
694 | v = sqlite3GetVdbe(pParse); | ||
695 | pIdx = pTab->pIndex; | ||
696 | if( pIdx ){ | ||
697 | int i = 0; | ||
698 | sqlite3VdbeSetNumCols(v, 3); | ||
699 | sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "seq", P3_STATIC); | ||
700 | sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "name", P3_STATIC); | ||
701 | sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "unique", P3_STATIC); | ||
702 | while(pIdx){ | ||
703 | sqlite3VdbeAddOp(v, OP_Integer, i, 0); | ||
704 | sqlite3VdbeOp3(v, OP_String8, 0, 0, pIdx->zName, 0); | ||
705 | sqlite3VdbeAddOp(v, OP_Integer, pIdx->onError!=OE_None, 0); | ||
706 | sqlite3VdbeAddOp(v, OP_Callback, 3, 0); | ||
707 | ++i; | ||
708 | pIdx = pIdx->pNext; | ||
709 | } | ||
710 | } | ||
711 | } | ||
712 | }else | ||
713 | |||
714 | if( sqlite3StrICmp(zLeft, "database_list")==0 ){ | ||
715 | int i; | ||
716 | if( sqlite3ReadSchema(pParse) ) goto pragma_out; | ||
717 | sqlite3VdbeSetNumCols(v, 3); | ||
718 | sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "seq", P3_STATIC); | ||
719 | sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "name", P3_STATIC); | ||
720 | sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "file", P3_STATIC); | ||
721 | for(i=0; i<db->nDb; i++){ | ||
722 | if( db->aDb[i].pBt==0 ) continue; | ||
723 | assert( db->aDb[i].zName!=0 ); | ||
724 | sqlite3VdbeAddOp(v, OP_Integer, i, 0); | ||
725 | sqlite3VdbeOp3(v, OP_String8, 0, 0, db->aDb[i].zName, 0); | ||
726 | sqlite3VdbeOp3(v, OP_String8, 0, 0, | ||
727 | sqlite3BtreeGetFilename(db->aDb[i].pBt), 0); | ||
728 | sqlite3VdbeAddOp(v, OP_Callback, 3, 0); | ||
729 | } | ||
730 | }else | ||
731 | |||
732 | if( sqlite3StrICmp(zLeft, "collation_list")==0 ){ | ||
733 | int i = 0; | ||
734 | HashElem *p; | ||
735 | sqlite3VdbeSetNumCols(v, 2); | ||
736 | sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "seq", P3_STATIC); | ||
737 | sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "name", P3_STATIC); | ||
738 | for(p=sqliteHashFirst(&db->aCollSeq); p; p=sqliteHashNext(p)){ | ||
739 | CollSeq *pColl = (CollSeq *)sqliteHashData(p); | ||
740 | sqlite3VdbeAddOp(v, OP_Integer, i++, 0); | ||
741 | sqlite3VdbeOp3(v, OP_String8, 0, 0, pColl->zName, 0); | ||
742 | sqlite3VdbeAddOp(v, OP_Callback, 2, 0); | ||
743 | } | ||
744 | }else | ||
745 | #endif /* SQLITE_OMIT_SCHEMA_PRAGMAS */ | ||
746 | |||
747 | #ifndef SQLITE_OMIT_FOREIGN_KEY | ||
748 | if( sqlite3StrICmp(zLeft, "foreign_key_list")==0 && zRight ){ | ||
749 | FKey *pFK; | ||
750 | Table *pTab; | ||
751 | if( sqlite3ReadSchema(pParse) ) goto pragma_out; | ||
752 | pTab = sqlite3FindTable(db, zRight, zDb); | ||
753 | if( pTab ){ | ||
754 | v = sqlite3GetVdbe(pParse); | ||
755 | pFK = pTab->pFKey; | ||
756 | if( pFK ){ | ||
757 | int i = 0; | ||
758 | sqlite3VdbeSetNumCols(v, 5); | ||
759 | sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "id", P3_STATIC); | ||
760 | sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "seq", P3_STATIC); | ||
761 | sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "table", P3_STATIC); | ||
762 | sqlite3VdbeSetColName(v, 3, COLNAME_NAME, "from", P3_STATIC); | ||
763 | sqlite3VdbeSetColName(v, 4, COLNAME_NAME, "to", P3_STATIC); | ||
764 | while(pFK){ | ||
765 | int j; | ||
766 | for(j=0; j<pFK->nCol; j++){ | ||
767 | char *zCol = pFK->aCol[j].zCol; | ||
768 | sqlite3VdbeAddOp(v, OP_Integer, i, 0); | ||
769 | sqlite3VdbeAddOp(v, OP_Integer, j, 0); | ||
770 | sqlite3VdbeOp3(v, OP_String8, 0, 0, pFK->zTo, 0); | ||
771 | sqlite3VdbeOp3(v, OP_String8, 0, 0, | ||
772 | pTab->aCol[pFK->aCol[j].iFrom].zName, 0); | ||
773 | sqlite3VdbeOp3(v, zCol ? OP_String8 : OP_Null, 0, 0, zCol, 0); | ||
774 | sqlite3VdbeAddOp(v, OP_Callback, 5, 0); | ||
775 | } | ||
776 | ++i; | ||
777 | pFK = pFK->pNextFrom; | ||
778 | } | ||
779 | } | ||
780 | } | ||
781 | }else | ||
782 | #endif /* !defined(SQLITE_OMIT_FOREIGN_KEY) */ | ||
783 | |||
784 | #ifndef NDEBUG | ||
785 | if( sqlite3StrICmp(zLeft, "parser_trace")==0 ){ | ||
786 | if( zRight ){ | ||
787 | if( getBoolean(zRight) ){ | ||
788 | sqlite3ParserTrace(stderr, "parser: "); | ||
789 | }else{ | ||
790 | sqlite3ParserTrace(0, 0); | ||
791 | } | ||
792 | } | ||
793 | }else | ||
794 | #endif | ||
795 | |||
796 | /* Reinstall the LIKE and GLOB functions. The variant of LIKE | ||
797 | ** used will be case sensitive or not depending on the RHS. | ||
798 | */ | ||
799 | if( sqlite3StrICmp(zLeft, "case_sensitive_like")==0 ){ | ||
800 | if( zRight ){ | ||
801 | sqlite3RegisterLikeFunctions(db, getBoolean(zRight)); | ||
802 | } | ||
803 | }else | ||
804 | |||
805 | #ifndef SQLITE_INTEGRITY_CHECK_ERROR_MAX | ||
806 | # define SQLITE_INTEGRITY_CHECK_ERROR_MAX 100 | ||
807 | #endif | ||
808 | |||
809 | #ifndef SQLITE_OMIT_INTEGRITY_CHECK | ||
810 | if( sqlite3StrICmp(zLeft, "integrity_check")==0 ){ | ||
811 | int i, j, addr, mxErr; | ||
812 | |||
813 | /* Code that appears at the end of the integrity check. If no error | ||
814 | ** messages have been generated, output OK. Otherwise output the | ||
815 | ** error message | ||
816 | */ | ||
817 | static const VdbeOpList endCode[] = { | ||
818 | { OP_MemLoad, 0, 0, 0}, | ||
819 | { OP_Integer, 0, 0, 0}, | ||
820 | { OP_Ne, 0, 0, 0}, /* 2 */ | ||
821 | { OP_String8, 0, 0, "ok"}, | ||
822 | { OP_Callback, 1, 0, 0}, | ||
823 | }; | ||
824 | |||
825 | /* Initialize the VDBE program */ | ||
826 | if( sqlite3ReadSchema(pParse) ) goto pragma_out; | ||
827 | sqlite3VdbeSetNumCols(v, 1); | ||
828 | sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "integrity_check", P3_STATIC); | ||
829 | |||
830 | /* Set the maximum error count */ | ||
831 | mxErr = SQLITE_INTEGRITY_CHECK_ERROR_MAX; | ||
832 | if( zRight ){ | ||
833 | mxErr = atoi(zRight); | ||
834 | if( mxErr<=0 ){ | ||
835 | mxErr = SQLITE_INTEGRITY_CHECK_ERROR_MAX; | ||
836 | } | ||
837 | } | ||
838 | sqlite3VdbeAddOp(v, OP_MemInt, mxErr, 0); | ||
839 | |||
840 | /* Do an integrity check on each database file */ | ||
841 | for(i=0; i<db->nDb; i++){ | ||
842 | HashElem *x; | ||
843 | Hash *pTbls; | ||
844 | int cnt = 0; | ||
845 | |||
846 | if( OMIT_TEMPDB && i==1 ) continue; | ||
847 | |||
848 | sqlite3CodeVerifySchema(pParse, i); | ||
849 | addr = sqlite3VdbeAddOp(v, OP_IfMemPos, 0, 0); | ||
850 | sqlite3VdbeAddOp(v, OP_Halt, 0, 0); | ||
851 | sqlite3VdbeJumpHere(v, addr); | ||
852 | |||
853 | /* Do an integrity check of the B-Tree | ||
854 | */ | ||
855 | pTbls = &db->aDb[i].pSchema->tblHash; | ||
856 | for(x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){ | ||
857 | Table *pTab = sqliteHashData(x); | ||
858 | Index *pIdx; | ||
859 | sqlite3VdbeAddOp(v, OP_Integer, pTab->tnum, 0); | ||
860 | cnt++; | ||
861 | for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ | ||
862 | sqlite3VdbeAddOp(v, OP_Integer, pIdx->tnum, 0); | ||
863 | cnt++; | ||
864 | } | ||
865 | } | ||
866 | if( cnt==0 ) continue; | ||
867 | sqlite3VdbeAddOp(v, OP_IntegrityCk, 0, i); | ||
868 | addr = sqlite3VdbeAddOp(v, OP_IsNull, -1, 0); | ||
869 | sqlite3VdbeOp3(v, OP_String8, 0, 0, | ||
870 | sqlite3MPrintf(db, "*** in database %s ***\n", db->aDb[i].zName), | ||
871 | P3_DYNAMIC); | ||
872 | sqlite3VdbeAddOp(v, OP_Pull, 1, 0); | ||
873 | sqlite3VdbeAddOp(v, OP_Concat, 0, 0); | ||
874 | sqlite3VdbeAddOp(v, OP_Callback, 1, 0); | ||
875 | sqlite3VdbeJumpHere(v, addr); | ||
876 | |||
877 | /* Make sure all the indices are constructed correctly. | ||
878 | */ | ||
879 | for(x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){ | ||
880 | Table *pTab = sqliteHashData(x); | ||
881 | Index *pIdx; | ||
882 | int loopTop; | ||
883 | |||
884 | if( pTab->pIndex==0 ) continue; | ||
885 | addr = sqlite3VdbeAddOp(v, OP_IfMemPos, 0, 0); | ||
886 | sqlite3VdbeAddOp(v, OP_Halt, 0, 0); | ||
887 | sqlite3VdbeJumpHere(v, addr); | ||
888 | sqlite3OpenTableAndIndices(pParse, pTab, 1, OP_OpenRead); | ||
889 | sqlite3VdbeAddOp(v, OP_MemInt, 0, 1); | ||
890 | loopTop = sqlite3VdbeAddOp(v, OP_Rewind, 1, 0); | ||
891 | sqlite3VdbeAddOp(v, OP_MemIncr, 1, 1); | ||
892 | for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){ | ||
893 | int jmp2; | ||
894 | static const VdbeOpList idxErr[] = { | ||
895 | { OP_MemIncr, -1, 0, 0}, | ||
896 | { OP_String8, 0, 0, "rowid "}, | ||
897 | { OP_Rowid, 1, 0, 0}, | ||
898 | { OP_String8, 0, 0, " missing from index "}, | ||
899 | { OP_String8, 0, 0, 0}, /* 4 */ | ||
900 | { OP_Concat, 2, 0, 0}, | ||
901 | { OP_Callback, 1, 0, 0}, | ||
902 | }; | ||
903 | sqlite3GenerateIndexKey(v, pIdx, 1); | ||
904 | jmp2 = sqlite3VdbeAddOp(v, OP_Found, j+2, 0); | ||
905 | addr = sqlite3VdbeAddOpList(v, ArraySize(idxErr), idxErr); | ||
906 | sqlite3VdbeChangeP3(v, addr+4, pIdx->zName, P3_STATIC); | ||
907 | sqlite3VdbeJumpHere(v, jmp2); | ||
908 | } | ||
909 | sqlite3VdbeAddOp(v, OP_Next, 1, loopTop+1); | ||
910 | sqlite3VdbeJumpHere(v, loopTop); | ||
911 | for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){ | ||
912 | static const VdbeOpList cntIdx[] = { | ||
913 | { OP_MemInt, 0, 2, 0}, | ||
914 | { OP_Rewind, 0, 0, 0}, /* 1 */ | ||
915 | { OP_MemIncr, 1, 2, 0}, | ||
916 | { OP_Next, 0, 0, 0}, /* 3 */ | ||
917 | { OP_MemLoad, 1, 0, 0}, | ||
918 | { OP_MemLoad, 2, 0, 0}, | ||
919 | { OP_Eq, 0, 0, 0}, /* 6 */ | ||
920 | { OP_MemIncr, -1, 0, 0}, | ||
921 | { OP_String8, 0, 0, "wrong # of entries in index "}, | ||
922 | { OP_String8, 0, 0, 0}, /* 9 */ | ||
923 | { OP_Concat, 0, 0, 0}, | ||
924 | { OP_Callback, 1, 0, 0}, | ||
925 | }; | ||
926 | if( pIdx->tnum==0 ) continue; | ||
927 | addr = sqlite3VdbeAddOp(v, OP_IfMemPos, 0, 0); | ||
928 | sqlite3VdbeAddOp(v, OP_Halt, 0, 0); | ||
929 | sqlite3VdbeJumpHere(v, addr); | ||
930 | addr = sqlite3VdbeAddOpList(v, ArraySize(cntIdx), cntIdx); | ||
931 | sqlite3VdbeChangeP1(v, addr+1, j+2); | ||
932 | sqlite3VdbeChangeP2(v, addr+1, addr+4); | ||
933 | sqlite3VdbeChangeP1(v, addr+3, j+2); | ||
934 | sqlite3VdbeChangeP2(v, addr+3, addr+2); | ||
935 | sqlite3VdbeJumpHere(v, addr+6); | ||
936 | sqlite3VdbeChangeP3(v, addr+9, pIdx->zName, P3_STATIC); | ||
937 | } | ||
938 | } | ||
939 | } | ||
940 | addr = sqlite3VdbeAddOpList(v, ArraySize(endCode), endCode); | ||
941 | sqlite3VdbeChangeP1(v, addr+1, mxErr); | ||
942 | sqlite3VdbeJumpHere(v, addr+2); | ||
943 | }else | ||
944 | #endif /* SQLITE_OMIT_INTEGRITY_CHECK */ | ||
945 | |||
946 | #ifndef SQLITE_OMIT_UTF16 | ||
947 | /* | ||
948 | ** PRAGMA encoding | ||
949 | ** PRAGMA encoding = "utf-8"|"utf-16"|"utf-16le"|"utf-16be" | ||
950 | ** | ||
951 | ** In it's first form, this pragma returns the encoding of the main | ||
952 | ** database. If the database is not initialized, it is initialized now. | ||
953 | ** | ||
954 | ** The second form of this pragma is a no-op if the main database file | ||
955 | ** has not already been initialized. In this case it sets the default | ||
956 | ** encoding that will be used for the main database file if a new file | ||
957 | ** is created. If an existing main database file is opened, then the | ||
958 | ** default text encoding for the existing database is used. | ||
959 | ** | ||
960 | ** In all cases new databases created using the ATTACH command are | ||
961 | ** created to use the same default text encoding as the main database. If | ||
962 | ** the main database has not been initialized and/or created when ATTACH | ||
963 | ** is executed, this is done before the ATTACH operation. | ||
964 | ** | ||
965 | ** In the second form this pragma sets the text encoding to be used in | ||
966 | ** new database files created using this database handle. It is only | ||
967 | ** useful if invoked immediately after the main database i | ||
968 | */ | ||
969 | if( sqlite3StrICmp(zLeft, "encoding")==0 ){ | ||
970 | static const struct EncName { | ||
971 | char *zName; | ||
972 | u8 enc; | ||
973 | } encnames[] = { | ||
974 | { "UTF-8", SQLITE_UTF8 }, | ||
975 | { "UTF8", SQLITE_UTF8 }, | ||
976 | { "UTF-16le", SQLITE_UTF16LE }, | ||
977 | { "UTF16le", SQLITE_UTF16LE }, | ||
978 | { "UTF-16be", SQLITE_UTF16BE }, | ||
979 | { "UTF16be", SQLITE_UTF16BE }, | ||
980 | { "UTF-16", 0 }, /* SQLITE_UTF16NATIVE */ | ||
981 | { "UTF16", 0 }, /* SQLITE_UTF16NATIVE */ | ||
982 | { 0, 0 } | ||
983 | }; | ||
984 | const struct EncName *pEnc; | ||
985 | if( !zRight ){ /* "PRAGMA encoding" */ | ||
986 | if( sqlite3ReadSchema(pParse) ) goto pragma_out; | ||
987 | sqlite3VdbeSetNumCols(v, 1); | ||
988 | sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "encoding", P3_STATIC); | ||
989 | sqlite3VdbeAddOp(v, OP_String8, 0, 0); | ||
990 | for(pEnc=&encnames[0]; pEnc->zName; pEnc++){ | ||
991 | if( pEnc->enc==ENC(pParse->db) ){ | ||
992 | sqlite3VdbeChangeP3(v, -1, pEnc->zName, P3_STATIC); | ||
993 | break; | ||
994 | } | ||
995 | } | ||
996 | sqlite3VdbeAddOp(v, OP_Callback, 1, 0); | ||
997 | }else{ /* "PRAGMA encoding = XXX" */ | ||
998 | /* Only change the value of sqlite.enc if the database handle is not | ||
999 | ** initialized. If the main database exists, the new sqlite.enc value | ||
1000 | ** will be overwritten when the schema is next loaded. If it does not | ||
1001 | ** already exists, it will be created to use the new encoding value. | ||
1002 | */ | ||
1003 | if( | ||
1004 | !(DbHasProperty(db, 0, DB_SchemaLoaded)) || | ||
1005 | DbHasProperty(db, 0, DB_Empty) | ||
1006 | ){ | ||
1007 | for(pEnc=&encnames[0]; pEnc->zName; pEnc++){ | ||
1008 | if( 0==sqlite3StrICmp(zRight, pEnc->zName) ){ | ||
1009 | ENC(pParse->db) = pEnc->enc ? pEnc->enc : SQLITE_UTF16NATIVE; | ||
1010 | break; | ||
1011 | } | ||
1012 | } | ||
1013 | if( !pEnc->zName ){ | ||
1014 | sqlite3ErrorMsg(pParse, "unsupported encoding: %s", zRight); | ||
1015 | } | ||
1016 | } | ||
1017 | } | ||
1018 | }else | ||
1019 | #endif /* SQLITE_OMIT_UTF16 */ | ||
1020 | |||
1021 | #ifndef SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS | ||
1022 | /* | ||
1023 | ** PRAGMA [database.]schema_version | ||
1024 | ** PRAGMA [database.]schema_version = <integer> | ||
1025 | ** | ||
1026 | ** PRAGMA [database.]user_version | ||
1027 | ** PRAGMA [database.]user_version = <integer> | ||
1028 | ** | ||
1029 | ** The pragma's schema_version and user_version are used to set or get | ||
1030 | ** the value of the schema-version and user-version, respectively. Both | ||
1031 | ** the schema-version and the user-version are 32-bit signed integers | ||
1032 | ** stored in the database header. | ||
1033 | ** | ||
1034 | ** The schema-cookie is usually only manipulated internally by SQLite. It | ||
1035 | ** is incremented by SQLite whenever the database schema is modified (by | ||
1036 | ** creating or dropping a table or index). The schema version is used by | ||
1037 | ** SQLite each time a query is executed to ensure that the internal cache | ||
1038 | ** of the schema used when compiling the SQL query matches the schema of | ||
1039 | ** the database against which the compiled query is actually executed. | ||
1040 | ** Subverting this mechanism by using "PRAGMA schema_version" to modify | ||
1041 | ** the schema-version is potentially dangerous and may lead to program | ||
1042 | ** crashes or database corruption. Use with caution! | ||
1043 | ** | ||
1044 | ** The user-version is not used internally by SQLite. It may be used by | ||
1045 | ** applications for any purpose. | ||
1046 | */ | ||
1047 | if( sqlite3StrICmp(zLeft, "schema_version")==0 | ||
1048 | || sqlite3StrICmp(zLeft, "user_version")==0 | ||
1049 | || sqlite3StrICmp(zLeft, "freelist_count")==0 | ||
1050 | ){ | ||
1051 | |||
1052 | int iCookie; /* Cookie index. 0 for schema-cookie, 6 for user-cookie. */ | ||
1053 | sqlite3VdbeUsesBtree(v, iDb); | ||
1054 | switch( zLeft[0] ){ | ||
1055 | case 's': case 'S': | ||
1056 | iCookie = 0; | ||
1057 | break; | ||
1058 | case 'f': case 'F': | ||
1059 | iCookie = 1; | ||
1060 | iDb = (-1*(iDb+1)); | ||
1061 | assert(iDb<=0); | ||
1062 | break; | ||
1063 | default: | ||
1064 | iCookie = 5; | ||
1065 | break; | ||
1066 | } | ||
1067 | |||
1068 | if( zRight && iDb>=0 ){ | ||
1069 | /* Write the specified cookie value */ | ||
1070 | static const VdbeOpList setCookie[] = { | ||
1071 | { OP_Transaction, 0, 1, 0}, /* 0 */ | ||
1072 | { OP_Integer, 0, 0, 0}, /* 1 */ | ||
1073 | { OP_SetCookie, 0, 0, 0}, /* 2 */ | ||
1074 | }; | ||
1075 | int addr = sqlite3VdbeAddOpList(v, ArraySize(setCookie), setCookie); | ||
1076 | sqlite3VdbeChangeP1(v, addr, iDb); | ||
1077 | sqlite3VdbeChangeP1(v, addr+1, atoi(zRight)); | ||
1078 | sqlite3VdbeChangeP1(v, addr+2, iDb); | ||
1079 | sqlite3VdbeChangeP2(v, addr+2, iCookie); | ||
1080 | }else{ | ||
1081 | /* Read the specified cookie value */ | ||
1082 | static const VdbeOpList readCookie[] = { | ||
1083 | { OP_ReadCookie, 0, 0, 0}, /* 0 */ | ||
1084 | { OP_Callback, 1, 0, 0} | ||
1085 | }; | ||
1086 | int addr = sqlite3VdbeAddOpList(v, ArraySize(readCookie), readCookie); | ||
1087 | sqlite3VdbeChangeP1(v, addr, iDb); | ||
1088 | sqlite3VdbeChangeP2(v, addr, iCookie); | ||
1089 | sqlite3VdbeSetNumCols(v, 1); | ||
1090 | sqlite3VdbeSetColName(v, 0, COLNAME_NAME, zLeft, P3_TRANSIENT); | ||
1091 | } | ||
1092 | }else | ||
1093 | #endif /* SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS */ | ||
1094 | |||
1095 | #if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) | ||
1096 | /* | ||
1097 | ** Report the current state of file logs for all databases | ||
1098 | */ | ||
1099 | if( sqlite3StrICmp(zLeft, "lock_status")==0 ){ | ||
1100 | static const char *const azLockName[] = { | ||
1101 | "unlocked", "shared", "reserved", "pending", "exclusive" | ||
1102 | }; | ||
1103 | int i; | ||
1104 | Vdbe *v = sqlite3GetVdbe(pParse); | ||
1105 | sqlite3VdbeSetNumCols(v, 2); | ||
1106 | sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "database", P3_STATIC); | ||
1107 | sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "status", P3_STATIC); | ||
1108 | for(i=0; i<db->nDb; i++){ | ||
1109 | Btree *pBt; | ||
1110 | Pager *pPager; | ||
1111 | const char *zState = "unknown"; | ||
1112 | int j; | ||
1113 | if( db->aDb[i].zName==0 ) continue; | ||
1114 | sqlite3VdbeOp3(v, OP_String8, 0, 0, db->aDb[i].zName, P3_STATIC); | ||
1115 | pBt = db->aDb[i].pBt; | ||
1116 | if( pBt==0 || (pPager = sqlite3BtreePager(pBt))==0 ){ | ||
1117 | zState = "closed"; | ||
1118 | }else if( sqlite3_file_control(db, db->aDb[i].zName, | ||
1119 | SQLITE_FCNTL_LOCKSTATE, &j)==SQLITE_OK ){ | ||
1120 | zState = azLockName[j]; | ||
1121 | } | ||
1122 | sqlite3VdbeOp3(v, OP_String8, 0, 0, zState, P3_STATIC); | ||
1123 | sqlite3VdbeAddOp(v, OP_Callback, 2, 0); | ||
1124 | } | ||
1125 | }else | ||
1126 | #endif | ||
1127 | |||
1128 | #ifdef SQLITE_SSE | ||
1129 | /* | ||
1130 | ** Check to see if the sqlite_statements table exists. Create it | ||
1131 | ** if it does not. | ||
1132 | */ | ||
1133 | if( sqlite3StrICmp(zLeft, "create_sqlite_statement_table")==0 ){ | ||
1134 | extern int sqlite3CreateStatementsTable(Parse*); | ||
1135 | sqlite3CreateStatementsTable(pParse); | ||
1136 | }else | ||
1137 | #endif | ||
1138 | |||
1139 | #if SQLITE_HAS_CODEC | ||
1140 | if( sqlite3StrICmp(zLeft, "key")==0 ){ | ||
1141 | sqlite3_key(db, zRight, strlen(zRight)); | ||
1142 | }else | ||
1143 | #endif | ||
1144 | #if SQLITE_HAS_CODEC || defined(SQLITE_ENABLE_CEROD) | ||
1145 | if( sqlite3StrICmp(zLeft, "activate_extensions")==0 ){ | ||
1146 | #if SQLITE_HAS_CODEC | ||
1147 | if( sqlite3StrNICmp(zRight, "see-", 4)==0 ){ | ||
1148 | extern void sqlite3_activate_see(const char*); | ||
1149 | sqlite3_activate_see(&zRight[4]); | ||
1150 | } | ||
1151 | #endif | ||
1152 | #ifdef SQLITE_ENABLE_CEROD | ||
1153 | if( sqlite3StrNICmp(zRight, "cerod-", 6)==0 ){ | ||
1154 | extern void sqlite3_activate_cerod(const char*); | ||
1155 | sqlite3_activate_cerod(&zRight[6]); | ||
1156 | } | ||
1157 | #endif | ||
1158 | } | ||
1159 | #endif | ||
1160 | |||
1161 | {} | ||
1162 | |||
1163 | if( v ){ | ||
1164 | /* Code an OP_Expire at the end of each PRAGMA program to cause | ||
1165 | ** the VDBE implementing the pragma to expire. Most (all?) pragmas | ||
1166 | ** are only valid for a single execution. | ||
1167 | */ | ||
1168 | sqlite3VdbeAddOp(v, OP_Expire, 1, 0); | ||
1169 | |||
1170 | /* | ||
1171 | ** Reset the safety level, in case the fullfsync flag or synchronous | ||
1172 | ** setting changed. | ||
1173 | */ | ||
1174 | #ifndef SQLITE_OMIT_PAGER_PRAGMAS | ||
1175 | if( db->autoCommit ){ | ||
1176 | sqlite3BtreeSetSafetyLevel(pDb->pBt, pDb->safety_level, | ||
1177 | (db->flags&SQLITE_FullFSync)!=0); | ||
1178 | } | ||
1179 | #endif | ||
1180 | } | ||
1181 | pragma_out: | ||
1182 | sqlite3_free(zLeft); | ||
1183 | sqlite3_free(zRight); | ||
1184 | } | ||
1185 | |||
1186 | #endif /* SQLITE_OMIT_PRAGMA || SQLITE_OMIT_PARSER */ | ||