]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Add support for the bTxtJsonb flag in sqlite3_qrf_spec, which if true causes
authordrh <>
Tue, 28 Oct 2025 22:25:24 +0000 (22:25 +0000)
committerdrh <>
Tue, 28 Oct 2025 22:25:24 +0000 (22:25 +0000)
JSONB blobs to be displayed as JSON text.

FossilOrigin-Name: 3fcf9ecb039a903cefcf4eeaf43974de0cbd48d899dc189b8f70c3745addc11a

ext/qrf/README.md
ext/qrf/qrf-tester.c
ext/qrf/qrf.c
ext/qrf/qrf.h
manifest
manifest.uuid

index ece06b60bce20bad7d74b8caf299fbcec667b6a5..000709efd19c6c28ea89e32c97845023cc94c53e 100644 (file)
@@ -44,6 +44,7 @@ struct sqlite3_qrf_spec {
   unsigned char eQuote;       /* Quoting style for text */
   unsigned char eBlob;        /* Quoting style for BLOBs */
   unsigned char bWordWrap;    /* Try to wrap on word boundaries */
+  unsigned char bTxtJsonb;    /* Render JSONB blobs as JSON text */
   short int mxWidth;          /* Maximum width of any column */
   int nWidth;                 /* Number of column width parameters */
   short int *aWidth;          /* Column widths */
@@ -170,10 +171,16 @@ A value of QRF_TXT_Json gives similar results as QRF_TXT_Tcl except that the
 rules are adjusted so that the displayed string is strictly conforming
 the JSON specification.
 
-### 2.7 How to escape BLOB values
+### 2.7 How to escape BLOB values (eBlob and bTxtJsonb)
 
-The sqlite3_qrf_spec.eBlob field determines out BLOB values are formatted
-for display.  This field can have one of the following values:
+If the sqlite3_qrf_spec.bTxtJsonb flag is true and if the value to be
+displayed is JSONB, then the JSONB is translated into text JSON and the
+text is shown according to the sqlite3_qrf_spec.eQuote setting as
+described in the previous section.
+
+If the bTxtJsonb flag is false (the usual case) or if the BLOB value to
+be displayed is not JSONB, then the sqlite3_qrf_spec.eBlob field determines
+how the BLOB value is formatted.  The following options are available;
 
 > ~~~
 #define QRF_BLOB_Auto    0 /* Determine BLOB quoting using eQuote */
index d264a7a7e9e8bdee5a507919bf72ba73beeb00be..4226782daf2fd025d9687a4154f1a4b8c66abf94 100644 (file)
@@ -297,6 +297,9 @@ int main(int argc, char **argv){
     if( strncmp(zLine, "--bShowCNames=", 14)==0 ){
       spec.bShowCNames = atoi(&zLine[14])!=0;
     }else
+    if( strncmp(zLine, "--bTxtJsonb=", 12)==0 ){
+      spec.bTxtJsonb = atoi(&zLine[12])!=0;
+    }else
     if( strncmp(zLine, "--zNull=", 8)==0 ){
       spec.zNull = tempStrdup(&zLine[8]);
     }else
index 437b5e5c6c3b92229fb3225abc996b0749af106d..7768d31674ce0a488404778b8c95b93004d40e60 100644 (file)
@@ -44,6 +44,7 @@ typedef struct Qrf Qrf;
 struct Qrf {
   sqlite3_stmt *pStmt;        /* The statement whose output is to be rendered */
   sqlite3 *db;                /* The corresponding database connection */
+  sqlite3_stmt *pJTrans;      /* JSONB to JSON translator statement */
   char **pzErr;               /* Write error message here, if not NULL */
   sqlite3_str *pOut;          /* Accumulated output */
   int iErr;                   /* Error code */
@@ -574,6 +575,48 @@ static void qrfEncodeText(Qrf *p, sqlite3_str *pOut, const char *zTxt){
   }
 }
 
+/*
+** The current iCol-th column of p->pStmt is known to be a BLOB.  Check
+** to see if that BLOB is really a JSONB blob.  If it is, then translate
+** it into a text JSON representation and return a pointer to that text JSON.
+**
+** The memory used to hold the JSON text is managed internally by the
+** "p" object and is overwritten and/or deallocated upon the next call
+** to this routine (with the same p argument) or when the p object is
+** finailized.
+*/
+static const char *qrfJsonbToJson(Qrf *p, int iCol){
+  int nByte;
+  const void *pBlob;
+  int rc;
+  if( p->pJTrans==0 ){
+    sqlite3 *db;
+    rc = sqlite3_open(":memory:",&db);
+    if( rc ){
+      sqlite3_close(db);
+      return 0;
+    }
+    rc = sqlite3_prepare_v2(db, "SELECT json(?1)", -1, &p->pJTrans, 0);
+    if( rc ){
+      sqlite3_finalize(p->pJTrans);
+      p->pJTrans = 0;
+      sqlite3_close(db);
+      return 0;
+    }
+  }else{
+    sqlite3_reset(p->pJTrans);
+  }
+  nByte = sqlite3_column_bytes(p->pStmt, iCol);
+  pBlob = sqlite3_column_blob(p->pStmt, iCol);
+  sqlite3_bind_blob(p->pJTrans, 1, (void*)pBlob, nByte, SQLITE_STATIC);
+  rc = sqlite3_step(p->pJTrans);
+  if( rc==SQLITE_ROW ){
+    return (const char*)sqlite3_column_text(p->pJTrans, 0);
+  }else{
+    return 0;
+  }
+}
+
 /*
 ** Render value pVal into pOut
 */
@@ -601,6 +644,13 @@ static void qrfRenderValue(Qrf *p, sqlite3_str *pOut, int iCol){
       break;
     }
     case SQLITE_BLOB: {
+      if( p->spec.bTxtJsonb ){
+        const char *zJson = qrfJsonbToJson(p, iCol);
+        if( zJson ){
+          qrfEncodeText(p, pOut, zJson);
+          break;
+        }
+      }
       switch( p->spec.eBlob ){
         case QRF_BLOB_Hex:
         case QRF_BLOB_Sql: {
@@ -1222,6 +1272,7 @@ qrf_column_end:
     sqlite3_free(azData[i]);
   }
   sqlite3_free(azData);
+  sqlite3_free(abRowDiv);
   
   return;
 }
@@ -1675,6 +1726,11 @@ static void qrfFinalize(Qrf *p){
     sqlite3_free(sqlite3_str_finish(p->pOut));
   }
   if( p->actualWidth ) sqlite3_free(p->actualWidth);
+  if( p->pJTrans ){
+    sqlite3 *db = sqlite3_db_handle(p->pJTrans);
+    sqlite3_finalize(p->pJTrans);
+    sqlite3_close(db);
+  }
 }
 
 /*
index 0cf5d01c82ec1f613cd3bf8ca5820595370f5c23..f4e8a42e3c79233af8ab0c948747a8bdb971f7b8 100644 (file)
@@ -27,6 +27,7 @@ struct sqlite3_qrf_spec {
   unsigned char eQuote;       /* Quoting style for text */
   unsigned char eBlob;        /* Quoting style for BLOBs */
   unsigned char bWordWrap;    /* Try to wrap on word boundaries */
+  unsigned char bTxtJsonb;    /* Render JSONB blobs as JSON text */
   short int mxWidth;          /* Maximum width of any column */
   int nWidth;                 /* Number of column width parameters */
   short int *aWidth;          /* Column widths */
index d463706e6fdc1c1b2d9f30ecd63eac646f4fb311..fbbc68b34102afc0cfac2b10570dbef31cd72b51 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Fix\sa\sharmless\scompiler\swarning.
-D 2025-10-28T19:37:18.472
+C Add\ssupport\sfor\sthe\sbTxtJsonb\sflag\sin\ssqlite3_qrf_spec,\swhich\sif\strue\scauses\nJSONB\sblobs\sto\sbe\sdisplayed\sas\sJSON\stext.
+D 2025-10-28T22:25:24.967
 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
@@ -416,10 +416,10 @@ 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 f98f1777446c7ae96c9a60f7d2042e3e8c8f80db75c4aa69f7314b1d27fb1814
-F ext/qrf/qrf-tester.c 7d72e3268db31a348c2e8002b174eac9a25d1f93350d845e1ef5f60dfddd95a9
-F ext/qrf/qrf.c 2522d8a938875badb499e199c13fc68eaa9b9141ce4f4acf843e00e8d0d64d20
-F ext/qrf/qrf.h 68c7d03ece46d329d0df90e2bae2d08771bba32bb9affc368691249b7b605158
+F ext/qrf/README.md 8e0763e34c97c288c8e913f8984c89c270aa9f681a9fc389320b3e36cdf7ea4f
+F ext/qrf/qrf-tester.c 25b5c71fecde6053d7c49e91de578b15b09f370cc9d2db0de3bc55251da9fe45
+F ext/qrf/qrf.c 221937b10e5ced56a4bbdeae940b75f4c71776827910a34cd0b3168374e4eaec
+F ext/qrf/qrf.h 70d3e5b24c22bb14a19cdc2121aeff6a4054e29541e14dcb4750c0cfba6078c2
 F ext/rbu/rbu.c 801450b24eaf14440d8fd20385aacc751d5c9d6123398df41b1b5aa804bf4ce8
 F ext/rbu/rbu1.test 25870dd7db7eb5597e2b4d6e29e7a7e095abf332660f67d89959552ce8f8f255
 F ext/rbu/rbu10.test 7c22caa32c2ff26983ca8320779a31495a6555737684af7aba3daaf762ef3363
@@ -2175,8 +2175,8 @@ F tool/version-info.c 33d0390ef484b3b1cb685d59362be891ea162123cea181cb8e6d2cf6dd
 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7
 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd
 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
-P fa5661ea8b6b5ca368d719477bd82a954d2f979f4ab85fff2720cf7bb7cc427d
-R cd4e401ce66ee9cb501533b05e6c9f99
+P d00c549126ca96b061e537dfabb93b02824e3a9b8fa0c9135a96cf060262206e
+R eb84edc720870a58624028e0ab77bb61
 U drh
-Z d0bb32d0a0ee6a7455bdbcfecd272cc9
+Z 008d48891a8df1ef5b5f2498f9433818
 # Remove this line to create a well-formed Fossil manifest.
index 25f14a6950de1c52d0345f5efdf111e14b77d58f..83386db7065d8bfea826ac6251a5654fb23b46be 100644 (file)
@@ -1 +1 @@
-d00c549126ca96b061e537dfabb93b02824e3a9b8fa0c9135a96cf060262206e
+3fcf9ecb039a903cefcf4eeaf43974de0cbd48d899dc189b8f70c3745addc11a