The list of all the queries

Do not use dual-purpose foreign keys

Query goal: Find cases where the same column of a base table T is used to record references to multiple base tables. In addition, one has to add additional column to T for holding metadata about the parent table, referenced by the current row.
Query type: Problem detection (Each row in the result could represent a flaw in the design)
Query reliability: Medium (Medium number of false-positive results)
Query license: MIT License
Fixing suggestion: Create separate foreign key columns and constraints.
Data source: INFORMATION_SCHEMA only
SQL query: Click on query to copy it

CREATE EXTENSION IF NOT EXISTS fuzzystrmatch;
SELECT table1.table_schema, table1.table_name, table2.column_name AS
polymorphic_column, table1.column_name AS classifier_column
FROM (SELECT table_schema, table_name, column_name
FROM INFORMATION_SCHEMA.constraint_column_usage
WHERE table_schema NOT IN (SELECT schema_name
FROM INFORMATION_SCHEMA.schemata
WHERE schema_name<>'public' AND
schema_owner='postgres' AND schema_name IS NOT NULL) AND
(constraint_schema, constraint_name) IN
(SELECT constraint_schema, constraint_name
FROM INFORMATION_SCHEMA.check_constraints
WHERE check_clause~*'^.+=.*ANY.*[(].*ARRAY[[].+[])].*$')
UNION
SELECT cdu.table_schema, cdu.table_name, cdu.column_name
FROM INFORMATION_SCHEMA.column_domain_usage AS cdu INNER JOIN
INFORMATION_SCHEMA.tables AS t USING (table_schema, table_name)
WHERE t.table_type='BASE TABLE' AND (domain_schema, domain_name) IN
(SELECT domain_schema, domain_name
FROM INFORMATION_SCHEMA.domain_constraints
WHERE (constraint_schema,  constraint_name) IN
(SELECT constraint_schema, constraint_name
FROM INFORMATION_SCHEMA.check_constraints
WHERE check_clause~*'^.+=.*ANY.*[(].*ARRAY[[].+[])].*$'))) AS table1,
(SELECT c.table_schema, c.table_name, c.column_name
FROM INFORMATION_SCHEMA.columns AS c INNER JOIN INFORMATION_SCHEMA.tables AS t
USING (table_schema, table_name)
WHERE t.table_type='BASE TABLE') AS table2
WHERE table1.table_schema=table2.table_schema AND
table1.table_name=table2.table_name
AND table1.column_name<>table2.column_name AND
levenshtein(table1.column_name,table2.column_name)<=4 AND
(table2.table_schema, table2.table_name, table2.column_name) NOT IN (SELECT
kcu_dependent.table_schema, kcu_dependent.table_name, kcu_dependent.column_name
FROM INFORMATION_SCHEMA.key_column_usage AS kcu_dependent
INNER JOIN INFORMATION_SCHEMA.referential_constraints AS rc ON
(kcu_dependent.constraint_schema = rc.constraint_schema) AND
(kcu_dependent.constraint_name = rc.constraint_name))
ORDER BY table1.table_schema, table1.table_name;

Categories where the query belongs to

Category nameCategory description
Database design antipatternsQueries of this category provide information about possible occurrences of SQL database design antipatterns.
Relationships between tablesQueries of this category provide information about how database tables are connected to each other and whether such connections have been explicitly defined and whether it has been done correctly.
Structure of base tablesQueries of this category provide information about the structuring of base tables at the database conceptual level

Reference materials for further reading

Reference
This is one of the antipatterns from the Bill Karwin's book of SQL antipatterns. See Chapter 7: Polymorphic Associations.
Smell "Polymorphic association": Sharma, T., Fragkoulis, M., Rizou, S., Bruntink, M. and Spinellis, D.: Smelly relations: measuring and understanding database schema quality. In: Proceedings of the 40th International Conference on Software Engineering: Software Engineering in Practice, pp. 55-64. ACM, (2018).

The list of all the queries