]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Enhance faststat1.c to deal better with WITHOUT ROWID tables.
authordrh <drh@noemail.net>
Tue, 25 Oct 2016 18:28:29 +0000 (18:28 +0000)
committerdrh <drh@noemail.net>
Tue, 25 Oct 2016 18:28:29 +0000 (18:28 +0000)
FossilOrigin-Name: 65444f2e35cfd51ece1ba6e37b39d181da479137

manifest
manifest.uuid
tool/faststat1.c

index 035b02b58a323aced12132318298cca42f428ad8..665d8208e9a1fabe4aa3bbacd2595cbf9045f770 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Merge\srecent\strunk\schanges,\sand\sespecially\sthe\sPRAGMA\sindex_info\senhancement\nwhich\sis\sneeded\son\sthis\sbranch.
-D 2016-10-25T17:28:49.402
+C Enhance\sfaststat1.c\sto\sdeal\sbetter\swith\sWITHOUT\sROWID\stables.
+D 2016-10-25T18:28:29.534
 F Makefile.in 6fd48ffcf7c2deea7499062d1f3747f986c19678
 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
 F Makefile.msc 5151cc64c4c05f3455f4f692ad11410a810d937f
@@ -1449,7 +1449,7 @@ F tool/checkSpacing.c 810e51703529a204fc4e1eb060e9ab663e3c06d2
 F tool/dbhash.c a06228aa21ebc4e6ea8daa486601d938499238a5
 F tool/extract.c 054069d81b095fbdc189a6f5d4466e40380505e2
 F tool/fast_vacuum.c 5ba0d6f5963a0a63bdc42840f678bad75b2ebce1
-F tool/faststat1.c 2178e42e0206ac80a49834454e716cfc21060cfa
+F tool/faststat1.c 1f95d54b32f96493ca3f1a9421eaf3e72a5c091e
 F tool/fragck.tcl 5265a95126abcf6ab357f7efa544787e5963f439
 F tool/fuzzershell.c f294ca67a10e87db76af130d75b2c94be36359c6
 F tool/genfkey.README cf68fddd4643bbe3ff8e31b8b6d8b0a1b85e20f4
@@ -1528,7 +1528,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 7b83581a43384fe81dc319482e03be0df45ab25d fe49fb03133fec8bed51c2e2c1b6848ab9fc563e
-R dc40a5d5b8b329a8e831d814ba1f0d9d
+P c3570e462a41586487c4ab3bd08129affe8bed3c
+R 213daab621065f2ee61de1ff06afe658
 U drh
-Z b7c4393dfca2a201afed4cf76221890b
+Z b9d2e2924768dab5d8a474892a087659
index 6148524a44941425f3d058a27949dd643c08fd98..927158706498cf998ab6eda3c3dbf2ef748d6d47 100644 (file)
@@ -1 +1 @@
-c3570e462a41586487c4ab3bd08129affe8bed3c
\ No newline at end of file
+65444f2e35cfd51ece1ba6e37b39d181da479137
\ No newline at end of file
index 233cfd28a8dcab106b82c9e08ca1a282e962ae14..7180f04414c4b009ae954069ef31bf1ee211085a 100644 (file)
@@ -119,24 +119,6 @@ static sqlite3_int64 estEntryCount(const char *zTabIdx){
   return n==0 ? 0 : (sqlite3_int64)(sum/n);
 }
 
-/*
-** Stat1 for a table.
-*/
-static void analyzeTable(const char *zTab){
-  sqlite3_int64 n = estEntryCount(zTab);
-  sqlite3_stmt *pStmt;
-  if( n==0 ){
-    printf("-- empty table: %s\n", zTab);
-    return;
-  }
-  pStmt = db_prepare(
-     "INSERT INTO temp.est_stat1(tbl,idx,stat)"
-     "VALUES(\"%w\",NULL,'%lld')", zTab, n
-  );
-  sqlite3_step(pStmt);
-  sqlite3_finalize(pStmt);
-}
-
 /*
 ** Compare the i-th column of pStmt against pValue.  Return true if they
 ** are different.
@@ -177,9 +159,9 @@ static int columnNotEqual(sqlite3_stmt *pStmt, int i, sqlite3_value *pValue){
 }
 
 /*
-** Stat1 for an index;
+** Stat1 for an index.  Return non-zero if an entry was created.
 */
-static void analyzeIndex(const char *zTab, const char *zIdx){
+static int analyzeIndex(const char *zTab, const char *zIdx){
   sqlite3_int64 n = estEntryCount(zIdx);
   sqlite3_stmt *pStmt;
   sqlite3_uint64 *aCnt;
@@ -194,7 +176,7 @@ static void analyzeIndex(const char *zTab, const char *zIdx){
   int rc;
 
 # define N_SPAN  5
-  if( n==0 ) return;
+  if( n==0 ) return 0;
   pStmt = db_prepare("PRAGMA index_xinfo=\"%w\"", zIdx);
   while( sqlite3_step(pStmt)==SQLITE_ROW ){
     const char *zColl = (const char*)sqlite3_column_text(pStmt,4);
@@ -203,12 +185,13 @@ static void analyzeIndex(const char *zTab, const char *zIdx){
              " collating sequence \"%s\".\n",
              zIdx, sqlite3_column_text(pStmt, 2), zColl);
       sqlite3_finalize(pStmt);
-      return;
+      return 0;
     }
     if( sqlite3_column_int(pStmt, 5)==0 ) break;
     nCol++;
   }
   sqlite3_finalize(pStmt);
+  if( nCol==0 ) return 0;
   nByte = (sizeof(aCnt[0]) + sizeof(apValue[0]))*nCol + 30*(nCol+1);
   aCnt = sqlite3_malloc( nByte );
   if( aCnt==0 ){
@@ -247,7 +230,7 @@ static void analyzeIndex(const char *zTab, const char *zIdx){
   sqlite3_snprintf(szRes, zRes, "%lld", n);
   k = (int)strlen(zRes);
   for(j=0; j<nCol; j++){
-    sqlite3_snprintf(szRes-k, zRes+k, " %d", nRow/aCnt[j]);
+    sqlite3_snprintf(szRes-k, zRes+k, " %d", (nRow+aCnt[j]-1)/aCnt[j]);
     k += (int)strlen(zRes+k);
   }
   pStmt = db_prepare(
@@ -256,8 +239,43 @@ static void analyzeIndex(const char *zTab, const char *zIdx){
   );
   sqlite3_step(pStmt);
   sqlite3_finalize(pStmt);
+  return 1;
 }
 
+/*
+** Stat1 for a table.
+*/
+static void analyzeTable(const char *zTab){
+  sqlite3_int64 n = estEntryCount(zTab);
+  sqlite3_stmt *pStmt;
+  int nIndex = 0;
+  int isWithoutRowid = 0;
+  if( n==0 ){
+    printf("-- empty table: %s\n", zTab);
+    return;
+  }
+  if( analyzeIndex(zTab,zTab) ){
+    isWithoutRowid = 1;
+    nIndex++;
+  }
+  pStmt = db_prepare("PRAGMA index_list(\"%w\")", zTab);
+  while( sqlite3_step(pStmt)==SQLITE_ROW ){
+    if( sqlite3_column_text(pStmt,3)[0]=='p' && isWithoutRowid ) continue;
+    if( sqlite3_column_int(pStmt,4)==0 ) nIndex++;
+    analyzeIndex(zTab, (const char*)sqlite3_column_text(pStmt,1));
+  }
+  sqlite3_finalize(pStmt);
+  if( nIndex==0 ){
+    pStmt = db_prepare(
+       "INSERT INTO temp.est_stat1(tbl,idx,stat)"
+       "VALUES(\"%w\",NULL,'%lld')", zTab, n
+    );
+    sqlite3_step(pStmt);
+    sqlite3_finalize(pStmt);
+  }
+}
+
+
 /*
 ** Print the sqlite3_value X as an SQL literal.
 */
@@ -401,20 +419,13 @@ int main(int argc, char **argv){
   if( rc || zErrMsg ){
     cmdlineError("Cannot CREATE TEMP TABLE");
   }
-  pStmt = db_prepare("SELECT type, name, tbl_name FROM sqlite_master"
-                     " WHERE type IN ('table','index')"
-                     "   AND rootpage>0"
-                     "   AND (type='index' OR name NOT LIKE 'sqlite_%%')"
-                     " ORDER BY tbl_name, type DESC, name");
+  pStmt = db_prepare("SELECT name FROM sqlite_master"
+                     " WHERE type='table' AND rootpage>0"
+                     "   AND name NOT LIKE 'sqlite_%%'"
+                     " ORDER BY name");
   while( sqlite3_step(pStmt)==SQLITE_ROW ){
-    const char *zType = (const char*)sqlite3_column_text(pStmt, 0);
-    const char *zName = (const char*)sqlite3_column_text(pStmt, 1);
-    const char *zTblName = (const char*)sqlite3_column_text(pStmt, 2);
-    if( zType[0]=='t' ){
-      analyzeTable(zName);
-    }else{
-      analyzeIndex(zTblName, zName);
-    }
+    const char *zName = (const char*)sqlite3_column_text(pStmt, 0);
+    analyzeTable(zName);
   }
   sqlite3_finalize(pStmt);
   dump_table("temp.est_stat1","sqlite_stat1");