Skip to content

Commit

Permalink
fix: json path query and value functions (#2060)
Browse files Browse the repository at this point in the history
* feat: udf onnx feature expression

* feat: udf onnx feature expression

* feat: udf onnx feature expression

* fix: e2e tests for json

* fix: e2e tests for json

* fix: e2e tests for json

* fix: e2e tests for json

* fix: e2e tests for json
  • Loading branch information
Chloe Kim authored Sep 20, 2023
1 parent c675e28 commit 44da022
Show file tree
Hide file tree
Showing 2 changed files with 252 additions and 4 deletions.
26 changes: 24 additions & 2 deletions dozer-sql/expression/src/json_functions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,18 @@ impl JsonFunctionType {
let json_input = args[0].evaluate(record, schema)?;
let path = args[1].evaluate(record, schema)?.to_string();

Ok(Field::Json(self.evaluate_json(json_input, path)?))
if let Ok(json_value) = self.evaluate_json(json_input, path) {
match json_value {
JsonValue::Object(_) => Ok(Field::Json(JsonValue::Null)),
JsonValue::Array(_) => Ok(Field::Json(JsonValue::Null)),
JsonValue::String(val) => Ok(Field::Json(JsonValue::String(val))),
JsonValue::Bool(val) => Ok(Field::Json(JsonValue::Bool(val))),
JsonValue::Number(val) => Ok(Field::Json(JsonValue::Number(val))),
JsonValue::Null => Ok(Field::Json(JsonValue::Null)),
}
} else {
Ok(Field::Null)
}
}

pub(crate) fn evaluate_json_query(
Expand All @@ -74,7 +85,18 @@ impl JsonFunctionType {
let json_input = args[0].evaluate(record, schema)?;
let path = args[1].evaluate(record, schema)?.to_string();

Ok(Field::Json(self.evaluate_json(json_input, path)?))
if let Ok(json_value) = self.evaluate_json(json_input, path) {
match json_value {
JsonValue::Object(val) => Ok(Field::Json(JsonValue::Object(val))),
JsonValue::Array(val) => Ok(Field::Json(JsonValue::Array(val))),
JsonValue::String(_) => Ok(Field::Json(JsonValue::Null)),
JsonValue::Bool(_) => Ok(Field::Json(JsonValue::Null)),
JsonValue::Number(_) => Ok(Field::Json(JsonValue::Null)),
JsonValue::Null => Ok(Field::Json(JsonValue::Null)),
}
} else {
Ok(Field::Null)
}
}
}

Expand Down
230 changes: 228 additions & 2 deletions dozer-sql/src/expression/tests/json_functions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ fn test_json_query_null() {
.clone(),
vec![Field::Json(json_val)],
);
assert_eq!(f, Field::Json(JsonValue::String("Basic".to_string())));
assert_eq!(f, Field::Json(JsonValue::Null));
}

#[test]
Expand All @@ -187,7 +187,7 @@ fn test_json_query_len_one_array() {
.unwrap();

let f = run_fct(
"SELECT JSON_VALUE(jsonInfo,'$.info.tags') FROM users",
"SELECT JSON_QUERY(jsonInfo,'$.info.tags') FROM users",
Schema::default()
.field(
FieldDefinition::new(
Expand Down Expand Up @@ -645,3 +645,229 @@ fn test_json_value_cast() {

assert_eq!(f, Field::Boolean(true));
}

#[test]
fn test_json_value_diff_1() {
let json_val = serde_json_to_json_value(json!(
{ "x": [0,1], "y": "[0,1]", "z": "Monty" }
))
.unwrap();

let mut f = run_fct(
"SELECT JSON_QUERY(jsonInfo,'$') FROM users",
Schema::default()
.field(
FieldDefinition::new(
String::from("jsonInfo"),
FieldType::Json,
false,
SourceDefinition::Dynamic,
),
false,
)
.clone(),
vec![Field::Json(json_val.clone())],
);

assert_eq!(f, Field::Json(json_val.clone()));

f = run_fct(
"SELECT JSON_VALUE(jsonInfo,'$') FROM users",
Schema::default()
.field(
FieldDefinition::new(
String::from("jsonInfo"),
FieldType::Json,
false,
SourceDefinition::Dynamic,
),
false,
)
.clone(),
vec![Field::Json(json_val)],
);

assert_eq!(f, Field::Json(JsonValue::Null));
}

#[test]
fn test_json_value_diff_2() {
let json_val = serde_json_to_json_value(json!(
{ "x": [0,1], "y": "[0,1]", "z": "Monty" }
))
.unwrap();

let mut f = run_fct(
"SELECT JSON_QUERY(jsonInfo,'$.x') FROM users",
Schema::default()
.field(
FieldDefinition::new(
String::from("jsonInfo"),
FieldType::Json,
false,
SourceDefinition::Dynamic,
),
false,
)
.clone(),
vec![Field::Json(json_val.clone())],
);

assert_eq!(
f,
Field::Json(JsonValue::Array(vec![
JsonValue::Number(OrderedFloat(0_f64)),
JsonValue::Number(OrderedFloat(1_f64))
]))
);

f = run_fct(
"SELECT JSON_VALUE(jsonInfo,'$.x') FROM users",
Schema::default()
.field(
FieldDefinition::new(
String::from("jsonInfo"),
FieldType::Json,
false,
SourceDefinition::Dynamic,
),
false,
)
.clone(),
vec![Field::Json(json_val)],
);

assert_eq!(f, Field::Json(JsonValue::Null));
}

#[test]
fn test_json_value_diff_3() {
let json_val = serde_json_to_json_value(json!(
{ "x": [0,1], "y": "[0,1]", "z": "Monty" }
))
.unwrap();

let mut f = run_fct(
"SELECT JSON_QUERY(jsonInfo,'$.y') FROM users",
Schema::default()
.field(
FieldDefinition::new(
String::from("jsonInfo"),
FieldType::Json,
false,
SourceDefinition::Dynamic,
),
false,
)
.clone(),
vec![Field::Json(json_val.clone())],
);

assert_eq!(f, Field::Json(JsonValue::Null));

f = run_fct(
"SELECT JSON_VALUE(jsonInfo,'$.y') FROM users",
Schema::default()
.field(
FieldDefinition::new(
String::from("jsonInfo"),
FieldType::Json,
false,
SourceDefinition::Dynamic,
),
false,
)
.clone(),
vec![Field::Json(json_val)],
);

assert_eq!(f, Field::Json(JsonValue::String("[0,1]".to_string())));
}

#[test]
fn test_json_value_diff_4() {
let json_val = serde_json_to_json_value(json!(
{ "x": [0,1], "y": "[0,1]", "z": "Monty" }
))
.unwrap();

let mut f = run_fct(
"SELECT JSON_QUERY(jsonInfo,'$.z') FROM users",
Schema::default()
.field(
FieldDefinition::new(
String::from("jsonInfo"),
FieldType::Json,
false,
SourceDefinition::Dynamic,
),
false,
)
.clone(),
vec![Field::Json(json_val.clone())],
);

assert_eq!(f, Field::Json(JsonValue::Null));

f = run_fct(
"SELECT JSON_VALUE(jsonInfo,'$.z') FROM users",
Schema::default()
.field(
FieldDefinition::new(
String::from("jsonInfo"),
FieldType::Json,
false,
SourceDefinition::Dynamic,
),
false,
)
.clone(),
vec![Field::Json(json_val)],
);

assert_eq!(f, Field::Json(JsonValue::String("Monty".to_string())));
}

#[test]
fn test_json_value_diff_5() {
let json_val = serde_json_to_json_value(json!(
{ "x": [0,1], "y": "[0,1]", "z": "Monty" }
))
.unwrap();

let mut f = run_fct(
"SELECT JSON_QUERY(jsonInfo,'$.x[0]') FROM users",
Schema::default()
.field(
FieldDefinition::new(
String::from("jsonInfo"),
FieldType::Json,
false,
SourceDefinition::Dynamic,
),
false,
)
.clone(),
vec![Field::Json(json_val.clone())],
);

assert_eq!(f, Field::Json(JsonValue::Null));

f = run_fct(
"SELECT JSON_VALUE(jsonInfo,'$.x[0]') FROM users",
Schema::default()
.field(
FieldDefinition::new(
String::from("jsonInfo"),
FieldType::Json,
false,
SourceDefinition::Dynamic,
),
false,
)
.clone(),
vec![Field::Json(json_val)],
);

assert_eq!(f, Field::Json(JsonValue::Number(OrderedFloat(0_f64))));
}

0 comments on commit 44da022

Please sign in to comment.