[
https://issues.apache.org/jira/browse/ARROW-9790?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17180510#comment-17180510
]
Andrew Lamb commented on ARROW-9790:
------------------------------------
Here is the reproducer code, to save you from having to download it:
{code}
use std::{fs, path::Path, rc::Rc};
use parquet::{
file::{
properties::WriterProperties,
writer::{FileWriter, SerializedFileWriter},
},
schema::parser::parse_message_type, column::writer::ColumnWriter,
};
use parquet::arrow::arrow_reader::ArrowReader;
use arrow::record_batch::RecordBatchReader;
fn main() {
make_repro_file();
println!("Size when reading with batch_size 100 : {}",
read_record_batches(100));
println!("Size when reading with batch_size 7 : {}",
read_record_batches(7));
println!("Size when reading with batch_size 5 : {}",
read_record_batches(5));
}
/// create repro.parquet file
fn make_repro_file() {
let path = Path::new("/tmp/repro.parquet");
let message_type = "
message schema {
REQUIRED INT32 b;
}
";
let schema = Rc::new(parse_message_type(message_type).unwrap());
let props = Rc::new(WriterProperties::builder().build());
let file = fs::File::create(&path).unwrap();
let mut writer = SerializedFileWriter::new(file, schema, props).unwrap();
let data = [1,2,3,4,5];
for _ in 0..4 {
let mut row_group_writer = writer.next_row_group().unwrap();
if let Some(mut col_writer) = row_group_writer.next_column().unwrap() {
match &mut col_writer {
ColumnWriter::Int32ColumnWriter(w) => {
w.write_batch(&data, None, None).expect("Writing data");
},
_=> unimplemented!("unexpected type")
}
row_group_writer.close_column(col_writer).unwrap();
}
writer.close_row_group(row_group_writer).unwrap();
}
writer.close().unwrap();
println!("wrote 20 rows in 4 row groups to /tmp/repro.parquet");
}
// returns the number of total rows, using batch_size
fn read_record_batches(batch_size: usize) -> usize {
//println!("Opening the file....");
let r = fs::File::open("/tmp/repro.parquet").unwrap();
let parquet_reader =
parquet::file::reader::SerializedFileReader::new(r).unwrap();
let mut reader =
parquet::arrow::arrow_reader::ParquetFileArrowReader::new(Rc::new(parquet_reader));
let mut record_batch_reader = reader.get_record_reader(batch_size).unwrap();
let mut total_rows = 0;
loop {
let rb = record_batch_reader.next_batch();
match rb {
Err(e) => println!("WARNING: error reading batch: {:?}, SKIPPING",
e),
Ok(Some(rb)) => {
//println!("Successfully got a new record batch of {} rows",
rb.num_rows());
total_rows += rb.num_rows();
},
Ok(None) => {
//println!("No more batches");
break;
}
}
}
total_rows
}
{code}
> [Rust] [Parquet] ParquetFileArrowReader fails to decode all pages if batches
> fall exactly on row group boundaries
> -----------------------------------------------------------------------------------------------------------------
>
> Key: ARROW-9790
> URL: https://issues.apache.org/jira/browse/ARROW-9790
> Project: Apache Arrow
> Issue Type: Bug
> Reporter: Andrew Lamb
> Assignee: Andrew Lamb
> Priority: Major
> Attachments: parquet_file_arrow_reader.zip
>
>
> When I was reading a parquet file into RecordBatches using
> {{ParquetFileArrowReader}} that had row groups that were 100,000 rows in
> length with a batch size of 60,000, after reading 300,000 rows successfully,
> I started seeing this error
> {code}
> ParquetError("Parquet error: Not all children array length are the same!")
> {code}
> Upon investigation, I found that when reading with
> {{ParquetFileArrowReader}}, if the parquet input file has multiple row
> groups, and if a batch happens to end at the end of a row group for Int or
> Float, no subsequent row groups are read
> Visually:
> {code}
> +-----+
> | RG1 |
> | |
> +-----+ <-- If a batch ends exactly at the end of this row group (page), RG2
> is never read
> +-----+
> | RG2 |
> | |
> +-----+
> {code}
> A reproducer is attached. 20 values should be read by the
> {{ParquetFileArrowReader}} regardless of the batch size. However, when using
> batch sizes such as {{5}} or {{3}} (which fall on a boundary between row
> groups) not all the rows are read.
> To run the reproducer, decompress the attachment
> [^parquet_file_arrow_reader.zip] and do `cargo run`
> The output is as follows:
> {code}
> wrote 20 rows in 4 row groups to /tmp/repro.parquet
> Size when reading with batch_size 100 : 20
> Size when reading with batch_size 7 : 20
> Size when reading with batch_size 5 : 5
> {code}
> The expected output is as follows (should always read 20 rows, regardless of
> the batch size):
> {code}
> wrote 20 rows in 4 row groups to /tmp/repro.parquet
> Size when reading with batch_size 100 : 20
> Size when reading with batch_size 7 : 20
> Size when reading with batch_size 5 : 20
> {code}
> h2. Workaround
> Use a different batch size that will not fall on record batch boundaries
--
This message was sent by Atlassian Jira
(v8.3.4#803005)