-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
Add support for postgre jsonb_set_lax #4396
Conversation
There was a problem hiding this 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. The definition looks ok, but I would like to make the invariant for the null_value_treatment
parameter a bit more robust by only accepting enum values with any of the allowed values there. I've left more detailed instructions for this a comment on the code itself. If you need help implementing that please let me know.
/// 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'. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would rather prefer having an enum with all allowed variants instead of allowing a text input here.
That would require something like this:
diesel/diesel/src/pg/types/mod.rs
Lines 211 to 232 in 9861bcb
/// This is a wrapper for [`RangeBound`] to represent range bounds: '[]', '(]', '[)', '()', | |
/// used in functions int4range, int8range, numrange, tsrange, tstzrange, daterange. | |
#[derive(Debug, Clone, Copy, QueryId, SqlType)] | |
#[cfg(feature = "postgres_backend")] | |
#[diesel(postgres_type(name = "text"))] | |
pub struct RangeBoundEnum; | |
/// Represent postgres range bounds: '[]', '(]', '[)', '()', | |
/// used in functions int4range, int8range, numrange, tsrange, tstzrange, daterange. | |
#[derive(Debug, Clone, Copy, diesel_derives::AsExpression)] | |
#[diesel(sql_type = RangeBoundEnum)] | |
#[allow(clippy::enum_variant_names)] | |
pub enum RangeBound { | |
/// postgres '[]' | |
LowerBoundInclusiveUpperBoundInclusive, | |
/// postgres '[)' | |
LowerBoundInclusiveUpperBoundExclusive, | |
/// postgres '(]' | |
LowerBoundExclusiveUpperBoundInclusive, | |
/// postgres '()' | |
LowerBoundExclusiveUpperBoundExclusive, | |
} |
and
diesel/diesel/src/pg/types/ranges.rs
Lines 276 to 289 in 9861bcb
#[cfg(feature = "postgres_backend")] | |
impl ToSql<RangeBoundEnum, Pg> for RangeBound { | |
fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, Pg>) -> serialize::Result { | |
let literal = match self { | |
Self::LowerBoundInclusiveUpperBoundInclusive => "[]", | |
Self::LowerBoundInclusiveUpperBoundExclusive => "[)", | |
Self::LowerBoundExclusiveUpperBoundInclusive => "(]", | |
Self::LowerBoundExclusiveUpperBoundExclusive => "()", | |
}; | |
out.write_all(literal.as_bytes()) | |
.map(|_| IsNull::No) | |
.map_err(|e| Box::new(e) as Box<dyn Error + Send + Sync>) | |
} | |
} |
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:
diesel/diesel/src/pg/expression/functions.rs
Line 442 in 9861bcb
fn int4range(lower: Nullable<Integer>, upper: Nullable<Integer>, bound: RangeBoundEnum) -> Int4range; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for your kind instructions.
I impl to_sql in a new mod called json_function_enum, do you think it's ok?
I'm ready to make more changes if you think it's not fit to make a new mod for it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No it's good that way, thanks for implementing this change ❤️
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good now, thanks for the fast update 👍
#4216
Though create_if_missing and null_value_treatment is optional, the case without them is already supported in jsonb_set and jsonb_set_create_if_missing. So I just do not treat them as optional field here. Do you think it's ok?