Skip to content

Commit

Permalink
Box Parquet Schema/Reader for List to avoid infinite types. Hopefully…
Browse files Browse the repository at this point in the history
… can revert in future
  • Loading branch information
alecmocatta committed Jun 23, 2020
1 parent 7cb4b7d commit 4ea6447
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 6 deletions.
13 changes: 7 additions & 6 deletions amadeus-parquet/src/internal/record/impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -523,12 +523,13 @@ fn parse_list<T: ParquetData>(
Err(ParquetError::General(String::from("Couldn't parse Vec<T>")))
}

// TODO: remove boxing of schema & reader
impl<T: Data> ParquetData for List<T>
where
T: ParquetData,
{
default type Schema = ListSchema<T::Schema>;
default type Reader = RepeatedReader<T::Reader>;
default type Schema = ListSchema<Box<T::Schema>>;
default type Reader = RepeatedReader<Box<T::Reader>>;
type Predicate = T::Predicate;

default fn parse(
Expand All @@ -545,10 +546,10 @@ where
if repetition == Some(Repetition::Repeated) {
return Ok((
schema.name().to_owned(),
type_coerce(ListSchema(
type_coerce(Box::new(ListSchema(
T::parse(&schema, predicate, Some(Repetition::Required))?.1,
ListSchemaType::Repeated,
)),
))),
));
}
Err(ParquetError::General(String::from("Couldn't parse Vec<T>")))
Expand All @@ -559,9 +560,9 @@ where
paths: &mut HashMap<ColumnPath, ColumnReader>, batch_size: usize,
) -> Self::Reader {
let schema: &ListSchema<T::Schema> = type_coerce(schema);
type_coerce(list_reader::<T>(
type_coerce(Box::new(list_reader::<T>(
schema, path, def_level, rep_level, paths, batch_size,
))
)))
}
}

Expand Down
34 changes: 34 additions & 0 deletions amadeus-parquet/src/internal/record/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,17 @@ pub trait Schema: Debug {
) -> fmt::Result;
}

impl<T: ?Sized> Schema for Box<T>
where
T: Schema,
{
fn fmt(
self_: Option<&Self>, r: Option<Repetition>, name: Option<&str>, f: &mut fmt::Formatter,
) -> fmt::Result {
<T as Schema>::fmt(self_.map(|self_| &**self_), r, name, f)
}
}

/// This trait is implemented by Readers so the values of one or more columns can be read
/// while taking into account the definition and repetition levels for optional and
/// repeated values.
Expand All @@ -197,3 +208,26 @@ pub trait Reader {
/// Get the current repetition level.
fn current_rep_level(&self) -> i16;
}

impl<T: ?Sized> Reader for Box<T>
where
T: Reader,
{
type Item = T::Item;

fn read(&mut self, def_level: i16, rep_level: i16) -> Result<Self::Item> {
(&mut **self).read(def_level, rep_level)
}
fn advance_columns(&mut self) -> Result<()> {
(&mut **self).advance_columns()
}
fn has_next(&self) -> bool {
(&**self).has_next()
}
fn current_def_level(&self) -> i16 {
(&**self).current_def_level()
}
fn current_rep_level(&self) -> i16 {
(&**self).current_rep_level()
}
}

0 comments on commit 4ea6447

Please sign in to comment.