From: drh <> Date: Tue, 14 Apr 2026 19:36:33 +0000 (+0000) Subject: Implementation of the analyze() SQL function is now mostly complete. X-Git-Url: http://git.ipfire.org/gitweb/?a=commitdiff_plain;h=395ac6c1bc99fd72a79e1bc3b76c5f33af5c9afc;p=thirdparty%2Fsqlite.git Implementation of the analyze() SQL function is now mostly complete. FossilOrigin-Name: 1ca0386ab2df0d88ed52941469d459114f483ecf6b7e4691bcc32e909636cb7d --- diff --git a/ext/misc/analyze.c b/ext/misc/analyze.c index 127d010aab..900a6203fa 100644 --- a/ext/misc/analyze.c +++ b/ext/misc/analyze.c @@ -358,16 +358,23 @@ static int analysisSubreport( analysisLine(p, "Bytes of storage consumed", "%lld\n", storage); analysisLine(p, "Bytes of payload", "%-11lld", payload); analysisPercent(p, 0, payload*100.0/(double)storage); + if( ovfl_cnt>0 ){ + analysisLine(p, "Bytes of payload in overflow", "%-11lld", ovfl_payload); + analysisPercent(p, 0, ovfl_payload*100.0/(double)payload); + } total_unused = leaf_unused + int_unused + ovfl_unused; total_meta = storage - payload - total_unused; - analysisLine(p, "Bytes of metadata", "%lld", total_meta); + analysisLine(p, "Bytes of metadata", "%-11lld", total_meta); analysisPercent(p, 0, total_meta*100.0/(double)storage); + if( cnt==1 ){ + analysisLine(p, "B-tree depth", "%lld\n", depth); + } if( nentry>0 ){ - analysisLine(p, "Average payload per entry", "%g\n", + analysisLine(p, "Average payload per entry", "%.1f\n", (double)payload/(double)nentry); - analysisLine(p, "Average unused bytes per entry", "%g\n", + analysisLine(p, "Average unused bytes per entry", "%.1f\n", (double)total_unused/(double)nentry); - analysisLine(p, "Average metadata per entry", "%g\n", + analysisLine(p, "Average metadata per entry", "%.1f\n", (double)total_meta/(double)nentry); } analysisLine(p, "Maximum single-entry payload", "%lld\n", mx_payload); @@ -379,10 +386,19 @@ static int analysisSubreport( analysisLine(p, "Index pages used", "%lld\n", int_pages); } analysisLine(p, "Primary pages used", "%lld\n", leaf_pages); - analysisLine(p, "Overflow pages used", "%lld\n", ovfl_pages); + if( ovfl_cnt ){ + analysisLine(p, "Overflow pages used", "%lld\n", ovfl_pages); + } analysisLine(p, "Total pages used", "%lld\n", total_pages); - - + if( int_pages>0 ){ + analysisLine(p, "Unused bytes on index pages", "%lld\n", int_unused); + } + analysisLine(p, "Unused bytes on primary pages", "%lld\n", leaf_unused); + if( ovfl_cnt ){ + analysisLine(p, "Unused bytes on overflow pages", "%lld\n", ovfl_unused); + } + analysisLine(p, "Unused bytes on all pages", "%-11lld", total_unused); + analysisPercent(p, 0, total_unused*100.0/(double)storage); } if( analysisStmtFinish(p, rc, pStmt) ){ return rc; @@ -615,7 +631,6 @@ static void analyzeFunc( analysisPercent(&s, 0, (n*100.0)/(double)nPage); } if( analysisStmtFinish(&s, rc, pStmt) ) return; - sqlite3_str_append(s.pOut, "\n", 1); rc = analysisSubreport(&s, "All tables and indexes", "1", pgsz, nPage); if( rc ) return; @@ -649,6 +664,8 @@ static void analyzeFunc( sqlite3_free(zWhere); if( rc ) break; }else{ + sqlite3_stmt *pS2; + int rc2; char *zTitle = sqlite3_mprintf("Table %s and all its indexes", zUpper); char *zWhere = sqlite3_mprintf("tblname=%Q", zName); rc = analysisSubreport(&s, zTitle, zWhere, pgsz, nPage); @@ -661,11 +678,35 @@ static void analyzeFunc( sqlite3_free(zTitle); sqlite3_free(zWhere); if( rc ) break; - zTitle = sqlite3_mprintf("All index of table %s", zUpper); - zWhere = sqlite3_mprintf("tblname=%Q AND is_index", zName); - rc = analysisSubreport(&s, zTitle, zWhere, pgsz, nPage); - sqlite3_free(zTitle); - sqlite3_free(zWhere); + if( nIndex>1 ){ + zTitle = sqlite3_mprintf("All indexes of table %s", zUpper); + zWhere = sqlite3_mprintf("tblname=%Q AND is_index", zName); + rc = analysisSubreport(&s, zTitle, zWhere, pgsz, nPage); + sqlite3_free(zTitle); + sqlite3_free(zWhere); + if( rc ) break; + } + pS2 = analysisPrepare(&s, + "SELECT name, upper(name) FROM temp.%s" + " WHERE is_index AND tblname=%Q", + s.zSU, zName); + if( pS2==0 ){ + rc = SQLITE_NOMEM; + break; + } + while( (rc = sqlite3_step(pS2))==SQLITE_ROW ){ + const char *zU = (const char*)sqlite3_column_text(pS2, 1); + const char *zN = (const char*)sqlite3_column_text(pS2, 0); + zTitle = sqlite3_mprintf("Index %s", zU); + zWhere = sqlite3_mprintf("name=%Q", zN); + rc = analysisSubreport(&s, zTitle, zWhere, pgsz, nPage); + sqlite3_free(zTitle); + sqlite3_free(zWhere); + if( rc ) break; + } + if( rc==SQLITE_DONE ) rc = SQLITE_OK; + rc2 = sqlite3_finalize(pS2); + if( rc==SQLITE_OK && rc2!=SQLITE_OK ) rc = rc2; if( rc ) break; } } @@ -744,7 +785,7 @@ static void analyzeFunc( sqlite3_finalize(pStmt); return; } - sqlite3_str_appendf(s.pOut,"\nCOMMIT;\n"); + sqlite3_str_appendf(s.pOut,";\nCOMMIT;\n"); sqlite3_finalize(pStmt); if( sqlite3_str_length(s.pOut) ){ diff --git a/manifest b/manifest index b28c44a30c..9f702950b4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Much,\sbut\snot\sall,\sof\sthe\sreport\sgeneration\sis\sadded.\s\sAn\sincremental\scheck-in. -D 2026-04-14T19:02:40.997 +C Implementation\sof\sthe\sanalyze()\sSQL\sfunction\sis\snow\smostly\scomplete. +D 2026-04-14T19:36:33.575 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -358,7 +358,7 @@ F ext/jni/src/tests/000-001-ignored.test e17e874c6ab3c437f1293d88093cf06286083b6 F ext/jni/src/tests/900-001-fts.test bf0ce17a8d082773450e91f2388f5bbb2dfa316d0b676c313c637a91198090f0 F ext/misc/README.md 6243cdc4d7eb791c41ef0716f3980b8b5f6aa8c61ff76a3958cbf0031c6ebfa7 F ext/misc/amatch.c 8d237cc014b3736922c26a76a451050d244aa4980c47c531f368f817b1e77b49 -F ext/misc/analyze.c a08a09619c5e206ee403199f5299618bc8163972bcc2252d0e2e164e75b623c6 +F ext/misc/analyze.c 200aa4a378e54b710cd774d70a3a65d916972bcf695671eff306309cd37fa8da F ext/misc/anycollseq.c 5ffdfde9829eeac52219136ad6aa7cd9a4edb3b15f4f2532de52f4a22525eddb F ext/misc/appendvfs.c 9642c7a194a2a25dca7ad3e36af24a0a46d7702168c4ad7e59c9f9b0e16a3824 F ext/misc/base64.c 1445761667c16356e827fc6418294c869468be934429aaa8315035e76dd58acf @@ -2199,8 +2199,8 @@ F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee F tool/warnings.sh a554d13f6e5cf3760f041b87939e3d616ec6961859c3245e8ef701d1eafc2ca2 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f F tool/winmain.c 00c8fb88e365c9017db14c73d3c78af62194d9644feaf60e220ab0f411f3604c -P 037a0e586c4aa81a53aea164080e739f9d5b87197d04fdd68feb0ab5eb01020b -R 70ce17d6d01e5469f673e51601f83039 +P 289fefc3edfeecb06dc11897d3ff24763fd9e25db44e369eeec29b9ed3de5ccc +R 635177803a58986bff71c8ff6e3e87a1 U drh -Z c9e2ac614964bb80c0cde4c2ca0cf6c6 +Z cf63c806645e7784cf6fda78da65684e # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 7f8a4fc5f3..fdf1e55aa4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -289fefc3edfeecb06dc11897d3ff24763fd9e25db44e369eeec29b9ed3de5ccc +1ca0386ab2df0d88ed52941469d459114f483ecf6b7e4691bcc32e909636cb7d