Enhance the json_insert(), json_replace(), and json_set() functions with the
ability to add JSON instead of text if the argument is text and if the PATH begins with '$$' instead of just '$'. FossilOrigin-Name: 44f103d8862abc2d5613bac04dc2ea8e625b1f40
This commit is contained in:
parent
2dc292930d
commit
ecb5fedb3f
@ -80,6 +80,7 @@ static const char * const jsonType[] = {
|
|||||||
#define JNODE_REMOVE 0x04 /* Do not output */
|
#define JNODE_REMOVE 0x04 /* Do not output */
|
||||||
#define JNODE_REPLACE 0x08 /* Replace with JsonNode.iVal */
|
#define JNODE_REPLACE 0x08 /* Replace with JsonNode.iVal */
|
||||||
#define JNODE_APPEND 0x10 /* More ARRAY/OBJECT entries at u.iAppend */
|
#define JNODE_APPEND 0x10 /* More ARRAY/OBJECT entries at u.iAppend */
|
||||||
|
#define JNODE_JSON 0x20 /* Treat REPLACE as JSON text */
|
||||||
|
|
||||||
|
|
||||||
/* A single node of parsed JSON
|
/* A single node of parsed JSON
|
||||||
@ -238,7 +239,8 @@ static void jsonAppendString(JsonString *p, const char *zIn, u32 N){
|
|||||||
*/
|
*/
|
||||||
static void jsonAppendValue(
|
static void jsonAppendValue(
|
||||||
JsonString *p, /* Append to this JSON string */
|
JsonString *p, /* Append to this JSON string */
|
||||||
sqlite3_value *pValue /* Value to append */
|
sqlite3_value *pValue, /* Value to append */
|
||||||
|
u8 textIsJson /* Try to treat text values as JSON */
|
||||||
){
|
){
|
||||||
switch( sqlite3_value_type(pValue) ){
|
switch( sqlite3_value_type(pValue) ){
|
||||||
case SQLITE_NULL: {
|
case SQLITE_NULL: {
|
||||||
@ -255,7 +257,11 @@ static void jsonAppendValue(
|
|||||||
case SQLITE_TEXT: {
|
case SQLITE_TEXT: {
|
||||||
const char *z = (const char*)sqlite3_value_text(pValue);
|
const char *z = (const char*)sqlite3_value_text(pValue);
|
||||||
u32 n = (u32)sqlite3_value_bytes(pValue);
|
u32 n = (u32)sqlite3_value_bytes(pValue);
|
||||||
jsonAppendString(p, z, n);
|
if( textIsJson ){
|
||||||
|
jsonAppendRaw(p, z, n);
|
||||||
|
}else{
|
||||||
|
jsonAppendString(p, z, n);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
@ -355,7 +361,8 @@ static void jsonRenderNode(
|
|||||||
if( pNode[j].jnFlags & (JNODE_REMOVE|JNODE_REPLACE) ){
|
if( pNode[j].jnFlags & (JNODE_REMOVE|JNODE_REPLACE) ){
|
||||||
if( pNode[j].jnFlags & JNODE_REPLACE ){
|
if( pNode[j].jnFlags & JNODE_REPLACE ){
|
||||||
jsonAppendSeparator(pOut);
|
jsonAppendSeparator(pOut);
|
||||||
jsonAppendValue(pOut, aReplace[pNode[j].iVal]);
|
jsonAppendValue(pOut, aReplace[pNode[j].iVal],
|
||||||
|
(pNode[j].jnFlags & JNODE_JSON)!=0);
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
jsonAppendSeparator(pOut);
|
jsonAppendSeparator(pOut);
|
||||||
@ -380,7 +387,8 @@ static void jsonRenderNode(
|
|||||||
jsonRenderNode(&pNode[j], pOut, aReplace);
|
jsonRenderNode(&pNode[j], pOut, aReplace);
|
||||||
jsonAppendChar(pOut, ':');
|
jsonAppendChar(pOut, ':');
|
||||||
if( pNode[j+1].jnFlags & JNODE_REPLACE ){
|
if( pNode[j+1].jnFlags & JNODE_REPLACE ){
|
||||||
jsonAppendValue(pOut, aReplace[pNode[j+1].iVal]);
|
jsonAppendValue(pOut, aReplace[pNode[j+1].iVal],
|
||||||
|
(pNode[j+1].jnFlags & JNODE_JSON)!=0);
|
||||||
}else{
|
}else{
|
||||||
jsonRenderNode(&pNode[j+1], pOut, aReplace);
|
jsonRenderNode(&pNode[j+1], pOut, aReplace);
|
||||||
}
|
}
|
||||||
@ -993,7 +1001,7 @@ static void jsonArrayFunc(
|
|||||||
jsonAppendChar(&jx, '[');
|
jsonAppendChar(&jx, '[');
|
||||||
for(i=0; i<argc; i++){
|
for(i=0; i<argc; i++){
|
||||||
jsonAppendSeparator(&jx);
|
jsonAppendSeparator(&jx);
|
||||||
jsonAppendValue(&jx, argv[i]);
|
jsonAppendValue(&jx, argv[i], 0);
|
||||||
}
|
}
|
||||||
jsonAppendChar(&jx, ']');
|
jsonAppendChar(&jx, ']');
|
||||||
jsonResult(&jx);
|
jsonResult(&jx);
|
||||||
@ -1101,7 +1109,7 @@ static void jsonObjectFunc(
|
|||||||
n = (u32)sqlite3_value_bytes(argv[i]);
|
n = (u32)sqlite3_value_bytes(argv[i]);
|
||||||
jsonAppendString(&jx, z, n);
|
jsonAppendString(&jx, z, n);
|
||||||
jsonAppendChar(&jx, ':');
|
jsonAppendChar(&jx, ':');
|
||||||
jsonAppendValue(&jx, argv[i+1]);
|
jsonAppendValue(&jx, argv[i+1], 0);
|
||||||
}
|
}
|
||||||
jsonAppendChar(&jx, '}');
|
jsonAppendChar(&jx, '}');
|
||||||
jsonResult(&jx);
|
jsonResult(&jx);
|
||||||
@ -1166,12 +1174,18 @@ static void jsonReplaceFunc(
|
|||||||
if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
|
if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
|
||||||
if( x.nNode ){
|
if( x.nNode ){
|
||||||
for(i=1; i<(u32)argc; i+=2){
|
for(i=1; i<(u32)argc; i+=2){
|
||||||
|
u8 jnFlags = JNODE_REPLACE;
|
||||||
zPath = (const char*)sqlite3_value_text(argv[i]);
|
zPath = (const char*)sqlite3_value_text(argv[i]);
|
||||||
if( zPath==0 ) continue;
|
if( zPath==0 ) continue;
|
||||||
if( zPath[0]!='$' ) continue;
|
if( zPath[0]!='$' ) continue;
|
||||||
|
if( zPath[1]=='$' ){
|
||||||
|
zPath++;
|
||||||
|
jnFlags = JNODE_REPLACE|JNODE_JSON;
|
||||||
|
}
|
||||||
pNode = jsonLookup(&x, 0, &zPath[1], 0);
|
pNode = jsonLookup(&x, 0, &zPath[1], 0);
|
||||||
if( pNode ){
|
if( pNode ){
|
||||||
pNode->jnFlags |= JNODE_REPLACE;
|
pNode->jnFlags &= ~JNODE_JSON;
|
||||||
|
pNode->jnFlags |= jnFlags;
|
||||||
pNode->iVal = i+1;
|
pNode->iVal = i+1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1216,16 +1230,22 @@ static void jsonSetFunc(
|
|||||||
if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
|
if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
|
||||||
if( x.nNode ){
|
if( x.nNode ){
|
||||||
for(i=1; i<(u32)argc; i+=2){
|
for(i=1; i<(u32)argc; i+=2){
|
||||||
|
u8 jnFlags = JNODE_REPLACE;
|
||||||
zPath = (const char*)sqlite3_value_text(argv[i]);
|
zPath = (const char*)sqlite3_value_text(argv[i]);
|
||||||
if( zPath==0 ) continue;
|
if( zPath==0 ) continue;
|
||||||
if( zPath[0]!='$' ) continue;
|
if( zPath[0]!='$' ) continue;
|
||||||
|
if( zPath[1]=='$' ){
|
||||||
|
zPath++;
|
||||||
|
jnFlags = JNODE_REPLACE|JNODE_JSON;
|
||||||
|
}
|
||||||
bApnd = 0;
|
bApnd = 0;
|
||||||
pNode = jsonLookup(&x, 0, &zPath[1], &bApnd);
|
pNode = jsonLookup(&x, 0, &zPath[1], &bApnd);
|
||||||
if( x.oom ){
|
if( x.oom ){
|
||||||
sqlite3_result_error_nomem(ctx);
|
sqlite3_result_error_nomem(ctx);
|
||||||
goto jsonSetDone;
|
goto jsonSetDone;
|
||||||
}else if( pNode && (bApnd || bIsSet) ){
|
}else if( pNode && (bApnd || bIsSet) ){
|
||||||
pNode->jnFlags |= JNODE_REPLACE;
|
pNode->jnFlags &= ~JNODE_JSON;
|
||||||
|
pNode->jnFlags |= jnFlags;
|
||||||
pNode->iVal = i+1;
|
pNode->iVal = i+1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
14
manifest
14
manifest
@ -1,5 +1,5 @@
|
|||||||
C Fix\sthe\sOR-optimization\sso\sthat\sit\salways\signores\ssubplans\sthat\sdo\snot\nuse\san\sindex.
|
C Enhance\sthe\sjson_insert(),\sjson_replace(),\sand\sjson_set()\sfunctions\swith\sthe\nability\sto\sadd\sJSON\sinstead\sof\stext\sif\sthe\sargument\sis\stext\sand\sif\sthe\sPATH\nbegins\swith\s'$$'\sinstead\sof\sjust\s'$'.
|
||||||
D 2015-08-27T23:18:55.309
|
D 2015-08-28T03:33:50.087
|
||||||
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
||||||
F Makefile.in e2218eb228374422969de7b1680eda6864affcef
|
F Makefile.in e2218eb228374422969de7b1680eda6864affcef
|
||||||
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
||||||
@ -192,7 +192,7 @@ F ext/misc/eval.c f971962e92ebb8b0a4e6b62949463ee454d88fa2
|
|||||||
F ext/misc/fileio.c d4171c815d6543a9edef8308aab2951413cd8d0f
|
F ext/misc/fileio.c d4171c815d6543a9edef8308aab2951413cd8d0f
|
||||||
F ext/misc/fuzzer.c 4c84635c71c26cfa7c2e5848cf49fe2d2cfcd767
|
F ext/misc/fuzzer.c 4c84635c71c26cfa7c2e5848cf49fe2d2cfcd767
|
||||||
F ext/misc/ieee754.c b0362167289170627659e84173f5d2e8fee8566e
|
F ext/misc/ieee754.c b0362167289170627659e84173f5d2e8fee8566e
|
||||||
F ext/misc/json1.c 541004e47235cefc2843ab03c100517452931913
|
F ext/misc/json1.c e0aeaa8b2f374d06ca19081afbd70b271731b130
|
||||||
F ext/misc/nextchar.c 35c8b8baacb96d92abbb34a83a997b797075b342
|
F ext/misc/nextchar.c 35c8b8baacb96d92abbb34a83a997b797075b342
|
||||||
F ext/misc/percentile.c bcbee3c061b884eccb80e21651daaae8e1e43c63
|
F ext/misc/percentile.c bcbee3c061b884eccb80e21651daaae8e1e43c63
|
||||||
F ext/misc/regexp.c af92cdaa5058fcec1451e49becc7ba44dba023dc
|
F ext/misc/regexp.c af92cdaa5058fcec1451e49becc7ba44dba023dc
|
||||||
@ -810,7 +810,7 @@ F test/journal3.test ff8af941f9e06161d3db1b46bb9f965ff0e7f307
|
|||||||
F test/jrnlmode.test 7864d59cf7f6e552b9b99ba0f38acd167edc10fa
|
F test/jrnlmode.test 7864d59cf7f6e552b9b99ba0f38acd167edc10fa
|
||||||
F test/jrnlmode2.test 81610545a4e6ed239ea8fa661891893385e23a1d
|
F test/jrnlmode2.test 81610545a4e6ed239ea8fa661891893385e23a1d
|
||||||
F test/jrnlmode3.test 556b447a05be0e0963f4311e95ab1632b11c9eaa
|
F test/jrnlmode3.test 556b447a05be0e0963f4311e95ab1632b11c9eaa
|
||||||
F test/json101.test 950ed4e8deb8ad4c10bd4fbc858eb54143de9867
|
F test/json101.test 5dfb181790c123123c8e7981d4d3c941b6cc8af4
|
||||||
F test/keyword1.test 37ef6bba5d2ed5b07ecdd6810571de2956599dff
|
F test/keyword1.test 37ef6bba5d2ed5b07ecdd6810571de2956599dff
|
||||||
F test/lastinsert.test 42e948fd6442f07d60acbd15d33fb86473e0ef63
|
F test/lastinsert.test 42e948fd6442f07d60acbd15d33fb86473e0ef63
|
||||||
F test/laststmtchanges.test ae613f53819206b3222771828d024154d51db200
|
F test/laststmtchanges.test ae613f53819206b3222771828d024154d51db200
|
||||||
@ -1380,7 +1380,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
|
|||||||
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
|
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
|
||||||
F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b
|
F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b
|
||||||
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
|
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
|
||||||
P cbc3c9a8bf169ae0b21f26855038502c6cc25cfe
|
P 66f92a16866e5825363636b9cc4b8f9b29d9e84d
|
||||||
R 3aef897e420a61a50263b8e461848e83
|
R 8075e39a7f0130f58ac8ab5ea1825d8f
|
||||||
U drh
|
U drh
|
||||||
Z b614bfef572643d9445d8b8a4d103409
|
Z 9db1096145751bb3222f3dab3f132c33
|
||||||
|
@ -1 +1 @@
|
|||||||
66f92a16866e5825363636b9cc4b8f9b29d9e84d
|
44f103d8862abc2d5613bac04dc2ea8e625b1f40
|
@ -50,5 +50,17 @@ do_catchsql_test json1-2.4 {
|
|||||||
SELECT json_object('a',1,'b',x'abcd');
|
SELECT json_object('a',1,'b',x'abcd');
|
||||||
} {1 {JSON cannot hold BLOB values}}
|
} {1 {JSON cannot hold BLOB values}}
|
||||||
|
|
||||||
|
do_execsql_test json1-3.1 {
|
||||||
|
SELECT json_replace('{"a":1,"b":2}','$.a','[3,4,5]');
|
||||||
|
} {{{"a":"[3,4,5]","b":2}}}
|
||||||
|
do_execsql_test json1-3.2 {
|
||||||
|
SELECT json_replace('{"a":1,"b":2}','$$.a','[3,4,5]');
|
||||||
|
} {{{"a":[3,4,5],"b":2}}}
|
||||||
|
do_execsql_test json1-3.3 {
|
||||||
|
SELECT json_type(json_set('{"a":1,"b":2}','$.b','{"x":3,"y":4}'),'$.b');
|
||||||
|
} {text}
|
||||||
|
do_execsql_test json1-3.4 {
|
||||||
|
SELECT json_type(json_set('{"a":1,"b":2}','$$.b','{"x":3,"y":4}'),'$.b');
|
||||||
|
} {object}
|
||||||
|
|
||||||
finish_test
|
finish_test
|
||||||
|
Loading…
Reference in New Issue
Block a user