diff options
Diffstat (limited to 'ext/pdo_sqlite/sqlite/src/pragma.c')
| -rw-r--r-- | ext/pdo_sqlite/sqlite/src/pragma.c | 134 |
1 files changed, 117 insertions, 17 deletions
diff --git a/ext/pdo_sqlite/sqlite/src/pragma.c b/ext/pdo_sqlite/sqlite/src/pragma.c index fbcc1adc0..831aac57b 100644 --- a/ext/pdo_sqlite/sqlite/src/pragma.c +++ b/ext/pdo_sqlite/sqlite/src/pragma.c @@ -62,6 +62,17 @@ static int getBoolean(const char *z){ return getSafetyLevel(z)&1; } +/* +** Interpret the given string as a locking mode value. +*/ +static int getLockingMode(const char *z){ + if( z ){ + if( 0==sqlite3StrICmp(z, "exclusive") ) return PAGER_LOCKINGMODE_EXCLUSIVE; + if( 0==sqlite3StrICmp(z, "normal") ) return PAGER_LOCKINGMODE_NORMAL; + } + return PAGER_LOCKINGMODE_QUERY; +} + #ifndef SQLITE_OMIT_PAGER_PRAGMAS /* ** Interpret the given string as a temp db location. Return 1 for file @@ -89,7 +100,7 @@ static int getTempStore(const char *z){ static int invalidateTempStorage(Parse *pParse){ sqlite3 *db = pParse->db; if( db->aDb[1].pBt!=0 ){ - if( db->flags & SQLITE_InTrans ){ + if( !db->autoCommit ){ sqlite3ErrorMsg(pParse, "temporary storage cannot be changed " "from within a transaction"); return SQLITE_ERROR; @@ -157,7 +168,7 @@ static int flagPragma(Parse *pParse, const char *zLeft, const char *zRight){ { "ignore_check_constraints", SQLITE_IgnoreChecks }, #endif /* The following is VERY experimental */ - { "writable_schema", SQLITE_WriteSchema }, + { "writable_schema", SQLITE_WriteSchema|SQLITE_RecoveryMode }, { "omit_readlock", SQLITE_NoReadlock }, /* TODO: Maybe it shouldn't be possible to change the ReadUncommitted @@ -315,6 +326,53 @@ void sqlite3Pragma( sqlite3BtreeSetPageSize(pBt, atoi(zRight), -1); } }else + + /* + ** PRAGMA [database.]locking_mode + ** PRAGMA [database.]locking_mode = (normal|exclusive) + */ + if( sqlite3StrICmp(zLeft,"locking_mode")==0 ){ + const char *zRet = "normal"; + int eMode = getLockingMode(zRight); + + if( pId2->n==0 && eMode==PAGER_LOCKINGMODE_QUERY ){ + /* Simple "PRAGMA locking_mode;" statement. This is a query for + ** the current default locking mode (which may be different to + ** the locking-mode of the main database). + */ + eMode = db->dfltLockMode; + }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 locking-mode must be + ** set on all attached databases, as well as the main db file. + ** + ** Also, the sqlite3.dfltLockMode variable is set so that + ** any subsequently attached databases also use the specified + ** locking mode. + */ + int ii; + assert(pDb==&db->aDb[0]); + for(ii=2; ii<db->nDb; ii++){ + pPager = sqlite3BtreePager(db->aDb[ii].pBt); + sqlite3PagerLockingMode(pPager, eMode); + } + db->dfltLockMode = eMode; + } + pPager = sqlite3BtreePager(pDb->pBt); + eMode = sqlite3PagerLockingMode(pPager, eMode); + } + + assert(eMode==PAGER_LOCKINGMODE_NORMAL||eMode==PAGER_LOCKINGMODE_EXCLUSIVE); + if( eMode==PAGER_LOCKINGMODE_EXCLUSIVE ){ + zRet = "exclusive"; + } + sqlite3VdbeSetNumCols(v, 1); + sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "locking_mode", P3_STATIC); + sqlite3VdbeOp3(v, OP_String8, 0, 0, zRet, 0); + sqlite3VdbeAddOp(v, OP_Callback, 1, 0); + }else #endif /* SQLITE_OMIT_PAGER_PRAGMAS */ /* @@ -482,12 +540,17 @@ void sqlite3Pragma( sqlite3VdbeSetColName(v, 5, COLNAME_NAME, "pk", P3_STATIC); sqlite3ViewGetColumnNames(pParse, pTab); for(i=0, pCol=pTab->aCol; i<pTab->nCol; i++, pCol++){ + const Token *pDflt; sqlite3VdbeAddOp(v, OP_Integer, i, 0); sqlite3VdbeOp3(v, OP_String8, 0, 0, pCol->zName, 0); sqlite3VdbeOp3(v, OP_String8, 0, 0, pCol->zType ? pCol->zType : "", 0); sqlite3VdbeAddOp(v, OP_Integer, pCol->notNull, 0); - sqlite3ExprCode(pParse, pCol->pDflt); + if( pCol->pDflt && (pDflt = &pCol->pDflt->span)->z ){ + sqlite3VdbeOp3(v, OP_String8, 0, 0, (char*)pDflt->z, pDflt->n); + }else{ + sqlite3VdbeAddOp(v, OP_Null, 0, 0); + } sqlite3VdbeAddOp(v, OP_Integer, pCol->isPrimKey, 0); sqlite3VdbeAddOp(v, OP_Callback, 6, 0); } @@ -635,9 +698,13 @@ void sqlite3Pragma( } }else +#ifndef SQLITE_INTEGRITY_CHECK_ERROR_MAX +# define SQLITE_INTEGRITY_CHECK_ERROR_MAX 100 +#endif + #ifndef SQLITE_OMIT_INTEGRITY_CHECK if( sqlite3StrICmp(zLeft, "integrity_check")==0 ){ - int i, j, addr; + int i, j, addr, mxErr; /* Code that appears at the end of the integrity check. If no error ** messages have been generated, output OK. Otherwise output the @@ -655,7 +722,16 @@ void sqlite3Pragma( if( sqlite3ReadSchema(pParse) ) goto pragma_out; sqlite3VdbeSetNumCols(v, 1); sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "integrity_check", P3_STATIC); - sqlite3VdbeAddOp(v, OP_MemInt, 0, 0); /* Initialize error count to 0 */ + + /* Set the maximum error count */ + mxErr = SQLITE_INTEGRITY_CHECK_ERROR_MAX; + if( zRight ){ + mxErr = atoi(zRight); + if( mxErr<=0 ){ + mxErr = SQLITE_INTEGRITY_CHECK_ERROR_MAX; + } + } + sqlite3VdbeAddOp(v, OP_MemInt, mxErr, 0); /* Do an integrity check on each database file */ for(i=0; i<db->nDb; i++){ @@ -666,6 +742,9 @@ void sqlite3Pragma( if( OMIT_TEMPDB && i==1 ) continue; sqlite3CodeVerifySchema(pParse, i); + addr = sqlite3VdbeAddOp(v, OP_IfMemPos, 0, 0); + sqlite3VdbeAddOp(v, OP_Halt, 0, 0); + sqlite3VdbeJumpHere(v, addr); /* Do an integrity check of the B-Tree */ @@ -680,28 +759,28 @@ void sqlite3Pragma( cnt++; } } - assert( cnt>0 ); - sqlite3VdbeAddOp(v, OP_IntegrityCk, cnt, i); - sqlite3VdbeAddOp(v, OP_Dup, 0, 1); - addr = sqlite3VdbeOp3(v, OP_String8, 0, 0, "ok", P3_STATIC); - sqlite3VdbeAddOp(v, OP_Eq, 0, addr+7); + if( cnt==0 ) continue; + sqlite3VdbeAddOp(v, OP_IntegrityCk, 0, i); + addr = sqlite3VdbeAddOp(v, OP_IsNull, -1, 0); sqlite3VdbeOp3(v, OP_String8, 0, 0, sqlite3MPrintf("*** in database %s ***\n", db->aDb[i].zName), P3_DYNAMIC); sqlite3VdbeAddOp(v, OP_Pull, 1, 0); - sqlite3VdbeAddOp(v, OP_Concat, 0, 1); + sqlite3VdbeAddOp(v, OP_Concat, 0, 0); sqlite3VdbeAddOp(v, OP_Callback, 1, 0); - sqlite3VdbeAddOp(v, OP_MemIncr, 1, 0); + sqlite3VdbeJumpHere(v, addr); /* Make sure all the indices are constructed correctly. */ - sqlite3CodeVerifySchema(pParse, i); for(x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){ Table *pTab = sqliteHashData(x); Index *pIdx; int loopTop; if( pTab->pIndex==0 ) continue; + addr = sqlite3VdbeAddOp(v, OP_IfMemPos, 0, 0); + sqlite3VdbeAddOp(v, OP_Halt, 0, 0); + sqlite3VdbeJumpHere(v, addr); sqlite3OpenTableAndIndices(pParse, pTab, 1, OP_OpenRead); sqlite3VdbeAddOp(v, OP_MemInt, 0, 1); loopTop = sqlite3VdbeAddOp(v, OP_Rewind, 1, 0); @@ -709,7 +788,7 @@ void sqlite3Pragma( for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){ int jmp2; static const VdbeOpList idxErr[] = { - { OP_MemIncr, 1, 0, 0}, + { OP_MemIncr, -1, 0, 0}, { OP_String8, 0, 0, "rowid "}, { OP_Rowid, 1, 0, 0}, { OP_String8, 0, 0, " missing from index "}, @@ -734,13 +813,16 @@ void sqlite3Pragma( { OP_MemLoad, 1, 0, 0}, { OP_MemLoad, 2, 0, 0}, { OP_Eq, 0, 0, 0}, /* 6 */ - { OP_MemIncr, 1, 0, 0}, + { OP_MemIncr, -1, 0, 0}, { OP_String8, 0, 0, "wrong # of entries in index "}, { OP_String8, 0, 0, 0}, /* 9 */ { OP_Concat, 0, 0, 0}, { OP_Callback, 1, 0, 0}, }; if( pIdx->tnum==0 ) continue; + addr = sqlite3VdbeAddOp(v, OP_IfMemPos, 0, 0); + sqlite3VdbeAddOp(v, OP_Halt, 0, 0); + sqlite3VdbeJumpHere(v, addr); addr = sqlite3VdbeAddOpList(v, ArraySize(cntIdx), cntIdx); sqlite3VdbeChangeP1(v, addr+1, j+2); sqlite3VdbeChangeP2(v, addr+1, addr+4); @@ -752,6 +834,7 @@ void sqlite3Pragma( } } addr = sqlite3VdbeAddOpList(v, ArraySize(endCode), endCode); + sqlite3VdbeChangeP1(v, addr+1, mxErr); sqlite3VdbeJumpHere(v, addr+2); }else #endif /* SQLITE_OMIT_INTEGRITY_CHECK */ @@ -889,8 +972,9 @@ void sqlite3Pragma( sqlite3VdbeChangeP1(v, addr, iDb); sqlite3VdbeChangeP2(v, addr, iCookie); sqlite3VdbeSetNumCols(v, 1); + sqlite3VdbeSetColName(v, 0, COLNAME_NAME, zLeft, P3_TRANSIENT); } - } + }else #endif /* SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS */ #if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) @@ -915,7 +999,7 @@ void sqlite3Pragma( if( pBt==0 || (pPager = sqlite3BtreePager(pBt))==0 ){ sqlite3VdbeOp3(v, OP_String8, 0, 0, "closed", P3_STATIC); }else{ - int j = sqlite3pager_lockstate(pPager); + int j = sqlite3PagerLockstate(pPager); sqlite3VdbeOp3(v, OP_String8, 0, 0, (j>=0 && j<=4) ? azLockName[j] : "unknown", P3_STATIC); } @@ -940,6 +1024,22 @@ void sqlite3Pragma( sqlite3_key(db, zRight, strlen(zRight)); }else #endif +#if SQLITE_HAS_CODEC || defined(SQLITE_ENABLE_CEROD) + if( sqlite3StrICmp(zLeft, "activate_extensions")==0 ){ +#if 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 + } +#endif {} |
