PostgreSQL: come elencare tutte le funzioni memorizzate che accedono a una tabella specifica


13

Introduzione:

Database PostgreSQL con diverse centinaia di funzioni memorizzate, tra cui obsolete, non utilizzate ecc.

Problema

Devo scoprire tutte le funzioni memorizzate che hanno qualche relazione con la tabella X, poiché voglio cambiare la struttura della tabella. Alcuni di essi potrebbero non essere utilizzati, quindi non posso farlo semplicemente guardando il codice.

La soluzione che ho ATM sta eseguendo psql \df+e output grepping, ma preferirei una soluzione più simile a un database, cioè usando lo schema informativo. Questo sarà sicuramente un compito ripetitivo e mi piacerebbe averlo bello e pulito.

Eventuali suggerimenti?

Risposte:


18

Il corpo di una funzione è semplicemente memorizzato come stringa . Non esiste un elenco di oggetti referenziati. (Diverso dalle visualizzazioni, ad esempio, in cui vengono salvati i collegamenti effettivi alle tabelle referenziate.)

Questa query per Postgres 10 o precedenti utilizza la funzione di informazioni del catalogo di sistemapg_get_functiondef() per ricostruire lo CREATE FUNCTIONscript per funzioni pertinenti e cerca il nome della tabella con un'espressione regolare senza distinzione tra maiuscole e minuscole:

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';

Dovrebbe fare il lavoro, ma ovviamente non è a prova di proiettile. Può non riuscire per SQL dinamico in cui il nome della tabella viene generato in modo dinamico e può restituire un numero qualsiasi di falsi positivi, soprattutto se il nome della tabella è una parola comune.

Sono escluse le funzioni aggregate e tutte le funzioni dagli schemi di sistema.

\me\M segna l'inizio e la fine di una parola nell'espressione regolare.

Il catalogo di sistema pg_procmodificato in Postgres 11. è proisaggstato sostituito da prokind, sono state aggiunte vere procedure memorizzate. Devi adattarti. Relazionato:


1
Sì ... non è del tutto robusto, nel senso che non troverà EXECUTEespressioni simili 'mm_'||name_parameter, e non affronterà correttamente i nomi tra virgolette "my""table""o con la piegatura delle maiuscole, ma farà la maggior parte di ciò che la maggior parte delle persone vorrà .
Craig Ringer,

@CraigRinger: Sì, le query dinamiche con EXECUTEsono quasi impossibili da coprire. Ma la piegatura delle maiuscole può essere coperta ~*invece di ~- o qualsiasi altra corrispondenza di pattern insensibile alle maiuscole.
Erwin Brandstetter,

Finché l'operatore non è abbastanza pazzo da creare effettivamente tabelle con nome "MyTable"e MyTable, almeno ... e onestamente, è una mossa "beh, che potrebbe essere consentita ma non intelligente".
Craig Ringer,

Grazie per la risposta! In realtà non uso la costruzione dinamica di nomi di tabelle da nessuna parte e tutti i nomi di tabelle sono minuscoli.
Sergey Kudriavtsev, il

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.