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

Code before:
    /// #     Ok(())
    /// # }
    /// ```
    #[sql_name = "jsonb_set"]
    fn jsonb_set_create_if_missing<
        E: JsonbOrNullableJsonb + SingleValue,
        Arr: TextArrayOrNullableTextArray + CombinedNullableValue<E,Jsonb>
    >(base: E, path: Arr, new_value: E, create_if_missing: Bool) -> Arr::Out;
}

#[cfg(feature = "postgres_backend")]
define_sql_function! {
    /// Returns target with the item designated by path replaced by new_value,
    ///     or with new_value added and the item designated by path does not exist.
    ///
    /// It can't set path in scalar
    ///
    /// All earlier steps in the path must exist, or the target is returned unchanged.
    /// As with the path oriented operators, negative integers that appear in the path count from the end of JSON arrays.
    /// If the last path step is an array index that is out of range,
    ///    the new value is added at the beginning of the array if the index is negative,
    ///     or at the end of the array if it is positive.
    ///
    /// If new_value is not NULL, behaves identically to jsonb_set.
    ///    Otherwise behaves according to the value of null_value_treatment
    ///    which must be one of 'raise_exception', 'use_json_null', 'delete_key', or 'return_target'.
    ///    The default is 'use_json_null'.
    ///
    /// # Example
    ///
    /// ```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_set_lax;
    /// #     use diesel::sql_types::{Jsonb,Array, Json, Nullable, Text};
    /// #     use serde_json::{json,Value};
    /// #     let connection = &mut establish_connection();
    ///
    /// let null_value_treatment : String = "use_json_null".into();
    /// let result = diesel::select(jsonb_set_lax::<Jsonb, Array<Text>, Text, _, _, _, _, _>(
    ///         json!([{"f1":1,"f2":null},2,null,3]),
    ///         vec!["0","f1"],
    ///         json!([2,3,4]),
    ///         true,

Review comment (suggestion):
I would rather prefer having an enum with all allowed variants instead of allowing a text input here.

That would require something like this:

https://github.com/diesel-rs/diesel/blob/9861bcba0f48f64481bf7a312da2bb2d3ea2f208/diesel/src/pg/types/mod.rs#L211-L232

and 

https://github.com/diesel-rs/diesel/blob/9861bcba0f48f64481bf7a312da2bb2d3ea2f208/diesel/src/pg/types/ranges.rs#L276-L289

with the corresponding enum variants.

Afterwards the function signature needs to change so that it accepts only the SQL type (`RangeBoundEnum` in that example) instead of arbitrary text. (See here for an example usage: https://github.com/diesel-rs/diesel/blob/9861bcba0f48f64481bf7a312da2bb2d3ea2f208/diesel/src/pg/expression/functions.rs#L442)

Code after:
    /// # }
    /// ```
    #[sql_name = "jsonb_set"]
    fn jsonb_set_create_if_missing<
        E: JsonbOrNullableJsonb + SingleValue,
        Arr: TextArrayOrNullableTextArray + CombinedNullableValue<E,Jsonb>
    >(base: E, path: Arr, new_value: E, create_if_missing: Bool) -> Arr::Out;
}

#[cfg(feature = "postgres_backend")]
define_sql_function! {
    /// Returns target with the item designated by path replaced by new_value,
    ///     or with new_value added and the item designated by path does not exist.
    ///
    /// It can't set path in scalar
    ///
    /// All earlier steps in the path must exist, or the target is returned unchanged.
    /// As with the path oriented operators, negative integers that appear in the path count from the end of JSON arrays.
    /// If the last path step is an array index that is out of range,
    ///    the new value is added at the beginning of the array if the index is negative,
    ///     or at the end of the array if it is positive.
    ///
    /// If new_value is not NULL, behaves identically to jsonb_set.
    ///    Otherwise behaves according to the value of null_value_treatment
    ///    which must be one of 'raise_exception', 'use_json_null', 'delete_key', or 'return_target'.
    ///    The default is 'use_json_null'.
    ///
    /// # Example
    ///
    /// ```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_set_lax;
    /// #     use diesel::sql_types::{Jsonb,Array,NullValueTreatment, Json, Nullable, Text};
    /// #     use serde_json::{json,Value};
    /// #     let connection = &mut establish_connection();
    ///
    /// let null_value_treatment = NullValueTreatment::UseJsonNull;
    /// let result = diesel::select(jsonb_set_lax::<Jsonb, Array<Text>, _, _, _, _, _>(
    ///         json!([{"f1":1,"f2":null},2,null,3]),
    ///         vec!["0","f1"],
    ///         json!([2,3,4]),
    ///         true,
    ///         null_value_treatment