diff --git a/manifest b/manifest index b25987a370..84e9c1d09c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Allow\sFTS4\smulti-token\sphrases\sto\suse\sa\scombination\sof\sin-memory\sand\sincrementally\sloaded\sdoclists.\sThis\sallows\sphrases\sto\s(partially)\sbenefit\sfrom\sincremental\sdoclists\swithout\sdisabling\sthe\sdeferred\stoken\soptimization. -D 2013-10-03T19:27:14.455 +C Merge\slatest\strunk\schanges. +D 2013-10-03T20:28:22.404 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5e41da95d92656a5004b03d3576e8b226858a28e F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -158,15 +158,15 @@ F sqlite3.1 6be1ad09113570e1fc8dcaff84c9b0b337db5ffc F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a F src/alter.c 2af0330bb1b601af7a7789bf7229675fd772a083 F src/analyze.c d322972af09e3f8debb45f420dfe3ded142b108b -F src/attach.c 4a2b6a6d9b5f9fd55a8b59488ff7929fef73a195 +F src/attach.c 0a17c9364895316ca4f52d06a97a72c0af1ae8b3 F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34 F src/backup.c 2f1987981139bd2f6d8c728d64bf09fb387443c3 F src/bitvec.c 19a4ba637bd85f8f63fc8c9bae5ade9fb05ec1cb F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7 F src/btree.c 5ccbbaed7a32ba774306f610da4ab4f3e5348294 F src/btree.h bfe0e8c5759b4ec77b0d18390064a6ef3cdffaaf -F src/btreeInt.h 51cf220a9b9223354770883e93a859dc377aa27f -F src/build.c f63e8929c7f89c0074fbc74929bc946ea117b2f8 +F src/btreeInt.h f038e818bfadf75afbd09819ed93c26a333d39e0 +F src/build.c 834fa4bb0fa936c39336c52f5aacc659035d973e F src/callback.c f99a8957ba2adf369645fac0db09ad8adcf1caa2 F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c ea4b7f3623a0fcb1146e7f245d7410033e86859c @@ -210,7 +210,7 @@ F src/parse.y a97566d6da75075589a7c716d1bda14b586cf8da F src/pcache.c f8043b433a57aba85384a531e3937a804432a346 F src/pcache.h a5e4f5d9f5d592051d91212c5949517971ae6222 F src/pcache1.c a467393909a4ed7ca9de066d85ba5c5b04a5be63 -F src/pragma.c 0c7a67a75cb4f9849190f33f62534d37f38ff8ed +F src/pragma.c 5a4d8d9c3c7d22ef920487a260ea3d4b59d3b3a6 F src/prepare.c fa6988589f39af8504a61731614cd4f6ae71554f F src/printf.c da9119eb31a187a4b99f60aa4a225141c0ebb74b F src/random.c 0b2dbc37fdfbfa6bd455b091dfcef5bdb32dba68 @@ -221,11 +221,11 @@ F src/shell.c 5ee50ca3e35453bbd6ccdf1bdd0f6bbe9738e9fb F src/sqlite.h.in ec40aa958a270416fb04b4f72210357bf163d2c5 F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc -F src/sqliteInt.h 18c7f80e7e23098942436f7286e9c93adc6908be +F src/sqliteInt.h 50f51427e7afd2803c9b8380d34069ae212a0f4c F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e -F src/tclsqlite.c 659dad8ef30b54831306a244b43e37af4725a444 +F src/tclsqlite.c 3b5f3716e320480659239abe887164521c575d83 F src/test1.c 26226cfd2b6dc3f77d2eb27f07ffcf236b4e728b F src/test2.c 7355101c085304b90024f2261e056cdff13c6c35 F src/test3.c 1c0e5d6f080b8e33c1ce8b3078e7013fdbcd560c @@ -245,7 +245,7 @@ F src/test_devsym.c e7498904e72ba7491d142d5c83b476c4e76993bc F src/test_fs.c ced436e3d4b8e4681328409b8081051ce614e28f F src/test_func.c f8235719dff4bf9ffee04c55a190af8782ce9ab5 F src/test_hexio.c abfdecb6fa58c354623978efceb088ca18e379cd -F src/test_init.c 3cbad7ce525aec925f8fda2192d576d47f0d478a +F src/test_init.c 66b33120ffe9cd853b5a905ec850d51151337b32 F src/test_intarray.c 87847c71c3c36889c0bcc9c4baf9d31881665d61 F src/test_intarray.h 2ece66438cfd177b78d1bfda7a4180cd3a10844d F src/test_journal.c f5c0a05b7b3d5930db769b5ee6c3766dc2221a64 @@ -272,7 +272,7 @@ F src/test_vfs.c e72f555ef7a59080f898fcf1a233deb9eb704ea9 F src/test_vfstrace.c 34b544e80ba7fb77be15395a609c669df2e660a2 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/tokenize.c 70061085a51f2f4fc15ece94f32c03bcb78e63b2 -F src/trigger.c 5c0ea9b8755e7c5e1a700f3e27ac4f8d92dd221e +F src/trigger.c ba0a883cd536b7dfdd4df3733001f5372a4299da F src/update.c f5182157f5d0d0a97bc5f5e3c9bdba0dfbe08f08 F src/utf.c 6fc6c88d50448c469c5c196acf21617a24f90269 F src/util.c 7f3e35432d6888d1e770c488c35bd98970c44eec @@ -989,6 +989,7 @@ F test/triggerA.test fe5597f47ee21bacb4936dc827994ed94161e332 F test/triggerB.test 56780c031b454abac2340dbb3b71ac5c56c3d7fe F test/triggerC.test a7b4367392c755bc5fd5fff88011753e6b6afe90 F test/triggerD.test 8e7f3921a92a5797d472732108109e44575fa650 +F test/triggerE.test 355e9c5cbaed5cd039a60baad1fb2197caeb8e52 F test/tt3_checkpoint.c 415eccce672d681b297485fc20f44cdf0eac93af F test/types.test bf816ce73c7dfcfe26b700c19f97ef4050d194ff F test/types2.test 3555aacf8ed8dc883356e59efc314707e6247a84 @@ -1082,12 +1083,12 @@ F tool/fragck.tcl 5265a95126abcf6ab357f7efa544787e5963f439 F tool/genfkey.README cf68fddd4643bbe3ff8e31b8b6d8b0a1b85e20f4 F tool/genfkey.test 4196a8928b78f51d54ef58e99e99401ab2f0a7e5 F tool/getlock.c f4c39b651370156cae979501a7b156bdba50e7ce -F tool/lemon.c 680980c7935bfa1edec20c804c9e5ba4b1dd96f5 +F tool/lemon.c 323e54ac86fb2393f9950219224e304620d2fb12 F tool/lempar.c 01ca97f87610d1dac6d8cd96ab109ab1130e76dc F tool/mkautoconfamal.sh f8d8dbf7d62f409ebed5134998bf5b51d7266383 F tool/mkkeywordhash.c bb52064aa614e1426445e4b2b9b00eeecd23cc79 F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e -F tool/mkpragmatab.tcl e24da1496b4af6de448e9673cf6adbef53e6e830 +F tool/mkpragmatab.tcl 33fa7a6e824b14f7b04109ed75b19f3e9e228412 F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97 F tool/mksqlite3c-noext.tcl 8bce31074e4cbe631bb7676526a048335f4c9f02 F tool/mksqlite3c.tcl d344cc3144a0271cd853c5e3df36e9f31d78d619 @@ -1120,7 +1121,7 @@ F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/wherecosttest.c f407dc4c79786982a475261866a161cd007947ae F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P bc3a2ed5fb2402805928b0002457eebf06f87c47 -R 901c988fa73ccb0a783d711147163b1a +P f6819c5f3363d358e7ef65fe6978f13991bd44af 500c5932fe3f5fcd0940522f7839d581c555e0eb +R 699a595349579dae27a85bc7620bf39e U dan -Z a8c5d4de2473f3c23eca341d3a936ce8 +Z 5bb0415038281aaab1af73554b907022 diff --git a/manifest.uuid b/manifest.uuid index a09415fd3f..169d9fcd3b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f6819c5f3363d358e7ef65fe6978f13991bd44af \ No newline at end of file +24aa20da222a9cc181473bc41d0f8791be91fa97 \ No newline at end of file diff --git a/src/attach.c b/src/attach.c index 805305dab6..223c166482 100644 --- a/src/attach.c +++ b/src/attach.c @@ -417,11 +417,8 @@ void sqlite3Attach(Parse *pParse, Expr *p, Expr *pDbname, Expr *pKey){ /* ** Initialize a DbFixer structure. This routine must be called prior ** to passing the structure to one of the sqliteFixAAAA() routines below. -** -** The return value indicates whether or not fixation is required. TRUE -** means we do need to fix the database references, FALSE means we do not. */ -int sqlite3FixInit( +void sqlite3FixInit( DbFixer *pFix, /* The fixer to be initialized */ Parse *pParse, /* Error messages will be written here */ int iDb, /* This is the database that must be used */ @@ -430,7 +427,6 @@ int sqlite3FixInit( ){ sqlite3 *db; - if( NEVER(iDb<0) || iDb==1 ) return 0; db = pParse->db; assert( db->nDb>iDb ); pFix->pParse = pParse; @@ -438,7 +434,7 @@ int sqlite3FixInit( pFix->pSchema = db->aDb[iDb].pSchema; pFix->zType = zType; pFix->pName = pName; - return 1; + pFix->bVarOnly = (iDb==1); } /* @@ -466,15 +462,17 @@ int sqlite3FixSrcList( if( NEVER(pList==0) ) return 0; zDb = pFix->zDb; for(i=0, pItem=pList->a; inSrc; i++, pItem++){ - if( pItem->zDatabase && sqlite3StrICmp(pItem->zDatabase, zDb) ){ - sqlite3ErrorMsg(pFix->pParse, - "%s %T cannot reference objects in database %s", - pFix->zType, pFix->pName, pItem->zDatabase); - return 1; + if( pFix->bVarOnly==0 ){ + if( pItem->zDatabase && sqlite3StrICmp(pItem->zDatabase, zDb) ){ + sqlite3ErrorMsg(pFix->pParse, + "%s %T cannot reference objects in database %s", + pFix->zType, pFix->pName, pItem->zDatabase); + return 1; + } + sqlite3DbFree(pFix->pParse->db, pItem->zDatabase); + pItem->zDatabase = 0; + pItem->pSchema = pFix->pSchema; } - sqlite3DbFree(pFix->pParse->db, pItem->zDatabase); - pItem->zDatabase = 0; - pItem->pSchema = pFix->pSchema; #if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER) if( sqlite3FixSelect(pFix, pItem->pSelect) ) return 1; if( sqlite3FixExpr(pFix, pItem->pOn) ) return 1; @@ -497,9 +495,21 @@ int sqlite3FixSelect( if( sqlite3FixExpr(pFix, pSelect->pWhere) ){ return 1; } + if( sqlite3FixExprList(pFix, pSelect->pGroupBy) ){ + return 1; + } if( sqlite3FixExpr(pFix, pSelect->pHaving) ){ return 1; } + if( sqlite3FixExprList(pFix, pSelect->pOrderBy) ){ + return 1; + } + if( sqlite3FixExpr(pFix, pSelect->pLimit) ){ + return 1; + } + if( sqlite3FixExpr(pFix, pSelect->pOffset) ){ + return 1; + } pSelect = pSelect->pPrior; } return 0; @@ -509,6 +519,14 @@ int sqlite3FixExpr( Expr *pExpr /* The expression to be fixed to one database */ ){ while( pExpr ){ + if( pExpr->op==TK_VARIABLE ){ + if( pFix->pParse->db->init.busy ){ + pExpr->op = TK_NULL; + }else{ + sqlite3ErrorMsg(pFix->pParse, "%s cannot use variables", pFix->zType); + return 1; + } + } if( ExprHasProperty(pExpr, EP_TokenOnly) ) break; if( ExprHasProperty(pExpr, EP_xIsSelect) ){ if( sqlite3FixSelect(pFix, pExpr->x.pSelect) ) return 1; diff --git a/src/btreeInt.h b/src/btreeInt.h index 60da24d90c..3ebdeb663e 100644 --- a/src/btreeInt.h +++ b/src/btreeInt.h @@ -56,13 +56,13 @@ ** ** OFFSET SIZE DESCRIPTION ** 0 16 Header string: "SQLite format 3\000" -** 16 2 Page size in bytes. +** 16 2 Page size in bytes. (1 means 65536) ** 18 1 File format write version ** 19 1 File format read version ** 20 1 Bytes of unused space at the end of each page -** 21 1 Max embedded payload fraction -** 22 1 Min embedded payload fraction -** 23 1 Min leaf payload fraction +** 21 1 Max embedded payload fraction (must be 64) +** 22 1 Min embedded payload fraction (must be 32) +** 23 1 Min leaf payload fraction (must be 32) ** 24 4 File change counter ** 28 4 Reserved for future use ** 32 4 First freelist page @@ -76,9 +76,10 @@ ** 56 4 1=UTF-8 2=UTF16le 3=UTF16be ** 60 4 User version ** 64 4 Incremental vacuum mode -** 68 4 unused -** 72 4 unused -** 76 4 unused +** 68 4 Application-ID +** 72 20 unused +** 92 4 The version-valid-for number +** 96 4 SQLITE_VERSION_NUMBER ** ** All of the integer values are big-endian (most significant byte first). ** diff --git a/src/build.c b/src/build.c index 491ca28382..79753f093f 100644 --- a/src/build.c +++ b/src/build.c @@ -1722,9 +1722,8 @@ void sqlite3CreateView( } sqlite3TwoPartName(pParse, pName1, pName2, &pName); iDb = sqlite3SchemaToIndex(db, p->pSchema); - if( sqlite3FixInit(&sFix, pParse, iDb, "view", pName) - && sqlite3FixSelect(&sFix, pSelect) - ){ + sqlite3FixInit(&sFix, pParse, iDb, "view", pName); + if( sqlite3FixSelect(&sFix, pSelect) ){ sqlite3SelectDelete(db, pSelect); return; } @@ -2524,9 +2523,8 @@ Index *sqlite3CreateIndex( } #endif - if( sqlite3FixInit(&sFix, pParse, iDb, "index", pName) && - sqlite3FixSrcList(&sFix, pTblName) - ){ + sqlite3FixInit(&sFix, pParse, iDb, "index", pName); + if( sqlite3FixSrcList(&sFix, pTblName) ){ /* Because the parser constructs pTblName from a single identifier, ** sqlite3FixSrcList can never fail. */ assert(0); diff --git a/src/pragma.c b/src/pragma.c index a79b401f03..f533b71c21 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -68,175 +68,353 @@ #define PragTyp_REKEY 37 #define PragTyp_LOCK_STATUS 38 #define PragTyp_PARSER_TRACE 39 +#define PragFlag_NeedSchema 0x01 static const struct sPragmaNames { const char *const zName; /* Name of pragma */ u8 ePragTyp; /* PragTyp_XXX value */ + u8 mPragFlag; /* Zero or more PragFlag_XXX values */ u32 iArg; /* Extra argument */ } aPragmaNames[] = { #if defined(SQLITE_HAS_CODEC) || defined(SQLITE_ENABLE_CEROD) - { "activate_extensions", PragTyp_ACTIVATE_EXTENSIONS, 0 }, + { /* zName: */ "activate_extensions", + /* ePragTyp: */ PragTyp_ACTIVATE_EXTENSIONS, + /* ePragFlag: */ 0, + /* iArg: */ 0 }, #endif #if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS) - { "application_id", PragTyp_HEADER_VALUE, 0 }, + { /* zName: */ "application_id", + /* ePragTyp: */ PragTyp_HEADER_VALUE, + /* ePragFlag: */ 0, + /* iArg: */ 0 }, #endif #if !defined(SQLITE_OMIT_AUTOVACUUM) - { "auto_vacuum", PragTyp_AUTO_VACUUM, 0 }, + { /* zName: */ "auto_vacuum", + /* ePragTyp: */ PragTyp_AUTO_VACUUM, + /* ePragFlag: */ PragFlag_NeedSchema, + /* iArg: */ 0 }, #endif #if !defined(SQLITE_OMIT_AUTOMATIC_INDEX) - { "automatic_index", PragTyp_FLAG, - SQLITE_AutoIndex }, + { /* zName: */ "automatic_index", + /* ePragTyp: */ PragTyp_FLAG, + /* ePragFlag: */ 0, + /* iArg: */ SQLITE_AutoIndex }, #endif - { "busy_timeout", PragTyp_BUSY_TIMEOUT, 0 }, + { /* zName: */ "busy_timeout", + /* ePragTyp: */ PragTyp_BUSY_TIMEOUT, + /* ePragFlag: */ 0, + /* iArg: */ 0 }, #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) - { "cache_size", PragTyp_CACHE_SIZE, 0 }, + { /* zName: */ "cache_size", + /* ePragTyp: */ PragTyp_CACHE_SIZE, + /* ePragFlag: */ PragFlag_NeedSchema, + /* iArg: */ 0 }, #endif - { "cache_spill", PragTyp_FLAG, - SQLITE_CacheSpill }, - { "case_sensitive_like", PragTyp_CASE_SENSITIVE_LIKE, 0 }, - { "checkpoint_fullfsync", PragTyp_FLAG, - SQLITE_CkptFullFSync }, + { /* zName: */ "cache_spill", + /* ePragTyp: */ PragTyp_FLAG, + /* ePragFlag: */ 0, + /* iArg: */ SQLITE_CacheSpill }, + { /* zName: */ "case_sensitive_like", + /* ePragTyp: */ PragTyp_CASE_SENSITIVE_LIKE, + /* ePragFlag: */ 0, + /* iArg: */ 0 }, + { /* zName: */ "checkpoint_fullfsync", + /* ePragTyp: */ PragTyp_FLAG, + /* ePragFlag: */ 0, + /* iArg: */ SQLITE_CkptFullFSync }, #if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) - { "collation_list", PragTyp_COLLATION_LIST, 0 }, + { /* zName: */ "collation_list", + /* ePragTyp: */ PragTyp_COLLATION_LIST, + /* ePragFlag: */ 0, + /* iArg: */ 0 }, #endif #if !defined(SQLITE_OMIT_COMPILEOPTION_DIAGS) - { "compile_options", PragTyp_COMPILE_OPTIONS, 0 }, + { /* zName: */ "compile_options", + /* ePragTyp: */ PragTyp_COMPILE_OPTIONS, + /* ePragFlag: */ 0, + /* iArg: */ 0 }, #endif - { "count_changes", PragTyp_FLAG, - SQLITE_CountRows }, + { /* zName: */ "count_changes", + /* ePragTyp: */ PragTyp_FLAG, + /* ePragFlag: */ 0, + /* iArg: */ SQLITE_CountRows }, #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && SQLITE_OS_WIN - { "data_store_directory", PragTyp_DATA_STORE_DIRECTORY, 0 }, + { /* zName: */ "data_store_directory", + /* ePragTyp: */ PragTyp_DATA_STORE_DIRECTORY, + /* ePragFlag: */ 0, + /* iArg: */ 0 }, #endif #if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) - { "database_list", PragTyp_DATABASE_LIST, 0 }, + { /* zName: */ "database_list", + /* ePragTyp: */ PragTyp_DATABASE_LIST, + /* ePragFlag: */ PragFlag_NeedSchema, + /* iArg: */ 0 }, #endif #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && !defined(SQLITE_OMIT_DEPRECATED) - { "default_cache_size", PragTyp_DEFAULT_CACHE_SIZE, 0 }, + { /* zName: */ "default_cache_size", + /* ePragTyp: */ PragTyp_DEFAULT_CACHE_SIZE, + /* ePragFlag: */ PragFlag_NeedSchema, + /* iArg: */ 0 }, #endif #if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER) - { "defer_foreign_keys", PragTyp_FLAG, - SQLITE_DeferFKs }, + { /* zName: */ "defer_foreign_keys", + /* ePragTyp: */ PragTyp_FLAG, + /* ePragFlag: */ 0, + /* iArg: */ SQLITE_DeferFKs }, #endif - { "empty_result_callbacks", PragTyp_FLAG, - SQLITE_NullCallback }, + { /* zName: */ "empty_result_callbacks", + /* ePragTyp: */ PragTyp_FLAG, + /* ePragFlag: */ 0, + /* iArg: */ SQLITE_NullCallback }, #if !defined(SQLITE_OMIT_UTF16) - { "encoding", PragTyp_ENCODING, 0 }, + { /* zName: */ "encoding", + /* ePragTyp: */ PragTyp_ENCODING, + /* ePragFlag: */ 0, + /* iArg: */ 0 }, #endif #if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER) - { "foreign_key_check", PragTyp_FOREIGN_KEY_CHECK, 0 }, + { /* zName: */ "foreign_key_check", + /* ePragTyp: */ PragTyp_FOREIGN_KEY_CHECK, + /* ePragFlag: */ PragFlag_NeedSchema, + /* iArg: */ 0 }, #endif #if !defined(SQLITE_OMIT_FOREIGN_KEY) - { "foreign_key_list", PragTyp_FOREIGN_KEY_LIST, 0 }, + { /* zName: */ "foreign_key_list", + /* ePragTyp: */ PragTyp_FOREIGN_KEY_LIST, + /* ePragFlag: */ PragFlag_NeedSchema, + /* iArg: */ 0 }, #endif #if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER) - { "foreign_keys", PragTyp_FLAG, - SQLITE_ForeignKeys }, + { /* zName: */ "foreign_keys", + /* ePragTyp: */ PragTyp_FLAG, + /* ePragFlag: */ 0, + /* iArg: */ SQLITE_ForeignKeys }, #endif #if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS) - { "freelist_count", PragTyp_HEADER_VALUE, 0 }, + { /* zName: */ "freelist_count", + /* ePragTyp: */ PragTyp_HEADER_VALUE, + /* ePragFlag: */ 0, + /* iArg: */ 0 }, #endif - { "full_column_names", PragTyp_FLAG, - SQLITE_FullColNames }, - { "fullfsync", PragTyp_FLAG, - SQLITE_FullFSync }, + { /* zName: */ "full_column_names", + /* ePragTyp: */ PragTyp_FLAG, + /* ePragFlag: */ 0, + /* iArg: */ SQLITE_FullColNames }, + { /* zName: */ "fullfsync", + /* ePragTyp: */ PragTyp_FLAG, + /* ePragFlag: */ 0, + /* iArg: */ SQLITE_FullFSync }, #if defined(SQLITE_HAS_CODEC) - { "hexkey", PragTyp_HEXKEY, 0 }, + { /* zName: */ "hexkey", + /* ePragTyp: */ PragTyp_HEXKEY, + /* ePragFlag: */ 0, + /* iArg: */ 0 }, #endif #if !defined(SQLITE_OMIT_CHECK) - { "ignore_check_constraints", PragTyp_FLAG, - SQLITE_IgnoreChecks }, + { /* zName: */ "ignore_check_constraints", + /* ePragTyp: */ PragTyp_FLAG, + /* ePragFlag: */ 0, + /* iArg: */ SQLITE_IgnoreChecks }, #endif #if !defined(SQLITE_OMIT_AUTOVACUUM) - { "incremental_vacuum", PragTyp_INCREMENTAL_VACUUM, 0 }, + { /* zName: */ "incremental_vacuum", + /* ePragTyp: */ PragTyp_INCREMENTAL_VACUUM, + /* ePragFlag: */ PragFlag_NeedSchema, + /* iArg: */ 0 }, #endif #if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) - { "index_info", PragTyp_INDEX_INFO, 0 }, - { "index_list", PragTyp_INDEX_LIST, 0 }, + { /* zName: */ "index_info", + /* ePragTyp: */ PragTyp_INDEX_INFO, + /* ePragFlag: */ PragFlag_NeedSchema, + /* iArg: */ 0 }, + { /* zName: */ "index_list", + /* ePragTyp: */ PragTyp_INDEX_LIST, + /* ePragFlag: */ PragFlag_NeedSchema, + /* iArg: */ 0 }, #endif #if !defined(SQLITE_OMIT_INTEGRITY_CHECK) - { "integrity_check", PragTyp_INTEGRITY_CHECK, 0 }, + { /* zName: */ "integrity_check", + /* ePragTyp: */ PragTyp_INTEGRITY_CHECK, + /* ePragFlag: */ PragFlag_NeedSchema, + /* iArg: */ 0 }, #endif #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) - { "journal_mode", PragTyp_JOURNAL_MODE, 0 }, - { "journal_size_limit", PragTyp_JOURNAL_SIZE_LIMIT, 0 }, + { /* zName: */ "journal_mode", + /* ePragTyp: */ PragTyp_JOURNAL_MODE, + /* ePragFlag: */ PragFlag_NeedSchema, + /* iArg: */ 0 }, + { /* zName: */ "journal_size_limit", + /* ePragTyp: */ PragTyp_JOURNAL_SIZE_LIMIT, + /* ePragFlag: */ 0, + /* iArg: */ 0 }, #endif #if defined(SQLITE_HAS_CODEC) - { "key", PragTyp_KEY, 0 }, + { /* zName: */ "key", + /* ePragTyp: */ PragTyp_KEY, + /* ePragFlag: */ 0, + /* iArg: */ 0 }, #endif - { "legacy_file_format", PragTyp_FLAG, - SQLITE_LegacyFileFmt }, + { /* zName: */ "legacy_file_format", + /* ePragTyp: */ PragTyp_FLAG, + /* ePragFlag: */ 0, + /* iArg: */ SQLITE_LegacyFileFmt }, #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && SQLITE_ENABLE_LOCKING_STYLE - { "lock_proxy_file", PragTyp_LOCK_PROXY_FILE, 0 }, + { /* zName: */ "lock_proxy_file", + /* ePragTyp: */ PragTyp_LOCK_PROXY_FILE, + /* ePragFlag: */ 0, + /* iArg: */ 0 }, #endif #if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) - { "lock_status", PragTyp_LOCK_STATUS, 0 }, + { /* zName: */ "lock_status", + /* ePragTyp: */ PragTyp_LOCK_STATUS, + /* ePragFlag: */ 0, + /* iArg: */ 0 }, #endif #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) - { "locking_mode", PragTyp_LOCKING_MODE, 0 }, - { "max_page_count", PragTyp_PAGE_COUNT, 0 }, - { "mmap_size", PragTyp_MMAP_SIZE, 0 }, - { "page_count", PragTyp_PAGE_COUNT, 0 }, - { "page_size", PragTyp_PAGE_SIZE, 0 }, + { /* zName: */ "locking_mode", + /* ePragTyp: */ PragTyp_LOCKING_MODE, + /* ePragFlag: */ 0, + /* iArg: */ 0 }, + { /* zName: */ "max_page_count", + /* ePragTyp: */ PragTyp_PAGE_COUNT, + /* ePragFlag: */ PragFlag_NeedSchema, + /* iArg: */ 0 }, + { /* zName: */ "mmap_size", + /* ePragTyp: */ PragTyp_MMAP_SIZE, + /* ePragFlag: */ 0, + /* iArg: */ 0 }, + { /* zName: */ "page_count", + /* ePragTyp: */ PragTyp_PAGE_COUNT, + /* ePragFlag: */ PragFlag_NeedSchema, + /* iArg: */ 0 }, + { /* zName: */ "page_size", + /* ePragTyp: */ PragTyp_PAGE_SIZE, + /* ePragFlag: */ 0, + /* iArg: */ 0 }, #endif #if defined(SQLITE_DEBUG) - { "parser_trace", PragTyp_PARSER_TRACE, 0 }, + { /* zName: */ "parser_trace", + /* ePragTyp: */ PragTyp_PARSER_TRACE, + /* ePragFlag: */ 0, + /* iArg: */ 0 }, #endif - { "query_only", PragTyp_FLAG, - SQLITE_QueryOnly }, + { /* zName: */ "query_only", + /* ePragTyp: */ PragTyp_FLAG, + /* ePragFlag: */ 0, + /* iArg: */ SQLITE_QueryOnly }, #if !defined(SQLITE_OMIT_INTEGRITY_CHECK) - { "quick_check", PragTyp_INTEGRITY_CHECK, 0 }, + { /* zName: */ "quick_check", + /* ePragTyp: */ PragTyp_INTEGRITY_CHECK, + /* ePragFlag: */ PragFlag_NeedSchema, + /* iArg: */ 0 }, #endif - { "read_uncommitted", PragTyp_FLAG, - SQLITE_ReadUncommitted }, - { "recursive_triggers", PragTyp_FLAG, - SQLITE_RecTriggers }, + { /* zName: */ "read_uncommitted", + /* ePragTyp: */ PragTyp_FLAG, + /* ePragFlag: */ 0, + /* iArg: */ SQLITE_ReadUncommitted }, + { /* zName: */ "recursive_triggers", + /* ePragTyp: */ PragTyp_FLAG, + /* ePragFlag: */ 0, + /* iArg: */ SQLITE_RecTriggers }, #if defined(SQLITE_HAS_CODEC) - { "rekey", PragTyp_REKEY, 0 }, + { /* zName: */ "rekey", + /* ePragTyp: */ PragTyp_REKEY, + /* ePragFlag: */ 0, + /* iArg: */ 0 }, #endif - { "reverse_unordered_selects", PragTyp_FLAG, - SQLITE_ReverseOrder }, + { /* zName: */ "reverse_unordered_selects", + /* ePragTyp: */ PragTyp_FLAG, + /* ePragFlag: */ 0, + /* iArg: */ SQLITE_ReverseOrder }, #if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS) - { "schema_version", PragTyp_HEADER_VALUE, 0 }, + { /* zName: */ "schema_version", + /* ePragTyp: */ PragTyp_HEADER_VALUE, + /* ePragFlag: */ 0, + /* iArg: */ 0 }, #endif #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) - { "secure_delete", PragTyp_SECURE_DELETE, 0 }, + { /* zName: */ "secure_delete", + /* ePragTyp: */ PragTyp_SECURE_DELETE, + /* ePragFlag: */ 0, + /* iArg: */ 0 }, #endif - { "short_column_names", PragTyp_FLAG, - SQLITE_ShortColNames }, - { "shrink_memory", PragTyp_SHRINK_MEMORY, 0 }, - { "soft_heap_limit", PragTyp_SOFT_HEAP_LIMIT, 0 }, + { /* zName: */ "short_column_names", + /* ePragTyp: */ PragTyp_FLAG, + /* ePragFlag: */ 0, + /* iArg: */ SQLITE_ShortColNames }, + { /* zName: */ "shrink_memory", + /* ePragTyp: */ PragTyp_SHRINK_MEMORY, + /* ePragFlag: */ 0, + /* iArg: */ 0 }, + { /* zName: */ "soft_heap_limit", + /* ePragTyp: */ PragTyp_SOFT_HEAP_LIMIT, + /* ePragFlag: */ 0, + /* iArg: */ 0 }, #if defined(SQLITE_DEBUG) - { "sql_trace", PragTyp_FLAG, - SQLITE_SqlTrace }, + { /* zName: */ "sql_trace", + /* ePragTyp: */ PragTyp_FLAG, + /* ePragFlag: */ 0, + /* iArg: */ SQLITE_SqlTrace }, #endif #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) - { "synchronous", PragTyp_SYNCHRONOUS, 0 }, + { /* zName: */ "synchronous", + /* ePragTyp: */ PragTyp_SYNCHRONOUS, + /* ePragFlag: */ PragFlag_NeedSchema, + /* iArg: */ 0 }, #endif #if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) - { "table_info", PragTyp_TABLE_INFO, 0 }, + { /* zName: */ "table_info", + /* ePragTyp: */ PragTyp_TABLE_INFO, + /* ePragFlag: */ PragFlag_NeedSchema, + /* iArg: */ 0 }, #endif #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) - { "temp_store", PragTyp_TEMP_STORE, 0 }, - { "temp_store_directory", PragTyp_TEMP_STORE_DIRECTORY, 0 }, + { /* zName: */ "temp_store", + /* ePragTyp: */ PragTyp_TEMP_STORE, + /* ePragFlag: */ 0, + /* iArg: */ 0 }, + { /* zName: */ "temp_store_directory", + /* ePragTyp: */ PragTyp_TEMP_STORE_DIRECTORY, + /* ePragFlag: */ 0, + /* iArg: */ 0 }, #endif #if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS) - { "user_version", PragTyp_HEADER_VALUE, 0 }, + { /* zName: */ "user_version", + /* ePragTyp: */ PragTyp_HEADER_VALUE, + /* ePragFlag: */ 0, + /* iArg: */ 0 }, #endif #if defined(SQLITE_DEBUG) - { "vdbe_addoptrace", PragTyp_FLAG, - SQLITE_VdbeAddopTrace }, - { "vdbe_debug", PragTyp_FLAG, - SQLITE_SqlTrace|SQLITE_VdbeListing|SQLITE_VdbeTrace }, - { "vdbe_listing", PragTyp_FLAG, - SQLITE_VdbeListing }, - { "vdbe_trace", PragTyp_FLAG, - SQLITE_VdbeTrace }, + { /* zName: */ "vdbe_addoptrace", + /* ePragTyp: */ PragTyp_FLAG, + /* ePragFlag: */ 0, + /* iArg: */ SQLITE_VdbeAddopTrace }, + { /* zName: */ "vdbe_debug", + /* ePragTyp: */ PragTyp_FLAG, + /* ePragFlag: */ 0, + /* iArg: */ SQLITE_SqlTrace|SQLITE_VdbeListing|SQLITE_VdbeTrace }, + { /* zName: */ "vdbe_listing", + /* ePragTyp: */ PragTyp_FLAG, + /* ePragFlag: */ 0, + /* iArg: */ SQLITE_VdbeListing }, + { /* zName: */ "vdbe_trace", + /* ePragTyp: */ PragTyp_FLAG, + /* ePragFlag: */ 0, + /* iArg: */ SQLITE_VdbeTrace }, #endif #if !defined(SQLITE_OMIT_WAL) - { "wal_autocheckpoint", PragTyp_WAL_AUTOCHECKPOINT, 0 }, - { "wal_checkpoint", PragTyp_WAL_CHECKPOINT, 0 }, + { /* zName: */ "wal_autocheckpoint", + /* ePragTyp: */ PragTyp_WAL_AUTOCHECKPOINT, + /* ePragFlag: */ 0, + /* iArg: */ 0 }, + { /* zName: */ "wal_checkpoint", + /* ePragTyp: */ PragTyp_WAL_CHECKPOINT, + /* ePragFlag: */ PragFlag_NeedSchema, + /* iArg: */ 0 }, #endif - { "writable_schema", PragTyp_FLAG, - SQLITE_WriteSchema|SQLITE_RecoveryMode }, + { /* zName: */ "writable_schema", + /* ePragTyp: */ PragTyp_FLAG, + /* ePragFlag: */ 0, + /* iArg: */ SQLITE_WriteSchema|SQLITE_RecoveryMode }, }; /* Number of pragmas: 55 on by default, 66 total. */ /* End of the automatically generated pragma table. @@ -571,6 +749,11 @@ void sqlite3Pragma( } if( lwr>upr ) goto pragma_out; + /* Make sure the database schema is loaded if the pragma requires that */ + if( (aPragmaNames[mid].mPragFlag & PragFlag_NeedSchema)!=0 ){ + if( sqlite3ReadSchema(pParse) ) goto pragma_out; + } + /* Jump to the appropriate pragma handler */ switch( aPragmaNames[mid].ePragTyp ){ @@ -604,7 +787,6 @@ void sqlite3Pragma( { OP_ResultRow, 1, 1, 0}, }; int addr; - if( sqlite3ReadSchema(pParse) ) goto pragma_out; sqlite3VdbeUsesBtree(v, iDb); if( !zRight ){ sqlite3VdbeSetNumCols(v, 1); @@ -700,7 +882,6 @@ void sqlite3Pragma( */ case PragTyp_PAGE_COUNT: { int iReg; - if( sqlite3ReadSchema(pParse) ) goto pragma_out; sqlite3CodeVerifySchema(pParse, iDb); iReg = ++pParse->nMem; if( sqlite3Tolower(zLeft[0])=='p' ){ @@ -773,14 +954,6 @@ void sqlite3Pragma( int eMode; /* One of the PAGER_JOURNALMODE_XXX symbols */ int ii; /* Loop counter */ - /* Force the schema to be loaded on all databases. This causes all - ** database files to be opened and the journal_modes set. This is - ** necessary because subsequent processing must know if the databases - ** are in WAL mode. */ - if( sqlite3ReadSchema(pParse) ){ - goto pragma_out; - } - sqlite3VdbeSetNumCols(v, 1); sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "journal_mode", SQLITE_STATIC); @@ -846,51 +1019,40 @@ void sqlite3Pragma( case PragTyp_AUTO_VACUUM: { Btree *pBt = pDb->pBt; assert( pBt!=0 ); - if( sqlite3ReadSchema(pParse) ){ - goto pragma_out; - } if( !zRight ){ - int auto_vacuum; - if( ALWAYS(pBt) ){ - auto_vacuum = sqlite3BtreeGetAutoVacuum(pBt); - }else{ - auto_vacuum = SQLITE_DEFAULT_AUTOVACUUM; - } - returnSingleInt(pParse, "auto_vacuum", auto_vacuum); + returnSingleInt(pParse, "auto_vacuum", sqlite3BtreeGetAutoVacuum(pBt)); }else{ int eAuto = getAutoVacuum(zRight); assert( eAuto>=0 && eAuto<=2 ); db->nextAutovac = (u8)eAuto; - if( ALWAYS(eAuto>=0) ){ - /* Call SetAutoVacuum() to set initialize the internal auto and - ** incr-vacuum flags. This is required in case this connection - ** creates the database file. It is important that it is created - ** as an auto-vacuum capable db. + /* Call SetAutoVacuum() to set initialize the internal auto and + ** incr-vacuum flags. This is required in case this connection + ** creates the database file. It is important that it is created + ** as an auto-vacuum capable db. + */ + rc = sqlite3BtreeSetAutoVacuum(pBt, eAuto); + if( rc==SQLITE_OK && (eAuto==1 || eAuto==2) ){ + /* When setting the auto_vacuum mode to either "full" or + ** "incremental", write the value of meta[6] in the database + ** file. Before writing to meta[6], check that meta[3] indicates + ** that this really is an auto-vacuum capable database. */ - rc = sqlite3BtreeSetAutoVacuum(pBt, eAuto); - if( rc==SQLITE_OK && (eAuto==1 || eAuto==2) ){ - /* When setting the auto_vacuum mode to either "full" or - ** "incremental", write the value of meta[6] in the database - ** file. Before writing to meta[6], check that meta[3] indicates - ** that this really is an auto-vacuum capable database. - */ - static const VdbeOpList setMeta6[] = { - { OP_Transaction, 0, 1, 0}, /* 0 */ - { OP_ReadCookie, 0, 1, BTREE_LARGEST_ROOT_PAGE}, - { OP_If, 1, 0, 0}, /* 2 */ - { OP_Halt, SQLITE_OK, OE_Abort, 0}, /* 3 */ - { OP_Integer, 0, 1, 0}, /* 4 */ - { OP_SetCookie, 0, BTREE_INCR_VACUUM, 1}, /* 5 */ - }; - int iAddr; - iAddr = sqlite3VdbeAddOpList(v, ArraySize(setMeta6), setMeta6); - sqlite3VdbeChangeP1(v, iAddr, iDb); - sqlite3VdbeChangeP1(v, iAddr+1, iDb); - sqlite3VdbeChangeP2(v, iAddr+2, iAddr+4); - sqlite3VdbeChangeP1(v, iAddr+4, eAuto-1); - sqlite3VdbeChangeP1(v, iAddr+5, iDb); - sqlite3VdbeUsesBtree(v, iDb); - } + static const VdbeOpList setMeta6[] = { + { OP_Transaction, 0, 1, 0}, /* 0 */ + { OP_ReadCookie, 0, 1, BTREE_LARGEST_ROOT_PAGE}, + { OP_If, 1, 0, 0}, /* 2 */ + { OP_Halt, SQLITE_OK, OE_Abort, 0}, /* 3 */ + { OP_Integer, 0, 1, 0}, /* 4 */ + { OP_SetCookie, 0, BTREE_INCR_VACUUM, 1}, /* 5 */ + }; + int iAddr; + iAddr = sqlite3VdbeAddOpList(v, ArraySize(setMeta6), setMeta6); + sqlite3VdbeChangeP1(v, iAddr, iDb); + sqlite3VdbeChangeP1(v, iAddr+1, iDb); + sqlite3VdbeChangeP2(v, iAddr+2, iAddr+4); + sqlite3VdbeChangeP1(v, iAddr+4, eAuto-1); + sqlite3VdbeChangeP1(v, iAddr+5, iDb); + sqlite3VdbeUsesBtree(v, iDb); } } break; @@ -905,9 +1067,6 @@ void sqlite3Pragma( #ifndef SQLITE_OMIT_AUTOVACUUM case PragTyp_INCREMENTAL_VACUUM: { int iLimit, addr; - if( sqlite3ReadSchema(pParse) ){ - goto pragma_out; - } if( zRight==0 || !sqlite3GetInt32(zRight, &iLimit) || iLimit<=0 ){ iLimit = 0x7fffffff; } @@ -935,7 +1094,6 @@ void sqlite3Pragma( ** of memory. */ case PragTyp_CACHE_SIZE: { - if( sqlite3ReadSchema(pParse) ) goto pragma_out; assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); if( !zRight ){ returnSingleInt(pParse, "cache_size", pDb->pSchema->cache_size); @@ -1156,7 +1314,6 @@ void sqlite3Pragma( ** opened. */ case PragTyp_SYNCHRONOUS: { - if( sqlite3ReadSchema(pParse) ) goto pragma_out; if( !zRight ){ returnSingleInt(pParse, "synchronous", pDb->safety_level-1); }else{ @@ -1218,7 +1375,6 @@ void sqlite3Pragma( */ case PragTyp_TABLE_INFO: if( zRight ){ Table *pTab; - if( sqlite3ReadSchema(pParse) ) goto pragma_out; pTab = sqlite3FindTable(db, zRight, zDb); if( pTab ){ int i, k; @@ -1268,7 +1424,6 @@ void sqlite3Pragma( case PragTyp_INDEX_INFO: if( zRight ){ Index *pIdx; Table *pTab; - if( sqlite3ReadSchema(pParse) ) goto pragma_out; pIdx = sqlite3FindIndex(db, zRight, zDb); if( pIdx ){ int i; @@ -1294,7 +1449,6 @@ void sqlite3Pragma( case PragTyp_INDEX_LIST: if( zRight ){ Index *pIdx; Table *pTab; - if( sqlite3ReadSchema(pParse) ) goto pragma_out; pTab = sqlite3FindTable(db, zRight, zDb); if( pTab ){ v = sqlite3GetVdbe(pParse); @@ -1322,7 +1476,6 @@ void sqlite3Pragma( case PragTyp_DATABASE_LIST: { int i; - if( sqlite3ReadSchema(pParse) ) goto pragma_out; sqlite3VdbeSetNumCols(v, 3); pParse->nMem = 3; sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "seq", SQLITE_STATIC); @@ -1361,7 +1514,6 @@ void sqlite3Pragma( case PragTyp_FOREIGN_KEY_LIST: if( zRight ){ FKey *pFK; Table *pTab; - if( sqlite3ReadSchema(pParse) ) goto pragma_out; pTab = sqlite3FindTable(db, zRight, zDb); if( pTab ){ v = sqlite3GetVdbe(pParse); @@ -1423,7 +1575,6 @@ void sqlite3Pragma( int addrOk; /* Jump here if the key is OK */ int *aiCols; /* child to parent column mapping */ - if( sqlite3ReadSchema(pParse) ) goto pragma_out; regResult = pParse->nMem+1; pParse->nMem += 4; regKey = ++pParse->nMem; @@ -1584,7 +1735,6 @@ void sqlite3Pragma( if( pId2->z==0 ) iDb = -1; /* Initialize the VDBE program */ - if( sqlite3ReadSchema(pParse) ) goto pragma_out; pParse->nMem = 6; sqlite3VdbeSetNumCols(v, 1); sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "integrity_check", SQLITE_STATIC); @@ -1908,7 +2058,6 @@ void sqlite3Pragma( eMode = SQLITE_CHECKPOINT_RESTART; } } - if( sqlite3ReadSchema(pParse) ) goto pragma_out; sqlite3VdbeSetNumCols(v, 3); pParse->nMem = 3; sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "busy", SQLITE_STATIC); diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 4a52b64f62..4fa7332035 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2414,6 +2414,7 @@ typedef struct DbFixer DbFixer; struct DbFixer { Parse *pParse; /* The parsing context. Error messages written here */ Schema *pSchema; /* Fix items to this schema */ + int bVarOnly; /* Check for variable references only */ const char *zDb; /* Make sure all objects are contained in this database */ const char *zType; /* Type of the container - used for error messages */ const Token *pName; /* Name of the container - used for error messages */ @@ -2952,7 +2953,7 @@ void sqlite3DeferForeignKey(Parse*, int); #endif void sqlite3Attach(Parse*, Expr*, Expr*, Expr*); void sqlite3Detach(Parse*, Expr*); -int sqlite3FixInit(DbFixer*, Parse*, int, const char*, const Token*); +void sqlite3FixInit(DbFixer*, Parse*, int, const char*, const Token*); int sqlite3FixSrcList(DbFixer*, SrcList*); int sqlite3FixSelect(DbFixer*, Select*); int sqlite3FixExpr(DbFixer*, Expr*); diff --git a/src/tclsqlite.c b/src/tclsqlite.c index 42f7bcdc3a..b8fdf23c4e 100644 --- a/src/tclsqlite.c +++ b/src/tclsqlite.c @@ -3377,7 +3377,6 @@ static void MD5Final(unsigned char digest[16], MD5Context *ctx){ MD5Transform(ctx->buf, (uint32 *)ctx->in); byteReverse((unsigned char *)ctx->buf, 4); memcpy(digest, ctx->buf, 16); - memset(ctx, 0, sizeof(ctx)); /* In case it is sensitive */ } /* diff --git a/src/test_init.c b/src/test_init.c index e3724d8be3..502d95c052 100644 --- a/src/test_init.c +++ b/src/test_init.c @@ -219,7 +219,6 @@ static int init_wrapper_uninstall( return TCL_ERROR; } - memset(&wrapped, 0, sizeof(&wrapped)); sqlite3_shutdown(); sqlite3_config(SQLITE_CONFIG_MUTEX, &wrapped.mutex); sqlite3_config(SQLITE_CONFIG_MALLOC, &wrapped.mem); diff --git a/src/trigger.c b/src/trigger.c index b901d07678..774711f0f5 100644 --- a/src/trigger.c +++ b/src/trigger.c @@ -148,8 +148,8 @@ void sqlite3BeginTrigger( /* Ensure the table name matches database name and that the table exists */ if( db->mallocFailed ) goto trigger_cleanup; assert( pTableName->nSrc==1 ); - if( sqlite3FixInit(&sFix, pParse, iDb, "trigger", pName) && - sqlite3FixSrcList(&sFix, pTableName) ){ + sqlite3FixInit(&sFix, pParse, iDb, "trigger", pName); + if( sqlite3FixSrcList(&sFix, pTableName) ){ goto trigger_cleanup; } pTab = sqlite3SrcListLookup(pParse, pTableName); @@ -291,8 +291,10 @@ void sqlite3FinishTrigger( } nameToken.z = pTrig->zName; nameToken.n = sqlite3Strlen30(nameToken.z); - if( sqlite3FixInit(&sFix, pParse, iDb, "trigger", &nameToken) - && sqlite3FixTriggerStep(&sFix, pTrig->step_list) ){ + sqlite3FixInit(&sFix, pParse, iDb, "trigger", &nameToken); + if( sqlite3FixTriggerStep(&sFix, pTrig->step_list) + || sqlite3FixExpr(&sFix, pTrig->pWhen) + ){ goto triggerfinish_cleanup; } diff --git a/test/triggerE.test b/test/triggerE.test new file mode 100644 index 0000000000..e2727bbdcb --- /dev/null +++ b/test/triggerE.test @@ -0,0 +1,112 @@ +# 2009 December 29 +# +# The author disclaims copyright to this source code. In place of +# a legal notice', here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# +# This file tests the effects of SQL variable references embedded in +# triggers. If the user attempts to create such a trigger, it is an +# error. However, if an existing trigger definition is read from +# the sqlite_master table, the variable reference always evaluates +# to NULL. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +ifcapable {!trigger} { + finish_test + return +} +set testprefix triggerE + +do_execsql_test 1.0 { + CREATE TABLE t1(a, b); + CREATE TABLE t2(c, d); + CREATE TABLE t3(e, f); +} + +# forcedelete test.db2 +# do_execsql_test 1.1 { +# ATTACH 'test.db2' AS aux; +# CREATE TABLE aux.t4(x); +# INSERT INTO aux.t4 VALUES(5); +# +# CREATE TRIGGER tr1 AFTER INSERT ON t1 WHEN new.a IN (SELECT x FROM aux.t4) +# BEGIN +# SELECT 1; +# END; +# } +# do_execsql_test 1.2 { INSERT INTO t1 VALUES(1,1); } +# do_execsql_test 1.3 { INSERT INTO t1 VALUES(5,5); } + +#------------------------------------------------------------------------- +# Attempt to create various triggers that use bound variables. +# +set errmsg "trigger cannot use variables" +foreach {tn defn} { + 1 { AFTER INSERT ON t1 WHEN new.a = ? BEGIN SELECT 1; END; } + 2 { BEFORE DELETE ON t1 BEGIN SELECT ?; END; } + 3 { BEFORE DELETE ON t1 BEGIN SELECT * FROM (SELECT * FROM (SELECT ?)); END; } + 5 { BEFORE DELETE ON t1 BEGIN SELECT * FROM t2 GROUP BY ?; END; } + 6 { BEFORE DELETE ON t1 BEGIN SELECT * FROM t2 LIMIT ?; END; } + 7 { BEFORE DELETE ON t1 BEGIN SELECT * FROM t2 ORDER BY ?; END; } + 8 { BEFORE UPDATE ON t1 BEGIN UPDATE t2 SET c = ?; END; } + 9 { BEFORE UPDATE ON t1 BEGIN UPDATE t2 SET c = 1 WHERE d = ?; END; } +} { + catchsql {drop trigger tr1} + do_catchsql_test 1.1.$tn "CREATE TRIGGER tr1 $defn" [list 1 $errmsg] + do_catchsql_test 1.2.$tn "CREATE TEMP TRIGGER tr1 $defn" [list 1 $errmsg] +} + +#------------------------------------------------------------------------- +# Test that variable references within trigger definitions loaded from +# the sqlite_master table are automatically converted to NULL. +# +do_execsql_test 2.1 { + PRAGMA writable_schema = 1; + INSERT INTO sqlite_master VALUES('trigger', 'tr1', 't1', 0, + 'CREATE TRIGGER tr1 AFTER INSERT ON t1 BEGIN + INSERT INTO t2 VALUES(?1, ?2); + END' + ); + + INSERT INTO sqlite_master VALUES('trigger', 'tr2', 't3', 0, + 'CREATE TRIGGER tr2 AFTER INSERT ON t3 WHEN ?1 IS NULL BEGIN + UPDATE t2 SET c=d WHERE c IS ?2; + END' + ); +} +db close +sqlite3 db test.db + +do_execsql_test 2.2.1 { + INSERT INTO t1 VALUES(1, 2); + SELECT * FROM t2; +} {{} {}} +do_test 2.2.2 { + set one 3 + execsql { + DELETE FROM t2; + INSERT INTO t1 VALUES($one, ?1); + SELECT * FROM t2; + } +} {{} {}} +do_execsql_test 2.2.3 { SELECT * FROM t1 } {1 2 3 3} + +do_execsql_test 2.3 { + DELETE FROM t2; + INSERT INTO t2 VALUES('x', 'y'); + INSERT INTO t2 VALUES(NULL, 'z'); + INSERT INTO t3 VALUES(1, 2); + SELECT * FROM t3; + SELECT * FROM t2; +} {1 2 x y z z} + +finish_test + + diff --git a/tool/lemon.c b/tool/lemon.c index f63e76facb..ac08250220 100644 --- a/tool/lemon.c +++ b/tool/lemon.c @@ -3391,7 +3391,7 @@ void print_stack_union( int maxdtlength; /* Maximum length of any ".datatype" field. */ char *stddt; /* Standardized name for a datatype */ int i,j; /* Loop counters */ - int hash; /* For hashing the name of a type */ + unsigned hash; /* For hashing the name of a type */ const char *name; /* Name of the parser */ /* Allocate and initialize types[] and allocate stddt[] */ @@ -4234,10 +4234,10 @@ int SetUnion(char *s1, char *s2) ** Code for processing tables in the LEMON parser generator. */ -PRIVATE int strhash(const char *x) +PRIVATE unsigned strhash(const char *x) { - int h = 0; - while( *x) h = h*13 + *(x++); + unsigned h = 0; + while( *x ) h = h*13 + *(x++); return h; } @@ -4309,8 +4309,8 @@ void Strsafe_init(){ int Strsafe_insert(const char *data) { x1node *np; - int h; - int ph; + unsigned h; + unsigned ph; if( x1a==0 ) return 0; ph = strhash(data); @@ -4364,7 +4364,7 @@ int Strsafe_insert(const char *data) ** if no such key. */ const char *Strsafe_find(const char *key) { - int h; + unsigned h; x1node *np; if( x1a==0 ) return 0; @@ -4475,8 +4475,8 @@ void Symbol_init(){ int Symbol_insert(struct symbol *data, const char *key) { x2node *np; - int h; - int ph; + unsigned h; + unsigned ph; if( x2a==0 ) return 0; ph = strhash(key); @@ -4532,7 +4532,7 @@ int Symbol_insert(struct symbol *data, const char *key) ** if no such key. */ struct symbol *Symbol_find(const char *key) { - int h; + unsigned h; x2node *np; if( x2a==0 ) return 0; @@ -4606,9 +4606,9 @@ PRIVATE int statecmp(struct config *a, struct config *b) } /* Hash a state */ -PRIVATE int statehash(struct config *a) +PRIVATE unsigned statehash(struct config *a) { - int h=0; + unsigned h=0; while( a ){ h = h*571 + a->rp->index*37 + a->dot; a = a->bp; @@ -4674,8 +4674,8 @@ void State_init(){ int State_insert(struct state *data, struct config *key) { x3node *np; - int h; - int ph; + unsigned h; + unsigned ph; if( x3a==0 ) return 0; ph = statehash(key); @@ -4731,7 +4731,7 @@ int State_insert(struct state *data, struct config *key) ** if no such key. */ struct state *State_find(struct config *key) { - int h; + unsigned h; x3node *np; if( x3a==0 ) return 0; @@ -4761,9 +4761,9 @@ struct state **State_arrayof() } /* Hash a configuration */ -PRIVATE int confighash(struct config *a) +PRIVATE unsigned confighash(struct config *a) { - int h=0; + unsigned h=0; h = h*571 + a->rp->index*37 + a->dot; return h; } @@ -4816,8 +4816,8 @@ void Configtable_init(){ int Configtable_insert(struct config *data) { x4node *np; - int h; - int ph; + unsigned h; + unsigned ph; if( x4a==0 ) return 0; ph = confighash(data); diff --git a/tool/mkpragmatab.tcl b/tool/mkpragmatab.tcl index fd4490c4bc..4416616f50 100644 --- a/tool/mkpragmatab.tcl +++ b/tool/mkpragmatab.tcl @@ -109,6 +109,7 @@ set pragma_def { IF: !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER) NAME: default_cache_size + FLAG: NeedSchema IF: !defined(SQLITE_OMIT_PAGER_PRAGMAS) && !defined(SQLITE_OMIT_DEPRECATED) NAME: page_size @@ -118,31 +119,37 @@ set pragma_def { IF: !defined(SQLITE_OMIT_PAGER_PRAGMAS) NAME: page_count + FLAG: NeedSchema IF: !defined(SQLITE_OMIT_PAGER_PRAGMAS) NAME: max_page_count TYPE: PAGE_COUNT + FLAG: NeedSchema IF: !defined(SQLITE_OMIT_PAGER_PRAGMAS) NAME: locking_mode IF: !defined(SQLITE_OMIT_PAGER_PRAGMAS) NAME: journal_mode + FLAG: NeedSchema IF: !defined(SQLITE_OMIT_PAGER_PRAGMAS) NAME: journal_size_limit IF: !defined(SQLITE_OMIT_PAGER_PRAGMAS) NAME: cache_size + FLAG: NeedSchema IF: !defined(SQLITE_OMIT_PAGER_PRAGMAS) NAME: mmap_size IF: !defined(SQLITE_OMIT_PAGER_PRAGMAS) NAME: auto_vacuum + FLAG: NeedSchema IF: !defined(SQLITE_OMIT_AUTOVACUUM) NAME: incremental_vacuum + FLAG: NeedSchema IF: !defined(SQLITE_OMIT_AUTOVACUUM) NAME: temp_store @@ -158,27 +165,34 @@ set pragma_def { IF: !defined(SQLITE_OMIT_PAGER_PRAGMAS) && SQLITE_ENABLE_LOCKING_STYLE NAME: synchronous + FLAG: NeedSchema IF: !defined(SQLITE_OMIT_PAGER_PRAGMAS) NAME: table_info + FLAG: NeedSchema IF: !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) NAME: index_info + FLAG: NeedSchema IF: !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) NAME: index_list + FLAG: NeedSchema IF: !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) NAME: database_list + FLAG: NeedSchema IF: !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) NAME: collation_list IF: !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) NAME: foreign_key_list + FLAG: NeedSchema IF: !defined(SQLITE_OMIT_FOREIGN_KEY) NAME: foreign_key_check + FLAG: NeedSchema IF: !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER) NAME: parser_trace @@ -187,10 +201,12 @@ set pragma_def { NAME: case_sensitive_like NAME: integrity_check + FLAG: NeedSchema IF: !defined(SQLITE_OMIT_INTEGRITY_CHECK) NAME: quick_check TYPE: INTEGRITY_CHECK + FLAG: NeedSchema IF: !defined(SQLITE_OMIT_INTEGRITY_CHECK) NAME: encoding @@ -216,6 +232,7 @@ set pragma_def { IF: !defined(SQLITE_OMIT_COMPILEOPTION_DIAGS) NAME: wal_checkpoint + FLAG: NeedSchema IF: !defined(SQLITE_OMIT_WAL) NAME: wal_autocheckpoint @@ -245,14 +262,16 @@ set pragma_def { set name {} set type {} set if {} +set flags {} set arg 0 proc record_one {} { - global name type if arg allbyname typebyif + global name type if arg allbyname typebyif flags if {$name==""} return - set allbyname($name) [list $type $arg $if] + set allbyname($name) [list $type $arg $if $flags] set name {} set type {} set if {} + set flags {} set arg 0 } foreach line [split $pragma_def \n] { @@ -270,6 +289,11 @@ foreach line [split $pragma_def \n] { set arg $val } elseif {$id=="IF"} { set if $val + } elseif {$id=="FLAG"} { + foreach term [split $val] { + lappend flags $term + set allflags($term) 1 + } } else { error "bad pragma_def line: $line" } @@ -308,30 +332,42 @@ foreach name $allnames { incr pnum } +# Generate #defines for flags +# +set fv 1 +foreach f [lsort [array names allflags]] { + puts [format {#define PragFlag_%-20s 0x%02x} $f $fv] + set fv [expr {$fv*2}] +} + # Generate the lookup table # puts "static const struct sPragmaNames \173" puts " const char *const zName; /* Name of pragma */" puts " u8 ePragTyp; /* PragTyp_XXX value */" +puts " u8 mPragFlag; /* Zero or more PragFlag_XXX values */" puts " u32 iArg; /* Extra argument */" puts "\175 aPragmaNames\[\] = \173" set current_if {} set spacer [format { %26s } {}] foreach name $allnames { - foreach {type arg if} $allbyname($name) break + foreach {type arg if flag} $allbyname($name) break if {$if!=$current_if} { if {$current_if!=""} {puts "#endif"} set current_if $if if {$current_if!=""} {puts "#if $current_if"} } - set namex [format %-26s \"$name\",] set typex [format PragTyp_%-23s $type,] - if {[string length $arg]>10} { - puts " \173 $namex $typex\n$spacer$arg \175," + if {$flag==""} { + set flagx "0" } else { - puts " \173 $namex $typex $arg \175," + set flagx PragFlag_[join $flag {|PragFlag_}] } + puts " \173 /* zName: */ \"$name\"," + puts " /* ePragTyp: */ PragTyp_$type," + puts " /* ePragFlag: */ $flagx," + puts " /* iArg: */ $arg \175," } if {$current_if!=""} {puts "#endif"} puts "\175;"