Skip to content

Commit

Permalink
added test for json when json is invalid
Browse files Browse the repository at this point in the history
  • Loading branch information
dadepo committed Nov 18, 2023
1 parent e2f4ab5 commit bd7f798
Showing 1 changed file with 38 additions and 4 deletions.
42 changes: 38 additions & 4 deletions df_extras_sqlite/src/json_udfs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,20 @@ use datafusion::common::DataFusionError;
use datafusion::error::Result;
use serde_json::Value;

/// The json(X) function verifies that its argument X is a valid JSON string and returns a minified
/// version of that JSON string (with all unnecessary whitespace removed).
/// If X is not a well-formed JSON string, then this routine throws an error.
pub fn json(args: &[ArrayRef]) -> Result<ArrayRef> {
let json_strings = datafusion::common::cast::as_string_array(&args[0])?;

let mut string_builder = StringBuilder::with_capacity(json_strings.len(), u8::MAX as usize);
json_strings.iter().try_for_each(|json_string| {
if let Some(json_string) = json_string {
let value: Value = serde_json::from_str(json_string).map_err(|e| {
DataFusionError::Internal(format!("Parsing {json_string} failed with error {e}"))
let value: Value = serde_json::from_str(json_string).map_err(|_| {
DataFusionError::Internal("Runtime error: malformed JSON".to_string())
})?;
let pretty_json = serde_json::to_string(&value).map_err(|e| {
DataFusionError::Internal(format!("Parsing {json_string} failed with error {e}"))
let pretty_json = serde_json::to_string(&value).map_err(|_| {
DataFusionError::Internal("Runtime error: malformed JSON".to_string())
})?;
string_builder.append_value(pretty_json);
Ok::<(), DataFusionError>(())
Expand All @@ -28,6 +31,15 @@ pub fn json(args: &[ArrayRef]) -> Result<ArrayRef> {
Ok(Arc::new(string_builder.finish()) as ArrayRef)
}

/// The json_valid(X) function return 1 if the argument X is well-formed canonical RFC-7159 JSON
/// without any extensions, or return 0 if the argument X is not well-formed JSON or is
/// JSON that includes JSON5 extensions.
///
/// Examples:
///
/// json_valid('{"x":35}') → 1
/// json_valid('{"x":35') → 0
/// json_valid(NULL) → NULL
pub fn json_valid(args: &[ArrayRef]) -> Result<ArrayRef> {
let json_strings = datafusion::common::cast::as_string_array(&args[0])?;
let mut uint_builder = UInt8Array::builder(json_strings.len());
Expand Down Expand Up @@ -87,6 +99,28 @@ mod tests {
Ok(())
}

#[tokio::test]
async fn test_invalid_json() -> Result<()> {
let ctx = register_udfs_for_test()?;
let df = ctx
.sql(
r#"select index, json(' { "this" : "is", "a": [ "test" ] ') as col_result FROM json_table ORDER BY index ASC"#,
)
.await?;

let result = df.clone().collect().await;

assert!(&result
.err()
.unwrap()
.find_root()
.find_root()
.to_string()
.contains("Internal error: Runtime error: malformed JSON"));

Ok(())
}

#[tokio::test]
async fn test_json_valid() -> Result<()> {
let ctx = register_udfs_for_test()?;
Expand Down

0 comments on commit bd7f798

Please sign in to comment.