From: drh <> Date: Sun, 26 Nov 2023 00:48:37 +0000 (+0000) Subject: Same results as the legacy JsonNode implementation on a small set of test cases. X-Git-Tag: version-3.45.0~116^2~54^2~2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=50b37832b250acb3fc55b8f177935ab7af4eef48;p=thirdparty%2Fsqlite.git Same results as the legacy JsonNode implementation on a small set of test cases. FossilOrigin-Name: c3da4b079a1a15a4c0b1a6e71f876648b1d9eb32eddc67b9946c2475c7b6d085 --- diff --git a/manifest b/manifest index 17f760ca91..4ae8c18715 100644 --- 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. diff --git a/manifest.uuid b/manifest.uuid index a22ec07c45..a5cbb721e5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -914a50117d477b2cd30d58388fb8d1b71ff7ff6842ba025f38efc6e9647d06d0 \ No newline at end of file +c3da4b079a1a15a4c0b1a6e71f876648b1d9eb32eddc67b9946c2475c7b6d085 \ No newline at end of file diff --git a/src/json.c b/src/json.c index 1a2a5bd9ef..14fe274146 100644 --- a/src/json.c +++ b/src/json.c @@ -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;