Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions arrow-json/src/reader/list_array.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,18 +34,18 @@ pub struct ListArrayDecoder<O> {
impl<O: OffsetSizeTrait> ListArrayDecoder<O> {
pub fn new(
ctx: &DecoderContext,
data_type: DataType,
data_type: &DataType,
is_nullable: bool,
) -> Result<Self, ArrowError> {
let field = match &data_type {
let field = match data_type {
DataType::List(f) if !O::IS_LARGE => f,
DataType::LargeList(f) if O::IS_LARGE => f,
_ => unreachable!(),
};
let decoder = ctx.make_decoder(field.data_type().clone(), field.is_nullable())?;
let decoder = ctx.make_decoder(field.data_type(), field.is_nullable())?;

Ok(Self {
data_type,
data_type: data_type.clone(),
decoder,
phantom: Default::default(),
is_nullable,
Expand Down
10 changes: 5 additions & 5 deletions arrow-json/src/reader/map_array.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,10 @@ pub struct MapArrayDecoder {
impl MapArrayDecoder {
pub fn new(
ctx: &DecoderContext,
data_type: DataType,
data_type: &DataType,
is_nullable: bool,
) -> Result<Self, ArrowError> {
let fields = match &data_type {
let fields = match data_type {
DataType::Map(_, true) => {
return Err(ArrowError::NotYetImplemented(
"Decoding MapArray with sorted fields".to_string(),
Expand All @@ -53,11 +53,11 @@ impl MapArrayDecoder {
_ => unreachable!(),
};

let keys = ctx.make_decoder(fields[0].data_type().clone(), fields[0].is_nullable())?;
let values = ctx.make_decoder(fields[1].data_type().clone(), fields[1].is_nullable())?;
let keys = ctx.make_decoder(fields[0].data_type(), fields[0].is_nullable())?;
let values = ctx.make_decoder(fields[1].data_type(), fields[1].is_nullable())?;

Ok(Self {
data_type,
data_type: data_type.clone(),
keys,
values,
is_nullable,
Expand Down
24 changes: 13 additions & 11 deletions arrow-json/src/reader/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ use crate::StructMode;
use crate::reader::binary_array::{
BinaryArrayDecoder, BinaryViewDecoder, FixedSizeBinaryArrayDecoder,
};
use std::borrow::Cow;
use std::io::BufRead;
use std::sync::Arc;

Expand Down Expand Up @@ -295,20 +296,21 @@ impl ReaderBuilder {

/// Create a [`Decoder`]
pub fn build_decoder(self) -> Result<Decoder, ArrowError> {
let (data_type, nullable) = match self.is_field {
false => (DataType::Struct(self.schema.fields.clone()), false),
true => {
let field = &self.schema.fields[0];
(field.data_type().clone(), field.is_nullable())
}
let (data_type, nullable) = if self.is_field {
let field = &self.schema.fields[0];
let data_type = Cow::Borrowed(field.data_type());
(data_type, field.is_nullable())
} else {
let data_type = Cow::Owned(DataType::Struct(self.schema.fields.clone()));
(data_type, false)
};

let ctx = DecoderContext {
coerce_primitive: self.coerce_primitive,
strict_mode: self.strict_mode,
struct_mode: self.struct_mode,
};
let decoder = ctx.make_decoder(data_type, nullable)?;
let decoder = ctx.make_decoder(data_type.as_ref(), nullable)?;

let num_fields = self.schema.flattened_fields().len();

Expand Down Expand Up @@ -713,7 +715,7 @@ impl DecoderContext {
/// implementation.
fn make_decoder(
&self,
data_type: DataType,
data_type: &DataType,
is_nullable: bool,
) -> Result<Box<dyn ArrayDecoder>, ArrowError> {
make_decoder(self, data_type, is_nullable)
Expand All @@ -728,12 +730,12 @@ macro_rules! primitive_decoder {

fn make_decoder(
ctx: &DecoderContext,
data_type: DataType,
data_type: &DataType,
is_nullable: bool,
) -> Result<Box<dyn ArrayDecoder>, ArrowError> {
let coerce_primitive = ctx.coerce_primitive();
downcast_integer! {
data_type => (primitive_decoder, data_type),
*data_type => (primitive_decoder, data_type),
DataType::Null => Ok(Box::<NullArrayDecoder>::default()),
DataType::Float16 => primitive_decoder!(Float16Type, data_type),
DataType::Float32 => primitive_decoder!(Float32Type, data_type),
Expand Down Expand Up @@ -792,7 +794,7 @@ fn make_decoder(
DataType::FixedSizeBinary(len) => Ok(Box::new(FixedSizeBinaryArrayDecoder::new(len))),
DataType::BinaryView => Ok(Box::new(BinaryViewDecoder::default())),
DataType::Map(_, _) => Ok(Box::new(MapArrayDecoder::new(ctx, data_type, is_nullable)?)),
d => Err(ArrowError::NotYetImplemented(format!("Support for {d} in JSON reader")))
_ => Err(ArrowError::NotYetImplemented(format!("Support for {data_type} in JSON reader")))
}
}

Expand Down
4 changes: 2 additions & 2 deletions arrow-json/src/reader/primitive_array.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,9 @@ pub struct PrimitiveArrayDecoder<P: ArrowPrimitiveType> {
}

impl<P: ArrowPrimitiveType> PrimitiveArrayDecoder<P> {
pub fn new(data_type: DataType) -> Self {
pub fn new(data_type: &DataType) -> Self {
Self {
data_type,
data_type: data_type.clone(),
phantom: Default::default(),
}
}
Expand Down
20 changes: 11 additions & 9 deletions arrow-json/src/reader/struct_array.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,28 +81,30 @@ pub struct StructArrayDecoder {
impl StructArrayDecoder {
pub fn new(
ctx: &DecoderContext,
data_type: DataType,
data_type: &DataType,
is_nullable: bool,
) -> Result<Self, ArrowError> {
let struct_mode = ctx.struct_mode();
let fields = struct_fields(&data_type);

// If this struct nullable, need to permit nullability in child array
// StructArrayDecoder::decode verifies that if the child is not nullable
// it doesn't contain any nulls not masked by its parent
Comment on lines -90 to -92
Copy link
Contributor Author

@scovich scovich Jan 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#9271 merged too quickly... this comment was supposed to remain inside the .map call. So I'm restoring this code back to follow the original upstream approach, instead of opening a separate PR just for that.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thank you

let fields = struct_fields(data_type);
let decoders = fields
.iter()
.map(|f| ctx.make_decoder(f.data_type().clone(), f.is_nullable() || is_nullable))
.map(|f| {
// If this struct nullable, need to permit nullability in child array
// StructArrayDecoder::decode verifies that if the child is not nullable
// it doesn't contain any nulls not masked by its parent
let nullable = f.is_nullable() || is_nullable;
ctx.make_decoder(f.data_type(), nullable)
})
.collect::<Result<Vec<_>, ArrowError>>()?;

let struct_mode = ctx.struct_mode();
let field_name_to_index = if struct_mode == StructMode::ObjectOnly {
build_field_index(fields)
} else {
None
};

Ok(Self {
data_type,
data_type: data_type.clone(),
decoders,
strict_mode: ctx.strict_mode(),
is_nullable,
Expand Down
4 changes: 2 additions & 2 deletions arrow-json/src/reader/timestamp_array.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,9 @@ pub struct TimestampArrayDecoder<P: ArrowTimestampType, Tz: TimeZone> {
}

impl<P: ArrowTimestampType, Tz: TimeZone> TimestampArrayDecoder<P, Tz> {
pub fn new(data_type: DataType, timezone: Tz) -> Self {
pub fn new(data_type: &DataType, timezone: Tz) -> Self {
Self {
data_type,
data_type: data_type.clone(),
timezone,
phantom: Default::default(),
}
Expand Down
Loading