pg_restore error: function raise_err (tidak diketahui) tidak ada
Saya menjalankan backup harian database saya menggunakan pg_dump dan pg_restore yang baru-baru ini berhenti berfungsi setelah saya mendorong pembaruan.
Saya memiliki fungsi validate_idyang merupakan Case/Whenpernyataan hanya sebagai pemeriksaan cepat untuk beberapa data yang memiliki masalah integritas. Tampak seperti ini:
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;
Sejak saya menambahkan fungsi ini, ketika saya membuang menggunakan perintah ini:
pg_dump -U postgres -h ipaddress -p 5432 -w -F t databaseName > backupsfolder/databaseName.tar
Ketika saya menggunakan perintah ini:
pg_restore -U postgres -h localhost -p 5432 -d postgres -C "backupsfolder/databaseName.tar"
Pada dua hari yang lalu, ini sekarang memunculkan kesalahan:
pg_restore: error: could not execute query: ERROR: function raise_err(unknown) does not exist
Aku sangat bingung harus berbuat apa. Saya pikir apa yang mungkin terjadi adalah mencoba mengembalikan fungsi ini sebelum mengembalikan raise_errfungsi tersebut. Yang saya pikir dibangun untuk postgres (saya bisa SELECT raise_err('Hello, World');). Apakah ini mungkin? Apakah ini CASEpernyataan saya karena saya hanya perlu mengembalikan Boolean? Semua izin tampak benar dan memulihkan dengan cadangan sebelumnya berfungsi dengan baik.
Jawaban
Masalahnya adalah raise_errskema yang tidak memenuhi syarat dalam kode fungsi Anda.
Ini berpotensi berbahaya: pengguna yang berniat jahat dapat membuat fungsinya sendiri raise_errdan menyetel search_pathagar fungsi yang salah dipanggil.
Karena pg_restorebiasanya dijalankan oleh superuser, ini bisa menjadi masalah keamanan. Bayangkan fungsi seperti itu digunakan dalam definisi indeks!
Untuk alasan ini pg_dumpdan pg_restorekosongkan search_pathdi versi PostgreSQL saat ini.
Solusi untuk masalah Anda adalah dengan menggunakan skema fungsi secara eksplisit dalam pernyataan SQL Anda.
Saya akhirnya menyelesaikan masalah ini dengan secara eksplisit mengatur jalur pencarian untuk kedua fungsi, raise_err()dan validate_id()ke public:
ALTER FUNCTION validate_id(text,text) SET search_path=public;
ALTER FUNCTION raise_err(text,text) SET search_path=public;