Open a partitioned JSON file. If `file_meta.range` is `None`, the entire file is opened. Else `file_meta.range` is `Some(FileRange{start, end})`, which corresponds to the byte range [start, end) within the file. Note: `start` or `end` might be in the middle of some lines. In such cases, the following rules are applied to determine which lines to read: 1. The first line of the partition is the li
(&self, partitioned_file: PartitionedFile)
| 247 | /// |
| 248 | /// Note: JSON array format does not support range-based scanning. |
| 249 | fn open(&self, partitioned_file: PartitionedFile) -> Result<FileOpenFuture> { |
| 250 | let store = Arc::clone(&self.object_store); |
| 251 | let schema = Arc::clone(&self.projected_schema); |
| 252 | let batch_size = self.batch_size; |
| 253 | let file_compression_type = self.file_compression_type.to_owned(); |
| 254 | let newline_delimited = self.newline_delimited; |
| 255 | |
| 256 | // JSON array format requires reading the complete file |
| 257 | if !newline_delimited && partitioned_file.range.is_some() { |
| 258 | return Err(DataFusionError::NotImplemented( |
| 259 | "JSON array format does not support range-based file scanning. \ |
| 260 | Disable repartition_file_scans or use newline-delimited JSON format." |
| 261 | .to_string(), |
| 262 | )); |
| 263 | } |
| 264 | |
| 265 | Ok(Box::pin(async move { |
| 266 | let file_size = partitioned_file.object_meta.size; |
| 267 | let location = &partitioned_file.object_meta.location; |
| 268 | |
| 269 | if let Some(file_range) = partitioned_file.range.as_ref() { |
| 270 | let raw_start: u64 = file_range.start.try_into().map_err(|_| { |
| 271 | exec_datafusion_err!( |
| 272 | "Expected start range to fit in u64, got {}", |
| 273 | file_range.start |
| 274 | ) |
| 275 | })?; |
| 276 | let raw_end: u64 = file_range.end.try_into().map_err(|_| { |
| 277 | exec_datafusion_err!( |
| 278 | "Expected end range to fit in u64, got {}", |
| 279 | file_range.end |
| 280 | ) |
| 281 | })?; |
| 282 | |
| 283 | let aligned_stream = AlignedBoundaryStream::new( |
| 284 | Arc::clone(&store), |
| 285 | location.clone(), |
| 286 | raw_start, |
| 287 | raw_end, |
| 288 | file_size, |
| 289 | b'\n', |
| 290 | ) |
| 291 | .await? |
| 292 | .map_err(DataFusionError::from); |
| 293 | |
| 294 | let decoder = ReaderBuilder::new(schema) |
| 295 | .with_batch_size(batch_size) |
| 296 | .build_decoder()?; |
| 297 | let input = file_compression_type |
| 298 | .convert_stream(aligned_stream.boxed())? |
| 299 | .fuse(); |
| 300 | let stream = deserialize_stream( |
| 301 | input, |
| 302 | DecoderDeserializer::new(JsonDecoder::new(decoder)), |
| 303 | ); |
| 304 | return Ok(stream.map_err(Into::into).boxed()); |
| 305 | } |
| 306 |