mirror of
https://github.com/sqlite/sqlite.git
synced 2025-07-30 19:03:16 +03:00
Various fixes to the json_merge_patch() function.
FossilOrigin-Name: f49fd2554b0723eb7cf2fd765d655c6820833ee7e5f7d7629d98c27a6fffa1d9
This commit is contained in:
@ -1364,7 +1364,7 @@ static JsonNode *jsonMergePatch(
|
||||
JsonNode *pPatch /* The PATCH */
|
||||
){
|
||||
int i, j;
|
||||
int iApnd;
|
||||
int iRoot;
|
||||
JsonNode *pTarget;
|
||||
if( pPatch->eType!=JSON_OBJECT ){
|
||||
return pPatch;
|
||||
@ -1373,14 +1373,14 @@ static JsonNode *jsonMergePatch(
|
||||
pTarget = &pParse->aNode[iTarget];
|
||||
assert( (pPatch->jnFlags & JNODE_APPEND)==0 );
|
||||
if( pTarget->eType!=JSON_OBJECT ){
|
||||
for(i=2; i<pPatch->n; i += jsonNodeSize(&pPatch[i])+1){
|
||||
for(i=2; i<=pPatch->n; i += jsonNodeSize(&pPatch[i])+1){
|
||||
if( pPatch[i].eType==JSON_NULL ){
|
||||
pPatch[i-1].jnFlags |= JNODE_REMOVE;
|
||||
pPatch[i].jnFlags |= JNODE_REMOVE;
|
||||
}
|
||||
}
|
||||
return pPatch;
|
||||
}
|
||||
iApnd = iTarget;
|
||||
iRoot = iTarget;
|
||||
for(i=1; i<pPatch->n; i += jsonNodeSize(&pPatch[i+1])+1){
|
||||
int nKey;
|
||||
const char *zKey;
|
||||
@ -1388,21 +1388,19 @@ static JsonNode *jsonMergePatch(
|
||||
assert( pPatch[i].jnFlags & JNODE_LABEL );
|
||||
nKey = pPatch[i].n;
|
||||
zKey = pPatch[i].u.zJContent;
|
||||
if( (pPatch[i].jnFlags & JNODE_RAW)==0 ){
|
||||
assert( nKey>=2 && zKey[0]=='"' && zKey[nKey-1]=='"' );
|
||||
nKey -= 2;
|
||||
zKey ++;
|
||||
}
|
||||
assert( (pPatch[i].jnFlags & JNODE_RAW)==0 );
|
||||
for(j=1; j<pTarget->n; j += jsonNodeSize(&pTarget[j+1])+1 ){
|
||||
assert( pTarget[j].eType==JSON_STRING );
|
||||
assert( pTarget[j].jnFlags & JNODE_LABEL );
|
||||
if( jsonLabelCompare(&pTarget[j], zKey, nKey)
|
||||
&& (pTarget[j+1].jnFlags & (JNODE_REMOVE|JNODE_PATCH))==0
|
||||
assert( (pPatch[i].jnFlags & JNODE_RAW)==0 );
|
||||
if( (pTarget[j+1].jnFlags & (JNODE_REMOVE|JNODE_PATCH))==0
|
||||
&& pTarget[j].n==nKey
|
||||
&& strncmp(pTarget[j].u.zJContent, zKey, nKey)==0
|
||||
){
|
||||
if( pPatch[i+1].eType==JSON_NULL ){
|
||||
pTarget[j+1].jnFlags |= JNODE_REMOVE;
|
||||
}else{
|
||||
JsonNode *pNew = jsonMergePatch(pParse, j+1, &pPatch[i+1]);
|
||||
JsonNode *pNew = jsonMergePatch(pParse, iTarget+j+1, &pPatch[i+1]);
|
||||
if( pNew==0 ) return 0;
|
||||
pTarget = &pParse->aNode[iTarget];
|
||||
if( pNew!=&pTarget[j+1] ){
|
||||
@ -1413,16 +1411,16 @@ static JsonNode *jsonMergePatch(
|
||||
break;
|
||||
}
|
||||
}
|
||||
if( j>=pTarget->n ){
|
||||
if( j>=pTarget->n && pPatch[i+1].eType!=JSON_NULL ){
|
||||
int iStart, iPatch;
|
||||
iStart = jsonParseAddNode(pParse, JSON_OBJECT, 2, 0);
|
||||
jsonParseAddNode(pParse, JSON_STRING, nKey, zKey);
|
||||
iPatch = jsonParseAddNode(pParse, JSON_TRUE, 0, 0);
|
||||
if( pParse->oom ) return 0;
|
||||
pTarget = &pParse->aNode[iTarget];
|
||||
pParse->aNode[iApnd].jnFlags |= JNODE_APPEND;
|
||||
pParse->aNode[iApnd].u.iAppend = iStart;
|
||||
iApnd = iStart;
|
||||
pParse->aNode[iRoot].jnFlags |= JNODE_APPEND;
|
||||
pParse->aNode[iRoot].u.iAppend = iStart - iRoot;
|
||||
iRoot = iStart;
|
||||
pParse->aNode[iPatch].jnFlags |= JNODE_PATCH;
|
||||
pParse->aNode[iPatch].u.pPatch = &pPatch[i+1];
|
||||
}
|
||||
@ -1442,13 +1440,20 @@ static void jsonMergePatchFunc(
|
||||
){
|
||||
JsonParse x; /* The JSON that is being patched */
|
||||
JsonParse y; /* The patch */
|
||||
JsonNode *pResult; /* The result of the merge */
|
||||
|
||||
if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
|
||||
if( jsonParse(&y, ctx, (const char*)sqlite3_value_text(argv[1])) ){
|
||||
jsonParseReset(&x);
|
||||
return;
|
||||
}
|
||||
jsonReturnJson(jsonMergePatch(&x, 0, y.aNode), ctx, 0);
|
||||
pResult = jsonMergePatch(&x, 0, y.aNode);
|
||||
assert( pResult!=0 || x.oom );
|
||||
if( pResult ){
|
||||
jsonReturnJson(pResult, ctx, 0);
|
||||
}else{
|
||||
sqlite3_result_error_nomem(ctx);
|
||||
}
|
||||
jsonParseReset(&x);
|
||||
jsonParseReset(&y);
|
||||
}
|
||||
|
14
manifest
14
manifest
@ -1,5 +1,5 @@
|
||||
C Change\sthe\sname\sof\sthe\snew\sfunction\sto\s"json_merge_patch()".
|
||||
D 2017-03-22T21:45:20.759
|
||||
C Various\sfixes\sto\sthe\sjson_merge_patch()\sfunction.
|
||||
D 2017-03-23T00:13:52.903
|
||||
F Makefile.in 1cc758ce3374a32425e4d130c2fe7b026b20de5b8843243de75f087c0a2661fb
|
||||
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
|
||||
F Makefile.msc 1faf9f06aadc9284c212dea7bbc7c0dea7e8337f0287c81001eff500912c790a
|
||||
@ -218,7 +218,7 @@ F ext/misc/eval.c f971962e92ebb8b0a4e6b62949463ee454d88fa2
|
||||
F ext/misc/fileio.c d4171c815d6543a9edef8308aab2951413cd8d0f
|
||||
F ext/misc/fuzzer.c 7c64b8197bb77b7d64eff7cac7848870235d4c25
|
||||
F ext/misc/ieee754.c f190d0cc5182529acb15babd177781be1ac1718c
|
||||
F ext/misc/json1.c be1032c54498ae8d884b7c430da876a0f895dfc734ac3255336014ce79e3f219
|
||||
F ext/misc/json1.c 8a8ba23a0715858ff393aa890e379912759712518afa4d28de6308a79287cb61
|
||||
F ext/misc/memvfs.c e5225bc22e79dde6b28380f3a068ddf600683a33
|
||||
F ext/misc/nextchar.c 35c8b8baacb96d92abbb34a83a997b797075b342
|
||||
F ext/misc/percentile.c 92699c8cd7d517ff610e6037e56506f8904dae2e
|
||||
@ -913,7 +913,7 @@ F test/jrnlmode3.test 556b447a05be0e0963f4311e95ab1632b11c9eaa
|
||||
F test/json101.test c0897616f32d95431f37fd291cb78742181980ac
|
||||
F test/json102.test bf3fe7a706d30936a76a0f7a0375e1e8e73aff5a
|
||||
F test/json103.test c5f6b85e69de05f6b3195f9f9d5ce9cd179099a0
|
||||
F test/json104.test 66d3dfc9f76e413c7c957d897325b17b9d1bbdf471225310dbf47279e36f1937
|
||||
F test/json104.test 9f8358fd4ec94eca27b31d4ad7f75482edf24c865df378e5129c0b3107c9664e
|
||||
F test/keyword1.test 37ef6bba5d2ed5b07ecdd6810571de2956599dff
|
||||
F test/kvtest.c b9a9822dda05a1aa481215a52e2fc93cd8b22ee5
|
||||
F test/lastinsert.test 42e948fd6442f07d60acbd15d33fb86473e0ef63
|
||||
@ -1568,7 +1568,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
|
||||
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
||||
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
||||
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
||||
P a267444039af519f088dd8f8ee33f686cc3071c087677075af2364ebc2587514
|
||||
R f0982f12ae9e098efe5bc17c4edc8338
|
||||
P 53bf70f37bbca319ea35f70849e2a34ae628a504486158fdad5c4bb7431c68e0
|
||||
R 7c38ec8ac02c81967ed35b7b062ffaf6
|
||||
U drh
|
||||
Z 17fdf70c56513cf2488f301085ed16e1
|
||||
Z e95ab9d86e57fcad88a27a5fb020f800
|
||||
|
@ -1 +1 @@
|
||||
53bf70f37bbca319ea35f70849e2a34ae628a504486158fdad5c4bb7431c68e0
|
||||
f49fd2554b0723eb7cf2fd765d655c6820833ee7e5f7d7629d98c27a6fffa1d9
|
@ -54,6 +54,13 @@ do_execsql_test json104-110 {
|
||||
},
|
||||
"tags": [ "example" ]
|
||||
}');
|
||||
} {{{"title":"Hello!","author":{"givenName":"John"},"tags":["example"],"content":"This will be unchanged",phoneNumber:"+01-123-456-7890"}}}
|
||||
} {{{"title":"Hello!","author":{"givenName":"John"},"tags":["example"],"content":"This will be unchanged","phoneNumber":"+01-123-456-7890"}}}
|
||||
|
||||
do_execsql_test json104-200 {
|
||||
SELECT json_merge_patch('[1,2,3]','{"x":null}');
|
||||
} {{{}}}
|
||||
do_execsql_test json104-210 {
|
||||
SELECT json_merge_patch('[1,2,3]','{"x":null,"y":1,"z":null}');
|
||||
} {{{"y":1}}}
|
||||
|
||||
finish_test
|
||||
|
Reference in New Issue
Block a user