]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Same results as the legacy JsonNode implementation on a small set of test cases.
authordrh <>
Sun, 26 Nov 2023 00:48:37 +0000 (00:48 +0000)
committerdrh <>
Sun, 26 Nov 2023 00:48:37 +0000 (00:48 +0000)
FossilOrigin-Name: c3da4b079a1a15a4c0b1a6e71f876648b1d9eb32eddc67b9946c2475c7b6d085

manifest
manifest.uuid
src/json.c

index 17f760ca913022dc8848d0424af09a0a2bb92284..4ae8c1871525f26cd194f869234409f4c99f06b8 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Remove\sunused\selements\sfrom\sthe\sjson_tree()\scursor.
-D 2023-11-25T23:00:50.622
+C Same\sresults\sas\sthe\slegacy\sJsonNode\simplementation\son\sa\ssmall\sset\sof\stest\scases.
+D 2023-11-26T00:48:37.511
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@@ -688,7 +688,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 7bd0d3809b31e32ffa053ba68cf03f67121f6bdd0be7031e8d4c761bef9b6aee
+F src/json.c b93f282f032f904118121ae64552972f078ac13adcd7fc982d20f596f97a424a
 F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa
 F src/loadext.c 7432c944ff197046d67a1207790a1b13eec4548c85a9457eb0896bb3641dfb36
 F src/main.c 1b89f3de98d1b59fec5bac1d66d6ece21f703821b8eaa0d53d9604c35309f6f9
@@ -2145,8 +2145,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 66c2ab9ebbf90477742e6be0d30e061d827c409de038f2a5b73479ed9448c4a6
-R 79cb22ebedffb4f5b0a0989ee5c920ed
+P 914a50117d477b2cd30d58388fb8d1b71ff7ff6842ba025f38efc6e9647d06d0
+R d2ae12035201ed7d53848ee421edc8df
 U drh
-Z b95c9f50e6b9041cf41818958255b068
+Z e4ce705fdf38aad5873f97f479b0490a
 # Remove this line to create a well-formed Fossil manifest.
index a22ec07c45840db0a00a188887ddf88f243547b2..a5cbb721e585b81e7e889604b15641e0ec33cd8a 100644 (file)
@@ -1 +1 @@
-914a50117d477b2cd30d58388fb8d1b71ff7ff6842ba025f38efc6e9647d06d0
\ No newline at end of file
+c3da4b079a1a15a4c0b1a6e71f876648b1d9eb32eddc67b9946c2475c7b6d085
\ No newline at end of file
index 1a2a5bd9ef2c0c124dfffec8e0aca74db0a6e146..14fe274146b95dbc65c83a7f9e86e38a0a7f9026 100644 (file)
@@ -5542,7 +5542,7 @@ struct JsonEachCursor {
   u32 iRowid;                /* The rowid */
   u32 i;                     /* Index in sParse.aBlob[] of current row */
   u32 iEnd;                  /* EOF when i equals or exceeds this value */
-  u32 nRoot;                 /* Size of the root argument in bytes */
+  u32 nRoot;                 /* Size of the root path in bytes */
   u8 eType;                  /* Type of the container for element i */
   u8 bRecursive;             /* True for json_tree().  False for json_each() */
   u32 nParent;               /* Current nesting depth */
@@ -5760,20 +5760,44 @@ static int jsonEachNext(sqlite3_vtab_cursor *cur){
         p->eType = 0;
       }
     }
-    if( p->eType==JSONB_ARRAY ){
-      assert( p->nParent>0 );
-      p->aParent[p->nParent-1].iKey++;
-    }
   }else{
     u32 n, sz = 0;
     u32 i = jsonSkipLabel(p);
     n = jsonbPayloadSize(&p->sParse, i, &sz);
     p->i = i + n + sz;
   }
+  if( p->eType==JSONB_ARRAY ){
+    assert( p->nParent>0 );
+    p->aParent[p->nParent-1].iKey++;
+  }
   p->iRowid++;
   return SQLITE_OK;
 }
 
+/* Length of the path for rowid==0 in bRecursive mode.
+*/
+static int jsonEachPathLength(JsonEachCursor *p){
+  u32 n = p->path.nUsed;
+  if( p->iRowid==0 && p->bRecursive && n>1 ){
+    if( p->path.zBuf[n-1]==']' ){
+      do{
+        n--;
+        assert( n>0 );
+      }while( p->path.zBuf[n]!='[' );
+    }else{
+      u32 sz = 0;
+      jsonbPayloadSize(&p->sParse, p->i, &sz);
+      if( p->path.zBuf[n-1]=='"' ) sz += 2;
+      n -= sz;
+      while( p->path.zBuf[n]!='.' ){
+        n--;
+        assert( n>0 );
+      }
+    }
+  }
+  return n;
+}
+
 /* Return the value of a column */
 static int jsonEachColumn(
   sqlite3_vtab_cursor *cur,   /* The cursor */
@@ -5783,7 +5807,23 @@ static int jsonEachColumn(
   JsonEachCursor *p = (JsonEachCursor*)cur;
   switch( iColumn ){
     case JEACH_KEY: {
-      if( p->nParent==0 ) break;
+      if( p->nParent==0 ){
+        u32 n, j;
+        assert( p->iRowid==0 && p->bRecursive );
+        if( p->nRoot==1 ) break;
+        j = jsonEachPathLength(p);
+        n = p->nRoot - j;
+        if( p->path.zBuf[j]=='[' ){
+          i64 x;
+          sqlite3Atoi64(&p->path.zBuf[j+1], &x, n-1, SQLITE_UTF8);
+          sqlite3_result_int64(ctx, x);
+        }else if( p->path.zBuf[j+1]=='"' ){
+          sqlite3_result_text(ctx, &p->path.zBuf[j+2], n-3, SQLITE_TRANSIENT);
+        }else{
+          sqlite3_result_text(ctx, &p->path.zBuf[j+1], n-1, SQLITE_TRANSIENT);
+        }
+        break;
+      }
       if( p->eType==JSONB_OBJECT ){
         jsonReturnFromBlob(&p->sParse, p->i, ctx, 1);
       }else{
@@ -5815,7 +5855,7 @@ static int jsonEachColumn(
       break;
     }
     case JEACH_PARENT: {
-      if( p->nParent>0 ){
+      if( p->nParent>0 && p->bRecursive ){
         sqlite3_result_int64(ctx, p->aParent[p->nParent-1].iHead);
       }
       break;
@@ -5829,7 +5869,8 @@ static int jsonEachColumn(
       break;
     }
     case JEACH_PATH: {
-      sqlite3_result_text64(ctx, p->path.zBuf, p->path.nUsed,
+      u32 n = jsonEachPathLength(p);
+      sqlite3_result_text64(ctx, p->path.zBuf, n,
                             SQLITE_TRANSIENT, SQLITE_UTF8);
       break;
     }
@@ -5970,6 +6011,7 @@ static int jsonEachFilter(
       jsonEachCursorReset(p);
       return cur->pVtab->zErrMsg ? SQLITE_ERROR : SQLITE_NOMEM;
     }
+    p->nRoot = sqlite3_value_bytes(argv[1]);
     if( zRoot[1]==0 ){
       i = p->i = 0;
       p->eType = 0;
@@ -5989,13 +6031,13 @@ static int jsonEachFilter(
         p->eType = JSONB_ARRAY;
       }
     }
-    jsonAppendRaw(&p->path, zRoot, sqlite3Strlen30(zRoot));
+    jsonAppendRaw(&p->path, zRoot, p->nRoot);
   }else{
     i = p->i = 0;
     p->eType = 0;
+    p->nRoot = 1;
     jsonAppendRaw(&p->path, "$", 1);
   }
-  p->nRoot = p->path.nUsed;
   p->nParent = 0;
   n = jsonbPayloadSize(&p->sParse, i, &sz);
   p->iEnd = i+n+sz;