From 9e1ab1a8a43c1d8fa5aabbd08aad7c917ba5b510 Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 5 Jan 2017 19:32:48 +0000 Subject: [PATCH] Ensure that sqlite3_column_count() returns 0 for the "set" mode of "get/set" PRAGMA statements that do not return a value in that case (e.g. page_size, cache_size, auto_vacuum). FossilOrigin-Name: 5c05d8ec5e895661dae2de30c73dfdeaff93511e --- manifest | 24 +++++++----- manifest.uuid | 2 +- src/pragma.c | 13 ++++++- src/pragma.h | 89 ++++++++++++++++++++++---------------------- src/vdbe.h | 2 + src/vdbeaux.c | 16 ++++++++ test/pragma4.test | 73 ++++++++++++++++++++++++++++++++++++ tool/mkpragmatab.tcl | 32 +++++++++------- 8 files changed, 181 insertions(+), 70 deletions(-) create mode 100644 test/pragma4.test diff --git a/manifest b/manifest index a63cb41c6a..11b3fdb8d5 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\shandling\sthe\scase\swhere\sa\ssub-query\sin\sa\sFROM\sclause\sis\sitself\sa\sUNION\nALL,\sand\sone\sside\sof\sthat\sUNION\sALL\sis\sa\squery\son\sa\sview\sthat\sincludes\san\nORDER\sBY.\sFix\sfor\sticket\s[190c2507]. -D 2017-01-05T17:23:11.079 +C Ensure\sthat\ssqlite3_column_count()\sreturns\s0\sfor\sthe\s"set"\smode\sof\s"get/set"\nPRAGMA\sstatements\sthat\sdo\snot\sreturn\sa\svalue\sin\sthat\scase\s(e.g.\spage_size,\ncache_size,\sauto_vacuum). +D 2017-01-05T19:32:48.544 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -381,8 +381,8 @@ F src/parse.y 29153738a7322054359320eb00b5a4cd44389f20 F src/pcache.c 51070ec9b8251bbf9c6ea3d35fd96a458752929e F src/pcache.h 2cedcd8407eb23017d92790b112186886e179490 F src/pcache1.c e3967219b2a92b9edcb9324a4ba75009090d3953 -F src/pragma.c 5a23557e490e7ac5afef097efc4b59dce5b482c2 -F src/pragma.h f9b221b2c8949ea941dbee49934299e4ed5af41c +F src/pragma.c 0e7a7c6f1c6fd8ff50c0fff65b8bb80174bc49c5 +F src/pragma.h 27fd6a8a051d6ea09bb656ce8a01dfc76f101956 F src/prepare.c b1140c3d0cf59bc85ace00ce363153041b424b7a F src/printf.c ff10a9b9902cd2afe5f655f3013c6307d969b1fd F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 @@ -456,10 +456,10 @@ F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c a88b0466fddf445ce752226d4698ca3faada620a F src/vacuum.c 33c174b28886b2faf26e503b5a49a1c01a9b1c16 F src/vdbe.c 88bd6c32b333580d2661ac3afe33369757fb1522 -F src/vdbe.h 50ee139f9c68fff91be1d717ed3a6abbd496919c +F src/vdbe.h b0866e4191f096f1c987a84b042c3599bdf5423b F src/vdbeInt.h 281cb70332dc8b593b8c7afe776f3a2ba7d4255e F src/vdbeapi.c d6ebaa465f070eb1af8ba4e7b34583ece87bdd24 -F src/vdbeaux.c 12919c5aa354296d6b9ba808bca3e9dda836858c +F src/vdbeaux.c 35c9a9908174e5a26c96d15e1f98214814a39147 F src/vdbeblob.c f4f98ea672b242f807c08c92c7faaa79e5091b65 F src/vdbemem.c 3b5a9a5b375458d3e12a50ae1aaa41eeec2175fd F src/vdbesort.c eda25cb2d1727efca6f7862fea32b8aa33c0face @@ -1010,6 +1010,7 @@ F test/permutations.test cd0b7bc04bf5e50d3a993d24c834d591f7d4f5fe F test/pragma.test 1e94755164a3a3264cd39836de4bebcb7809e5f8 F test/pragma2.test e5d5c176360c321344249354c0c16aec46214c9f F test/pragma3.test 14c12bc5352b1e100e0b6b44f371053a81ccf8ed +F test/pragma4.test 30533f846aa8b44d8d48f5dce2fe2b672dbb57c5 F test/printf.test b3ff34e73d59124140eaf89f7672e21bc2ca5fcc F test/printf2.test 0b61566dd1c0f0b802f59dffa228c5dc5aa6b054 F test/progress.test ebab27f670bd0d4eb9d20d49cef96e68141d92fb @@ -1480,7 +1481,7 @@ F tool/mkmsvcmin.tcl 2f12f7fa8858bbe61cf81820a2da96c79ed1ca8d F tool/mkopcodec.tcl d1b6362bd3aa80d5520d4d6f3765badf01f6c43c F tool/mkopcodeh.tcl a01d2c1d8a6205b03fc635adf3735b4c523befd3 F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e -F tool/mkpragmatab.tcl a30ee93515135466fc49ae881f75da07ebcafd19 +F tool/mkpragmatab.tcl 1b2c06e1da539a1f1fbeba2d26041024012cf1e7 F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97 F tool/mksqlite3c-noext.tcl fef88397668ae83166735c41af99d79f56afaabb F tool/mksqlite3c.tcl 06b2e6a0f21cc0a5d70fbbd136b3e0a96470645e @@ -1542,7 +1543,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 571f166ea8721e2322965b6f23e758b78d13baca -R 5877f43df188f502f476d2f10520ec1c +P 590ca83b8e8cdd5d24ed7f10f43e540aa0627f22 +R 3cc0f54ce943c87173e4fcd78a65cfb2 +T *branch * pragma-columncount-fix +T *sym-pragma-columncount-fix * +T -sym-trunk * U dan -Z 5cce284946e3a767bc44d73b1e732025 +Z 05a2a3933bf879333729a3bc0a191043 diff --git a/manifest.uuid b/manifest.uuid index b593a2938f..56d578e48a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -590ca83b8e8cdd5d24ed7f10f43e540aa0627f22 \ No newline at end of file +5c05d8ec5e895661dae2de30c73dfdeaff93511e \ No newline at end of file diff --git a/src/pragma.c b/src/pragma.c index 6f2e0b545d..5251d0cd26 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -408,7 +408,9 @@ void sqlite3Pragma( } /* Register the result column names for pragmas that return results */ - if( (pPragma->mPragFlg & PragFlg_NoColumns)==0 ){ + if( (pPragma->mPragFlg & PragFlg_NoColumns)==0 + && ((pPragma->mPragFlg & PragFlg_NoColumns1)==0 || zRight==0) + ){ setPragmaResultColumnNames(v, pPragma); } @@ -1953,6 +1955,15 @@ void sqlite3Pragma( } /* End of the PRAGMA switch */ + /* The following block is a no-op unless SQLITE_DEBUG is defined. Its only + ** purpose is to execute assert() statements to verify that if the + ** PragFlg_NoColumns1 flag is set and the caller specified an argument + ** to the PRAGMA, the implementation has not added any OP_ResultRow + ** instructions to the VM. */ + if( (pPragma->mPragFlg & PragFlg_NoColumns1) && zRight ){ + sqlite3VdbeVerifyNoResultRow(v); + } + pragma_out: sqlite3DbFree(db, zLeft); sqlite3DbFree(db, zRight); diff --git a/src/pragma.h b/src/pragma.h index b854b4f38c..49a4080fe9 100644 --- a/src/pragma.h +++ b/src/pragma.h @@ -52,11 +52,12 @@ /* Property flags associated with various pragma. */ #define PragFlg_NeedSchema 0x01 /* Force schema load before running */ #define PragFlg_NoColumns 0x02 /* OP_ResultRow called with zero columns */ -#define PragFlg_ReadOnly 0x04 /* Read-only HEADER_VALUE */ -#define PragFlg_Result0 0x08 /* Acts as query when no argument */ -#define PragFlg_Result1 0x10 /* Acts as query when has one argument */ -#define PragFlg_SchemaOpt 0x20 /* Schema restricts name search if present */ -#define PragFlg_SchemaReq 0x40 /* Schema required - "main" is default */ +#define PragFlg_NoColumns1 0x04 /* zero columns if RHS argument is present */ +#define PragFlg_ReadOnly 0x08 /* Read-only HEADER_VALUE */ +#define PragFlg_Result0 0x10 /* Acts as query when no argument */ +#define PragFlg_Result1 0x20 /* Acts as query when has one argument */ +#define PragFlg_SchemaOpt 0x40 /* Schema restricts name search if present */ +#define PragFlg_SchemaReq 0x80 /* Schema required - "main" is default */ /* Names of columns for pragmas that return multi-column result ** or that return single-column results where the name of the @@ -133,14 +134,14 @@ static const PragmaName aPragmaName[] = { #if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS) {/* zName: */ "application_id", /* ePragTyp: */ PragTyp_HEADER_VALUE, - /* ePragFlg: */ PragFlg_Result0, + /* ePragFlg: */ PragFlg_NoColumns1|PragFlg_Result0, /* ColNames: */ 0, 0, /* iArg: */ BTREE_APPLICATION_ID }, #endif #if !defined(SQLITE_OMIT_AUTOVACUUM) {/* zName: */ "auto_vacuum", /* ePragTyp: */ PragTyp_AUTO_VACUUM, - /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq, + /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq|PragFlg_NoColumns1, /* ColNames: */ 0, 0, /* iArg: */ 0 }, #endif @@ -148,7 +149,7 @@ static const PragmaName aPragmaName[] = { #if !defined(SQLITE_OMIT_AUTOMATIC_INDEX) {/* zName: */ "automatic_index", /* ePragTyp: */ PragTyp_FLAG, - /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, /* ColNames: */ 0, 0, /* iArg: */ SQLITE_AutoIndex }, #endif @@ -161,14 +162,14 @@ static const PragmaName aPragmaName[] = { #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) {/* zName: */ "cache_size", /* ePragTyp: */ PragTyp_CACHE_SIZE, - /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq, + /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq|PragFlg_NoColumns1, /* ColNames: */ 0, 0, /* iArg: */ 0 }, #endif #if !defined(SQLITE_OMIT_FLAG_PRAGMAS) {/* zName: */ "cache_spill", /* ePragTyp: */ PragTyp_CACHE_SPILL, - /* ePragFlg: */ PragFlg_Result0|PragFlg_SchemaReq, + /* ePragFlg: */ PragFlg_Result0|PragFlg_SchemaReq|PragFlg_NoColumns1, /* ColNames: */ 0, 0, /* iArg: */ 0 }, #endif @@ -179,13 +180,13 @@ static const PragmaName aPragmaName[] = { /* iArg: */ 0 }, {/* zName: */ "cell_size_check", /* ePragTyp: */ PragTyp_FLAG, - /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, /* ColNames: */ 0, 0, /* iArg: */ SQLITE_CellSizeCk }, #if !defined(SQLITE_OMIT_FLAG_PRAGMAS) {/* zName: */ "checkpoint_fullfsync", /* ePragTyp: */ PragTyp_FLAG, - /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, /* ColNames: */ 0, 0, /* iArg: */ SQLITE_CkptFullFSync }, #endif @@ -206,21 +207,21 @@ static const PragmaName aPragmaName[] = { #if !defined(SQLITE_OMIT_FLAG_PRAGMAS) {/* zName: */ "count_changes", /* ePragTyp: */ PragTyp_FLAG, - /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, /* ColNames: */ 0, 0, /* iArg: */ SQLITE_CountRows }, #endif #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && SQLITE_OS_WIN {/* zName: */ "data_store_directory", /* ePragTyp: */ PragTyp_DATA_STORE_DIRECTORY, - /* ePragFlg: */ 0, + /* ePragFlg: */ PragFlg_NoColumns1, /* ColNames: */ 0, 0, /* iArg: */ 0 }, #endif #if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS) {/* zName: */ "data_version", /* ePragTyp: */ PragTyp_HEADER_VALUE, - /* ePragFlg: */ PragFlg_Result0|PragFlg_ReadOnly, + /* ePragFlg: */ PragFlg_ReadOnly|PragFlg_Result0, /* ColNames: */ 0, 0, /* iArg: */ BTREE_DATA_VERSION }, #endif @@ -234,7 +235,7 @@ static const PragmaName aPragmaName[] = { #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && !defined(SQLITE_OMIT_DEPRECATED) {/* zName: */ "default_cache_size", /* ePragTyp: */ PragTyp_DEFAULT_CACHE_SIZE, - /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq, + /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq|PragFlg_NoColumns1, /* ColNames: */ 0, 1, /* iArg: */ 0 }, #endif @@ -242,7 +243,7 @@ static const PragmaName aPragmaName[] = { #if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER) {/* zName: */ "defer_foreign_keys", /* ePragTyp: */ PragTyp_FLAG, - /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, /* ColNames: */ 0, 0, /* iArg: */ SQLITE_DeferFKs }, #endif @@ -250,14 +251,14 @@ static const PragmaName aPragmaName[] = { #if !defined(SQLITE_OMIT_FLAG_PRAGMAS) {/* zName: */ "empty_result_callbacks", /* ePragTyp: */ PragTyp_FLAG, - /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, /* ColNames: */ 0, 0, /* iArg: */ SQLITE_NullCallback }, #endif #if !defined(SQLITE_OMIT_UTF16) {/* zName: */ "encoding", /* ePragTyp: */ PragTyp_ENCODING, - /* ePragFlg: */ PragFlg_Result0, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, /* ColNames: */ 0, 0, /* iArg: */ 0 }, #endif @@ -279,7 +280,7 @@ static const PragmaName aPragmaName[] = { #if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER) {/* zName: */ "foreign_keys", /* ePragTyp: */ PragTyp_FLAG, - /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, /* ColNames: */ 0, 0, /* iArg: */ SQLITE_ForeignKeys }, #endif @@ -287,19 +288,19 @@ static const PragmaName aPragmaName[] = { #if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS) {/* zName: */ "freelist_count", /* ePragTyp: */ PragTyp_HEADER_VALUE, - /* ePragFlg: */ PragFlg_Result0|PragFlg_ReadOnly, + /* ePragFlg: */ PragFlg_ReadOnly|PragFlg_Result0, /* ColNames: */ 0, 0, /* iArg: */ BTREE_FREE_PAGE_COUNT }, #endif #if !defined(SQLITE_OMIT_FLAG_PRAGMAS) {/* zName: */ "full_column_names", /* ePragTyp: */ PragTyp_FLAG, - /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, /* ColNames: */ 0, 0, /* iArg: */ SQLITE_FullColNames }, {/* zName: */ "fullfsync", /* ePragTyp: */ PragTyp_FLAG, - /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, /* ColNames: */ 0, 0, /* iArg: */ SQLITE_FullFSync }, #endif @@ -319,7 +320,7 @@ static const PragmaName aPragmaName[] = { #if !defined(SQLITE_OMIT_CHECK) {/* zName: */ "ignore_check_constraints", /* ePragTyp: */ PragTyp_FLAG, - /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, /* ColNames: */ 0, 0, /* iArg: */ SQLITE_IgnoreChecks }, #endif @@ -377,14 +378,14 @@ static const PragmaName aPragmaName[] = { #if !defined(SQLITE_OMIT_FLAG_PRAGMAS) {/* zName: */ "legacy_file_format", /* ePragTyp: */ PragTyp_FLAG, - /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, /* ColNames: */ 0, 0, /* iArg: */ SQLITE_LegacyFileFmt }, #endif #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && SQLITE_ENABLE_LOCKING_STYLE {/* zName: */ "lock_proxy_file", /* ePragTyp: */ PragTyp_LOCK_PROXY_FILE, - /* ePragFlg: */ 0, + /* ePragFlg: */ PragFlg_NoColumns1, /* ColNames: */ 0, 0, /* iArg: */ 0 }, #endif @@ -418,7 +419,7 @@ static const PragmaName aPragmaName[] = { /* iArg: */ 0 }, {/* zName: */ "page_size", /* ePragTyp: */ PragTyp_PAGE_SIZE, - /* ePragFlg: */ PragFlg_Result0|PragFlg_SchemaReq, + /* ePragFlg: */ PragFlg_Result0|PragFlg_SchemaReq|PragFlg_NoColumns1, /* ColNames: */ 0, 0, /* iArg: */ 0 }, #endif @@ -432,7 +433,7 @@ static const PragmaName aPragmaName[] = { #if !defined(SQLITE_OMIT_FLAG_PRAGMAS) {/* zName: */ "query_only", /* ePragTyp: */ PragTyp_FLAG, - /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, /* ColNames: */ 0, 0, /* iArg: */ SQLITE_QueryOnly }, #endif @@ -446,12 +447,12 @@ static const PragmaName aPragmaName[] = { #if !defined(SQLITE_OMIT_FLAG_PRAGMAS) {/* zName: */ "read_uncommitted", /* ePragTyp: */ PragTyp_FLAG, - /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, /* ColNames: */ 0, 0, /* iArg: */ SQLITE_ReadUncommitted }, {/* zName: */ "recursive_triggers", /* ePragTyp: */ PragTyp_FLAG, - /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, /* ColNames: */ 0, 0, /* iArg: */ SQLITE_RecTriggers }, #endif @@ -465,14 +466,14 @@ static const PragmaName aPragmaName[] = { #if !defined(SQLITE_OMIT_FLAG_PRAGMAS) {/* zName: */ "reverse_unordered_selects", /* ePragTyp: */ PragTyp_FLAG, - /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, /* ColNames: */ 0, 0, /* iArg: */ SQLITE_ReverseOrder }, #endif #if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS) {/* zName: */ "schema_version", /* ePragTyp: */ PragTyp_HEADER_VALUE, - /* ePragFlg: */ PragFlg_Result0, + /* ePragFlg: */ PragFlg_NoColumns1|PragFlg_Result0, /* ColNames: */ 0, 0, /* iArg: */ BTREE_SCHEMA_VERSION }, #endif @@ -486,7 +487,7 @@ static const PragmaName aPragmaName[] = { #if !defined(SQLITE_OMIT_FLAG_PRAGMAS) {/* zName: */ "short_column_names", /* ePragTyp: */ PragTyp_FLAG, - /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, /* ColNames: */ 0, 0, /* iArg: */ SQLITE_ShortColNames }, #endif @@ -504,7 +505,7 @@ static const PragmaName aPragmaName[] = { #if defined(SQLITE_DEBUG) {/* zName: */ "sql_trace", /* ePragTyp: */ PragTyp_FLAG, - /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, /* ColNames: */ 0, 0, /* iArg: */ SQLITE_SqlTrace }, #endif @@ -519,7 +520,7 @@ static const PragmaName aPragmaName[] = { #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) {/* zName: */ "synchronous", /* ePragTyp: */ PragTyp_SYNCHRONOUS, - /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq, + /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq|PragFlg_NoColumns1, /* ColNames: */ 0, 0, /* iArg: */ 0 }, #endif @@ -533,12 +534,12 @@ static const PragmaName aPragmaName[] = { #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) {/* zName: */ "temp_store", /* ePragTyp: */ PragTyp_TEMP_STORE, - /* ePragFlg: */ PragFlg_Result0, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, /* ColNames: */ 0, 0, /* iArg: */ 0 }, {/* zName: */ "temp_store_directory", /* ePragTyp: */ PragTyp_TEMP_STORE_DIRECTORY, - /* ePragFlg: */ 0, + /* ePragFlg: */ PragFlg_NoColumns1, /* ColNames: */ 0, 0, /* iArg: */ 0 }, #endif @@ -550,7 +551,7 @@ static const PragmaName aPragmaName[] = { #if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS) {/* zName: */ "user_version", /* ePragTyp: */ PragTyp_HEADER_VALUE, - /* ePragFlg: */ PragFlg_Result0, + /* ePragFlg: */ PragFlg_NoColumns1|PragFlg_Result0, /* ColNames: */ 0, 0, /* iArg: */ BTREE_USER_VERSION }, #endif @@ -558,27 +559,27 @@ static const PragmaName aPragmaName[] = { #if defined(SQLITE_DEBUG) {/* zName: */ "vdbe_addoptrace", /* ePragTyp: */ PragTyp_FLAG, - /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, /* ColNames: */ 0, 0, /* iArg: */ SQLITE_VdbeAddopTrace }, {/* zName: */ "vdbe_debug", /* ePragTyp: */ PragTyp_FLAG, - /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, /* ColNames: */ 0, 0, /* iArg: */ SQLITE_SqlTrace|SQLITE_VdbeListing|SQLITE_VdbeTrace }, {/* zName: */ "vdbe_eqp", /* ePragTyp: */ PragTyp_FLAG, - /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, /* ColNames: */ 0, 0, /* iArg: */ SQLITE_VdbeEQP }, {/* zName: */ "vdbe_listing", /* ePragTyp: */ PragTyp_FLAG, - /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, /* ColNames: */ 0, 0, /* iArg: */ SQLITE_VdbeListing }, {/* zName: */ "vdbe_trace", /* ePragTyp: */ PragTyp_FLAG, - /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, /* ColNames: */ 0, 0, /* iArg: */ SQLITE_VdbeTrace }, #endif @@ -598,7 +599,7 @@ static const PragmaName aPragmaName[] = { #if !defined(SQLITE_OMIT_FLAG_PRAGMAS) {/* zName: */ "writable_schema", /* ePragTyp: */ PragTyp_FLAG, - /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, /* ColNames: */ 0, 0, /* iArg: */ SQLITE_WriteSchema|SQLITE_RecoveryMode }, #endif diff --git a/src/vdbe.h b/src/vdbe.h index 925ba08e50..feaf116807 100644 --- a/src/vdbe.h +++ b/src/vdbe.h @@ -183,8 +183,10 @@ int sqlite3VdbeAddOp4Int(Vdbe*,int,int,int,int,int); void sqlite3VdbeEndCoroutine(Vdbe*,int); #if defined(SQLITE_DEBUG) && !defined(SQLITE_TEST_REALLOC_STRESS) void sqlite3VdbeVerifyNoMallocRequired(Vdbe *p, int N); + void sqlite3VdbeVerifyNoResultRow(Vdbe *p); #else # define sqlite3VdbeVerifyNoMallocRequired(A,B) +# define sqlite3VdbeVerifyNoResultRow(A) #endif VdbeOp *sqlite3VdbeAddOpList(Vdbe*, int nOp, VdbeOpList const *aOp, int iLineno); void sqlite3VdbeAddParseSchemaOp(Vdbe*,int,char*); diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 7c9a295c92..85d273f1ec 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -648,6 +648,22 @@ void sqlite3VdbeVerifyNoMallocRequired(Vdbe *p, int N){ } #endif +/* +** Verify that the VM passed as the only argument does not contain +** an OP_ResultRow opcode. Fail an assert() if it does. This is used +** by code in pragma.c to ensure that the implementation of certain +** pragmas comports with the flags specified in the mkpragmatab.tcl +** script. +*/ +#if defined(SQLITE_DEBUG) && !defined(SQLITE_TEST_REALLOC_STRESS) +void sqlite3VdbeVerifyNoResultRow(Vdbe *p){ + int i; + for(i=0; inOp; i++){ + assert( p->aOp[i].opcode!=OP_ResultRow ); + } +} +#endif + /* ** This function returns a pointer to the array of opcodes associated with ** the Vdbe passed as the first argument. It is the callers responsibility diff --git a/test/pragma4.test b/test/pragma4.test new file mode 100644 index 0000000000..2fa9bd09bc --- /dev/null +++ b/test/pragma4.test @@ -0,0 +1,73 @@ +# 2017 Jan 4 +# +# 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 implements regression tests for SQLite library. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix pragma4 + +proc do_pragma_ncol_test {tn sql nCol} { + set ::stmt 0 + set ::stmt [sqlite3_prepare_v2 db $sql -1 dummy] + uplevel [list do_test $tn { sqlite3_column_count $::stmt } $nCol] + sqlite3_finalize $::stmt +} + +# If there is no RHS argument, the following PRAGMA statements operate as +# queries, returning a single row containing a single column. +# +# Or, if there is RHS argument, they return zero rows of zero columns. +# +foreach {tn sql} { + 1 "PRAGMA application_id = 10" + 2 "PRAGMA automatic_index = 1" + 3 "PRAGMA auto_vacuum = 1" + 4 "PRAGMA cache_size = -100" + 5 "PRAGMA cache_spill = 1" + 6 "PRAGMA cell_size_check = 1" + 7 "PRAGMA checkpoint_fullfsync = 1" + 8 "PRAGMA count_changes = 1" + 9 "PRAGMA default_cache_size = 100" + 10 "PRAGMA defer_foreign_keys = 1" + 11 "PRAGMA empty_result_callbacks = 1" + 12 "PRAGMA encoding = 'utf-8'" + 13 "PRAGMA foreign_keys = 1" + 14 "PRAGMA full_column_names = 1" + 15 "PRAGMA fullfsync = 1" + 16 "PRAGMA ignore_check_constraints = 1" + 17 "PRAGMA legacy_file_format = 1" + 18 "PRAGMA page_size = 511" + 19 "PRAGMA page_size = 512" + 20 "PRAGMA query_only = false" + 21 "PRAGMA read_uncommitted = true" + 22 "PRAGMA recursive_triggers = false" + 23 "PRAGMA reverse_unordered_selects = false" + 24 "PRAGMA schema_version = 211" + 25 "PRAGMA short_column_names = 1" + 26 "PRAGMA synchronous = full" + 27 "PRAGMA temp_store_directory = '/tmp'" + 28 "PRAGMA temp_store_directory = ''" + 29 "PRAGMA temp_store = memory" + 30 "PRAGMA user_version = 405" + 31 "PRAGMA writable_schema = 1" +} { + reset_db + + # Without RHS: + do_pragma_ncol_test 1.$tn.1 [lindex [split $sql =] 0] 1 + + # With RHS: + do_pragma_ncol_test 1.$tn.2 $sql 0 +} + + +finish_test diff --git a/tool/mkpragmatab.tcl b/tool/mkpragmatab.tcl index d9e100366c..c081a10474 100644 --- a/tool/mkpragmatab.tcl +++ b/tool/mkpragmatab.tcl @@ -18,6 +18,7 @@ set flagMeaning(Result1) {Acts as query when has one argument} set flagMeaning(SchemaReq) {Schema required - "main" is default} set flagMeaning(SchemaOpt) {Schema restricts name search if present} set flagMeaning(NoColumns) {OP_ResultRow called with zero columns} +set flagMeaning(NoColumns1) {zero columns if RHS argument is present} set pragma_def { NAME: full_column_names @@ -56,7 +57,7 @@ set pragma_def { IF: !defined(SQLITE_OMIT_FLAG_PRAGMAS) NAME: cache_spill - FLAG: Result0 SchemaReq + FLAG: Result0 SchemaReq NoColumns1 IF: !defined(SQLITE_OMIT_FLAG_PRAGMAS) NAME: reverse_unordered_selects @@ -149,12 +150,12 @@ set pragma_def { ARG: SQLITE_CellSizeCk NAME: default_cache_size - FLAG: NeedSchema Result0 SchemaReq + FLAG: NeedSchema Result0 SchemaReq NoColumns1 COLS: cache_size IF: !defined(SQLITE_OMIT_PAGER_PRAGMAS) && !defined(SQLITE_OMIT_DEPRECATED) NAME: page_size - FLAG: Result0 SchemaReq + FLAG: Result0 SchemaReq NoColumns1 IF: !defined(SQLITE_OMIT_PAGER_PRAGMAS) NAME: secure_delete @@ -183,14 +184,14 @@ set pragma_def { IF: !defined(SQLITE_OMIT_PAGER_PRAGMAS) NAME: cache_size - FLAG: NeedSchema Result0 SchemaReq + FLAG: NeedSchema Result0 SchemaReq NoColumns1 IF: !defined(SQLITE_OMIT_PAGER_PRAGMAS) NAME: mmap_size IF: !defined(SQLITE_OMIT_PAGER_PRAGMAS) NAME: auto_vacuum - FLAG: NeedSchema Result0 SchemaReq + FLAG: NeedSchema Result0 SchemaReq NoColumns1 IF: !defined(SQLITE_OMIT_AUTOVACUUM) NAME: incremental_vacuum @@ -198,20 +199,23 @@ set pragma_def { IF: !defined(SQLITE_OMIT_AUTOVACUUM) NAME: temp_store - FLAG: Result0 + FLAG: Result0 NoColumns1 IF: !defined(SQLITE_OMIT_PAGER_PRAGMAS) NAME: temp_store_directory + FLAG: NoColumns1 IF: !defined(SQLITE_OMIT_PAGER_PRAGMAS) NAME: data_store_directory + FLAG: NoColumns1 IF: !defined(SQLITE_OMIT_PAGER_PRAGMAS) && SQLITE_OS_WIN NAME: lock_proxy_file + FLAG: NoColumns1 IF: !defined(SQLITE_OMIT_PAGER_PRAGMAS) && SQLITE_ENABLE_LOCKING_STYLE NAME: synchronous - FLAG: NeedSchema Result0 SchemaReq + FLAG: NeedSchema Result0 SchemaReq NoColumns1 IF: !defined(SQLITE_OMIT_PAGER_PRAGMAS) NAME: table_info @@ -278,34 +282,37 @@ set pragma_def { IF: !defined(SQLITE_OMIT_INTEGRITY_CHECK) NAME: encoding - FLAG: Result0 + FLAG: Result0 NoColumns1 IF: !defined(SQLITE_OMIT_UTF16) NAME: schema_version TYPE: HEADER_VALUE ARG: BTREE_SCHEMA_VERSION + FLAG: NoColumns1 Result0 IF: !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS) NAME: user_version TYPE: HEADER_VALUE ARG: BTREE_USER_VERSION + FLAG: NoColumns1 Result0 IF: !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS) NAME: data_version TYPE: HEADER_VALUE ARG: BTREE_DATA_VERSION - FLAG: ReadOnly + FLAG: ReadOnly Result0 IF: !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS) NAME: freelist_count TYPE: HEADER_VALUE ARG: BTREE_FREE_PAGE_COUNT - FLAG: ReadOnly + FLAG: ReadOnly Result0 IF: !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS) NAME: application_id TYPE: HEADER_VALUE ARG: BTREE_APPLICATION_ID + FLAG: NoColumns1 Result0 IF: !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS) NAME: compile_options @@ -408,10 +415,7 @@ foreach line [split $pragma_def \n] { } elseif {$id=="TYPE"} { set type $val if {$type=="FLAG"} { - lappend flags Result0 NoColumns - } - if {$type=="HEADER_VALUE"} { - lappend flags Result0 + lappend flags Result0 NoColumns1 } } elseif {$id=="ARG"} { set arg $val -- 2.39.5