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..362e77f29e955ee15130362459936d72ee51ecac 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" |
@@ -175,6 +173,9 @@ static int flagPragma(Parse *pParse, const char *zLeft, const char *zRight){ |
{ "legacy_file_format", SQLITE_LegacyFileFmt }, |
{ "fullfsync", SQLITE_FullFSync }, |
{ "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 +192,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 +211,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 +242,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 +313,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 +354,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[] = { |
@@ -344,10 +387,6 @@ void sqlite3Pragma( |
if( size<0 ) size = -size; |
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); |
pDb->pSchema->cache_size = size; |
sqlite3BtreeSetCacheSize(pDb->pBt, pDb->pSchema->cache_size); |
@@ -403,6 +442,31 @@ void sqlite3Pragma( |
}else |
/* |
+ ** PRAGMA [database.]secure_delete |
+ ** PRAGMA [database.]secure_delete=ON/OFF |
+ ** |
+ ** The first form reports the current setting for the |
+ ** secure_delete flag. The second form changes the secure_delete |
+ ** flag setting and reports thenew value. |
+ */ |
+ if( sqlite3StrICmp(zLeft,"secure_delete")==0 ){ |
+ Btree *pBt = pDb->pBt; |
+ int b = -1; |
+ assert( pBt!=0 ); |
+ if( zRight ){ |
+ b = getBoolean(zRight); |
+ } |
+ if( pId2->n==0 && b>=0 ){ |
+ int ii; |
+ for(ii=0; ii<db->nDb; ii++){ |
+ sqlite3BtreeSecureDelete(db->aDb[ii].pBt, b); |
+ } |
+ } |
+ b = sqlite3BtreeSecureDelete(pBt, b); |
+ returnSingleInt(pParse, "secure_delete", b); |
+ }else |
+ |
+ /* |
** PRAGMA [database.]page_count |
** |
** Return the number of pages in the specified database. |
@@ -467,62 +531,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 +587,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); |
@@ -714,7 +765,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 +1016,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); |
@@ -1114,6 +1165,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,8 +1179,8 @@ 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); |
@@ -1319,6 +1371,56 @@ 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 |
+ ** |
+ ** Checkpoint the database. |
+ */ |
+ if( sqlite3StrICmp(zLeft, "wal_checkpoint")==0 ){ |
+ if( sqlite3ReadSchema(pParse) ) goto pragma_out; |
+ sqlite3VdbeAddOp3(v, OP_Checkpoint, pId2->z?iDb:SQLITE_MAX_ATTACHED, 0, 0); |
+ }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 ){ |
+ int nAuto = atoi(zRight); |
+ sqlite3_wal_autocheckpoint(db, nAuto); |
+ } |
+ 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 +1455,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 +1478,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 +1496,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. |