From: drh Date: Sat, 29 Aug 2015 19:41:45 +0000 (+0000) Subject: Enhance the json_extract() function so that if given multiple PATH arguments X-Git-Tag: version-3.9.0~172 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=3ad93bba84bf191bfe75facd6680c4dfa4b3b827;p=thirdparty%2Fsqlite.git Enhance the json_extract() function so that if given multiple PATH arguments it will return a JSON array with all of the answers. Also update comments within the json1 extension to reflect stricter interpretation of JSON and PATH arguments. FossilOrigin-Name: 1da60c3dda4254620052a83c853c2d2b6dd5009f --- diff --git a/ext/misc/json1.c b/ext/misc/json1.c index aad5c57fdc..5df7551dec 100644 --- a/ext/misc/json1.c +++ b/ext/misc/json1.c @@ -1145,10 +1145,12 @@ static void jsonArrayLengthFunc( } /* -** json_extract(JSON, PATH) +** json_extract(JSON, PATH, ...) ** -** Return the element described by PATH. Return NULL if JSON is not -** valid JSON or if there is no PATH element or if PATH is malformed. +** Return the element described by PATH. Return NULL if there is no +** PATH element. If there are multiple PATHs, then return a JSON array +** with the result from each path. Throw an error if the JSON or any PATH +** is malformed. */ static void jsonExtractFunc( sqlite3_context *ctx, @@ -1158,13 +1160,33 @@ static void jsonExtractFunc( JsonParse x; /* The parse */ JsonNode *pNode; const char *zPath; - assert( argc==2 ); - zPath = (const char*)sqlite3_value_text(argv[1]); + JsonString jx; + int i; + + if( argc<2 ) return; if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return; - pNode = jsonLookup(&x, zPath, 0, ctx, 0); - if( pNode ){ - jsonReturn(pNode, ctx, 0); + jsonInit(&jx, ctx); + jsonAppendChar(&jx, '['); + for(i=1; i2 ){ + jsonAppendSeparator(&jx); + if( pNode ){ + jsonRenderNode(pNode, &jx, 0); + }else{ + jsonAppendRaw(&jx, "null", 4); + } + }else if( pNode ){ + jsonReturn(pNode, ctx, 0); + } + } + if( argc>2 && i==argc ){ + jsonAppendChar(&jx, ']'); + jsonResult(&jx); } + jsonReset(&jx); jsonParseReset(&x); } @@ -1211,9 +1233,8 @@ static void jsonObjectFunc( /* ** json_remove(JSON, PATH, ...) ** -** Remove the named elements from JSON and return the result. Ill-formed -** PATH arguments are silently ignored. If JSON is ill-formed, then NULL -** is returned. +** Remove the named elements from JSON and return the result. malformed +** JSON or PATH arguments result in an error. */ static void jsonRemoveFunc( sqlite3_context *ctx, @@ -1247,7 +1268,7 @@ remove_done: ** json_replace(JSON, PATH, VALUE, ...) ** ** Replace the value at PATH with VALUE. If PATH does not already exist, -** this routine is a no-op. If JSON is ill-formed, return NULL. +** this routine is a no-op. If JSON or PATH is malformed, throw an error. */ static void jsonReplaceFunc( sqlite3_context *ctx, @@ -1292,12 +1313,12 @@ replace_err: ** ** Set the value at PATH to VALUE. Create the PATH if it does not already ** exist. Overwrite existing values that do exist. -** If JSON is ill-formed, return NULL. +** If JSON or PATH is malformed, throw an error. ** ** json_insert(JSON, PATH, VALUE, ...) ** ** Create PATH and initialize it to VALUE. If PATH already exists, this -** routine is a no-op. If JSON is ill-formed, return NULL. +** routine is a no-op. If JSON or PATH is malformed, throw an error. */ static void jsonSetFunc( sqlite3_context *ctx, @@ -1348,8 +1369,8 @@ jsonSetDone: ** json_type(JSON) ** json_type(JSON, PATH) ** -** Return the top-level "type" of a JSON string. Return NULL if the -** input is not a well-formed JSON string. +** Return the top-level "type" of a JSON string. Throw an error if +** either the JSON or PATH inputs are not well-formed. */ static void jsonTypeFunc( sqlite3_context *ctx, @@ -1378,7 +1399,8 @@ static void jsonTypeFunc( /* ** json_valid(JSON) ** -** Return 1 if JSON is a valid JSON string. Return 0 otherwise. +** Return 1 if JSON is a well-formed JSON string according to RFC-7159. +** Return 0 otherwise. */ static void jsonValidFunc( sqlite3_context *ctx, @@ -1882,7 +1904,7 @@ int sqlite3_json_init( { "json_array", -1, 0, jsonArrayFunc }, { "json_array_length", 1, 0, jsonArrayLengthFunc }, { "json_array_length", 2, 0, jsonArrayLengthFunc }, - { "json_extract", 2, 0, jsonExtractFunc }, + { "json_extract", -1, 0, jsonExtractFunc }, { "json_insert", -1, 0, jsonSetFunc }, { "json_object", -1, 0, jsonObjectFunc }, { "json_remove", -1, 0, jsonRemoveFunc }, diff --git a/manifest b/manifest index 119ce7f47d..cb2ed48858 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Link\sthe\sjson1\sextension\sinto\sthe\scommand-line\sshell\sby\sdefault. -D 2015-08-29T19:03:33.633 +C Enhance\sthe\sjson_extract()\sfunction\sso\sthat\sif\sgiven\smultiple\sPATH\sarguments\nit\swill\sreturn\sa\sJSON\sarray\swith\sall\sof\sthe\sanswers.\s\sAlso\supdate\scomments\nwithin\sthe\sjson1\sextension\sto\sreflect\sstricter\sinterpretation\sof\sJSON\sand\sPATH\narguments. +D 2015-08-29T19:41:45.279 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in f85066ce844a28b671aaeeff320921cd0ce36239 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -192,7 +192,7 @@ F ext/misc/eval.c f971962e92ebb8b0a4e6b62949463ee454d88fa2 F ext/misc/fileio.c d4171c815d6543a9edef8308aab2951413cd8d0f F ext/misc/fuzzer.c 4c84635c71c26cfa7c2e5848cf49fe2d2cfcd767 F ext/misc/ieee754.c b0362167289170627659e84173f5d2e8fee8566e -F ext/misc/json1.c 5f39a87bf0697cca51e05a83cc5597a431d504de +F ext/misc/json1.c bd51e8c1e8ce580e6f21493bd8e94ed5aca3d777 F ext/misc/nextchar.c 35c8b8baacb96d92abbb34a83a997b797075b342 F ext/misc/percentile.c bcbee3c061b884eccb80e21651daaae8e1e43c63 F ext/misc/regexp.c af92cdaa5058fcec1451e49becc7ba44dba023dc @@ -1380,7 +1380,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P daff4832af963f98bcc1d2c2f84bd815d384f850 -R 082d6d0f70d8c030232efb6a589595f2 +P 2e8e239cec5a12ac81cf62c0fbe94fb5713c31b1 +R e2bf483acb1667e13821f8d776f13acb U drh -Z 988619e0978b399609ee7513adf0867a +Z ec66207700973851a4a5019af1bd75d1 diff --git a/manifest.uuid b/manifest.uuid index d0eeda427c..17d2b0dd8c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2e8e239cec5a12ac81cf62c0fbe94fb5713c31b1 \ No newline at end of file +1da60c3dda4254620052a83c853c2d2b6dd5009f \ No newline at end of file