Errore pg_restore: la funzione raise_err (sconosciuto) non esiste
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_id
che è una Case/When
dichiarazione 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_err
funzione. Che pensavo fosse integrato in postgres (posso SELECT raise_err('Hello, World');
). È possibile? È la mia CASE
dichiarazione perché devo restituire solo valori booleani? Tutte le autorizzazioni sembrano corrette e il ripristino con i backup precedenti funziona correttamente.
Risposte
Il problema è che raise_err
non è qualificato come schema nel codice della funzione.
Questo è potenzialmente pericoloso: un utente malintenzionato potrebbe creare la propria funzione raise_err
e impostare in search_path
modo 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_dump
e pg_restore
impostare un vuoto search_path
nelle versioni correnti di PostgreSQL.
La soluzione al tuo problema è utilizzare esplicitamente lo schema della funzione nella tua istruzione SQL.
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;