From: dan Date: Tue, 18 Jul 2017 20:03:49 +0000 (+0000) Subject: Improve the readability of the unionvtab code. X-Git-Tag: version-3.20.0~28 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=859e4a73b73085cd236e5d39d18f10c3445117fd;p=thirdparty%2Fsqlite.git Improve the readability of the unionvtab code. FossilOrigin-Name: 5bcf0f86ea7fbbc31a13b2d5b1cf93a92e46fb65fe8e779b3d7e4a98d60d7061 --- diff --git a/ext/misc/unionvtab.c b/ext/misc/unionvtab.c index d309d8e4ac..d957901833 100644 --- a/ext/misc/unionvtab.c +++ b/ext/misc/unionvtab.c @@ -152,31 +152,33 @@ static char *unionStrdup(int *pRc, const char *zIn){ ** function is a no-op. */ static void unionDequote(char *z){ - char q = z[0]; - - /* Set stack variable q to the close-quote character */ - if( q=='[' || q=='\'' || q=='"' || q=='`' ){ - int iIn = 1; - int iOut = 0; - if( q=='[' ) q = ']'; - while( z[iIn] ){ - if( z[iIn]==q ){ - if( z[iIn+1]!=q ){ - /* Character iIn was the close quote. */ - iIn++; - break; + if( z ){ + char q = z[0]; + + /* Set stack variable q to the close-quote character */ + if( q=='[' || q=='\'' || q=='"' || q=='`' ){ + int iIn = 1; + int iOut = 0; + if( q=='[' ) q = ']'; + while( z[iIn] ){ + if( z[iIn]==q ){ + if( z[iIn+1]!=q ){ + /* Character iIn was the close quote. */ + iIn++; + break; + }else{ + /* Character iIn and iIn+1 form an escaped quote character. Skip + ** the input cursor past both and copy a single quote character + ** to the output buffer. */ + iIn += 2; + z[iOut++] = q; + } }else{ - /* Character iIn and iIn+1 form an escaped quote character. Skip - ** the input cursor past both and copy a single quote character - ** to the output buffer. */ - iIn += 2; - z[iOut++] = q; + z[iOut++] = z[iIn++]; } - }else{ - z[iOut++] = z[iIn++]; } + z[iOut] = '\0'; } - z[iOut] = '\0'; } } @@ -210,6 +212,37 @@ static sqlite3_stmt *unionPrepare( return pRet; } +/* +** Like unionPrepare(), except prepare the results of vprintf(zFmt, ...) +** instead of a constant SQL string. +*/ +static sqlite3_stmt *unionPreparePrintf( + int *pRc, /* IN/OUT: Error code */ + char **pzErr, /* OUT: Error message */ + sqlite3 *db, /* Database handle */ + const char *zFmt, /* printf() format string */ + ... /* Trailing printf args */ +){ + sqlite3_stmt *pRet = 0; + char *zSql; + va_list ap; + va_start(ap, zFmt); + + zSql = sqlite3_vmprintf(zFmt, ap); + if( *pRc==SQLITE_OK ){ + if( zSql==0 ){ + *pRc = SQLITE_NOMEM; + }else{ + pRet = unionPrepare(pRc, db, zSql, pzErr); + } + } + sqlite3_free(zSql); + + va_end(ap); + return pRet; +} + + /* ** Call sqlite3_reset() on SQL statement pStmt. If *pRc is set to ** SQLITE_OK when this function is called, then it is set to the @@ -390,16 +423,10 @@ static int unionConnect( ** the results by the "minimum rowid" field. This makes it easier to ** check that there are no rowid range overlaps between source tables ** and that the UnionTab.aSrc[] array is always sorted by rowid. */ - if( zArg ){ - unionDequote(zArg); - zSql = sqlite3_mprintf("SELECT * FROM (%s) ORDER BY 3", zArg); - sqlite3_free(zArg); - zArg = 0; - } - if( zSql==0 ){ - rc = SQLITE_NOMEM; - } - pStmt = unionPrepare(&rc, db, zSql, pzErr); + unionDequote(zArg); + pStmt = unionPreparePrintf(&rc, pzErr, db, + "SELECT * FROM (%z) ORDER BY 3", zArg + ); /* Allocate the UnionTab structure */ pTab = unionMalloc(&rc, sizeof(UnionTab)); @@ -443,9 +470,7 @@ static int unionConnect( } unionFinalize(&rc, pStmt); pStmt = 0; - sqlite3_free(zArg); sqlite3_free(zSql); - zArg = 0; zSql = 0; /* Verify that all source tables exist and have compatible schemas. */ @@ -455,18 +480,14 @@ static int unionConnect( } /* Compose a CREATE TABLE statement and pass it to declare_vtab() */ - if( rc==SQLITE_OK ){ - zSql = sqlite3_mprintf("SELECT " - "'CREATE TABLE xyz('" - " || group_concat(quote(name) || ' ' || type, ', ')" - " || ')'," - "max((cid+1) * (type='INTEGER' COLLATE nocase AND pk=1))-1 " - "FROM pragma_table_info(%Q, ?)", - pTab->aSrc[0].zTab, pTab->aSrc[0].zDb - ); - if( zSql==0 ) rc = SQLITE_NOMEM; - } - pStmt = unionPrepare(&rc, db, zSql, pzErr); + pStmt = unionPreparePrintf(&rc, pzErr, db, "SELECT " + "'CREATE TABLE xyz('" + " || group_concat(quote(name) || ' ' || type, ', ')" + " || ')'," + "max((cid+1) * (type='INTEGER' COLLATE nocase AND pk=1))-1 " + "FROM pragma_table_info(%Q, ?)", + pTab->aSrc[0].zTab, pTab->aSrc[0].zDb + ); if( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){ const char *zDecl = (const char*)sqlite3_column_text(pStmt, 0); rc = sqlite3_declare_vtab(db, zDecl); diff --git a/manifest b/manifest index 2b29cef9a2..c0ff6acba9 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Have\sunionvtab\ssupport\sconstraints\son\sthe\scolumn\sthat\scorresponds\sto\sthe\nINTEGER\sPRIMARY\sKEY\sfield\sof\sthe\sunderlying\ssource\stables\sin\sthe\ssame\sway\sas\nrowid. -D 2017-07-18T19:51:11.061 +C Improve\sthe\sreadability\sof\sthe\sunionvtab\scode. +D 2017-07-18T20:03:49.037 F Makefile.in d9873c9925917cca9990ee24be17eb9613a668012c85a343aef7e5536ae266e8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 20850e3e8d4d4791e0531955852d768eb06f24138214870d543abb1a47346fba @@ -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 2ee97a136cc300fe17c9591015ae2ee4eea2a78458e46dd44550e0a441a091ff +F ext/misc/unionvtab.c 6f000dda30b9b757d96430b527fa914565db761b052eeff44f4ecc4fb78afb17 F ext/misc/vfslog.c fe40fab5c077a40477f7e5eba994309ecac6cc95 F ext/misc/vfsstat.c bf10ef0bc51e1ad6756629e1edb142f7a8db1178 F ext/misc/vtshim.c 1976e6dd68dd0d64508c91a6dfab8e75f8aaf6cd @@ -1635,7 +1635,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 6c9128e1a53f8cf26de9ef1bc07051f2c94287531edacfcfb69d3cd7590240b3 -R dc8f15610e867937249e25b515a6a200 +P 4a6c416fa025a34116ea30923a673cbb108b251b2676734ec8f603600e38e50e +R e0c4fc635382665649191367077e776c U dan -Z 6262d0cb27792cd399228e6052fa5f80 +Z e8f0cf724e634e649031bed86724d795 diff --git a/manifest.uuid b/manifest.uuid index 6fc68db875..3c95ab695a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4a6c416fa025a34116ea30923a673cbb108b251b2676734ec8f603600e38e50e \ No newline at end of file +5bcf0f86ea7fbbc31a13b2d5b1cf93a92e46fb65fe8e779b3d7e4a98d60d7061 \ No newline at end of file