WITH update_triggers AS (SELECT trigger_schema, trigger_table
FROM
(SELECT
T. trigger_schema,
T.event_object_table AS trigger_table,
T.trigger_name,
T.action_condition,
T.event_manipulation,
T.action_orientation,
T.action_timing,
array_agg(event_object_column::text) AS columns
FROM
(SELECT * FROM information_schema.triggers WHERE event_manipulation='UPDATE') AS T LEFT JOIN information_schema.triggered_update_columns AS TUC
ON T.trigger_schema=TUC.trigger_schema AND T.trigger_name=TUC.trigger_name AND
T.event_object_table=TUC.event_object_table
GROUP BY T. trigger_schema, T.event_object_table, T.trigger_name, T.event_manipulation,
T.action_orientation,
T.action_timing, T.action_condition) AS f
WHERE columns='{NULL}'
AND action_condition~'\*.*(IS[[:space:]]+DISTINCT[[:space:]]+FROM|<>|!=).*\*'),
routine_table AS (SELECT DISTINCT t.table_schema, t.table_name, rtu.routine_schema, rtu.routine_name, rtu.specific_name,
pg_get_function_identity_arguments(translate(substring(rtu.specific_name,'_[0-9]+$'),'_','')::int::oid) AS parameters,
pg_get_functiondef(translate(substring(rtu.specific_name,'_[0-9]+$'),'_','')::int::oid) AS routine_source, r.routine_type
FROM information_schema.tables AS t INNER JOIN information_schema.routine_column_usage AS rtu USING (table_schema, table_name)
INNER JOIN information_schema.routines AS r USING (specific_schema, specific_name)
WHERE t.table_type = 'BASE TABLE'
AND (t.table_schema, t.table_name) IN (SELECT table_schema, table_name
FROM INFORMATION_SCHEMA.columns
WHERE column_name~*'(muutm|update|change)'
AND data_type~*'(timestamp|date)')
AND t.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))
SELECT table_schema, table_name, routine_schema, routine_name, parameters, regexp_replace(regexp_replace(routine_source,'<','<','g'),'[\r\n]','<br>','g') AS routine_source, routine_type
FROM routine_table
WHERE routine_source~*'UPDATE[[:space:]].*SET[[:space:]]'
AND routine_source!~*'(localtimestamp|current_timestamp|now\(\))'
AND (routine_schema, specific_name) NOT IN (SELECT specific_schema, specific_name
FROM INFORMATION_SCHEMA.routine_column_usage INNER JOIN INFORMATION_SCHEMA.columns USING (table_schema, table_name, column_name)
WHERE column_name~*'(muutm|update|change)'
AND data_type~*'(timestamp|date)')
AND (table_schema, table_name) NOT IN (SELECT trigger_schema, trigger_table
FROM update_triggers)
ORDER BY table_schema, table_name, routine_schema, routine_name;