diesel-rs / diesel

A safe, extensible ORM and Query Builder for Rust
https://diesel.rs
Apache License 2.0
12.79k stars 1.08k forks source link

working on json_path_exists #4286

Open valkrypton opened 1 month ago

valkrypton commented 1 month ago

@weiznich I was trying to implement the jsonb_path_exists function. One of its argument is of type Jsonpath. Currently there is no such type in diesel, so I tried to implement it using the jsonpath_rust crate.

I implemented the FromSql trait for it, but I could not figure out how to implement the ToSql trait. I'd appreciate if you could take a look and help me with this or maybe i am going completely in the wrong direction with this?

weiznich commented 1 month ago

Thanks for working on this. The FromSql implementation needs to read the binary representation of a json path as defined in the PostgreSQL protocol. Unfortunately the documentation of that format is mostly not existing, at least for anything that's not a trivial type. That means you likely need to perform some experimentation. One possibility would be to just setup a test case that loads a jsonpath value from the database and inspect the output. That should tell us how postgres serializes these data. Hopefully that's just the path as string or something simple like that. The other way is to dig through the postgres source code and find something there. This file might be a starting point.

valkrypton commented 2 weeks ago

Hey @weiznich, I tried working on this again, and I somewhat got to implement the Jsonpath type. But now the doctest for the function are failing due to the following error:

failures:

---- diesel/src/pg/expression/functions.rs - pg::expression::functions::jsonb_path_exists (line 2290) stdout ----
error[E0599]: the method `get_result` exists for struct `jsonb_path_exists<Jsonb, Jsonpath, Bound<Jsonb, Value>, Bound<Jsonpath, JsonPath>>`, but its trait bounds were not satisfied
    --> diesel/src/pg/expression/functions.rs:2306:71
     |
18   |   let exists = jsonb_path_exists::<Jsonb,Jsonpath,_,_>(jsonb,json_path).get_result::<bool>(connection)?;
     |                                                                         ^^^^^^^^^^ method cannot be called due to unsatisfied trait bounds
     |
    ::: /Users/ali.tariq/diesel/diesel/src/pg/expression/functions.rs:2284:1
     |
2284 | / define_sql_function! {
2285 | |     /// This form of jsonb_object takes keys and values pairwise from two separate arrays.
2286 | |     /// In all other respects it is identical to the one-argument form.
2287 | |     ///
...    |
2310 | |     fn jsonb_path_exists<J: JsonbOrNullableJsonb + SingleValue, P: MaybeNullableValue<Jsonpath>>(jsonb: J, path: P) -> Bool;
2311 | | }
     | |_- doesn't satisfy `_: RunQueryDsl<_>` or `_: Table`
     |
     = note: the full type name has been written to '/var/folders/gn/jjjy0cpx2qvcq_ncmnq8bf3m0000gp/T/rustdoctestDCO66I/rust_out.long-type-7427101102093426123.txt'
     = note: consider using `--verbose` to print the full type name to the console
     = note: the following trait bounds were not satisfied:
             `diesel::pg::expression::functions::jsonb_path_exists_utils::jsonb_path_exists<Jsonb, Jsonpath, diesel::expression::bound::Bound<Jsonb, Value>, diesel::expression::bound::Bound<Jsonpath, JsonPath>>: Table`
             which is required by `diesel::pg::expression::functions::jsonb_path_exists_utils::jsonb_path_exists<Jsonb, Jsonpath, diesel::expression::bound::Bound<Jsonb, Value>, diesel::expression::bound::Bound<Jsonpath, JsonPath>>: diesel::RunQueryDsl<_>`
             `&diesel::pg::expression::functions::jsonb_path_exists_utils::jsonb_path_exists<Jsonb, Jsonpath, diesel::expression::bound::Bound<Jsonb, Value>, diesel::expression::bound::Bound<Jsonpath, JsonPath>>: Table`
             which is required by `&diesel::pg::expression::functions::jsonb_path_exists_utils::jsonb_path_exists<Jsonb, Jsonpath, diesel::expression::bound::Bound<Jsonb, Value>, diesel::expression::bound::Bound<Jsonpath, JsonPath>>: diesel::RunQueryDsl<_>`
             `&mut diesel::pg::expression::functions::jsonb_path_exists_utils::jsonb_path_exists<Jsonb, Jsonpath, diesel::expression::bound::Bound<Jsonb, Value>, diesel::expression::bound::Bound<Jsonpath, JsonPath>>: Table`
             which is required by `&mut diesel::pg::expression::functions::jsonb_path_exists_utils::jsonb_path_exists<Jsonb, Jsonpath, diesel::expression::bound::Bound<Jsonb, Value>, diesel::expression::bound::Bound<Jsonpath, JsonPath>>: diesel::RunQueryDsl<_>`

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0599`.
Couldn't compile the test.

failures:
    diesel/src/pg/expression/functions.rs - pg::expression::functions::jsonb_path_exists (line 2290)

test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 310 filtered out; finished in 0.67s

error: doctest failed, to rerun pass `--doc`

Some pointers would be appreciated on how to implement the missing traits.