-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
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
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
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.
}
/*
-** 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;
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);
" 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 ){
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(
);
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.
*/
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");