Repository: diesel-rs/diesel
File: diesel/src/sqlite/expression/functions.rs (Rust)

Code before:
    /// ))
    /// .get_result::<Option<Value>>(connection)?;
    /// assert_eq!(
    ///     Some(json!({"a":{"x":1,"y":9},"b":3,"c":8})),
    ///     result
    /// );
    ///
    /// // Nullable input yields nullable output
    /// let result = diesel::select(json_patch::<Nullable<Json>, Json, _, _>(
    ///     None::<Value>,
    ///     json!({}),
    /// ))
    /// .get_result::<Option<Value>>(connection)?;
    /// assert!(result.is_none());
    ///
    /// #     Ok(())
    /// # }
    /// ```
    #[cfg(feature = "sqlite")]
    fn json_patch<
        T: JsonOrNullableJsonOrJsonbOrNullableJsonb + SingleValue,
        P: JsonOrNullableJsonOrJsonbOrNullableJsonb + SingleValue,
    >(
        target: T,
        patch: P,
    ) -> Nullable<Json>;

    /// Applies an RFC 7396 MergePatch `patch` to the input JSON `target` and
    /// returns the patched JSON value in SQLite's binary JSONB format.
    ///
    /// See [`json_patch`](json_patch()) for details about the MergePatch semantics.
    ///
    /// # Examples
    ///
    /// ```rust
    /// # include!("../../doctest_setup.rs");
    /// #
    /// # fn main() {
    /// #     #[cfg(feature = "serde_json")]
    /// #     run_test().unwrap();
    /// # }
    /// #
    /// # #[cfg(feature = "serde_json")]
    /// # fn run_test() -> QueryResult<()> {
    /// #     use diesel::dsl::jsonb_patch;
    /// #     use serde_json::{json, Value};
    /// #     use diesel::sql_types::{Jsonb, Nullable};
    /// #     let connection = &mut establish_connection();
    /// #     assert_version!(connection, 3, 45, 0);
    ///
    /// let result = diesel::select(jsonb_patch::<Jsonb, Jsonb, _, _>(

Review comment (suggestion):
As far as I can see the return type is only null if one of the inputs is null. 

We need to do something like 


```suggestion
    fn json_patch<
        T: JsonOrNullableJsonOrJsonbOrNullableJsonb + SingleValue,
        P: JsonOrNullableJsonOrJsonbOrNullableJsonb + SingleValue + CombinedNullableValue<T, Json>,
    >(
        target: T,
        patch: P,
    ) -> P::Out
```

This will evaluate to `Nullable<Json>` if one of the types `T` or `P` is nullable and to `Json` if both types are not nullable.

Code after:
    ///     json!( {"a":{"y":9},"c":8} ),
    /// ))
    /// .get_result::<Value>(connection)?;
    /// assert_eq!(
    ///     json!({"a":{"x":1,"y":9},"b":3,"c":8}),
    ///     result
    /// );
    ///
    /// // Nullable input yields nullable output
    /// let result = diesel::select(json_patch::<Nullable<Json>, Json, _, _>(
    ///     None::<Value>,
    ///     json!({}),
    /// ))
    /// .get_result::<Option<Value>>(connection)?;
    /// assert!(result.is_none());
    ///
    /// #     Ok(())
    /// # }
    /// ```
    #[cfg(feature = "sqlite")]
    fn json_patch<
        T: JsonOrNullableJsonOrJsonbOrNullableJsonb + SingleValue,
        P: JsonOrNullableJsonOrJsonbOrNullableJsonb + SingleValue + CombinedNullableValue<T, Json>,
    >(
        target: T,
        patch: P,
    ) -> P::Out;

    /// Applies an RFC 7396 MergePatch `patch` to the input JSON `target` and
    /// returns the patched JSON value in SQLite's binary JSONB format.
    ///
    /// See [`json_patch`](json_patch()) for details about the MergePatch semantics.
    ///
    /// # Examples
    ///
    /// ```rust
    /// # include!("../../doctest_setup.rs");
    /// #
    /// # fn main() {
    /// #     #[cfg(feature = "serde_json")]
    /// #     run_test().unwrap();
    /// # }
    /// #
    /// # #[cfg(feature = "serde_json")]
    /// # fn run_test() -> QueryResult<()> {
    /// #     use diesel::dsl::jsonb_patch;
    /// #     use serde_json::{json, Value};
    /// #     use diesel::sql_types::{Jsonb, Nullable};
    /// #     let connection = &mut establish_connection();
    /// #     assert_version!(connection, 3, 45, 0);
    ///