Errore pg_restore: la funzione raise_err (sconosciuto) non esiste

Aug 21 2020

Eseguo un backup giornaliero del mio database utilizzando pg_dump e pg_restore che di recente hanno smesso di funzionare dopo aver inviato un aggiornamento.

Ho una funzione validate_idche è una Case/Whendichiarazione proprio come un controllo rapido per alcuni dati che presentano problemi di integrità. Assomiglia a questo:

CREATE OR REPLACE FUNCTION validate_id(
    _string text,
    _type type
) RETURNS boolean AS
$$ SELECT CASE WHEN (stuff) THEN TRUE WHEN (other stuff) THEN TRUE When (more stuff) THEN raise_err('Not an accepted type, the accepted types are: x y z') ELSE FALSE $$
LANGUAGE SQL;

Da quando ho aggiunto questa funzione, quando eseguo il dump usando questo comando:

pg_dump -U postgres -h ipaddress -p 5432 -w -F t databaseName > backupsfolder/databaseName.tar

Quando uso questo comando:

pg_restore -U postgres -h localhost -p 5432 -d postgres -C "backupsfolder/databaseName.tar"

Fino a due giorni fa, questo ora genera un errore:

pg_restore: error: could not execute query: ERROR: function raise_err(unknown) does not exist

Sono abbastanza perso su cosa fare. Penso che quello che potrebbe succedere è che sta cercando di ripristinare questa funzione prima che ripristini la raise_errfunzione. Che pensavo fosse integrato in postgres (posso SELECT raise_err('Hello, World');). È possibile? È la mia CASEdichiarazione perché devo restituire solo valori booleani? Tutte le autorizzazioni sembrano corrette e il ripristino con i backup precedenti funziona correttamente.

Risposte

1 LaurenzAlbe Aug 21 2020 at 14:26

Il problema è che raise_errnon è qualificato come schema nel codice della funzione.

Questo è potenzialmente pericoloso: un utente malintenzionato potrebbe creare la propria funzione raise_erre impostare in search_pathmodo che venga chiamata la funzione sbagliata.

Poiché pg_restoreè tipicamente gestito da un superutente, questo può essere un problema di sicurezza. Immagina che una tale funzione venga utilizzata in una definizione di indice!

Per questi motivi pg_dumpe pg_restoreimpostare un vuoto search_pathnelle versioni correnti di PostgreSQL.

La soluzione al tuo problema è utilizzare esplicitamente lo schema della funzione nella tua istruzione SQL.

HelpMeExitVim Aug 26 2020 at 02:42

Ho finito per risolvere questo problema impostando esplicitamente i percorsi di ricerca per entrambe le funzioni raise_err()e validate_id()per public:

ALTER FUNCTION validate_id(text,text) SET search_path=public;
ALTER FUNCTION raise_err(text,text) SET search_path=public;