]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Always include the sz=NNN option in the sqlite_stat1.stat field.
authordrh <>
Wed, 15 Jan 2025 00:29:07 +0000 (00:29 +0000)
committerdrh <>
Wed, 15 Jan 2025 00:29:07 +0000 (00:29 +0000)
FossilOrigin-Name: 9c0d6f29df8169efef0909ec53c09624128b429c5a03fabdb067aceb1a99f45b

manifest
manifest.uuid
src/analyze.c
src/vdbe.c

index 16e144446c7214763f653f551106f799264ad09d..4b0fece63435dae1fc4de51fabbd1c237610c017 100644 (file)
--- 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.
index 6b616acf3d606c97575667b77c096044c06aaef4..d44fba768bfb323f325cfdcc78954d0be1599e81 100644 (file)
@@ -1 +1 @@
-8165a3d3a40c5b43275fb4b1cdf57c44a57cd56c514bd2a550deac26a14795eb
+9c0d6f29df8169efef0909ec53c09624128b429c5a03fabdb067aceb1a99f45b
index 9213c202b77488c86e53ad93164337fbce6344e2..bccdb6037cc61e33c6510ef20785537ee49b3495 100644 (file)
@@ -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( iChng<p->nCol );
 
+  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;
index 558970ed953c06cc65045048213dab370faffdf9..a3d6ea2ef99bb3651f143d638425eebdb6eb3821 100644 (file)
@@ -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;
   }