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