diff options
author | Yorick Peterse <yorickpeterse@gmail.com> | 2017-02-21 17:07:02 +0300 |
---|---|---|
committer | Yorick Peterse <yorickpeterse@gmail.com> | 2017-02-21 17:07:02 +0300 |
commit | 79696f5b7aaf260176355026e91af05d40d92d0c (patch) | |
tree | efee41993f5d006e9c5b717af4789576a09f50d4 /lib/gitlab/database | |
parent | 459a97d46812fecc59c973bad356935422c7f60e (diff) |
Hash concurrent foreign key names similar to Rails
This was initially not implemented simply because I forgot about the
size limit of constraint names in PostgreSQL (63 bytes). Using the old
technique we can't add foreign keys for certain tables. For example,
adding a foreign key on
protected_branch_merge_access_levels.protected_branch_id would lead to
the following key name:
fk_protected_branch_merge_access_levels_protected_branches_protected_branch_id
This key is 78 bytes long, thus violating the PostgreSQL size
requirements.
The hashing strategy is copied from Rails' foreign_key_name() method,
which unfortunately is private and subject to change without notice.
Diffstat (limited to 'lib/gitlab/database')
-rw-r--r-- | lib/gitlab/database/migration_helpers.rb | 11 |
1 files changed, 10 insertions, 1 deletions
diff --git a/lib/gitlab/database/migration_helpers.rb b/lib/gitlab/database/migration_helpers.rb index 4800a509b37..fc445ab9483 100644 --- a/lib/gitlab/database/migration_helpers.rb +++ b/lib/gitlab/database/migration_helpers.rb @@ -54,7 +54,7 @@ module Gitlab disable_statement_timeout - key_name = "fk_#{source}_#{target}_#{column}" + key_name = concurrent_foreign_key_name(source, column) # Using NOT VALID allows us to create a key without immediately # validating it. This means we keep the ALTER TABLE lock only for a @@ -74,6 +74,15 @@ module Gitlab execute("ALTER TABLE #{source} VALIDATE CONSTRAINT #{key_name};") end + # Returns the name for a concurrent foreign key. + # + # PostgreSQL constraint names have a limit of 63 bytes. The logic used + # here is based on Rails' foreign_key_name() method, which unfortunately + # is private so we can't rely on it directly. + def concurrent_foreign_key_name(table, column) + "fk_#{Digest::SHA256.hexdigest("#{table}_#{column}_fk").first(10)}" + end + # Long-running migrations may take more than the timeout allowed by # the database. Disable the session's statement timeout to ensure # migrations don't get killed prematurely. (PostgreSQL only) |