]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Improve the readability of the unionvtab code.
authordan <dan@noemail.net>
Tue, 18 Jul 2017 20:03:49 +0000 (20:03 +0000)
committerdan <dan@noemail.net>
Tue, 18 Jul 2017 20:03:49 +0000 (20:03 +0000)
FossilOrigin-Name: 5bcf0f86ea7fbbc31a13b2d5b1cf93a92e46fb65fe8e779b3d7e4a98d60d7061

ext/misc/unionvtab.c
manifest
manifest.uuid

index d309d8e4acaaf797991a0e75e9b7808ad301c7d0..d9579018337be4b62ebc8454f4747165cca2a6dd 100644 (file)
@@ -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);
index 2b29cef9a2ccf583063277011719a9c1fe3a6b45..c0ff6acba96090ad3ecd3f56b44ae1e2f96e1cd3 100644 (file)
--- 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
index 6fc68db875dfe6d3b2875bb4d4755b32b9b60924..3c95ab695a6e08458126f2c38ddfc93741acd74b 100644 (file)
@@ -1 +1 @@
-4a6c416fa025a34116ea30923a673cbb108b251b2676734ec8f603600e38e50e
\ No newline at end of file
+5bcf0f86ea7fbbc31a13b2d5b1cf93a92e46fb65fe8e779b3d7e4a98d60d7061
\ No newline at end of file