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_id
yang merupakan Case/When
pernyataan 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_err
fungsi tersebut. Yang saya pikir dibangun untuk postgres (saya bisa SELECT raise_err('Hello, World');
). Apakah ini mungkin? Apakah ini CASE
pernyataan saya karena saya hanya perlu mengembalikan Boolean? Semua izin tampak benar dan memulihkan dengan cadangan sebelumnya berfungsi dengan baik.
Jawaban
Masalahnya adalah raise_err
skema yang tidak memenuhi syarat dalam kode fungsi Anda.
Ini berpotensi berbahaya: pengguna yang berniat jahat dapat membuat fungsinya sendiri raise_err
dan menyetel search_path
agar fungsi yang salah dipanggil.
Karena pg_restore
biasanya dijalankan oleh superuser, ini bisa menjadi masalah keamanan. Bayangkan fungsi seperti itu digunakan dalam definisi indeks!
Untuk alasan ini pg_dump
dan pg_restore
kosongkan search_path
di 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;