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

Allow table names with forUpdate/forShare (tgriesser/knex#2834) #2835

Merged
merged 5 commits into from Oct 4, 2018
Merged

Allow table names with forUpdate/forShare (tgriesser/knex#2834) #2835

merged 5 commits into from Oct 4, 2018

Conversation

sgoll
Copy link
Contributor

@sgoll sgoll commented Oct 2, 2018

This implements optional table names to select locks that get applied in SELECT … FOR UPDATE and SELECT … FOR SHARE queries for PostgreSQL dialect. See #2834 for details and rationale.

@@ -67,12 +67,35 @@ assign(QueryCompiler_PG.prototype, {
return value ? ` returning ${this.formatter.columnize(value)}` : '';
},

Copy link
Collaborator

Choose a reason for hiding this comment

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

How difficult would it be to also implement this functionality for at least MySQL?

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 see what you mean by the code fragment. If you mean the table names for locks, I am not sure if that is possible with MySQL at all, however I am not too familiar with that.

Maybe someone else can comment on that?

Copy link
Collaborator

Choose a reason for hiding this comment

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

I mean not code fragment per se but the new functionality in general.

MySQL also has SELECT FOR UPDATE functionality:
https://dev.mysql.com/doc/refman/5.7/en/select.html

Copy link
Contributor Author

Choose a reason for hiding this comment

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

MySQL has support for SELECT … FOR UPDATE (which is already supported by Knex) but it does not seem to have support for specifying which tables to lock and always locks rows in all tables involved in the SELECT query.

for (let i = 0; i < tables.length; i++) {
let tableName = tables[i];

if (tableName && schemaName) tableName = `${schemaName}.${tableName}`;
Copy link
Collaborator

Choose a reason for hiding this comment

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

It is typically recommended to wrap then clause in {} always.

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 copied that fragment verbatim from src/query/compiler.js, definition of property tableName (at the end of the file). Do you think both should be adjusted to conform to current code styles?

Copy link
Collaborator

Choose a reason for hiding this comment

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

There is plenty of sub-optimal existing code :). Personally yeah, I think that would make sense.

const sql = [];

for (let i = 0; i < tables.length; i++) {
let tableName = tables[i];
Copy link
Collaborator

@kibertoad kibertoad Oct 2, 2018

Choose a reason for hiding this comment

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

this probably could be simplified by using ternary operator

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 am curious. How would that work?

Copy link
Collaborator

Choose a reason for hiding this comment

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

One a second look, it's a bit more complicated than that, but I think that this is still simpler:

let tableName = tables[i];
if (!tableName) {
continue;
}
if (schemaName) {
tableName = `${schemaName}.${tableName}`;
}
sql.push(this.formatter.wrap(tableName));

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 simplified the code as suggested. I did not touch the other code fragment, however, that seems outside the scope of this pull request and should be handled in a separate issue, IMHO.

@@ -6023,6 +6023,34 @@ describe('QueryBuilder', function() {
);
});

Copy link
Collaborator

Choose a reason for hiding this comment

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

also needs integration test

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 went ahead and created an integration test that uses two tables, locking only rows from one of them.

Copy link
Member

Choose a reason for hiding this comment

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

@kibertoad In the future version of knex I'm working on, we're going to move away from requiring as many integration tests outside of basic connection management stuff. It's kind of silly to be testing the database functionality, that's outside of the scope of knex.

Copy link
Member

@elhigu elhigu Oct 8, 2018

Choose a reason for hiding this comment

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

@tgriesser problem of not having integration tests is that no one ever tests that given queries are actually doing what they are supposed to do. There has been many bugs because of that. So integration tests are not testing that DB works correctly, but it makes sure that created query does what it is supposed to do and keep on doing the correct thing in future, when someone decides to change the query.

@tgriesser
Copy link
Member

Cool, can you just add a note in the CHANGELOG.md and I'll merge this.

@sgoll
Copy link
Contributor Author

sgoll commented Oct 3, 2018

@tgriesser I added a note to CHANGELOG.md. Thanks for merging this so quickly.

@tgriesser tgriesser merged commit 1c782cf into knex:master Oct 4, 2018
@elhigu
Copy link
Member

elhigu commented Oct 8, 2018

I would have preferred of throwing an error instead of silent ignore, if one tries to pass table names with dialects which doesn't support it.

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.

None yet

4 participants