Simplify the DbStructure queries (#1478)
* remove unused parts of the DbStructure queries * explain magic numbers in DbStructure queries * simplify primary keys query
This commit is contained in:
+110
-166
@@ -189,14 +189,14 @@ accessibleProcs = H.Statement (toS sql) (param HE.text) decodeProcs True
|
|||||||
procsSqlQuery :: SqlQuery
|
procsSqlQuery :: SqlQuery
|
||||||
procsSqlQuery = [q|
|
procsSqlQuery = [q|
|
||||||
SELECT
|
SELECT
|
||||||
pn.nspname as "proc_schema",
|
pn.nspname as proc_schema,
|
||||||
p.proname as "proc_name",
|
p.proname as proc_name,
|
||||||
d.description as "proc_description",
|
d.description as proc_description,
|
||||||
pg_get_function_arguments(p.oid) as "args",
|
pg_get_function_arguments(p.oid) as args,
|
||||||
tn.nspname as "rettype_schema",
|
tn.nspname as rettype_schema,
|
||||||
coalesce(comp.relname, t.typname) as "rettype_name",
|
coalesce(comp.relname, t.typname) as rettype_name,
|
||||||
p.proretset as "rettype_is_setof",
|
p.proretset as rettype_is_setof,
|
||||||
t.typtype as "rettype_typ",
|
t.typtype as rettype_typ,
|
||||||
p.provolatile
|
p.provolatile
|
||||||
FROM pg_proc p
|
FROM pg_proc p
|
||||||
JOIN pg_namespace pn ON pn.oid = p.pronamespace
|
JOIN pg_namespace pn ON pn.oid = p.pronamespace
|
||||||
@@ -228,11 +228,22 @@ accessibleTables =
|
|||||||
n.nspname as table_schema,
|
n.nspname as table_schema,
|
||||||
relname as table_name,
|
relname as table_name,
|
||||||
d.description as table_description,
|
d.description as table_description,
|
||||||
c.relkind = 'r' or (c.relkind IN ('v', 'f')) and (pg_relation_is_updatable(c.oid::regclass, false) & 8) = 8
|
(
|
||||||
or (exists (
|
c.relkind in ('r', 'v', 'f')
|
||||||
select 1
|
and (pg_relation_is_updatable(c.oid::regclass, false) & 8) = 8
|
||||||
from pg_trigger
|
-- The function `pg_relation_is_updateable` returns a bitmask where 8
|
||||||
where pg_trigger.tgrelid = c.oid and (pg_trigger.tgtype::integer & 69) = 69)
|
-- corresponds to `1 << CMD_INSERT` in the PostgreSQL source code, i.e.
|
||||||
|
-- it's possible to insert into the relation.
|
||||||
|
or (exists (
|
||||||
|
select 1
|
||||||
|
from pg_trigger
|
||||||
|
where
|
||||||
|
pg_trigger.tgrelid = c.oid
|
||||||
|
and (pg_trigger.tgtype::integer & 69) = 69)
|
||||||
|
-- The trigger type `tgtype` is a bitmask where 69 corresponds to
|
||||||
|
-- TRIGGER_TYPE_ROW + TRIGGER_TYPE_INSTEAD + TRIGGER_TYPE_INSERT
|
||||||
|
-- in the PostgreSQL source code.
|
||||||
|
)
|
||||||
) as insertable
|
) as insertable
|
||||||
from
|
from
|
||||||
pg_class c
|
pg_class c
|
||||||
@@ -242,9 +253,9 @@ accessibleTables =
|
|||||||
c.relkind in ('v', 'r', 'm', 'f')
|
c.relkind in ('v', 'r', 'm', 'f')
|
||||||
and n.nspname = $1
|
and n.nspname = $1
|
||||||
and (
|
and (
|
||||||
pg_has_role(c.relowner, 'USAGE'::text)
|
pg_has_role(c.relowner, 'USAGE')
|
||||||
or has_table_privilege(c.oid, 'SELECT, INSERT, UPDATE, DELETE, TRUNCATE, REFERENCES, TRIGGER'::text)
|
or has_table_privilege(c.oid, 'SELECT, INSERT, UPDATE, DELETE, TRUNCATE, REFERENCES, TRIGGER')
|
||||||
or has_any_column_privilege(c.oid, 'SELECT, INSERT, UPDATE, REFERENCES'::text)
|
or has_any_column_privilege(c.oid, 'SELECT, INSERT, UPDATE, REFERENCES')
|
||||||
)
|
)
|
||||||
order by relname |]
|
order by relname |]
|
||||||
|
|
||||||
@@ -373,13 +384,17 @@ allTables =
|
|||||||
n.nspname AS table_schema,
|
n.nspname AS table_schema,
|
||||||
c.relname AS table_name,
|
c.relname AS table_name,
|
||||||
NULL AS table_description,
|
NULL AS table_description,
|
||||||
c.relkind = 'r' OR (c.relkind IN ('v','f'))
|
(
|
||||||
AND (pg_relation_is_updatable(c.oid::regclass, FALSE) & 8) = 8
|
c.relkind IN ('r', 'v','f')
|
||||||
OR (EXISTS
|
AND (pg_relation_is_updatable(c.oid::regclass, FALSE) & 8) = 8
|
||||||
( SELECT 1
|
OR EXISTS (
|
||||||
|
SELECT 1
|
||||||
FROM pg_trigger
|
FROM pg_trigger
|
||||||
WHERE pg_trigger.tgrelid = c.oid
|
WHERE
|
||||||
AND (pg_trigger.tgtype::integer & 69) = 69) ) AS insertable
|
pg_trigger.tgrelid = c.oid
|
||||||
|
AND (pg_trigger.tgtype::integer & 69) = 69
|
||||||
|
)
|
||||||
|
) AS insertable
|
||||||
FROM pg_class c
|
FROM pg_class c
|
||||||
JOIN pg_namespace n ON n.oid = c.relnamespace
|
JOIN pg_namespace n ON n.oid = c.relnamespace
|
||||||
WHERE c.relkind IN ('v','r','m','f')
|
WHERE c.relkind IN ('v','r','m','f')
|
||||||
@@ -406,9 +421,7 @@ allColumns tabs =
|
|||||||
info.column_default AS default_value,
|
info.column_default AS default_value,
|
||||||
array_to_string(enum_info.vals, ',') AS enum
|
array_to_string(enum_info.vals, ',') AS enum
|
||||||
FROM (
|
FROM (
|
||||||
/*
|
|
||||||
-- CTE based on pg_catalog to get PRIMARY/FOREIGN key and UNIQUE columns outside api schema
|
-- CTE based on pg_catalog to get PRIMARY/FOREIGN key and UNIQUE columns outside api schema
|
||||||
*/
|
|
||||||
WITH key_columns AS (
|
WITH key_columns AS (
|
||||||
SELECT
|
SELECT
|
||||||
r.oid AS r_oid,
|
r.oid AS r_oid,
|
||||||
@@ -436,19 +449,16 @@ allColumns tabs =
|
|||||||
-- limit columns to the ones in the api schema or PK/FK columns
|
-- limit columns to the ones in the api schema or PK/FK columns
|
||||||
*/
|
*/
|
||||||
columns AS (
|
columns AS (
|
||||||
SELECT current_database()::information_schema.sql_identifier AS table_catalog,
|
SELECT
|
||||||
nc.nspname::information_schema.sql_identifier AS table_schema,
|
nc.nspname::name AS table_schema,
|
||||||
c.relname::information_schema.sql_identifier AS table_name,
|
c.relname::name AS table_name,
|
||||||
a.attname::information_schema.sql_identifier AS column_name,
|
a.attname::name AS column_name,
|
||||||
d.description AS description,
|
d.description AS description,
|
||||||
a.attnum::information_schema.cardinal_number AS ordinal_position,
|
a.attnum::integer AS ordinal_position,
|
||||||
pg_get_expr(ad.adbin, ad.adrelid)::information_schema.character_data AS column_default,
|
pg_get_expr(ad.adbin, ad.adrelid)::text AS column_default,
|
||||||
|
not (a.attnotnull OR t.typtype = 'd' AND t.typnotnull) AS is_nullable,
|
||||||
CASE
|
CASE
|
||||||
WHEN a.attnotnull OR t.typtype = 'd'::"char" AND t.typnotnull THEN 'NO'::text
|
WHEN t.typtype = 'd' THEN
|
||||||
ELSE 'YES'::text
|
|
||||||
END::information_schema.yes_or_no AS is_nullable,
|
|
||||||
CASE
|
|
||||||
WHEN t.typtype = 'd'::"char" THEN
|
|
||||||
CASE
|
CASE
|
||||||
WHEN bt.typelem <> 0::oid AND bt.typlen = (-1) THEN 'ARRAY'::text
|
WHEN bt.typelem <> 0::oid AND bt.typlen = (-1) THEN 'ARRAY'::text
|
||||||
WHEN nbt.nspname = 'pg_catalog'::name THEN format_type(t.typbasetype, NULL::integer)
|
WHEN nbt.nspname = 'pg_catalog'::name THEN format_type(t.typbasetype, NULL::integer)
|
||||||
@@ -460,77 +470,42 @@ allColumns tabs =
|
|||||||
WHEN nt.nspname = 'pg_catalog'::name THEN format_type(a.atttypid, NULL::integer)
|
WHEN nt.nspname = 'pg_catalog'::name THEN format_type(a.atttypid, NULL::integer)
|
||||||
ELSE format_type(a.atttypid, a.atttypmod)
|
ELSE format_type(a.atttypid, a.atttypmod)
|
||||||
END
|
END
|
||||||
END::information_schema.character_data AS data_type,
|
END::text AS data_type,
|
||||||
information_schema._pg_char_max_length(information_schema._pg_truetypid(a.*, t.*), information_schema._pg_truetypmod(a.*, t.*))::information_schema.cardinal_number AS character_maximum_length,
|
information_schema._pg_char_max_length(
|
||||||
information_schema._pg_char_octet_length(information_schema._pg_truetypid(a.*, t.*), information_schema._pg_truetypmod(a.*, t.*))::information_schema.cardinal_number AS character_octet_length,
|
information_schema._pg_truetypid(a.*, t.*),
|
||||||
information_schema._pg_numeric_precision(information_schema._pg_truetypid(a.*, t.*), information_schema._pg_truetypmod(a.*, t.*))::information_schema.cardinal_number AS numeric_precision,
|
information_schema._pg_truetypmod(a.*, t.*)
|
||||||
information_schema._pg_numeric_precision_radix(information_schema._pg_truetypid(a.*, t.*), information_schema._pg_truetypmod(a.*, t.*))::information_schema.cardinal_number AS numeric_precision_radix,
|
)::integer AS character_maximum_length,
|
||||||
information_schema._pg_numeric_scale(information_schema._pg_truetypid(a.*, t.*), information_schema._pg_truetypmod(a.*, t.*))::information_schema.cardinal_number AS numeric_scale,
|
information_schema._pg_numeric_precision(
|
||||||
information_schema._pg_datetime_precision(information_schema._pg_truetypid(a.*, t.*), information_schema._pg_truetypmod(a.*, t.*))::information_schema.cardinal_number AS datetime_precision,
|
information_schema._pg_truetypid(a.*, t.*),
|
||||||
information_schema._pg_interval_type(information_schema._pg_truetypid(a.*, t.*), information_schema._pg_truetypmod(a.*, t.*))::information_schema.character_data AS interval_type,
|
information_schema._pg_truetypmod(a.*, t.*)
|
||||||
NULL::integer::information_schema.cardinal_number AS interval_precision,
|
)::integer AS numeric_precision,
|
||||||
NULL::character varying::information_schema.sql_identifier AS character_set_catalog,
|
COALESCE(bt.typname, t.typname)::name AS udt_name,
|
||||||
NULL::character varying::information_schema.sql_identifier AS character_set_schema,
|
(
|
||||||
NULL::character varying::information_schema.sql_identifier AS character_set_name,
|
c.relkind in ('r', 'v', 'f')
|
||||||
CASE
|
AND pg_column_is_updatable(c.oid::regclass, a.attnum, false)
|
||||||
WHEN nco.nspname IS NOT NULL THEN current_database()
|
)::bool is_updatable
|
||||||
ELSE NULL::name
|
|
||||||
END::information_schema.sql_identifier AS collation_catalog,
|
|
||||||
nco.nspname::information_schema.sql_identifier AS collation_schema,
|
|
||||||
co.collname::information_schema.sql_identifier AS collation_name,
|
|
||||||
CASE
|
|
||||||
WHEN t.typtype = 'd'::"char" THEN current_database()
|
|
||||||
ELSE NULL::name
|
|
||||||
END::information_schema.sql_identifier AS domain_catalog,
|
|
||||||
CASE
|
|
||||||
WHEN t.typtype = 'd'::"char" THEN nt.nspname
|
|
||||||
ELSE NULL::name
|
|
||||||
END::information_schema.sql_identifier AS domain_schema,
|
|
||||||
CASE
|
|
||||||
WHEN t.typtype = 'd'::"char" THEN t.typname
|
|
||||||
ELSE NULL::name
|
|
||||||
END::information_schema.sql_identifier AS domain_name,
|
|
||||||
current_database()::information_schema.sql_identifier AS udt_catalog,
|
|
||||||
COALESCE(nbt.nspname, nt.nspname)::information_schema.sql_identifier AS udt_schema,
|
|
||||||
COALESCE(bt.typname, t.typname)::information_schema.sql_identifier AS udt_name,
|
|
||||||
NULL::character varying::information_schema.sql_identifier AS scope_catalog,
|
|
||||||
NULL::character varying::information_schema.sql_identifier AS scope_schema,
|
|
||||||
NULL::character varying::information_schema.sql_identifier AS scope_name,
|
|
||||||
NULL::integer::information_schema.cardinal_number AS maximum_cardinality,
|
|
||||||
a.attnum::information_schema.sql_identifier AS dtd_identifier,
|
|
||||||
'NO'::character varying::information_schema.yes_or_no AS is_self_referencing,
|
|
||||||
'NO'::character varying::information_schema.yes_or_no AS is_identity,
|
|
||||||
NULL::character varying::information_schema.character_data AS identity_generation,
|
|
||||||
NULL::character varying::information_schema.character_data AS identity_start,
|
|
||||||
NULL::character varying::information_schema.character_data AS identity_increment,
|
|
||||||
NULL::character varying::information_schema.character_data AS identity_maximum,
|
|
||||||
NULL::character varying::information_schema.character_data AS identity_minimum,
|
|
||||||
NULL::character varying::information_schema.yes_or_no AS identity_cycle,
|
|
||||||
'NEVER'::character varying::information_schema.character_data AS is_generated,
|
|
||||||
NULL::character varying::information_schema.character_data AS generation_expression,
|
|
||||||
CASE
|
|
||||||
WHEN c.relkind = 'r'::"char" OR (c.relkind = ANY (ARRAY['v'::"char", 'f'::"char"])) AND pg_column_is_updatable(c.oid::regclass, a.attnum, false) THEN 'YES'::text
|
|
||||||
ELSE 'NO'::text
|
|
||||||
END::information_schema.yes_or_no AS is_updatable
|
|
||||||
FROM pg_attribute a
|
FROM pg_attribute a
|
||||||
LEFT JOIN key_columns kc ON kc.conkey = a.attnum AND kc.c_oid = a.attrelid
|
LEFT JOIN key_columns kc
|
||||||
LEFT JOIN pg_catalog.pg_description AS d ON d.objoid = a.attrelid and d.objsubid = a.attnum
|
ON kc.conkey = a.attnum AND kc.c_oid = a.attrelid
|
||||||
LEFT JOIN pg_attrdef ad ON a.attrelid = ad.adrelid AND a.attnum = ad.adnum
|
LEFT JOIN pg_catalog.pg_description AS d
|
||||||
JOIN (pg_class c
|
ON d.objoid = a.attrelid and d.objsubid = a.attnum
|
||||||
JOIN pg_namespace nc ON c.relnamespace = nc.oid) ON a.attrelid = c.oid
|
LEFT JOIN pg_attrdef ad
|
||||||
JOIN (pg_type t
|
ON a.attrelid = ad.adrelid AND a.attnum = ad.adnum
|
||||||
JOIN pg_namespace nt ON t.typnamespace = nt.oid) ON a.atttypid = t.oid
|
JOIN (pg_class c JOIN pg_namespace nc ON c.relnamespace = nc.oid)
|
||||||
LEFT JOIN (pg_type bt
|
ON a.attrelid = c.oid
|
||||||
JOIN pg_namespace nbt ON bt.typnamespace = nbt.oid) ON t.typtype = 'd'::"char" AND t.typbasetype = bt.oid
|
JOIN (pg_type t JOIN pg_namespace nt ON t.typnamespace = nt.oid)
|
||||||
LEFT JOIN (pg_collation co
|
ON a.atttypid = t.oid
|
||||||
JOIN pg_namespace nco ON co.collnamespace = nco.oid) ON a.attcollation = co.oid AND (nco.nspname <> 'pg_catalog'::name OR co.collname <> 'default'::name)
|
LEFT JOIN (pg_type bt JOIN pg_namespace nbt ON bt.typnamespace = nbt.oid)
|
||||||
|
ON t.typtype = 'd' AND t.typbasetype = bt.oid
|
||||||
|
LEFT JOIN (pg_collation co JOIN pg_namespace nco ON co.collnamespace = nco.oid)
|
||||||
|
ON a.attcollation = co.oid AND (nco.nspname <> 'pg_catalog'::name OR co.collname <> 'default'::name)
|
||||||
WHERE
|
WHERE
|
||||||
NOT pg_is_other_temp_schema(nc.oid)
|
NOT pg_is_other_temp_schema(nc.oid)
|
||||||
AND a.attnum > 0
|
AND a.attnum > 0
|
||||||
AND NOT a.attisdropped
|
AND NOT a.attisdropped
|
||||||
AND (c.relkind = ANY (ARRAY['r'::"char", 'v'::"char", 'f'::"char", 'm'::"char"]))
|
AND c.relkind in ('r', 'v', 'f', 'm')
|
||||||
AND (nc.nspname = ANY ($1) OR kc.r_oid IS NOT NULL) /*--filter only columns that are FK/PK or in the api schema */
|
-- Filter only columns that are FK/PK or in the api schema:
|
||||||
/*--AND (pg_has_role(c.relowner, 'USAGE'::text) OR has_column_privilege(c.oid, a.attnum, 'SELECT, INSERT, UPDATE, REFERENCES'::text))*/
|
AND (nc.nspname = ANY ($1) OR kc.r_oid IS NOT NULL)
|
||||||
)
|
)
|
||||||
SELECT
|
SELECT
|
||||||
table_schema,
|
table_schema,
|
||||||
@@ -545,7 +520,6 @@ allColumns tabs =
|
|||||||
numeric_precision,
|
numeric_precision,
|
||||||
column_default,
|
column_default,
|
||||||
udt_name
|
udt_name
|
||||||
/*-- FROM information_schema.columns*/
|
|
||||||
FROM columns
|
FROM columns
|
||||||
WHERE table_schema NOT IN ('pg_catalog', 'information_schema')
|
WHERE table_schema NOT IN ('pg_catalog', 'information_schema')
|
||||||
) AS info
|
) AS info
|
||||||
@@ -617,69 +591,36 @@ allPrimaryKeys tabs =
|
|||||||
H.Statement sql HE.noParams (decodePks tabs) True
|
H.Statement sql HE.noParams (decodePks tabs) True
|
||||||
where
|
where
|
||||||
sql = [q|
|
sql = [q|
|
||||||
/*
|
|
||||||
-- CTE to replace information_schema.table_constraints to remove owner limit
|
-- CTE to replace information_schema.table_constraints to remove owner limit
|
||||||
*/
|
|
||||||
WITH tc AS (
|
WITH tc AS (
|
||||||
SELECT current_database()::information_schema.sql_identifier AS constraint_catalog,
|
SELECT
|
||||||
nc.nspname::information_schema.sql_identifier AS constraint_schema,
|
c.conname::name AS constraint_name,
|
||||||
c.conname::information_schema.sql_identifier AS constraint_name,
|
nr.nspname::name AS table_schema,
|
||||||
current_database()::information_schema.sql_identifier AS table_catalog,
|
r.relname::name AS table_name
|
||||||
nr.nspname::information_schema.sql_identifier AS table_schema,
|
|
||||||
r.relname::information_schema.sql_identifier AS table_name,
|
|
||||||
CASE c.contype
|
|
||||||
WHEN 'c'::"char" THEN 'CHECK'::text
|
|
||||||
WHEN 'f'::"char" THEN 'FOREIGN KEY'::text
|
|
||||||
WHEN 'p'::"char" THEN 'PRIMARY KEY'::text
|
|
||||||
WHEN 'u'::"char" THEN 'UNIQUE'::text
|
|
||||||
ELSE NULL::text
|
|
||||||
END::information_schema.character_data AS constraint_type,
|
|
||||||
CASE
|
|
||||||
WHEN c.condeferrable THEN 'YES'::text
|
|
||||||
ELSE 'NO'::text
|
|
||||||
END::information_schema.yes_or_no AS is_deferrable,
|
|
||||||
CASE
|
|
||||||
WHEN c.condeferred THEN 'YES'::text
|
|
||||||
ELSE 'NO'::text
|
|
||||||
END::information_schema.yes_or_no AS initially_deferred
|
|
||||||
FROM pg_namespace nc,
|
FROM pg_namespace nc,
|
||||||
pg_namespace nr,
|
pg_namespace nr,
|
||||||
pg_constraint c,
|
pg_constraint c,
|
||||||
pg_class r
|
pg_class r
|
||||||
WHERE nc.oid = c.connamespace AND nr.oid = r.relnamespace AND c.conrelid = r.oid AND (c.contype <> ALL (ARRAY['t'::"char", 'x'::"char"])) AND r.relkind = 'r'::"char" AND NOT pg_is_other_temp_schema(nr.oid)
|
WHERE
|
||||||
/*--AND (pg_has_role(r.relowner, 'USAGE'::text) OR has_table_privilege(r.oid, 'INSERT, UPDATE, DELETE, TRUNCATE, REFERENCES, TRIGGER'::text) OR has_any_column_privilege(r.oid, 'INSERT, UPDATE, REFERENCES'::text))*/
|
nc.oid = c.connamespace
|
||||||
UNION ALL
|
AND nr.oid = r.relnamespace
|
||||||
SELECT current_database()::information_schema.sql_identifier AS constraint_catalog,
|
AND c.conrelid = r.oid
|
||||||
nr.nspname::information_schema.sql_identifier AS constraint_schema,
|
AND r.relkind = 'r'
|
||||||
(((((nr.oid::text || '_'::text) || r.oid::text) || '_'::text) || a.attnum::text) || '_not_null'::text)::information_schema.sql_identifier AS constraint_name,
|
AND NOT pg_is_other_temp_schema(nr.oid)
|
||||||
current_database()::information_schema.sql_identifier AS table_catalog,
|
AND c.contype = 'p'
|
||||||
nr.nspname::information_schema.sql_identifier AS table_schema,
|
|
||||||
r.relname::information_schema.sql_identifier AS table_name,
|
|
||||||
'CHECK'::character varying::information_schema.character_data AS constraint_type,
|
|
||||||
'NO'::character varying::information_schema.yes_or_no AS is_deferrable,
|
|
||||||
'NO'::character varying::information_schema.yes_or_no AS initially_deferred
|
|
||||||
FROM pg_namespace nr,
|
|
||||||
pg_class r,
|
|
||||||
pg_attribute a
|
|
||||||
WHERE nr.oid = r.relnamespace AND r.oid = a.attrelid AND a.attnotnull AND a.attnum > 0 AND NOT a.attisdropped AND r.relkind = 'r'::"char" AND NOT pg_is_other_temp_schema(nr.oid)
|
|
||||||
/*--AND (pg_has_role(r.relowner, 'USAGE'::text) OR has_table_privilege(r.oid, 'INSERT, UPDATE, DELETE, TRUNCATE, REFERENCES, TRIGGER'::text) OR has_any_column_privilege(r.oid, 'INSERT, UPDATE, REFERENCES'::text))*/
|
|
||||||
),
|
),
|
||||||
/*
|
|
||||||
-- CTE to replace information_schema.key_column_usage to remove owner limit
|
-- CTE to replace information_schema.key_column_usage to remove owner limit
|
||||||
*/
|
|
||||||
kc AS (
|
kc AS (
|
||||||
SELECT current_database()::information_schema.sql_identifier AS constraint_catalog,
|
SELECT
|
||||||
ss.nc_nspname::information_schema.sql_identifier AS constraint_schema,
|
ss.conname::name AS constraint_name,
|
||||||
ss.conname::information_schema.sql_identifier AS constraint_name,
|
ss.nr_nspname::name AS table_schema,
|
||||||
current_database()::information_schema.sql_identifier AS table_catalog,
|
ss.relname::name AS table_name,
|
||||||
ss.nr_nspname::information_schema.sql_identifier AS table_schema,
|
a.attname::name AS column_name,
|
||||||
ss.relname::information_schema.sql_identifier AS table_name,
|
(ss.x).n::integer AS ordinal_position,
|
||||||
a.attname::information_schema.sql_identifier AS column_name,
|
CASE
|
||||||
(ss.x).n::information_schema.cardinal_number AS ordinal_position,
|
WHEN ss.contype = 'f' THEN information_schema._pg_index_position(ss.conindid, ss.confkey[(ss.x).n])
|
||||||
CASE
|
ELSE NULL::integer
|
||||||
WHEN ss.contype = 'f'::"char" THEN information_schema._pg_index_position(ss.conindid, ss.confkey[(ss.x).n])
|
END::integer AS position_in_unique_constraint
|
||||||
ELSE NULL::integer
|
|
||||||
END::information_schema.cardinal_number AS position_in_unique_constraint
|
|
||||||
FROM pg_attribute a,
|
FROM pg_attribute a,
|
||||||
( SELECT r.oid AS roid,
|
( SELECT r.oid AS roid,
|
||||||
r.relname,
|
r.relname,
|
||||||
@@ -691,28 +632,31 @@ allPrimaryKeys tabs =
|
|||||||
c.contype,
|
c.contype,
|
||||||
c.conindid,
|
c.conindid,
|
||||||
c.confkey,
|
c.confkey,
|
||||||
c.confrelid,
|
|
||||||
information_schema._pg_expandarray(c.conkey) AS x
|
information_schema._pg_expandarray(c.conkey) AS x
|
||||||
FROM pg_namespace nr,
|
FROM pg_namespace nr,
|
||||||
pg_class r,
|
pg_class r,
|
||||||
pg_namespace nc,
|
pg_namespace nc,
|
||||||
pg_constraint c
|
pg_constraint c
|
||||||
WHERE nr.oid = r.relnamespace AND r.oid = c.conrelid AND nc.oid = c.connamespace AND (c.contype = ANY (ARRAY['p'::"char", 'u'::"char", 'f'::"char"])) AND r.relkind = 'r'::"char" AND NOT pg_is_other_temp_schema(nr.oid)) ss
|
WHERE
|
||||||
WHERE ss.roid = a.attrelid AND a.attnum = (ss.x).x AND NOT a.attisdropped
|
nr.oid = r.relnamespace
|
||||||
/*--AND (pg_has_role(ss.relowner, 'USAGE'::text) OR has_column_privilege(ss.roid, a.attnum, 'SELECT, INSERT, UPDATE, REFERENCES'::text))*/
|
AND r.oid = c.conrelid
|
||||||
|
AND nc.oid = c.connamespace
|
||||||
|
AND c.contype in ('p', 'u', 'f')
|
||||||
|
AND r.relkind = 'r'
|
||||||
|
AND NOT pg_is_other_temp_schema(nr.oid)
|
||||||
|
) ss
|
||||||
|
WHERE
|
||||||
|
ss.roid = a.attrelid
|
||||||
|
AND a.attnum = (ss.x).x
|
||||||
|
AND NOT a.attisdropped
|
||||||
)
|
)
|
||||||
SELECT
|
SELECT
|
||||||
kc.table_schema,
|
kc.table_schema,
|
||||||
kc.table_name,
|
kc.table_name,
|
||||||
kc.column_name
|
kc.column_name
|
||||||
FROM
|
FROM
|
||||||
/*
|
|
||||||
--information_schema.table_constraints tc,
|
|
||||||
--information_schema.key_column_usage kc
|
|
||||||
*/
|
|
||||||
tc, kc
|
tc, kc
|
||||||
WHERE
|
WHERE
|
||||||
tc.constraint_type = 'PRIMARY KEY' AND
|
|
||||||
kc.table_name = tc.table_name AND
|
kc.table_name = tc.table_name AND
|
||||||
kc.table_schema = tc.table_schema AND
|
kc.table_schema = tc.table_schema AND
|
||||||
kc.constraint_name = tc.constraint_name AND
|
kc.constraint_name = tc.constraint_name AND
|
||||||
@@ -743,7 +687,7 @@ allSourceColumns cols pgVer =
|
|||||||
from pg_class c
|
from pg_class c
|
||||||
join pg_namespace n on n.oid = c.relnamespace
|
join pg_namespace n on n.oid = c.relnamespace
|
||||||
join pg_rewrite r on r.ev_class = c.oid
|
join pg_rewrite r on r.ev_class = c.oid
|
||||||
where (c.relkind in ('v', 'm')) and n.nspname = ANY ($1)
|
where c.relkind in ('v', 'm') and n.nspname = ANY ($1)
|
||||||
),
|
),
|
||||||
removed_subselects as(
|
removed_subselects as(
|
||||||
select
|
select
|
||||||
|
|||||||
Reference in New Issue
Block a user