style(db): rename constraint names to follow sql style guide (#2973)
* programatically rename unique and foreign key constraints to enforce 'tablename_uq' and 'reftable_fkey' patterns * manually rename unique constraints for names over 63 characters * update changed constraint names in db update testcases
This commit is contained in:
1 parent
b974063a52
commit
b806297afe
7 files changed
+116
-3
No files matched your search
@@ -88,6 +88,7 @@ begin;
|
||||
-- is 68 characters.
|
||||
--
|
||||
-- https://www.postgresql.org/docs/current/limits.html
|
||||
-- Constraint renamed in 67/01_rename_constraints.up.sql
|
||||
constraint credential_static_username_password_store_id_public_id_uq
|
||||
unique(store_id, public_id)
|
||||
);
|
||||
|
||||
@@ -63,6 +63,7 @@ begin;
|
||||
-- is 67 characters.
|
||||
--
|
||||
-- https://www.postgresql.org/docs/current/limits.html
|
||||
-- Constraint renamed in 67/01_rename_constraints.up.sql
|
||||
constraint credential_static_ssh_private_key_store_id_public_id_uq
|
||||
unique(store_id, public_id)
|
||||
);
|
||||
|
||||
@@ -0,0 +1,108 @@
|
||||
-- Copyright (c) HashiCorp, Inc.
|
||||
-- SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
begin;
|
||||
|
||||
-- procedurally rename unique constraints to follow style guide `tablename_col1_colx_uq`
|
||||
-- if constraint name format is under 63 characters
|
||||
do $$
|
||||
declare
|
||||
const record;
|
||||
i int;
|
||||
begin
|
||||
for const in
|
||||
select pc.conname as constraint_name,
|
||||
pgc.relname as table_name,
|
||||
pgc.relname || '_' || (
|
||||
select string_agg(attname, '_')
|
||||
from (
|
||||
select pa.attname
|
||||
from pg_catalog.pg_attribute pa
|
||||
where pa.attrelid = pc.conrelid
|
||||
and pa.attnum = any(pc.conkey)
|
||||
order by pa.attname asc
|
||||
) as attname
|
||||
) || '_uq' as new_name,
|
||||
pc.conrelid as table_num,
|
||||
pc.conkey as attr_keys,
|
||||
regexp_replace(regexp_replace(pc.conname, '^' || pgc.relname || '_', ''), 'uq$', '') as attrs_concat
|
||||
from pg_catalog.pg_constraint pc
|
||||
join pg_catalog.pg_class pgc on pc.conrelid = pgc.oid
|
||||
where pgc.relname not like 'pg_%'
|
||||
and contype = 'u'
|
||||
order by pgc.relname, pc.conname
|
||||
loop foreach i in array const.attr_keys
|
||||
loop const.attrs_concat := regexp_replace(
|
||||
const.attrs_concat,
|
||||
concat((
|
||||
select pa.attname
|
||||
from pg_catalog.pg_attribute pa
|
||||
where pa.attnum = i
|
||||
and pa.attrelid = const.table_num
|
||||
), '_'), '');
|
||||
end loop;
|
||||
if length(const.attrs_concat) > 0 and length(const.new_name) <= 63
|
||||
then
|
||||
execute format('alter table %I rename constraint %I to %I', const.table_name, const.constraint_name, const.new_name);
|
||||
end if;
|
||||
end loop;
|
||||
end;
|
||||
$$ language plpgsql;
|
||||
|
||||
-- manually rename unique constraints to follow style guide if constraint name format exceeds 63 characters
|
||||
alter table auth_password_argon2_conf rename constraint auth_password_argon2_conf_password_method_id_iterations_mem_key
|
||||
to auth_password_argon2_conf_iters_thrds_mem_pm_id_key_salt_len_uq;
|
||||
alter table auth_password_credential rename constraint auth_password_credential_password_method_id_password_conf_i_key
|
||||
to auth_password_credential_password_method_conf_account_ids_uq;
|
||||
-- Renames credential from 33/01_static_credential.up.sql
|
||||
alter table credential_static_username_password_credential rename constraint credential_static_username_password_store_id_public_id_uq
|
||||
to credential_static_username_password_credential_store_pub_ids_uq;
|
||||
-- Renames credential from 39/01_static_ssh_private_key_creds.up.sql
|
||||
alter table credential_static_ssh_private_key_credential rename constraint credential_static_ssh_private_key_store_id_public_id_uq
|
||||
to credential_static_ssh_private_key_credential_store_pub_ids_uq;
|
||||
|
||||
-- procedurally rename foreign key constraints to follow style guide 'reftable_fkey'
|
||||
-- if constraint name format is under 63 characters
|
||||
do $$
|
||||
declare
|
||||
const record;
|
||||
i int;
|
||||
begin
|
||||
for const in
|
||||
select pc.conname as constraint_name,
|
||||
pgc.relname as table_name,
|
||||
pgc.relname || '_' as new_name,
|
||||
pc.conrelid as conrelid,
|
||||
pc.conkey as conkey,
|
||||
pgc2.relname as con_table
|
||||
from pg_catalog.pg_constraint pc
|
||||
join pg_catalog.pg_class pgc on pc.confrelid = pgc.oid
|
||||
join pg_catalog.pg_class pgc2 on pc.conrelid = pgc2.oid
|
||||
where pgc.relname not like 'pg_%'
|
||||
and contype = 'f'
|
||||
and (pc.conname !~ ('^' || pgc.relname || '_')
|
||||
or pc.conname !~ 'fkey[1]?$')
|
||||
order by pgc.relname, pc.conname
|
||||
loop
|
||||
i = (
|
||||
select max(x)
|
||||
from unnest(const.conkey) as x
|
||||
);
|
||||
const.new_name = const.new_name || (
|
||||
select pa.attname
|
||||
from pg_catalog.pg_attribute pa
|
||||
where const.conrelid = pa.attrelid
|
||||
and pa.attnum = i
|
||||
) || '_fkey';
|
||||
if length(const.new_name) <= 63
|
||||
then
|
||||
begin
|
||||
execute format('alter table if exists %I rename constraint %I to %I', const.con_table, const.constraint_name, const.new_name);
|
||||
exception when others then
|
||||
end;
|
||||
end if;
|
||||
end loop;
|
||||
end;
|
||||
$$ language plpgsql;
|
||||
|
||||
commit;
|
||||
@@ -282,7 +282,7 @@ func Test_GroupUpdate(t *testing.T) {
|
||||
},
|
||||
wantErr: true,
|
||||
wantDup: true,
|
||||
wantErrMsg: `db.Update: duplicate key value violates unique constraint "iam_group_name_scope_id_key": unique constraint violation: integrity violation: error #1002`,
|
||||
wantErrMsg: `db.Update: duplicate key value violates unique constraint "iam_group_name_scope_id_uq": unique constraint violation: integrity violation: error #1002`,
|
||||
},
|
||||
{
|
||||
name: "set description null",
|
||||
|
||||
@@ -287,7 +287,7 @@ func Test_RoleUpdate(t *testing.T) {
|
||||
},
|
||||
wantErr: true,
|
||||
wantDup: true,
|
||||
wantErrMsg: `db.Update: duplicate key value violates unique constraint "iam_role_name_scope_id_key": unique constraint violation: integrity violation: error #1002`,
|
||||
wantErrMsg: `db.Update: duplicate key value violates unique constraint "iam_role_name_scope_id_uq": unique constraint violation: integrity violation: error #1002`,
|
||||
},
|
||||
{
|
||||
name: "set description null",
|
||||
|
||||
@@ -205,7 +205,7 @@ func Test_UserUpdate(t *testing.T) {
|
||||
},
|
||||
wantErr: true,
|
||||
wantDup: true,
|
||||
wantErrMsg: `db.Update: duplicate key value violates unique constraint "iam_user_name_scope_id_key": unique constraint violation: integrity violation: error #1002`,
|
||||
wantErrMsg: `db.Update: duplicate key value violates unique constraint "iam_user_name_scope_id_uq": unique constraint violation: integrity violation: error #1002`,
|
||||
},
|
||||
{
|
||||
name: "modified-scope",
|
||||
|
||||
@@ -66,6 +66,9 @@ For `create table` statements:
|
||||
- The naming pattern for unique constraints is `tablename_col1_colx_uq` where
|
||||
`tablename` is the name of the table and `col1_colx` is the name of each
|
||||
column in the unique constraint.
|
||||
- The naming pattern for unique constraint names which would be over 63 characters
|
||||
in length is to prioritize keeping the full 'tablename_uq' pattern intact and
|
||||
abbreviate the names of the columns.
|
||||
|
||||
### Functions
|
||||
|
||||
|
||||
Reference in new issue
Block a user