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

Add support for postgre jsonb_set_lax #4396

Merged
merged 3 commits into from
Dec 20, 2024

Conversation

accestfromim
Copy link
Contributor

#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?

@weiznich weiznich requested a review from a team December 18, 2024 14:56
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 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.

Comment on lines +2596 to +2599
/// 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'.
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 prefer having an enum with all allowed variants instead of allowing a text input here.

That would require something like this:

/// 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

#[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:

fn int4range(lower: Nullable<Integer>, upper: Nullable<Integer>, bound: RangeBoundEnum) -> Int4range;
)

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 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.

Copy link
Member

@weiznich weiznich Dec 20, 2024

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 ❤️

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.

Looks good now, thanks for the fast update 👍

@weiznich weiznich added this pull request to the merge queue Dec 20, 2024
Merged via the queue into diesel-rs:master with commit c2c521d Dec 20, 2024
48 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