]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Enhance the (undocumented, debug-only) json_parse() SQL function so that it
authordrh <>
Thu, 28 Dec 2023 16:21:22 +0000 (16:21 +0000)
committerdrh <>
Thu, 28 Dec 2023 16:21:22 +0000 (16:21 +0000)
returns the text rendering of the JSONB parse of the input, rather than printing
the rendering on stdout.

FossilOrigin-Name: 056de8d551dcbdf1d162e2db15ed418fa9c786f900cd3972ef8a1dea3f4f3aa1

manifest
manifest.uuid
src/json.c

index 692bc455100561f2bf12e0c6a6d93803142e8454..0aaf21b3f9f47786033343a5ee92f62c78e66628 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Fix\sa\sproblem\sin\sthe\sshell\stool\s(not\slibrary)\scausing\san\sout-of-bounds\swrite\sif\san\s".open"\scommand\sfailed,\sthen\sthe\suser\spressed\sctrl-c\sto\sinterrupt\sa\squery\srunning\son\sthe\ssubstitute\sin-memory\sdatabase.
-D 2023-12-27T16:24:53.514
+C Enhance\sthe\s(undocumented,\sdebug-only)\sjson_parse()\sSQL\sfunction\sso\sthat\sit\nreturns\sthe\stext\srendering\sof\sthe\sJSONB\sparse\sof\sthe\sinput,\srather\sthan\sprinting\nthe\srendering\son\sstdout.
+D 2023-12-28T16:21:22.018
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@@ -697,7 +697,7 @@ F src/hash.h 3340ab6e1d13e725571d7cee6d3e3135f0779a7d8e76a9ce0a85971fa3953c51
 F src/hwtime.h f9c2dfb84dce7acf95ce6d289e46f5f9d3d1afd328e53da8f8e9008e3b3caae6
 F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71
 F src/insert.c 3f0a94082d978bbdd33c38fefea15346c6c6bffb70bc645a71dc0f1f87dd3276
-F src/json.c bc90605da937ca0cd72ff0492216fbb38fd8f9025e6344499f9db235be98e36f
+F src/json.c 4e389cbf100c53c19fff7e6fca50efb8b1ed989350eb1ae25e2950416cc9c972
 F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa
 F src/loadext.c 7432c944ff197046d67a1207790a1b13eec4548c85a9457eb0896bb3641dfb36
 F src/main.c ce714ee501122c76eb2e69b292bebe443aba611fc3b88e6786eb910285515fe4
@@ -2156,8 +2156,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
 F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P 1a8a9b1c89519d265869251e8b6d3c5db733f0d3a7dea6c7962811a8f1157dff
-R 9be7ded4b93fb872773060703710555e
-U dan
-Z 20de7b64b135a6b7a6b0796593663512
+P 026618b9e321576f616a32e41329066ba629814170c6cfeef35430343f5003f3
+R 4f345097ec9904c5b67a6755cec93b7a
+U drh
+Z 755e762b4bd7fb34fd05935917357de5
 # Remove this line to create a well-formed Fossil manifest.
index f5d9fa1a12a2aa44bcfb00869a6a99e5cfe60b9f..33cc0bd2eff27254906b40c960d2228878f406ef 100644 (file)
@@ -1 +1 @@
-026618b9e321576f616a32e41329066ba629814170c6cfeef35430343f5003f3
\ No newline at end of file
+056de8d551dcbdf1d162e2db15ed418fa9c786f900cd3972ef8a1dea3f4f3aa1
\ No newline at end of file
index 42d6155fb6ca757347739456e11e40d5c9d03f96..5f5440ec315b08a191f31a4edf812836aeaed835 100644 (file)
@@ -3351,14 +3351,15 @@ static void jsonDebugPrintBlob(
   JsonParse *pParse, /* JSON content */
   u32 iStart,        /* Start rendering here */
   u32 iEnd,          /* Do not render this byte or any byte after this one */
-  int nIndent        /* Indent by this many spaces */
+  int nIndent,       /* Indent by this many spaces */
+  sqlite3_str *pOut  /* Generate output into this sqlite3_str object */
 ){
   while( iStart<iEnd ){
     u32 i, n, nn, sz = 0;
     int showContent = 1;
     u8 x = pParse->aBlob[iStart] & 0x0f;
     u32 savedNBlob = pParse->nBlob;
-    printf("%5d:%*s", iStart, nIndent, "");
+    sqlite3_str_appendf(pOut, "%5d:%*s", iStart, nIndent, "");
     if( pParse->nBlobAlloc>pParse->nBlob ){
       pParse->nBlob = pParse->nBlobAlloc;
     }
@@ -3367,9 +3368,11 @@ static void jsonDebugPrintBlob(
     if( sz>0 && x<JSONB_ARRAY ){
       nn += sz;
     }
-    for(i=0; i<nn; i++) printf(" %02x", pParse->aBlob[iStart+i]);
+    for(i=0; i<nn; i++){
+      sqlite3_str_appendf(pOut, " %02x", pParse->aBlob[iStart+i]);
+    }
     if( n==0 ){
-      printf("   ERROR invalid node size\n");
+      sqlite3_str_appendf(pOut, "   ERROR invalid node size\n");
       iStart = n==0 ? iStart+1 : iEnd;
       continue;
     }
@@ -3384,55 +3387,57 @@ static void jsonDebugPrintBlob(
         }
       }
     }
-    printf("  <-- ");
+    sqlite3_str_appendall(pOut,"  <-- ");
     switch( x ){
-      case JSONB_NULL:     printf("null"); break;
-      case JSONB_TRUE:     printf("true"); break;
-      case JSONB_FALSE:    printf("false"); break;
-      case JSONB_INT:      printf("int"); break;
-      case JSONB_INT5:     printf("int5"); break;
-      case JSONB_FLOAT:    printf("float"); break;
-      case JSONB_FLOAT5:   printf("float5"); break;
-      case JSONB_TEXT:     printf("text"); break;
-      case JSONB_TEXTJ:    printf("textj"); break;
-      case JSONB_TEXT5:    printf("text5"); break;
-      case JSONB_TEXTRAW:  printf("textraw"); break;
+      case JSONB_NULL:     sqlite3_str_appendall(pOut,"null"); break;
+      case JSONB_TRUE:     sqlite3_str_appendall(pOut,"true"); break;
+      case JSONB_FALSE:    sqlite3_str_appendall(pOut,"false"); break;
+      case JSONB_INT:      sqlite3_str_appendall(pOut,"int"); break;
+      case JSONB_INT5:     sqlite3_str_appendall(pOut,"int5"); break;
+      case JSONB_FLOAT:    sqlite3_str_appendall(pOut,"float"); break;
+      case JSONB_FLOAT5:   sqlite3_str_appendall(pOut,"float5"); break;
+      case JSONB_TEXT:     sqlite3_str_appendall(pOut,"text"); break;
+      case JSONB_TEXTJ:    sqlite3_str_appendall(pOut,"textj"); break;
+      case JSONB_TEXT5:    sqlite3_str_appendall(pOut,"text5"); break;
+      case JSONB_TEXTRAW:  sqlite3_str_appendall(pOut,"textraw"); break;
       case JSONB_ARRAY: {
-        printf("array, %u bytes\n", sz);
-        jsonDebugPrintBlob(pParse, iStart+n, iStart+n+sz, nIndent+2);
+        sqlite3_str_appendf(pOut,"array, %u bytes\n", sz);
+        jsonDebugPrintBlob(pParse, iStart+n, iStart+n+sz, nIndent+2, pOut);
         showContent = 0;
         break;
       }
       case JSONB_OBJECT: {
-        printf("object, %u bytes\n", sz);
-        jsonDebugPrintBlob(pParse, iStart+n, iStart+n+sz, nIndent+2);
+        sqlite3_str_appendf(pOut, "object, %u bytes\n", sz);
+        jsonDebugPrintBlob(pParse, iStart+n, iStart+n+sz, nIndent+2, pOut);
         showContent = 0;
         break;
       }
       default: {
-        printf("ERROR: unknown node type\n");
+        sqlite3_str_appendall(pOut, "ERROR: unknown node type\n");
         showContent = 0;
         break;
       }
     }
     if( showContent ){
       if( sz==0 && x<=JSONB_FALSE ){
-        printf("\n");
+        sqlite3_str_append(pOut, "\n", 1);
       }else{
         u32 i;
-        printf(": \"");
+        sqlite3_str_appendall(pOut, ": \"");
         for(i=iStart+n; i<iStart+n+sz; i++){
           u8 c = pParse->aBlob[i];
           if( c<0x20 || c>=0x7f ) c = '.';
-          putchar(c);
+          sqlite3_str_append(pOut, (char*)&c, 1);
         }
-        printf("\"\n");
+        sqlite3_str_append(pOut, "\"\n", 2);
       }
     }
     iStart += n + sz;
   }
 }
 static void jsonShowParse(JsonParse *pParse){
+  sqlite3_str out;
+  char zBuf[1000];
   if( pParse==0 ){
     printf("NULL pointer\n");
     return;
@@ -3443,7 +3448,10 @@ static void jsonShowParse(JsonParse *pParse){
     if( pParse->nBlob==0 ) return;
     printf("content (bytes 0..%u):\n", pParse->nBlob-1);
   }
-  jsonDebugPrintBlob(pParse, 0, pParse->nBlob, 0);
+  sqlite3StrAccumInit(&out, 0, zBuf, sizeof(zBuf), 1000000);
+  jsonDebugPrintBlob(pParse, 0, pParse->nBlob, 0, &out);
+  printf("%s", sqlite3_str_value(&out));
+  sqlite3_str_reset(&out);
 }
 #endif /* SQLITE_DEBUG */
 
@@ -3451,8 +3459,8 @@ static void jsonShowParse(JsonParse *pParse){
 /*
 ** SQL function:   json_parse(JSON)
 **
-** Parse JSON using jsonParseFuncArg().  Then print a dump of that
-** parse on standard output.
+** Parse JSON using jsonParseFuncArg().  Return text that is a
+** human-readable dump of the binary JSONB for the input parameter.
 */
 static void jsonParseFunc(
   sqlite3_context *ctx,
@@ -3460,10 +3468,18 @@ static void jsonParseFunc(
   sqlite3_value **argv
 ){
   JsonParse *p;        /* The parse */
+  sqlite3_str out;
 
-  assert( argc==1 );
+  assert( argc>=1 );
+  sqlite3StrAccumInit(&out, 0, 0, 0, 1000000);
   p = jsonParseFuncArg(ctx, argv[0], 0);
-  jsonShowParse(p);
+  if( p==0 ) return;
+  if( argc==1 ){
+    jsonDebugPrintBlob(p, 0, p->nBlob, 0, &out);
+    sqlite3_result_text64(ctx, out.zText, out.nChar, sqlite3_free, SQLITE_UTF8);
+  }else{
+    jsonShowParse(p);
+  }
   jsonParseFree(p);
 }
 #endif /* SQLITE_DEBUG */