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
fix(postgres): do not ignore custom PK constraint names #2931
Conversation
9e99430
to
8ef4752
Compare
Codecov Report
@@ Coverage Diff @@
## master #2931 +/- ##
===========================================
- Coverage 100.00% 99.98% -0.02%
===========================================
Files 193 193
Lines 11783 11800 +17
Branches 2721 2723 +2
===========================================
+ Hits 11783 11798 +15
- Misses 0 2 +2
Continue to review full report at Codecov.
|
210db01
to
9dca2ba
Compare
getDefaultPrimaryName(tableName: string, columns: string[]): string { | ||
return this.namingStrategy.indexName(tableName, columns, 'primary'); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this seems like a wrong default to me, how can you then compare the default implementation with the one from naming strategy, if both ways use the naming strategy?
edit: i see it gets overridden, so not a big deal, but it looks confusing. note that method will need to be unit tested to keep full coverage
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i would say this can be done in much more readable way, now it seems quite confusing to me, please give it another try, or i can take over if you want :]
getDefaultPrimaryName(tableName: string, columns: string[]): string { | ||
const indexName = `${tableName}_pkey`; | ||
if (indexName.length > 64) { | ||
return `${indexName.substr(0, 57 - 'primary'.length)}_${Utils.hash(indexName).substr(0, 5)}_primary`; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i dont think we need to care about this for default primary index name, it will be problematic only if the table name will be too long, which will on its own cause other problems, and i am also quite sure the default way of handling this would produce something else than our custom md5 hash in the pk name
|
||
/* istanbul ignore next */ | ||
if (indexName.length > 64) { | ||
indexName = `${indexName.substr(0, 57 - type.length)}_${Utils.hash(indexName).substr(0, 5)}_${type}`; | ||
return `${indexName.substr(0, 57 - type.length)}_${Utils.hash(indexName).substr(0, 5)}_${type}`; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i dont mind the early return, but the way it was written before made all the branches covered, your changes will result in lower code coverage and i do care about that. if you want to use early return, add more tests that will cover the following branch
@@ -488,14 +488,22 @@ export class SchemaGenerator extends AbstractSchemaGenerator<AbstractSqlDriver> | |||
}); | |||
} | |||
|
|||
private createIndex(table: Knex.CreateTableBuilder, index: Index, createPrimary = false) { | |||
private createIndex(table: Knex.CreateTableBuilder, index: Index, tableDef: DatabaseTable, createPrimary = false, useExplicitPKName = false) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i dont understand why you need useExplicitPKName
parameter (it should always behave like that based on the NS/default pk name from platform), and generally i would expect this method not to change that much
i would very much like to keep the previous code structure as this is much less readable and i can imagine it will have some branches where it wont create the PK. there should be one call to table.primary()
as it was, and it should be always fired if index.primary
is true.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If PK columns is autoincrement
and table.primary()
is fired. knex
generates sql which have explicit PK name.
(I can not 100% sure it's knex
doing)
create table "new_table" ("id" serial, "enum_test" varchar(255) not null);
alter table "new_table" add constraint "new_table_pkey" primary key ("id");
If table.primary()
is not fired. It generates primary key
keyword anyway.
create table "new_table" ("id" serial primary key, "enum_test" varchar(255) not null);
This is the why there are some branches table.primary()
is not fired when index.primary
is true
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have one question.
Could we change existing behavior to have explicit PK name when NS not override and PK column is autoincrement
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If PK columns is autoincrement and table.primary() is fired
It should not be fired, that is the exact reason why we have the createPrimary
parameter
Could we change existing behavior to have explicit PK name when PK column is autoincrement?
Nope, that would affect most of the users in a bad way I'd say. I want the exact opposite, have the names there only when needed, not always.
If table.primary() is not fired. It generates primary key keyword anyway.
That's because the column.primary()
is called for those. As said above, we have the createPrimary
parameter to distinguish.
edit: or maybe not, I need to check the code more deeper, it was working like that before but now I can't find any reference. but knex on its own will definitely not mark things as PK if we dont instruct it that way, so it needs to happen somewhere
edit2: it does work this way, i just confused myself because we dont call col.primary()
, instead we call table.increments()
for those, which implies col.primary()
@@ -466,7 +466,7 @@ export class SchemaGenerator extends AbstractSchemaGenerator<AbstractSqlDriver> | |||
}); | |||
|
|||
for (const index of tableDef.getIndexes()) { | |||
this.createIndex(table, index, !tableDef.getColumns().some(c => c.autoincrement)); | |||
this.createIndex(table, index, tableDef, true); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i dont understand why the createPrimary
is no longer driven by this, i believe it was still valid, and now you just hide it inside the method implementation, making it much more complex
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To check if table.primary()
should be called.
- Have override for NS <- should be called
- Not have override and table has some
autoincrement
<- should not be called - Not have override and table do not have
autoincrement
<- should be called
To handle the above branches in createIndex
. I have changed the createPrimary
code.
Based on the code changes, it feels like you wanted to make all the existing tests pass. That is wrong, the snapshots are not 100% correct, this change should be reflected in them too. One example is that |
Yes, you are right. I have thought that this PR should not impact existing behavior and only add functionality to have custom PK name in postresql. Now that we are allowed to change existing behavior. I think I can make more readable code. |
maybe i should finish this myself, i just checked the code more in depth and it is a bit more complicated, as the current code was doing some workaround to make things work the way they work, and those should be refactored as well, otherwise we cant make this cleaner. will try to spend some time with it and report back to you |
Thanks a lot! |
resolve #2930