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