@@ -44,12 +44,47 @@ where traint.contype = 'f'
4444and traint .conparentid = 0
4545order by traint .conrelid , traint .conname ;
4646
47+
4748-- type for the array of (column_name, view_columns[]), otherwise the creation of the function would fail
4849CREATE TYPE col_dep AS (
4950 col text ,
5051 view_columns text []
5152);
5253
54+ CREATE TYPE key_dep_type AS enum(
55+ ' p' , -- pk dependency
56+ ' f_ref' , -- fk dependency
57+ ' f' -- fk reference dependency
58+ );
59+
60+ -- | A view foreign key or primary key dependency detected on its source table
61+ -- Each column of the key could be referenced multiple times in the view, e.g.
62+ --
63+ -- create view projects_view as
64+ -- select
65+ -- id as id_1,
66+ -- id as id_2,
67+ -- id as id_3,
68+ -- name
69+ -- from projects
70+ --
71+ -- In this case, the keyDepCols mapping maps projects.id to all three of the columns:
72+ --
73+ -- [('id', ['id_1', 'id_2', 'id_3'])]
74+ --
75+ -- Depending on key type, we can then choose how to handle this case. Primary keys
76+ -- can arbitrarily choose one of the columns, but for foreign keys we need to create
77+ -- relationships for each possible combinations.
78+ CREATE TYPE view_key_dependency AS (
79+ table_schema text ,
80+ table_name text ,
81+ view_schema text ,
82+ view_name text ,
83+ constraint_name text ,
84+ key_dep key_dep_type,
85+ column_dependencies col_dep[]
86+ );
87+
5388-- Same query as PostgREST's allViewsKeyDependencies
5489-- Returns all the views' primary keys and foreign keys dependencies
5590-- query explanation at:
@@ -58,16 +93,8 @@ CREATE TYPE col_dep AS (
5893create or replace function all_views_key_dependencies
5994( db_schemas regnamespace[] default ' {public}'
6095, db_extra_search_path regnamespace[] default ' {public}'
61- )
62- returns table (
63- table_schema text ,
64- table_name text ,
65- view_schema text ,
66- view_name text ,
67- constraint_name text ,
68- constraint_type text ,
69- column_dependencies col_dep[] -- array of (col, view_columns[])
70- ) as $func$
96+ ) returns setof view_key_dependency as $$
97+
7198with recursive
7299pks_fks as (
73100 -- pk + fk referencing col
@@ -247,7 +274,7 @@ select
247274 rep .view_schema ,
248275 rep .view_name ,
249276 pks_fks .conname as constraint_name,
250- pks_fks .contype as constraint_type,
277+ pks_fks .contype ::key_dep_type as constraint_type,
251278 array_agg(row(col .attname , view_columns)::col_dep order by pks_fks .ord ) as column_dependencies
252279from repeated_references rep
253280join pks_fks using (resorigtbl, resorigcol)
@@ -257,5 +284,5 @@ join pg_namespace sch on sch.oid = tbl.relnamespace
257284group by sch .nspname , tbl .relname , rep .view_schema , rep .view_name , pks_fks .conname , pks_fks .contype , pks_fks .ncol
258285-- make sure we only return key for which all columns are referenced in the view - no partial PKs or FKs
259286having ncol = array_length(array_agg(row(col .attname , view_columns) order by pks_fks .ord ), 1 )
260- $func$
261- language sql stable;
287+
288+ $$ language sql stable;
0 commit comments