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: |