Skip to content

feat(sqlite): Add json_extract and jsonb_extract functions #4530

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

KekmaTime
Copy link
Contributor

This PR covers implementation of json_extract() function

  • json_extract(X, P) - Extracts values from JSON data using path expressions.
  • jsonb_extract(X, P) - Similar to json_extract but returns arrays/objects in JSONB format.

@KekmaTime KekmaTime force-pushed the sqlite-json-extract branch from 1b8f6c4 to 56fbeb4 Compare March 9, 2025 02:18
@weiznich weiznich requested a review from a team March 11, 2025 18:55
Copy link
Member

@weiznich weiznich left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for opening this PR. It seems like this method is not as straighforward to represent in diesel as we would like. I made some suggestions how we could represent it anyway. Maybe you can have a look at updating the PR? Let me know if you need more help there.

The comments about the signatures apply to the jsonb variant as well.

/// Return type of [`json_extract(json, path)`](super::functions::json_extract())
#[allow(non_camel_case_types)]
#[cfg(feature = "sqlite")]
pub type json_extract<J, P> = super::functions::json_extract<J, P, J, P>;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
pub type json_extract<J, P> = super::functions::json_extract<J, P, J, P>;
pub type json_extract<J, P> = super::functions::json_extract<SqlTypeOf<J>, SqlTypeOf<P>, J, P>;

To fix the compilation errors

/// Return type of [`jsonb_extract(json, path)`](super::functions::jsonb_extract())
#[allow(non_camel_case_types)]
#[cfg(feature = "sqlite")]
pub type jsonb_extract<J, P> = super::functions::jsonb_extract<J, P, J, P>;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
pub type jsonb_extract<J, P> = super::functions::jsonb_extract<J, P, J, P>;
pub type jsonb_extract<J, P> = super::functions::jsonb_extract<SqlTypeOf<J>, SqlTypeOf<P>, J, P>;

to fix the compilation errors

Comment on lines +902 to +903
/// If there are multiple path arguments (P1, P2, and so forth) then this routine returns SQLite text
/// which is a well-formed JSON array holding the various values.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This part is not possible with the function signature below. This refers to a use case where you would call json_extract(json_col, path_1, path_2) which is disallowed by the signature.

Comment on lines +898 to +900
/// If only a single path P1 is provided, then the SQL datatype of the result is NULL for a JSON null,
/// INTEGER or REAL for a JSON numeric value, an INTEGER zero for a JSON false value, an INTEGER one for a JSON true value,
/// the dequoted text for a JSON string value, and a text representation for JSON object and array values.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That means the signature as expressed below doesn't really match what is returned by the function. Given that is is essentially a runtime determined value I do not have any good recommendation how to make this work with diesels static checking.

I could imaging to expose just several variants of this function, so json_extract_as_text, json_extract_as_integer, json_extract_as_float and json_extract_as_json for the different return type variants and let the users chose the right one for their usecase. After all you can even convert any sql return value to any other type internally.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants