-
-
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 json expression methods #4324
add support for json expression methods #4324
Conversation
…_not_json_array, is_json_scalar, is_not_json_scalar expression methods
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 the PR!
I was playing with these operators on the shell and noticed that the IS JSON
operator does not support int, boolean, or array. I could only make it work with text type.
If these operands are only supported by text type, I think we should restrict these methods to only diesel text type.
I also notice that SELECT NULL IS JSON SCALLAR
returns NULL
, so I would like some test showing that this case does not break anything.
@guissalustiano , I moved json expression methods under PgTextExpressionMethods as you suggested. When it comes to |
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!
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'm sorry to took so long to add this here, but the nullability handling is still not correct. I've added a more detailed comment in the relevant location explaining what needs to change there. If you need more help to fix this, just let me know. I can also try to change the macro myself, but that won't happen before next week.
/// assert_eq!(res, false); | ||
/// let res = diesel::select(("\"abc\"".into_sql::<Text>().is_json_scalar())).get_result::<bool>(conn)?; | ||
/// assert_eq!(res, true); | ||
/// let res = diesel::select(sql::<Nullable<Text>>("NULL").is_json_scalar().nullable()).get_result::<Option<bool>>(conn)?; |
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'm sorry to bring this up now, but this is an issue. In this case is_json_scalar()
should evaluate to Nullable<Bool>
instead. It's actually a short coming of the postfix_operator!()
macro that I forgot about. The diesel::infix_operator!()
already handles this internally:
diesel/diesel/src/expression/operators.rs
Lines 296 to 330 in 2090344
name = $name:ident, | |
operator = $operator:expr, | |
return_ty = NullableBasedOnArgs ($($return_ty:tt)+), | |
backend_ty_params = $backend_ty_params:tt, | |
backend_ty = $backend_ty:ty, | |
) => { | |
$crate::__diesel_infix_operator!( | |
name = $name, | |
operator = $operator, | |
return_ty = ( | |
$crate::sql_types::is_nullable::MaybeNullable< | |
$crate::sql_types::is_nullable::IsOneNullable< | |
<T as $crate::expression::Expression>::SqlType, | |
<U as $crate::expression::Expression>::SqlType | |
>, | |
$($return_ty)+ | |
> | |
), | |
expression_bounds = ( | |
$crate::sql_types::is_nullable::IsSqlTypeNullable< | |
<T as $crate::expression::Expression>::SqlType | |
>: $crate::sql_types::OneIsNullable< | |
$crate::sql_types::is_nullable::IsSqlTypeNullable< | |
<U as $crate::expression::Expression>::SqlType | |
> | |
>, | |
$crate::sql_types::is_nullable::IsOneNullable< | |
<T as $crate::expression::Expression>::SqlType, | |
<U as $crate::expression::Expression>::SqlType | |
>: $crate::sql_types::MaybeNullableType<$($return_ty)+>, | |
), | |
backend_ty_params = $backend_ty_params, | |
backend_ty = $backend_ty, | |
); | |
}; |
Something like this is also needed for the postfix_operator!()
macro, although:
- We need to make sure that's not the new default, as that would be a breaking chaneg
- It's likely simpler as we just have one argument instead of two.
We likely just need to introduce an explict opt-in branch to this macro that sets the return type to
$crate::sql_types::is_nullable::MaybeNullable<<T as Expression>::SqlType>
after that this test should just compile as
diesel::select(sql::<Nullable<Text>>("NULL").is_json_scalar()).get_result::<Option<bool>>(conn)?;
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 am not an expert when it comes to macros but I am thinking about sth like postfix_operator!(IsJsonScalar, " IS JSON SCALAR", ConditionalNullability Bool, backend: Pg);
to make it backward compatible. Implementations without ConditionalNullability Bool
specified will evaluate to the legacy branch. @weiznich , what do you think ?
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.
That would be a fine solution 👍
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.
@weiznich , I added ConditionalNullability support to postfix_operator. Please let me know if it makes sense.
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 fixing 👍
(I made a minor adjustment to simplify the calculated return type a bit)
This PR adds support for json expression methods mentioned in #4216