From d83e082524d56d8138ef84c7ff0fa02c0c6172dc Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 4 Aug 2017 17:39:13 +0000 Subject: [PATCH] Add further test cases for swarmvtab. And minor code changes. FossilOrigin-Name: 0f82d3b9dd5bd2e34a984c78e4a4a87921cf3e15b01b611133378c0ea9901010 --- ext/misc/unionvtab.c | 106 ++++++++++++++++++++++----------------- manifest | 14 +++--- manifest.uuid | 2 +- test/unionvtabfault.test | 12 +++++ 4 files changed, 79 insertions(+), 55 deletions(-) diff --git a/ext/misc/unionvtab.c b/ext/misc/unionvtab.c index 2df3c30e06..c4e3fff039 100644 --- a/ext/misc/unionvtab.c +++ b/ext/misc/unionvtab.c @@ -84,6 +84,23 @@ SQLITE_EXTENSION_INIT1 # define SMALLEST_INT64 (((sqlite3_int64)-1) - LARGEST_INT64) #endif +/* +** The following is also copied from sqliteInt.h. To facilitate coverage +** testing. +*/ +#ifndef ALWAYS +# if defined(SQLITE_COVERAGE_TEST) || defined(SQLITE_MUTATION_TEST) +# define ALWAYS(X) (1) +# define NEVER(X) (0) +# elif !defined(NDEBUG) +# define ALWAYS(X) ((X)?1:(assert(0),0)) +# define NEVER(X) ((X)?(assert(0),1):0) +# else +# define ALWAYS(X) (X) +# define NEVER(X) (X) +# endif +#endif + /* ** The swarmvtab module attempts to keep the number of open database files ** at or below this limit. This may not be possible if there are too many @@ -211,7 +228,7 @@ static void unionDequote(char *z){ int iIn = 1; int iOut = 0; if( q=='[' ) q = ']'; - while( z[iIn] ){ + while( ALWAYS(z[iIn]) ){ if( z[iIn]==q ){ if( z[iIn+1]!=q ){ /* Character iIn was the close quote. */ @@ -253,9 +270,10 @@ static sqlite3_stmt *unionPrepare( char **pzErr /* OUT: Error message */ ){ sqlite3_stmt *pRet = 0; + assert( pzErr ); if( *pRc==SQLITE_OK ){ int rc = sqlite3_prepare_v2(db, zSql, -1, &pRet, 0); - if( rc!=SQLITE_OK && pzErr ){ + if( rc!=SQLITE_OK ){ *pzErr = sqlite3_mprintf("sql error: %s", sqlite3_errmsg(db)); *pRc = rc; } @@ -301,6 +319,7 @@ static sqlite3_stmt *unionPreparePrintf( ** In this case, *pzErr may be set to point to an error message ** buffer allocated by sqlite3_malloc(). */ +#if 0 static void unionReset(int *pRc, sqlite3_stmt *pStmt, char **pzErr){ int rc = sqlite3_reset(pStmt); if( *pRc==SQLITE_OK ){ @@ -310,6 +329,7 @@ static void unionReset(int *pRc, sqlite3_stmt *pStmt, char **pzErr){ } } } +#endif /* ** Call sqlite3_finalize() on SQL statement pStmt. If *pRc is set to @@ -332,20 +352,16 @@ static void unionFinalize(int *pRc, sqlite3_stmt *pStmt, char **pzErr){ ** close open database files until at most nMax are open. An SQLite error ** code is returned if an error occurs, or SQLITE_OK otherwise. */ -static int unionCloseSources(UnionTab *pTab, int nMax){ - int rc = SQLITE_OK; - if( pTab->bSwarm ){ - while( rc==SQLITE_OK && pTab->pClosable && pTab->nOpen>nMax ){ - UnionSrc **pp; - for(pp=&pTab->pClosable; (*pp)->pNextClosable; pp=&(*pp)->pNextClosable); - assert( (*pp)->db ); - rc = sqlite3_close((*pp)->db); - (*pp)->db = 0; - *pp = 0; - pTab->nOpen--; - } +static void unionCloseSources(UnionTab *pTab, int nMax){ + while( pTab->pClosable && pTab->nOpen>nMax ){ + UnionSrc **pp; + for(pp=&pTab->pClosable; (*pp)->pNextClosable; pp=&(*pp)->pNextClosable); + assert( (*pp)->db ); + sqlite3_close((*pp)->db); + (*pp)->db = 0; + *pp = 0; + pTab->nOpen--; } - return rc; } /* @@ -428,11 +444,11 @@ static char *unionSourceToStr( if( *pRc==SQLITE_OK ){ sqlite3 *db = unionGetDb(pTab, pSrc); int rc = unionIsIntkeyTable(db, pSrc, pzErr); + sqlite3_stmt *pStmt = unionPrepare(&rc, db, + "SELECT group_concat(quote(name) || '.' || quote(type)) " + "FROM pragma_table_info(?, ?)", pzErr + ); if( rc==SQLITE_OK ){ - sqlite3_stmt *pStmt = unionPrepare(&rc, db, - "SELECT group_concat(quote(name) || '.' || quote(type)) " - "FROM pragma_table_info(?, ?)", pzErr - ); sqlite3_bind_text(pStmt, 1, pSrc->zTab, -1, SQLITE_STATIC); sqlite3_bind_text(pStmt, 2, pSrc->zDb, -1, SQLITE_STATIC); if( SQLITE_ROW==sqlite3_step(pStmt) ){ @@ -496,35 +512,32 @@ static int unionOpenDatabase(UnionTab *pTab, int iSrc, char **pzErr){ assert( pTab->bSwarm && iSrcnSrc ); if( pSrc->db==0 ){ - rc = unionCloseSources(pTab, pTab->nMaxOpen-1); - - if( rc==SQLITE_OK ){ - rc = sqlite3_open_v2(pSrc->zFile, &pSrc->db, SQLITE_OPEN_READONLY, 0); - if( rc!=SQLITE_OK ){ - *pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(pSrc->db)); - }else{ - char *z = unionSourceToStr(&rc, pTab, pSrc, pzErr); - if( rc==SQLITE_OK ){ - if( pTab->zSourceStr==0 ){ - pTab->zSourceStr = z; - }else{ - if( sqlite3_stricmp(z, pTab->zSourceStr) ){ - *pzErr = sqlite3_mprintf("source table schema mismatch"); - rc = SQLITE_ERROR; - } - sqlite3_free(z); + unionCloseSources(pTab, pTab->nMaxOpen-1); + rc = sqlite3_open_v2(pSrc->zFile, &pSrc->db, SQLITE_OPEN_READONLY, 0); + if( rc!=SQLITE_OK ){ + *pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(pSrc->db)); + }else{ + char *z = unionSourceToStr(&rc, pTab, pSrc, pzErr); + if( rc==SQLITE_OK ){ + if( pTab->zSourceStr==0 ){ + pTab->zSourceStr = z; + }else{ + if( sqlite3_stricmp(z, pTab->zSourceStr) ){ + *pzErr = sqlite3_mprintf("source table schema mismatch"); + rc = SQLITE_ERROR; } + sqlite3_free(z); } } + } - if( rc==SQLITE_OK ){ - pSrc->pNextClosable = pTab->pClosable; - pTab->pClosable = pSrc; - pTab->nOpen++; - }else{ - sqlite3_close(pSrc->db); - pSrc->db = 0; - } + if( rc==SQLITE_OK ){ + pSrc->pNextClosable = pTab->pClosable; + pTab->pClosable = pSrc; + pTab->nOpen++; + }else{ + sqlite3_close(pSrc->db); + pSrc->db = 0; } } @@ -574,6 +587,7 @@ static int unionFinalizeCsrStmt(UnionCsr *pCsr){ pSrc->pNextClosable = pTab->pClosable; pTab->pClosable = pSrc; } + unionCloseSources(pTab, pTab->nMaxOpen); } } return rc; @@ -763,10 +777,8 @@ static int doUnionNext(UnionCsr *pCsr){ UnionSrc *pSrc = &pTab->aSrc[pCsr->iTab]; if( pCsr->iMaxRowid>=pSrc->iMin ){ /* It is necessary to scan the next table. */ - sqlite3 *db; rc = unionOpenDatabase(pTab, pCsr->iTab, &pTab->base.zErrMsg); - db = unionGetDb(pTab, pSrc); - pCsr->pStmt = unionPreparePrintf(&rc, &pTab->base.zErrMsg, db, + pCsr->pStmt = unionPreparePrintf(&rc, &pTab->base.zErrMsg, pSrc->db, "SELECT rowid, * FROM %Q %s %lld", pSrc->zTab, (pSrc->iMax>pCsr->iMaxRowid ? "WHERE _rowid_ <=" : "-- "), diff --git a/manifest b/manifest index 51d9536952..720dbcbf68 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\stest\scases\sand\sassociated\sfixes\sfor\sswarmvtab. -D 2017-08-04T16:16:32.840 +C Add\sfurther\stest\scases\sfor\sswarmvtab.\sAnd\sminor\scode\schanges. +D 2017-08-04T17:39:13.161 F Makefile.in d9873c9925917cca9990ee24be17eb9613a668012c85a343aef7e5536ae266e8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 02b469e9dcd5b7ee63fc1fb05babc174260ee4cfa4e0ef2e48c3c6801567a016 @@ -281,7 +281,7 @@ F ext/misc/showauth.c 732578f0fe4ce42d577e1c86dc89dd14a006ab52 F ext/misc/spellfix.c a4723b6aff748a417b5091b68a46443265c40f0d F ext/misc/stmt.c 6f16443abb3551e3f5813bb13ba19a30e7032830015b0f92fe0c0453045c0a11 F ext/misc/totype.c 4a167594e791abeed95e0a8db028822b5e8fe512 -F ext/misc/unionvtab.c e388c29b4af5ad66fb463fd7db9242c89d03639f030e3e8829ad336b7002a48f +F ext/misc/unionvtab.c c30398ece1cfe07d97334acdf3bd0f082782b493af254557f389c8fc1635aa7f F ext/misc/vfslog.c fe40fab5c077a40477f7e5eba994309ecac6cc95 F ext/misc/vfsstat.c bf10ef0bc51e1ad6756629e1edb142f7a8db1178 F ext/misc/vtshim.c 1976e6dd68dd0d64508c91a6dfab8e75f8aaf6cd @@ -1437,7 +1437,7 @@ F test/types.test bf816ce73c7dfcfe26b700c19f97ef4050d194ff F test/types2.test 1aeb81976841a91eef292723649b5c4fe3bc3cac F test/types3.test 99e009491a54f4dc02c06bdbc0c5eea56ae3e25a F test/unionvtab.test 595fb601de00188ca5e7c6dbe266c17a0faf234cf434ce85eccec1a929ef9baf -F test/unionvtabfault.test 18f4f878e550ae3c5efa195b1420c78607c0f9810f7a71a49ab6379dfe501f32 +F test/unionvtabfault.test 26b6854d5aef9005cd630513025690bff1b7378ae9c97b81e2a3cbe84eee0f58 F test/unique.test 93f8b2ef5ea51b9495f8d6493429b1fd0f465264 F test/unique2.test 3674e9f2a3f1fbbfd4772ac74b7a97090d0f77d2 F test/unixexcl.test d936ba2b06794018e136418addd59a2354eeae97 @@ -1641,7 +1641,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 1f05ad29c3a540408470da7f8111f1319f961539c1a96b1a81abf1423af90f15 -R 7e7ab9819e0aed7a3e8424d62e02f2a0 +P 7ae20eac83fc053dc1bbc42501dd41f77445a6b9a33cfa42b899fc7a18c637ab +R f110030d9eaed7a6ec593149c64799ea U dan -Z 2e976f6f51ee5c8476d79b5286404931 +Z 1047b1cef8ad6de0923837acad2fcea1 diff --git a/manifest.uuid b/manifest.uuid index f000a4bbfd..05e3670fa1 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7ae20eac83fc053dc1bbc42501dd41f77445a6b9a33cfa42b899fc7a18c637ab \ No newline at end of file +0f82d3b9dd5bd2e34a984c78e4a4a87921cf3e15b01b611133378c0ea9901010 \ No newline at end of file diff --git a/test/unionvtabfault.test b/test/unionvtabfault.test index e0b78cbc88..061645cd6a 100644 --- a/test/unionvtabfault.test +++ b/test/unionvtabfault.test @@ -67,6 +67,18 @@ do_faultsim_test 1.2 -faults oom* -prep { faultsim_test_result {0 {1 one 2 two 3 three 10 ten 11 eleven 12 twelve 20 twenty 21 twenty-one 22 twenty-two}} } +#------------------------------------------------------------------------- +# Error while registering the two vtab modules. +do_faultsim_test 2.0 -faults * -prep { + catch { db close } + sqlite3 db :memory: +} -body { + load_static_extension db unionvtab +} -test { + faultsim_test_result {0 {}} {1 {initialization of unionvtab failed: }} +} + + finish_test