]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Enhance the json_extract() function so that if given multiple PATH arguments
authordrh <drh@noemail.net>
Sat, 29 Aug 2015 19:41:45 +0000 (19:41 +0000)
committerdrh <drh@noemail.net>
Sat, 29 Aug 2015 19:41:45 +0000 (19:41 +0000)
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

ext/misc/json1.c
manifest
manifest.uuid

index aad5c57fdc2c3c72eb9ea1cc490ca647f44f8a7e..5df7551decbba9fa94eda82ad0bca1b0e2b8ed9a 100644 (file)
@@ -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; i<argc; i++){
+    zPath = (const char*)sqlite3_value_text(argv[i]);
+    pNode = jsonLookup(&x, zPath, 0, ctx, 0);
+    if( x.nErr ) break;
+    if( argc>2 ){
+      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        },
index 119ce7f47da4bc244ad95c536da65ca7ceb94381..cb2ed488589cc3abe38a247ead89132c5988601d 100644 (file)
--- 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
index d0eeda427c169025f35307c5ce712605a3d0d6a8..17d2b0dd8c4dc014b485020eb84a22f9d99cb184 100644 (file)
@@ -1 +1 @@
-2e8e239cec5a12ac81cf62c0fbe94fb5713c31b1
\ No newline at end of file
+1da60c3dda4254620052a83c853c2d2b6dd5009f
\ No newline at end of file