use datafusion::error::Result as DFResult;
use datafusion::prelude::SessionContext;
use datafusion_functions_json::udfs;
pub fn register_json_getter_udfs(ctx: &SessionContext) -> DFResult<()> {
for udf in [
udfs::json_get_udf(),
udfs::json_get_bool_udf(),
udfs::json_get_float_udf(),
udfs::json_get_int_udf(),
udfs::json_get_json_udf(),
udfs::json_get_array_udf(),
udfs::json_as_text_udf(),
udfs::json_get_str_udf(),
udfs::json_contains_udf(),
udfs::json_length_udf(),
udfs::json_object_keys_udf(),
udfs::json_from_scalar_udf(),
] {
ctx.register_udf((*udf).clone());
}
Ok(())
}
#[cfg(test)]
mod tests {
use super::*;
#[tokio::test]
async fn the_getters_are_registered_and_extract() {
let ctx = SessionContext::new();
register_json_getter_udfs(&ctx).expect("registers");
let batches = ctx
.sql("SELECT json_get_str('{\"a\": \"x\"}', 'a') AS v")
.await
.expect("plans")
.collect()
.await
.expect("executes");
let col = batches[0]
.column(0)
.as_any()
.downcast_ref::<arrow::array::StringArray>()
.expect("string column");
assert_eq!(col.value(0), "x");
}
#[tokio::test]
async fn arrow_operators_keep_native_planning() {
let ctx = SessionContext::new();
register_json_getter_udfs(&ctx).expect("registers");
let err = ctx
.sql("SELECT '{\"a\":1}'::text ->> 'a'")
.await
.expect_err("no rewrite means no plan");
let msg = err.to_string();
assert!(msg.contains("->>"), "the operator is named: {msg}");
assert!(
msg.contains("not yet supported"),
"native (unsupported), not rewritten: {msg}"
);
}
}