diff --git a/core/json/json_path.rs b/core/json/json_path.rs index a4028311b..1a15aef9a 100644 --- a/core/json/json_path.rs +++ b/core/json/json_path.rs @@ -6,19 +6,24 @@ use pest_derive::Parser; #[grammar = "json/json_path.pest"] struct Parser; -#[derive(Clone, Debug, PartialEq)] -pub enum PathElement { - Root(), - Key(String), - ArrayLocator(i32), -} - +/// Describes a JSON path, which is a sequence of keys and/or array locators. #[derive(Debug)] pub struct JsonPath { pub elements: Vec, } -// Parses path into a Vec of Strings, where each string is a key or an array locator. +/// PathElement describes a single element of a JSON path. +#[derive(Clone, Debug, PartialEq)] +pub enum PathElement { + /// Root element: '$' + Root(), + /// JSON key + Key(String), + /// Array locator, eg. [2], [#-5] + ArrayLocator(i32), +} + +/// Parses path into a Vec of Strings, where each string is a key or an array locator. pub fn json_path(path: &str) -> crate::Result { let parsed = Parser::parse(Rule::path, path); diff --git a/core/json/mod.rs b/core/json/mod.rs index 0878378a3..9a38e1879 100644 --- a/core/json/mod.rs +++ b/core/json/mod.rs @@ -185,7 +185,7 @@ pub fn json_extract(value: &OwnedValue, paths: &[OwnedValue]) -> crate::Result 1 { - result.pop(); + result.pop(); // remove the final comma result.push(']'); } diff --git a/testing/json.test b/testing/json.test index a7e219915..39fce86de 100755 --- a/testing/json.test +++ b/testing/json.test @@ -113,6 +113,18 @@ do_execsql_test json_extract_number { SELECT json_extract(1, '$') } {{1}} +do_execsql_test json_extract_object_1 { + SELECT json_extract('{"a": [1,2,3]}', '$.a') +} {{[1,2,3]}} + +do_execsql_test json_extract_object_2 { + SELECT json_extract('{"a": [1,2,3]}', '$.a', '$.a[0]', '$.a[1]', '$.a[3]') +} {{[[1,2,3],1,2,null]}} + +do_execsql_test json_extract_object_3 { + SELECT json_extract('{"a": [1,2,3]}', '$.a', '$.a[0]', '$.a[1]', null, '$.a[3]') +} {{}} + # TODO: fix me # \x61 is the ASCII code for 'a' # do_execsql_test json_extract_with_escaping {