PostgreSQL: cómo enumerar todas las funciones almacenadas que acceden a una tabla específica

13

Introducción:

Base de datos PostgreSQL con varios cientos de funciones almacenadas, incluidas obsoletas, no utilizadas, etc.

Problema

Necesito encontrar todas las funciones almacenadas que tienen alguna relación con la tabla X, ya que quiero cambiar la estructura de la tabla. Es posible que algunos de ellos no se usen, por lo que no puedo hacerlo solo mirando el código.

La solución que tengo ATM está ejecutando psql \df+y resultados de grepping, pero preferiría una solución más similar a la base de datos, es decir, mediante el uso del esquema de información. Definitivamente será una tarea repetitiva y me gustaría que fuera agradable y limpia.

¿Alguna sugerencia?

Sergey Kudriavtsev
fuente

Respuestas:

18

El cuerpo de una función solo se almacena como una cadena . No hay una lista de objetos referenciados. (Eso es diferente de las vistas, por ejemplo, donde se guardan los enlaces reales a las tablas referenciadas).

Esta consulta para Postgres 10 o anterior utiliza la función de información del catálogopg_get_functiondef() del sistema para reconstruir el CREATE FUNCTIONscript para funciones relevantes y busca el nombre de la tabla con una expresión regular que no distinga entre mayúsculas y minúsculas:

SELECT n.nspname AS schema_name
     , p.proname AS function_name
     , pg_get_function_arguments(p.oid) AS args
     , pg_get_functiondef(p.oid) AS func_def
FROM   pg_proc p
JOIN   pg_namespace n ON n.oid = p.pronamespace
WHERE  NOT p.proisagg
AND    n.nspname NOT LIKE 'pg_%'
AND    n.nspname <> 'information_schema'
AND    pg_get_functiondef(p.oid) ~* '\mbig\M';

Debería hacer el trabajo, pero obviamente no es a prueba de balas. Puede fallar para SQL dinámico donde el nombre de la tabla se genera dinámicamente y puede devolver cualquier cantidad de falsos positivos, especialmente si el nombre de la tabla es una palabra común.

Se excluyen las funciones agregadas y todas las funciones de los esquemas del sistema.

\my\M marque el principio y el final de una palabra en la expresión regular.

El catálogo del sistema pg_proccambiado en Postgres 11. proisaggfue reemplazado por prokind, se agregaron verdaderos procedimientos almacenados. Necesitas adaptarte. Relacionado:

Erwin Brandstetter
fuente
1
Sí ... no es totalmente robusto, en el sentido de que no encontrará EXECUTEexpresiones como 'mm_'||name_parameter, y no hará frente correctamente a los nombres citados como "my""table""o con mayúsculas y minúsculas, pero hará lo que la mayoría de la gente querrá .
Craig Ringer
@CraigRinger: Sí, las consultas dinámicas EXECUTEson casi imposibles de cubrir. Pero el plegado de mayúsculas y minúsculas puede cubrirse en ~*lugar de ~, o cualquier otra coincidencia de patrones que no distinga entre mayúsculas y minúsculas.
Erwin Brandstetter
Mientras el operador no esté lo suficientemente loco como para crear tablas con nombre "MyTable"y MyTable, al menos ... y honestamente, ese es un movimiento "bueno, eso podría permitirse pero no es inteligente".
Craig Ringer
¡Gracias por la respuesta! En realidad, no uso la construcción dinámica de nombres de tablas en ningún lado y todos los nombres de tablas están en minúsculas.
Sergey Kudriavtsev
1

Esta consulta es bastante fácil de usar:

SELECT proname, proargnames, prosrc FROM pg_proc WHERE prosrc ILIKE '%Text to search%';
joao victor silva de oliveira
fuente