blob: 043174b9ac80baf462942e52228b46d76bb967ec [file] [log] [blame]
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
use super::*;
use crate::datatypes::*;
use array::Array;
use hex::FromHex;
use serde_json::value::Value::{Null as JNull, Object, String as JString};
use serde_json::Value;
/// Trait for comparing arrow array with json array
pub trait JsonEqual {
/// Checks whether arrow array equals to json array.
fn equals_json(&self, json: &[&Value]) -> bool;
/// Checks whether arrow array equals to json array.
fn equals_json_values(&self, json: &[Value]) -> bool {
let refs = json.iter().collect::<Vec<&Value>>();
self.equals_json(&refs)
}
}
/// Implement array equals for numeric type
impl<T: ArrowPrimitiveType> JsonEqual for PrimitiveArray<T> {
fn equals_json(&self, json: &[&Value]) -> bool {
self.len() == json.len()
&& (0..self.len()).all(|i| match json[i] {
Value::Null => self.is_null(i),
v => {
self.is_valid(i)
&& Some(v) == self.value(i).into_json_value().as_ref()
}
})
}
}
/// Implement array equals for numeric type
impl JsonEqual for BooleanArray {
fn equals_json(&self, json: &[&Value]) -> bool {
self.len() == json.len()
&& (0..self.len()).all(|i| match json[i] {
Value::Null => self.is_null(i),
v => {
self.is_valid(i)
&& Some(v) == self.value(i).into_json_value().as_ref()
}
})
}
}
impl<T: ArrowPrimitiveType> PartialEq<Value> for PrimitiveArray<T> {
fn eq(&self, json: &Value) -> bool {
match json {
Value::Array(array) => self.equals_json_values(&array),
_ => false,
}
}
}
impl<T: ArrowPrimitiveType> PartialEq<PrimitiveArray<T>> for Value {
fn eq(&self, arrow: &PrimitiveArray<T>) -> bool {
match self {
Value::Array(array) => arrow.equals_json_values(&array),
_ => false,
}
}
}
impl<OffsetSize: OffsetSizeTrait> JsonEqual for GenericListArray<OffsetSize> {
fn equals_json(&self, json: &[&Value]) -> bool {
if self.len() != json.len() {
return false;
}
(0..self.len()).all(|i| match json[i] {
Value::Array(v) => self.is_valid(i) && self.value(i).equals_json_values(v),
Value::Null => self.is_null(i) || self.value_length(i).is_zero(),
_ => false,
})
}
}
impl<OffsetSize: OffsetSizeTrait> PartialEq<Value> for GenericListArray<OffsetSize> {
fn eq(&self, json: &Value) -> bool {
match json {
Value::Array(json_array) => self.equals_json_values(json_array),
_ => false,
}
}
}
impl<OffsetSize: OffsetSizeTrait> PartialEq<GenericListArray<OffsetSize>> for Value {
fn eq(&self, arrow: &GenericListArray<OffsetSize>) -> bool {
match self {
Value::Array(json_array) => arrow.equals_json_values(json_array),
_ => false,
}
}
}
impl<T: ArrowPrimitiveType> JsonEqual for DictionaryArray<T> {
fn equals_json(&self, json: &[&Value]) -> bool {
// todo: this is wrong: we must test the values also
self.keys().equals_json(json)
}
}
impl<T: ArrowPrimitiveType> PartialEq<Value> for DictionaryArray<T> {
fn eq(&self, json: &Value) -> bool {
match json {
Value::Array(json_array) => self.equals_json_values(json_array),
_ => false,
}
}
}
impl<T: ArrowPrimitiveType> PartialEq<DictionaryArray<T>> for Value {
fn eq(&self, arrow: &DictionaryArray<T>) -> bool {
match self {
Value::Array(json_array) => arrow.equals_json_values(json_array),
_ => false,
}
}
}
impl JsonEqual for FixedSizeListArray {
fn equals_json(&self, json: &[&Value]) -> bool {
if self.len() != json.len() {
return false;
}
(0..self.len()).all(|i| match json[i] {
Value::Array(v) => self.is_valid(i) && self.value(i).equals_json_values(v),
Value::Null => self.is_null(i) || self.value_length() == 0,
_ => false,
})
}
}
impl PartialEq<Value> for FixedSizeListArray {
fn eq(&self, json: &Value) -> bool {
match json {
Value::Array(json_array) => self.equals_json_values(json_array),
_ => false,
}
}
}
impl PartialEq<FixedSizeListArray> for Value {
fn eq(&self, arrow: &FixedSizeListArray) -> bool {
match self {
Value::Array(json_array) => arrow.equals_json_values(json_array),
_ => false,
}
}
}
impl JsonEqual for StructArray {
fn equals_json(&self, json: &[&Value]) -> bool {
if self.len() != json.len() {
return false;
}
let all_object = json.iter().all(|v| matches!(v, Object(_) | JNull));
if !all_object {
return false;
}
for column_name in self.column_names() {
let json_values = json
.iter()
.map(|obj| obj.get(column_name).unwrap_or(&Value::Null))
.collect::<Vec<&Value>>();
if !self
.column_by_name(column_name)
.map(|arr| arr.equals_json(&json_values))
.unwrap_or(false)
{
return false;
}
}
true
}
}
impl PartialEq<Value> for StructArray {
fn eq(&self, json: &Value) -> bool {
match json {
Value::Array(json_array) => self.equals_json_values(&json_array),
_ => false,
}
}
}
impl PartialEq<StructArray> for Value {
fn eq(&self, arrow: &StructArray) -> bool {
match self {
Value::Array(json_array) => arrow.equals_json_values(&json_array),
_ => false,
}
}
}
impl<OffsetSize: BinaryOffsetSizeTrait> JsonEqual for GenericBinaryArray<OffsetSize> {
fn equals_json(&self, json: &[&Value]) -> bool {
if self.len() != json.len() {
return false;
}
(0..self.len()).all(|i| match json[i] {
JString(s) => {
// binary data is sometimes hex encoded, this checks if bytes are equal,
// and if not converting to hex is attempted
self.is_valid(i)
&& (s.as_str().as_bytes() == self.value(i)
|| Vec::from_hex(s.as_str()) == Ok(self.value(i).to_vec()))
}
JNull => self.is_null(i),
_ => false,
})
}
}
impl<OffsetSize: BinaryOffsetSizeTrait> PartialEq<Value>
for GenericBinaryArray<OffsetSize>
{
fn eq(&self, json: &Value) -> bool {
match json {
Value::Array(json_array) => self.equals_json_values(&json_array),
_ => false,
}
}
}
impl<OffsetSize: BinaryOffsetSizeTrait> PartialEq<GenericBinaryArray<OffsetSize>>
for Value
{
fn eq(&self, arrow: &GenericBinaryArray<OffsetSize>) -> bool {
match self {
Value::Array(json_array) => arrow.equals_json_values(&json_array),
_ => false,
}
}
}
impl<OffsetSize: StringOffsetSizeTrait> JsonEqual for GenericStringArray<OffsetSize> {
fn equals_json(&self, json: &[&Value]) -> bool {
if self.len() != json.len() {
return false;
}
(0..self.len()).all(|i| match json[i] {
JString(s) => self.is_valid(i) && s.as_str() == self.value(i),
JNull => self.is_null(i),
_ => false,
})
}
}
impl<OffsetSize: StringOffsetSizeTrait> PartialEq<Value>
for GenericStringArray<OffsetSize>
{
fn eq(&self, json: &Value) -> bool {
match json {
Value::Array(json_array) => self.equals_json_values(&json_array),
_ => false,
}
}
}
impl<OffsetSize: StringOffsetSizeTrait> PartialEq<GenericStringArray<OffsetSize>>
for Value
{
fn eq(&self, arrow: &GenericStringArray<OffsetSize>) -> bool {
match self {
Value::Array(json_array) => arrow.equals_json_values(&json_array),
_ => false,
}
}
}
impl JsonEqual for FixedSizeBinaryArray {
fn equals_json(&self, json: &[&Value]) -> bool {
if self.len() != json.len() {
return false;
}
(0..self.len()).all(|i| match json[i] {
JString(s) => {
// binary data is sometimes hex encoded, this checks if bytes are equal,
// and if not converting to hex is attempted
self.is_valid(i)
&& (s.as_str().as_bytes() == self.value(i)
|| Vec::from_hex(s.as_str()) == Ok(self.value(i).to_vec()))
}
JNull => self.is_null(i),
_ => false,
})
}
}
impl PartialEq<Value> for FixedSizeBinaryArray {
fn eq(&self, json: &Value) -> bool {
match json {
Value::Array(json_array) => self.equals_json_values(&json_array),
_ => false,
}
}
}
impl PartialEq<FixedSizeBinaryArray> for Value {
fn eq(&self, arrow: &FixedSizeBinaryArray) -> bool {
match self {
Value::Array(json_array) => arrow.equals_json_values(&json_array),
_ => false,
}
}
}
impl JsonEqual for DecimalArray {
fn equals_json(&self, json: &[&Value]) -> bool {
if self.len() != json.len() {
return false;
}
(0..self.len()).all(|i| match json[i] {
JString(s) => {
self.is_valid(i)
&& (s
.parse::<i128>()
.map_or_else(|_| false, |v| v == self.value(i)))
}
JNull => self.is_null(i),
_ => false,
})
}
}
impl PartialEq<Value> for DecimalArray {
fn eq(&self, json: &Value) -> bool {
match json {
Value::Array(json_array) => self.equals_json_values(&json_array),
_ => false,
}
}
}
impl PartialEq<DecimalArray> for Value {
fn eq(&self, arrow: &DecimalArray) -> bool {
match self {
Value::Array(json_array) => arrow.equals_json_values(&json_array),
_ => false,
}
}
}
impl JsonEqual for UnionArray {
fn equals_json(&self, _json: &[&Value]) -> bool {
unimplemented!(
"Added to allow UnionArray to implement the Array trait: see ARROW-8547"
)
}
}
impl JsonEqual for NullArray {
fn equals_json(&self, json: &[&Value]) -> bool {
if self.len() != json.len() {
return false;
}
// all JSON values must be nulls
json.iter().all(|&v| v == &JNull)
}
}
impl PartialEq<NullArray> for Value {
fn eq(&self, arrow: &NullArray) -> bool {
match self {
Value::Array(json_array) => arrow.equals_json_values(&json_array),
_ => false,
}
}
}
impl PartialEq<Value> for NullArray {
fn eq(&self, json: &Value) -> bool {
match json {
Value::Array(json_array) => self.equals_json_values(&json_array),
_ => false,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::error::Result;
use std::{convert::TryFrom, sync::Arc};
fn create_list_array<U: AsRef<[i32]>, T: AsRef<[Option<U>]>>(
builder: &mut ListBuilder<Int32Builder>,
data: T,
) -> Result<ListArray> {
for d in data.as_ref() {
if let Some(v) = d {
builder.values().append_slice(v.as_ref())?;
builder.append(true)?
} else {
builder.append(false)?
}
}
Ok(builder.finish())
}
/// Create a fixed size list of 2 value lengths
fn create_fixed_size_list_array<U: AsRef<[i32]>, T: AsRef<[Option<U>]>>(
builder: &mut FixedSizeListBuilder<Int32Builder>,
data: T,
) -> Result<FixedSizeListArray> {
for d in data.as_ref() {
if let Some(v) = d {
builder.values().append_slice(v.as_ref())?;
builder.append(true)?
} else {
for _ in 0..builder.value_length() {
builder.values().append_null()?;
}
builder.append(false)?
}
}
Ok(builder.finish())
}
#[test]
fn test_primitive_json_equal() {
// Test equaled array
let arrow_array = Int32Array::from(vec![Some(1), None, Some(2), Some(3)]);
let json_array: Value = serde_json::from_str(
r#"
[
1, null, 2, 3
]
"#,
)
.unwrap();
assert!(arrow_array.eq(&json_array));
assert!(json_array.eq(&arrow_array));
// Test unequaled array
let arrow_array = Int32Array::from(vec![Some(1), None, Some(2), Some(3)]);
let json_array: Value = serde_json::from_str(
r#"
[
1, 1, 2, 3
]
"#,
)
.unwrap();
assert!(arrow_array.ne(&json_array));
assert!(json_array.ne(&arrow_array));
// Test unequal length case
let arrow_array = Int32Array::from(vec![Some(1), None, Some(2), Some(3)]);
let json_array: Value = serde_json::from_str(
r#"
[
1, 1
]
"#,
)
.unwrap();
assert!(arrow_array.ne(&json_array));
assert!(json_array.ne(&arrow_array));
// Test not json array type case
let arrow_array = Int32Array::from(vec![Some(1), None, Some(2), Some(3)]);
let json_array: Value = serde_json::from_str(
r#"
{
"a": 1
}
"#,
)
.unwrap();
assert!(arrow_array.ne(&json_array));
assert!(json_array.ne(&arrow_array));
}
#[test]
fn test_list_json_equal() {
// Test equal case
let arrow_array = create_list_array(
&mut ListBuilder::new(Int32Builder::new(10)),
&[Some(&[1, 2, 3]), None, Some(&[4, 5, 6])],
)
.unwrap();
let json_array: Value = serde_json::from_str(
r#"
[
[1, 2, 3],
null,
[4, 5, 6]
]
"#,
)
.unwrap();
assert!(arrow_array.eq(&json_array));
assert!(json_array.eq(&arrow_array));
// Test unequal case
let arrow_array = create_list_array(
&mut ListBuilder::new(Int32Builder::new(10)),
&[Some(&[1, 2, 3]), None, Some(&[4, 5, 6])],
)
.unwrap();
let json_array: Value = serde_json::from_str(
r#"
[
[1, 2, 3],
[7, 8],
[4, 5, 6]
]
"#,
)
.unwrap();
assert!(arrow_array.ne(&json_array));
assert!(json_array.ne(&arrow_array));
// Test incorrect type case
let arrow_array = create_list_array(
&mut ListBuilder::new(Int32Builder::new(10)),
&[Some(&[1, 2, 3]), None, Some(&[4, 5, 6])],
)
.unwrap();
let json_array: Value = serde_json::from_str(
r#"
{
"a": 1
}
"#,
)
.unwrap();
assert!(arrow_array.ne(&json_array));
assert!(json_array.ne(&arrow_array));
}
#[test]
fn test_fixed_size_list_json_equal() {
// Test equal case
let arrow_array = create_fixed_size_list_array(
&mut FixedSizeListBuilder::new(Int32Builder::new(10), 3),
&[Some(&[1, 2, 3]), None, Some(&[4, 5, 6])],
)
.unwrap();
let json_array: Value = serde_json::from_str(
r#"
[
[1, 2, 3],
null,
[4, 5, 6]
]
"#,
)
.unwrap();
println!("{:?}", arrow_array);
println!("{:?}", json_array);
assert!(arrow_array.eq(&json_array));
assert!(json_array.eq(&arrow_array));
// Test unequal case
let arrow_array = create_fixed_size_list_array(
&mut FixedSizeListBuilder::new(Int32Builder::new(10), 3),
&[Some(&[1, 2, 3]), None, Some(&[4, 5, 6])],
)
.unwrap();
let json_array: Value = serde_json::from_str(
r#"
[
[1, 2, 3],
[7, 8, 9],
[4, 5, 6]
]
"#,
)
.unwrap();
assert!(arrow_array.ne(&json_array));
assert!(json_array.ne(&arrow_array));
// Test incorrect type case
let arrow_array = create_fixed_size_list_array(
&mut FixedSizeListBuilder::new(Int32Builder::new(10), 3),
&[Some(&[1, 2, 3]), None, Some(&[4, 5, 6])],
)
.unwrap();
let json_array: Value = serde_json::from_str(
r#"
{
"a": 1
}
"#,
)
.unwrap();
assert!(arrow_array.ne(&json_array));
assert!(json_array.ne(&arrow_array));
}
#[test]
fn test_string_json_equal() {
// Test the equal case
let arrow_array =
StringArray::from(vec![Some("hello"), None, None, Some("world"), None, None]);
let json_array: Value = serde_json::from_str(
r#"
[
"hello",
null,
null,
"world",
null,
null
]
"#,
)
.unwrap();
assert!(arrow_array.eq(&json_array));
assert!(json_array.eq(&arrow_array));
// Test unequal case
let arrow_array =
StringArray::from(vec![Some("hello"), None, None, Some("world"), None, None]);
let json_array: Value = serde_json::from_str(
r#"
[
"hello",
null,
null,
"arrow",
null,
null
]
"#,
)
.unwrap();
assert!(arrow_array.ne(&json_array));
assert!(json_array.ne(&arrow_array));
// Test unequal length case
let arrow_array =
StringArray::from(vec![Some("hello"), None, None, Some("world"), None]);
let json_array: Value = serde_json::from_str(
r#"
[
"hello",
null,
null,
"arrow",
null,
null
]
"#,
)
.unwrap();
assert!(arrow_array.ne(&json_array));
assert!(json_array.ne(&arrow_array));
// Test incorrect type case
let arrow_array =
StringArray::from(vec![Some("hello"), None, None, Some("world"), None]);
let json_array: Value = serde_json::from_str(
r#"
{
"a": 1
}
"#,
)
.unwrap();
assert!(arrow_array.ne(&json_array));
assert!(json_array.ne(&arrow_array));
// Test incorrect value type case
let arrow_array =
StringArray::from(vec![Some("hello"), None, None, Some("world"), None]);
let json_array: Value = serde_json::from_str(
r#"
[
"hello",
null,
null,
1,
null,
null
]
"#,
)
.unwrap();
assert!(arrow_array.ne(&json_array));
assert!(json_array.ne(&arrow_array));
}
#[test]
fn test_binary_json_equal() {
// Test the equal case
let mut builder = BinaryBuilder::new(6);
builder.append_value(b"hello").unwrap();
builder.append_null().unwrap();
builder.append_null().unwrap();
builder.append_value(b"world").unwrap();
builder.append_null().unwrap();
builder.append_null().unwrap();
let arrow_array = builder.finish();
let json_array: Value = serde_json::from_str(
r#"
[
"hello",
null,
null,
"world",
null,
null
]
"#,
)
.unwrap();
assert!(arrow_array.eq(&json_array));
assert!(json_array.eq(&arrow_array));
// Test unequal case
let arrow_array =
StringArray::from(vec![Some("hello"), None, None, Some("world"), None, None]);
let json_array: Value = serde_json::from_str(
r#"
[
"hello",
null,
null,
"arrow",
null,
null
]
"#,
)
.unwrap();
assert!(arrow_array.ne(&json_array));
assert!(json_array.ne(&arrow_array));
// Test unequal length case
let arrow_array =
StringArray::from(vec![Some("hello"), None, None, Some("world"), None]);
let json_array: Value = serde_json::from_str(
r#"
[
"hello",
null,
null,
"arrow",
null,
null
]
"#,
)
.unwrap();
assert!(arrow_array.ne(&json_array));
assert!(json_array.ne(&arrow_array));
// Test incorrect type case
let arrow_array =
StringArray::from(vec![Some("hello"), None, None, Some("world"), None]);
let json_array: Value = serde_json::from_str(
r#"
{
"a": 1
}
"#,
)
.unwrap();
assert!(arrow_array.ne(&json_array));
assert!(json_array.ne(&arrow_array));
// Test incorrect value type case
let arrow_array =
StringArray::from(vec![Some("hello"), None, None, Some("world"), None]);
let json_array: Value = serde_json::from_str(
r#"
[
"hello",
null,
null,
1,
null,
null
]
"#,
)
.unwrap();
assert!(arrow_array.ne(&json_array));
assert!(json_array.ne(&arrow_array));
}
#[test]
fn test_fixed_size_binary_json_equal() {
// Test the equal case
let mut builder = FixedSizeBinaryBuilder::new(15, 5);
builder.append_value(b"hello").unwrap();
builder.append_null().unwrap();
builder.append_value(b"world").unwrap();
let arrow_array: FixedSizeBinaryArray = builder.finish();
let json_array: Value = serde_json::from_str(
r#"
[
"hello",
null,
"world"
]
"#,
)
.unwrap();
assert!(arrow_array.eq(&json_array));
assert!(json_array.eq(&arrow_array));
// Test unequal case
builder.append_value(b"hello").unwrap();
builder.append_null().unwrap();
builder.append_value(b"world").unwrap();
let arrow_array: FixedSizeBinaryArray = builder.finish();
let json_array: Value = serde_json::from_str(
r#"
[
"hello",
null,
"arrow"
]
"#,
)
.unwrap();
assert!(arrow_array.ne(&json_array));
assert!(json_array.ne(&arrow_array));
// Test unequal length case
let json_array: Value = serde_json::from_str(
r#"
[
"hello",
null,
null,
"world"
]
"#,
)
.unwrap();
assert!(arrow_array.ne(&json_array));
assert!(json_array.ne(&arrow_array));
// Test incorrect type case
let json_array: Value = serde_json::from_str(
r#"
{
"a": 1
}
"#,
)
.unwrap();
assert!(arrow_array.ne(&json_array));
assert!(json_array.ne(&arrow_array));
// Test incorrect value type case
let json_array: Value = serde_json::from_str(
r#"
[
"hello",
null,
1
]
"#,
)
.unwrap();
assert!(arrow_array.ne(&json_array));
assert!(json_array.ne(&arrow_array));
}
#[test]
fn test_decimal_json_equal() {
// Test the equal case
let mut builder = DecimalBuilder::new(30, 23, 6);
builder.append_value(1_000).unwrap();
builder.append_null().unwrap();
builder.append_value(-250).unwrap();
let arrow_array: DecimalArray = builder.finish();
let json_array: Value = serde_json::from_str(
r#"
[
"1000",
null,
"-250"
]
"#,
)
.unwrap();
assert!(arrow_array.eq(&json_array));
assert!(json_array.eq(&arrow_array));
// Test unequal case
builder.append_value(1_000).unwrap();
builder.append_null().unwrap();
builder.append_value(55).unwrap();
let arrow_array: DecimalArray = builder.finish();
let json_array: Value = serde_json::from_str(
r#"
[
"1000",
null,
"-250"
]
"#,
)
.unwrap();
assert!(arrow_array.ne(&json_array));
assert!(json_array.ne(&arrow_array));
// Test unequal length case
let json_array: Value = serde_json::from_str(
r#"
[
"1000",
null,
null,
"55"
]
"#,
)
.unwrap();
assert!(arrow_array.ne(&json_array));
assert!(json_array.ne(&arrow_array));
// Test incorrect type case
let json_array: Value = serde_json::from_str(
r#"
{
"a": 1
}
"#,
)
.unwrap();
assert!(arrow_array.ne(&json_array));
assert!(json_array.ne(&arrow_array));
// Test incorrect value type case
let json_array: Value = serde_json::from_str(
r#"
[
"hello",
null,
1
]
"#,
)
.unwrap();
assert!(arrow_array.ne(&json_array));
assert!(json_array.ne(&arrow_array));
}
#[test]
fn test_struct_json_equal() {
let strings: ArrayRef = Arc::new(StringArray::from(vec![
Some("joe"),
None,
None,
Some("mark"),
Some("doe"),
]));
let ints: ArrayRef = Arc::new(Int32Array::from(vec![
Some(1),
Some(2),
None,
Some(4),
Some(5),
]));
let arrow_array =
StructArray::try_from(vec![("f1", strings.clone()), ("f2", ints.clone())])
.unwrap();
let json_array: Value = serde_json::from_str(
r#"
[
{
"f1": "joe",
"f2": 1
},
{
"f2": 2
},
null,
{
"f1": "mark",
"f2": 4
},
{
"f1": "doe",
"f2": 5
}
]
"#,
)
.unwrap();
assert!(arrow_array.eq(&json_array));
assert!(json_array.eq(&arrow_array));
// Test unequal length case
let json_array: Value = serde_json::from_str(
r#"
[
{
"f1": "joe",
"f2": 1
},
{
"f2": 2
},
null,
{
"f1": "mark",
"f2": 4
}
]
"#,
)
.unwrap();
assert!(arrow_array.ne(&json_array));
assert!(json_array.ne(&arrow_array));
// Test incorrect type case
let json_array: Value = serde_json::from_str(
r#"
{
"f1": "joe",
"f2": 1
}
"#,
)
.unwrap();
assert!(arrow_array.ne(&json_array));
assert!(json_array.ne(&arrow_array));
// Test not all object case
let json_array: Value = serde_json::from_str(
r#"
[
{
"f1": "joe",
"f2": 1
},
2,
null,
{
"f1": "mark",
"f2": 4
}
]
"#,
)
.unwrap();
assert!(arrow_array.ne(&json_array));
assert!(json_array.ne(&arrow_array));
}
#[test]
fn test_null_json_equal() {
// Test equaled array
let arrow_array = NullArray::new(4);
let json_array: Value = serde_json::from_str(
r#"
[
null, null, null, null
]
"#,
)
.unwrap();
assert!(arrow_array.eq(&json_array));
assert!(json_array.eq(&arrow_array));
// Test unequaled array
let arrow_array = NullArray::new(2);
let json_array: Value = serde_json::from_str(
r#"
[
null, null, null
]
"#,
)
.unwrap();
assert!(arrow_array.ne(&json_array));
assert!(json_array.ne(&arrow_array));
}
}