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