]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Rename "mxWidth" to "mxColWidth". Add "mxTotalWidth" and "mxLength"
authordrh <>
Fri, 7 Nov 2025 13:11:16 +0000 (13:11 +0000)
committerdrh <>
Fri, 7 Nov 2025 13:11:16 +0000 (13:11 +0000)
settings and hook them up to the TCL interface, but those settings are
not yet implemented.

FossilOrigin-Name: 3f327e8fbc295b43c79118f8f49f8d2e20c2f3ac96e3b7f996720dab858d8199

ext/qrf/README.md
ext/qrf/qrf.c
ext/qrf/qrf.h
manifest
manifest.uuid
src/tclsqlite.c
test/qrf01.test

index 36ef6cf346e81433c2dd108c1fc8d26f72d21608..b291d2a463bbbcc844120e4cdb549899032bf301 100644 (file)
@@ -60,10 +60,12 @@ struct sqlite3_qrf_spec {
   unsigned char eEsc;         /* How to escape control characters in text */
   unsigned char eText;        /* Quoting style for text */
   unsigned char eBlob;        /* Quoting style for BLOBs */
-  unsigned char bColumnNames; /* QRF_SW_On to show column names */
+  unsigned char bColumnNames; /* True to show column names */
   unsigned char bWordWrap;    /* Try to wrap on word boundaries */
   unsigned char bTextJsonb;   /* Render JSONB blobs as JSON text */
-  short int mxWidth;          /* Maximum width of any column */
+  short int mxColWidth;       /* Maximum width of any individual column */
+  short int mxTotalWidth;     /* Maximum overall table width */
+  int mxLength;               /* Maximum content to display per element */
   int nWidth;                 /* Number of column width parameters */
   short int *aWidth;          /* Column widths */
   const char *zColumnSep;     /* Alternative column separator */
@@ -71,7 +73,7 @@ struct sqlite3_qrf_spec {
   const char *zTableName;     /* Output table name */
   const char *zNull;          /* Rendering of NULL */
   char *(*xRender)(void*,sqlite3_value*);                /* Render a value */
-  ssize_t (*xWrite)(void*,const unsigned char*,size_t);  /* Write callback */
+  sqlite3_int64 (*xWrite)(void*,const unsigned char*,sqlite3_int64);
   void *pRenderArg;           /* First argument to the xRender callback */
   void *pWriteArg;            /* First argument to the xWrite callback */
   char **pzOutput;            /* Storage location for output string */
@@ -259,24 +261,44 @@ the C/Tcl/Perl octal backslash escapes.  So the string from the
 previous paragraph would be shown as
 `"\u0005\u0028\u0081\u00f3"`.
 
-### 2.8 Word Wrapping In Columnar Modes (mxWidth and bWordWrap)
+### 2.8 Maximum displayed content length (mxLength)
+
+If the sqlite3_qrf_spec.mxLength setting is non-zero, then the formatter
+*attempts* to show only the first mxLength characters of each value.
+This limit is approximate.  The content length might exceed the limit
+by a few characters, especially if the limit is very small.
+
+Content length limits only apply to TEXT and BLOB values.  Numeric
+values and NULLs always display their full text regardless of the
+mxLength setting.
+
+### 2.9 Word Wrapping In Columnar Modes (mxColWidth, mxTotalWidth, bWordWrap)
 
 When using columnar formatting modes (QRF_STYLE_Box, QRF_STYLE_Column,
-QRF_STYLE_Markdown, or QRF_STYLE_Table) and with sqlite3_qrf_spec.mxWidth
-set to some non-zero value, then when an output is too wide to be
-displayed in just mxWidth standard character widths, the output is
-split into multiple lines, where each line is a maximum of 
-mxWidth characters wide.  "Width" hear means the actual displayed
-width of the text in a fixed-pitch font.  The code takes into account
-zero-width and double-width characters when computing the display width.
-
-If the sqlite3_qrf_spec.bWordWrap flag is set to QRF_SW_On,
-then the formatter attempts to split lines at whitespace or word boundaries.
-If the bWorkWrap flag is set QRF_SW_Off, then the QRF makes not attempt
-to find good places to split lines and will usually split lines in the
-middle of words.
-
-### 2.9 Column width and alignment (nWidth and aWidth)
+QRF_STYLE_Markdown, or QRF_STYLE_Table), the formatter attempts to limit
+the width of any individual column to sqlite3_qrf_spec.mxColWidth characters
+if mxColWidth is non-zero.  A zero value for mxColWidth means "unlimited".
+The formatter also attempts to limit the width of the entire table to
+no more than sqlite3_qrf_spec.mxTotalWidth characters.  Again, a zero
+value means "no-limit".
+
+The mxColWidth limit might be exceeded if the limit is very small.
+The mxTotalWidth is "best effort"; the formatter might go significantly
+beyond the mxTotalWidth if the table has too many columns
+to squeeze into the specified space.
+
+In order to keep individual columns, or the entire table, within
+requested length limits, it is sometimes necessary to wrap the content
+for a single row of a single column across multiple lines.  When this
+becomes necessary and if the bWordWrap setting is QRF_SW_On, then the
+formatter attempts to split the content on whitespace or at a word boundary.
+If bWordWrap is QRF_SW_Off, then the formatter is free to split content
+anywhere, including in the middle of a word.
+
+For narrow columns and wide words, it might sometimes be necessary to split
+a column in the middle of a word, even when bWordWrap is QRF_SW_On.
+
+### 2.10 Column width and alignment (nWidth and aWidth)
 
 The sqlite3_qrf_spec.aWidth field is a pointer to an array of
 signed 16-bit integers that control column widths and alignments
@@ -315,7 +337,7 @@ width of the corresponding column.  Negative values are used for
 right-justified columns and positive values are used for left-justified
 columns.
 
-### 2.10 Row and Column Separator Strings
+### 2.11 Row and Column Separator Strings
 
 The sqlite3_qrf_spec.zColumnSep and sqlite3_qrf_spec.zRowSep strings
 are alternative column and row separator character sequences.  If not
@@ -323,18 +345,18 @@ specified (if these pointers are left as NULL) then appropriate defaults
 are used.  Some output styles have hard-coded column and row separators
 and these settings are ignored for those styles.
 
-### 2.11 The Output Table Name
+### 2.12 The Output Table Name
 
 The sqlite3_qrf_spec.zTableName value is the name of the output table
 when eStyle is QRF_STYLE_Insert.
 
-### 2.12 The Rendering Of NULL
+### 2.13 The Rendering Of NULL
 
 If a value is NULL then show the NULL using the string
 found in sqlite3_qrf_spec.zNull.  If zNull is itself a NULL pointer
 then NULL values are rendered as an empty string.
 
-### 2.13 Optional Value Rendering Callback
+### 2.14 Optional Value Rendering Callback
 
 If the sqlite3_qrf_spec.xRender field is not NULL, then each
 sqlite3_value coming out of the query is first passed to the
index e6790f0c4df83126bf60335db367b0da5b2f729c..bf2d3cc05b347cd08ea9e07b07c9776b9e58330a 100644 (file)
@@ -911,7 +911,7 @@ static char *qrfTableCell(
     return 0;
   }
   if( mxWidth<0 ) mxWidth = -mxWidth;
-  if( mxWidth==0 ) mxWidth = 1000000;
+  if( mxWidth==0 ) mxWidth = QRF_MX_WIDTH;
   i = j = n = 0;
   while( n<=mxWidth ){
     unsigned char c = z[i];
@@ -1213,7 +1213,7 @@ static void qrfColumnar(Qrf *p){
       const unsigned char *zNotUsed;
       int wx = p->actualWidth[i];
       if( wx==0 ){
-        wx = p->spec.mxWidth;
+        wx = p->spec.mxColWidth;
       }
       if( wx<0 ) wx = -wx;
       uz = (const unsigned char*)sqlite3_column_name(p->pStmt,i);
@@ -1259,7 +1259,7 @@ static void qrfColumnar(Qrf *p){
       for(i=0; i<nColumn; i++){
         int wx = i<p->spec.nWidth ? p->spec.aWidth[i] : 0;
         if( wx==0 || wx==QRF_MINUS_ZERO ){
-          wx = p->spec.mxWidth;
+          wx = p->spec.mxColWidth;
         }
         if( wx<0 ) wx = -wx;
         if( useNextLine ){
index fb567a77ffea1d745c8599f88b352eed1f70693f..7d18a9e1d65881ed812dcddb66a90fbf8777483c 100644 (file)
@@ -30,7 +30,9 @@ struct sqlite3_qrf_spec {
   unsigned char bColumnNames; /* True to show column names */
   unsigned char bWordWrap;    /* Try to wrap on word boundaries */
   unsigned char bTextJsonb;   /* Render JSONB blobs as JSON text */
-  short int mxWidth;          /* Maximum width of any column */
+  short int mxColWidth;       /* Maximum width of any individual column */
+  short int mxTotalWidth;     /* Maximum overall table width */
+  int mxLength;               /* Maximum content to display per element */
   int nWidth;                 /* Number of column width parameters */
   short int *aWidth;          /* Column widths */
   const char *zColumnSep;     /* Alternative column separator */
@@ -46,7 +48,8 @@ struct sqlite3_qrf_spec {
 };
 
 /*
-** Range of values for sqlite3_qrf_spec.aWidth[] entries:
+** Range of values for sqlite3_qrf_spec.aWidth[] entries and for
+** sqlite3_qrf_spec.mxColWidth and .mxTotalWidth
 */
 #define QRF_MX_WIDTH    (10000)
 #define QRF_MN_WIDTH    (-10000)
index 312b1b1540f1977a2ee44fdb2d7d8565bda565e5..230ba0988a2ac3eb2ab199320ef267ee37548ee4 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Fix\san\serror-message\stest\scase\sbroken\sby\sthe\sprevious\scheck-in.
-D 2025-11-07T12:15:25.909
+C Rename\s"mxWidth"\sto\s"mxColWidth".\s\sAdd\s"mxTotalWidth"\sand\s"mxLength"\nsettings\sand\shook\sthem\sup\sto\sthe\sTCL\sinterface,\sbut\sthose\ssettings\sare\nnot\syet\simplemented.
+D 2025-11-07T13:11:16.220
 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
@@ -416,9 +416,9 @@ F ext/misc/wholenumber.c 0fa0c082676b7868bf2fa918e911133f2b349bcdceabd1198bba5f6
 F ext/misc/windirent.h 02211ce51f3034c675f2dbf4d228194d51b3ee05734678bad5106fff6292e60c
 F ext/misc/zipfile.c 09e6e3a3ff40a99677de3c0bc6569bd5f4709b1844ac3d1c1452a456c5a62f1c
 F ext/misc/zorder.c bddff2e1b9661a90c95c2a9a9c7ecd8908afab5763256294dd12d609d4664eee
-F ext/qrf/README.md 251568600920db5f82524ec63fc07e2dfebf98697cbaa708271b4ac6055ffb58
-F ext/qrf/qrf.c 772c87f50d591d7fa6e82730856ce04ac4321c31169d5025eae8608df3adc9b9
-F ext/qrf/qrf.h 39ba5d895f123bcce155b40446ec6d2728055f1f8bf29fdf8221f1eb8835d56d
+F ext/qrf/README.md a8d288316000b17675400e8e141e5377a1e0bb0090d443421dbf062ef88e2bac
+F ext/qrf/qrf.c ca5394613a0e755f68db3622b33c4abae23aacd3c4c2544dcf355558220217c3
+F ext/qrf/qrf.h a02d156e54e05c5ef66012b66817beecd6e2c60327491d98eb11361e7c0a19e2
 F ext/rbu/rbu.c 801450b24eaf14440d8fd20385aacc751d5c9d6123398df41b1b5aa804bf4ce8
 F ext/rbu/rbu1.test 25870dd7db7eb5597e2b4d6e29e7a7e095abf332660f67d89959552ce8f8f255
 F ext/rbu/rbu10.test 7c22caa32c2ff26983ca8320779a31495a6555737684af7aba3daaf762ef3363
@@ -743,7 +743,7 @@ F src/sqliteInt.h 88f7fc9ce1630d9a5f7e0a8e1f3287cdc63882fba985c18e7eee1b9f457f59
 F src/sqliteLimit.h fe70bd8983e5d317a264f2ea97473b359faf3ebb0827877a76813f5cf0cdc364
 F src/status.c 7565d63a79aa2f326339a24a0461a60096d0bd2bce711fefb50b5c89335f3592
 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1
-F src/tclsqlite.c c180acb528411fcb468a2d5f925befdc53afe4c4f821bd7ca35d86826a6d4787
+F src/tclsqlite.c cb5e3f5de07367b5b83af046c4ee4abae6b12b61bcbcf0d5df5049c17e9131f8
 F src/tclsqlite.h 614b3780a62522bc9f8f2b9fb22689e8009958e7aa77e572d0f3149050af348a
 F src/test1.c f880ab766eeedf2c063662bd9538b923fd42c4341b7bfc2150a6d93ab8b9341c
 F src/test2.c 62f0830958f9075692c29c6de51b495ae8969e1bef85f239ffcd9ba5fb44a5ff
@@ -1506,7 +1506,7 @@ F test/printf2.test 3f55c1871a5a65507416076f6eb97e738d5210aeda7595a74ee895f2224c
 F test/progress.test ebab27f670bd0d4eb9d20d49cef96e68141d92fb
 F test/ptrchng.test ef1aa72d6cf35a2bbd0869a649b744e9d84977fc
 F test/pushdown.test 46a626ef1c0ca79b85296ff2e078b9da20a50e9b804b38f441590c3987580ddd
-F test/qrf01.test 802e45eb9b106ad915ea561fafb709d626c8cb1bfee8e372bbcfd182002ddb77
+F test/qrf01.test 193a3ad8101975d3e574f0855eb7285928a554420fc354916a199600234e3d62
 F test/qrf02.test 39b4afdc000bedccdafc0aecf17638df67a67aaa2d2942865ae6abcc48ba0e92
 F test/queryonly.test 5f653159e0f552f0552d43259890c1089391dcca
 F test/quick.test 1681febc928d686362d50057c642f77a02c62e57
@@ -2173,8 +2173,8 @@ F tool/version-info.c 33d0390ef484b3b1cb685d59362be891ea162123cea181cb8e6d2cf6dd
 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7
 F tool/warnings.sh d924598cf2f55a4ecbc2aeb055c10bd5f48114793e7ba25f9585435da29e7e98
 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
-P 7dfba841cfc515ac28401c4eb90ec24e04fd52cddaeae41be3cfa6967dac0eac
-R bcc8bcd428fc9db4943cd2c8ec4dbd87
+P fb040354901569915389c8c4c1530dfda8b724be7885adfde654e229d3e98eec
+R 07c0c21d8a92a6dbfbd7b3fed9158cb5
 U drh
-Z fa3fc5dd07b68cd8fbb8a0b772680d8e
+Z f2a96b5e64232cb1c60df6a68367fba5
 # Remove this line to create a well-formed Fossil manifest.
index d5ee9f2bb1f433d675105c6b811abe407e4ca206..e49e88e9cfd3428a823aa28e351a2cb8c22a61ad 100644 (file)
@@ -1 +1 @@
-fb040354901569915389c8c4c1530dfda8b724be7885adfde654e229d3e98eec
+3f327e8fbc295b43c79118f8f49f8d2e20c2f3ac96e3b7f996720dab858d8199
index 31c03acdb194a56b3a893934b5bfd74dc9470afa..8fd252462c12d6b591189a9fd2c7a9465c225b69 100644 (file)
@@ -2062,7 +2062,9 @@ static void DbHookCmd(
 **     -columnnames ("auto"|"off"|"on")        Show column names?
 **     -wordwrap ("auto"|"off"|"on")           Try to wrap at word boundry?
 **     -textjsonb ("auto"|"off"|"on")          Auto-convert JSONB to text?
-**     -maxwidth NUMBER                        Default column width
+**     -maxcolwidth NUMBER                     Max width of any single column
+**     -maxwidth NUMBER                        Max width of the entire table
+**     -maxlength NUMBER                       Content truncated to this size
 **     -widths LIST-OF-NUMBERS                 Widths for individual columns
 **     -columnsep TEXT                         Column separator text
 **     -rowsep TEXT                            Row separator text
@@ -2081,7 +2083,9 @@ static void DbHookCmd(
 **     -columnnames      bColumnNames
 **     -wordwrap         bWordWrap
 **     -textjsonb        bTextJsonb
-**     -maxwidth         mxWidth
+**     -maxcolwidth      mxColWidth
+**     -maxwidth         mxTotalWidth
+**     -maxlength        mxLength
 **     -widths           nWidth, aWidth
 **     -columnsep        zColumnSep
 **     -rowsep           zRowSep
@@ -2207,7 +2211,7 @@ static int dbQrf(SqliteDb *pDb, int objc, Tcl_Obj *const*objv){
       if( rc ) goto format_failed;
       qrf.bTextJsonb = v;
       i++;
-    }else if( strcmp(zArg,"-maxwidth")==0 ){
+    }else if( strcmp(zArg,"-maxcolwidth")==0 || strcmp(zArg,"-maxwidth")==0 ){
       int v = 0;
       rc = Tcl_GetIntFromObj(pDb->interp, objv[i+1], &v);
       if( rc ) goto format_failed;
@@ -2216,7 +2220,18 @@ static int dbQrf(SqliteDb *pDb, int objc, Tcl_Obj *const*objv){
       }else if( v>QRF_MX_WIDTH ){
         v = QRF_MX_WIDTH;
       }
-      qrf.mxWidth = v;
+      if( zArg[4]=='c' ){
+        qrf.mxColWidth = v;
+      }else{
+        qrf.mxTotalWidth = v;
+      }
+      i++;
+    }else if( strcmp(zArg,"-maxlength")==0 ){
+      int v = 0;
+      rc = Tcl_GetIntFromObj(pDb->interp, objv[i+1], &v);
+      if( rc ) goto format_failed;
+      if( v<0 ) v = 0;
+      qrf.mxLength = v;
       i++;
     }else if( strcmp(zArg,"-widths")==0 ){
       Tcl_Size n = 0;
index 90708e972001da7e00b5702fd9447f91acebf43c..cf970f8844a429626b9f4364a71d87e857378699 100644 (file)
@@ -466,7 +466,7 @@ do_test 4.2 {
 └─────────────────┴─────────────────┴────┘
 }
 do_test 4.3 {
-  set result "\n[db format -text off -textjsonb on -maxwidth 10 \
+  set result "\n[db format -text off -textjsonb on -maxcolwidth 10 \
               {SELECT a AS json, b AS jsonb, c AS num FROM t1}]"
 } {
 ┌─────────────┬─────────────┬─────┐