From 2e50d3c9ab9a639a1a51070b029269aa202a9edb Mon Sep 17 00:00:00 2001 From: Mateusz Gienieczko Date: Wed, 6 Sep 2023 19:26:37 +0100 Subject: [PATCH 1/4] chore: apply clippy --fix for nightly lints --- crates/rsonpath-benchmarks | 2 +- crates/rsonpath-lib/src/query/parser.rs | 8 ++++---- .../tests/classifier_correctness_tests.rs | 4 ++-- .../rsonpath-lib/tests/query_parser_tests.rs | 20 +++++++++---------- rsonpath.code-workspace | 4 ++++ 5 files changed, 21 insertions(+), 17 deletions(-) diff --git a/crates/rsonpath-benchmarks b/crates/rsonpath-benchmarks index 7798a29f..ec38b049 160000 --- a/crates/rsonpath-benchmarks +++ b/crates/rsonpath-benchmarks @@ -1 +1 @@ -Subproject commit 7798a29fb982d2c864c633fc6d7b627e0aa73918 +Subproject commit ec38b049318df487242a36b8060d075db26085af diff --git a/crates/rsonpath-lib/src/query/parser.rs b/crates/rsonpath-lib/src/query/parser.rs index 6de1347c..9d7ceba2 100644 --- a/crates/rsonpath-lib/src/query/parser.rs +++ b/crates/rsonpath-lib/src/query/parser.rs @@ -355,20 +355,20 @@ mod tests { #[test] fn single_quoted_member_should_not_unescape_backslashes() { - let input = r#"\\x"#; + let input = r"\\x"; let result = super::single_quoted_member()(input); - assert_eq!(result, Ok(("", r#"\\x"#.to_owned()))); + assert_eq!(result, Ok(("", r"\\x".to_owned()))); } #[test] fn double_quoted_member_should_not_unescape_backslashes() { - let input = r#"\\x"#; + let input = r"\\x"; let result = super::double_quoted_member()(input); - assert_eq!(result, Ok(("", r#"\\x"#.to_owned()))); + assert_eq!(result, Ok(("", r"\\x".to_owned()))); } #[test] diff --git a/crates/rsonpath-lib/tests/classifier_correctness_tests.rs b/crates/rsonpath-lib/tests/classifier_correctness_tests.rs index 2150ecd8..0b0bf487 100644 --- a/crates/rsonpath-lib/tests/classifier_correctness_tests.rs +++ b/crates/rsonpath-lib/tests/classifier_correctness_tests.rs @@ -144,7 +144,7 @@ mod prop_test { let escaped_string: String = value .chars() .map(|c| match c { - '\\' => String::from(r#"\\"#), + '\\' => String::from(r"\\"), '"' => String::from(r#"\""#), x => x.to_string(), }) @@ -187,7 +187,7 @@ mod prop_test { Just(Token::OpeningBracket), Just(Token::ClosingBrace), Just(Token::ClosingBracket), - r#"[ -!#-+\--9;-Z^-z|~]+"#.prop_map(Token::Garbage), // ascii characters except structural + r"[ -!#-+\--9;-Z^-z|~]+".prop_map(Token::Garbage), // ascii characters except structural "[ -~]".prop_map(|x| Token::Quoted(QuotedString::from(&x))) // all ascii characters ] } diff --git a/crates/rsonpath-lib/tests/query_parser_tests.rs b/crates/rsonpath-lib/tests/query_parser_tests.rs index 1172ec15..a3f49334 100644 --- a/crates/rsonpath-lib/tests/query_parser_tests.rs +++ b/crates/rsonpath-lib/tests/query_parser_tests.rs @@ -149,7 +149,7 @@ fn indexed_wildcard_descendant_selector_nested() { #[test] fn escaped_single_quote_in_single_quote_member() { - let input = r#"['\'']"#; + let input = r"['\'']"; let expected_query = JsonPathQueryBuilder::new().child(JsonString::new("'")).into(); let result = JsonPathQuery::parse(input).expect("expected Ok"); @@ -227,15 +227,15 @@ mod transform_json_escape_sequences_tests { #[test_case("" => ""; "empty is unchanged")] #[test_case("abc" => "abc")] - #[test_case(r#"['\n']"# => r#"['\n']"#; "endline is unchanged")] - #[test_case(r#"['\t']"# => r#"['\t']"#; "tab is unchanged")] - #[test_case(r#"['\\']"# => r#"['\\']"#; "backslash is unchanged")] - #[test_case(r#"['\'']"# => r#"[''']"#; "single quote is unescaped")] + #[test_case(r"['\n']" => r"['\n']"; "endline is unchanged")] + #[test_case(r"['\t']" => r"['\t']"; "tab is unchanged")] + #[test_case(r"['\\']" => r"['\\']"; "backslash is unchanged")] + #[test_case(r"['\'']" => r#"[''']"#; "single quote is unescaped")] #[test_case(r#"['"']"# => r#"['\"']"#; "unescaped double quote is escaped")] #[test_case(r#"['\"']"# => r#"['\"']"#; "escaped double quote is unchanged")] - #[test_case(r#"['\/']"# => r#"['/']"#; "slash is unescaped")] + #[test_case(r"['\/']" => r#"['/']"#; "slash is unescaped")] #[test_case(r#"['\\"']"# => r#"['\\\"']"#; "escapes don't flow")] - #[test_case(r#"['\\'']"# => r#"['\\'']"#; "escapes don't flow2")] + #[test_case(r"['\\'']" => r"['\\'']"; "escapes don't flow2")] fn cases(input: &str) -> String { super::transform_json_escape_sequences(input.to_owned()) } @@ -282,7 +282,7 @@ mod proptests { // .* or [*] fn any_wildcard_child() -> impl Strategy { - r#"(\.\*|\[\*\])"#.prop_map(|x| Selector { + r"(\.\*|\[\*\])".prop_map(|x| Selector { string: x, tag: SelectorTag::WildcardChild, }) @@ -290,7 +290,7 @@ mod proptests { // ..* or ..[*] fn any_wildcard_descendant() -> impl Strategy { - r#"(\*|\[\*\])"#.prop_map(|x| Selector { + r"(\*|\[\*\])".prop_map(|x| Selector { string: format!("..{x}"), tag: SelectorTag::WildcardDescendant, }) @@ -327,7 +327,7 @@ mod proptests { } fn any_member() -> impl Strategy { - r#"([A-Za-z]|_|[^\u0000-\u007F])([A-Za-z0-9]|_|[^\u0000-\u007F])*"# + r"([A-Za-z]|_|[^\u0000-\u007F])([A-Za-z0-9]|_|[^\u0000-\u007F])*" } fn any_name() -> impl Strategy { diff --git a/rsonpath.code-workspace b/rsonpath.code-workspace index c416a9e2..5789b481 100644 --- a/rsonpath.code-workspace +++ b/rsonpath.code-workspace @@ -82,6 +82,10 @@ "lldb.consoleMode": "commands", "rust-analyzer.cargo.features": "all", "rust-analyzer.linkedProjects": [ + "./crates/rsonpath/Cargo.toml", + "./crates/rsonpath-lib/Cargo.toml", + "./crates/rsonpath-benchmarks/Cargo.toml", + "./crates/rsonpath-test/Cargo.toml", "./crates/rsonpath-test-codegen/Cargo.toml" ] } From 70e76bd5b366042f9e6e4d920308b10f2a98932d Mon Sep 17 00:00:00 2001 From: Mateusz Gienieczko Date: Thu, 7 Sep 2023 20:33:07 +0100 Subject: [PATCH 2/4] fix: panic when head-skipping block boundary - Fixed an issue when head-skipping acceleration in nodes result mode would panic in very specific input circumstances, or if the input had really long JSON keys. Ref: #249 --- Justfile | 4 +- crates/rsonpath-lib/src/classification.rs | 66 ++- .../src/classification/memmem/avx2_64.rs | 3 + .../rsonpath-lib/src/classification/quotes.rs | 7 +- .../src/classification/quotes/nosimd.rs | 10 +- .../src/classification/quotes/shared.rs | 13 +- .../rsonpath-lib/src/engine/head_skipping.rs | 48 +- crates/rsonpath-lib/src/lib.rs | 2 +- .../tests/documents/toml/head_skip_long.toml | 54 ++ crates/rsonpath-lib/tests/end_to_end.rs | 503 +++++++++++++++++- 10 files changed, 648 insertions(+), 62 deletions(-) create mode 100644 crates/rsonpath-lib/tests/documents/toml/head_skip_long.toml diff --git a/Justfile b/Justfile index 3e292f52..6a9864eb 100644 --- a/Justfile +++ b/Justfile @@ -139,12 +139,12 @@ test-book: @add-test name: f=`echo {{name}} | sed s/-/_/g` && \ - cp ./crates/rsonpath-lib/tests/documents/toml/test-template-inline.toml ./crates/rsonpath-lib/tests/documents/toml/$f.toml && \ + cp ./crates/rsonpath-lib/tests/documents/toml/test_template_inline.toml ./crates/rsonpath-lib/tests/documents/toml/$f.toml && \ echo "Test template initialised at crates/rsonpath-lib/tests/documents/toml/$f.toml" @add-test-large name: f=`echo {{name}} | sed s/-/_/g` && \ - cp ./crates/rsonpath-lib/tests/documents/toml/test-template-large.toml ./crates/rsonpath-lib/tests/documents/toml/$f.toml && \ + cp ./crates/rsonpath-lib/tests/documents/toml/test_template_large.toml ./crates/rsonpath-lib/tests/documents/toml/$f.toml && \ echo "Test template initialised at crates/rsonpath-lib/tests/documents/toml/$f.toml" && \ echo "{}" > ./crates/rsonpath-lib/tests/documents/json/large/$f.json && \ echo "Put your large JSON document as contents of crates/rsonpath-lib/tests/documents/json/large/$f.json" diff --git a/crates/rsonpath-lib/src/classification.rs b/crates/rsonpath-lib/src/classification.rs index 71ccc952..a2bca799 100644 --- a/crates/rsonpath-lib/src/classification.rs +++ b/crates/rsonpath-lib/src/classification.rs @@ -46,8 +46,8 @@ //! let mut resume_state = structural_classifier.stop(); //! assert_eq!(resume_state.get_idx(), 5); //! -//! // Skip 6 bytes. -//! resume_state.offset_bytes(6); +//! // Skip to index 11. +//! resume_state.forward_to(11); //! assert_eq!(resume_state.get_idx(), 11); //! //! // Resume. @@ -113,42 +113,62 @@ where self.iter.get_offset() + self.block.as_ref().map_or(0, |b| b.idx) } - /// Move the state forward by `count` bytes. + /// Move the state forward to `index`. /// /// # Errors /// If the offset crosses block boundaries, then a new block is read from the underlying /// [`Input`](crate::input::Input) implementation, which can fail. /// /// # Panics - /// If the `count` is not positive. + /// If the `index` is not ahead of the current position of the state ([`get_idx`](ResumeClassifierState::get_idx)). #[inline] #[allow(clippy::panic_in_result_fn)] - pub fn offset_bytes(&mut self, count: isize) -> Result<(), InputError> { - assert!(count > 0); - let count = count as usize; + pub fn forward_to(&mut self, index: usize) -> Result<(), InputError> { + let current_block_start = self.iter.get_offset(); + let current_block_idx = self.block.as_ref().map_or(0, |b| b.idx); + let current_idx = current_block_start + current_block_idx; - let remaining_in_block = self.block.as_ref().map_or(0, |b| b.block.len() - b.idx); - - match self.block.as_mut() { - Some(b) if b.block.len() - b.idx > count => { - b.idx += count; - } - _ => { - let blocks_to_advance = (count - remaining_in_block) / N; + debug!( + "Calling forward_to({index}) when the inner iter offset is {} and block idx is {:?}", + current_block_start, current_block_idx + ); - let remainder = (self.block.as_ref().map_or(0, |b| b.idx) + count - blocks_to_advance * N) % N; + // We want to move by this much forward, and delta > 0. + assert!(index > current_idx); + let delta = index - current_idx; - self.iter.offset(blocks_to_advance as isize); - let next_block = self.iter.next()?; + // First we virtually pretend to move *backward*, setting the index of the current block to zero, + // and adjust the delta to cover that distance. This makes calculations simpler. + // Then we need to skip zero or more blocks and set our self.block to the last one we visit. + let remaining = delta + current_block_idx; + let blocks_to_skip = remaining / N; + let remainder = remaining % N; - self.block = next_block.map(|b| ResumeClassifierBlockState { - block: b, - idx: remainder, - }); + match self.block.as_mut() { + Some(b) if blocks_to_skip == 0 => { + b.idx = remaining; + } + Some(_) => { + self.block = self + .iter + .offset(blocks_to_skip as isize)? + .map(|b| ResumeClassifierBlockState { + block: b, + idx: remainder, + }); + } + None => { + self.block = self + .iter + .offset((blocks_to_skip + 1) as isize)? + .map(|b| ResumeClassifierBlockState { + block: b, + idx: remainder, + }); } } - debug!("offset_bytes({count}) results in idx moved to {}", self.get_idx()); + debug!("forward_to({index}) results in idx moved to {}", self.get_idx()); Ok(()) } diff --git a/crates/rsonpath-lib/src/classification/memmem/avx2_64.rs b/crates/rsonpath-lib/src/classification/memmem/avx2_64.rs index 57f49a6e..24196eb3 100644 --- a/crates/rsonpath-lib/src/classification/memmem/avx2_64.rs +++ b/crates/rsonpath-lib/src/classification/memmem/avx2_64.rs @@ -1,3 +1,5 @@ +use log::debug; + use super::{shared::mask_64, shared::vector_256, *}; use crate::{ classification::mask::m64, @@ -117,6 +119,7 @@ where label: &JsonString, ) -> Result)>, InputError> { if let Some(b) = first_block { + debug!("Looking at the first_block first..."); if let Some(res) = shared::find_label_in_first_block(self.input, b, start_idx, label)? { return Ok(Some(res)); } diff --git a/crates/rsonpath-lib/src/classification/quotes.rs b/crates/rsonpath-lib/src/classification/quotes.rs index d70e0ccc..ebe8ee7d 100644 --- a/crates/rsonpath-lib/src/classification/quotes.rs +++ b/crates/rsonpath-lib/src/classification/quotes.rs @@ -63,8 +63,11 @@ pub trait QuoteClassifiedIterator<'i, I: InputBlockIterator<'i, N>, M, const N: fn get_offset(&self) -> usize; /// Move the iterator `count` blocks forward. - /// Effectively skips `count * Twice::size()` bytes. - fn offset(&mut self, count: isize); + /// + /// # Errors + /// At least one new block is read from the underlying + /// [`InputBlockIterator`] implementation, which can fail. + fn offset(&mut self, count: isize) -> Result>, InputError>; /// Flip the bit representing whether the last block ended with a nonescaped quote. /// diff --git a/crates/rsonpath-lib/src/classification/quotes/nosimd.rs b/crates/rsonpath-lib/src/classification/quotes/nosimd.rs index db013e12..13eeca1e 100644 --- a/crates/rsonpath-lib/src/classification/quotes/nosimd.rs +++ b/crates/rsonpath-lib/src/classification/quotes/nosimd.rs @@ -107,15 +107,15 @@ where self.iter.get_offset() - N } - fn offset(&mut self, count: isize) { - debug_assert!(count >= 0); + fn offset(&mut self, count: isize) -> Result>, InputError> { + debug_assert!(count > 0); debug!("Offsetting by {count}"); - if count == 0 { - return; + for _ in 0..count - 1 { + self.iter.next()?; } - self.iter.offset(count); + self.next() } fn flip_quotes_bit(&mut self) { diff --git a/crates/rsonpath-lib/src/classification/quotes/shared.rs b/crates/rsonpath-lib/src/classification/quotes/shared.rs index 9273f781..b884e473 100644 --- a/crates/rsonpath-lib/src/classification/quotes/shared.rs +++ b/crates/rsonpath-lib/src/classification/quotes/shared.rs @@ -89,15 +89,18 @@ macro_rules! quote_classifier { self.iter.get_offset() - $size } - fn offset(&mut self, count: isize) { - debug_assert!(count >= 0); + fn offset( + &mut self, + count: isize, + ) -> Result>, InputError> { + debug_assert!(count > 0); debug!("Offsetting by {count}"); - if count == 0 { - return; + for _ in 0..count - 1 { + self.iter.next()?; } - self.iter.offset(count); + self.next() } fn flip_quotes_bit(&mut self) { diff --git a/crates/rsonpath-lib/src/engine/head_skipping.rs b/crates/rsonpath-lib/src/engine/head_skipping.rs index f78188a5..2c7b2156 100644 --- a/crates/rsonpath-lib/src/engine/head_skipping.rs +++ b/crates/rsonpath-lib/src/engine/head_skipping.rs @@ -12,7 +12,7 @@ use crate::{ debug, depth::Depth, engine::EngineError, - input::{Input, InputBlockIterator}, + input::Input, query::{ automaton::{Automaton, State}, JsonString, @@ -139,19 +139,10 @@ impl<'b, 'q, I: Input> HeadSkip<'b, 'q, I, BLOCK_SIZE> { .seek_non_whitespace_forward(colon_idx + 1)? .ok_or(EngineError::MissingItem())?; - // The goal is initializing the quote classifier correctly. - // We can do it as follows: - // - Initialize it to point to the start of the first block. - // - Now we need to move it to the next_idx. Calculate the offset from that point. - // - Offset by that much plus one. - let start_of_second_block = input_iter.get_offset(); - debug_assert!(start_of_second_block >= BLOCK_SIZE); - let start_of_first_block = start_of_second_block - BLOCK_SIZE; - let distance_to_colon = colon_idx - start_of_first_block; - let distance_to_value = next_idx - start_of_first_block - distance_to_colon; - let (quote_classifier, quote_classified_first_block) = resume_quote_classification(input_iter, first_block); + // Temporarily set the index within the current block to zero. + // This makes sense for the move below. let mut classifier_state = ResumeClassifierState { iter: quote_classifier, block: quote_classified_first_block @@ -163,26 +154,37 @@ impl<'b, 'q, I: Input> HeadSkip<'b, 'q, I, BLOCK_SIZE> { debug!("Actual match with colon at {colon_idx}"); debug!("Next significant character at {next_idx}"); debug!("Classifier is at {}", classifier_state.get_idx()); - debug!("We want to offset by {distance_to_colon} first, then by {distance_to_value}",); - - classifier_state.offset_bytes(distance_to_colon as isize)?; - - // Check if the colon is marked as within quotes. - // If yes, that is an error of state propagation through skipped blocks. - // Flip the quote mask. + debug!("We will forward to {colon_idx} first, then to {next_idx}",); + + // Now we want to move the entire iterator state so that the current block is quote-classified, + // and correctly points to the place the engine would expect had it found the matching key + // in the regular loop. If the value is atomic, we handle it ourselves. If the value is complex, + // the engine wants to start one byte *after* the opening character. + let resume_idx = if next_c == b'{' || next_c == b'[' { + next_idx + 1 + } else { + next_idx + }; + classifier_state.forward_to(resume_idx)?; + + // We now have the block where we want and we ran quote classification, but during the `forward_to` + // call we lose all the flow-through quote information that usually is passed from one block to the next. + // We need to manually verify the soundness of the classification. Fortunately: + // 1. we know that resume_idx is either the start of a value, or one byte after an opening - + // in a valid JSON this character can be within quotes if and only if it is itself a quote; + // 2. the only way the mask can be wrong is if it is flipped - marks chars within quotes + // as outside and vice versa - so it suffices to flip it if it is wrong. if let Some(block) = classifier_state.block.as_mut() { - if block.block.within_quotes_mask.is_lit(block.idx) { + let should_be_quoted = block.block.block[block.idx] == b'"'; + if block.block.within_quotes_mask.is_lit(block.idx) != should_be_quoted { debug!("Mask needs flipping!"); block.block.within_quotes_mask = !block.block.within_quotes_mask; classifier_state.iter.flip_quotes_bit(); } } - classifier_state.offset_bytes(distance_to_value as isize)?; - classifier_state = match next_c { b'{' | b'[' => { - classifier_state.offset_bytes(1)?; debug!("resuming"); if self.is_accepting { engine.recorder().record_match( diff --git a/crates/rsonpath-lib/src/lib.rs b/crates/rsonpath-lib/src/lib.rs index 8e3f2edf..8e4a7866 100644 --- a/crates/rsonpath-lib/src/lib.rs +++ b/crates/rsonpath-lib/src/lib.rs @@ -244,7 +244,7 @@ macro_rules! block { .map(|x| if x.is_ascii_whitespace() { b' ' } else { *x }) .collect::>() ) - .unwrap() + .unwrap_or("[INVALID UTF8]") ); }; } diff --git a/crates/rsonpath-lib/tests/documents/toml/head_skip_long.toml b/crates/rsonpath-lib/tests/documents/toml/head_skip_long.toml new file mode 100644 index 00000000..4ab6ce30 --- /dev/null +++ b/crates/rsonpath-lib/tests/documents/toml/head_skip_long.toml @@ -0,0 +1,54 @@ +# Define the JSON input for all query test cases. +[input] +# Short description of the input structure. +description = "Long labels to search with head skipping (issue #249)" +# Set to true only if your specific test input is fully compressed (no extraneous whitespace). +is_compressed = false + +# Inline JSON document. +[input.source] +json_string = ''' +{ + "target": { + "please note the important whitespaces after the upcoming comma (pretend indentation is really big)": 42 + }, + "target" : 43, + "very long label to search for, like, extremely long, so that the colon occurs really far away from the start of the needle match, which triggers some interesting behavior and might break the head skipping module like in #249": 44 +} +''' + +# Define queries to test on the input. +[[queries]] +# First scenario causing the #249 panic - label that is so long that it spans multiple blocks of input. +query = "$..['very long label to search for, like, extremely long, so that the colon occurs really far away from the start of the needle match, which triggers some interesting behavior and might break the head skipping module like in #249']" +# Short descritpion of the query semantics. +description = "select the extremely long label" + +[queries.results] +# Number of expected matches. +count = 1 +# Byte locations of starts of all matches, in order. +bytes = [428] +# Stringified values of all matches, verbatim as in the input, +# in the same order as above. +nodes = ['44'] + +[[queries]] +# Second scenario causing the #249 panic - extremely specific location of tokens, where +# the end of a subtree (the closing character) is exactly at the end of a block, +# the key being looked for is found in the next block, +# but whitespace cause the colon to occur in the next-next block. +# Trust me, it makes sense. +query = "$..target" +description = "select the label starting exactly at block boundary" + +[queries.results] +# Number of expected matches. +count = 2 +# Byte locations of starts of all matches, in order. +bytes = [14, 194] +# Stringified values of all matches, verbatim as in the input, +# in the same order as above. +nodes = ['''{ + "please note the important whitespaces after the upcoming comma (pretend indentation is really big)": 42 + }''', '43'] diff --git a/crates/rsonpath-lib/tests/end_to_end.rs b/crates/rsonpath-lib/tests/end_to_end.rs index eaa4d8da..506b9055 100644 --- a/crates/rsonpath-lib/tests/end_to_end.rs +++ b/crates/rsonpath-lib/tests/end_to_end.rs @@ -1,4 +1,4 @@ -// fc8d21b99a7454b201b4bff92524ec24 +// 5dc22515f57ed020ebfab849db867ac9 use pretty_assertions::assert_eq; use rsonpath::engine::{main::MainEngine, Compiler, Engine}; use rsonpath::input::*; @@ -10964,6 +10964,507 @@ fn list_with_nested_sublists_to_stress_output_ordering_with_query_select_all_sub Ok(()) } #[test] +fn long_labels_to_search_with_head_skipping_compressed_with_query_select_the_extremely_long_label_with_buffered_input_and_count_result_using_main_engine( +) -> Result<(), Box> { + println ! ("on document compressed/head_skip_long.toml running the query $..['very long label to search for, like, extremely long, so that the colon occurs really far away from the start of the needle match, which triggers some interesting behavior and might break the head skipping module like in #249'] (select the extremely long label) with Input impl BufferedInput and result mode CountResult"); + let jsonpath_query = JsonPathQuery :: parse ("$..['very long label to search for, like, extremely long, so that the colon occurs really far away from the start of the needle match, which triggers some interesting behavior and might break the head skipping module like in #249']") ? ; + let json_file = fs::File::open("../rsonpath-lib/tests/documents/json/compressed/head_skip_long.json")?; + let input = BufferedInput::new(json_file); + let engine = MainEngine::compile_query(&jsonpath_query)?; + let result = engine.count(&input)?; + assert_eq!(result, 1u64, "result != expected"); + Ok(()) +} +#[test] +fn long_labels_to_search_with_head_skipping_compressed_with_query_select_the_extremely_long_label_with_buffered_input_and_index_result_using_main_engine( +) -> Result<(), Box> { + println ! ("on document compressed/head_skip_long.toml running the query $..['very long label to search for, like, extremely long, so that the colon occurs really far away from the start of the needle match, which triggers some interesting behavior and might break the head skipping module like in #249'] (select the extremely long label) with Input impl BufferedInput and result mode IndexResult"); + let jsonpath_query = JsonPathQuery :: parse ("$..['very long label to search for, like, extremely long, so that the colon occurs really far away from the start of the needle match, which triggers some interesting behavior and might break the head skipping module like in #249']") ? ; + let json_file = fs::File::open("../rsonpath-lib/tests/documents/json/compressed/head_skip_long.json")?; + let input = BufferedInput::new(json_file); + let engine = MainEngine::compile_query(&jsonpath_query)?; + let mut result = vec![]; + engine.indices(&input, &mut result)?; + assert_eq!(result, vec![355usize,], "result != expected"); + Ok(()) +} +#[test] +fn long_labels_to_search_with_head_skipping_compressed_with_query_select_the_extremely_long_label_with_buffered_input_and_nodes_result_using_main_engine( +) -> Result<(), Box> { + println ! ("on document compressed/head_skip_long.toml running the query $..['very long label to search for, like, extremely long, so that the colon occurs really far away from the start of the needle match, which triggers some interesting behavior and might break the head skipping module like in #249'] (select the extremely long label) with Input impl BufferedInput and result mode NodesResult"); + let jsonpath_query = JsonPathQuery :: parse ("$..['very long label to search for, like, extremely long, so that the colon occurs really far away from the start of the needle match, which triggers some interesting behavior and might break the head skipping module like in #249']") ? ; + let json_file = fs::File::open("../rsonpath-lib/tests/documents/json/compressed/head_skip_long.json")?; + let input = BufferedInput::new(json_file); + let engine = MainEngine::compile_query(&jsonpath_query)?; + let mut result = vec![]; + engine.matches(&input, &mut result)?; + let utf8: Result, _> = result.iter().map(|x| str::from_utf8(&x.bytes)).collect(); + let utf8 = utf8.expect("valid utf8"); + let expected: Vec<&str> = vec!["44"]; + assert_eq!(utf8, expected, "result != expected"); + Ok(()) +} +#[test] +fn long_labels_to_search_with_head_skipping_compressed_with_query_select_the_extremely_long_label_with_mmap_input_and_count_result_using_main_engine( +) -> Result<(), Box> { + println ! ("on document compressed/head_skip_long.toml running the query $..['very long label to search for, like, extremely long, so that the colon occurs really far away from the start of the needle match, which triggers some interesting behavior and might break the head skipping module like in #249'] (select the extremely long label) with Input impl MmapInput and result mode CountResult"); + let jsonpath_query = JsonPathQuery :: parse ("$..['very long label to search for, like, extremely long, so that the colon occurs really far away from the start of the needle match, which triggers some interesting behavior and might break the head skipping module like in #249']") ? ; + let json_file = fs::File::open("../rsonpath-lib/tests/documents/json/compressed/head_skip_long.json")?; + let input = unsafe { MmapInput::map_file(&json_file)? }; + let engine = MainEngine::compile_query(&jsonpath_query)?; + let result = engine.count(&input)?; + assert_eq!(result, 1u64, "result != expected"); + Ok(()) +} +#[test] +fn long_labels_to_search_with_head_skipping_compressed_with_query_select_the_extremely_long_label_with_mmap_input_and_index_result_using_main_engine( +) -> Result<(), Box> { + println ! ("on document compressed/head_skip_long.toml running the query $..['very long label to search for, like, extremely long, so that the colon occurs really far away from the start of the needle match, which triggers some interesting behavior and might break the head skipping module like in #249'] (select the extremely long label) with Input impl MmapInput and result mode IndexResult"); + let jsonpath_query = JsonPathQuery :: parse ("$..['very long label to search for, like, extremely long, so that the colon occurs really far away from the start of the needle match, which triggers some interesting behavior and might break the head skipping module like in #249']") ? ; + let json_file = fs::File::open("../rsonpath-lib/tests/documents/json/compressed/head_skip_long.json")?; + let input = unsafe { MmapInput::map_file(&json_file)? }; + let engine = MainEngine::compile_query(&jsonpath_query)?; + let mut result = vec![]; + engine.indices(&input, &mut result)?; + assert_eq!(result, vec![355usize,], "result != expected"); + Ok(()) +} +#[test] +fn long_labels_to_search_with_head_skipping_compressed_with_query_select_the_extremely_long_label_with_mmap_input_and_nodes_result_using_main_engine( +) -> Result<(), Box> { + println ! ("on document compressed/head_skip_long.toml running the query $..['very long label to search for, like, extremely long, so that the colon occurs really far away from the start of the needle match, which triggers some interesting behavior and might break the head skipping module like in #249'] (select the extremely long label) with Input impl MmapInput and result mode NodesResult"); + let jsonpath_query = JsonPathQuery :: parse ("$..['very long label to search for, like, extremely long, so that the colon occurs really far away from the start of the needle match, which triggers some interesting behavior and might break the head skipping module like in #249']") ? ; + let json_file = fs::File::open("../rsonpath-lib/tests/documents/json/compressed/head_skip_long.json")?; + let input = unsafe { MmapInput::map_file(&json_file)? }; + let engine = MainEngine::compile_query(&jsonpath_query)?; + let mut result = vec![]; + engine.matches(&input, &mut result)?; + let utf8: Result, _> = result.iter().map(|x| str::from_utf8(&x.bytes)).collect(); + let utf8 = utf8.expect("valid utf8"); + let expected: Vec<&str> = vec!["44"]; + assert_eq!(utf8, expected, "result != expected"); + Ok(()) +} +#[test] +fn long_labels_to_search_with_head_skipping_compressed_with_query_select_the_extremely_long_label_with_owned_bytes_and_count_result_using_main_engine( +) -> Result<(), Box> { + println ! ("on document compressed/head_skip_long.toml running the query $..['very long label to search for, like, extremely long, so that the colon occurs really far away from the start of the needle match, which triggers some interesting behavior and might break the head skipping module like in #249'] (select the extremely long label) with Input impl OwnedBytes and result mode CountResult"); + let jsonpath_query = JsonPathQuery :: parse ("$..['very long label to search for, like, extremely long, so that the colon occurs really far away from the start of the needle match, which triggers some interesting behavior and might break the head skipping module like in #249']") ? ; + let raw_json = fs::read_to_string("../rsonpath-lib/tests/documents/json/compressed/head_skip_long.json")?; + let input = OwnedBytes::new(&raw_json.as_bytes())?; + let engine = MainEngine::compile_query(&jsonpath_query)?; + let result = engine.count(&input)?; + assert_eq!(result, 1u64, "result != expected"); + Ok(()) +} +#[test] +fn long_labels_to_search_with_head_skipping_compressed_with_query_select_the_extremely_long_label_with_owned_bytes_and_index_result_using_main_engine( +) -> Result<(), Box> { + println ! ("on document compressed/head_skip_long.toml running the query $..['very long label to search for, like, extremely long, so that the colon occurs really far away from the start of the needle match, which triggers some interesting behavior and might break the head skipping module like in #249'] (select the extremely long label) with Input impl OwnedBytes and result mode IndexResult"); + let jsonpath_query = JsonPathQuery :: parse ("$..['very long label to search for, like, extremely long, so that the colon occurs really far away from the start of the needle match, which triggers some interesting behavior and might break the head skipping module like in #249']") ? ; + let raw_json = fs::read_to_string("../rsonpath-lib/tests/documents/json/compressed/head_skip_long.json")?; + let input = OwnedBytes::new(&raw_json.as_bytes())?; + let engine = MainEngine::compile_query(&jsonpath_query)?; + let mut result = vec![]; + engine.indices(&input, &mut result)?; + assert_eq!(result, vec![355usize,], "result != expected"); + Ok(()) +} +#[test] +fn long_labels_to_search_with_head_skipping_compressed_with_query_select_the_extremely_long_label_with_owned_bytes_and_nodes_result_using_main_engine( +) -> Result<(), Box> { + println ! ("on document compressed/head_skip_long.toml running the query $..['very long label to search for, like, extremely long, so that the colon occurs really far away from the start of the needle match, which triggers some interesting behavior and might break the head skipping module like in #249'] (select the extremely long label) with Input impl OwnedBytes and result mode NodesResult"); + let jsonpath_query = JsonPathQuery :: parse ("$..['very long label to search for, like, extremely long, so that the colon occurs really far away from the start of the needle match, which triggers some interesting behavior and might break the head skipping module like in #249']") ? ; + let raw_json = fs::read_to_string("../rsonpath-lib/tests/documents/json/compressed/head_skip_long.json")?; + let input = OwnedBytes::new(&raw_json.as_bytes())?; + let engine = MainEngine::compile_query(&jsonpath_query)?; + let mut result = vec![]; + engine.matches(&input, &mut result)?; + let utf8: Result, _> = result.iter().map(|x| str::from_utf8(&x.bytes)).collect(); + let utf8 = utf8.expect("valid utf8"); + let expected: Vec<&str> = vec!["44"]; + assert_eq!(utf8, expected, "result != expected"); + Ok(()) +} +#[test] +fn long_labels_to_search_with_head_skipping_compressed_with_query_select_the_label_starting_exactly_at_block_boundary_with_buffered_input_and_count_result_using_main_engine( +) -> Result<(), Box> { + println ! ("on document compressed/head_skip_long.toml running the query $..target (select the label starting exactly at block boundary) with Input impl BufferedInput and result mode CountResult"); + let jsonpath_query = JsonPathQuery::parse("$..target")?; + let json_file = fs::File::open("../rsonpath-lib/tests/documents/json/compressed/head_skip_long.json")?; + let input = BufferedInput::new(json_file); + let engine = MainEngine::compile_query(&jsonpath_query)?; + let result = engine.count(&input)?; + assert_eq!(result, 2u64, "result != expected"); + Ok(()) +} +#[test] +fn long_labels_to_search_with_head_skipping_compressed_with_query_select_the_label_starting_exactly_at_block_boundary_with_buffered_input_and_index_result_using_main_engine( +) -> Result<(), Box> { + println ! ("on document compressed/head_skip_long.toml running the query $..target (select the label starting exactly at block boundary) with Input impl BufferedInput and result mode IndexResult"); + let jsonpath_query = JsonPathQuery::parse("$..target")?; + let json_file = fs::File::open("../rsonpath-lib/tests/documents/json/compressed/head_skip_long.json")?; + let input = BufferedInput::new(json_file); + let engine = MainEngine::compile_query(&jsonpath_query)?; + let mut result = vec![]; + engine.indices(&input, &mut result)?; + assert_eq!(result, vec![10usize, 125usize,], "result != expected"); + Ok(()) +} +#[test] +fn long_labels_to_search_with_head_skipping_compressed_with_query_select_the_label_starting_exactly_at_block_boundary_with_buffered_input_and_nodes_result_using_main_engine( +) -> Result<(), Box> { + println ! ("on document compressed/head_skip_long.toml running the query $..target (select the label starting exactly at block boundary) with Input impl BufferedInput and result mode NodesResult"); + let jsonpath_query = JsonPathQuery::parse("$..target")?; + let json_file = fs::File::open("../rsonpath-lib/tests/documents/json/compressed/head_skip_long.json")?; + let input = BufferedInput::new(json_file); + let engine = MainEngine::compile_query(&jsonpath_query)?; + let mut result = vec![]; + engine.matches(&input, &mut result)?; + let utf8: Result, _> = result.iter().map(|x| str::from_utf8(&x.bytes)).collect(); + let utf8 = utf8.expect("valid utf8"); + let expected: Vec<&str> = vec![ + "{\"please note the important whitespaces after the upcoming comma (pretend indentation is really big)\":42}", + "43", + ]; + assert_eq!(utf8, expected, "result != expected"); + Ok(()) +} +#[test] +fn long_labels_to_search_with_head_skipping_compressed_with_query_select_the_label_starting_exactly_at_block_boundary_with_mmap_input_and_count_result_using_main_engine( +) -> Result<(), Box> { + println ! ("on document compressed/head_skip_long.toml running the query $..target (select the label starting exactly at block boundary) with Input impl MmapInput and result mode CountResult"); + let jsonpath_query = JsonPathQuery::parse("$..target")?; + let json_file = fs::File::open("../rsonpath-lib/tests/documents/json/compressed/head_skip_long.json")?; + let input = unsafe { MmapInput::map_file(&json_file)? }; + let engine = MainEngine::compile_query(&jsonpath_query)?; + let result = engine.count(&input)?; + assert_eq!(result, 2u64, "result != expected"); + Ok(()) +} +#[test] +fn long_labels_to_search_with_head_skipping_compressed_with_query_select_the_label_starting_exactly_at_block_boundary_with_mmap_input_and_index_result_using_main_engine( +) -> Result<(), Box> { + println ! ("on document compressed/head_skip_long.toml running the query $..target (select the label starting exactly at block boundary) with Input impl MmapInput and result mode IndexResult"); + let jsonpath_query = JsonPathQuery::parse("$..target")?; + let json_file = fs::File::open("../rsonpath-lib/tests/documents/json/compressed/head_skip_long.json")?; + let input = unsafe { MmapInput::map_file(&json_file)? }; + let engine = MainEngine::compile_query(&jsonpath_query)?; + let mut result = vec![]; + engine.indices(&input, &mut result)?; + assert_eq!(result, vec![10usize, 125usize,], "result != expected"); + Ok(()) +} +#[test] +fn long_labels_to_search_with_head_skipping_compressed_with_query_select_the_label_starting_exactly_at_block_boundary_with_mmap_input_and_nodes_result_using_main_engine( +) -> Result<(), Box> { + println ! ("on document compressed/head_skip_long.toml running the query $..target (select the label starting exactly at block boundary) with Input impl MmapInput and result mode NodesResult"); + let jsonpath_query = JsonPathQuery::parse("$..target")?; + let json_file = fs::File::open("../rsonpath-lib/tests/documents/json/compressed/head_skip_long.json")?; + let input = unsafe { MmapInput::map_file(&json_file)? }; + let engine = MainEngine::compile_query(&jsonpath_query)?; + let mut result = vec![]; + engine.matches(&input, &mut result)?; + let utf8: Result, _> = result.iter().map(|x| str::from_utf8(&x.bytes)).collect(); + let utf8 = utf8.expect("valid utf8"); + let expected: Vec<&str> = vec![ + "{\"please note the important whitespaces after the upcoming comma (pretend indentation is really big)\":42}", + "43", + ]; + assert_eq!(utf8, expected, "result != expected"); + Ok(()) +} +#[test] +fn long_labels_to_search_with_head_skipping_compressed_with_query_select_the_label_starting_exactly_at_block_boundary_with_owned_bytes_and_count_result_using_main_engine( +) -> Result<(), Box> { + println ! ("on document compressed/head_skip_long.toml running the query $..target (select the label starting exactly at block boundary) with Input impl OwnedBytes and result mode CountResult"); + let jsonpath_query = JsonPathQuery::parse("$..target")?; + let raw_json = fs::read_to_string("../rsonpath-lib/tests/documents/json/compressed/head_skip_long.json")?; + let input = OwnedBytes::new(&raw_json.as_bytes())?; + let engine = MainEngine::compile_query(&jsonpath_query)?; + let result = engine.count(&input)?; + assert_eq!(result, 2u64, "result != expected"); + Ok(()) +} +#[test] +fn long_labels_to_search_with_head_skipping_compressed_with_query_select_the_label_starting_exactly_at_block_boundary_with_owned_bytes_and_index_result_using_main_engine( +) -> Result<(), Box> { + println ! ("on document compressed/head_skip_long.toml running the query $..target (select the label starting exactly at block boundary) with Input impl OwnedBytes and result mode IndexResult"); + let jsonpath_query = JsonPathQuery::parse("$..target")?; + let raw_json = fs::read_to_string("../rsonpath-lib/tests/documents/json/compressed/head_skip_long.json")?; + let input = OwnedBytes::new(&raw_json.as_bytes())?; + let engine = MainEngine::compile_query(&jsonpath_query)?; + let mut result = vec![]; + engine.indices(&input, &mut result)?; + assert_eq!(result, vec![10usize, 125usize,], "result != expected"); + Ok(()) +} +#[test] +fn long_labels_to_search_with_head_skipping_compressed_with_query_select_the_label_starting_exactly_at_block_boundary_with_owned_bytes_and_nodes_result_using_main_engine( +) -> Result<(), Box> { + println ! ("on document compressed/head_skip_long.toml running the query $..target (select the label starting exactly at block boundary) with Input impl OwnedBytes and result mode NodesResult"); + let jsonpath_query = JsonPathQuery::parse("$..target")?; + let raw_json = fs::read_to_string("../rsonpath-lib/tests/documents/json/compressed/head_skip_long.json")?; + let input = OwnedBytes::new(&raw_json.as_bytes())?; + let engine = MainEngine::compile_query(&jsonpath_query)?; + let mut result = vec![]; + engine.matches(&input, &mut result)?; + let utf8: Result, _> = result.iter().map(|x| str::from_utf8(&x.bytes)).collect(); + let utf8 = utf8.expect("valid utf8"); + let expected: Vec<&str> = vec![ + "{\"please note the important whitespaces after the upcoming comma (pretend indentation is really big)\":42}", + "43", + ]; + assert_eq!(utf8, expected, "result != expected"); + Ok(()) +} +#[test] +fn long_labels_to_search_with_head_skipping_with_query_select_the_extremely_long_label_with_buffered_input_and_count_result_using_main_engine( +) -> Result<(), Box> { + println ! ("on document head_skip_long.toml running the query $..['very long label to search for, like, extremely long, so that the colon occurs really far away from the start of the needle match, which triggers some interesting behavior and might break the head skipping module like in #249'] (select the extremely long label) with Input impl BufferedInput and result mode CountResult"); + let jsonpath_query = JsonPathQuery :: parse ("$..['very long label to search for, like, extremely long, so that the colon occurs really far away from the start of the needle match, which triggers some interesting behavior and might break the head skipping module like in #249']") ? ; + let json_file = fs::File::open("../rsonpath-lib/tests/documents/json/head_skip_long.json")?; + let input = BufferedInput::new(json_file); + let engine = MainEngine::compile_query(&jsonpath_query)?; + let result = engine.count(&input)?; + assert_eq!(result, 1u64, "result != expected"); + Ok(()) +} +#[test] +fn long_labels_to_search_with_head_skipping_with_query_select_the_extremely_long_label_with_buffered_input_and_index_result_using_main_engine( +) -> Result<(), Box> { + println ! ("on document head_skip_long.toml running the query $..['very long label to search for, like, extremely long, so that the colon occurs really far away from the start of the needle match, which triggers some interesting behavior and might break the head skipping module like in #249'] (select the extremely long label) with Input impl BufferedInput and result mode IndexResult"); + let jsonpath_query = JsonPathQuery :: parse ("$..['very long label to search for, like, extremely long, so that the colon occurs really far away from the start of the needle match, which triggers some interesting behavior and might break the head skipping module like in #249']") ? ; + let json_file = fs::File::open("../rsonpath-lib/tests/documents/json/head_skip_long.json")?; + let input = BufferedInput::new(json_file); + let engine = MainEngine::compile_query(&jsonpath_query)?; + let mut result = vec![]; + engine.indices(&input, &mut result)?; + assert_eq!(result, vec![428usize,], "result != expected"); + Ok(()) +} +#[test] +fn long_labels_to_search_with_head_skipping_with_query_select_the_extremely_long_label_with_buffered_input_and_nodes_result_using_main_engine( +) -> Result<(), Box> { + println ! ("on document head_skip_long.toml running the query $..['very long label to search for, like, extremely long, so that the colon occurs really far away from the start of the needle match, which triggers some interesting behavior and might break the head skipping module like in #249'] (select the extremely long label) with Input impl BufferedInput and result mode NodesResult"); + let jsonpath_query = JsonPathQuery :: parse ("$..['very long label to search for, like, extremely long, so that the colon occurs really far away from the start of the needle match, which triggers some interesting behavior and might break the head skipping module like in #249']") ? ; + let json_file = fs::File::open("../rsonpath-lib/tests/documents/json/head_skip_long.json")?; + let input = BufferedInput::new(json_file); + let engine = MainEngine::compile_query(&jsonpath_query)?; + let mut result = vec![]; + engine.matches(&input, &mut result)?; + let utf8: Result, _> = result.iter().map(|x| str::from_utf8(&x.bytes)).collect(); + let utf8 = utf8.expect("valid utf8"); + let expected: Vec<&str> = vec!["44"]; + assert_eq!(utf8, expected, "result != expected"); + Ok(()) +} +#[test] +fn long_labels_to_search_with_head_skipping_with_query_select_the_extremely_long_label_with_mmap_input_and_count_result_using_main_engine( +) -> Result<(), Box> { + println ! ("on document head_skip_long.toml running the query $..['very long label to search for, like, extremely long, so that the colon occurs really far away from the start of the needle match, which triggers some interesting behavior and might break the head skipping module like in #249'] (select the extremely long label) with Input impl MmapInput and result mode CountResult"); + let jsonpath_query = JsonPathQuery :: parse ("$..['very long label to search for, like, extremely long, so that the colon occurs really far away from the start of the needle match, which triggers some interesting behavior and might break the head skipping module like in #249']") ? ; + let json_file = fs::File::open("../rsonpath-lib/tests/documents/json/head_skip_long.json")?; + let input = unsafe { MmapInput::map_file(&json_file)? }; + let engine = MainEngine::compile_query(&jsonpath_query)?; + let result = engine.count(&input)?; + assert_eq!(result, 1u64, "result != expected"); + Ok(()) +} +#[test] +fn long_labels_to_search_with_head_skipping_with_query_select_the_extremely_long_label_with_mmap_input_and_index_result_using_main_engine( +) -> Result<(), Box> { + println ! ("on document head_skip_long.toml running the query $..['very long label to search for, like, extremely long, so that the colon occurs really far away from the start of the needle match, which triggers some interesting behavior and might break the head skipping module like in #249'] (select the extremely long label) with Input impl MmapInput and result mode IndexResult"); + let jsonpath_query = JsonPathQuery :: parse ("$..['very long label to search for, like, extremely long, so that the colon occurs really far away from the start of the needle match, which triggers some interesting behavior and might break the head skipping module like in #249']") ? ; + let json_file = fs::File::open("../rsonpath-lib/tests/documents/json/head_skip_long.json")?; + let input = unsafe { MmapInput::map_file(&json_file)? }; + let engine = MainEngine::compile_query(&jsonpath_query)?; + let mut result = vec![]; + engine.indices(&input, &mut result)?; + assert_eq!(result, vec![428usize,], "result != expected"); + Ok(()) +} +#[test] +fn long_labels_to_search_with_head_skipping_with_query_select_the_extremely_long_label_with_mmap_input_and_nodes_result_using_main_engine( +) -> Result<(), Box> { + println ! ("on document head_skip_long.toml running the query $..['very long label to search for, like, extremely long, so that the colon occurs really far away from the start of the needle match, which triggers some interesting behavior and might break the head skipping module like in #249'] (select the extremely long label) with Input impl MmapInput and result mode NodesResult"); + let jsonpath_query = JsonPathQuery :: parse ("$..['very long label to search for, like, extremely long, so that the colon occurs really far away from the start of the needle match, which triggers some interesting behavior and might break the head skipping module like in #249']") ? ; + let json_file = fs::File::open("../rsonpath-lib/tests/documents/json/head_skip_long.json")?; + let input = unsafe { MmapInput::map_file(&json_file)? }; + let engine = MainEngine::compile_query(&jsonpath_query)?; + let mut result = vec![]; + engine.matches(&input, &mut result)?; + let utf8: Result, _> = result.iter().map(|x| str::from_utf8(&x.bytes)).collect(); + let utf8 = utf8.expect("valid utf8"); + let expected: Vec<&str> = vec!["44"]; + assert_eq!(utf8, expected, "result != expected"); + Ok(()) +} +#[test] +fn long_labels_to_search_with_head_skipping_with_query_select_the_extremely_long_label_with_owned_bytes_and_count_result_using_main_engine( +) -> Result<(), Box> { + println ! ("on document head_skip_long.toml running the query $..['very long label to search for, like, extremely long, so that the colon occurs really far away from the start of the needle match, which triggers some interesting behavior and might break the head skipping module like in #249'] (select the extremely long label) with Input impl OwnedBytes and result mode CountResult"); + let jsonpath_query = JsonPathQuery :: parse ("$..['very long label to search for, like, extremely long, so that the colon occurs really far away from the start of the needle match, which triggers some interesting behavior and might break the head skipping module like in #249']") ? ; + let raw_json = fs::read_to_string("../rsonpath-lib/tests/documents/json/head_skip_long.json")?; + let input = OwnedBytes::new(&raw_json.as_bytes())?; + let engine = MainEngine::compile_query(&jsonpath_query)?; + let result = engine.count(&input)?; + assert_eq!(result, 1u64, "result != expected"); + Ok(()) +} +#[test] +fn long_labels_to_search_with_head_skipping_with_query_select_the_extremely_long_label_with_owned_bytes_and_index_result_using_main_engine( +) -> Result<(), Box> { + println ! ("on document head_skip_long.toml running the query $..['very long label to search for, like, extremely long, so that the colon occurs really far away from the start of the needle match, which triggers some interesting behavior and might break the head skipping module like in #249'] (select the extremely long label) with Input impl OwnedBytes and result mode IndexResult"); + let jsonpath_query = JsonPathQuery :: parse ("$..['very long label to search for, like, extremely long, so that the colon occurs really far away from the start of the needle match, which triggers some interesting behavior and might break the head skipping module like in #249']") ? ; + let raw_json = fs::read_to_string("../rsonpath-lib/tests/documents/json/head_skip_long.json")?; + let input = OwnedBytes::new(&raw_json.as_bytes())?; + let engine = MainEngine::compile_query(&jsonpath_query)?; + let mut result = vec![]; + engine.indices(&input, &mut result)?; + assert_eq!(result, vec![428usize,], "result != expected"); + Ok(()) +} +#[test] +fn long_labels_to_search_with_head_skipping_with_query_select_the_extremely_long_label_with_owned_bytes_and_nodes_result_using_main_engine( +) -> Result<(), Box> { + println ! ("on document head_skip_long.toml running the query $..['very long label to search for, like, extremely long, so that the colon occurs really far away from the start of the needle match, which triggers some interesting behavior and might break the head skipping module like in #249'] (select the extremely long label) with Input impl OwnedBytes and result mode NodesResult"); + let jsonpath_query = JsonPathQuery :: parse ("$..['very long label to search for, like, extremely long, so that the colon occurs really far away from the start of the needle match, which triggers some interesting behavior and might break the head skipping module like in #249']") ? ; + let raw_json = fs::read_to_string("../rsonpath-lib/tests/documents/json/head_skip_long.json")?; + let input = OwnedBytes::new(&raw_json.as_bytes())?; + let engine = MainEngine::compile_query(&jsonpath_query)?; + let mut result = vec![]; + engine.matches(&input, &mut result)?; + let utf8: Result, _> = result.iter().map(|x| str::from_utf8(&x.bytes)).collect(); + let utf8 = utf8.expect("valid utf8"); + let expected: Vec<&str> = vec!["44"]; + assert_eq!(utf8, expected, "result != expected"); + Ok(()) +} +#[test] +fn long_labels_to_search_with_head_skipping_with_query_select_the_label_starting_exactly_at_block_boundary_with_buffered_input_and_count_result_using_main_engine( +) -> Result<(), Box> { + println ! ("on document head_skip_long.toml running the query $..target (select the label starting exactly at block boundary) with Input impl BufferedInput and result mode CountResult"); + let jsonpath_query = JsonPathQuery::parse("$..target")?; + let json_file = fs::File::open("../rsonpath-lib/tests/documents/json/head_skip_long.json")?; + let input = BufferedInput::new(json_file); + let engine = MainEngine::compile_query(&jsonpath_query)?; + let result = engine.count(&input)?; + assert_eq!(result, 2u64, "result != expected"); + Ok(()) +} +#[test] +fn long_labels_to_search_with_head_skipping_with_query_select_the_label_starting_exactly_at_block_boundary_with_buffered_input_and_index_result_using_main_engine( +) -> Result<(), Box> { + println ! ("on document head_skip_long.toml running the query $..target (select the label starting exactly at block boundary) with Input impl BufferedInput and result mode IndexResult"); + let jsonpath_query = JsonPathQuery::parse("$..target")?; + let json_file = fs::File::open("../rsonpath-lib/tests/documents/json/head_skip_long.json")?; + let input = BufferedInput::new(json_file); + let engine = MainEngine::compile_query(&jsonpath_query)?; + let mut result = vec![]; + engine.indices(&input, &mut result)?; + assert_eq!(result, vec![14usize, 194usize,], "result != expected"); + Ok(()) +} +#[test] +fn long_labels_to_search_with_head_skipping_with_query_select_the_label_starting_exactly_at_block_boundary_with_buffered_input_and_nodes_result_using_main_engine( +) -> Result<(), Box> { + println ! ("on document head_skip_long.toml running the query $..target (select the label starting exactly at block boundary) with Input impl BufferedInput and result mode NodesResult"); + let jsonpath_query = JsonPathQuery::parse("$..target")?; + let json_file = fs::File::open("../rsonpath-lib/tests/documents/json/head_skip_long.json")?; + let input = BufferedInput::new(json_file); + let engine = MainEngine::compile_query(&jsonpath_query)?; + let mut result = vec![]; + engine.matches(&input, &mut result)?; + let utf8: Result, _> = result.iter().map(|x| str::from_utf8(&x.bytes)).collect(); + let utf8 = utf8.expect("valid utf8"); + let expected : Vec < & str > = vec ! ["{\n \"please note the important whitespaces after the upcoming comma (pretend indentation is really big)\": 42\n }" , "43" ,] ; + assert_eq!(utf8, expected, "result != expected"); + Ok(()) +} +#[test] +fn long_labels_to_search_with_head_skipping_with_query_select_the_label_starting_exactly_at_block_boundary_with_mmap_input_and_count_result_using_main_engine( +) -> Result<(), Box> { + println ! ("on document head_skip_long.toml running the query $..target (select the label starting exactly at block boundary) with Input impl MmapInput and result mode CountResult"); + let jsonpath_query = JsonPathQuery::parse("$..target")?; + let json_file = fs::File::open("../rsonpath-lib/tests/documents/json/head_skip_long.json")?; + let input = unsafe { MmapInput::map_file(&json_file)? }; + let engine = MainEngine::compile_query(&jsonpath_query)?; + let result = engine.count(&input)?; + assert_eq!(result, 2u64, "result != expected"); + Ok(()) +} +#[test] +fn long_labels_to_search_with_head_skipping_with_query_select_the_label_starting_exactly_at_block_boundary_with_mmap_input_and_index_result_using_main_engine( +) -> Result<(), Box> { + println ! ("on document head_skip_long.toml running the query $..target (select the label starting exactly at block boundary) with Input impl MmapInput and result mode IndexResult"); + let jsonpath_query = JsonPathQuery::parse("$..target")?; + let json_file = fs::File::open("../rsonpath-lib/tests/documents/json/head_skip_long.json")?; + let input = unsafe { MmapInput::map_file(&json_file)? }; + let engine = MainEngine::compile_query(&jsonpath_query)?; + let mut result = vec![]; + engine.indices(&input, &mut result)?; + assert_eq!(result, vec![14usize, 194usize,], "result != expected"); + Ok(()) +} +#[test] +fn long_labels_to_search_with_head_skipping_with_query_select_the_label_starting_exactly_at_block_boundary_with_mmap_input_and_nodes_result_using_main_engine( +) -> Result<(), Box> { + println ! ("on document head_skip_long.toml running the query $..target (select the label starting exactly at block boundary) with Input impl MmapInput and result mode NodesResult"); + let jsonpath_query = JsonPathQuery::parse("$..target")?; + let json_file = fs::File::open("../rsonpath-lib/tests/documents/json/head_skip_long.json")?; + let input = unsafe { MmapInput::map_file(&json_file)? }; + let engine = MainEngine::compile_query(&jsonpath_query)?; + let mut result = vec![]; + engine.matches(&input, &mut result)?; + let utf8: Result, _> = result.iter().map(|x| str::from_utf8(&x.bytes)).collect(); + let utf8 = utf8.expect("valid utf8"); + let expected : Vec < & str > = vec ! ["{\n \"please note the important whitespaces after the upcoming comma (pretend indentation is really big)\": 42\n }" , "43" ,] ; + assert_eq!(utf8, expected, "result != expected"); + Ok(()) +} +#[test] +fn long_labels_to_search_with_head_skipping_with_query_select_the_label_starting_exactly_at_block_boundary_with_owned_bytes_and_count_result_using_main_engine( +) -> Result<(), Box> { + println ! ("on document head_skip_long.toml running the query $..target (select the label starting exactly at block boundary) with Input impl OwnedBytes and result mode CountResult"); + let jsonpath_query = JsonPathQuery::parse("$..target")?; + let raw_json = fs::read_to_string("../rsonpath-lib/tests/documents/json/head_skip_long.json")?; + let input = OwnedBytes::new(&raw_json.as_bytes())?; + let engine = MainEngine::compile_query(&jsonpath_query)?; + let result = engine.count(&input)?; + assert_eq!(result, 2u64, "result != expected"); + Ok(()) +} +#[test] +fn long_labels_to_search_with_head_skipping_with_query_select_the_label_starting_exactly_at_block_boundary_with_owned_bytes_and_index_result_using_main_engine( +) -> Result<(), Box> { + println ! ("on document head_skip_long.toml running the query $..target (select the label starting exactly at block boundary) with Input impl OwnedBytes and result mode IndexResult"); + let jsonpath_query = JsonPathQuery::parse("$..target")?; + let raw_json = fs::read_to_string("../rsonpath-lib/tests/documents/json/head_skip_long.json")?; + let input = OwnedBytes::new(&raw_json.as_bytes())?; + let engine = MainEngine::compile_query(&jsonpath_query)?; + let mut result = vec![]; + engine.indices(&input, &mut result)?; + assert_eq!(result, vec![14usize, 194usize,], "result != expected"); + Ok(()) +} +#[test] +fn long_labels_to_search_with_head_skipping_with_query_select_the_label_starting_exactly_at_block_boundary_with_owned_bytes_and_nodes_result_using_main_engine( +) -> Result<(), Box> { + println ! ("on document head_skip_long.toml running the query $..target (select the label starting exactly at block boundary) with Input impl OwnedBytes and result mode NodesResult"); + let jsonpath_query = JsonPathQuery::parse("$..target")?; + let raw_json = fs::read_to_string("../rsonpath-lib/tests/documents/json/head_skip_long.json")?; + let input = OwnedBytes::new(&raw_json.as_bytes())?; + let engine = MainEngine::compile_query(&jsonpath_query)?; + let mut result = vec![]; + engine.matches(&input, &mut result)?; + let utf8: Result, _> = result.iter().map(|x| str::from_utf8(&x.bytes)).collect(); + let utf8 = utf8.expect("valid utf8"); + let expected : Vec < & str > = vec ! ["{\n \"please note the important whitespaces after the upcoming comma (pretend indentation is really big)\": 42\n }" , "43" ,] ; + assert_eq!(utf8, expected, "result != expected"); + Ok(()) +} +#[test] fn members_with_escaped_double_quotes_and_braces_and_brackets_compressed_with_query_select_label_with_one_actual_backslash_which_is_two_backslashes_in_the_query_with_buffered_input_and_count_result_using_main_engine( ) -> Result<(), Box> { println ! ("on document compressed/escapes.toml running the query $..a..b..['label\\\\'] (select label with one actual backslash, which is two backslashes in the query) with Input impl BufferedInput and result mode CountResult"); From 70d647a07307d85e24da48ab25146131c31b29e8 Mon Sep 17 00:00:00 2001 From: Mateusz Gienieczko Date: Sat, 9 Sep 2023 02:27:02 +0100 Subject: [PATCH 3/4] chore: fix invalid log statement --- .../src/classification/memmem/avx2_64.rs | 3 - crates/rsonpath-lib/src/input/borrowed.rs | 4 +- crates/rsonpath-lib/tests/end_to_end.rs | 74 +++++++++---------- 3 files changed, 38 insertions(+), 43 deletions(-) diff --git a/crates/rsonpath-lib/src/classification/memmem/avx2_64.rs b/crates/rsonpath-lib/src/classification/memmem/avx2_64.rs index 24196eb3..57f49a6e 100644 --- a/crates/rsonpath-lib/src/classification/memmem/avx2_64.rs +++ b/crates/rsonpath-lib/src/classification/memmem/avx2_64.rs @@ -1,5 +1,3 @@ -use log::debug; - use super::{shared::mask_64, shared::vector_256, *}; use crate::{ classification::mask::m64, @@ -119,7 +117,6 @@ where label: &JsonString, ) -> Result)>, InputError> { if let Some(b) = first_block { - debug!("Looking at the first_block first..."); if let Some(res) = shared::find_label_in_first_block(self.input, b, start_idx, label)? { return Ok(Some(res)); } diff --git a/crates/rsonpath-lib/src/input/borrowed.rs b/crates/rsonpath-lib/src/input/borrowed.rs index 2990b441..1db8dcff 100644 --- a/crates/rsonpath-lib/src/input/borrowed.rs +++ b/crates/rsonpath-lib/src/input/borrowed.rs @@ -9,10 +9,8 @@ //! This type of input is the fastest to process for the engine, //! since there is no additional overhead from loading anything to memory. -use log::debug; - use super::*; -use crate::{query::JsonString, result::InputRecorder}; +use crate::{debug, query::JsonString, result::InputRecorder}; /// Input wrapping a borrowed [`[u8]`] buffer. pub struct BorrowedBytes<'a> { diff --git a/crates/rsonpath-lib/tests/end_to_end.rs b/crates/rsonpath-lib/tests/end_to_end.rs index 506b9055..2ac914a7 100644 --- a/crates/rsonpath-lib/tests/end_to_end.rs +++ b/crates/rsonpath-lib/tests/end_to_end.rs @@ -1,4 +1,4 @@ -// 5dc22515f57ed020ebfab849db867ac9 +// 031ac21ad8baf84d2d626e0fc1d0f14d use pretty_assertions::assert_eq; use rsonpath::engine::{main::MainEngine, Compiler, Engine}; use rsonpath::input::*; @@ -10964,7 +10964,7 @@ fn list_with_nested_sublists_to_stress_output_ordering_with_query_select_all_sub Ok(()) } #[test] -fn long_labels_to_search_with_head_skipping_compressed_with_query_select_the_extremely_long_label_with_buffered_input_and_count_result_using_main_engine( +fn long_labels_to_search_with_head_skipping_issue_249_compressed_with_query_select_the_extremely_long_label_with_buffered_input_and_count_result_using_main_engine( ) -> Result<(), Box> { println ! ("on document compressed/head_skip_long.toml running the query $..['very long label to search for, like, extremely long, so that the colon occurs really far away from the start of the needle match, which triggers some interesting behavior and might break the head skipping module like in #249'] (select the extremely long label) with Input impl BufferedInput and result mode CountResult"); let jsonpath_query = JsonPathQuery :: parse ("$..['very long label to search for, like, extremely long, so that the colon occurs really far away from the start of the needle match, which triggers some interesting behavior and might break the head skipping module like in #249']") ? ; @@ -10976,7 +10976,7 @@ fn long_labels_to_search_with_head_skipping_compressed_with_query_select_the_ext Ok(()) } #[test] -fn long_labels_to_search_with_head_skipping_compressed_with_query_select_the_extremely_long_label_with_buffered_input_and_index_result_using_main_engine( +fn long_labels_to_search_with_head_skipping_issue_249_compressed_with_query_select_the_extremely_long_label_with_buffered_input_and_index_result_using_main_engine( ) -> Result<(), Box> { println ! ("on document compressed/head_skip_long.toml running the query $..['very long label to search for, like, extremely long, so that the colon occurs really far away from the start of the needle match, which triggers some interesting behavior and might break the head skipping module like in #249'] (select the extremely long label) with Input impl BufferedInput and result mode IndexResult"); let jsonpath_query = JsonPathQuery :: parse ("$..['very long label to search for, like, extremely long, so that the colon occurs really far away from the start of the needle match, which triggers some interesting behavior and might break the head skipping module like in #249']") ? ; @@ -10989,7 +10989,7 @@ fn long_labels_to_search_with_head_skipping_compressed_with_query_select_the_ext Ok(()) } #[test] -fn long_labels_to_search_with_head_skipping_compressed_with_query_select_the_extremely_long_label_with_buffered_input_and_nodes_result_using_main_engine( +fn long_labels_to_search_with_head_skipping_issue_249_compressed_with_query_select_the_extremely_long_label_with_buffered_input_and_nodes_result_using_main_engine( ) -> Result<(), Box> { println ! ("on document compressed/head_skip_long.toml running the query $..['very long label to search for, like, extremely long, so that the colon occurs really far away from the start of the needle match, which triggers some interesting behavior and might break the head skipping module like in #249'] (select the extremely long label) with Input impl BufferedInput and result mode NodesResult"); let jsonpath_query = JsonPathQuery :: parse ("$..['very long label to search for, like, extremely long, so that the colon occurs really far away from the start of the needle match, which triggers some interesting behavior and might break the head skipping module like in #249']") ? ; @@ -11005,7 +11005,7 @@ fn long_labels_to_search_with_head_skipping_compressed_with_query_select_the_ext Ok(()) } #[test] -fn long_labels_to_search_with_head_skipping_compressed_with_query_select_the_extremely_long_label_with_mmap_input_and_count_result_using_main_engine( +fn long_labels_to_search_with_head_skipping_issue_249_compressed_with_query_select_the_extremely_long_label_with_mmap_input_and_count_result_using_main_engine( ) -> Result<(), Box> { println ! ("on document compressed/head_skip_long.toml running the query $..['very long label to search for, like, extremely long, so that the colon occurs really far away from the start of the needle match, which triggers some interesting behavior and might break the head skipping module like in #249'] (select the extremely long label) with Input impl MmapInput and result mode CountResult"); let jsonpath_query = JsonPathQuery :: parse ("$..['very long label to search for, like, extremely long, so that the colon occurs really far away from the start of the needle match, which triggers some interesting behavior and might break the head skipping module like in #249']") ? ; @@ -11017,7 +11017,7 @@ fn long_labels_to_search_with_head_skipping_compressed_with_query_select_the_ext Ok(()) } #[test] -fn long_labels_to_search_with_head_skipping_compressed_with_query_select_the_extremely_long_label_with_mmap_input_and_index_result_using_main_engine( +fn long_labels_to_search_with_head_skipping_issue_249_compressed_with_query_select_the_extremely_long_label_with_mmap_input_and_index_result_using_main_engine( ) -> Result<(), Box> { println ! ("on document compressed/head_skip_long.toml running the query $..['very long label to search for, like, extremely long, so that the colon occurs really far away from the start of the needle match, which triggers some interesting behavior and might break the head skipping module like in #249'] (select the extremely long label) with Input impl MmapInput and result mode IndexResult"); let jsonpath_query = JsonPathQuery :: parse ("$..['very long label to search for, like, extremely long, so that the colon occurs really far away from the start of the needle match, which triggers some interesting behavior and might break the head skipping module like in #249']") ? ; @@ -11030,7 +11030,7 @@ fn long_labels_to_search_with_head_skipping_compressed_with_query_select_the_ext Ok(()) } #[test] -fn long_labels_to_search_with_head_skipping_compressed_with_query_select_the_extremely_long_label_with_mmap_input_and_nodes_result_using_main_engine( +fn long_labels_to_search_with_head_skipping_issue_249_compressed_with_query_select_the_extremely_long_label_with_mmap_input_and_nodes_result_using_main_engine( ) -> Result<(), Box> { println ! ("on document compressed/head_skip_long.toml running the query $..['very long label to search for, like, extremely long, so that the colon occurs really far away from the start of the needle match, which triggers some interesting behavior and might break the head skipping module like in #249'] (select the extremely long label) with Input impl MmapInput and result mode NodesResult"); let jsonpath_query = JsonPathQuery :: parse ("$..['very long label to search for, like, extremely long, so that the colon occurs really far away from the start of the needle match, which triggers some interesting behavior and might break the head skipping module like in #249']") ? ; @@ -11046,7 +11046,7 @@ fn long_labels_to_search_with_head_skipping_compressed_with_query_select_the_ext Ok(()) } #[test] -fn long_labels_to_search_with_head_skipping_compressed_with_query_select_the_extremely_long_label_with_owned_bytes_and_count_result_using_main_engine( +fn long_labels_to_search_with_head_skipping_issue_249_compressed_with_query_select_the_extremely_long_label_with_owned_bytes_and_count_result_using_main_engine( ) -> Result<(), Box> { println ! ("on document compressed/head_skip_long.toml running the query $..['very long label to search for, like, extremely long, so that the colon occurs really far away from the start of the needle match, which triggers some interesting behavior and might break the head skipping module like in #249'] (select the extremely long label) with Input impl OwnedBytes and result mode CountResult"); let jsonpath_query = JsonPathQuery :: parse ("$..['very long label to search for, like, extremely long, so that the colon occurs really far away from the start of the needle match, which triggers some interesting behavior and might break the head skipping module like in #249']") ? ; @@ -11058,7 +11058,7 @@ fn long_labels_to_search_with_head_skipping_compressed_with_query_select_the_ext Ok(()) } #[test] -fn long_labels_to_search_with_head_skipping_compressed_with_query_select_the_extremely_long_label_with_owned_bytes_and_index_result_using_main_engine( +fn long_labels_to_search_with_head_skipping_issue_249_compressed_with_query_select_the_extremely_long_label_with_owned_bytes_and_index_result_using_main_engine( ) -> Result<(), Box> { println ! ("on document compressed/head_skip_long.toml running the query $..['very long label to search for, like, extremely long, so that the colon occurs really far away from the start of the needle match, which triggers some interesting behavior and might break the head skipping module like in #249'] (select the extremely long label) with Input impl OwnedBytes and result mode IndexResult"); let jsonpath_query = JsonPathQuery :: parse ("$..['very long label to search for, like, extremely long, so that the colon occurs really far away from the start of the needle match, which triggers some interesting behavior and might break the head skipping module like in #249']") ? ; @@ -11071,7 +11071,7 @@ fn long_labels_to_search_with_head_skipping_compressed_with_query_select_the_ext Ok(()) } #[test] -fn long_labels_to_search_with_head_skipping_compressed_with_query_select_the_extremely_long_label_with_owned_bytes_and_nodes_result_using_main_engine( +fn long_labels_to_search_with_head_skipping_issue_249_compressed_with_query_select_the_extremely_long_label_with_owned_bytes_and_nodes_result_using_main_engine( ) -> Result<(), Box> { println ! ("on document compressed/head_skip_long.toml running the query $..['very long label to search for, like, extremely long, so that the colon occurs really far away from the start of the needle match, which triggers some interesting behavior and might break the head skipping module like in #249'] (select the extremely long label) with Input impl OwnedBytes and result mode NodesResult"); let jsonpath_query = JsonPathQuery :: parse ("$..['very long label to search for, like, extremely long, so that the colon occurs really far away from the start of the needle match, which triggers some interesting behavior and might break the head skipping module like in #249']") ? ; @@ -11087,7 +11087,7 @@ fn long_labels_to_search_with_head_skipping_compressed_with_query_select_the_ext Ok(()) } #[test] -fn long_labels_to_search_with_head_skipping_compressed_with_query_select_the_label_starting_exactly_at_block_boundary_with_buffered_input_and_count_result_using_main_engine( +fn long_labels_to_search_with_head_skipping_issue_249_compressed_with_query_select_the_label_starting_exactly_at_block_boundary_with_buffered_input_and_count_result_using_main_engine( ) -> Result<(), Box> { println ! ("on document compressed/head_skip_long.toml running the query $..target (select the label starting exactly at block boundary) with Input impl BufferedInput and result mode CountResult"); let jsonpath_query = JsonPathQuery::parse("$..target")?; @@ -11099,7 +11099,7 @@ fn long_labels_to_search_with_head_skipping_compressed_with_query_select_the_lab Ok(()) } #[test] -fn long_labels_to_search_with_head_skipping_compressed_with_query_select_the_label_starting_exactly_at_block_boundary_with_buffered_input_and_index_result_using_main_engine( +fn long_labels_to_search_with_head_skipping_issue_249_compressed_with_query_select_the_label_starting_exactly_at_block_boundary_with_buffered_input_and_index_result_using_main_engine( ) -> Result<(), Box> { println ! ("on document compressed/head_skip_long.toml running the query $..target (select the label starting exactly at block boundary) with Input impl BufferedInput and result mode IndexResult"); let jsonpath_query = JsonPathQuery::parse("$..target")?; @@ -11112,7 +11112,7 @@ fn long_labels_to_search_with_head_skipping_compressed_with_query_select_the_lab Ok(()) } #[test] -fn long_labels_to_search_with_head_skipping_compressed_with_query_select_the_label_starting_exactly_at_block_boundary_with_buffered_input_and_nodes_result_using_main_engine( +fn long_labels_to_search_with_head_skipping_issue_249_compressed_with_query_select_the_label_starting_exactly_at_block_boundary_with_buffered_input_and_nodes_result_using_main_engine( ) -> Result<(), Box> { println ! ("on document compressed/head_skip_long.toml running the query $..target (select the label starting exactly at block boundary) with Input impl BufferedInput and result mode NodesResult"); let jsonpath_query = JsonPathQuery::parse("$..target")?; @@ -11131,7 +11131,7 @@ fn long_labels_to_search_with_head_skipping_compressed_with_query_select_the_lab Ok(()) } #[test] -fn long_labels_to_search_with_head_skipping_compressed_with_query_select_the_label_starting_exactly_at_block_boundary_with_mmap_input_and_count_result_using_main_engine( +fn long_labels_to_search_with_head_skipping_issue_249_compressed_with_query_select_the_label_starting_exactly_at_block_boundary_with_mmap_input_and_count_result_using_main_engine( ) -> Result<(), Box> { println ! ("on document compressed/head_skip_long.toml running the query $..target (select the label starting exactly at block boundary) with Input impl MmapInput and result mode CountResult"); let jsonpath_query = JsonPathQuery::parse("$..target")?; @@ -11143,7 +11143,7 @@ fn long_labels_to_search_with_head_skipping_compressed_with_query_select_the_lab Ok(()) } #[test] -fn long_labels_to_search_with_head_skipping_compressed_with_query_select_the_label_starting_exactly_at_block_boundary_with_mmap_input_and_index_result_using_main_engine( +fn long_labels_to_search_with_head_skipping_issue_249_compressed_with_query_select_the_label_starting_exactly_at_block_boundary_with_mmap_input_and_index_result_using_main_engine( ) -> Result<(), Box> { println ! ("on document compressed/head_skip_long.toml running the query $..target (select the label starting exactly at block boundary) with Input impl MmapInput and result mode IndexResult"); let jsonpath_query = JsonPathQuery::parse("$..target")?; @@ -11156,7 +11156,7 @@ fn long_labels_to_search_with_head_skipping_compressed_with_query_select_the_lab Ok(()) } #[test] -fn long_labels_to_search_with_head_skipping_compressed_with_query_select_the_label_starting_exactly_at_block_boundary_with_mmap_input_and_nodes_result_using_main_engine( +fn long_labels_to_search_with_head_skipping_issue_249_compressed_with_query_select_the_label_starting_exactly_at_block_boundary_with_mmap_input_and_nodes_result_using_main_engine( ) -> Result<(), Box> { println ! ("on document compressed/head_skip_long.toml running the query $..target (select the label starting exactly at block boundary) with Input impl MmapInput and result mode NodesResult"); let jsonpath_query = JsonPathQuery::parse("$..target")?; @@ -11175,7 +11175,7 @@ fn long_labels_to_search_with_head_skipping_compressed_with_query_select_the_lab Ok(()) } #[test] -fn long_labels_to_search_with_head_skipping_compressed_with_query_select_the_label_starting_exactly_at_block_boundary_with_owned_bytes_and_count_result_using_main_engine( +fn long_labels_to_search_with_head_skipping_issue_249_compressed_with_query_select_the_label_starting_exactly_at_block_boundary_with_owned_bytes_and_count_result_using_main_engine( ) -> Result<(), Box> { println ! ("on document compressed/head_skip_long.toml running the query $..target (select the label starting exactly at block boundary) with Input impl OwnedBytes and result mode CountResult"); let jsonpath_query = JsonPathQuery::parse("$..target")?; @@ -11187,7 +11187,7 @@ fn long_labels_to_search_with_head_skipping_compressed_with_query_select_the_lab Ok(()) } #[test] -fn long_labels_to_search_with_head_skipping_compressed_with_query_select_the_label_starting_exactly_at_block_boundary_with_owned_bytes_and_index_result_using_main_engine( +fn long_labels_to_search_with_head_skipping_issue_249_compressed_with_query_select_the_label_starting_exactly_at_block_boundary_with_owned_bytes_and_index_result_using_main_engine( ) -> Result<(), Box> { println ! ("on document compressed/head_skip_long.toml running the query $..target (select the label starting exactly at block boundary) with Input impl OwnedBytes and result mode IndexResult"); let jsonpath_query = JsonPathQuery::parse("$..target")?; @@ -11200,7 +11200,7 @@ fn long_labels_to_search_with_head_skipping_compressed_with_query_select_the_lab Ok(()) } #[test] -fn long_labels_to_search_with_head_skipping_compressed_with_query_select_the_label_starting_exactly_at_block_boundary_with_owned_bytes_and_nodes_result_using_main_engine( +fn long_labels_to_search_with_head_skipping_issue_249_compressed_with_query_select_the_label_starting_exactly_at_block_boundary_with_owned_bytes_and_nodes_result_using_main_engine( ) -> Result<(), Box> { println ! ("on document compressed/head_skip_long.toml running the query $..target (select the label starting exactly at block boundary) with Input impl OwnedBytes and result mode NodesResult"); let jsonpath_query = JsonPathQuery::parse("$..target")?; @@ -11219,7 +11219,7 @@ fn long_labels_to_search_with_head_skipping_compressed_with_query_select_the_lab Ok(()) } #[test] -fn long_labels_to_search_with_head_skipping_with_query_select_the_extremely_long_label_with_buffered_input_and_count_result_using_main_engine( +fn long_labels_to_search_with_head_skipping_issue_249_with_query_select_the_extremely_long_label_with_buffered_input_and_count_result_using_main_engine( ) -> Result<(), Box> { println ! ("on document head_skip_long.toml running the query $..['very long label to search for, like, extremely long, so that the colon occurs really far away from the start of the needle match, which triggers some interesting behavior and might break the head skipping module like in #249'] (select the extremely long label) with Input impl BufferedInput and result mode CountResult"); let jsonpath_query = JsonPathQuery :: parse ("$..['very long label to search for, like, extremely long, so that the colon occurs really far away from the start of the needle match, which triggers some interesting behavior and might break the head skipping module like in #249']") ? ; @@ -11231,7 +11231,7 @@ fn long_labels_to_search_with_head_skipping_with_query_select_the_extremely_long Ok(()) } #[test] -fn long_labels_to_search_with_head_skipping_with_query_select_the_extremely_long_label_with_buffered_input_and_index_result_using_main_engine( +fn long_labels_to_search_with_head_skipping_issue_249_with_query_select_the_extremely_long_label_with_buffered_input_and_index_result_using_main_engine( ) -> Result<(), Box> { println ! ("on document head_skip_long.toml running the query $..['very long label to search for, like, extremely long, so that the colon occurs really far away from the start of the needle match, which triggers some interesting behavior and might break the head skipping module like in #249'] (select the extremely long label) with Input impl BufferedInput and result mode IndexResult"); let jsonpath_query = JsonPathQuery :: parse ("$..['very long label to search for, like, extremely long, so that the colon occurs really far away from the start of the needle match, which triggers some interesting behavior and might break the head skipping module like in #249']") ? ; @@ -11244,7 +11244,7 @@ fn long_labels_to_search_with_head_skipping_with_query_select_the_extremely_long Ok(()) } #[test] -fn long_labels_to_search_with_head_skipping_with_query_select_the_extremely_long_label_with_buffered_input_and_nodes_result_using_main_engine( +fn long_labels_to_search_with_head_skipping_issue_249_with_query_select_the_extremely_long_label_with_buffered_input_and_nodes_result_using_main_engine( ) -> Result<(), Box> { println ! ("on document head_skip_long.toml running the query $..['very long label to search for, like, extremely long, so that the colon occurs really far away from the start of the needle match, which triggers some interesting behavior and might break the head skipping module like in #249'] (select the extremely long label) with Input impl BufferedInput and result mode NodesResult"); let jsonpath_query = JsonPathQuery :: parse ("$..['very long label to search for, like, extremely long, so that the colon occurs really far away from the start of the needle match, which triggers some interesting behavior and might break the head skipping module like in #249']") ? ; @@ -11260,7 +11260,7 @@ fn long_labels_to_search_with_head_skipping_with_query_select_the_extremely_long Ok(()) } #[test] -fn long_labels_to_search_with_head_skipping_with_query_select_the_extremely_long_label_with_mmap_input_and_count_result_using_main_engine( +fn long_labels_to_search_with_head_skipping_issue_249_with_query_select_the_extremely_long_label_with_mmap_input_and_count_result_using_main_engine( ) -> Result<(), Box> { println ! ("on document head_skip_long.toml running the query $..['very long label to search for, like, extremely long, so that the colon occurs really far away from the start of the needle match, which triggers some interesting behavior and might break the head skipping module like in #249'] (select the extremely long label) with Input impl MmapInput and result mode CountResult"); let jsonpath_query = JsonPathQuery :: parse ("$..['very long label to search for, like, extremely long, so that the colon occurs really far away from the start of the needle match, which triggers some interesting behavior and might break the head skipping module like in #249']") ? ; @@ -11272,7 +11272,7 @@ fn long_labels_to_search_with_head_skipping_with_query_select_the_extremely_long Ok(()) } #[test] -fn long_labels_to_search_with_head_skipping_with_query_select_the_extremely_long_label_with_mmap_input_and_index_result_using_main_engine( +fn long_labels_to_search_with_head_skipping_issue_249_with_query_select_the_extremely_long_label_with_mmap_input_and_index_result_using_main_engine( ) -> Result<(), Box> { println ! ("on document head_skip_long.toml running the query $..['very long label to search for, like, extremely long, so that the colon occurs really far away from the start of the needle match, which triggers some interesting behavior and might break the head skipping module like in #249'] (select the extremely long label) with Input impl MmapInput and result mode IndexResult"); let jsonpath_query = JsonPathQuery :: parse ("$..['very long label to search for, like, extremely long, so that the colon occurs really far away from the start of the needle match, which triggers some interesting behavior and might break the head skipping module like in #249']") ? ; @@ -11285,7 +11285,7 @@ fn long_labels_to_search_with_head_skipping_with_query_select_the_extremely_long Ok(()) } #[test] -fn long_labels_to_search_with_head_skipping_with_query_select_the_extremely_long_label_with_mmap_input_and_nodes_result_using_main_engine( +fn long_labels_to_search_with_head_skipping_issue_249_with_query_select_the_extremely_long_label_with_mmap_input_and_nodes_result_using_main_engine( ) -> Result<(), Box> { println ! ("on document head_skip_long.toml running the query $..['very long label to search for, like, extremely long, so that the colon occurs really far away from the start of the needle match, which triggers some interesting behavior and might break the head skipping module like in #249'] (select the extremely long label) with Input impl MmapInput and result mode NodesResult"); let jsonpath_query = JsonPathQuery :: parse ("$..['very long label to search for, like, extremely long, so that the colon occurs really far away from the start of the needle match, which triggers some interesting behavior and might break the head skipping module like in #249']") ? ; @@ -11301,7 +11301,7 @@ fn long_labels_to_search_with_head_skipping_with_query_select_the_extremely_long Ok(()) } #[test] -fn long_labels_to_search_with_head_skipping_with_query_select_the_extremely_long_label_with_owned_bytes_and_count_result_using_main_engine( +fn long_labels_to_search_with_head_skipping_issue_249_with_query_select_the_extremely_long_label_with_owned_bytes_and_count_result_using_main_engine( ) -> Result<(), Box> { println ! ("on document head_skip_long.toml running the query $..['very long label to search for, like, extremely long, so that the colon occurs really far away from the start of the needle match, which triggers some interesting behavior and might break the head skipping module like in #249'] (select the extremely long label) with Input impl OwnedBytes and result mode CountResult"); let jsonpath_query = JsonPathQuery :: parse ("$..['very long label to search for, like, extremely long, so that the colon occurs really far away from the start of the needle match, which triggers some interesting behavior and might break the head skipping module like in #249']") ? ; @@ -11313,7 +11313,7 @@ fn long_labels_to_search_with_head_skipping_with_query_select_the_extremely_long Ok(()) } #[test] -fn long_labels_to_search_with_head_skipping_with_query_select_the_extremely_long_label_with_owned_bytes_and_index_result_using_main_engine( +fn long_labels_to_search_with_head_skipping_issue_249_with_query_select_the_extremely_long_label_with_owned_bytes_and_index_result_using_main_engine( ) -> Result<(), Box> { println ! ("on document head_skip_long.toml running the query $..['very long label to search for, like, extremely long, so that the colon occurs really far away from the start of the needle match, which triggers some interesting behavior and might break the head skipping module like in #249'] (select the extremely long label) with Input impl OwnedBytes and result mode IndexResult"); let jsonpath_query = JsonPathQuery :: parse ("$..['very long label to search for, like, extremely long, so that the colon occurs really far away from the start of the needle match, which triggers some interesting behavior and might break the head skipping module like in #249']") ? ; @@ -11326,7 +11326,7 @@ fn long_labels_to_search_with_head_skipping_with_query_select_the_extremely_long Ok(()) } #[test] -fn long_labels_to_search_with_head_skipping_with_query_select_the_extremely_long_label_with_owned_bytes_and_nodes_result_using_main_engine( +fn long_labels_to_search_with_head_skipping_issue_249_with_query_select_the_extremely_long_label_with_owned_bytes_and_nodes_result_using_main_engine( ) -> Result<(), Box> { println ! ("on document head_skip_long.toml running the query $..['very long label to search for, like, extremely long, so that the colon occurs really far away from the start of the needle match, which triggers some interesting behavior and might break the head skipping module like in #249'] (select the extremely long label) with Input impl OwnedBytes and result mode NodesResult"); let jsonpath_query = JsonPathQuery :: parse ("$..['very long label to search for, like, extremely long, so that the colon occurs really far away from the start of the needle match, which triggers some interesting behavior and might break the head skipping module like in #249']") ? ; @@ -11342,7 +11342,7 @@ fn long_labels_to_search_with_head_skipping_with_query_select_the_extremely_long Ok(()) } #[test] -fn long_labels_to_search_with_head_skipping_with_query_select_the_label_starting_exactly_at_block_boundary_with_buffered_input_and_count_result_using_main_engine( +fn long_labels_to_search_with_head_skipping_issue_249_with_query_select_the_label_starting_exactly_at_block_boundary_with_buffered_input_and_count_result_using_main_engine( ) -> Result<(), Box> { println ! ("on document head_skip_long.toml running the query $..target (select the label starting exactly at block boundary) with Input impl BufferedInput and result mode CountResult"); let jsonpath_query = JsonPathQuery::parse("$..target")?; @@ -11354,7 +11354,7 @@ fn long_labels_to_search_with_head_skipping_with_query_select_the_label_starting Ok(()) } #[test] -fn long_labels_to_search_with_head_skipping_with_query_select_the_label_starting_exactly_at_block_boundary_with_buffered_input_and_index_result_using_main_engine( +fn long_labels_to_search_with_head_skipping_issue_249_with_query_select_the_label_starting_exactly_at_block_boundary_with_buffered_input_and_index_result_using_main_engine( ) -> Result<(), Box> { println ! ("on document head_skip_long.toml running the query $..target (select the label starting exactly at block boundary) with Input impl BufferedInput and result mode IndexResult"); let jsonpath_query = JsonPathQuery::parse("$..target")?; @@ -11367,7 +11367,7 @@ fn long_labels_to_search_with_head_skipping_with_query_select_the_label_starting Ok(()) } #[test] -fn long_labels_to_search_with_head_skipping_with_query_select_the_label_starting_exactly_at_block_boundary_with_buffered_input_and_nodes_result_using_main_engine( +fn long_labels_to_search_with_head_skipping_issue_249_with_query_select_the_label_starting_exactly_at_block_boundary_with_buffered_input_and_nodes_result_using_main_engine( ) -> Result<(), Box> { println ! ("on document head_skip_long.toml running the query $..target (select the label starting exactly at block boundary) with Input impl BufferedInput and result mode NodesResult"); let jsonpath_query = JsonPathQuery::parse("$..target")?; @@ -11383,7 +11383,7 @@ fn long_labels_to_search_with_head_skipping_with_query_select_the_label_starting Ok(()) } #[test] -fn long_labels_to_search_with_head_skipping_with_query_select_the_label_starting_exactly_at_block_boundary_with_mmap_input_and_count_result_using_main_engine( +fn long_labels_to_search_with_head_skipping_issue_249_with_query_select_the_label_starting_exactly_at_block_boundary_with_mmap_input_and_count_result_using_main_engine( ) -> Result<(), Box> { println ! ("on document head_skip_long.toml running the query $..target (select the label starting exactly at block boundary) with Input impl MmapInput and result mode CountResult"); let jsonpath_query = JsonPathQuery::parse("$..target")?; @@ -11395,7 +11395,7 @@ fn long_labels_to_search_with_head_skipping_with_query_select_the_label_starting Ok(()) } #[test] -fn long_labels_to_search_with_head_skipping_with_query_select_the_label_starting_exactly_at_block_boundary_with_mmap_input_and_index_result_using_main_engine( +fn long_labels_to_search_with_head_skipping_issue_249_with_query_select_the_label_starting_exactly_at_block_boundary_with_mmap_input_and_index_result_using_main_engine( ) -> Result<(), Box> { println ! ("on document head_skip_long.toml running the query $..target (select the label starting exactly at block boundary) with Input impl MmapInput and result mode IndexResult"); let jsonpath_query = JsonPathQuery::parse("$..target")?; @@ -11408,7 +11408,7 @@ fn long_labels_to_search_with_head_skipping_with_query_select_the_label_starting Ok(()) } #[test] -fn long_labels_to_search_with_head_skipping_with_query_select_the_label_starting_exactly_at_block_boundary_with_mmap_input_and_nodes_result_using_main_engine( +fn long_labels_to_search_with_head_skipping_issue_249_with_query_select_the_label_starting_exactly_at_block_boundary_with_mmap_input_and_nodes_result_using_main_engine( ) -> Result<(), Box> { println ! ("on document head_skip_long.toml running the query $..target (select the label starting exactly at block boundary) with Input impl MmapInput and result mode NodesResult"); let jsonpath_query = JsonPathQuery::parse("$..target")?; @@ -11424,7 +11424,7 @@ fn long_labels_to_search_with_head_skipping_with_query_select_the_label_starting Ok(()) } #[test] -fn long_labels_to_search_with_head_skipping_with_query_select_the_label_starting_exactly_at_block_boundary_with_owned_bytes_and_count_result_using_main_engine( +fn long_labels_to_search_with_head_skipping_issue_249_with_query_select_the_label_starting_exactly_at_block_boundary_with_owned_bytes_and_count_result_using_main_engine( ) -> Result<(), Box> { println ! ("on document head_skip_long.toml running the query $..target (select the label starting exactly at block boundary) with Input impl OwnedBytes and result mode CountResult"); let jsonpath_query = JsonPathQuery::parse("$..target")?; @@ -11436,7 +11436,7 @@ fn long_labels_to_search_with_head_skipping_with_query_select_the_label_starting Ok(()) } #[test] -fn long_labels_to_search_with_head_skipping_with_query_select_the_label_starting_exactly_at_block_boundary_with_owned_bytes_and_index_result_using_main_engine( +fn long_labels_to_search_with_head_skipping_issue_249_with_query_select_the_label_starting_exactly_at_block_boundary_with_owned_bytes_and_index_result_using_main_engine( ) -> Result<(), Box> { println ! ("on document head_skip_long.toml running the query $..target (select the label starting exactly at block boundary) with Input impl OwnedBytes and result mode IndexResult"); let jsonpath_query = JsonPathQuery::parse("$..target")?; @@ -11449,7 +11449,7 @@ fn long_labels_to_search_with_head_skipping_with_query_select_the_label_starting Ok(()) } #[test] -fn long_labels_to_search_with_head_skipping_with_query_select_the_label_starting_exactly_at_block_boundary_with_owned_bytes_and_nodes_result_using_main_engine( +fn long_labels_to_search_with_head_skipping_issue_249_with_query_select_the_label_starting_exactly_at_block_boundary_with_owned_bytes_and_nodes_result_using_main_engine( ) -> Result<(), Box> { println ! ("on document head_skip_long.toml running the query $..target (select the label starting exactly at block boundary) with Input impl OwnedBytes and result mode NodesResult"); let jsonpath_query = JsonPathQuery::parse("$..target")?; From 66768f2d4ee2f33859adfbff42db204c63b909ea Mon Sep 17 00:00:00 2001 From: Mateusz Gienieczko Date: Sat, 9 Sep 2023 22:38:03 +0100 Subject: [PATCH 4/4] chore: address review comments --- crates/rsonpath-lib/src/classification.rs | 3 +-- crates/rsonpath-lib/src/classification/quotes.rs | 6 +++++- crates/rsonpath-lib/src/classification/quotes/nosimd.rs | 2 +- crates/rsonpath-lib/src/classification/quotes/shared.rs | 5 +---- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/crates/rsonpath-lib/src/classification.rs b/crates/rsonpath-lib/src/classification.rs index a2bca799..2cad6b98 100644 --- a/crates/rsonpath-lib/src/classification.rs +++ b/crates/rsonpath-lib/src/classification.rs @@ -129,8 +129,7 @@ where let current_idx = current_block_start + current_block_idx; debug!( - "Calling forward_to({index}) when the inner iter offset is {} and block idx is {:?}", - current_block_start, current_block_idx + "Calling forward_to({index}) when the inner iter offset is {current_block_start} and block idx is {current_block_idx:?}" ); // We want to move by this much forward, and delta > 0. diff --git a/crates/rsonpath-lib/src/classification/quotes.rs b/crates/rsonpath-lib/src/classification/quotes.rs index ebe8ee7d..a84708c0 100644 --- a/crates/rsonpath-lib/src/classification/quotes.rs +++ b/crates/rsonpath-lib/src/classification/quotes.rs @@ -38,6 +38,10 @@ use crate::{ }; use cfg_if::cfg_if; +/// Result of the [`FallibleIterator`] for quote classification, +/// and of the [`offset`](`QuoteClassifiedIterator::offset`) function. +pub type QuoteIterResult = Result>, InputError>; + /// Input block with a bitmask signifying which characters are within quotes. /// /// Characters within quotes in the input are guaranteed to have their corresponding @@ -67,7 +71,7 @@ pub trait QuoteClassifiedIterator<'i, I: InputBlockIterator<'i, N>, M, const N: /// # Errors /// At least one new block is read from the underlying /// [`InputBlockIterator`] implementation, which can fail. - fn offset(&mut self, count: isize) -> Result>, InputError>; + fn offset(&mut self, count: isize) -> QuoteIterResult; /// Flip the bit representing whether the last block ended with a nonescaped quote. /// diff --git a/crates/rsonpath-lib/src/classification/quotes/nosimd.rs b/crates/rsonpath-lib/src/classification/quotes/nosimd.rs index 13eeca1e..3e37ef1f 100644 --- a/crates/rsonpath-lib/src/classification/quotes/nosimd.rs +++ b/crates/rsonpath-lib/src/classification/quotes/nosimd.rs @@ -107,7 +107,7 @@ where self.iter.get_offset() - N } - fn offset(&mut self, count: isize) -> Result>, InputError> { + fn offset(&mut self, count: isize) -> QuoteIterResult { debug_assert!(count > 0); debug!("Offsetting by {count}"); diff --git a/crates/rsonpath-lib/src/classification/quotes/shared.rs b/crates/rsonpath-lib/src/classification/quotes/shared.rs index b884e473..d3f5318a 100644 --- a/crates/rsonpath-lib/src/classification/quotes/shared.rs +++ b/crates/rsonpath-lib/src/classification/quotes/shared.rs @@ -89,10 +89,7 @@ macro_rules! quote_classifier { self.iter.get_offset() - $size } - fn offset( - &mut self, - count: isize, - ) -> Result>, InputError> { + fn offset(&mut self, count: isize) -> QuoteIterResult { debug_assert!(count > 0); debug!("Offsetting by {count}");