From f0f7e635a0db934b379bd27a279da8b868ef6a2c Mon Sep 17 00:00:00 2001 From: Johan Brandhorst-Satzkorn Date: Fri, 24 Nov 2023 17:22:43 -0800 Subject: [PATCH] internal/db: add target schema for pagination design The new design uses the base table for querying, so the base table needs to have both create_time and update_time. In this commit we add the update_time to the target base table. We also add a number of new indexes to help with looking up targets. --- .../79/02_target_base_table_updates.up.sql | 45 +++++++++++++++++++ .../postgres/79/02_update_time_indexes.up.sql | 39 ---------------- internal/db/sqltest/Makefile | 4 +- .../db/sqltest/tests/index/update_time.sql | 27 ----------- .../db/sqltest/tests/pagination/target.sql | 26 +++++++++++ 5 files changed, 73 insertions(+), 68 deletions(-) create mode 100644 internal/db/schema/migrations/oss/postgres/79/02_target_base_table_updates.up.sql delete mode 100644 internal/db/schema/migrations/oss/postgres/79/02_update_time_indexes.up.sql delete mode 100644 internal/db/sqltest/tests/index/update_time.sql create mode 100644 internal/db/sqltest/tests/pagination/target.sql diff --git a/internal/db/schema/migrations/oss/postgres/79/02_target_base_table_updates.up.sql b/internal/db/schema/migrations/oss/postgres/79/02_target_base_table_updates.up.sql new file mode 100644 index 0000000000..30f63b6eb9 --- /dev/null +++ b/internal/db/schema/migrations/oss/postgres/79/02_target_base_table_updates.up.sql @@ -0,0 +1,45 @@ +-- Copyright (c) HashiCorp, Inc. +-- SPDX-License-Identifier: BUSL-1.1 + +begin; + + -- Add update_time to base target table. + -- It already has the create time. + alter table target add column update_time wt_timestamp; + + -- Update rows with current values + update target + set update_time = target_tcp.update_time + from target as t + left join target_tcp on t.public_id = target_tcp.public_id; + update target + set update_time = target_ssh.update_time + from target as t + left join target_ssh on t.public_id = target_ssh.public_id; + + -- Add trigger to update the new column on every subtype update. + create function update_target_table_update_time() returns trigger + as $$ + begin + update target set update_time = now() where public_id = new.public_id; + return new; + end; + $$ language plpgsql; + comment on function update_target_table_update_time() is + 'update_target_table_update_time is used to automatically update the update_time ' + 'of the base table whenever one of the subtype tables are updated'; + + create trigger update_target_table_update_time before update on target_tcp + for each row execute procedure update_target_table_update_time(); + create trigger update_target_table_update_time before update on target_ssh + for each row execute procedure update_target_table_update_time(); + + -- Add new indexes for the update time queries. + create index target_create_time_public_id_idx + on target (create_time desc, public_id asc); + create index target_update_time_public_id_idx + on target (update_time desc, public_id asc); + + analyze target; + +commit; diff --git a/internal/db/schema/migrations/oss/postgres/79/02_update_time_indexes.up.sql b/internal/db/schema/migrations/oss/postgres/79/02_update_time_indexes.up.sql deleted file mode 100644 index 7c5762820c..0000000000 --- a/internal/db/schema/migrations/oss/postgres/79/02_update_time_indexes.up.sql +++ /dev/null @@ -1,39 +0,0 @@ --- Copyright (c) HashiCorp, Inc. --- SPDX-License-Identifier: BUSL-1.1 - -begin; - - create index auth_ldap_account_update_time_idx on auth_ldap_account (update_time); - create index auth_ldap_managed_group_update_time_idx on auth_ldap_managed_group (update_time); - create index auth_ldap_method_update_time_idx on auth_ldap_method (update_time); - create index auth_oidc_account_update_time_idx on auth_oidc_account (update_time); - create index auth_oidc_managed_group_update_time_idx on auth_oidc_managed_group (update_time); - create index auth_oidc_method_update_time_idx on auth_oidc_method (update_time); - create index auth_password_account_update_time_idx on auth_password_account (update_time); - create index auth_password_method_update_time_idx on auth_password_method (update_time); - create index auth_token_update_time_idx on auth_token (update_time); - create index credential_static_json_credential_update_time_idx on credential_static_json_credential (update_time); - create index credential_static_ssh_private_key_credential_update_time_idx on credential_static_ssh_private_key_credential (update_time); - create index credential_static_store_update_time_idx on credential_static_store (update_time); - create index credential_static_username_password_credential_update_time_idx on credential_static_username_password_credential (update_time); - create index credential_vault_library_update_time_idx on credential_vault_library (update_time); - create index credential_vault_ssh_cert_library_update_time_idx on credential_vault_ssh_cert_library (update_time); - create index credential_vault_store_update_time_idx on credential_vault_store (update_time); - create index host_plugin_catalog_update_time_idx on host_plugin_catalog (update_time); - create index host_plugin_host_update_time_idx on host_plugin_host (update_time); - create index host_plugin_set_update_time_idx on host_plugin_set (update_time); - create index iam_group_update_time_idx on iam_group (update_time); - create index iam_role_update_time_idx on iam_role (update_time); - create index iam_scope_update_time_idx on iam_scope (update_time); - create index iam_user_update_time_idx on iam_user (update_time); - create index recording_session_update_time_idx on recording_session (update_time); - create index server_worker_update_time_idx on server_worker (update_time); - create index session_update_time_idx on session (update_time); - create index static_host_catalog_update_time_idx on static_host_catalog (update_time); - create index static_host_update_time_idx on static_host (update_time); - create index static_host_set_update_time_idx on static_host_set (update_time); - create index storage_plugin_storage_bucket_update_time_idx on storage_plugin_storage_bucket (update_time); - create index target_ssh_update_time_idx on target_ssh (update_time); - create index target_tcp_update_time_idx on target_tcp (update_time); - -commit; diff --git a/internal/db/sqltest/Makefile b/internal/db/sqltest/Makefile index 2dc6268d00..c3d8b70d7b 100644 --- a/internal/db/sqltest/Makefile +++ b/internal/db/sqltest/Makefile @@ -34,8 +34,8 @@ TESTS ?= tests/setup/*.sql \ tests/history/*.sql \ tests/recording/*.sql \ tests/auth/*/*.sql \ - tests/purge/*sql \ - tests/index/*sql + tests/purge/*.sql \ + tests/pagination/*.sql POSTGRES_DOCKER_IMAGE_BASE ?= postgres diff --git a/internal/db/sqltest/tests/index/update_time.sql b/internal/db/sqltest/tests/index/update_time.sql deleted file mode 100644 index 1fe13918b1..0000000000 --- a/internal/db/sqltest/tests/index/update_time.sql +++ /dev/null @@ -1,27 +0,0 @@ --- Copyright (c) HashiCorp, Inc. --- SPDX-License-Identifier: BUSL-1.1 - -begin; - create function op_table(deletion_table_name name) returns text - as $$ - select split_part(deletion_table_name, '_deleted', 1); - $$ language sql; - create function has_update_time_index(table_name name) returns text - as $$ - select * from collect_tap( - has_index(table_name, table_name || '_update_time_idx', 'update_time') - ); - $$ language sql; - - -- the op table for each deletion table should be tested for the index - select plan(a.table_count::integer) - from ( - select count(*) as table_count - from get_deletion_tables() - ) as a; - - select has_update_time_index(op_table(a)) - from get_deletion_tables() a; - - select * from finish(); -rollback; diff --git a/internal/db/sqltest/tests/pagination/target.sql b/internal/db/sqltest/tests/pagination/target.sql new file mode 100644 index 0000000000..73d3cfb236 --- /dev/null +++ b/internal/db/sqltest/tests/pagination/target.sql @@ -0,0 +1,26 @@ +-- Copyright (c) HashiCorp, Inc. +-- SPDX-License-Identifier: BUSL-1.1 + +begin; + select plan(8); + + -- Verify the trigger functions exist and are declared properly + select has_function('update_target_table_update_time'); + select volatility_is('update_target_table_update_time', 'volatile'); + select isnt_strict('update_target_table_update_time'); + select has_trigger('target_ssh', 'update_target_table_update_time'); + select has_trigger('target_tcp', 'update_target_table_update_time'); + select has_index('target', 'target_create_time_public_id_idx', array['create_time', 'public_id']); + select has_index('target', 'target_update_time_public_id_idx', array['update_time', 'public_id']); + + -- To test the trigger that updates the update_time of the base table, + -- we update one of the existing targets and check that the base table + -- entry has the same update_time as the subtype one. + update target_tcp set name='Blue black color target' where public_id='t_________cb'; + prepare target_update_time as select update_time from target where public_id='t_________cb'; + prepare target_tcp_update_time as select update_time from target_tcp where public_id='t_________cb'; + select results_eq('target_update_time','target_tcp_update_time'); + + select * from finish(); + +rollback;