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

Support Joins and Using syntax for PostgreSQL Delete Statement (#4591) #4800

Merged

Conversation

OlivierCavadenti
Copy link
Collaborator

@OlivierCavadenti OlivierCavadenti commented Nov 3, 2021

So implicit method, with usual join methods work:

 qb()
    .del()
    .from('users')
    .join('photos', 'photos.id', 'users.id')
    .where({ 'user.email': 'mock@example.com' })

and will generate the query with 'using' and 'where' to work in PostgreSQL.
It will general the same query that explicit form:

 qb()
  .del()
  .from('users')
  .using('photos')
  .whereRaw('photos.id = users.id')
  .where({ 'user.email': 'mock@example.com'})
  • I dont want to go in intrusive and complex implementation (no new kind of joins...) so I just add small using method in querybuilder and make all the specific logic in PG files. Finally I implements both implicit joins conversion and explicit form.
  • I choose to make a specific implement of Delete that dont allow joins in Delete and throw an error when user try to make the joins with Delete statement => "Joins with delete query isn't valid in PostgreSQL, use 'using' with 'where' functions instead." Specific implement of Delete for PostgreSQL that convert joins in 'using' + 'wheres'
  • Fixes pg: incorrect "delete + join" query since 0.95.8 #4591

const withSQL = this.with();
const wheres = this.where();
// Joins in PG with delete it's not valid, we throw an error and ask to use 'using'
if (this.join().length > 0) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

converting joins to using transparently is not feasible?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

You mean use the joins logic by add 'using' joins types with the 'using()' syntax ?
I think about that but with that implementation I cant throw an error here.
Also we have a join with using syntax inside and I quite afraid about some misunderstand.

Copy link
Collaborator

Choose a reason for hiding this comment

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

I'm still on the fence about this, TBH. Considering that many multi-db systems use knex specifically to abstract away db differences, transforming joins to using here would allow them to avoid having some conditional logic. Is it possible to always transform join into using, or you see certain case where that would fail and user would be forced to use using explicitly anyway?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I see the argument. I start on 'using' function because of an argument in the original PR about avoid silent converting operations. But in fact, we always do "silent" operations in Knex, especially with oracle, when converting limit/offset functions...
I will rework it.

Copy link
Collaborator

Choose a reason for hiding this comment

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

I wonder if we should also keep using syntax for those who want to be explicit.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I push with implicit joins to 'using' + 'where's syntax and I also keep the actual using syntax too.

@t1a2l
Copy link

t1a2l commented Nov 4, 2021

@elhigu - are you going to review this?

@t1a2l
Copy link

t1a2l commented Nov 4, 2021

ok i just added the fix to local project.

@kibertoad
Copy link
Collaborator

Would also be helpful to update existing Delete with join tests, so that they would no longer skip PostgreSQL. They also currently miss assertions that only correct data is deleted, which would be great to add too.

@OlivierCavadenti OlivierCavadenti changed the title Support Using syntax for PostgreSQL delete (#4591) Support Joins and Using syntax for PostgreSQL Delete Statement (#4591) Nov 7, 2021
@OlivierCavadenti
Copy link
Collaborator Author

Would also be helpful to update existing Delete with join tests, so that they would no longer skip PostgreSQL. They also currently miss assertions that only correct data is deleted, which would be great to add too.

I push with more integration tests + one unit test (mixed joins + using notation).
By the way I made fixes on querycompiler ('where' value as column value for ex).
I see that my example in this PR + unit test are not good (cannot use id columns with 'where' use 'whereRaw' instead).

Copy link
Collaborator

@kibertoad kibertoad left a comment

Choose a reason for hiding this comment

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

Outstanding work on this one!

@OlivierCavadenti OlivierCavadenti merged commit ffd0c10 into knex:master Nov 7, 2021
@OlivierCavadenti OlivierCavadenti deleted the delete-using-postgres-4591 branch December 20, 2021 22:18
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.

pg: incorrect "delete + join" query since 0.95.8
3 participants