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 WHERE clauses to "upsert" queries #4148

Merged
merged 14 commits into from Dec 9, 2020

Conversation

markdboyd
Copy link
Contributor

@markdboyd markdboyd commented Dec 7, 2020

This is a follow-up to #3763, which adds support for WHERE clauses to "upsert" queries for the DB engines that support this functionality.

Based on my research on the DB engines that support "upsert" queries, it seems like PostgreSQL and SQLite support WHERE clauses for them, but MySQL does not:

https://www.postgresql.org/docs/10/sql-insert.html
https://sqlite.org/lang_upsert.html
https://dev.mysql.com/doc/refman/8.0/en/insert-on-duplicate.html

To do:

Closes #4145

);
});
} catch (err) {
if (/oracle|mssql/i.test(knex.client.driverName)) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Skipping test altogether same as is done for redshift probably would be more transparent in test results log.

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 don't fully understand the test setup - but it seems like the difference between redshift and oracle/mssql is that for oracle/mssql we expect an error to be thrown, but not redshift? Should I preserve that distinction or just add mssql/oracle to the skip?

Copy link
Collaborator

Choose a reason for hiding this comment

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

TBH, I think we don't even run redshift in CI, so feel free to just keep ignoring it.
BTW, shouldn't MySQL also be included in error assertion?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ah yeah. Added MySQL to have an error assertion:

90cba49

@@ -1465,6 +1465,110 @@ module.exports = function (knex) {
expect(rows[0].name).to.equal('AFTER');
});

it('conditionally updates rows when inserting a duplicate key to unique column and merge with where clause matching row(s) is specified', async function () {
if (/redshift/i.test(knex.client.driverName)) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

shouldn't mysql be also skipped if you are saying it is not supported?

@kibertoad
Copy link
Collaborator

kibertoad commented Dec 8, 2020

Since you are still planning to add support for SQLite, that will resolve one of the currently failing tests. Could you please add the sanity check for MySQL, which would throw an error if someone tries to use it with WHERE clause, and adjust assertion accordingly?

@markdboyd
Copy link
Contributor Author

@kibertoad I think I have addressed your feedback, minus one question I had about the integration tests

if (merge) {
sql += this._merge(merge.updates, insert);
const wheres = this.where();
if (wheres) {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

It feels like there might be a better way to check whether where is called after a merge statement for MySQL, but I could not figure out what it is

@@ -1465,6 +1465,130 @@ module.exports = function (knex) {
expect(rows[0].name).to.equal('AFTER');
});

it('conditionally updates rows when inserting a duplicate key to unique column and merge with where clause matching row(s) is specified', async function () {
if (/redshift|mysql/i.test(knex.client.driverName)) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

since you are asserting the error now, probably no longer you need to skip it

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sorry about that. Fixed: 80f366d

@kibertoad
Copy link
Collaborator

This can be merged after documentation is added to https://github.com/knex/documentation

@markdboyd
Copy link
Contributor Author

@kibertoad OK, I have created a documentation PR: knex/documentation#300

@kibertoad
Copy link
Collaborator

Thanks a lot!

@kibertoad kibertoad merged commit 76c131e into knex:master Dec 9, 2020
@markdboyd markdboyd deleted the add-upsert-where-support branch December 9, 2020 15:53
@kibertoad
Copy link
Collaborator

Released in 0.21.13

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.

Add support for WHERE clause to upsert
2 participants