datafusion-contrib / datafusion-contrib/datafusion-functions-json
feat: Function to mimick Postgres `json_extract_path_text`
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 62
- Forks
- 33
- Avg merge
- 1d 12h
- Merged PRs (30d)
- 9
Description
In Postgres, json_extract_path_text will return a string value without the surrounding double quotes, and any other values as casted strings. Paths not found become NULL's.
https://www.postgresql.org/docs/9.3/functions-json.html
I tried using json_as_text but it fails on cases where the path is not found.
Locally I have vendored the JsonPath and created this function which is giving me the expected behavior.
If there is no way of getting this desired behavior with the existing tools, I could publish my UDF. It's marginally redundant behavior, so I wonder if theres an easier way to factor things.
/// This function mimics the behavior of PostgreSQL's `json_extract_path_text`,
/// which returns the value at a given JSON path as text or NULL if not found.
/// Non-string values are returned as their JSON representation.
fn jiter_json_extract_path_text(
opt_json: Option<&str>,
path: &[JsonPath],
) -> Result<Option<String>, jiter::JiterError> {
if let Some((mut jiter, peek)) = jiter_json_find(opt_json, path) {
match peek {
Peek::Null => {
jiter.known_null()?;
// The value is JSON null; Postgres returns SQL NULL in this case
Ok(None)
}
Peek::String => {
let s = jiter.known_str()?;
Ok(Some(s.to_owned()))
}
_ => {
// For other types (number, bool, object, array), we return their textual representation.
let start = jiter.current_index();
jiter.known_skip(peek)?;
let slice = jiter.slice_to_current(start);
match String::from_utf8(slice.to_vec()) {
Ok(val_str) => Ok(Some(val_str)),
Err(_) => Ok(None),
}
}
}
} else {
// Path not found; return NULL
Ok(None)
}
}
Side note: Could JsonPath be published with the crate in a common package?
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by examining the existing json_as_text behavior and the locally described jiter_json_find and JsonPath usage. Compare the desired PostgreSQL semantics for missing paths, JSON nulls, strings, and other values with the available tools. Done means a supported function returns text or NULL consistently with the stated behavior, with relevant tests added if the project has an established test location.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- postgresql, rust
- Domain
- databases
- Issue type
- Feature
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 38/100