From d4d0b5ff1518d9355a146adcfe1568223cdd2b18 Mon Sep 17 00:00:00 2001 From: Jason Petersen Date: Fri, 9 Jun 2017 15:05:07 -0600 Subject: [PATCH] Move test functions into early, separate file --- src/test/regress/expected/multi_extension.out | 167 ---------------- .../regress/expected/multi_test_helpers.out | 86 ++++++++ ...i_behavioral_analytics_create_table.source | 8 - src/test/regress/multi_binary_schedule | 1 + src/test/regress/multi_mx_schedule | 1 + src/test/regress/multi_schedule | 1 + .../regress/multi_task_tracker_extra_schedule | 1 + ...i_behavioral_analytics_create_table.source | 7 - src/test/regress/sql/multi_extension.sql | 183 ------------------ src/test/regress/sql/multi_test_helpers.sql | 83 ++++++++ 10 files changed, 173 insertions(+), 365 deletions(-) create mode 100644 src/test/regress/expected/multi_test_helpers.out create mode 100644 src/test/regress/sql/multi_test_helpers.sql diff --git a/src/test/regress/expected/multi_extension.out b/src/test/regress/expected/multi_extension.out index 6a3bc6543..08762ae0e 100644 --- a/src/test/regress/expected/multi_extension.out +++ b/src/test/regress/expected/multi_extension.out @@ -197,170 +197,3 @@ ALTER EXTENSION citus UPDATE; --------+------+------+------- (0 rows) -\c - - - :master_port -CREATE VIEW table_fkey_cols AS -SELECT rc.constraint_name AS "name", - kcu.column_name AS "column_name", - uc_kcu.column_name AS "refd_column_name", - format('%I.%I', kcu.table_schema, kcu.table_name)::regclass::oid AS relid, - format('%I.%I', uc_kcu.table_schema, uc_kcu.table_name)::regclass::oid AS refd_relid -FROM information_schema.referential_constraints rc, - information_schema.key_column_usage kcu, - information_schema.key_column_usage uc_kcu -WHERE rc.constraint_schema = kcu.constraint_schema AND - rc.constraint_name = kcu.constraint_name AND - rc.unique_constraint_schema = uc_kcu.constraint_schema AND - rc.unique_constraint_name = uc_kcu.constraint_name; -CREATE VIEW table_fkeys AS -SELECT name AS "Constraint", - format('FOREIGN KEY (%s) REFERENCES %s(%s)', - string_agg(DISTINCT quote_ident(column_name), ', '), - string_agg(DISTINCT refd_relid::regclass::text, ', '), - string_agg(DISTINCT quote_ident(refd_column_name), ', ')) AS "Definition", - "relid" -FROM table_fkey_cols -GROUP BY (name, relid); --- create views used to describe relations -CREATE OR REPLACE VIEW table_attrs AS -SELECT c.column_name AS "name", - c.data_type AS "type", - CASE - WHEN character_maximum_length IS NOT NULL THEN - format('(%s)', character_maximum_length) - WHEN data_type = 'numeric' AND numeric_precision IS NOT NULL THEN - format('(%s,%s)', numeric_precision, numeric_scale) - ELSE '' - END AS "modifier", - c.column_default AS "default", - (NOT c.is_nullable::boolean) AS "notnull", - format('%I.%I', c.table_schema, c.table_name)::regclass::oid AS "relid" -FROM information_schema.columns AS c -ORDER BY ordinal_position; -CREATE VIEW table_desc AS -SELECT "name" AS "Column", - "type" || "modifier" AS "Type", - rtrim(( - CASE "notnull" - WHEN true THEN 'not null ' - ELSE '' - END - ) || ( - CASE WHEN "default" IS NULL THEN '' - ELSE 'default ' || "default" - END - )) AS "Modifiers", - "relid" -FROM table_attrs; -CREATE VIEW table_checks AS -SELECT cc.constraint_name AS "Constraint", - ('CHECK ' || regexp_replace(check_clause, '^\((.*)\)$', '\1')) AS "Definition", - format('%I.%I', ccu.table_schema, ccu.table_name)::regclass::oid AS relid -FROM information_schema.check_constraints cc, - information_schema.constraint_column_usage ccu -WHERE cc.constraint_schema = ccu.constraint_schema AND - cc.constraint_name = ccu.constraint_name -ORDER BY cc.constraint_name ASC; -\c - - - :worker_1_port -CREATE VIEW table_fkey_cols AS -SELECT rc.constraint_name AS "name", - kcu.column_name AS "column_name", - uc_kcu.column_name AS "refd_column_name", - format('%I.%I', kcu.table_schema, kcu.table_name)::regclass::oid AS relid, - format('%I.%I', uc_kcu.table_schema, uc_kcu.table_name)::regclass::oid AS refd_relid -FROM information_schema.referential_constraints rc, - information_schema.key_column_usage kcu, - information_schema.key_column_usage uc_kcu -WHERE rc.constraint_schema = kcu.constraint_schema AND - rc.constraint_name = kcu.constraint_name AND - rc.unique_constraint_schema = uc_kcu.constraint_schema AND - rc.unique_constraint_name = uc_kcu.constraint_name; -CREATE VIEW table_fkeys AS -SELECT name AS "Constraint", - format('FOREIGN KEY (%s) REFERENCES %s(%s)', - string_agg(DISTINCT quote_ident(column_name), ', '), - string_agg(DISTINCT refd_relid::regclass::text, ', '), - string_agg(DISTINCT quote_ident(refd_column_name), ', ')) AS "Definition", - "relid" -FROM table_fkey_cols -GROUP BY (name, relid); --- create views used to describe relations -CREATE OR REPLACE VIEW table_attrs AS -SELECT c.column_name AS "name", - c.data_type AS "type", - CASE - WHEN character_maximum_length IS NOT NULL THEN - format('(%s)', character_maximum_length) - WHEN data_type = 'numeric' AND numeric_precision IS NOT NULL THEN - format('(%s,%s)', numeric_precision, numeric_scale) - ELSE '' - END AS "modifier", - c.column_default AS "default", - (NOT c.is_nullable::boolean) AS "notnull", - format('%I.%I', c.table_schema, c.table_name)::regclass::oid AS "relid" -FROM information_schema.columns AS c -ORDER BY ordinal_position; -CREATE VIEW table_desc AS -SELECT "name" AS "Column", - "type" || "modifier" AS "Type", - rtrim(( - CASE "notnull" - WHEN true THEN 'not null ' - ELSE '' - END - ) || ( - CASE WHEN "default" IS NULL THEN '' - ELSE 'default ' || "default" - END - )) AS "Modifiers", - "relid" -FROM table_attrs; -CREATE VIEW table_checks AS -SELECT cc.constraint_name AS "Constraint", - ('CHECK ' || regexp_replace(check_clause, '^\((.*)\)$', '\1')) AS "Definition", - format('%I.%I', ccu.table_schema, ccu.table_name)::regclass::oid AS relid -FROM information_schema.check_constraints cc, - information_schema.constraint_column_usage ccu -WHERE cc.constraint_schema = ccu.constraint_schema AND - cc.constraint_name = ccu.constraint_name -ORDER BY cc.constraint_name ASC; -\c - - - :worker_2_port --- create views used to describe relations -CREATE OR REPLACE VIEW table_attrs AS -SELECT c.column_name AS "name", - c.data_type AS "type", - CASE - WHEN character_maximum_length IS NOT NULL THEN - format('(%s)', character_maximum_length) - WHEN data_type = 'numeric' AND numeric_precision IS NOT NULL THEN - format('(%s,%s)', numeric_precision, numeric_scale) - ELSE '' - END AS "modifier", - c.column_default AS "default", - (NOT c.is_nullable::boolean) AS "notnull", - format('%I.%I', c.table_schema, c.table_name)::regclass::oid AS "relid" -FROM information_schema.columns AS c -ORDER BY ordinal_position; -CREATE VIEW table_desc AS -SELECT "name" AS "Column", - "type" || "modifier" AS "Type", - rtrim(( - CASE "notnull" - WHEN true THEN 'not null ' - ELSE '' - END - ) || ( - CASE WHEN "default" IS NULL THEN '' - ELSE 'default ' || "default" - END - )) AS "Modifiers", - "relid" -FROM table_attrs; -CREATE VIEW table_checks AS -SELECT cc.constraint_name AS "Constraint", - ('CHECK ' || regexp_replace(check_clause, '^\((.*)\)$', '\1')) AS "Definition", - format('%I.%I', ccu.table_schema, ccu.table_name)::regclass::oid AS relid -FROM information_schema.check_constraints cc, - information_schema.constraint_column_usage ccu -WHERE cc.constraint_schema = ccu.constraint_schema AND - cc.constraint_name = ccu.constraint_name -ORDER BY cc.constraint_name ASC; diff --git a/src/test/regress/expected/multi_test_helpers.out b/src/test/regress/expected/multi_test_helpers.out new file mode 100644 index 000000000..7f8b92503 --- /dev/null +++ b/src/test/regress/expected/multi_test_helpers.out @@ -0,0 +1,86 @@ +-- File to create functions and helpers needed for subsequent tests +-- create a helper function to create objects on each node +CREATE FUNCTION run_command_on_master_and_workers(p_sql text) +RETURNS void LANGUAGE plpgsql AS $$ +BEGIN + EXECUTE p_sql; + PERFORM run_command_on_workers(p_sql); +END;$$; +-- The following views are intended as alternatives to \d commands, whose +-- output changed in PostgreSQL 10. In particular, they must be used any time +-- a test wishes to print out the structure of a relation, which previously +-- was safely accomplished by a \d invocation. +SELECT run_command_on_master_and_workers( +$desc_views$ +CREATE VIEW table_fkey_cols AS +SELECT rc.constraint_name AS "name", + kcu.column_name AS "column_name", + uc_kcu.column_name AS "refd_column_name", + format('%I.%I', kcu.table_schema, kcu.table_name)::regclass::oid AS relid, + format('%I.%I', uc_kcu.table_schema, uc_kcu.table_name)::regclass::oid AS refd_relid +FROM information_schema.referential_constraints rc, + information_schema.key_column_usage kcu, + information_schema.key_column_usage uc_kcu +WHERE rc.constraint_schema = kcu.constraint_schema AND + rc.constraint_name = kcu.constraint_name AND + rc.unique_constraint_schema = uc_kcu.constraint_schema AND + rc.unique_constraint_name = uc_kcu.constraint_name; + +CREATE VIEW table_fkeys AS +SELECT name AS "Constraint", + format('FOREIGN KEY (%s) REFERENCES %s(%s)', + string_agg(DISTINCT quote_ident(column_name), ', '), + string_agg(DISTINCT refd_relid::regclass::text, ', '), + string_agg(DISTINCT quote_ident(refd_column_name), ', ')) AS "Definition", + "relid" +FROM table_fkey_cols +GROUP BY (name, relid); + +CREATE VIEW table_attrs AS +SELECT c.column_name AS "name", + c.data_type AS "type", + CASE + WHEN character_maximum_length IS NOT NULL THEN + format('(%s)', character_maximum_length) + WHEN data_type = 'numeric' AND numeric_precision IS NOT NULL THEN + format('(%s,%s)', numeric_precision, numeric_scale) + ELSE '' + END AS "modifier", + c.column_default AS "default", + (NOT c.is_nullable::boolean) AS "notnull", + format('%I.%I', c.table_schema, c.table_name)::regclass::oid AS "relid" +FROM information_schema.columns AS c +ORDER BY ordinal_position; + +CREATE VIEW table_desc AS +SELECT "name" AS "Column", + "type" || "modifier" AS "Type", + rtrim(( + CASE "notnull" + WHEN true THEN 'not null ' + ELSE '' + END + ) || ( + CASE WHEN "default" IS NULL THEN '' + ELSE 'default ' || "default" + END + )) AS "Modifiers", + "relid" +FROM table_attrs; + +CREATE VIEW table_checks AS +SELECT cc.constraint_name AS "Constraint", + ('CHECK ' || regexp_replace(check_clause, '^\((.*)\)$', '\1')) AS "Definition", + format('%I.%I', ccu.table_schema, ccu.table_name)::regclass::oid AS relid +FROM information_schema.check_constraints cc, + information_schema.constraint_column_usage ccu +WHERE cc.constraint_schema = ccu.constraint_schema AND + cc.constraint_name = ccu.constraint_name +ORDER BY cc.constraint_name ASC; +$desc_views$ +); + run_command_on_master_and_workers +----------------------------------- + +(1 row) + diff --git a/src/test/regress/input/multi_behavioral_analytics_create_table.source b/src/test/regress/input/multi_behavioral_analytics_create_table.source index b246564db..fcb1ade20 100644 --- a/src/test/regress/input/multi_behavioral_analytics_create_table.source +++ b/src/test/regress/input/multi_behavioral_analytics_create_table.source @@ -41,14 +41,6 @@ CREATE INDEX is_index4 ON events_table(event_type); CREATE INDEX is_index5 ON users_table(value_2); CREATE INDEX is_index6 ON events_table(value_2); --- create a helper function to create types/functions on each node -CREATE FUNCTION run_command_on_master_and_workers(p_sql text) -RETURNS void LANGUAGE plpgsql AS $$ -BEGIN - EXECUTE p_sql; - PERFORM run_command_on_workers(p_sql); -END;$$; - -- Create composite type to use in subquery pushdown SELECT run_command_on_master_and_workers($f$ diff --git a/src/test/regress/multi_binary_schedule b/src/test/regress/multi_binary_schedule index 698eb69a2..44b277067 100644 --- a/src/test/regress/multi_binary_schedule +++ b/src/test/regress/multi_binary_schedule @@ -12,6 +12,7 @@ # --- test: multi_extension test: multi_cluster_management +test: multi_test_helpers test: multi_table_ddl # ---------- diff --git a/src/test/regress/multi_mx_schedule b/src/test/regress/multi_mx_schedule index 36182b000..c8ae84212 100644 --- a/src/test/regress/multi_mx_schedule +++ b/src/test/regress/multi_mx_schedule @@ -15,6 +15,7 @@ # --- test: multi_extension test: multi_cluster_management +test: multi_test_helpers test: multi_mx_create_table test: multi_mx_copy_data multi_mx_router_planner diff --git a/src/test/regress/multi_schedule b/src/test/regress/multi_schedule index bc7d0d977..2fdd9b3d5 100644 --- a/src/test/regress/multi_schedule +++ b/src/test/regress/multi_schedule @@ -17,6 +17,7 @@ # --- test: multi_extension test: multi_cluster_management +test: multi_test_helpers test: multi_table_ddl test: multi_name_lengths test: multi_metadata_access diff --git a/src/test/regress/multi_task_tracker_extra_schedule b/src/test/regress/multi_task_tracker_extra_schedule index b56ba506f..bdccc840b 100644 --- a/src/test/regress/multi_task_tracker_extra_schedule +++ b/src/test/regress/multi_task_tracker_extra_schedule @@ -15,6 +15,7 @@ # --- test: multi_extension test: multi_cluster_management +test: multi_test_helpers test: multi_table_ddl # ---------- diff --git a/src/test/regress/output/multi_behavioral_analytics_create_table.source b/src/test/regress/output/multi_behavioral_analytics_create_table.source index c07e21cad..093bc1d15 100644 --- a/src/test/regress/output/multi_behavioral_analytics_create_table.source +++ b/src/test/regress/output/multi_behavioral_analytics_create_table.source @@ -62,13 +62,6 @@ CREATE INDEX is_index3 ON users_table(value_1); CREATE INDEX is_index4 ON events_table(event_type); CREATE INDEX is_index5 ON users_table(value_2); CREATE INDEX is_index6 ON events_table(value_2); --- create a helper function to create types/functions on each node -CREATE FUNCTION run_command_on_master_and_workers(p_sql text) -RETURNS void LANGUAGE plpgsql AS $$ -BEGIN - EXECUTE p_sql; - PERFORM run_command_on_workers(p_sql); -END;$$; -- Create composite type to use in subquery pushdown SELECT run_command_on_master_and_workers($f$ diff --git a/src/test/regress/sql/multi_extension.sql b/src/test/regress/sql/multi_extension.sql index a47def409..7c6ed0b7f 100644 --- a/src/test/regress/sql/multi_extension.sql +++ b/src/test/regress/sql/multi_extension.sql @@ -175,186 +175,3 @@ ALTER EXTENSION citus UPDATE; -- if cache is invalidated succesfull, this \d should work without any problem \d - -\c - - - :master_port - -CREATE VIEW table_fkey_cols AS -SELECT rc.constraint_name AS "name", - kcu.column_name AS "column_name", - uc_kcu.column_name AS "refd_column_name", - format('%I.%I', kcu.table_schema, kcu.table_name)::regclass::oid AS relid, - format('%I.%I', uc_kcu.table_schema, uc_kcu.table_name)::regclass::oid AS refd_relid -FROM information_schema.referential_constraints rc, - information_schema.key_column_usage kcu, - information_schema.key_column_usage uc_kcu -WHERE rc.constraint_schema = kcu.constraint_schema AND - rc.constraint_name = kcu.constraint_name AND - rc.unique_constraint_schema = uc_kcu.constraint_schema AND - rc.unique_constraint_name = uc_kcu.constraint_name; - -CREATE VIEW table_fkeys AS -SELECT name AS "Constraint", - format('FOREIGN KEY (%s) REFERENCES %s(%s)', - string_agg(DISTINCT quote_ident(column_name), ', '), - string_agg(DISTINCT refd_relid::regclass::text, ', '), - string_agg(DISTINCT quote_ident(refd_column_name), ', ')) AS "Definition", - "relid" -FROM table_fkey_cols -GROUP BY (name, relid); - --- create views used to describe relations -CREATE OR REPLACE VIEW table_attrs AS -SELECT c.column_name AS "name", - c.data_type AS "type", - CASE - WHEN character_maximum_length IS NOT NULL THEN - format('(%s)', character_maximum_length) - WHEN data_type = 'numeric' AND numeric_precision IS NOT NULL THEN - format('(%s,%s)', numeric_precision, numeric_scale) - ELSE '' - END AS "modifier", - c.column_default AS "default", - (NOT c.is_nullable::boolean) AS "notnull", - format('%I.%I', c.table_schema, c.table_name)::regclass::oid AS "relid" -FROM information_schema.columns AS c -ORDER BY ordinal_position; - -CREATE VIEW table_desc AS -SELECT "name" AS "Column", - "type" || "modifier" AS "Type", - rtrim(( - CASE "notnull" - WHEN true THEN 'not null ' - ELSE '' - END - ) || ( - CASE WHEN "default" IS NULL THEN '' - ELSE 'default ' || "default" - END - )) AS "Modifiers", - "relid" -FROM table_attrs; - -CREATE VIEW table_checks AS -SELECT cc.constraint_name AS "Constraint", - ('CHECK ' || regexp_replace(check_clause, '^\((.*)\)$', '\1')) AS "Definition", - format('%I.%I', ccu.table_schema, ccu.table_name)::regclass::oid AS relid -FROM information_schema.check_constraints cc, - information_schema.constraint_column_usage ccu -WHERE cc.constraint_schema = ccu.constraint_schema AND - cc.constraint_name = ccu.constraint_name -ORDER BY cc.constraint_name ASC; - -\c - - - :worker_1_port - -CREATE VIEW table_fkey_cols AS -SELECT rc.constraint_name AS "name", - kcu.column_name AS "column_name", - uc_kcu.column_name AS "refd_column_name", - format('%I.%I', kcu.table_schema, kcu.table_name)::regclass::oid AS relid, - format('%I.%I', uc_kcu.table_schema, uc_kcu.table_name)::regclass::oid AS refd_relid -FROM information_schema.referential_constraints rc, - information_schema.key_column_usage kcu, - information_schema.key_column_usage uc_kcu -WHERE rc.constraint_schema = kcu.constraint_schema AND - rc.constraint_name = kcu.constraint_name AND - rc.unique_constraint_schema = uc_kcu.constraint_schema AND - rc.unique_constraint_name = uc_kcu.constraint_name; - -CREATE VIEW table_fkeys AS -SELECT name AS "Constraint", - format('FOREIGN KEY (%s) REFERENCES %s(%s)', - string_agg(DISTINCT quote_ident(column_name), ', '), - string_agg(DISTINCT refd_relid::regclass::text, ', '), - string_agg(DISTINCT quote_ident(refd_column_name), ', ')) AS "Definition", - "relid" -FROM table_fkey_cols -GROUP BY (name, relid); - --- create views used to describe relations -CREATE OR REPLACE VIEW table_attrs AS -SELECT c.column_name AS "name", - c.data_type AS "type", - CASE - WHEN character_maximum_length IS NOT NULL THEN - format('(%s)', character_maximum_length) - WHEN data_type = 'numeric' AND numeric_precision IS NOT NULL THEN - format('(%s,%s)', numeric_precision, numeric_scale) - ELSE '' - END AS "modifier", - c.column_default AS "default", - (NOT c.is_nullable::boolean) AS "notnull", - format('%I.%I', c.table_schema, c.table_name)::regclass::oid AS "relid" -FROM information_schema.columns AS c -ORDER BY ordinal_position; - -CREATE VIEW table_desc AS -SELECT "name" AS "Column", - "type" || "modifier" AS "Type", - rtrim(( - CASE "notnull" - WHEN true THEN 'not null ' - ELSE '' - END - ) || ( - CASE WHEN "default" IS NULL THEN '' - ELSE 'default ' || "default" - END - )) AS "Modifiers", - "relid" -FROM table_attrs; - -CREATE VIEW table_checks AS -SELECT cc.constraint_name AS "Constraint", - ('CHECK ' || regexp_replace(check_clause, '^\((.*)\)$', '\1')) AS "Definition", - format('%I.%I', ccu.table_schema, ccu.table_name)::regclass::oid AS relid -FROM information_schema.check_constraints cc, - information_schema.constraint_column_usage ccu -WHERE cc.constraint_schema = ccu.constraint_schema AND - cc.constraint_name = ccu.constraint_name -ORDER BY cc.constraint_name ASC; - -\c - - - :worker_2_port - --- create views used to describe relations -CREATE OR REPLACE VIEW table_attrs AS -SELECT c.column_name AS "name", - c.data_type AS "type", - CASE - WHEN character_maximum_length IS NOT NULL THEN - format('(%s)', character_maximum_length) - WHEN data_type = 'numeric' AND numeric_precision IS NOT NULL THEN - format('(%s,%s)', numeric_precision, numeric_scale) - ELSE '' - END AS "modifier", - c.column_default AS "default", - (NOT c.is_nullable::boolean) AS "notnull", - format('%I.%I', c.table_schema, c.table_name)::regclass::oid AS "relid" -FROM information_schema.columns AS c -ORDER BY ordinal_position; - -CREATE VIEW table_desc AS -SELECT "name" AS "Column", - "type" || "modifier" AS "Type", - rtrim(( - CASE "notnull" - WHEN true THEN 'not null ' - ELSE '' - END - ) || ( - CASE WHEN "default" IS NULL THEN '' - ELSE 'default ' || "default" - END - )) AS "Modifiers", - "relid" -FROM table_attrs; - -CREATE VIEW table_checks AS -SELECT cc.constraint_name AS "Constraint", - ('CHECK ' || regexp_replace(check_clause, '^\((.*)\)$', '\1')) AS "Definition", - format('%I.%I', ccu.table_schema, ccu.table_name)::regclass::oid AS relid -FROM information_schema.check_constraints cc, - information_schema.constraint_column_usage ccu -WHERE cc.constraint_schema = ccu.constraint_schema AND - cc.constraint_name = ccu.constraint_name -ORDER BY cc.constraint_name ASC; diff --git a/src/test/regress/sql/multi_test_helpers.sql b/src/test/regress/sql/multi_test_helpers.sql new file mode 100644 index 000000000..d63ab6529 --- /dev/null +++ b/src/test/regress/sql/multi_test_helpers.sql @@ -0,0 +1,83 @@ +-- File to create functions and helpers needed for subsequent tests + +-- create a helper function to create objects on each node +CREATE FUNCTION run_command_on_master_and_workers(p_sql text) +RETURNS void LANGUAGE plpgsql AS $$ +BEGIN + EXECUTE p_sql; + PERFORM run_command_on_workers(p_sql); +END;$$; + +-- The following views are intended as alternatives to \d commands, whose +-- output changed in PostgreSQL 10. In particular, they must be used any time +-- a test wishes to print out the structure of a relation, which previously +-- was safely accomplished by a \d invocation. +SELECT run_command_on_master_and_workers( +$desc_views$ +CREATE VIEW table_fkey_cols AS +SELECT rc.constraint_name AS "name", + kcu.column_name AS "column_name", + uc_kcu.column_name AS "refd_column_name", + format('%I.%I', kcu.table_schema, kcu.table_name)::regclass::oid AS relid, + format('%I.%I', uc_kcu.table_schema, uc_kcu.table_name)::regclass::oid AS refd_relid +FROM information_schema.referential_constraints rc, + information_schema.key_column_usage kcu, + information_schema.key_column_usage uc_kcu +WHERE rc.constraint_schema = kcu.constraint_schema AND + rc.constraint_name = kcu.constraint_name AND + rc.unique_constraint_schema = uc_kcu.constraint_schema AND + rc.unique_constraint_name = uc_kcu.constraint_name; + +CREATE VIEW table_fkeys AS +SELECT name AS "Constraint", + format('FOREIGN KEY (%s) REFERENCES %s(%s)', + string_agg(DISTINCT quote_ident(column_name), ', '), + string_agg(DISTINCT refd_relid::regclass::text, ', '), + string_agg(DISTINCT quote_ident(refd_column_name), ', ')) AS "Definition", + "relid" +FROM table_fkey_cols +GROUP BY (name, relid); + +CREATE VIEW table_attrs AS +SELECT c.column_name AS "name", + c.data_type AS "type", + CASE + WHEN character_maximum_length IS NOT NULL THEN + format('(%s)', character_maximum_length) + WHEN data_type = 'numeric' AND numeric_precision IS NOT NULL THEN + format('(%s,%s)', numeric_precision, numeric_scale) + ELSE '' + END AS "modifier", + c.column_default AS "default", + (NOT c.is_nullable::boolean) AS "notnull", + format('%I.%I', c.table_schema, c.table_name)::regclass::oid AS "relid" +FROM information_schema.columns AS c +ORDER BY ordinal_position; + +CREATE VIEW table_desc AS +SELECT "name" AS "Column", + "type" || "modifier" AS "Type", + rtrim(( + CASE "notnull" + WHEN true THEN 'not null ' + ELSE '' + END + ) || ( + CASE WHEN "default" IS NULL THEN '' + ELSE 'default ' || "default" + END + )) AS "Modifiers", + "relid" +FROM table_attrs; + +CREATE VIEW table_checks AS +SELECT cc.constraint_name AS "Constraint", + ('CHECK ' || regexp_replace(check_clause, '^\((.*)\)$', '\1')) AS "Definition", + format('%I.%I', ccu.table_schema, ccu.table_name)::regclass::oid AS relid +FROM information_schema.check_constraints cc, + information_schema.constraint_column_usage ccu +WHERE cc.constraint_schema = ccu.constraint_schema AND + cc.constraint_name = ccu.constraint_name +ORDER BY cc.constraint_name ASC; +$desc_views$ +);