1use bytes::Bytes;
21
22use super::page::{Page, PageReader};
23use crate::basic::*;
24use crate::column::reader::decoder::{
25 ColumnValueDecoder, ColumnValueDecoderImpl, DefinitionLevelDecoder, DefinitionLevelDecoderImpl,
26 RepetitionLevelDecoder, RepetitionLevelDecoderImpl, normalize_fixed_len_byte_array_data,
27 prepare_v1_fixed_len_byte_array,
28};
29use crate::data_type::*;
30use crate::errors::{ParquetError, Result};
31use crate::schema::types::ColumnDescPtr;
32use crate::util::bit_util::{ceil, num_required_bits, read_num_bytes};
33
34pub(crate) mod decoder;
35mod legacy_fixed_len_byte_array;
36
37pub enum ColumnReader {
39 BoolColumnReader(ColumnReaderImpl<BoolType>),
41 Int32ColumnReader(ColumnReaderImpl<Int32Type>),
43 Int64ColumnReader(ColumnReaderImpl<Int64Type>),
45 Int96ColumnReader(ColumnReaderImpl<Int96Type>),
47 FloatColumnReader(ColumnReaderImpl<FloatType>),
49 DoubleColumnReader(ColumnReaderImpl<DoubleType>),
51 ByteArrayColumnReader(ColumnReaderImpl<ByteArrayType>),
53 FixedLenByteArrayColumnReader(ColumnReaderImpl<FixedLenByteArrayType>),
55}
56
57pub fn get_column_reader(
60 col_descr: ColumnDescPtr,
61 col_page_reader: Box<dyn PageReader>,
62) -> ColumnReader {
63 match col_descr.physical_type() {
64 Type::BOOLEAN => {
65 ColumnReader::BoolColumnReader(ColumnReaderImpl::new(col_descr, col_page_reader))
66 }
67 Type::INT32 => {
68 ColumnReader::Int32ColumnReader(ColumnReaderImpl::new(col_descr, col_page_reader))
69 }
70 Type::INT64 => {
71 ColumnReader::Int64ColumnReader(ColumnReaderImpl::new(col_descr, col_page_reader))
72 }
73 Type::INT96 => {
74 ColumnReader::Int96ColumnReader(ColumnReaderImpl::new(col_descr, col_page_reader))
75 }
76 Type::FLOAT => {
77 ColumnReader::FloatColumnReader(ColumnReaderImpl::new(col_descr, col_page_reader))
78 }
79 Type::DOUBLE => {
80 ColumnReader::DoubleColumnReader(ColumnReaderImpl::new(col_descr, col_page_reader))
81 }
82 Type::BYTE_ARRAY => {
83 ColumnReader::ByteArrayColumnReader(ColumnReaderImpl::new(col_descr, col_page_reader))
84 }
85 Type::FIXED_LEN_BYTE_ARRAY => ColumnReader::FixedLenByteArrayColumnReader(
86 ColumnReaderImpl::new(col_descr, col_page_reader),
87 ),
88 }
89}
90
91pub fn get_typed_column_reader<T: DataType>(col_reader: ColumnReader) -> ColumnReaderImpl<T> {
98 T::get_column_reader(col_reader).unwrap_or_else(|| {
99 panic!(
100 "Failed to convert column reader into a typed column reader for `{}` type",
101 T::get_physical_type()
102 )
103 })
104}
105
106pub type ColumnReaderImpl<T> = GenericColumnReader<
108 RepetitionLevelDecoderImpl,
109 DefinitionLevelDecoderImpl,
110 ColumnValueDecoderImpl<T>,
111>;
112
113pub struct GenericColumnReader<R, D, V> {
119 descr: ColumnDescPtr,
120
121 page_reader: Box<dyn PageReader>,
122
123 num_buffered_values: usize,
125
126 num_decoded_values: usize,
129
130 has_record_delimiter: bool,
132
133 def_level_decoder: Option<D>,
135
136 rep_level_decoder: Option<R>,
138
139 values_decoder: V,
141
142 remaining_fixed_len_bytes: Option<(usize, usize)>,
145}
146
147impl<V> GenericColumnReader<RepetitionLevelDecoderImpl, DefinitionLevelDecoderImpl, V>
148where
149 V: ColumnValueDecoder,
150{
151 pub fn new(descr: ColumnDescPtr, page_reader: Box<dyn PageReader>) -> Self {
153 let values_decoder = V::new(&descr);
154
155 let def_level_decoder = (descr.max_def_level() != 0)
156 .then(|| DefinitionLevelDecoderImpl::new(descr.max_def_level()));
157
158 let rep_level_decoder = (descr.max_rep_level() != 0)
159 .then(|| RepetitionLevelDecoderImpl::new(descr.max_rep_level()));
160
161 Self::new_with_decoders(
162 descr,
163 page_reader,
164 values_decoder,
165 def_level_decoder,
166 rep_level_decoder,
167 )
168 }
169}
170
171impl<R, D, V> GenericColumnReader<R, D, V>
172where
173 R: RepetitionLevelDecoder,
174 D: DefinitionLevelDecoder,
175 V: ColumnValueDecoder,
176{
177 pub(crate) fn new_with_decoders(
178 descr: ColumnDescPtr,
179 page_reader: Box<dyn PageReader>,
180 values_decoder: V,
181 def_level_decoder: Option<D>,
182 rep_level_decoder: Option<R>,
183 ) -> Self {
184 Self {
185 descr,
186 def_level_decoder,
187 rep_level_decoder,
188 page_reader,
189 num_buffered_values: 0,
190 num_decoded_values: 0,
191 values_decoder,
192 has_record_delimiter: false,
193 remaining_fixed_len_bytes: None,
194 }
195 }
196
197 pub fn read_records(
216 &mut self,
217 max_records: usize,
218 def_levels: Option<&mut D::Buffer>,
219 rep_levels: Option<&mut R::Buffer>,
220 values: &mut V::Buffer,
221 ) -> Result<(usize, usize, usize)> {
222 self.read_records_with_reservation(
223 max_records,
224 def_levels,
225 rep_levels,
226 values,
227 |_, _, _, _| Ok(()),
228 )
229 }
230
231 pub(crate) fn read_records_with_reservation<F>(
234 &mut self,
235 max_records: usize,
236 mut def_levels: Option<&mut D::Buffer>,
237 mut rep_levels: Option<&mut R::Buffer>,
238 values: &mut V::Buffer,
239 mut reserve_values: F,
240 ) -> Result<(usize, usize, usize)>
241 where
242 F: FnMut(&mut V::Buffer, usize, usize, Option<&D::Buffer>) -> Result<()>,
243 {
244 let mut total_records_read = 0;
245 let mut total_levels_read = 0;
246 let mut total_values_read = 0;
247
248 while total_records_read < max_records && self.has_next()? {
249 let remaining_records = max_records - total_records_read;
250 let remaining_levels = self.num_buffered_values - self.num_decoded_values;
251
252 let (records_read, levels_to_read) = match self.rep_level_decoder.as_mut() {
253 Some(reader) => {
254 let out = rep_levels
255 .as_mut()
256 .ok_or_else(|| general_err!("must specify repetition levels"))?;
257
258 let (mut records_read, levels_read) =
259 reader.read_rep_levels(out, remaining_records, remaining_levels)?;
260
261 if records_read == 0 && levels_read == 0 {
262 return Err(general_err!(
264 "Insufficient repetition levels read from column"
265 ));
266 }
267 if levels_read == remaining_levels && self.has_record_delimiter {
268 check_partial_record_fits(records_read, remaining_records)?;
269 records_read += reader.flush_partial() as usize;
270 }
271 (records_read, levels_read)
272 }
273 None => {
274 let min = remaining_records.min(remaining_levels);
275 (min, min)
276 }
277 };
278
279 let values_to_read = match self.def_level_decoder.as_mut() {
280 Some(reader) => {
281 let out = def_levels
282 .as_mut()
283 .ok_or_else(|| general_err!("must specify definition levels"))?;
284
285 let (values_read, levels_read) = reader.read_def_levels(out, levels_to_read)?;
286
287 if levels_read != levels_to_read {
288 return Err(general_err!(
289 "insufficient definition levels read from column - expected {levels_to_read}, got {levels_read}"
290 ));
291 }
292
293 values_read
294 }
295 None => levels_to_read,
296 };
297
298 self.check_fixed_len_bytes(values_to_read, levels_to_read == remaining_levels)?;
299
300 let def_levels = def_levels.as_deref();
301 reserve_values(values, values_to_read, levels_to_read, def_levels)?;
302
303 let values_read = self.values_decoder.read(values, values_to_read)?;
304
305 if values_read != values_to_read {
306 return Err(general_err!(
307 "insufficient values read from column - expected: {values_to_read}, got: {values_read}",
308 ));
309 }
310
311 self.num_decoded_values += levels_to_read;
312 total_records_read += records_read;
313 total_levels_read += levels_to_read;
314 total_values_read += values_read;
315 }
316
317 Ok((total_records_read, total_values_read, total_levels_read))
318 }
319
320 pub fn skip_records(&mut self, num_records: usize) -> Result<usize> {
326 let mut remaining_records = num_records;
327 while remaining_records != 0 {
328 if self.num_buffered_values == self.num_decoded_values {
329 let Some(metadata) = self.page_reader.peek_next_page()? else {
330 return Ok(num_records - remaining_records);
331 };
332
333 if metadata.is_dict {
336 if self.page_reader.supports_deferred_dictionary() {
337 self.page_reader.skip_next_page()?;
338 } else {
339 self.read_dictionary_page()?;
340 }
341 continue;
342 }
343
344 let rows = metadata.num_rows.or_else(|| {
347 self.rep_level_decoder
349 .is_none()
350 .then_some(metadata.num_levels)?
351 });
352
353 if let Some(rows) = rows
354 && rows <= remaining_records
355 {
356 self.page_reader.skip_next_page()?;
357 remaining_records -= rows;
358 continue;
359 }
360 if !self.read_new_page()? {
363 return Ok(num_records - remaining_records);
364 }
365 }
366
367 let remaining_levels = self.num_buffered_values - self.num_decoded_values;
371
372 let (records_read, rep_levels_read) = match self.rep_level_decoder.as_mut() {
373 Some(decoder) => {
374 let (mut records_read, levels_read) =
375 decoder.skip_rep_levels(remaining_records, remaining_levels)?;
376
377 if levels_read == remaining_levels && self.has_record_delimiter {
378 check_partial_record_fits(records_read, remaining_records)?;
379 records_read += decoder.flush_partial() as usize;
380 }
381
382 (records_read, levels_read)
383 }
384 None => {
385 let levels = remaining_levels.min(remaining_records);
387 (levels, levels)
388 }
389 };
390
391 self.num_decoded_values += rep_levels_read;
392 remaining_records -= records_read;
393
394 let page_finished = self.num_buffered_values == self.num_decoded_values;
395 if page_finished && self.remaining_fixed_len_bytes.is_none() {
396 continue;
398 }
399
400 let (values_read, def_levels_read) = match self.def_level_decoder.as_mut() {
401 Some(decoder) => decoder.skip_def_levels(rep_levels_read)?,
402 None => (rep_levels_read, rep_levels_read),
403 };
404
405 if rep_levels_read != def_levels_read {
406 return Err(general_err!(
407 "levels mismatch, read {} repetition levels and {} definition levels",
408 rep_levels_read,
409 def_levels_read
410 ));
411 }
412
413 self.check_fixed_len_bytes(values_read, page_finished)?;
414 if page_finished {
415 continue;
416 }
417
418 let values = self.values_decoder.skip_values(values_read)?;
419 if values != values_read {
420 return Err(general_err!(
421 "skipped {} values, expected {}",
422 values,
423 values_read
424 ));
425 }
426 }
427 Ok(num_records - remaining_records)
428 }
429
430 fn check_fixed_len_bytes(&mut self, values: usize, page_finished: bool) -> Result<()> {
433 if let Some((width, remaining)) = self.remaining_fixed_len_bytes.as_mut() {
434 let bytes = values
435 .checked_mul(*width)
436 .ok_or_else(|| general_err!("FIXED_LEN_BYTE_ARRAY payload size overflow"))?;
437 let left = remaining.checked_sub(bytes).ok_or_else(|| {
438 general_err!(
439 "Invalid FIXED_LEN_BYTE_ARRAY PLAIN data page payload length: \
440 need {bytes} value bytes, only {remaining} remain"
441 )
442 })?;
443 if page_finished && left != 0 {
444 return Err(general_err!(
445 "Invalid FIXED_LEN_BYTE_ARRAY PLAIN data page payload length: \
446 {left} trailing value bytes"
447 ));
448 }
449 *remaining = left;
450 if page_finished {
451 self.remaining_fixed_len_bytes = None;
452 }
453 }
454 Ok(())
455 }
456
457 fn read_dictionary_page(&mut self) -> Result<()> {
464 match self.page_reader.get_next_page()? {
465 Some(Page::DictionaryPage {
466 buf,
467 num_values,
468 encoding,
469 is_sorted,
470 }) => self
471 .values_decoder
472 .set_dict(buf, num_values, encoding, is_sorted),
473 _ => Err(ParquetError::General(
474 "Invalid page. Expecting dictionary page".to_string(),
475 )),
476 }
477 }
478
479 fn install_deferred_dictionary(&mut self) -> Result<()> {
482 match self.page_reader.take_deferred_dictionary()? {
483 Some(Page::DictionaryPage {
484 buf,
485 num_values,
486 encoding,
487 is_sorted,
488 }) => self
489 .values_decoder
490 .set_dict(buf, num_values, encoding, is_sorted),
491 Some(_) => Err(ParquetError::General(
492 "Invalid page. Expecting dictionary page".to_string(),
493 )),
494 None => Ok(()),
495 }
496 }
497
498 fn read_new_page(&mut self) -> Result<bool> {
501 loop {
502 match self.page_reader.get_next_page()? {
503 None => return Ok(false),
505 Some(current_page) => {
506 match current_page {
507 Page::DictionaryPage {
509 buf,
510 num_values,
511 encoding,
512 is_sorted,
513 } => {
514 self.values_decoder
515 .set_dict(buf, num_values, encoding, is_sorted)?;
516 }
517 Page::DataPage {
519 buf,
520 num_values,
521 encoding,
522 def_level_encoding,
523 rep_level_encoding,
524 statistics: _,
525 } => {
526 if matches!(
527 encoding,
528 Encoding::PLAIN_DICTIONARY | Encoding::RLE_DICTIONARY
529 ) {
530 self.install_deferred_dictionary()?;
531 }
532 self.num_buffered_values = num_values as _;
533 self.num_decoded_values = 0;
534
535 let max_rep_level = self.descr.max_rep_level();
536 let max_def_level = self.descr.max_def_level();
537 self.remaining_fixed_len_bytes = None;
538
539 let mut offset = 0;
540
541 if max_rep_level > 0 {
542 let (bytes_read, level_data) = parse_v1_level(
543 max_rep_level,
544 num_values,
545 rep_level_encoding,
546 buf.slice(offset..),
547 )?;
548 offset += bytes_read;
549
550 self.has_record_delimiter =
551 self.page_reader.at_record_boundary()?;
552
553 self.rep_level_decoder
554 .as_mut()
555 .unwrap()
556 .set_data(rep_level_encoding, level_data)?;
557 }
558
559 let definition_levels = if max_def_level > 0 {
560 let (bytes_read, level_data) = parse_v1_level(
561 max_def_level,
562 num_values,
563 def_level_encoding,
564 buf.slice(offset..),
565 )?;
566 offset += bytes_read;
567 Some(level_data)
568 } else {
569 None
570 };
571
572 let data = buf.slice(offset..);
573 let (encoding, data) =
574 if self.descr.physical_type() == Type::FIXED_LEN_BYTE_ARRAY {
575 let width = self.descr.type_length() as usize;
576 let page = prepare_v1_fixed_len_byte_array(
577 data,
578 num_values as usize,
579 width,
580 encoding,
581 definition_levels.as_ref().map(|levels| {
582 (max_def_level, def_level_encoding, levels)
583 }),
584 )?;
585 self.remaining_fixed_len_bytes =
586 page.validate_count.then_some((width, page.data.len()));
587 (page.encoding, page.data)
588 } else {
589 (encoding, data)
590 };
591 if let Some(level_data) = definition_levels {
592 self.def_level_decoder
593 .as_mut()
594 .unwrap()
595 .set_data(def_level_encoding, level_data)?;
596 }
597 self.values_decoder.set_data(
598 encoding,
599 data,
600 num_values as usize,
601 None,
602 )?;
603 return Ok(true);
604 }
605 Page::DataPageV2 {
607 buf,
608 num_values,
609 encoding,
610 num_nulls,
611 num_rows: _,
612 def_levels_byte_len,
613 rep_levels_byte_len,
614 is_compressed: _,
615 statistics: _,
616 } => {
617 if matches!(
618 encoding,
619 Encoding::PLAIN_DICTIONARY | Encoding::RLE_DICTIONARY
620 ) {
621 self.install_deferred_dictionary()?;
622 }
623 if num_nulls > num_values {
624 return Err(general_err!(
625 "more nulls than values in page, contained {} values and {} nulls",
626 num_values,
627 num_nulls
628 ));
629 }
630
631 self.num_buffered_values = num_values as _;
632 self.num_decoded_values = 0;
633
634 self.remaining_fixed_len_bytes = None;
635
636 if self.descr.max_rep_level() > 0 {
639 self.has_record_delimiter =
643 self.page_reader.at_record_boundary()?;
644
645 self.rep_level_decoder.as_mut().unwrap().set_data(
646 Encoding::RLE,
647 buf.slice(..rep_levels_byte_len as usize),
648 )?;
649 }
650
651 if self.descr.max_def_level() > 0 {
654 self.def_level_decoder.as_mut().unwrap().set_data(
655 Encoding::RLE,
656 buf.slice(
657 rep_levels_byte_len as usize
658 ..(rep_levels_byte_len + def_levels_byte_len) as usize,
659 ),
660 )?;
661 }
662
663 let data =
664 buf.slice((rep_levels_byte_len + def_levels_byte_len) as usize..);
665 let (encoding, data) =
666 if self.descr.physical_type() == Type::FIXED_LEN_BYTE_ARRAY {
667 normalize_fixed_len_byte_array_data(
668 data,
669 (num_values - num_nulls) as usize,
670 self.descr.type_length() as usize,
671 encoding,
672 )?
673 } else {
674 (encoding, data)
675 };
676 self.values_decoder.set_data(
677 encoding,
678 data,
679 num_values as usize,
680 Some((num_values - num_nulls) as usize),
681 )?;
682 return Ok(true);
683 }
684 }
685 }
686 }
687 }
688 }
689
690 #[inline]
694 pub(crate) fn has_next(&mut self) -> Result<bool> {
695 if self.num_buffered_values == 0 || self.num_buffered_values == self.num_decoded_values {
696 if !self.read_new_page()? {
699 Ok(false)
700 } else {
701 Ok(self.num_buffered_values != 0)
702 }
703 } else {
704 Ok(true)
705 }
706 }
707}
708
709fn check_partial_record_fits(records_read: usize, remaining_records: usize) -> Result<()> {
716 if remaining_records <= records_read {
717 return Err(general_err!(
718 "page ended after {records_read} record(s), which is already all of the \
719 {remaining_records} record(s) asked for, so there is no partial record to flush"
720 ));
721 }
722 Ok(())
723}
724
725fn parse_v1_level(
726 max_level: i16,
727 num_buffered_values: u32,
728 encoding: Encoding,
729 buf: Bytes,
730) -> Result<(usize, Bytes)> {
731 match encoding {
732 Encoding::RLE => {
733 let i32_size = std::mem::size_of::<i32>();
734 if i32_size <= buf.len() {
735 let data_size = read_num_bytes::<i32>(i32_size, buf.as_ref()) as usize;
736 let end = i32_size
737 .checked_add(data_size)
738 .ok_or(general_err!("invalid level length"))?;
739 if end <= buf.len() {
740 return Ok((end, buf.slice(i32_size..end)));
741 }
742 }
743 Err(general_err!("not enough data to read levels"))
744 }
745 #[expect(deprecated)]
746 Encoding::BIT_PACKED => {
747 let bit_width = num_required_bits(max_level as u64);
748 let num_bytes = ceil(num_buffered_values as usize * bit_width as usize, 8);
749 Ok((num_bytes, buf.slice(..num_bytes)))
750 }
751 _ => Err(general_err!("invalid level encoding: {}", encoding)),
752 }
753}
754
755#[cfg(test)]
756mod tests {
757 use super::*;
758
759 use rand::distr::uniform::SampleUniform;
760 use std::{collections::VecDeque, sync::Arc};
761
762 use crate::basic::Type as PhysicalType;
763 use crate::schema::types::{ColumnDescriptor, ColumnPath, Type as SchemaType};
764 use crate::util::test_common::page_util::InMemoryPageReader;
765 use crate::util::test_common::rand_gen::make_pages;
766
767 pub(super) fn nullable_fixed_page(def: &[i16], encoding: Encoding, payload: &[u8]) -> Page {
768 use crate::encodings::levels::LevelEncoder;
769 let mut levels = LevelEncoder::v1_streaming(1);
770 levels.put_with_observer(def, |_, _| {});
771 let mut buf = levels.consume();
772 buf.extend_from_slice(payload);
773 Page::DataPage {
774 buf: buf.into(),
775 num_values: def.len() as u32,
776 encoding,
777 def_level_encoding: Encoding::RLE,
778 rep_level_encoding: Encoding::RLE,
779 statistics: None,
780 }
781 }
782
783 pub(super) fn nullable_fixed_reader(
784 pages: Vec<Page>,
785 ) -> ColumnReaderImpl<FixedLenByteArrayType> {
786 let descr = Arc::new(ColumnDescriptor::new(
787 Arc::new(
788 SchemaType::primitive_type_builder("fixed", PhysicalType::FIXED_LEN_BYTE_ARRAY)
789 .with_length(4)
790 .build()
791 .unwrap(),
792 ),
793 1,
794 0,
795 ColumnPath::from("fixed"),
796 ));
797 ColumnReaderImpl::<FixedLenByteArrayType>::new(
798 descr,
799 Box::new(InMemoryPageReader::new(pages)),
800 )
801 }
802
803 pub(super) fn check_incremental_fixed_len_byte_array_pages(
805 encoding: Encoding,
806 payload: impl Fn(usize) -> Vec<u8>,
807 ) {
808 for count in [1, 2, 3] {
809 for finish_by_skipping in [false, true] {
810 let mut reader = nullable_fixed_reader(vec![nullable_fixed_page(
811 &[1, 0, 1, 0],
812 encoding,
813 &payload(count),
814 )]);
815 let mut values = vec![];
816 assert_eq!(
817 reader
818 .read_records(1, Some(&mut vec![]), None, &mut values)
819 .unwrap(),
820 (1, 1, 1)
821 );
822 assert_eq!(values[0].data(), b"abcd");
825 assert_eq!(reader.remaining_fixed_len_bytes, Some((4, (count - 1) * 4)));
826 assert_eq!(reader.skip_records(1).unwrap(), 1);
827 let result = if finish_by_skipping {
828 reader.skip_records(2).map(|_| ())
829 } else {
830 reader
831 .read_records(2, Some(&mut vec![]), None, &mut values)
832 .map(|_| ())
833 };
834 if count == 2 {
835 result.unwrap();
836 assert!(reader.remaining_fixed_len_bytes.is_none());
837 } else {
838 assert!(result.unwrap_err().to_string().contains("payload length"));
839 }
840 }
841 }
842 }
843
844 #[test]
845 fn fixed_v1_incremental_count_validation() {
846 check_incremental_fixed_len_byte_array_pages(Encoding::PLAIN, |n| b"abcd".repeat(n));
847
848 for last in [0, 1] {
851 for payload in [b"".as_slice(), b"abcd".as_slice()] {
852 let mut reader = nullable_fixed_reader(vec![nullable_fixed_page(
853 &[0, 0, 0, last],
854 Encoding::PLAIN,
855 payload,
856 )]);
857 let mut values = vec![];
858 assert_eq!(
859 reader
860 .read_records(1, Some(&mut vec![]), None, &mut values)
861 .unwrap(),
862 (1, 0, 1)
863 );
864 assert_eq!(
865 reader.skip_records(3).is_ok(),
866 payload.len() == last as usize * 4
867 );
868 assert!(values.is_empty());
869 }
870 }
871 }
872
873 #[test]
874 fn fixed_v1_canonical_prefix_shaped_values() {
875 let raw = 4_u32.to_le_bytes().repeat(10);
877 let mut reader =
878 nullable_fixed_reader(vec![nullable_fixed_page(&[1; 10], Encoding::PLAIN, &raw)]);
879 let mut values = vec![];
880 assert_eq!(
881 reader
882 .read_records(1, Some(&mut vec![]), None, &mut values)
883 .unwrap(),
884 (1, 1, 1)
885 );
886 reader
887 .read_records(usize::MAX, Some(&mut vec![]), None, &mut values)
888 .unwrap();
889 assert_eq!(values.len(), 10);
890 assert!(values.iter().all(|v| v.data() == 4_u32.to_le_bytes()));
891 }
892
893 #[test]
894 fn fixed_v1_incremental_page_transitions_and_short_levels() {
895 let first = nullable_fixed_page(&[1, 0, 1, 0], Encoding::PLAIN, b"abcdabcd");
896 let second = nullable_fixed_page(&[1, 1], Encoding::PLAIN, b"efghefgh");
897 let mut reader = nullable_fixed_reader(vec![first.clone(), second]);
898 let mut values = vec![];
899 reader
900 .read_records(1, Some(&mut vec![]), None, &mut values)
901 .unwrap();
902 assert_eq!(reader.skip_records(3).unwrap(), 3);
903 assert!(reader.remaining_fixed_len_bytes.is_none());
904 assert_eq!(
905 reader
906 .read_records(usize::MAX, Some(&mut vec![]), None, &mut values)
907 .unwrap(),
908 (2, 2, 2)
909 );
910 assert_eq!(
911 values.iter().map(|v| v.data()).collect::<Vec<_>>(),
912 [b"abcd", b"efgh", b"efgh"]
913 );
914
915 let mut short_levels = first;
916 if let Page::DataPage { num_values, .. } = &mut short_levels {
917 *num_values += 8; }
919 let mut reader = nullable_fixed_reader(vec![short_levels]);
920 reader
921 .read_records(1, Some(&mut vec![]), None, &mut vec![])
922 .unwrap();
923 let err = reader
924 .read_records(usize::MAX, Some(&mut vec![]), None, &mut vec![])
925 .unwrap_err();
926 assert!(err.to_string().contains("definition levels"));
927 }
928
929 #[test]
930 fn fixed_plain_payload_length_validation() {
931 check_fixed_len_byte_array_pages(
932 |raw| vec![(Encoding::PLAIN, raw.to_vec())],
933 |raw| {
934 let mut extra = raw.to_vec();
935 extra.push(0);
936 let mut malformed = vec![extra];
937 if !raw.is_empty() {
938 malformed.push(raw[..raw.len() - 1].to_vec());
939 }
940 malformed
941 },
942 );
943 }
944
945 #[expect(deprecated, reason = "Cover legacy BIT_PACKED definition levels")]
948 pub(super) fn check_fixed_len_byte_array_pages(
949 payloads: impl Fn(&[u8]) -> Vec<(Encoding, Vec<u8>)>,
950 malformed_plain: impl Fn(&[u8]) -> Vec<Vec<u8>>,
951 ) {
952 use crate::encodings::levels::LevelEncoder;
953 use crate::encodings::rle::RleEncoder;
954 use crate::util::bit_util::BitWriter;
955
956 fn levels(data: &[i16], max: i16, v2: bool, encoding: Encoding) -> Vec<u8> {
957 if max == 0 {
958 return vec![];
959 }
960 if encoding == Encoding::BIT_PACKED {
961 let mut encoder = BitWriter::new(data.len());
962 for &value in data {
963 encoder.put_value(value as u64, num_required_bits(max as u64) as usize);
964 }
965 return encoder.consume();
966 }
967 let mut encoder = if v2 {
968 LevelEncoder::v2_streaming(max)
969 } else {
970 LevelEncoder::v1_streaming(max)
971 };
972 encoder.put_with_observer(data, |_, _| {});
973 encoder.consume()
974 }
975
976 for (max_def, def, rep) in [
977 (0, vec![], vec![]),
978 (1, vec![1, 0, 1, 0, 1], vec![]),
979 (1, vec![0; 5], vec![]),
980 (3, vec![0, 1, 2, 3, 3, 1, 3], vec![0, 0, 0, 1, 1, 0, 1]),
982 (
984 1,
985 (0..2051).map(|i| i16::from(i % 3 == 0)).collect(),
986 vec![],
987 ),
988 ] {
989 let max_rep = i16::from(!rep.is_empty());
990 let num_levels = if max_def == 0 { 3 } else { def.len() };
991 let num_values = if max_def == 0 {
992 num_levels
993 } else {
994 def.iter().filter(|&&v| v == max_def).count()
995 };
996 let num_rows = if max_rep == 0 {
997 num_levels
998 } else {
999 rep.iter().filter(|&&v| v == 0).count()
1000 };
1001 let desc = Arc::new(ColumnDescriptor::new(
1002 Arc::new(
1003 SchemaType::primitive_type_builder("fixed", PhysicalType::FIXED_LEN_BYTE_ARRAY)
1004 .with_length(4)
1005 .build()
1006 .unwrap(),
1007 ),
1008 max_def,
1009 max_rep,
1010 ColumnPath::from("fixed"),
1011 ));
1012 let raw: Vec<u8> = b"\x04\0\0\0\xff\xff\xff\xffabcd"
1013 .as_chunks::<4>()
1014 .0
1015 .iter()
1016 .cycle()
1017 .take(num_values)
1018 .flatten()
1019 .copied()
1020 .collect();
1021 let malformed = malformed_plain(&raw);
1022
1023 for (v2, level_encoding) in [
1024 (false, Encoding::RLE),
1025 (false, Encoding::BIT_PACKED),
1026 (true, Encoding::RLE),
1027 ] {
1028 let rep_data = levels(&rep, max_rep, v2, level_encoding);
1029 let def_data = levels(&def, max_def, v2, level_encoding);
1030 let make_page = |encoding, payload: &[u8]| {
1031 let mut buf = rep_data.clone();
1032 buf.extend_from_slice(&def_data);
1033 buf.extend_from_slice(payload);
1034 if v2 {
1035 Page::DataPageV2 {
1036 buf: Bytes::from(buf),
1037 num_values: num_levels as u32,
1038 encoding,
1039 num_nulls: (num_levels - num_values) as u32,
1040 num_rows: num_rows as u32,
1041 def_levels_byte_len: def_data.len() as u32,
1042 rep_levels_byte_len: rep_data.len() as u32,
1043 is_compressed: false,
1044 statistics: None,
1045 }
1046 } else {
1047 Page::DataPage {
1048 buf: Bytes::from(buf),
1049 num_values: num_levels as u32,
1050 encoding,
1051 def_level_encoding: level_encoding,
1052 rep_level_encoding: level_encoding,
1053 statistics: None,
1054 }
1055 }
1056 };
1057 let make_reader = |pages| {
1058 ColumnReaderImpl::<FixedLenByteArrayType>::new(
1059 desc.clone(),
1060 Box::new(InMemoryPageReader::new(pages)),
1061 )
1062 };
1063 for (encoding, payload) in payloads(&raw) {
1064 let payload = payload.as_slice();
1065 let mut reader = make_reader(vec![make_page(encoding, payload)]);
1066 let (mut values, mut actual_def, mut actual_rep) = (vec![], vec![], vec![]);
1067 assert_eq!(
1068 reader
1069 .read_records(
1070 usize::MAX,
1071 Some(&mut actual_def),
1072 Some(&mut actual_rep),
1073 &mut values
1074 )
1075 .unwrap(),
1076 (num_rows, num_values, num_levels)
1077 );
1078 assert_eq!(actual_def, def);
1079 assert_eq!(actual_rep, rep);
1080 assert_eq!(
1081 values.iter().map(|v| v.data()).collect::<Vec<_>>(),
1082 raw.as_chunks::<4>().0.iter().collect::<Vec<_>>()
1083 );
1084
1085 let first_record_levels = if max_rep == 0 {
1086 1
1087 } else {
1088 rep.iter().skip(1).position(|&v| v == 0).unwrap() + 1
1089 };
1090 let first_record_values = if max_def == 0 {
1091 1
1092 } else {
1093 def[..first_record_levels]
1094 .iter()
1095 .filter(|&&v| v == max_def)
1096 .count()
1097 };
1098 let mut reader = make_reader(vec![make_page(encoding, payload)]);
1099 assert_eq!(reader.skip_records(1).unwrap(), 1);
1100 let mut values = vec![];
1101 reader
1102 .read_records(
1103 usize::MAX,
1104 Some(&mut vec![]),
1105 Some(&mut vec![]),
1106 &mut values,
1107 )
1108 .unwrap();
1109 assert_eq!(
1110 values.iter().map(|v| v.data()).collect::<Vec<_>>(),
1111 raw[first_record_values * 4..]
1112 .as_chunks::<4>()
1113 .0
1114 .iter()
1115 .collect::<Vec<_>>()
1116 );
1117 }
1118
1119 if !v2 && max_def != 0 && level_encoding == Encoding::RLE {
1120 let mut page = make_page(Encoding::PLAIN, &raw);
1121 if let Page::DataPage { num_values, .. } = &mut page {
1122 *num_values += 8;
1124 }
1125 let err = make_reader(vec![page])
1128 .read_records(
1129 usize::MAX,
1130 Some(&mut vec![]),
1131 Some(&mut vec![]),
1132 &mut vec![],
1133 )
1134 .unwrap_err()
1135 .to_string();
1136 assert!(
1137 err.contains("definition levels")
1138 || (max_rep != 0 && err.contains("repetition levels")),
1139 "{err}"
1140 );
1141 }
1142
1143 for payload in &malformed {
1144 for skip in [false, true] {
1147 let mut reader = make_reader(vec![make_page(Encoding::PLAIN, payload)]);
1148 let mut values = vec![];
1149 let mut result = if skip {
1150 reader.skip_records(1).map(|_| ())
1151 } else {
1152 reader
1153 .read_records(1, Some(&mut vec![]), Some(&mut vec![]), &mut values)
1154 .map(|_| ())
1155 };
1156 let provisional_values = values.len();
1157 if result.is_err() {
1158 assert!(values.is_empty());
1159 } else {
1160 assert!(!v2 && max_def != 0);
1161 result = if skip {
1162 reader.skip_records(usize::MAX).map(|_| ())
1163 } else {
1164 reader
1165 .read_records(
1166 usize::MAX,
1167 Some(&mut vec![]),
1168 Some(&mut vec![]),
1169 &mut values,
1170 )
1171 .map(|_| ())
1172 };
1173 }
1174 let err = result.unwrap_err().to_string();
1175 assert!(
1176 err.contains(
1177 "Invalid FIXED_LEN_BYTE_ARRAY PLAIN data page payload length"
1178 ),
1179 "v2={v2} {level_encoding} max_def={max_def} skip={skip}: {err}"
1180 );
1181 assert_eq!(values.len(), provisional_values);
1182 }
1183
1184 let mut indices = RleEncoder::new(1, 64);
1187 for _ in 0..num_values {
1188 indices.put(0);
1189 }
1190 let mut encoded = vec![1];
1191 encoded.extend(indices.consume());
1192 let mut reader = make_reader(vec![
1193 Page::DictionaryPage {
1194 buf: Bytes::from_static(b"abcd"),
1195 num_values: 1,
1196 encoding: Encoding::PLAIN,
1197 is_sorted: false,
1198 },
1199 make_page(Encoding::RLE_DICTIONARY, &encoded),
1200 make_page(Encoding::PLAIN, payload),
1201 ]);
1202 let mut values = vec![];
1203 let err = reader
1204 .read_records(
1205 usize::MAX,
1206 Some(&mut vec![]),
1207 Some(&mut vec![]),
1208 &mut values,
1209 )
1210 .unwrap_err()
1211 .to_string();
1212 assert!(err.contains("PLAIN data page payload length"), "{err}");
1213 assert_eq!(values.len(), num_values);
1214 assert!(values.iter().all(|v| v.data() == b"abcd"));
1215 }
1216 }
1217 }
1218 }
1219
1220 #[test]
1221 fn test_parse_v1_level_invalid_length() {
1222 let buf = Bytes::from(vec![10, 0, 0, 0]);
1224 let err = parse_v1_level(1, 100, Encoding::RLE, buf).unwrap_err();
1225 assert_eq!(
1226 err.to_string(),
1227 "Parquet error: not enough data to read levels"
1228 );
1229
1230 let buf = Bytes::from(vec![4, 0, 0]);
1232 let err = parse_v1_level(1, 100, Encoding::RLE, buf).unwrap_err();
1233 assert_eq!(
1234 err.to_string(),
1235 "Parquet error: not enough data to read levels"
1236 );
1237 }
1238
1239 const NUM_LEVELS: usize = 128;
1240 const NUM_PAGES: usize = 2;
1241 const MAX_DEF_LEVEL: i16 = 5;
1242 const MAX_REP_LEVEL: i16 = 5;
1243
1244 macro_rules! test {
1246 ($test_func:ident, i32, $func:ident, $def_level:expr, $rep_level:expr,
1248 $num_pages:expr, $num_levels:expr, $batch_size:expr, $min:expr, $max:expr) => {
1249 test_internal!(
1250 $test_func,
1251 Int32Type,
1252 get_test_int32_type,
1253 $func,
1254 $def_level,
1255 $rep_level,
1256 $num_pages,
1257 $num_levels,
1258 $batch_size,
1259 $min,
1260 $max
1261 );
1262 };
1263 ($test_func:ident, i64, $func:ident, $def_level:expr, $rep_level:expr,
1265 $num_pages:expr, $num_levels:expr, $batch_size:expr, $min:expr, $max:expr) => {
1266 test_internal!(
1267 $test_func,
1268 Int64Type,
1269 get_test_int64_type,
1270 $func,
1271 $def_level,
1272 $rep_level,
1273 $num_pages,
1274 $num_levels,
1275 $batch_size,
1276 $min,
1277 $max
1278 );
1279 };
1280 }
1281
1282 macro_rules! test_internal {
1283 ($test_func:ident, $ty:ident, $pty:ident, $func:ident, $def_level:expr,
1284 $rep_level:expr, $num_pages:expr, $num_levels:expr, $batch_size:expr,
1285 $min:expr, $max:expr) => {
1286 #[test]
1287 fn $test_func() {
1288 let desc = Arc::new(ColumnDescriptor::new(
1289 Arc::new($pty()),
1290 $def_level,
1291 $rep_level,
1292 ColumnPath::new(Vec::new()),
1293 ));
1294 let mut tester = ColumnReaderTester::<$ty>::new();
1295 tester.$func(desc, $num_pages, $num_levels, $batch_size, $min, $max);
1296 }
1297 };
1298 }
1299
1300 test!(
1301 test_read_plain_v1_int32,
1302 i32,
1303 plain_v1,
1304 MAX_DEF_LEVEL,
1305 MAX_REP_LEVEL,
1306 NUM_PAGES,
1307 NUM_LEVELS,
1308 16,
1309 i32::MIN,
1310 i32::MAX
1311 );
1312 test!(
1313 test_read_plain_v2_int32,
1314 i32,
1315 plain_v2,
1316 MAX_DEF_LEVEL,
1317 MAX_REP_LEVEL,
1318 NUM_PAGES,
1319 NUM_LEVELS,
1320 16,
1321 i32::MIN,
1322 i32::MAX
1323 );
1324
1325 test!(
1326 test_read_plain_v1_int32_uneven,
1327 i32,
1328 plain_v1,
1329 MAX_DEF_LEVEL,
1330 MAX_REP_LEVEL,
1331 NUM_PAGES,
1332 NUM_LEVELS,
1333 17,
1334 i32::MIN,
1335 i32::MAX
1336 );
1337 test!(
1338 test_read_plain_v2_int32_uneven,
1339 i32,
1340 plain_v2,
1341 MAX_DEF_LEVEL,
1342 MAX_REP_LEVEL,
1343 NUM_PAGES,
1344 NUM_LEVELS,
1345 17,
1346 i32::MIN,
1347 i32::MAX
1348 );
1349
1350 test!(
1351 test_read_plain_v1_int32_multi_page,
1352 i32,
1353 plain_v1,
1354 MAX_DEF_LEVEL,
1355 MAX_REP_LEVEL,
1356 NUM_PAGES,
1357 NUM_LEVELS,
1358 512,
1359 i32::MIN,
1360 i32::MAX
1361 );
1362 test!(
1363 test_read_plain_v2_int32_multi_page,
1364 i32,
1365 plain_v2,
1366 MAX_DEF_LEVEL,
1367 MAX_REP_LEVEL,
1368 NUM_PAGES,
1369 NUM_LEVELS,
1370 512,
1371 i32::MIN,
1372 i32::MAX
1373 );
1374
1375 test!(
1377 test_read_plain_v1_int32_required_non_repeated,
1378 i32,
1379 plain_v1,
1380 0,
1381 0,
1382 NUM_PAGES,
1383 NUM_LEVELS,
1384 16,
1385 i32::MIN,
1386 i32::MAX
1387 );
1388 test!(
1389 test_read_plain_v2_int32_required_non_repeated,
1390 i32,
1391 plain_v2,
1392 0,
1393 0,
1394 NUM_PAGES,
1395 NUM_LEVELS,
1396 16,
1397 i32::MIN,
1398 i32::MAX
1399 );
1400
1401 test!(
1402 test_read_plain_v1_int64,
1403 i64,
1404 plain_v1,
1405 1,
1406 1,
1407 NUM_PAGES,
1408 NUM_LEVELS,
1409 16,
1410 i64::MIN,
1411 i64::MAX
1412 );
1413 test!(
1414 test_read_plain_v2_int64,
1415 i64,
1416 plain_v2,
1417 1,
1418 1,
1419 NUM_PAGES,
1420 NUM_LEVELS,
1421 16,
1422 i64::MIN,
1423 i64::MAX
1424 );
1425
1426 test!(
1427 test_read_plain_v1_int64_uneven,
1428 i64,
1429 plain_v1,
1430 1,
1431 1,
1432 NUM_PAGES,
1433 NUM_LEVELS,
1434 17,
1435 i64::MIN,
1436 i64::MAX
1437 );
1438 test!(
1439 test_read_plain_v2_int64_uneven,
1440 i64,
1441 plain_v2,
1442 1,
1443 1,
1444 NUM_PAGES,
1445 NUM_LEVELS,
1446 17,
1447 i64::MIN,
1448 i64::MAX
1449 );
1450
1451 test!(
1452 test_read_plain_v1_int64_multi_page,
1453 i64,
1454 plain_v1,
1455 1,
1456 1,
1457 NUM_PAGES,
1458 NUM_LEVELS,
1459 512,
1460 i64::MIN,
1461 i64::MAX
1462 );
1463 test!(
1464 test_read_plain_v2_int64_multi_page,
1465 i64,
1466 plain_v2,
1467 1,
1468 1,
1469 NUM_PAGES,
1470 NUM_LEVELS,
1471 512,
1472 i64::MIN,
1473 i64::MAX
1474 );
1475
1476 test!(
1478 test_read_plain_v1_int64_required_non_repeated,
1479 i64,
1480 plain_v1,
1481 0,
1482 0,
1483 NUM_PAGES,
1484 NUM_LEVELS,
1485 16,
1486 i64::MIN,
1487 i64::MAX
1488 );
1489 test!(
1490 test_read_plain_v2_int64_required_non_repeated,
1491 i64,
1492 plain_v2,
1493 0,
1494 0,
1495 NUM_PAGES,
1496 NUM_LEVELS,
1497 16,
1498 i64::MIN,
1499 i64::MAX
1500 );
1501
1502 test!(
1503 test_read_dict_v1_int32_small,
1504 i32,
1505 dict_v1,
1506 MAX_DEF_LEVEL,
1507 MAX_REP_LEVEL,
1508 2,
1509 2,
1510 16,
1511 0,
1512 3
1513 );
1514 test!(
1515 test_read_dict_v2_int32_small,
1516 i32,
1517 dict_v2,
1518 MAX_DEF_LEVEL,
1519 MAX_REP_LEVEL,
1520 2,
1521 2,
1522 16,
1523 0,
1524 3
1525 );
1526
1527 test!(
1528 test_read_dict_v1_int32,
1529 i32,
1530 dict_v1,
1531 MAX_DEF_LEVEL,
1532 MAX_REP_LEVEL,
1533 NUM_PAGES,
1534 NUM_LEVELS,
1535 16,
1536 0,
1537 3
1538 );
1539 test!(
1540 test_read_dict_v2_int32,
1541 i32,
1542 dict_v2,
1543 MAX_DEF_LEVEL,
1544 MAX_REP_LEVEL,
1545 NUM_PAGES,
1546 NUM_LEVELS,
1547 16,
1548 0,
1549 3
1550 );
1551
1552 test!(
1553 test_read_dict_v1_int32_uneven,
1554 i32,
1555 dict_v1,
1556 MAX_DEF_LEVEL,
1557 MAX_REP_LEVEL,
1558 NUM_PAGES,
1559 NUM_LEVELS,
1560 17,
1561 0,
1562 3
1563 );
1564 test!(
1565 test_read_dict_v2_int32_uneven,
1566 i32,
1567 dict_v2,
1568 MAX_DEF_LEVEL,
1569 MAX_REP_LEVEL,
1570 NUM_PAGES,
1571 NUM_LEVELS,
1572 17,
1573 0,
1574 3
1575 );
1576
1577 test!(
1578 test_read_dict_v1_int32_multi_page,
1579 i32,
1580 dict_v1,
1581 MAX_DEF_LEVEL,
1582 MAX_REP_LEVEL,
1583 NUM_PAGES,
1584 NUM_LEVELS,
1585 512,
1586 0,
1587 3
1588 );
1589 test!(
1590 test_read_dict_v2_int32_multi_page,
1591 i32,
1592 dict_v2,
1593 MAX_DEF_LEVEL,
1594 MAX_REP_LEVEL,
1595 NUM_PAGES,
1596 NUM_LEVELS,
1597 512,
1598 0,
1599 3
1600 );
1601
1602 test!(
1603 test_read_dict_v1_int64,
1604 i64,
1605 dict_v1,
1606 MAX_DEF_LEVEL,
1607 MAX_REP_LEVEL,
1608 NUM_PAGES,
1609 NUM_LEVELS,
1610 16,
1611 0,
1612 3
1613 );
1614 test!(
1615 test_read_dict_v2_int64,
1616 i64,
1617 dict_v2,
1618 MAX_DEF_LEVEL,
1619 MAX_REP_LEVEL,
1620 NUM_PAGES,
1621 NUM_LEVELS,
1622 16,
1623 0,
1624 3
1625 );
1626
1627 #[test]
1628 fn test_read_batch_values_only() {
1629 test_read_batch_int32(16, 0, 0);
1630 }
1631
1632 #[test]
1633 fn test_read_batch_values_def_levels() {
1634 test_read_batch_int32(16, MAX_DEF_LEVEL, 0);
1635 }
1636
1637 #[test]
1638 fn test_read_batch_values_rep_levels() {
1639 test_read_batch_int32(16, 0, MAX_REP_LEVEL);
1640 }
1641
1642 #[test]
1643 fn test_read_batch_values_def_rep_levels() {
1644 test_read_batch_int32(128, MAX_DEF_LEVEL, MAX_REP_LEVEL);
1645 }
1646
1647 #[test]
1648 fn test_read_batch_adjust_after_buffering_page() {
1649 let primitive_type = get_test_int32_type();
1656 let desc = Arc::new(ColumnDescriptor::new(
1657 Arc::new(primitive_type),
1658 1,
1659 1,
1660 ColumnPath::new(Vec::new()),
1661 ));
1662
1663 let num_pages = 2;
1664 let num_levels = 4;
1665 let batch_size = 5;
1666
1667 let mut tester = ColumnReaderTester::<Int32Type>::new();
1668 tester.test_read_batch(
1669 desc,
1670 Encoding::RLE_DICTIONARY,
1671 num_pages,
1672 num_levels,
1673 batch_size,
1674 i32::MIN,
1675 i32::MAX,
1676 false,
1677 );
1678 }
1679
1680 fn get_test_int32_type() -> SchemaType {
1726 SchemaType::primitive_type_builder("a", PhysicalType::INT32)
1727 .with_repetition(Repetition::REQUIRED)
1728 .with_converted_type(ConvertedType::INT_32)
1729 .with_length(-1)
1730 .build()
1731 .expect("build() should be OK")
1732 }
1733
1734 fn get_test_int64_type() -> SchemaType {
1736 SchemaType::primitive_type_builder("a", PhysicalType::INT64)
1737 .with_repetition(Repetition::REQUIRED)
1738 .with_converted_type(ConvertedType::INT_64)
1739 .with_length(-1)
1740 .build()
1741 .expect("build() should be OK")
1742 }
1743
1744 fn test_read_batch_int32(batch_size: usize, max_def_level: i16, max_rep_level: i16) {
1749 let primitive_type = get_test_int32_type();
1750
1751 let desc = Arc::new(ColumnDescriptor::new(
1752 Arc::new(primitive_type),
1753 max_def_level,
1754 max_rep_level,
1755 ColumnPath::new(Vec::new()),
1756 ));
1757
1758 let mut tester = ColumnReaderTester::<Int32Type>::new();
1759 tester.test_read_batch(
1760 desc,
1761 Encoding::RLE_DICTIONARY,
1762 NUM_PAGES,
1763 NUM_LEVELS,
1764 batch_size,
1765 i32::MIN,
1766 i32::MAX,
1767 false,
1768 );
1769 }
1770
1771 struct ColumnReaderTester<T: DataType>
1772 where
1773 T::T: PartialOrd + SampleUniform + Copy,
1774 {
1775 rep_levels: Vec<i16>,
1776 def_levels: Vec<i16>,
1777 values: Vec<T::T>,
1778 }
1779
1780 impl<T: DataType> ColumnReaderTester<T>
1781 where
1782 T::T: PartialOrd + SampleUniform + Copy,
1783 {
1784 pub fn new() -> Self {
1785 Self {
1786 rep_levels: Vec::new(),
1787 def_levels: Vec::new(),
1788 values: Vec::new(),
1789 }
1790 }
1791
1792 fn plain_v1(
1794 &mut self,
1795 desc: ColumnDescPtr,
1796 num_pages: usize,
1797 num_levels: usize,
1798 batch_size: usize,
1799 min: T::T,
1800 max: T::T,
1801 ) {
1802 self.test_read_batch_general(
1803 desc,
1804 Encoding::PLAIN,
1805 num_pages,
1806 num_levels,
1807 batch_size,
1808 min,
1809 max,
1810 false,
1811 );
1812 }
1813
1814 fn plain_v2(
1816 &mut self,
1817 desc: ColumnDescPtr,
1818 num_pages: usize,
1819 num_levels: usize,
1820 batch_size: usize,
1821 min: T::T,
1822 max: T::T,
1823 ) {
1824 self.test_read_batch_general(
1825 desc,
1826 Encoding::PLAIN,
1827 num_pages,
1828 num_levels,
1829 batch_size,
1830 min,
1831 max,
1832 true,
1833 );
1834 }
1835
1836 fn dict_v1(
1838 &mut self,
1839 desc: ColumnDescPtr,
1840 num_pages: usize,
1841 num_levels: usize,
1842 batch_size: usize,
1843 min: T::T,
1844 max: T::T,
1845 ) {
1846 self.test_read_batch_general(
1847 desc,
1848 Encoding::RLE_DICTIONARY,
1849 num_pages,
1850 num_levels,
1851 batch_size,
1852 min,
1853 max,
1854 false,
1855 );
1856 }
1857
1858 fn dict_v2(
1860 &mut self,
1861 desc: ColumnDescPtr,
1862 num_pages: usize,
1863 num_levels: usize,
1864 batch_size: usize,
1865 min: T::T,
1866 max: T::T,
1867 ) {
1868 self.test_read_batch_general(
1869 desc,
1870 Encoding::RLE_DICTIONARY,
1871 num_pages,
1872 num_levels,
1873 batch_size,
1874 min,
1875 max,
1876 true,
1877 );
1878 }
1879
1880 #[expect(clippy::too_many_arguments)]
1883 fn test_read_batch_general(
1884 &mut self,
1885 desc: ColumnDescPtr,
1886 encoding: Encoding,
1887 num_pages: usize,
1888 num_levels: usize,
1889 batch_size: usize,
1890 min: T::T,
1891 max: T::T,
1892 use_v2: bool,
1893 ) {
1894 self.test_read_batch(
1895 desc, encoding, num_pages, num_levels, batch_size, min, max, use_v2,
1896 );
1897 }
1898
1899 #[expect(clippy::too_many_arguments)]
1902 fn test_read_batch(
1903 &mut self,
1904 desc: ColumnDescPtr,
1905 encoding: Encoding,
1906 num_pages: usize,
1907 num_levels: usize,
1908 batch_size: usize,
1909 min: T::T,
1910 max: T::T,
1911 use_v2: bool,
1912 ) {
1913 let mut pages = VecDeque::new();
1914 make_pages::<T>(
1915 desc.clone(),
1916 encoding,
1917 num_pages,
1918 num_levels,
1919 min,
1920 max,
1921 &mut self.def_levels,
1922 &mut self.rep_levels,
1923 &mut self.values,
1924 &mut pages,
1925 use_v2,
1926 );
1927 let max_def_level = desc.max_def_level();
1928 let max_rep_level = desc.max_rep_level();
1929 let page_reader = InMemoryPageReader::new(pages);
1930 let column_reader = get_column_reader(desc, Box::new(page_reader));
1931 let mut typed_column_reader = get_typed_column_reader::<T>(column_reader);
1932
1933 let mut values = Vec::new();
1934 let mut def_levels = Vec::new();
1935 let mut rep_levels = Vec::new();
1936
1937 let mut curr_values_read = 0;
1938 let mut curr_levels_read = 0;
1939 loop {
1940 let (_, values_read, levels_read) = typed_column_reader
1941 .read_records(
1942 batch_size,
1943 Some(&mut def_levels),
1944 Some(&mut rep_levels),
1945 &mut values,
1946 )
1947 .expect("read_batch() should be OK");
1948
1949 curr_values_read += values_read;
1950 curr_levels_read += levels_read;
1951
1952 if values_read == 0 && levels_read == 0 {
1953 break;
1954 }
1955 }
1956
1957 assert_eq!(values, self.values, "values content doesn't match");
1958
1959 if max_def_level > 0 {
1960 assert_eq!(
1961 def_levels, self.def_levels,
1962 "definition levels content doesn't match"
1963 );
1964 }
1965
1966 if max_rep_level > 0 {
1967 assert_eq!(
1968 rep_levels, self.rep_levels,
1969 "repetition levels content doesn't match"
1970 );
1971 }
1972
1973 assert!(
1974 curr_levels_read >= curr_values_read,
1975 "expected levels read to be greater than values read"
1976 );
1977 }
1978 }
1979
1980 #[test]
1998 fn test_skip_records_v2_page_skip_accounts_for_partial() {
1999 use crate::encodings::levels::LevelEncoder;
2000
2001 let max_rep_level: i16 = 1;
2002 let max_def_level: i16 = 1;
2003
2004 let primitive_type = SchemaType::primitive_type_builder("element", PhysicalType::INT32)
2006 .with_repetition(Repetition::REQUIRED)
2007 .build()
2008 .unwrap();
2009 let desc = Arc::new(ColumnDescriptor::new(
2010 Arc::new(primitive_type),
2011 max_def_level,
2012 max_rep_level,
2013 ColumnPath::new(vec!["list".to_string(), "element".to_string()]),
2014 ));
2015
2016 let make_v2_page =
2018 |rep_levels: &[i16], def_levels: &[i16], values: &[i32], num_rows: u32| -> Page {
2019 let mut rep_enc = LevelEncoder::v2_streaming(max_rep_level);
2020 rep_enc.put_with_observer(rep_levels, |_, _| {});
2021 let rep_bytes = rep_enc.consume();
2022
2023 let mut def_enc = LevelEncoder::v2_streaming(max_def_level);
2024 def_enc.put_with_observer(def_levels, |_, _| {});
2025 let def_bytes = def_enc.consume();
2026
2027 let val_bytes: Vec<u8> = values.iter().flat_map(|v| v.to_le_bytes()).collect();
2028
2029 let mut buf = Vec::new();
2030 buf.extend_from_slice(&rep_bytes);
2031 buf.extend_from_slice(&def_bytes);
2032 buf.extend_from_slice(&val_bytes);
2033
2034 Page::DataPageV2 {
2035 buf: Bytes::from(buf),
2036 num_values: rep_levels.len() as u32,
2037 encoding: Encoding::PLAIN,
2038 num_nulls: 0,
2039 num_rows,
2040 def_levels_byte_len: def_bytes.len() as u32,
2041 rep_levels_byte_len: rep_bytes.len() as u32,
2042 is_compressed: false,
2043 statistics: None,
2044 }
2045 };
2046
2047 let page1 = make_v2_page(&[0, 1, 0, 1], &[1, 1, 1, 1], &[10, 20, 30, 40], 2);
2053
2054 let page2 = make_v2_page(&[0, 1, 0, 1], &[1, 1, 1, 1], &[50, 60, 70, 80], 2);
2056
2057 let page3 = make_v2_page(&[0, 1], &[1, 1], &[90, 100], 1);
2059
2060 let pages = VecDeque::from(vec![page1, page2, page3]);
2062 let page_reader = InMemoryPageReader::new(pages);
2063 let column_reader = get_column_reader(desc, Box::new(page_reader));
2064 let mut typed_reader = get_typed_column_reader::<Int32Type>(column_reader);
2065
2066 let skipped = typed_reader.skip_records(1).unwrap();
2072 assert_eq!(skipped, 1);
2073
2074 let skipped = typed_reader.skip_records(2).unwrap();
2089 assert_eq!(skipped, 2);
2090
2091 let mut values = Vec::new();
2093 let mut def_levels = Vec::new();
2094 let mut rep_levels = Vec::new();
2095
2096 let (records, values_read, levels_read) = typed_reader
2097 .read_records(1, Some(&mut def_levels), Some(&mut rep_levels), &mut values)
2098 .unwrap();
2099
2100 assert_eq!(records, 1, "should read exactly 1 record");
2104 assert_eq!(levels_read, 2, "should read 2 levels for the record");
2105 assert_eq!(values_read, 2, "should read 2 non-null values");
2106 assert_eq!(values, vec![70, 80], "should contain 4th record's values");
2107 assert_eq!(rep_levels, vec![0, 1], "rep levels for a 2-element list");
2108 assert_eq!(def_levels, vec![1, 1], "def levels (all non-null)");
2109 }
2110}