From: drh <> Date: Wed, 15 Jan 2025 00:29:07 +0000 (+0000) Subject: Always include the sz=NNN option in the sqlite_stat1.stat field. X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=42e56496e8f9dce1cc0c03080480b16111c1c5ab;p=thirdparty%2Fsqlite.git Always include the sz=NNN option in the sqlite_stat1.stat field. FossilOrigin-Name: 9c0d6f29df8169efef0909ec53c09624128b429c5a03fabdb067aceb1a99f45b --- diff --git a/manifest b/manifest index 16e144446c..4b0fece634 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Change\sthe\sversion\snumber\sto\s3.49.0\sto\sbegin\sthe\snext\sdevelopment\ncycle.\s\sAny\spatches\sto\s3.48.0\swill\sgo\son\sa\sbranch. -D 2025-01-14T20:47:23.128 +C Always\sinclude\sthe\ssz=NNN\soption\sin\sthe\ssqlite_stat1.stat\sfield. +D 2025-01-15T00:29:07.273 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -711,7 +711,7 @@ F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 acdff36db796e2d00225b911d3047d580cd136547298435426ce9d40347973cc F sqlite3.pc.in 0977c03a4da7c4204bd60e784a0efb8d51a190448aba78a4e973fe7192bdaf03 F src/alter.c aa93e37e4a36a0525bbb2a2aeda20d2018f0aa995542c7dc658e031375e3f532 -F src/analyze.c 9a8b67239d899ac12289db5db3f5bfe7f7a0ad1277f80f87ead1d048085876eb +F src/analyze.c b626b6ff849e38abf23c636c54aade8123a818fbb61052f3f40b5f07156d4126 F src/attach.c f35bb8cc1fcdde8f6815a7ef09ae413bcac71821d530796800ba24b3c7da1e80 F src/auth.c 54ab9c6c5803b47c0d45b76ce27eff22a03b4b1f767c5945a3a4eb13aa4c78dc F src/backup.c 5c97e8023aab1ce14a42387eb3ae00ba5a0644569e3476f38661fa6f824c3523 @@ -847,7 +847,7 @@ F src/upsert.c 215328c3f91623c520ec8672c44323553f12caeb4f01b1090ebdca99fdf7b4f1 F src/utf.c 8b29d9a5956569ea2700f869669b8ef67a9662ee5e724ff77ab3c387e27094ba F src/util.c e5f6a5eeaa26b69054a43bbd0048cfe3d2851f6961052b35aed8f695df922850 F src/vacuum.c b763b6457bd058d2072ef9364832351fd8d11e8abf70cbb349657360f7d55c40 -F src/vdbe.c 8a6eb02823b424b273614bae41579392a5c495424592b60423dd2c443a583df0 +F src/vdbe.c faec343c9644a331c6022ee651c98d9e56a031f36b5adc23bccb177b1066ee8e F src/vdbe.h 9676348d342bd04e21e384c63b57224171ce84fac77853357334ef94c4d33cf4 F src/vdbeInt.h bf294a0c8fc4cc80779e74b04b8bd82c6e1197b3137cefe0b16cdf002fc7dfd6 F src/vdbeapi.c 38c252a202d70b56cfb734460bc888ddbd581afec1a10cd4d6c894c9e0b5baea @@ -2205,8 +2205,11 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P bc6de90c7049dd429a82d32b186a838f4a21aa7b8a83418eaf0416d19771b41e -R 7be4e73ee614c5955da7d841289f67c4 +P 8165a3d3a40c5b43275fb4b1cdf57c44a57cd56c514bd2a550deac26a14795eb +R 75951752e714dce0865aa5bd2ffc033f +T *branch * analyze-row-size +T *sym-analyze-row-size * +T -sym-trunk * U drh -Z 4394aec1aff44c176b2cf58b3618b986 +Z 540f2f22b8607354d71f9232e8098a95 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 6b616acf3d..d44fba768b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8165a3d3a40c5b43275fb4b1cdf57c44a57cd56c514bd2a550deac26a14795eb +9c0d6f29df8169efef0909ec53c09624128b429c5a03fabdb067aceb1a99f45b diff --git a/src/analyze.c b/src/analyze.c index 9213c202b7..bccdb6037c 100644 --- a/src/analyze.c +++ b/src/analyze.c @@ -178,9 +178,9 @@ static void openStatTable( #if defined(SQLITE_ENABLE_STAT4) { "sqlite_stat4", "tbl,idx,neq,nlt,ndlt,sample" }, #else - { "sqlite_stat4", 0 }, + { "sqlite_stat4", 0 }, /* Not created or written, but is cleared if present */ #endif - { "sqlite_stat3", 0 }, + { "sqlite_stat3", 0 }, /* Not created or written, but is cleared if present */ }; int i; sqlite3 *db = pParse->db; @@ -282,6 +282,7 @@ struct StatAccum { sqlite3 *db; /* Database connection, for malloc() */ tRowcnt nEst; /* Estimated number of rows */ tRowcnt nRow; /* Number of rows visited so far */ + i64 nByte; /* Total size of all rows visited */ int nLimit; /* Analysis row-scan limit */ int nCol; /* Number of columns in index + pk/rowid */ int nKeyCol; /* Number of index columns w/o the pk/rowid */ @@ -680,11 +681,12 @@ static void samplePushPrevious(StatAccum *p, int iChng){ #endif /* SQLITE_ENABLE_STAT4 */ /* -** Implementation of the stat_push SQL function: stat_push(P,C,R) +** Implementation of the stat_push SQL function: stat_push(P,C,S,R) ** Arguments: ** ** P Pointer to the StatAccum object created by stat_init() ** C Index of left-most column to differ from previous row +** S The size in bytes of the on-disk representation of the current row ** R Rowid for the current row. Might be a key record for ** WITHOUT ROWID tables. ** @@ -714,6 +716,7 @@ static void statPush( assert( p->nCol>0 ); assert( iChngnCol ); + p->nByte += sqlite3_value_int(argv[2]); if( p->nRow==0 ){ /* This is the first call to this function. Do initialization. */ #ifdef SQLITE_ENABLE_STAT4 @@ -875,6 +878,9 @@ static void statGet( assert( p->current.anEq[i] || p->nRow==0 ); #endif } + if( ALWAYS(p->nRow>0) ){ + sqlite3_str_appendf(&sStat, " sz=%d", p->nByte/p->nRow); + } sqlite3ResultStrAccum(context, &sStat); } #ifdef SQLITE_ENABLE_STAT4 @@ -993,6 +999,7 @@ static void analyzeOneTable( int regNewRowid = iMem++; /* Rowid for the inserted record */ int regStat = iMem++; /* Register to hold StatAccum object */ int regChng = iMem++; /* Index of changed index field */ + int regRowSz = iMem++; /* Register holding the row size */ int regRowid = iMem++; /* Rowid argument passed to stat_push() */ int regTemp = iMem++; /* Temporary use register */ int regTemp2 = iMem++; /* Second temporary use register */ @@ -1138,26 +1145,26 @@ static void analyzeOneTable( ** count() ** stat_init() ** goto chng_addr_0; - */ - assert( regTemp2==regStat+4 ); - sqlite3VdbeAddOp2(v, OP_Integer, db->nAnalysisLimit, regTemp2); - - /* Arguments to stat_init(): + ** + ** Arguments to stat_init(): ** (1) the number of columns in the index including the rowid ** (or for a WITHOUT ROWID table, the number of PK columns), ** (2) the number of columns in the key without the rowid/pk - ** (3) estimated number of rows in the index. */ + ** (3) estimated number of rows in the index. + ** (4) Analysis limit + */ sqlite3VdbeAddOp2(v, OP_Integer, nCol, regStat+1); - assert( regRowid==regStat+2 ); - sqlite3VdbeAddOp2(v, OP_Integer, pIdx->nKeyCol, regRowid); - sqlite3VdbeAddOp3(v, OP_Count, iIdxCur, regTemp, + sqlite3VdbeAddOp2(v, OP_Integer, pIdx->nKeyCol, regStat+2); + sqlite3VdbeAddOp3(v, OP_Count, iIdxCur, regStat+3, OptimizationDisabled(db, SQLITE_Stat4)); + sqlite3VdbeAddOp2(v, OP_Integer, db->nAnalysisLimit, regStat+4); sqlite3VdbeAddFunctionCall(pParse, 0, regStat+1, regStat, 4, &statInitFuncdef, 0); addrGotoEnd = sqlite3VdbeAddOp1(v, OP_Rewind, iIdxCur); VdbeCoverage(v); sqlite3VdbeAddOp2(v, OP_Integer, 0, regChng); + sqlite3VdbeAddOp2(v, OP_Integer, 0, regRowSz); addrNextRow = sqlite3VdbeCurrentAddr(v); if( nColTest>0 ){ @@ -1190,6 +1197,7 @@ static void analyzeOneTable( sqlite3VdbeAddOp2(v, OP_Integer, i, regChng); sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, i, regTemp); analyzeVdbeCommentIndexWithColumnName(v,pIdx,i); + if( i==0 ) sqlite3VdbeAddOp2(v, OP_RowSize, iIdxCur, regRowSz); aGotoChng[i] = sqlite3VdbeAddOp4(v, OP_Ne, regTemp, 0, regPrev+i, pColl, P4_COLLSEQ); sqlite3VdbeChangeP5(v, SQLITE_NULLEQ); @@ -1245,7 +1253,7 @@ static void analyzeOneTable( #endif assert( regChng==(regStat+1) ); { - sqlite3VdbeAddFunctionCall(pParse, 1, regStat, regTemp, 2+IsStat4, + sqlite3VdbeAddFunctionCall(pParse, 1, regStat, regTemp, 3+IsStat4, &statPushFuncdef, 0); if( db->nAnalysisLimit ){ int j1, j2, j3; diff --git a/src/vdbe.c b/src/vdbe.c index 558970ed95..a3d6ea2ef9 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -6006,6 +6006,15 @@ case OP_SorterData: { /* ncycle */ break; } +/* Opcode: RowSize P1 P2 ** * +** Synopsis: r[P2]=sizeof(data) +** +** Write into register P2 the number of bytes in the on-disk +** representation of the row to which cursor P1 is pointing. +** +** If the P1 cursor must be pointing to a valid row (not a NULL row) +** of a real table, not a pseudo-table. +*/ /* Opcode: RowData P1 P2 P3 * * ** Synopsis: r[P2]=data ** @@ -6034,6 +6043,7 @@ case OP_SorterData: { /* ncycle */ ** The P2 register content is invalidated by opcodes like OP_Function or ** by any use of another cursor pointing to the same table. */ +case OP_RowSize: case OP_RowData: { VdbeCursor *pC; BtCursor *pCrsr; @@ -6062,6 +6072,10 @@ case OP_RowData: { assert( sqlite3BtreeCursorIsValid(pCrsr) ); n = sqlite3BtreePayloadSize(pCrsr); + if( pOp->opcode==OP_RowSize ){ + sqlite3VdbeMemSetInt64(pOut, n); + break; + } if( n>(u32)db->aLimit[SQLITE_LIMIT_LENGTH] ){ goto too_big; }