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