1#![warn(missing_docs)]
25use arrow_buffer::{IntervalDayTime, IntervalMonthDayNano, ScalarBuffer};
26use hex::decode;
27use num::BigInt;
28use num::Signed;
29use serde::{Deserialize, Serialize};
30use serde_json::{Map as SJMap, Value};
31use std::collections::HashMap;
32use std::sync::Arc;
33
34use arrow::array::*;
35use arrow::buffer::{Buffer, MutableBuffer};
36use arrow::datatypes::*;
37use arrow::error::{ArrowError, Result};
38use arrow::util::bit_util;
39
40mod datatype;
41mod field;
42mod schema;
43
44pub use datatype::*;
45pub use field::*;
46pub use schema::*;
47
48#[derive(Deserialize, Serialize, Debug)]
52pub struct ArrowJson {
53 pub schema: ArrowJsonSchema,
55 pub batches: Vec<ArrowJsonBatch>,
57 #[serde(skip_serializing_if = "Option::is_none")]
59 pub dictionaries: Option<Vec<ArrowJsonDictionaryBatch>>,
60}
61
62#[derive(Deserialize, Serialize, Debug)]
66pub struct ArrowJsonSchema {
67 pub fields: Vec<ArrowJsonField>,
69 #[serde(skip_serializing_if = "Option::is_none")]
71 pub metadata: Option<Vec<HashMap<String, String>>>,
72}
73
74#[derive(Deserialize, Serialize, Debug)]
76pub struct ArrowJsonField {
77 pub name: String,
79 #[serde(rename = "type")]
82 pub field_type: Value,
83 pub nullable: bool,
85 pub children: Vec<ArrowJsonField>,
87 #[serde(skip_serializing_if = "Option::is_none")]
89 pub dictionary: Option<ArrowJsonFieldDictionary>,
90 #[serde(skip_serializing_if = "Option::is_none")]
92 pub metadata: Option<Value>,
93}
94
95impl From<&FieldRef> for ArrowJsonField {
96 fn from(value: &FieldRef) -> Self {
97 Self::from(value.as_ref())
98 }
99}
100
101impl From<&Field> for ArrowJsonField {
102 fn from(field: &Field) -> Self {
103 let metadata_value = match field.metadata().is_empty() {
104 false => {
105 let mut array = Vec::new();
106 for (k, v) in field.metadata() {
107 let mut kv_map = SJMap::new();
108 kv_map.insert(k.clone(), Value::String(v.clone()));
109 array.push(Value::Object(kv_map));
110 }
111 if !array.is_empty() {
112 Some(Value::Array(array))
113 } else {
114 None
115 }
116 }
117 _ => None,
118 };
119
120 Self {
121 name: field.name().to_string(),
122 field_type: data_type_to_json(field.data_type()),
123 nullable: field.is_nullable(),
124 children: vec![],
125 dictionary: None, metadata: metadata_value,
127 }
128 }
129}
130
131#[derive(Deserialize, Serialize, Debug)]
133pub struct ArrowJsonFieldDictionary {
134 pub id: i64,
136 #[serde(rename = "indexType")]
138 pub index_type: DictionaryIndexType,
139 #[serde(rename = "isOrdered")]
141 pub is_ordered: bool,
142}
143
144#[derive(Deserialize, Serialize, Debug)]
146pub struct DictionaryIndexType {
147 pub name: String,
149 #[serde(rename = "isSigned")]
151 pub is_signed: bool,
152 #[serde(rename = "bitWidth")]
154 pub bit_width: i64,
155}
156
157#[derive(Deserialize, Serialize, Debug, Clone)]
159pub struct ArrowJsonBatch {
160 count: usize,
161 pub columns: Vec<ArrowJsonColumn>,
163}
164
165#[derive(Deserialize, Serialize, Debug, Clone)]
167#[allow(non_snake_case)]
168pub struct ArrowJsonDictionaryBatch {
169 pub id: i64,
171 pub data: ArrowJsonBatch,
173}
174
175#[derive(Deserialize, Serialize, Clone, Debug)]
177pub struct ArrowJsonColumn {
178 name: String,
179 pub count: usize,
181 #[serde(rename = "VALIDITY")]
183 pub validity: Option<Vec<u8>>,
184 #[serde(rename = "DATA")]
186 pub data: Option<Vec<Value>>,
187 #[serde(rename = "OFFSET")]
189 pub offset: Option<Vec<Value>>, #[serde(rename = "TYPE_ID")]
192 pub type_id: Option<Vec<i8>>,
193 pub children: Option<Vec<ArrowJsonColumn>>,
195}
196
197impl ArrowJson {
198 pub fn equals_reader(&self, reader: &mut dyn RecordBatchReader) -> Result<bool> {
200 if !self.schema.equals_schema(&reader.schema()) {
201 return Ok(false);
202 }
203
204 for json_batch in self.get_record_batches()?.into_iter() {
205 let batch = reader.next();
206 match batch {
207 Some(Ok(batch)) => {
208 if json_batch != batch {
209 println!("json: {json_batch:?}");
210 println!("batch: {batch:?}");
211 return Ok(false);
212 }
213 }
214 Some(Err(e)) => return Err(e),
215 None => return Ok(false),
216 }
217 }
218
219 Ok(true)
220 }
221
222 pub fn get_record_batches(&self) -> Result<Vec<RecordBatch>> {
224 let schema = self.schema.to_arrow_schema()?;
225
226 let mut dictionaries = HashMap::new();
227 self.dictionaries.iter().for_each(|dict_batches| {
228 dict_batches.iter().for_each(|d| {
229 dictionaries.insert(d.id, d.clone());
230 });
231 });
232
233 let batches: Result<Vec<_>> = self
234 .batches
235 .iter()
236 .map(|col| record_batch_from_json(&schema, col.clone(), Some(&dictionaries)))
237 .collect();
238
239 batches
240 }
241}
242
243impl ArrowJsonSchema {
244 fn equals_schema(&self, schema: &Schema) -> bool {
246 let field_len = self.fields.len();
247 if field_len != schema.fields().len() {
248 return false;
249 }
250 for i in 0..field_len {
251 let json_field = &self.fields[i];
252 let field = schema.field(i);
253 if !json_field.equals_field(field) {
254 return false;
255 }
256 }
257 true
258 }
259
260 fn to_arrow_schema(&self) -> Result<Schema> {
261 let arrow_fields: Result<Vec<_>> = self
262 .fields
263 .iter()
264 .map(|field| field.to_arrow_field())
265 .collect();
266
267 if let Some(metadatas) = &self.metadata {
268 let mut metadata: HashMap<String, String> = HashMap::new();
269
270 metadatas.iter().for_each(|pair| {
271 let key = pair.get("key").unwrap();
272 let value = pair.get("value").unwrap();
273 metadata.insert(key.clone(), value.clone());
274 });
275
276 Ok(Schema::new_with_metadata(arrow_fields?, metadata))
277 } else {
278 Ok(Schema::new(arrow_fields?))
279 }
280 }
281}
282
283impl ArrowJsonField {
284 fn equals_field(&self, field: &Field) -> bool {
286 match self.to_arrow_field() {
288 Ok(self_field) => {
289 assert_eq!(&self_field, field, "Arrow fields not the same");
290 true
291 }
292 Err(e) => {
293 eprintln!("Encountered error while converting JSON field to Arrow field: {e:?}");
294 false
295 }
296 }
297 }
298
299 fn to_arrow_field(&self) -> Result<Field> {
302 let field =
304 serde_json::to_value(self).map_err(|error| ArrowError::JsonError(error.to_string()))?;
305 field_from_json(&field)
306 }
307}
308
309pub fn record_batch_from_json(
311 schema: &Schema,
312 json_batch: ArrowJsonBatch,
313 json_dictionaries: Option<&HashMap<i64, ArrowJsonDictionaryBatch>>,
314) -> Result<RecordBatch> {
315 let mut columns = vec![];
316
317 for (field, json_col) in schema.fields().iter().zip(json_batch.columns) {
318 let col = array_from_json(field, json_col, json_dictionaries)?;
319 columns.push(col);
320 }
321
322 RecordBatch::try_new(Arc::new(schema.clone()), columns)
323}
324
325pub fn array_from_json(
327 field: &Field,
328 json_col: ArrowJsonColumn,
329 dictionaries: Option<&HashMap<i64, ArrowJsonDictionaryBatch>>,
330) -> Result<ArrayRef> {
331 match field.data_type() {
332 DataType::Null => Ok(Arc::new(NullArray::new(json_col.count))),
333 DataType::Boolean => {
334 let mut b = BooleanBuilder::with_capacity(json_col.count);
335 for (is_valid, value) in json_col
336 .validity
337 .as_ref()
338 .unwrap()
339 .iter()
340 .zip(json_col.data.unwrap())
341 {
342 match is_valid {
343 1 => b.append_value(value.as_bool().unwrap()),
344 _ => b.append_null(),
345 };
346 }
347 Ok(Arc::new(b.finish()))
348 }
349 DataType::Int8 => {
350 let mut b = Int8Builder::with_capacity(json_col.count);
351 for (is_valid, value) in json_col
352 .validity
353 .as_ref()
354 .unwrap()
355 .iter()
356 .zip(json_col.data.unwrap())
357 {
358 match is_valid {
359 1 => b.append_value(value.as_i64().ok_or_else(|| {
360 ArrowError::JsonError(format!("Unable to get {value:?} as int64"))
361 })? as i8),
362 _ => b.append_null(),
363 };
364 }
365 Ok(Arc::new(b.finish()))
366 }
367 DataType::Int16 => {
368 let mut b = Int16Builder::with_capacity(json_col.count);
369 for (is_valid, value) in json_col
370 .validity
371 .as_ref()
372 .unwrap()
373 .iter()
374 .zip(json_col.data.unwrap())
375 {
376 match is_valid {
377 1 => b.append_value(value.as_i64().unwrap() as i16),
378 _ => b.append_null(),
379 };
380 }
381 Ok(Arc::new(b.finish()))
382 }
383 DataType::Int32 | DataType::Date32 | DataType::Time32(_) => {
384 let mut b = Int32Builder::with_capacity(json_col.count);
385 for (is_valid, value) in json_col
386 .validity
387 .as_ref()
388 .unwrap()
389 .iter()
390 .zip(json_col.data.unwrap())
391 {
392 match is_valid {
393 1 => b.append_value(value.as_i64().unwrap() as i32),
394 _ => b.append_null(),
395 };
396 }
397 let array = Arc::new(b.finish()) as ArrayRef;
398 arrow::compute::cast(&array, field.data_type())
399 }
400 DataType::Interval(IntervalUnit::YearMonth) => {
401 let mut b = IntervalYearMonthBuilder::with_capacity(json_col.count);
402 for (is_valid, value) in json_col
403 .validity
404 .as_ref()
405 .unwrap()
406 .iter()
407 .zip(json_col.data.unwrap())
408 {
409 match is_valid {
410 1 => b.append_value(value.as_i64().unwrap() as i32),
411 _ => b.append_null(),
412 };
413 }
414 Ok(Arc::new(b.finish()))
415 }
416 DataType::Int64
417 | DataType::Date64
418 | DataType::Time64(_)
419 | DataType::Timestamp(_, _)
420 | DataType::Duration(_) => {
421 let mut b = Int64Builder::with_capacity(json_col.count);
422 for (is_valid, value) in json_col
423 .validity
424 .as_ref()
425 .unwrap()
426 .iter()
427 .zip(json_col.data.unwrap())
428 {
429 match is_valid {
430 1 => b.append_value(match value {
431 Value::Number(n) => n.as_i64().unwrap(),
432 Value::String(s) => s.parse().expect("Unable to parse string as i64"),
433 _ => panic!("Unable to parse {value:?} as number"),
434 }),
435 _ => b.append_null(),
436 };
437 }
438 let array = Arc::new(b.finish()) as ArrayRef;
439 arrow::compute::cast(&array, field.data_type())
440 }
441 DataType::Interval(IntervalUnit::DayTime) => {
442 let mut b = IntervalDayTimeBuilder::with_capacity(json_col.count);
443 for (is_valid, value) in json_col
444 .validity
445 .as_ref()
446 .unwrap()
447 .iter()
448 .zip(json_col.data.unwrap())
449 {
450 match is_valid {
451 1 => b.append_value(match value {
452 Value::Object(ref map)
453 if map.contains_key("days") && map.contains_key("milliseconds") =>
454 {
455 match field.data_type() {
456 DataType::Interval(IntervalUnit::DayTime) => {
457 let days = map.get("days").unwrap();
458 let milliseconds = map.get("milliseconds").unwrap();
459
460 match (days, milliseconds) {
461 (Value::Number(d), Value::Number(m)) => {
462 let days = d.as_i64().unwrap() as _;
463 let millis = m.as_i64().unwrap() as _;
464 IntervalDayTime::new(days, millis)
465 }
466 _ => {
467 panic!("Unable to parse {value:?} as interval daytime")
468 }
469 }
470 }
471 _ => panic!("Unable to parse {value:?} as interval daytime"),
472 }
473 }
474 _ => panic!("Unable to parse {value:?} as number"),
475 }),
476 _ => b.append_null(),
477 };
478 }
479 Ok(Arc::new(b.finish()))
480 }
481 DataType::UInt8 => {
482 let mut b = UInt8Builder::with_capacity(json_col.count);
483 for (is_valid, value) in json_col
484 .validity
485 .as_ref()
486 .unwrap()
487 .iter()
488 .zip(json_col.data.unwrap())
489 {
490 match is_valid {
491 1 => b.append_value(value.as_u64().unwrap() as u8),
492 _ => b.append_null(),
493 };
494 }
495 Ok(Arc::new(b.finish()))
496 }
497 DataType::UInt16 => {
498 let mut b = UInt16Builder::with_capacity(json_col.count);
499 for (is_valid, value) in json_col
500 .validity
501 .as_ref()
502 .unwrap()
503 .iter()
504 .zip(json_col.data.unwrap())
505 {
506 match is_valid {
507 1 => b.append_value(value.as_u64().unwrap() as u16),
508 _ => b.append_null(),
509 };
510 }
511 Ok(Arc::new(b.finish()))
512 }
513 DataType::UInt32 => {
514 let mut b = UInt32Builder::with_capacity(json_col.count);
515 for (is_valid, value) in json_col
516 .validity
517 .as_ref()
518 .unwrap()
519 .iter()
520 .zip(json_col.data.unwrap())
521 {
522 match is_valid {
523 1 => b.append_value(value.as_u64().unwrap() as u32),
524 _ => b.append_null(),
525 };
526 }
527 Ok(Arc::new(b.finish()))
528 }
529 DataType::UInt64 => {
530 let mut b = UInt64Builder::with_capacity(json_col.count);
531 for (is_valid, value) in json_col
532 .validity
533 .as_ref()
534 .unwrap()
535 .iter()
536 .zip(json_col.data.unwrap())
537 {
538 match is_valid {
539 1 => {
540 if value.is_string() {
541 b.append_value(
542 value
543 .as_str()
544 .unwrap()
545 .parse()
546 .expect("Unable to parse string as u64"),
547 )
548 } else if value.is_number() {
549 b.append_value(value.as_u64().expect("Unable to read number as u64"))
550 } else {
551 panic!("Unable to parse value {value:?} as u64")
552 }
553 }
554 _ => b.append_null(),
555 };
556 }
557 Ok(Arc::new(b.finish()))
558 }
559 DataType::Interval(IntervalUnit::MonthDayNano) => {
560 let mut b = IntervalMonthDayNanoBuilder::with_capacity(json_col.count);
561 for (is_valid, value) in json_col
562 .validity
563 .as_ref()
564 .unwrap()
565 .iter()
566 .zip(json_col.data.unwrap())
567 {
568 match is_valid {
569 1 => b.append_value(match value {
570 Value::Object(v) => {
571 let months = v.get("months").unwrap();
572 let days = v.get("days").unwrap();
573 let nanoseconds = v.get("nanoseconds").unwrap();
574 match (months, days, nanoseconds) {
575 (
576 Value::Number(months),
577 Value::Number(days),
578 Value::Number(nanoseconds),
579 ) => {
580 let months = months.as_i64().unwrap() as i32;
581 let days = days.as_i64().unwrap() as i32;
582 let nanoseconds = nanoseconds.as_i64().unwrap();
583 IntervalMonthDayNano::new(months, days, nanoseconds)
584 }
585 (_, _, _) => {
586 panic!("Unable to parse {v:?} as MonthDayNano")
587 }
588 }
589 }
590 _ => panic!("Unable to parse {value:?} as MonthDayNano"),
591 }),
592 _ => b.append_null(),
593 };
594 }
595 Ok(Arc::new(b.finish()))
596 }
597 DataType::Float32 => {
598 let mut b = Float32Builder::with_capacity(json_col.count);
599 for (is_valid, value) in json_col
600 .validity
601 .as_ref()
602 .unwrap()
603 .iter()
604 .zip(json_col.data.unwrap())
605 {
606 match is_valid {
607 1 => b.append_value(value.as_f64().unwrap() as f32),
608 _ => b.append_null(),
609 };
610 }
611 Ok(Arc::new(b.finish()))
612 }
613 DataType::Float64 => {
614 let mut b = Float64Builder::with_capacity(json_col.count);
615 for (is_valid, value) in json_col
616 .validity
617 .as_ref()
618 .unwrap()
619 .iter()
620 .zip(json_col.data.unwrap())
621 {
622 match is_valid {
623 1 => b.append_value(value.as_f64().unwrap()),
624 _ => b.append_null(),
625 };
626 }
627 Ok(Arc::new(b.finish()))
628 }
629 DataType::Binary => {
630 let mut b = BinaryBuilder::with_capacity(json_col.count, 1024);
631 for (is_valid, value) in json_col
632 .validity
633 .as_ref()
634 .unwrap()
635 .iter()
636 .zip(json_col.data.unwrap())
637 {
638 match is_valid {
639 1 => {
640 let v = decode(value.as_str().unwrap()).unwrap();
641 b.append_value(&v)
642 }
643 _ => b.append_null(),
644 };
645 }
646 Ok(Arc::new(b.finish()))
647 }
648 DataType::LargeBinary => {
649 let mut b = LargeBinaryBuilder::with_capacity(json_col.count, 1024);
650 for (is_valid, value) in json_col
651 .validity
652 .as_ref()
653 .unwrap()
654 .iter()
655 .zip(json_col.data.unwrap())
656 {
657 match is_valid {
658 1 => {
659 let v = decode(value.as_str().unwrap()).unwrap();
660 b.append_value(&v)
661 }
662 _ => b.append_null(),
663 };
664 }
665 Ok(Arc::new(b.finish()))
666 }
667 DataType::Utf8 => {
668 let mut b = StringBuilder::with_capacity(json_col.count, 1024);
669 for (is_valid, value) in json_col
670 .validity
671 .as_ref()
672 .unwrap()
673 .iter()
674 .zip(json_col.data.unwrap())
675 {
676 match is_valid {
677 1 => b.append_value(value.as_str().unwrap()),
678 _ => b.append_null(),
679 };
680 }
681 Ok(Arc::new(b.finish()))
682 }
683 DataType::LargeUtf8 => {
684 let mut b = LargeStringBuilder::with_capacity(json_col.count, 1024);
685 for (is_valid, value) in json_col
686 .validity
687 .as_ref()
688 .unwrap()
689 .iter()
690 .zip(json_col.data.unwrap())
691 {
692 match is_valid {
693 1 => b.append_value(value.as_str().unwrap()),
694 _ => b.append_null(),
695 };
696 }
697 Ok(Arc::new(b.finish()))
698 }
699 DataType::FixedSizeBinary(len) => {
700 let mut b = FixedSizeBinaryBuilder::with_capacity(json_col.count, *len);
701 for (is_valid, value) in json_col
702 .validity
703 .as_ref()
704 .unwrap()
705 .iter()
706 .zip(json_col.data.unwrap())
707 {
708 match is_valid {
709 1 => {
710 let v = hex::decode(value.as_str().unwrap()).unwrap();
711 b.append_value(&v)?
712 }
713 _ => b.append_null(),
714 };
715 }
716 Ok(Arc::new(b.finish()))
717 }
718 DataType::List(child_field) => {
719 let null_buf = create_null_buf(&json_col);
720 let children = json_col.children.clone().unwrap();
721 let child_array = array_from_json(child_field, children[0].clone(), dictionaries)?;
722 let offsets: Vec<i32> = json_col
723 .offset
724 .unwrap()
725 .iter()
726 .map(|v| v.as_i64().unwrap() as i32)
727 .collect();
728 let list_data = ArrayData::builder(field.data_type().clone())
729 .len(json_col.count)
730 .offset(0)
731 .add_buffer(Buffer::from(offsets.to_byte_slice()))
732 .add_child_data(child_array.into_data())
733 .null_bit_buffer(Some(null_buf))
734 .build()
735 .unwrap();
736 Ok(Arc::new(ListArray::from(list_data)))
737 }
738 DataType::LargeList(child_field) => {
739 let null_buf = create_null_buf(&json_col);
740 let children = json_col.children.clone().unwrap();
741 let child_array = array_from_json(child_field, children[0].clone(), dictionaries)?;
742 let offsets: Vec<i64> = json_col
743 .offset
744 .unwrap()
745 .iter()
746 .map(|v| match v {
747 Value::Number(n) => n.as_i64().unwrap(),
748 Value::String(s) => s.parse::<i64>().unwrap(),
749 _ => panic!("64-bit offset must be either string or number"),
750 })
751 .collect();
752 let list_data = ArrayData::builder(field.data_type().clone())
753 .len(json_col.count)
754 .offset(0)
755 .add_buffer(Buffer::from(offsets.to_byte_slice()))
756 .add_child_data(child_array.into_data())
757 .null_bit_buffer(Some(null_buf))
758 .build()
759 .unwrap();
760 Ok(Arc::new(LargeListArray::from(list_data)))
761 }
762 DataType::FixedSizeList(child_field, _) => {
763 let children = json_col.children.clone().unwrap();
764 let child_array = array_from_json(child_field, children[0].clone(), dictionaries)?;
765 let null_buf = create_null_buf(&json_col);
766 let list_data = ArrayData::builder(field.data_type().clone())
767 .len(json_col.count)
768 .add_child_data(child_array.into_data())
769 .null_bit_buffer(Some(null_buf))
770 .build()
771 .unwrap();
772 Ok(Arc::new(FixedSizeListArray::from(list_data)))
773 }
774 DataType::Struct(fields) => {
775 let null_buf = create_null_buf(&json_col);
777 let mut array_data = ArrayData::builder(field.data_type().clone())
778 .len(json_col.count)
779 .null_bit_buffer(Some(null_buf));
780
781 for (field, col) in fields.iter().zip(json_col.children.unwrap()) {
782 let array = array_from_json(field, col, dictionaries)?;
783 array_data = array_data.add_child_data(array.into_data());
784 }
785
786 let array = StructArray::from(array_data.build().unwrap());
787 Ok(Arc::new(array))
788 }
789 DataType::Dictionary(key_type, value_type) => {
790 #[allow(deprecated)]
791 let dict_id = field.dict_id().ok_or_else(|| {
792 ArrowError::JsonError(format!("Unable to find dict_id for field {field:?}"))
793 })?;
794 let dictionary = dictionaries
796 .ok_or_else(|| {
797 ArrowError::JsonError(format!(
798 "Unable to find any dictionaries for field {field:?}"
799 ))
800 })?
801 .get(&dict_id);
802 match dictionary {
803 Some(dictionary) => dictionary_array_from_json(
804 field,
805 json_col,
806 key_type,
807 value_type,
808 dictionary,
809 dictionaries,
810 ),
811 None => Err(ArrowError::JsonError(format!(
812 "Unable to find dictionary for field {field:?}"
813 ))),
814 }
815 }
816 DataType::Decimal128(precision, scale) => {
817 let mut b = Decimal128Builder::with_capacity(json_col.count);
818 for (is_valid, value) in json_col
819 .validity
820 .as_ref()
821 .unwrap()
822 .iter()
823 .zip(json_col.data.unwrap())
824 {
825 match is_valid {
826 1 => b.append_value(value.as_str().unwrap().parse::<i128>().unwrap()),
827 _ => b.append_null(),
828 };
829 }
830 Ok(Arc::new(
831 b.finish().with_precision_and_scale(*precision, *scale)?,
832 ))
833 }
834 DataType::Decimal256(precision, scale) => {
835 let mut b = Decimal256Builder::with_capacity(json_col.count);
836 for (is_valid, value) in json_col
837 .validity
838 .as_ref()
839 .unwrap()
840 .iter()
841 .zip(json_col.data.unwrap())
842 {
843 match is_valid {
844 1 => {
845 let str = value.as_str().unwrap();
846 let integer = BigInt::parse_bytes(str.as_bytes(), 10).unwrap();
847 let integer_bytes = integer.to_signed_bytes_le();
848 let mut bytes = if integer.is_positive() {
849 [0_u8; 32]
850 } else {
851 [255_u8; 32]
852 };
853 bytes[0..integer_bytes.len()].copy_from_slice(integer_bytes.as_slice());
854 b.append_value(i256::from_le_bytes(bytes));
855 }
856 _ => b.append_null(),
857 }
858 }
859 Ok(Arc::new(
860 b.finish().with_precision_and_scale(*precision, *scale)?,
861 ))
862 }
863 DataType::Map(child_field, _) => {
864 let null_buf = create_null_buf(&json_col);
865 let children = json_col.children.clone().unwrap();
866 let child_array = array_from_json(child_field, children[0].clone(), dictionaries)?;
867 let offsets: Vec<i32> = json_col
868 .offset
869 .unwrap()
870 .iter()
871 .map(|v| v.as_i64().unwrap() as i32)
872 .collect();
873 let array_data = ArrayData::builder(field.data_type().clone())
874 .len(json_col.count)
875 .add_buffer(Buffer::from(offsets.to_byte_slice()))
876 .add_child_data(child_array.into_data())
877 .null_bit_buffer(Some(null_buf))
878 .build()
879 .unwrap();
880
881 let array = MapArray::from(array_data);
882 Ok(Arc::new(array))
883 }
884 DataType::Union(fields, _) => {
885 let type_ids = if let Some(type_id) = json_col.type_id {
886 type_id
887 } else {
888 return Err(ArrowError::JsonError(
889 "Cannot find expected type_id in json column".to_string(),
890 ));
891 };
892
893 let offset: Option<ScalarBuffer<i32>> = json_col
894 .offset
895 .map(|offsets| offsets.iter().map(|v| v.as_i64().unwrap() as i32).collect());
896
897 let mut children = Vec::with_capacity(fields.len());
898 for ((_, field), col) in fields.iter().zip(json_col.children.unwrap()) {
899 let array = array_from_json(field, col, dictionaries)?;
900 children.push(array);
901 }
902
903 let array =
904 UnionArray::try_new(fields.clone(), type_ids.into(), offset, children).unwrap();
905 Ok(Arc::new(array))
906 }
907 t => Err(ArrowError::JsonError(format!(
908 "data type {t:?} not supported"
909 ))),
910 }
911}
912
913pub fn dictionary_array_from_json(
915 field: &Field,
916 json_col: ArrowJsonColumn,
917 dict_key: &DataType,
918 dict_value: &DataType,
919 dictionary: &ArrowJsonDictionaryBatch,
920 dictionaries: Option<&HashMap<i64, ArrowJsonDictionaryBatch>>,
921) -> Result<ArrayRef> {
922 match dict_key {
923 DataType::Int8
924 | DataType::Int16
925 | DataType::Int32
926 | DataType::Int64
927 | DataType::UInt8
928 | DataType::UInt16
929 | DataType::UInt32
930 | DataType::UInt64 => {
931 let null_buf = create_null_buf(&json_col);
932
933 #[allow(deprecated)]
935 let key_field = Field::new_dict(
936 "key",
937 dict_key.clone(),
938 field.is_nullable(),
939 #[allow(deprecated)]
940 field
941 .dict_id()
942 .expect("Dictionary fields must have a dict_id value"),
943 field
944 .dict_is_ordered()
945 .expect("Dictionary fields must have a dict_is_ordered value"),
946 );
947 let keys = array_from_json(&key_field, json_col, None)?;
948 let value_field = Field::new("value", dict_value.clone(), true);
950 let values = array_from_json(
951 &value_field,
952 dictionary.data.columns[0].clone(),
953 dictionaries,
954 )?;
955
956 let dict_data = ArrayData::builder(field.data_type().clone())
958 .len(keys.len())
959 .add_buffer(keys.to_data().buffers()[0].clone())
960 .null_bit_buffer(Some(null_buf))
961 .add_child_data(values.into_data())
962 .build()
963 .unwrap();
964
965 let array = match dict_key {
966 DataType::Int8 => Arc::new(Int8DictionaryArray::from(dict_data)) as ArrayRef,
967 DataType::Int16 => Arc::new(Int16DictionaryArray::from(dict_data)),
968 DataType::Int32 => Arc::new(Int32DictionaryArray::from(dict_data)),
969 DataType::Int64 => Arc::new(Int64DictionaryArray::from(dict_data)),
970 DataType::UInt8 => Arc::new(UInt8DictionaryArray::from(dict_data)),
971 DataType::UInt16 => Arc::new(UInt16DictionaryArray::from(dict_data)),
972 DataType::UInt32 => Arc::new(UInt32DictionaryArray::from(dict_data)),
973 DataType::UInt64 => Arc::new(UInt64DictionaryArray::from(dict_data)),
974 _ => unreachable!(),
975 };
976 Ok(array)
977 }
978 _ => Err(ArrowError::JsonError(format!(
979 "Dictionary key type {dict_key:?} not supported"
980 ))),
981 }
982}
983
984fn create_null_buf(json_col: &ArrowJsonColumn) -> Buffer {
986 let num_bytes = bit_util::ceil(json_col.count, 8);
987 let mut null_buf = MutableBuffer::new(num_bytes).with_bitset(num_bytes, false);
988 json_col
989 .validity
990 .clone()
991 .unwrap()
992 .iter()
993 .enumerate()
994 .for_each(|(i, v)| {
995 let null_slice = null_buf.as_slice_mut();
996 if *v != 0 {
997 bit_util::set_bit(null_slice, i);
998 }
999 });
1000 null_buf.into()
1001}
1002
1003impl ArrowJsonBatch {
1004 pub fn from_batch(batch: &RecordBatch) -> ArrowJsonBatch {
1006 let mut json_batch = ArrowJsonBatch {
1007 count: batch.num_rows(),
1008 columns: Vec::with_capacity(batch.num_columns()),
1009 };
1010
1011 for (col, field) in batch.columns().iter().zip(batch.schema().fields.iter()) {
1012 let json_col = match field.data_type() {
1013 DataType::Int8 => {
1014 let col = col.as_any().downcast_ref::<Int8Array>().unwrap();
1015
1016 let mut validity: Vec<u8> = Vec::with_capacity(col.len());
1017 let mut data: Vec<Value> = Vec::with_capacity(col.len());
1018
1019 for i in 0..col.len() {
1020 if col.is_null(i) {
1021 validity.push(1);
1022 data.push(0i8.into());
1023 } else {
1024 validity.push(0);
1025 data.push(col.value(i).into());
1026 }
1027 }
1028
1029 ArrowJsonColumn {
1030 name: field.name().clone(),
1031 count: col.len(),
1032 validity: Some(validity),
1033 data: Some(data),
1034 offset: None,
1035 type_id: None,
1036 children: None,
1037 }
1038 }
1039 _ => ArrowJsonColumn {
1040 name: field.name().clone(),
1041 count: col.len(),
1042 validity: None,
1043 data: None,
1044 offset: None,
1045 type_id: None,
1046 children: None,
1047 },
1048 };
1049
1050 json_batch.columns.push(json_col);
1051 }
1052
1053 json_batch
1054 }
1055}
1056
1057#[cfg(test)]
1058mod tests {
1059 use super::*;
1060
1061 use std::fs::File;
1062 use std::io::Read;
1063
1064 #[test]
1065 fn test_schema_equality() {
1066 let json = r#"
1067 {
1068 "fields": [
1069 {
1070 "name": "c1",
1071 "type": {"name": "int", "isSigned": true, "bitWidth": 32},
1072 "nullable": true,
1073 "children": []
1074 },
1075 {
1076 "name": "c2",
1077 "type": {"name": "floatingpoint", "precision": "DOUBLE"},
1078 "nullable": true,
1079 "children": []
1080 },
1081 {
1082 "name": "c3",
1083 "type": {"name": "utf8"},
1084 "nullable": true,
1085 "children": []
1086 },
1087 {
1088 "name": "c4",
1089 "type": {
1090 "name": "list"
1091 },
1092 "nullable": true,
1093 "children": [
1094 {
1095 "name": "custom_item",
1096 "type": {
1097 "name": "int",
1098 "isSigned": true,
1099 "bitWidth": 32
1100 },
1101 "nullable": false,
1102 "children": []
1103 }
1104 ]
1105 }
1106 ]
1107 }"#;
1108 let json_schema: ArrowJsonSchema = serde_json::from_str(json).unwrap();
1109 let schema = Schema::new(vec![
1110 Field::new("c1", DataType::Int32, true),
1111 Field::new("c2", DataType::Float64, true),
1112 Field::new("c3", DataType::Utf8, true),
1113 Field::new(
1114 "c4",
1115 DataType::List(Arc::new(Field::new("custom_item", DataType::Int32, false))),
1116 true,
1117 ),
1118 ]);
1119 assert!(json_schema.equals_schema(&schema));
1120 }
1121
1122 #[test]
1123 fn test_arrow_data_equality() {
1124 let secs_tz = Some("Europe/Budapest".into());
1125 let millis_tz = Some("America/New_York".into());
1126 let micros_tz = Some("UTC".into());
1127 let nanos_tz = Some("Africa/Johannesburg".into());
1128
1129 let schema = Schema::new(vec![
1130 Field::new("bools-with-metadata-map", DataType::Boolean, true).with_metadata(
1131 [("k".to_string(), "v".to_string())]
1132 .iter()
1133 .cloned()
1134 .collect(),
1135 ),
1136 Field::new("bools-with-metadata-vec", DataType::Boolean, true).with_metadata(
1137 [("k2".to_string(), "v2".to_string())]
1138 .iter()
1139 .cloned()
1140 .collect(),
1141 ),
1142 Field::new("bools", DataType::Boolean, true),
1143 Field::new("int8s", DataType::Int8, true),
1144 Field::new("int16s", DataType::Int16, true),
1145 Field::new("int32s", DataType::Int32, true),
1146 Field::new("int64s", DataType::Int64, true),
1147 Field::new("uint8s", DataType::UInt8, true),
1148 Field::new("uint16s", DataType::UInt16, true),
1149 Field::new("uint32s", DataType::UInt32, true),
1150 Field::new("uint64s", DataType::UInt64, true),
1151 Field::new("float32s", DataType::Float32, true),
1152 Field::new("float64s", DataType::Float64, true),
1153 Field::new("date_days", DataType::Date32, true),
1154 Field::new("date_millis", DataType::Date64, true),
1155 Field::new("time_secs", DataType::Time32(TimeUnit::Second), true),
1156 Field::new("time_millis", DataType::Time32(TimeUnit::Millisecond), true),
1157 Field::new("time_micros", DataType::Time64(TimeUnit::Microsecond), true),
1158 Field::new("time_nanos", DataType::Time64(TimeUnit::Nanosecond), true),
1159 Field::new("ts_secs", DataType::Timestamp(TimeUnit::Second, None), true),
1160 Field::new(
1161 "ts_millis",
1162 DataType::Timestamp(TimeUnit::Millisecond, None),
1163 true,
1164 ),
1165 Field::new(
1166 "ts_micros",
1167 DataType::Timestamp(TimeUnit::Microsecond, None),
1168 true,
1169 ),
1170 Field::new(
1171 "ts_nanos",
1172 DataType::Timestamp(TimeUnit::Nanosecond, None),
1173 true,
1174 ),
1175 Field::new(
1176 "ts_secs_tz",
1177 DataType::Timestamp(TimeUnit::Second, secs_tz.clone()),
1178 true,
1179 ),
1180 Field::new(
1181 "ts_millis_tz",
1182 DataType::Timestamp(TimeUnit::Millisecond, millis_tz.clone()),
1183 true,
1184 ),
1185 Field::new(
1186 "ts_micros_tz",
1187 DataType::Timestamp(TimeUnit::Microsecond, micros_tz.clone()),
1188 true,
1189 ),
1190 Field::new(
1191 "ts_nanos_tz",
1192 DataType::Timestamp(TimeUnit::Nanosecond, nanos_tz.clone()),
1193 true,
1194 ),
1195 Field::new("utf8s", DataType::Utf8, true),
1196 Field::new(
1197 "lists",
1198 DataType::List(Arc::new(Field::new_list_field(DataType::Int32, true))),
1199 true,
1200 ),
1201 Field::new(
1202 "structs",
1203 DataType::Struct(Fields::from(vec![
1204 Field::new("int32s", DataType::Int32, true),
1205 Field::new("utf8s", DataType::Utf8, true),
1206 ])),
1207 true,
1208 ),
1209 ]);
1210
1211 let bools_with_metadata_map = BooleanArray::from(vec![Some(true), None, Some(false)]);
1212 let bools_with_metadata_vec = BooleanArray::from(vec![Some(true), None, Some(false)]);
1213 let bools = BooleanArray::from(vec![Some(true), None, Some(false)]);
1214 let int8s = Int8Array::from(vec![Some(1), None, Some(3)]);
1215 let int16s = Int16Array::from(vec![Some(1), None, Some(3)]);
1216 let int32s = Int32Array::from(vec![Some(1), None, Some(3)]);
1217 let int64s = Int64Array::from(vec![Some(1), None, Some(3)]);
1218 let uint8s = UInt8Array::from(vec![Some(1), None, Some(3)]);
1219 let uint16s = UInt16Array::from(vec![Some(1), None, Some(3)]);
1220 let uint32s = UInt32Array::from(vec![Some(1), None, Some(3)]);
1221 let uint64s = UInt64Array::from(vec![Some(1), None, Some(3)]);
1222 let float32s = Float32Array::from(vec![Some(1.0), None, Some(3.0)]);
1223 let float64s = Float64Array::from(vec![Some(1.0), None, Some(3.0)]);
1224 let date_days = Date32Array::from(vec![Some(1196848), None, None]);
1225 let date_millis = Date64Array::from(vec![
1226 Some(167903550396207),
1227 Some(29923997007884),
1228 Some(30612271819236),
1229 ]);
1230 let time_secs = Time32SecondArray::from(vec![Some(27974), Some(78592), Some(43207)]);
1231 let time_millis =
1232 Time32MillisecondArray::from(vec![Some(6613125), Some(74667230), Some(52260079)]);
1233 let time_micros = Time64MicrosecondArray::from(vec![Some(62522958593), None, None]);
1234 let time_nanos =
1235 Time64NanosecondArray::from(vec![Some(73380123595985), None, Some(16584393546415)]);
1236 let ts_secs = TimestampSecondArray::from(vec![None, Some(193438817552), None]);
1237 let ts_millis =
1238 TimestampMillisecondArray::from(vec![None, Some(38606916383008), Some(58113709376587)]);
1239 let ts_micros = TimestampMicrosecondArray::from(vec![None, None, None]);
1240 let ts_nanos = TimestampNanosecondArray::from(vec![None, None, Some(-6473623571954960143)]);
1241 let ts_secs_tz = TimestampSecondArray::from(vec![None, Some(193438817552), None])
1242 .with_timezone_opt(secs_tz);
1243 let ts_millis_tz =
1244 TimestampMillisecondArray::from(vec![None, Some(38606916383008), Some(58113709376587)])
1245 .with_timezone_opt(millis_tz);
1246 let ts_micros_tz =
1247 TimestampMicrosecondArray::from(vec![None, None, None]).with_timezone_opt(micros_tz);
1248 let ts_nanos_tz =
1249 TimestampNanosecondArray::from(vec![None, None, Some(-6473623571954960143)])
1250 .with_timezone_opt(nanos_tz);
1251 let utf8s = StringArray::from(vec![Some("aa"), None, Some("bbb")]);
1252
1253 let value_data = Int32Array::from(vec![None, Some(2), None, None]);
1254 let value_offsets = Buffer::from_slice_ref([0, 3, 4, 4]);
1255 let list_data_type = DataType::List(Arc::new(Field::new_list_field(DataType::Int32, true)));
1256 let list_data = ArrayData::builder(list_data_type)
1257 .len(3)
1258 .add_buffer(value_offsets)
1259 .add_child_data(value_data.into_data())
1260 .null_bit_buffer(Some(Buffer::from([0b00000011])))
1261 .build()
1262 .unwrap();
1263 let lists = ListArray::from(list_data);
1264
1265 let structs_int32s = Int32Array::from(vec![None, Some(-2), None]);
1266 let structs_utf8s = StringArray::from(vec![None, None, Some("aaaaaa")]);
1267 let struct_data_type = DataType::Struct(Fields::from(vec![
1268 Field::new("int32s", DataType::Int32, true),
1269 Field::new("utf8s", DataType::Utf8, true),
1270 ]));
1271 let struct_data = ArrayData::builder(struct_data_type)
1272 .len(3)
1273 .add_child_data(structs_int32s.into_data())
1274 .add_child_data(structs_utf8s.into_data())
1275 .null_bit_buffer(Some(Buffer::from([0b00000011])))
1276 .build()
1277 .unwrap();
1278 let structs = StructArray::from(struct_data);
1279
1280 let record_batch = RecordBatch::try_new(
1281 Arc::new(schema.clone()),
1282 vec![
1283 Arc::new(bools_with_metadata_map),
1284 Arc::new(bools_with_metadata_vec),
1285 Arc::new(bools),
1286 Arc::new(int8s),
1287 Arc::new(int16s),
1288 Arc::new(int32s),
1289 Arc::new(int64s),
1290 Arc::new(uint8s),
1291 Arc::new(uint16s),
1292 Arc::new(uint32s),
1293 Arc::new(uint64s),
1294 Arc::new(float32s),
1295 Arc::new(float64s),
1296 Arc::new(date_days),
1297 Arc::new(date_millis),
1298 Arc::new(time_secs),
1299 Arc::new(time_millis),
1300 Arc::new(time_micros),
1301 Arc::new(time_nanos),
1302 Arc::new(ts_secs),
1303 Arc::new(ts_millis),
1304 Arc::new(ts_micros),
1305 Arc::new(ts_nanos),
1306 Arc::new(ts_secs_tz),
1307 Arc::new(ts_millis_tz),
1308 Arc::new(ts_micros_tz),
1309 Arc::new(ts_nanos_tz),
1310 Arc::new(utf8s),
1311 Arc::new(lists),
1312 Arc::new(structs),
1313 ],
1314 )
1315 .unwrap();
1316 let mut file = File::open("data/integration.json").unwrap();
1317 let mut json = String::new();
1318 file.read_to_string(&mut json).unwrap();
1319 let arrow_json: ArrowJson = serde_json::from_str(&json).unwrap();
1320 assert!(arrow_json.schema.equals_schema(&schema));
1322 assert_eq!(arrow_json.get_record_batches().unwrap()[0], record_batch);
1324 }
1325}