#define JNODE_REMOVE 0x04 /* Do not output */
#define JNODE_REPLACE 0x08 /* Replace with JsonNode.iVal */
#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
*/
static void jsonAppendValue(
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) ){
case SQLITE_NULL: {
case SQLITE_TEXT: {
const char *z = (const char*)sqlite3_value_text(pValue);
u32 n = (u32)sqlite3_value_bytes(pValue);
- jsonAppendString(p, z, n);
+ if( textIsJson ){
+ jsonAppendRaw(p, z, n);
+ }else{
+ jsonAppendString(p, z, n);
+ }
break;
}
default: {
if( pNode[j].jnFlags & (JNODE_REMOVE|JNODE_REPLACE) ){
if( pNode[j].jnFlags & JNODE_REPLACE ){
jsonAppendSeparator(pOut);
- jsonAppendValue(pOut, aReplace[pNode[j].iVal]);
+ jsonAppendValue(pOut, aReplace[pNode[j].iVal],
+ (pNode[j].jnFlags & JNODE_JSON)!=0);
}
}else{
jsonAppendSeparator(pOut);
jsonRenderNode(&pNode[j], pOut, aReplace);
jsonAppendChar(pOut, ':');
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{
jsonRenderNode(&pNode[j+1], pOut, aReplace);
}
jsonAppendChar(&jx, '[');
for(i=0; i<argc; i++){
jsonAppendSeparator(&jx);
- jsonAppendValue(&jx, argv[i]);
+ jsonAppendValue(&jx, argv[i], 0);
}
jsonAppendChar(&jx, ']');
jsonResult(&jx);
n = (u32)sqlite3_value_bytes(argv[i]);
jsonAppendString(&jx, z, n);
jsonAppendChar(&jx, ':');
- jsonAppendValue(&jx, argv[i+1]);
+ jsonAppendValue(&jx, argv[i+1], 0);
}
jsonAppendChar(&jx, '}');
jsonResult(&jx);
if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
if( x.nNode ){
for(i=1; i<(u32)argc; i+=2){
+ u8 jnFlags = JNODE_REPLACE;
zPath = (const char*)sqlite3_value_text(argv[i]);
if( zPath==0 ) continue;
if( zPath[0]!='$' ) continue;
+ if( zPath[1]=='$' ){
+ zPath++;
+ jnFlags = JNODE_REPLACE|JNODE_JSON;
+ }
pNode = jsonLookup(&x, 0, &zPath[1], 0);
if( pNode ){
- pNode->jnFlags |= JNODE_REPLACE;
+ pNode->jnFlags &= ~JNODE_JSON;
+ pNode->jnFlags |= jnFlags;
pNode->iVal = i+1;
}
}
if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
if( x.nNode ){
for(i=1; i<(u32)argc; i+=2){
+ u8 jnFlags = JNODE_REPLACE;
zPath = (const char*)sqlite3_value_text(argv[i]);
if( zPath==0 ) continue;
if( zPath[0]!='$' ) continue;
+ if( zPath[1]=='$' ){
+ zPath++;
+ jnFlags = JNODE_REPLACE|JNODE_JSON;
+ }
bApnd = 0;
pNode = jsonLookup(&x, 0, &zPath[1], &bApnd);
if( x.oom ){
sqlite3_result_error_nomem(ctx);
goto jsonSetDone;
}else if( pNode && (bApnd || bIsSet) ){
- pNode->jnFlags |= JNODE_REPLACE;
+ pNode->jnFlags &= ~JNODE_JSON;
+ pNode->jnFlags |= jnFlags;
pNode->iVal = i+1;
}
}
-C Fix\sthe\sOR-optimization\sso\sthat\sit\salways\signores\ssubplans\sthat\sdo\snot\nuse\san\sindex.
-D 2015-08-27T23:18:55.309
+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-28T03:33:50.087
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in e2218eb228374422969de7b1680eda6864affcef
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
F ext/misc/fileio.c d4171c815d6543a9edef8308aab2951413cd8d0f
F ext/misc/fuzzer.c 4c84635c71c26cfa7c2e5848cf49fe2d2cfcd767
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/percentile.c bcbee3c061b884eccb80e21651daaae8e1e43c63
F ext/misc/regexp.c af92cdaa5058fcec1451e49becc7ba44dba023dc
F test/jrnlmode.test 7864d59cf7f6e552b9b99ba0f38acd167edc10fa
F test/jrnlmode2.test 81610545a4e6ed239ea8fa661891893385e23a1d
F test/jrnlmode3.test 556b447a05be0e0963f4311e95ab1632b11c9eaa
-F test/json101.test 950ed4e8deb8ad4c10bd4fbc858eb54143de9867
+F test/json101.test 5dfb181790c123123c8e7981d4d3c941b6cc8af4
F test/keyword1.test 37ef6bba5d2ed5b07ecdd6810571de2956599dff
F test/lastinsert.test 42e948fd6442f07d60acbd15d33fb86473e0ef63
F test/laststmtchanges.test ae613f53819206b3222771828d024154d51db200
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
-P cbc3c9a8bf169ae0b21f26855038502c6cc25cfe
-R 3aef897e420a61a50263b8e461848e83
+P 66f92a16866e5825363636b9cc4b8f9b29d9e84d
+R 8075e39a7f0130f58ac8ab5ea1825d8f
U drh
-Z b614bfef572643d9445d8b8a4d103409
+Z 9db1096145751bb3222f3dab3f132c33
SELECT json_object('a',1,'b',x'abcd');
} {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