Skip to content

Commit

Permalink
Added support for sqlites json_type
Browse files Browse the repository at this point in the history
  • Loading branch information
dadepo committed Nov 25, 2023
1 parent 3025357 commit 9d0e39c
Show file tree
Hide file tree
Showing 7 changed files with 645 additions and 16 deletions.
103 changes: 103 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@ version = "0.1.0"
edition = "2021"

[dependencies]
anyhow = "1.0.75"
datafusion = "33.0.0"
ipnet = "2.7.2"
serde = "1.0.192"
serde_json = { version = "1.0.108", features = ["preserve_order"] }
serde_json_path = "0.6.4"
tokio = { version = "1.25.0", features = ["macros", "rt", "parking_lot"] }

[features]
Expand Down
70 changes: 70 additions & 0 deletions src/common/mod.rs
Original file line number Diff line number Diff line change
@@ -1 +1,71 @@
use anyhow::anyhow;
use serde_json_path::JsonPath;

pub mod test_utils;

pub(crate) fn get_value_at(
json: serde_json::Value,
path: &str,
) -> anyhow::Result<serde_json::Value> {
let path = JsonPath::parse(path)?;
path.query(&json)
.exactly_one()
.map(|json| json.clone())
.map_err(|err| anyhow!(err))
}

pub(crate) fn get_value_at_string(
json_string: &str,
path: &str,
) -> anyhow::Result<serde_json::Value> {
let json_value: serde_json::Value = serde_json::from_str(json_string)?;
get_value_at(json_value, path)
}

pub(crate) fn get_json_type(json_value: &serde_json::Value) -> anyhow::Result<String> {
let result = if json_value.is_boolean() {
match json_value.as_bool() {
Some(bool_value) => bool_value.to_string(),
None => return Err(anyhow!("Internal error".to_string())),
}
} else if json_value.is_number() {
if json_value.to_string().parse::<i64>().is_ok() {
"integer".to_string()
} else {
"real".to_string()
}
} else if json_value.is_f64() || json_value.is_i64() || json_value.is_u64() {
"real".to_string()
} else if json_value.is_string() {
"text".to_string()
} else if json_value.is_array() {
"array".to_string()
} else if json_value.is_object() {
"object".to_string()
} else if json_value.is_null() {
"null".to_string()
} else {
return Err(anyhow!("Unknown json type".to_string()));
};

Ok(result)
}

pub(crate) fn get_json_string_type(json_string: &str) -> anyhow::Result<String> {
let json_value: serde_json::Value =
serde_json::from_str(json_string).map_err(|err| anyhow!(err))?;
get_json_type(&json_value)
}

#[cfg(test)]
mod test {
use crate::common::get_value_at;
use serde_json::json;

#[test]
fn test_get_value_at() {
let value = json!({"foo": ["bar", "baz"]});
let result = get_value_at(value, "$.foo").unwrap();
assert_eq!(result, json!(["bar", "baz"]));
}
}
33 changes: 27 additions & 6 deletions src/common/test_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,21 +54,42 @@ pub fn set_up_json_data_test() -> Result<SessionContext> {
let batch = RecordBatch::try_new(
schema,
vec![
Arc::new(UInt8Array::from_iter_values([1, 2])),
Arc::new(UInt8Array::from_iter_values([1, 2, 3, 4, 5, 6, 7, 8])),
Arc::new(StringArray::from(vec![
Some(r#" { "this" : "is", "a": [ "test" ] } "#),
// Some("172.16.0.0/20"),
// Some("10.0.0.0/16"),
// Some("2001:0db8::/32"),
// Some("2001:db8:abcd::/48"),
Some(r#"{"a":[2,3.5,true,false,null,"x"]}"#),
Some(r#"[ "one", "two" ]"#),
Some(r#"123"#),
Some(r#"12.3"#),
Some(r#"true"#),
Some(r#"false"#),
None,
])),
],
)?;

// declare a new context
let ctx = SessionContext::new();
ctx.register_batch("json_table", batch)?;
// declare a table in memory.
ctx.register_batch("json_table", batch)?;

// data for json_type
let schema = Arc::new(Schema::new(vec![
Field::new("index", DataType::UInt8, false),
Field::new("json_data", DataType::Utf8, true),
]));

// define data.
let batch = RecordBatch::try_new(
schema,
vec![
Arc::new(UInt8Array::from_iter_values([1])),
Arc::new(StringArray::from(vec![Some(
r#"{"a":[2,3.5,true,false,null,"x"]}"#,
)])),
],
)?;

ctx.register_batch("json_path_table", batch)?;
Ok(ctx)
}
Loading

0 comments on commit 9d0e39c

Please sign in to comment.