refactor: remove fkey from allPrimaryKeys query
The query had the unnecessary 'f' in `c.contype in ('p', 'u', 'f')`
Also comment and clarify the query by using explicit JOINs
This commit is contained in:
committed by
Steve Chavez
parent
44e2b2fbb4
commit
f995799e8f
@@ -657,27 +657,25 @@ allPrimaryKeys :: [Table] -> Bool -> SQL.Statement () [PrimaryKey]
|
|||||||
allPrimaryKeys tabs =
|
allPrimaryKeys tabs =
|
||||||
SQL.Statement sql HE.noParams (decodePks tabs)
|
SQL.Statement sql HE.noParams (decodePks tabs)
|
||||||
where
|
where
|
||||||
|
-- these CTEs are based on the standard "information_schema.table_constraints" and "information_schema.key_column_usage" views,
|
||||||
|
-- we cannot use those directly as they include the following privilege filter:
|
||||||
|
-- (pg_has_role(ss.relowner, 'USAGE'::text) OR has_column_privilege(ss.roid, a.attnum, 'SELECT, INSERT, UPDATE, REFERENCES'::text));
|
||||||
sql = [q|
|
sql = [q|
|
||||||
-- CTE to replace information_schema.table_constraints to remove owner limit
|
WITH tbl_constraints AS (
|
||||||
WITH tc AS (
|
|
||||||
SELECT
|
SELECT
|
||||||
c.conname::name AS constraint_name,
|
c.conname::name AS constraint_name,
|
||||||
nr.nspname::name AS table_schema,
|
nr.nspname::name AS table_schema,
|
||||||
r.relname::name AS table_name
|
r.relname::name AS table_name
|
||||||
FROM pg_namespace nc,
|
FROM pg_namespace nc
|
||||||
pg_namespace nr,
|
JOIN pg_constraint c ON nc.oid = c.connamespace
|
||||||
pg_constraint c,
|
JOIN pg_class r ON c.conrelid = r.oid
|
||||||
pg_class r
|
JOIN pg_namespace nr ON nr.oid = r.relnamespace
|
||||||
WHERE
|
WHERE
|
||||||
nc.oid = c.connamespace
|
r.relkind IN ('r', 'p')
|
||||||
AND nr.oid = r.relnamespace
|
AND NOT pg_is_other_temp_schema(nr.oid)
|
||||||
AND c.conrelid = r.oid
|
AND c.contype = 'p'
|
||||||
AND r.relkind IN ('r', 'p')
|
|
||||||
AND NOT pg_is_other_temp_schema(nr.oid)
|
|
||||||
AND c.contype = 'p'
|
|
||||||
),
|
),
|
||||||
-- CTE to replace information_schema.key_column_usage to remove owner limit
|
key_col_usage AS (
|
||||||
kc AS (
|
|
||||||
SELECT
|
SELECT
|
||||||
ss.conname::name AS constraint_name,
|
ss.conname::name AS constraint_name,
|
||||||
ss.nr_nspname::name AS table_schema,
|
ss.nr_nspname::name AS table_schema,
|
||||||
@@ -688,46 +686,48 @@ allPrimaryKeys tabs =
|
|||||||
WHEN ss.contype = 'f' THEN information_schema._pg_index_position(ss.conindid, ss.confkey[(ss.x).n])
|
WHEN ss.contype = 'f' THEN information_schema._pg_index_position(ss.conindid, ss.confkey[(ss.x).n])
|
||||||
ELSE NULL::integer
|
ELSE NULL::integer
|
||||||
END::integer AS position_in_unique_constraint
|
END::integer AS position_in_unique_constraint
|
||||||
FROM pg_attribute a,
|
FROM pg_attribute a
|
||||||
( SELECT r.oid AS roid,
|
JOIN (
|
||||||
r.relname,
|
SELECT r.oid AS roid,
|
||||||
r.relowner,
|
r.relname,
|
||||||
nc.nspname AS nc_nspname,
|
r.relowner,
|
||||||
nr.nspname AS nr_nspname,
|
nc.nspname AS nc_nspname,
|
||||||
c.oid AS coid,
|
nr.nspname AS nr_nspname,
|
||||||
c.conname,
|
c.oid AS coid,
|
||||||
c.contype,
|
c.conname,
|
||||||
c.conindid,
|
c.contype,
|
||||||
c.confkey,
|
c.conindid,
|
||||||
information_schema._pg_expandarray(c.conkey) AS x
|
c.confkey,
|
||||||
FROM pg_namespace nr,
|
information_schema._pg_expandarray(c.conkey) AS x
|
||||||
pg_class r,
|
FROM pg_namespace nr
|
||||||
pg_namespace nc,
|
JOIN pg_class r
|
||||||
pg_constraint c
|
ON nr.oid = r.relnamespace
|
||||||
WHERE
|
JOIN pg_constraint c
|
||||||
nr.oid = r.relnamespace
|
ON r.oid = c.conrelid
|
||||||
AND r.oid = c.conrelid
|
JOIN pg_namespace nc
|
||||||
AND nc.oid = c.connamespace
|
ON c.connamespace = nc.oid
|
||||||
AND c.contype in ('p', 'u', 'f')
|
WHERE
|
||||||
AND r.relkind IN ('r', 'p')
|
c.contype in ('p', 'u')
|
||||||
AND NOT pg_is_other_temp_schema(nr.oid)
|
AND r.relkind IN ('r', 'p')
|
||||||
) ss
|
AND NOT pg_is_other_temp_schema(nr.oid)
|
||||||
|
) ss ON a.attrelid = ss.roid AND a.attnum = (ss.x).x
|
||||||
WHERE
|
WHERE
|
||||||
ss.roid = a.attrelid
|
NOT a.attisdropped
|
||||||
AND a.attnum = (ss.x).x
|
|
||||||
AND NOT a.attisdropped
|
|
||||||
)
|
)
|
||||||
SELECT
|
SELECT
|
||||||
kc.table_schema,
|
key_col_usage.table_schema,
|
||||||
kc.table_name,
|
key_col_usage.table_name,
|
||||||
kc.column_name
|
key_col_usage.column_name
|
||||||
FROM
|
FROM
|
||||||
tc, kc
|
tbl_constraints
|
||||||
|
JOIN
|
||||||
|
key_col_usage
|
||||||
|
ON
|
||||||
|
key_col_usage.table_name = tbl_constraints.table_name AND
|
||||||
|
key_col_usage.table_schema = tbl_constraints.table_schema AND
|
||||||
|
key_col_usage.constraint_name = tbl_constraints.constraint_name
|
||||||
WHERE
|
WHERE
|
||||||
kc.table_name = tc.table_name AND
|
key_col_usage.table_schema NOT IN ('pg_catalog', 'information_schema') |]
|
||||||
kc.table_schema = tc.table_schema AND
|
|
||||||
kc.constraint_name = tc.constraint_name AND
|
|
||||||
kc.table_schema NOT IN ('pg_catalog', 'information_schema') |]
|
|
||||||
|
|
||||||
pkFromRow :: [Table] -> (Schema, Text, Text) -> Maybe PrimaryKey
|
pkFromRow :: [Table] -> (Schema, Text, Text) -> Maybe PrimaryKey
|
||||||
pkFromRow tabs (s, t, n) = PrimaryKey <$> table <*> pure n
|
pkFromRow tabs (s, t, n) = PrimaryKey <$> table <*> pure n
|
||||||
|
|||||||
Reference in New Issue
Block a user