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