| Index: third_party/sqlite/src/src/pragma.c
|
| diff --git a/third_party/sqlite/src/src/pragma.c b/third_party/sqlite/src/src/pragma.c
|
| index 60f214a0c39afc2328bafbd6aa8b89096b3b4823..75ab26d441a0463a1d15e16b160d7c338f592596 100644
|
| --- a/third_party/sqlite/src/src/pragma.c
|
| +++ b/third_party/sqlite/src/src/pragma.c
|
| @@ -10,8 +10,6 @@
|
| **
|
| *************************************************************************
|
| ** This file contains code used to implement the PRAGMA command.
|
| -**
|
| -** $Id: pragma.c,v 1.214 2009/07/02 07:47:33 danielk1977 Exp $
|
| */
|
| #include "sqliteInt.h"
|
|
|
| @@ -37,7 +35,7 @@ static u8 getSafetyLevel(const char *z){
|
| static const u8 iValue[] = {1, 0, 0, 0, 1, 1, 2};
|
| int i, n;
|
| if( sqlite3Isdigit(*z) ){
|
| - return (u8)atoi(z);
|
| + return (u8)sqlite3Atoi(z);
|
| }
|
| n = sqlite3Strlen30(z);
|
| for(i=0; i<ArraySize(iLength); i++){
|
| @@ -78,7 +76,7 @@ static int getAutoVacuum(const char *z){
|
| if( 0==sqlite3StrICmp(z, "none") ) return BTREE_AUTOVACUUM_NONE;
|
| if( 0==sqlite3StrICmp(z, "full") ) return BTREE_AUTOVACUUM_FULL;
|
| if( 0==sqlite3StrICmp(z, "incremental") ) return BTREE_AUTOVACUUM_INCR;
|
| - i = atoi(z);
|
| + i = sqlite3Atoi(z);
|
| return (u8)((i>=0&&i<=2)?i:0);
|
| }
|
| #endif /* ifndef SQLITE_OMIT_AUTOVACUUM */
|
| @@ -117,7 +115,7 @@ static int invalidateTempStorage(Parse *pParse){
|
| }
|
| sqlite3BtreeClose(db->aDb[1].pBt);
|
| db->aDb[1].pBt = 0;
|
| - sqlite3ResetInternalSchema(db, 0);
|
| + sqlite3ResetInternalSchema(db, -1);
|
| }
|
| return SQLITE_OK;
|
| }
|
| @@ -174,7 +172,11 @@ static int flagPragma(Parse *pParse, const char *zLeft, const char *zRight){
|
| { "empty_result_callbacks", SQLITE_NullCallback },
|
| { "legacy_file_format", SQLITE_LegacyFileFmt },
|
| { "fullfsync", SQLITE_FullFSync },
|
| + { "checkpoint_fullfsync", SQLITE_CkptFullFSync },
|
| { "reverse_unordered_selects", SQLITE_ReverseOrder },
|
| +#ifndef SQLITE_OMIT_AUTOMATIC_INDEX
|
| + { "automatic_index", SQLITE_AutoIndex },
|
| +#endif
|
| #ifdef SQLITE_DEBUG
|
| { "sql_trace", SQLITE_SqlTrace },
|
| { "vdbe_listing", SQLITE_VdbeListing },
|
| @@ -191,6 +193,12 @@ static int flagPragma(Parse *pParse, const char *zLeft, const char *zRight){
|
| ** flag if there are any active statements. */
|
| { "read_uncommitted", SQLITE_ReadUncommitted },
|
| { "recursive_triggers", SQLITE_RecTriggers },
|
| +
|
| + /* This flag may only be set if both foreign-key and trigger support
|
| + ** are present in the build. */
|
| +#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER)
|
| + { "foreign_keys", SQLITE_ForeignKeys },
|
| +#endif
|
| };
|
| int i;
|
| const struct sPragmaType *p;
|
| @@ -204,10 +212,17 @@ static int flagPragma(Parse *pParse, const char *zLeft, const char *zRight){
|
| if( zRight==0 ){
|
| returnSingleInt(pParse, p->zName, (db->flags & p->mask)!=0 );
|
| }else{
|
| + int mask = p->mask; /* Mask of bits to set or clear. */
|
| + if( db->autoCommit==0 ){
|
| + /* Foreign key support may not be enabled or disabled while not
|
| + ** in auto-commit mode. */
|
| + mask &= ~(SQLITE_ForeignKeys);
|
| + }
|
| +
|
| if( getBoolean(zRight) ){
|
| - db->flags |= p->mask;
|
| + db->flags |= mask;
|
| }else{
|
| - db->flags &= ~p->mask;
|
| + db->flags &= ~mask;
|
| }
|
|
|
| /* Many of the flag-pragmas modify the code generated by the SQL
|
| @@ -228,17 +243,45 @@ static int flagPragma(Parse *pParse, const char *zLeft, const char *zRight){
|
| /*
|
| ** Return a human-readable name for a constraint resolution action.
|
| */
|
| +#ifndef SQLITE_OMIT_FOREIGN_KEY
|
| static const char *actionName(u8 action){
|
| const char *zName;
|
| switch( action ){
|
| - case OE_SetNull: zName = "SET NULL"; break;
|
| - case OE_SetDflt: zName = "SET DEFAULT"; break;
|
| - case OE_Cascade: zName = "CASCADE"; break;
|
| - default: zName = "RESTRICT";
|
| - assert( action==OE_Restrict ); break;
|
| + case OE_SetNull: zName = "SET NULL"; break;
|
| + case OE_SetDflt: zName = "SET DEFAULT"; break;
|
| + case OE_Cascade: zName = "CASCADE"; break;
|
| + case OE_Restrict: zName = "RESTRICT"; break;
|
| + default: zName = "NO ACTION";
|
| + assert( action==OE_None ); break;
|
| }
|
| return zName;
|
| }
|
| +#endif
|
| +
|
| +
|
| +/*
|
| +** Parameter eMode must be one of the PAGER_JOURNALMODE_XXX constants
|
| +** defined in pager.h. This function returns the associated lowercase
|
| +** journal-mode name.
|
| +*/
|
| +const char *sqlite3JournalModename(int eMode){
|
| + static char * const azModeName[] = {
|
| + "delete", "persist", "off", "truncate", "memory"
|
| +#ifndef SQLITE_OMIT_WAL
|
| + , "wal"
|
| +#endif
|
| + };
|
| + assert( PAGER_JOURNALMODE_DELETE==0 );
|
| + assert( PAGER_JOURNALMODE_PERSIST==1 );
|
| + assert( PAGER_JOURNALMODE_OFF==2 );
|
| + assert( PAGER_JOURNALMODE_TRUNCATE==3 );
|
| + assert( PAGER_JOURNALMODE_MEMORY==4 );
|
| + assert( PAGER_JOURNALMODE_WAL==5 );
|
| + assert( eMode>=0 && eMode<=ArraySize(azModeName) );
|
| +
|
| + if( eMode==ArraySize(azModeName) ) return 0;
|
| + return azModeName[eMode];
|
| +}
|
|
|
| /*
|
| ** Process a pragma statement.
|
| @@ -271,6 +314,7 @@ void sqlite3Pragma(
|
| Db *pDb;
|
| Vdbe *v = pParse->pVdbe = sqlite3VdbeCreate(db);
|
| if( v==0 ) return;
|
| + sqlite3VdbeRunOnlyOnce(v);
|
| pParse->nMem = 2;
|
|
|
| /* Interpret the [database.] part of the pragma statement. iDb is the
|
| @@ -311,11 +355,11 @@ void sqlite3Pragma(
|
| ** page cache size value and the persistent page cache size value
|
| ** stored in the database file.
|
| **
|
| - ** The default cache size is stored in meta-value 2 of page 1 of the
|
| - ** database file. The cache size is actually the absolute value of
|
| - ** this memory location. The sign of meta-value 2 determines the
|
| - ** synchronous setting. A negative value means synchronous is off
|
| - ** and a positive value means synchronous is on.
|
| + ** Older versions of SQLite would set the default cache size to a
|
| + ** negative number to indicate synchronous=OFF. These days, synchronous
|
| + ** is always on by default regardless of the sign of the default cache
|
| + ** size. But continue to take the absolute value of the default cache
|
| + ** size of historical compatibility.
|
| */
|
| if( sqlite3StrICmp(zLeft,"default_cache_size")==0 ){
|
| static const VdbeOpList getCacheSize[] = {
|
| @@ -340,15 +384,11 @@ void sqlite3Pragma(
|
| sqlite3VdbeChangeP1(v, addr+1, iDb);
|
| sqlite3VdbeChangeP1(v, addr+6, SQLITE_DEFAULT_CACHE_SIZE);
|
| }else{
|
| - int size = atoi(zRight);
|
| - if( size<0 ) size = -size;
|
| + int size = sqlite3AbsInt32(sqlite3Atoi(zRight));
|
| sqlite3BeginWriteOperation(pParse, 0, iDb);
|
| sqlite3VdbeAddOp2(v, OP_Integer, size, 1);
|
| - sqlite3VdbeAddOp3(v, OP_ReadCookie, iDb, 2, BTREE_DEFAULT_CACHE_SIZE);
|
| - addr = sqlite3VdbeAddOp2(v, OP_IfPos, 2, 0);
|
| - sqlite3VdbeAddOp2(v, OP_Integer, -size, 1);
|
| - sqlite3VdbeJumpHere(v, addr);
|
| sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_DEFAULT_CACHE_SIZE, 1);
|
| + assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
|
| pDb->pSchema->cache_size = size;
|
| sqlite3BtreeSetCacheSize(pDb->pBt, pDb->pSchema->cache_size);
|
| }
|
| @@ -373,7 +413,7 @@ void sqlite3Pragma(
|
| /* Malloc may fail when setting the page-size, as there is an internal
|
| ** buffer that the pager module resizes using sqlite3_realloc().
|
| */
|
| - db->nextPagesize = atoi(zRight);
|
| + db->nextPagesize = sqlite3Atoi(zRight);
|
| if( SQLITE_NOMEM==sqlite3BtreeSetPageSize(pBt, db->nextPagesize, -1, 0) ){
|
| db->mallocFailed = 1;
|
| }
|
| @@ -381,41 +421,58 @@ void sqlite3Pragma(
|
| }else
|
|
|
| /*
|
| - ** PRAGMA [database.]max_page_count
|
| - ** PRAGMA [database.]max_page_count=N
|
| + ** PRAGMA [database.]secure_delete
|
| + ** PRAGMA [database.]secure_delete=ON/OFF
|
| **
|
| ** The first form reports the current setting for the
|
| - ** maximum number of pages in the database file. The
|
| - ** second form attempts to change this setting. Both
|
| - ** forms return the current setting.
|
| + ** secure_delete flag. The second form changes the secure_delete
|
| + ** flag setting and reports thenew value.
|
| */
|
| - if( sqlite3StrICmp(zLeft,"max_page_count")==0 ){
|
| + if( sqlite3StrICmp(zLeft,"secure_delete")==0 ){
|
| Btree *pBt = pDb->pBt;
|
| - int newMax = 0;
|
| + int b = -1;
|
| assert( pBt!=0 );
|
| if( zRight ){
|
| - newMax = atoi(zRight);
|
| + b = getBoolean(zRight);
|
| }
|
| - if( ALWAYS(pBt) ){
|
| - newMax = sqlite3BtreeMaxPageCount(pBt, newMax);
|
| + if( pId2->n==0 && b>=0 ){
|
| + int ii;
|
| + for(ii=0; ii<db->nDb; ii++){
|
| + sqlite3BtreeSecureDelete(db->aDb[ii].pBt, b);
|
| + }
|
| }
|
| - returnSingleInt(pParse, "max_page_count", newMax);
|
| + b = sqlite3BtreeSecureDelete(pBt, b);
|
| + returnSingleInt(pParse, "secure_delete", b);
|
| }else
|
|
|
| /*
|
| + ** PRAGMA [database.]max_page_count
|
| + ** PRAGMA [database.]max_page_count=N
|
| + **
|
| + ** The first form reports the current setting for the
|
| + ** maximum number of pages in the database file. The
|
| + ** second form attempts to change this setting. Both
|
| + ** forms return the current setting.
|
| + **
|
| ** PRAGMA [database.]page_count
|
| **
|
| ** Return the number of pages in the specified database.
|
| */
|
| - if( sqlite3StrICmp(zLeft,"page_count")==0 ){
|
| + if( sqlite3StrICmp(zLeft,"page_count")==0
|
| + || sqlite3StrICmp(zLeft,"max_page_count")==0
|
| + ){
|
| int iReg;
|
| if( sqlite3ReadSchema(pParse) ) goto pragma_out;
|
| sqlite3CodeVerifySchema(pParse, iDb);
|
| iReg = ++pParse->nMem;
|
| - sqlite3VdbeAddOp2(v, OP_Pagecount, iDb, iReg);
|
| + if( zLeft[0]=='p' ){
|
| + sqlite3VdbeAddOp2(v, OP_Pagecount, iDb, iReg);
|
| + }else{
|
| + sqlite3VdbeAddOp3(v, OP_MaxPgcnt, iDb, iReg, sqlite3Atoi(zRight));
|
| + }
|
| sqlite3VdbeAddOp2(v, OP_ResultRow, iReg, 1);
|
| sqlite3VdbeSetNumCols(v, 1);
|
| - sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "page_count", SQLITE_STATIC);
|
| + sqlite3VdbeSetColName(v, 0, COLNAME_NAME, zLeft, SQLITE_TRANSIENT);
|
| }else
|
|
|
| /*
|
| @@ -467,62 +524,49 @@ void sqlite3Pragma(
|
|
|
| /*
|
| ** PRAGMA [database.]journal_mode
|
| - ** PRAGMA [database.]journal_mode = (delete|persist|off|truncate|memory)
|
| + ** PRAGMA [database.]journal_mode =
|
| + ** (delete|persist|off|truncate|memory|wal|off)
|
| */
|
| if( sqlite3StrICmp(zLeft,"journal_mode")==0 ){
|
| - int eMode;
|
| - static char * const azModeName[] = {
|
| - "delete", "persist", "off", "truncate", "memory"
|
| - };
|
| + int eMode; /* One of the PAGER_JOURNALMODE_XXX symbols */
|
| + int ii; /* Loop counter */
|
| +
|
| + /* Force the schema to be loaded on all databases. This cases all
|
| + ** database files to be opened and the journal_modes set. */
|
| + if( sqlite3ReadSchema(pParse) ){
|
| + goto pragma_out;
|
| + }
|
| +
|
| + sqlite3VdbeSetNumCols(v, 1);
|
| + sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "journal_mode", SQLITE_STATIC);
|
|
|
| if( zRight==0 ){
|
| + /* If there is no "=MODE" part of the pragma, do a query for the
|
| + ** current mode */
|
| eMode = PAGER_JOURNALMODE_QUERY;
|
| }else{
|
| + const char *zMode;
|
| int n = sqlite3Strlen30(zRight);
|
| - eMode = sizeof(azModeName)/sizeof(azModeName[0]) - 1;
|
| - while( eMode>=0 && sqlite3StrNICmp(zRight, azModeName[eMode], n)!=0 ){
|
| - eMode--;
|
| + for(eMode=0; (zMode = sqlite3JournalModename(eMode))!=0; eMode++){
|
| + if( sqlite3StrNICmp(zRight, zMode, n)==0 ) break;
|
| + }
|
| + if( !zMode ){
|
| + /* If the "=MODE" part does not match any known journal mode,
|
| + ** then do a query */
|
| + eMode = PAGER_JOURNALMODE_QUERY;
|
| }
|
| }
|
| - if( pId2->n==0 && eMode==PAGER_JOURNALMODE_QUERY ){
|
| - /* Simple "PRAGMA journal_mode;" statement. This is a query for
|
| - ** the current default journal mode (which may be different to
|
| - ** the journal-mode of the main database).
|
| - */
|
| - eMode = db->dfltJournalMode;
|
| - }else{
|
| - Pager *pPager;
|
| - if( pId2->n==0 ){
|
| - /* This indicates that no database name was specified as part
|
| - ** of the PRAGMA command. In this case the journal-mode must be
|
| - ** set on all attached databases, as well as the main db file.
|
| - **
|
| - ** Also, the sqlite3.dfltJournalMode variable is set so that
|
| - ** any subsequently attached databases also use the specified
|
| - ** journal mode.
|
| - */
|
| - int ii;
|
| - assert(pDb==&db->aDb[0]);
|
| - for(ii=1; ii<db->nDb; ii++){
|
| - if( db->aDb[ii].pBt ){
|
| - pPager = sqlite3BtreePager(db->aDb[ii].pBt);
|
| - sqlite3PagerJournalMode(pPager, eMode);
|
| - }
|
| - }
|
| - db->dfltJournalMode = (u8)eMode;
|
| + if( eMode==PAGER_JOURNALMODE_QUERY && pId2->n==0 ){
|
| + /* Convert "PRAGMA journal_mode" into "PRAGMA main.journal_mode" */
|
| + iDb = 0;
|
| + pId2->n = 1;
|
| + }
|
| + for(ii=db->nDb-1; ii>=0; ii--){
|
| + if( db->aDb[ii].pBt && (ii==iDb || pId2->n==0) ){
|
| + sqlite3VdbeUsesBtree(v, ii);
|
| + sqlite3VdbeAddOp3(v, OP_JournalMode, ii, 1, eMode);
|
| }
|
| - pPager = sqlite3BtreePager(pDb->pBt);
|
| - eMode = sqlite3PagerJournalMode(pPager, eMode);
|
| }
|
| - assert( eMode==PAGER_JOURNALMODE_DELETE
|
| - || eMode==PAGER_JOURNALMODE_TRUNCATE
|
| - || eMode==PAGER_JOURNALMODE_PERSIST
|
| - || eMode==PAGER_JOURNALMODE_OFF
|
| - || eMode==PAGER_JOURNALMODE_MEMORY );
|
| - sqlite3VdbeSetNumCols(v, 1);
|
| - sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "journal_mode", SQLITE_STATIC);
|
| - sqlite3VdbeAddOp4(v, OP_String8, 0, 1, 0,
|
| - azModeName[eMode], P4_STATIC);
|
| sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1);
|
| }else
|
|
|
| @@ -536,7 +580,7 @@ void sqlite3Pragma(
|
| Pager *pPager = sqlite3BtreePager(pDb->pBt);
|
| i64 iLimit = -2;
|
| if( zRight ){
|
| - sqlite3Atoi64(zRight, &iLimit);
|
| + sqlite3Atoi64(zRight, &iLimit, 1000000, SQLITE_UTF8);
|
| if( iLimit<-1 ) iLimit = -1;
|
| }
|
| iLimit = sqlite3PagerJournalSizeLimit(pPager, iLimit);
|
| @@ -647,11 +691,11 @@ void sqlite3Pragma(
|
| */
|
| if( sqlite3StrICmp(zLeft,"cache_size")==0 ){
|
| if( sqlite3ReadSchema(pParse) ) goto pragma_out;
|
| + assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
|
| if( !zRight ){
|
| returnSingleInt(pParse, "cache_size", pDb->pSchema->cache_size);
|
| }else{
|
| - int size = atoi(zRight);
|
| - if( size<0 ) size = -size;
|
| + int size = sqlite3AbsInt32(sqlite3Atoi(zRight));
|
| pDb->pSchema->cache_size = size;
|
| sqlite3BtreeSetCacheSize(pDb->pBt, pDb->pSchema->cache_size);
|
| }
|
| @@ -714,7 +758,7 @@ void sqlite3Pragma(
|
| }
|
| sqlite3_free(sqlite3_temp_directory);
|
| if( zRight[0] ){
|
| - sqlite3_temp_directory = sqlite3DbStrDup(0, zRight);
|
| + sqlite3_temp_directory = sqlite3_mprintf("%s", zRight);
|
| }else{
|
| sqlite3_temp_directory = 0;
|
| }
|
| @@ -965,8 +1009,8 @@ void sqlite3Pragma(
|
| int j;
|
| for(j=0; j<pFK->nCol; j++){
|
| char *zCol = pFK->aCol[j].zCol;
|
| - char *zOnUpdate = (char *)actionName(pFK->updateConf);
|
| - char *zOnDelete = (char *)actionName(pFK->deleteConf);
|
| + char *zOnDelete = (char *)actionName(pFK->aAction[0]);
|
| + char *zOnUpdate = (char *)actionName(pFK->aAction[1]);
|
| sqlite3VdbeAddOp2(v, OP_Integer, i, 1);
|
| sqlite3VdbeAddOp2(v, OP_Integer, j, 2);
|
| sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, pFK->zTo, 0);
|
| @@ -1043,7 +1087,7 @@ void sqlite3Pragma(
|
| /* Set the maximum error count */
|
| mxErr = SQLITE_INTEGRITY_CHECK_ERROR_MAX;
|
| if( zRight ){
|
| - mxErr = atoi(zRight);
|
| + sqlite3GetInt32(zRight, &mxErr);
|
| if( mxErr<=0 ){
|
| mxErr = SQLITE_INTEGRITY_CHECK_ERROR_MAX;
|
| }
|
| @@ -1068,6 +1112,7 @@ void sqlite3Pragma(
|
| ** Begin by filling registers 2, 3, ... with the root pages numbers
|
| ** for all tables and indices in the database.
|
| */
|
| + assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
|
| pTbls = &db->aDb[i].pSchema->tblHash;
|
| for(x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){
|
| Table *pTab = sqliteHashData(x);
|
| @@ -1114,6 +1159,7 @@ void sqlite3Pragma(
|
| sqlite3VdbeAddOp2(v, OP_AddImm, 2, 1); /* increment entry count */
|
| for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
|
| int jmp2;
|
| + int r1;
|
| static const VdbeOpList idxErr[] = {
|
| { OP_AddImm, 1, -1, 0},
|
| { OP_String8, 0, 3, 0}, /* 1 */
|
| @@ -1127,12 +1173,12 @@ void sqlite3Pragma(
|
| { OP_IfPos, 1, 0, 0}, /* 9 */
|
| { OP_Halt, 0, 0, 0},
|
| };
|
| - sqlite3GenerateIndexKey(pParse, pIdx, 1, 3, 1);
|
| - jmp2 = sqlite3VdbeAddOp3(v, OP_Found, j+2, 0, 3);
|
| + r1 = sqlite3GenerateIndexKey(pParse, pIdx, 1, 3, 0);
|
| + jmp2 = sqlite3VdbeAddOp4Int(v, OP_Found, j+2, 0, r1, pIdx->nColumn+1);
|
| addr = sqlite3VdbeAddOpList(v, ArraySize(idxErr), idxErr);
|
| sqlite3VdbeChangeP4(v, addr+1, "rowid ", P4_STATIC);
|
| sqlite3VdbeChangeP4(v, addr+3, " missing from index ", P4_STATIC);
|
| - sqlite3VdbeChangeP4(v, addr+4, pIdx->zName, P4_STATIC);
|
| + sqlite3VdbeChangeP4(v, addr+4, pIdx->zName, P4_TRANSIENT);
|
| sqlite3VdbeJumpHere(v, addr+9);
|
| sqlite3VdbeJumpHere(v, jmp2);
|
| }
|
| @@ -1162,7 +1208,7 @@ void sqlite3Pragma(
|
| sqlite3VdbeJumpHere(v, addr+4);
|
| sqlite3VdbeChangeP4(v, addr+6,
|
| "wrong # of entries in index ", P4_STATIC);
|
| - sqlite3VdbeChangeP4(v, addr+7, pIdx->zName, P4_STATIC);
|
| + sqlite3VdbeChangeP4(v, addr+7, pIdx->zName, P4_TRANSIENT);
|
| }
|
| }
|
| }
|
| @@ -1299,7 +1345,7 @@ void sqlite3Pragma(
|
| };
|
| int addr = sqlite3VdbeAddOpList(v, ArraySize(setCookie), setCookie);
|
| sqlite3VdbeChangeP1(v, addr, iDb);
|
| - sqlite3VdbeChangeP1(v, addr+1, atoi(zRight));
|
| + sqlite3VdbeChangeP1(v, addr+1, sqlite3Atoi(zRight));
|
| sqlite3VdbeChangeP1(v, addr+2, iDb);
|
| sqlite3VdbeChangeP2(v, addr+2, iCookie);
|
| }else{
|
| @@ -1319,6 +1365,71 @@ void sqlite3Pragma(
|
| }else
|
| #endif /* SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS */
|
|
|
| +#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS
|
| + /*
|
| + ** PRAGMA compile_options
|
| + **
|
| + ** Return the names of all compile-time options used in this build,
|
| + ** one option per row.
|
| + */
|
| + if( sqlite3StrICmp(zLeft, "compile_options")==0 ){
|
| + int i = 0;
|
| + const char *zOpt;
|
| + sqlite3VdbeSetNumCols(v, 1);
|
| + pParse->nMem = 1;
|
| + sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "compile_option", SQLITE_STATIC);
|
| + while( (zOpt = sqlite3_compileoption_get(i++))!=0 ){
|
| + sqlite3VdbeAddOp4(v, OP_String8, 0, 1, 0, zOpt, 0);
|
| + sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1);
|
| + }
|
| + }else
|
| +#endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */
|
| +
|
| +#ifndef SQLITE_OMIT_WAL
|
| + /*
|
| + ** PRAGMA [database.]wal_checkpoint = passive|full|restart
|
| + **
|
| + ** Checkpoint the database.
|
| + */
|
| + if( sqlite3StrICmp(zLeft, "wal_checkpoint")==0 ){
|
| + int iBt = (pId2->z?iDb:SQLITE_MAX_ATTACHED);
|
| + int eMode = SQLITE_CHECKPOINT_PASSIVE;
|
| + if( zRight ){
|
| + if( sqlite3StrICmp(zRight, "full")==0 ){
|
| + eMode = SQLITE_CHECKPOINT_FULL;
|
| + }else if( sqlite3StrICmp(zRight, "restart")==0 ){
|
| + eMode = SQLITE_CHECKPOINT_RESTART;
|
| + }
|
| + }
|
| + if( sqlite3ReadSchema(pParse) ) goto pragma_out;
|
| + sqlite3VdbeSetNumCols(v, 3);
|
| + pParse->nMem = 3;
|
| + sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "busy", SQLITE_STATIC);
|
| + sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "log", SQLITE_STATIC);
|
| + sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "checkpointed", SQLITE_STATIC);
|
| +
|
| + sqlite3VdbeAddOp3(v, OP_Checkpoint, iBt, eMode, 1);
|
| + sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 3);
|
| + }else
|
| +
|
| + /*
|
| + ** PRAGMA wal_autocheckpoint
|
| + ** PRAGMA wal_autocheckpoint = N
|
| + **
|
| + ** Configure a database connection to automatically checkpoint a database
|
| + ** after accumulating N frames in the log. Or query for the current value
|
| + ** of N.
|
| + */
|
| + if( sqlite3StrICmp(zLeft, "wal_autocheckpoint")==0 ){
|
| + if( zRight ){
|
| + sqlite3_wal_autocheckpoint(db, sqlite3Atoi(zRight));
|
| + }
|
| + returnSingleInt(pParse, "wal_autocheckpoint",
|
| + db->xWalCallback==sqlite3WalDefaultHook ?
|
| + SQLITE_PTR_TO_INT(db->pWalArg) : 0);
|
| + }else
|
| +#endif
|
| +
|
| #if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
|
| /*
|
| ** Report the current state of file logs for all databases
|
| @@ -1353,7 +1464,7 @@ void sqlite3Pragma(
|
| }else
|
| #endif
|
|
|
| -#if SQLITE_HAS_CODEC
|
| +#ifdef SQLITE_HAS_CODEC
|
| if( sqlite3StrICmp(zLeft, "key")==0 && zRight ){
|
| sqlite3_key(db, zRight, sqlite3Strlen30(zRight));
|
| }else
|
| @@ -1376,17 +1487,15 @@ void sqlite3Pragma(
|
| }
|
| }else
|
| #endif
|
| -#if SQLITE_HAS_CODEC || defined(SQLITE_ENABLE_CEROD)
|
| +#if defined(SQLITE_HAS_CODEC) || defined(SQLITE_ENABLE_CEROD)
|
| if( sqlite3StrICmp(zLeft, "activate_extensions")==0 ){
|
| -#if SQLITE_HAS_CODEC
|
| +#ifdef SQLITE_HAS_CODEC
|
| if( sqlite3StrNICmp(zRight, "see-", 4)==0 ){
|
| - extern void sqlite3_activate_see(const char*);
|
| sqlite3_activate_see(&zRight[4]);
|
| }
|
| #endif
|
| #ifdef SQLITE_ENABLE_CEROD
|
| if( sqlite3StrNICmp(zRight, "cerod-", 6)==0 ){
|
| - extern void sqlite3_activate_cerod(const char*);
|
| sqlite3_activate_cerod(&zRight[6]);
|
| }
|
| #endif
|
| @@ -1396,12 +1505,6 @@ void sqlite3Pragma(
|
|
|
| {/* Empty ELSE clause */}
|
|
|
| - /* Code an OP_Expire at the end of each PRAGMA program to cause
|
| - ** the VDBE implementing the pragma to expire. Most (all?) pragmas
|
| - ** are only valid for a single execution.
|
| - */
|
| - sqlite3VdbeAddOp2(v, OP_Expire, 1, 0);
|
| -
|
| /*
|
| ** Reset the safety level, in case the fullfsync flag or synchronous
|
| ** setting changed.
|
| @@ -1409,7 +1512,8 @@ void sqlite3Pragma(
|
| #ifndef SQLITE_OMIT_PAGER_PRAGMAS
|
| if( db->autoCommit ){
|
| sqlite3BtreeSetSafetyLevel(pDb->pBt, pDb->safety_level,
|
| - (db->flags&SQLITE_FullFSync)!=0);
|
| + (db->flags&SQLITE_FullFSync)!=0,
|
| + (db->flags&SQLITE_CkptFullFSync)!=0);
|
| }
|
| #endif
|
| pragma_out:
|
|
|