From a6f742e3ad9036a68ae0b6b09f89a077901d960e Mon Sep 17 00:00:00 2001 From: freestrings Date: Tue, 10 Mar 2020 23:22:35 +0900 Subject: [PATCH 1/4] =?UTF-8?q?=EB=8B=A4=EC=A4=91=ED=8C=A8=EC=8A=A4=20?= =?UTF-8?q?=ED=95=84=ED=84=B0=20=EC=95=88=EB=90=98=EB=8A=94=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/select/mod.rs | 21 ++++++++++++++++++++- tests/filter.rs | 16 ++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/src/select/mod.rs b/src/select/mod.rs index 142b973..13266e7 100644 --- a/src/select/mod.rs +++ b/src/select/mod.rs @@ -286,7 +286,26 @@ impl<'a> ExprTerm<'a> { if ret.is_empty() { ExprTerm::Bool(cmp_fn.default()) } else if let Some(rel) = rel { - ExprTerm::Json(Some(rel.to_vec()), None, ret) + if let ExprTerm::Json(_, _, _) = &other { + ExprTerm::Json(Some(rel.to_vec()), None, ret) + } else { + let mut tmp = Vec::new(); + for rel_value in rel { + match rel_value { + Value::Object(map) => { + for map_value in map.values() { + for result_value in &ret { + if map_value.eq(*result_value) { + tmp.push(*rel_value); + } + } + } + } + _ => {} + } + } + ExprTerm::Json(Some(tmp), None, ret) + } } else { ExprTerm::Json(None, None, ret) } diff --git a/tests/filter.rs b/tests/filter.rs index 249350f..c353231 100644 --- a/tests/filter.rs +++ b/tests/filter.rs @@ -126,6 +126,22 @@ fn filter_parent_exist_child() { ); } +#[test] +fn filter_parent_paths() { + setup(); + + select_and_then_compare( + "$[?(@.key.subKey == 'subKey2')]", + json!([ + {"key": {"seq": 1, "subKey": "subKey1"}}, + {"key": {"seq": 2, "subKey": "subKey2"}}, + {"key": 42}, + {"some": "value"} + ]), + json!([{"key": {"seq": 2, "subKey": "subKey2"}}]), + ); +} + #[test] fn bugs33_exist_in_all() { setup(); From d618e60e13f6c264851ae5702fb4fb14fe39f3e3 Mon Sep 17 00:00:00 2001 From: freestrings Date: Mon, 9 Mar 2020 22:56:47 +0900 Subject: [PATCH 2/4] Bracket notation not supported inside filter expression #38 --- src/select/mod.rs | 28 ++++++++++++++++++++++++++++ tests/filter.rs | 21 +++++++++++++++++++++ 2 files changed, 49 insertions(+) diff --git a/src/select/mod.rs b/src/select/mod.rs index 13266e7..b0c1c6f 100644 --- a/src/select/mod.rs +++ b/src/select/mod.rs @@ -884,6 +884,7 @@ impl<'a, 'b> Selector<'a, 'b> { self.current = Some(vec![v]); } } + fn visit_relative(&mut self) { if let Some(ParseToken::Array) = self.tokens.last() { let array_token = self.tokens.pop(); @@ -897,6 +898,18 @@ impl<'a, 'b> Selector<'a, 'b> { } fn visit_array_eof(&mut self) { + if self.is_nested_array() { + if let Some(Some(e)) = self.terms.pop() { + if let ExprTerm::String(key) = e { + self.next_in_filter_with_str(&key); + self.tokens.pop(); + return; + } + + self.terms.push(Some(e)); + } + } + if let Some(Some(e)) = self.terms.pop() { match e { ExprTerm::Number(n) => { @@ -944,6 +957,21 @@ impl<'a, 'b> Selector<'a, 'b> { } } + fn is_nested_array(&mut self) -> bool { + let mut is_nested_array = false; + + if let Some(t) = self.tokens.pop() { + if let ParseToken::Array = t { + if let Some(ParseToken::Array) = self.tokens.last() { + is_nested_array = true; + } + } + self.tokens.push(t); + } + + is_nested_array + } + fn visit_key(&mut self, key: &str) { if let Some(ParseToken::Array) = self.tokens.last() { self.terms.push(Some(ExprTerm::String(key.to_string()))); diff --git a/tests/filter.rs b/tests/filter.rs index c353231..6484144 100644 --- a/tests/filter.rs +++ b/tests/filter.rs @@ -223,4 +223,25 @@ fn bugs33_exist_right_in_all_with_and_condition() { } ]), ); +} + +#[test] +fn bugs38_array_notation_in_filter() { + setup(); + + select_and_then_compare( + "$[?(@['key']==42)]", + json!([ + {"key": 0}, + {"key": 42}, + {"key": -1}, + {"key": 41}, + {"key": 43}, + {"key": 42.0001}, + {"key": 41.9999}, + {"key": 100}, + {"some": "value"} + ]), + json!([{"key": 42}]), + ); } \ No newline at end of file From ef52c63bc8d49155b92e70bb17e052f918895a79 Mon Sep 17 00:00:00 2001 From: freestrings Date: Mon, 16 Mar 2020 00:50:51 +0900 Subject: [PATCH 3/4] Bracket notation not supported inside filter expression #38 - add unit test --- tests/filter.rs | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/tests/filter.rs b/tests/filter.rs index 6484144..c847dab 100644 --- a/tests/filter.rs +++ b/tests/filter.rs @@ -244,4 +244,37 @@ fn bugs38_array_notation_in_filter() { ]), json!([{"key": 42}]), ); + + select_and_then_compare( + "$[?(@['key'].subKey == 'subKey2')]", + json!([ + {"key": {"seq": 1, "subKey": "subKey1"}}, + {"key": {"seq": 2, "subKey": "subKey2"}}, + {"key": 42}, + {"some": "value"} + ]), + json!([{"key": {"seq": 2, "subKey": "subKey2"}}]), + ); + + select_and_then_compare( + "$[?(@['key']['subKey'] == 'subKey2')]", + json!([ + {"key": {"seq": 1, "subKey": "subKey1"}}, + {"key": {"seq": 2, "subKey": "subKey2"}}, + {"key": 42}, + {"some": "value"} + ]), + json!([{"key": {"seq": 2, "subKey": "subKey2"}}]), + ); + + select_and_then_compare( + "$..key[?(@['subKey'] == 'subKey2')]", + json!([ + {"key": {"seq": 1, "subKey": "subKey1"}}, + {"key": {"seq": 2, "subKey": "subKey2"}}, + {"key": 42}, + {"some": "value"} + ]), + json!([{"seq": 2, "subKey": "subKey2"}]), + ); } \ No newline at end of file From de46a661485638102dee4bc90d1c10d2178fdfa1 Mon Sep 17 00:00:00 2001 From: freestrings Date: Mon, 16 Mar 2020 00:55:42 +0900 Subject: [PATCH 4/4] Bracket notation not supported inside filter expression #38 - fix clippy error --- src/select/mod.rs | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/select/mod.rs b/src/select/mod.rs index b0c1c6f..1d297e2 100644 --- a/src/select/mod.rs +++ b/src/select/mod.rs @@ -291,17 +291,14 @@ impl<'a> ExprTerm<'a> { } else { let mut tmp = Vec::new(); for rel_value in rel { - match rel_value { - Value::Object(map) => { - for map_value in map.values() { - for result_value in &ret { - if map_value.eq(*result_value) { - tmp.push(*rel_value); - } + if let Value::Object(map) = rel_value { + for map_value in map.values() { + for result_value in &ret { + if map_value.eq(*result_value) { + tmp.push(*rel_value); } } } - _ => {} } } ExprTerm::Json(Some(tmp), None, ret)