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 the row_to_json Method for diesel postgres #4303

Merged
merged 4 commits into from
Oct 25, 2024

Conversation

PratikFandade
Copy link
Contributor

@PratikFandade PratikFandade commented Oct 10, 2024

Adding the support as specified in #4216

Not sure if everything correct, still new to rust, let me know if you need any other changes.

@PratikFandade PratikFandade changed the title Add the row_to_json behavior for diesel postgres Add the row_to_json Method for diesel postgres Oct 10, 2024
@weiznich weiznich requested a review from a team October 11, 2024 06:55
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 working on this.

I fear I have bad news: The function seems to be impossible to implement with the current diesel type setup. Sorry for that :(

Comment on lines 3761 to 3764
impl RecordOrNullableRecord for Record<Text> {}
impl RecordOrNullableRecord for Record<Nullable<Text>> {}
impl RecordOrNullableRecord for Nullable<Record<Text>> {}
impl RecordOrNullableRecord for Nullable<Record<Nullable<Text>>> {}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Record is a somewhat especial type, in so far that it always accepts a tuple as generic argument. So something like Record<(Integer, Text)> or Record<(Text, Date, Integer)>.

The right variant here would be to write something like impl<T> RecordOrNullableRecord for Record<T> {} and impl<T> RecordOrNullableRecord for Nullable<Record<T>> {}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @weiznich , I'll make these changes

/// # }
/// ```
#[sql_name = "jsonb_object"]
fn row_to_json<R: RecordOrNullableRecord + SingleValue + CombinedNullableValue<Record<Text>, Jsonb>>(record: R) -> R::Out;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I fear this function is somewhat problematic to implement with the current diesel types setup. It doesn't accept anonymous record types (as represented by the diesel Record type), but only rows with names. The later is something that's not yet expressible with diesels type setup.

Given that I suppose this won't work in that way :(

(I also do not have any real suggestion how to make it easily work)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll modify the function as pointed by @meeshal to make it correct

@@ -52,7 +52,8 @@ table! {
multirange -> Multirange<Integer>,
timestamptz -> Timestamptz,
name -> Text,
text_array -> Array<Text>
text_array -> Array<Text>,
record -> Record,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We would need to define the record type here as Record<(Integer, Text)> or something like that to fix the compiler error.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, I'll make the changes

Comment on lines 3754 to 3648
#[diagnostic::on_unimplemented(
message = "`{Self}` is neither `Record<Text>`, `Record<Nullable<Text>>`,\
`Nullable<Record<Text>>` nor `diesel::sql_types::Nullable<Record<Nullable<Text>>>`",
note = "try to provide an expression that produces one of the expected sql types"
)]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The reference to Text fragments here is outdated

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Opps! My bad, guess I missed to unstash some changes, I'll fix this.

/// # let connection = &mut establish_connection();
///
/// // Example SQL query selecting a custom record type
/// let query = diesel::select(sql::<Record<(Text, Integer)>>("ROW('John', 30)::record"));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Imho, row_to_json should be used here instead of sql so, the returned value could be casted to json right away.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm so sorry, will fix this test

/// # }
/// ```
#[sql_name = "row_to_json"]
fn row_to_json<R: RecordOrNullableRecord + SingleValue + MaybeNullableValue<Json>>(record: R) -> R::Out;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SingleValue seems to be redundant as it is already implemented by MaybeNullableValue.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the insight will make these changes

@weiznich weiznich added this pull request to the merge queue Oct 25, 2024
Merged via the queue into diesel-rs:master with commit 569c684 Oct 25, 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.

4 participants