Skip to content

Implement where clauses on upsert for pg#2479

Merged
weiznich merged 12 commits intodiesel-rs:masterfrom
ropottnik:master
Sep 11, 2020
Merged

Implement where clauses on upsert for pg#2479
weiznich merged 12 commits intodiesel-rs:masterfrom
ropottnik:master

Conversation

@ropottnik
Copy link
Contributor

closes #2430

Hey all! Since this here is my first ever PR written in Rust I'm especially keen on getting feedback for things that someone better at Rust would do totally different.

There are to issues with which I would need expert help anyway:

  • I have explicitly imported the DecoratableTarget trait inside diesel_tests/tests/debug/mod.rs because I failed exporting it properly to be part of a use diesel::**statement. You can see my failed attempts indiesel/src/query_builder/mod.rsand others. If you could help me get these exports right I could remove that explicituse diesel::upsert::DecoratableTarget;indiesel_tests/tests/debug/mod.rs`
  • I have only tested that the debug string will show the expected statement "ON CONFLICT (...) WHERE ...". What other test scenarios would you like to have me cover in order to make sure it works.

@weiznich weiznich requested a review from a team August 10, 2020 08:41
@weiznich
Copy link
Member

If nobody from @diesel-rs/reviewers has time I will do a review after I'm back from holiday in sepember.

@ELD
Copy link

ELD commented Aug 12, 2020

@weiznich I should be able to leave a review on this in the next day or two.

@pksunkara
Copy link
Member

This was a little bit complex for me. I don't know the diesel code that much yet.

@ropottnik
Copy link
Contributor Author

@ELD is there any chance you can give me feedback on my PR in the next 1 or 2 days?

@ELD
Copy link

ELD commented Aug 19, 2020

@ropottnik Yes, absolutely. It's on my todo list for today. Sorry for taking so long to get back to this.

Copy link

@ELD ELD left a comment

Choose a reason for hiding this comment

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

I took a quick look at this tonight. Again, sorry for taking so long to get to this. I’ll follow up in the morning and consider it a bit more closely. On the face of it, it looks good, though.

I should have answered your question regarding the prelude export for the DecoratableTarget trait. Hopefully that helps!

I’ll also give some thought to other test cases we may want for this.

Overall, it looks good! :)

mod sql_query;
mod update_statement;
pub(crate) mod upsert;
pub use upsert::on_conflict_target_decorations::DecoratableTarget;
Copy link

Choose a reason for hiding this comment

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

Minor nit:

It would be good to match the style of other pub use statements and do it like this:

pub use self::upset::on_conflict_target_decorations::DecoratableTarget;

Also would be good to be moved down to the other use statements, as well.

@@ -1,4 +1,5 @@
use crate::schema::TestBackend;
use diesel::upsert::DecoratableTarget;
Copy link

Choose a reason for hiding this comment

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

To resolve this to make it so use diesel::* also pulls in the DecoratableTarget, you should add the trait as a public reexport in lib.rs of Diesel in the inline prelude module.

See this for more details: https://github.com/diesel-rs/diesel/blob/master/diesel/src/lib.rs#L308

Copy link
Contributor Author

Choose a reason for hiding this comment

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

aaah, makes sense, thanks!

{
fn walk_ast(&self, mut out: AstPass<DB>) -> QueryResult<()> {
self.target.walk_ast(out.reborrow())?;
// out.push_sql(" ");
Copy link

Choose a reason for hiding this comment

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

Is this a debug statement left in that is no longer effectual?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

oh yeah, that's just a remnant. I'll remove it.

@ropottnik
Copy link
Contributor Author

@ELD I think I just figured out myself why I would get this nullable error. I need to have the same bounds for the predicate as in the FilterDSL which is Predicate<Table>. In my case it is Expression<SqlType=Bool>. I need to establish a connection to the <Table> in my construction which is missing right now.

Could it be that something there changed rather recently? Because when I submitted the PR, my test passed. Now all of a sudden I get these Nullable type mismatch compiler errors.

@weiznich
Copy link
Member

@ropottnik That's likely caused by #2182

@ropottnik
Copy link
Contributor Author

@ELD @weiznich thanks for your comments.

I could fix the test that I had added previously.

Also I was able to simplify the DecoratableConflictTarget with af3fedb and d9f9fc6.

I have also added one more test that checks repeated filter_target calls which should add AND fragments to the WHERE clause of the conflict target.

Could you have a look again?

@ELD
Copy link

ELD commented Aug 24, 2020

@ropottnik I'll give this another look this afternoon!

@ropottnik
Copy link
Contributor Author

@ELD @weiznich
could you either let me know if or what I can do to improve my solution or merge my PR in?
Thanks

@ELD
Copy link

ELD commented Aug 26, 2020 via email

Copy link

@ELD ELD left a comment

Choose a reason for hiding this comment

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

From my perspective, this PR looks good. I'll defer to @weiznich for a final sign-off when he has the chance, but it looks like it's in a good state. The additional test is good, too. Nice work!

@ropottnik
Copy link
Contributor Author

Thanks!


/// Interface to add information to conflict targets.
/// Designed to be open for further additions to conflict targets like constraints
pub trait DecoratableTarget<P> {
Copy link
Member

Choose a reason for hiding this comment

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

Is there any reason why this needs to be a separate trait and we cannot reuse FilterDsl here?

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 review @weiznich!

My initial thought also was to use FilterDsl. However, I created a new trait for 2 reasons

  1. For me it is semantically different to add a WHERE clause on a SELECT or UPDATE statement which filters the statement as a whole. In contrast the WHERE clause added to a conflict target specifies the on conflict policy. These statements are usually chained together so to me it made sense to indicate that the WHERE clause groups with the conflict target.
  2. I designed the DecoratableTarget such that it easily allows for further specification of the on conflict policy such as adding constraint names as indicated in the PostgreSQL docs on insert.

does that make sense to you?

Copy link
Member

Choose a reason for hiding this comment

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

That sounds reasonable 👍

@sumeetattree
Copy link

@ropottnik Can we backport this into 1.4.x? Do you mind if I use this PR as a base to open a new PR? @weiznich is this something you would be interested in backporting into 1.4.x? Were there any blockers preventing this to go back into 1.4.x release?

@weiznich
Copy link
Member

@sumeetattree We do not accept backports of new features to old releases. In addition we also do not accept any backports to the 1.4.x release anymore as we do not have the capacity to maintain two major diesel versions at the same time. Please update to the 2.0 release to get access to the latest features.

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.

Feature request: support where clause for upsert

5 participants