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>