Skip to content
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

feat(sqlite): add json_array_length fn #4479

Merged

Conversation

IamTossan
Copy link
Contributor

@IamTossan IamTossan commented Feb 11, 2025

Add json_array_length to sqlite json functions

Notes

  • I noticed the doc-tests don't work with outdated versions of sqlite
    • use diesel::dsl::json_array_length was the postgres version ?!
    • use diesel::dsl::json_array_length_with_path was not found
  • this is why I added sqlite version assertion
    • that might break CI
    • that might explain why doctests are skipped for json_pretty in the same file below a certain version
  • as of now, I am not aware if there some kind official version support
  • using the apt package manager in Pop_os, i had to manually install libsqlite3 since the version from apt was outdated

Install sqlite3 lib

  • download sqlite-autoconf-<VERSION>.tar.gz from https://www.sqlite.org/download.html
  • unpack the file: tar xvfz ../sqlite-autoconf-<VERSION>.tar.gz
  • get into the created folder
  • run ./configure
  • run make
  • run sudo make install
  • find where to put libsqlite3.so (find / -name libsqlite3.so ... => in my case /usr/lib/x86_64-linux-gnu) and copy the file (in my case had to make a symbolic link too)

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 working on this. It's already looking like a good start, but we want to improve some things to get the CI passing + make it more robust in terms of how types are represented.

Comment on lines 196 to 197
/// assert_eq!(major, 3);
/// assert!(minor >= 46);
Copy link
Member

Choose a reason for hiding this comment

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

I would rather skip the test in this case instead of panicing, as we do for the other tests as well: https://github.com/diesel-rs/diesel/blob/master/diesel/src/sqlite/expression/functions.rs#L82-L87

Comment on lines 142 to 143
/// assert_eq!(major, 3);
/// assert!(minor >= 46);
Copy link
Member

Choose a reason for hiding this comment

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

I would rather skip the test in this case instead of panicing, as we do for the other tests as well: https://github.com/diesel-rs/diesel/blob/master/diesel/src/sqlite/expression/functions.rs#L82-L87

///
/// assert_eq!(json!(0), result);
///
/// # Ok(())
Copy link
Member

Choose a reason for hiding this comment

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

We also want a test here that checks what happens if you pass a SQL NULL value to the function. So something like

let result = diesel::select(json_array_length::<Nullable<Json, _>>(None::<serde_json::Value>())

Possibly we also want variants that use Jsonb instead of Json as SQL type.

/// # }
/// ```
#[sql_name = "json_array_length"]
fn json_array_length_with_path<J: JsonOrNullableJsonOrJsonbOrNullableJsonb + MaybeNullableValue<Json>>(j: J, path: Text) -> J::Out;
Copy link
Member

Choose a reason for hiding this comment

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

This must unconditionally return a Nullable<Json> or Nullable<Jsonb> type as the nullablity of the return value depends on runtime constraints (whether path exists or not).

Suggested change
fn json_array_length_with_path<J: JsonOrNullableJsonOrJsonbOrNullableJsonb + MaybeNullableValue<Json>>(j: J, path: Text) -> J::Out;
fn json_array_length_with_path<J: JsonOrNullableJsonOrJsonbOrNullableJsonb + IntoNullable>(j: J, path: Text) -> J::Nullable;

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The J::Nullable requires me to add + SingleValue to J which gets me this error:

the trait `sql_types::SingleValue` is not implemented for `<J as sql_types::IntoNullable>::Nullable`

Haven't been able to find a solution yet. Any insights?

Copy link
Member

Choose a reason for hiding this comment

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

I had another look and it turns out that the suggestion was not correct. This function needs to return Nullable<Integer> instead. I just push a fix in 4e181aa for that + rebased the PR to incorporate recent changes from master branch.

This should be good to merge now. Thanks again for contributing.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thank you!
As I am still fairly unfamiliar to the project, I hope to be even more helpful next time.

@weiznich weiznich force-pushed the feat/add-json-array-length-fn-to-sqlite branch from 8352d8a to 4e181aa Compare February 14, 2025 10:15
@weiznich weiznich enabled auto-merge February 14, 2025 10:19
@weiznich weiznich added this pull request to the merge queue Feb 14, 2025
Merged via the queue into diesel-rs:master with commit 3d14f75 Feb 14, 2025
34 checks passed
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