kesalahan pg_restore: fungsi raise_err (tidak diketahui) tidak ada

Saya menjalankan pencadangan 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 pernyataan Case/When hanya sebagai pemeriksaan cepat untuk beberapa data yang memiliki masalah integritas. Terlihat 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"

Sejak dua hari yang lalu, sekarang terjadi kesalahan:

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

Saya sangat bingung harus berbuat apa. Saya rasa yang mungkin terjadi adalah ia mencoba memulihkan fungsi ini sebelum memulihkan fungsi raise_err. Yang menurut saya sudah ada di dalam postgres (saya bisa SELECT raise_err('Hello, World');). Apakah ini mungkin? Apakah ini pernyataan CASE saya karena saya hanya perlu mengembalikan Boolean? Semua izin tampak benar dan pemulihan dengan cadangan sebelumnya berfungsi dengan baik.


person HelpMeExitVim    schedule 20.08.2020    source sumber
comment
Masuk ke database sumber Anda dengan psql, dan lakukan \df+ raise_err. Sejauh yang saya tahu, itu bukan fungsi standar. Anda tidak memerlukan fungsi lain untuk memunculkan kesalahan karena Anda cukup melakukan raise error   -  person Mike Organek    schedule 21.08.2020
comment
Apakah itu berfungsi dalam fungsi yang ditulis dalam sql atau harus plpgsql?   -  person HelpMeExitVim    schedule 21.08.2020
comment
\df+ raise_err tidak...mengembalikan fungsinya. Ini bukanlah sesuatu yang saya ingat secara eksplisit dibuatnya, tetapi maksud saya, banyak hal terjadi.   -  person HelpMeExitVim    schedule 21.08.2020
comment
Maaf aku tidak memikirkan hal itu. language sql tidak akan mendukungnya, dan itu mungkin menjelaskan mengapa Anda menulisnya sebagai sebuah fungsi. Juga, ini raise exception, bukan raise error seperti yang saya katakan secara keliru di komentar saya sebelumnya. Sepertinya hal ini terkadang terjadi: stackoverflow.com/q/30707533/13808319   -  person Mike Organek    schedule 21.08.2020
comment
Luar biasa! Ini dia, aku merasa sangat bodoh. Terima kasih untuk bantuannya!   -  person HelpMeExitVim    schedule 21.08.2020
comment
Apakah Anda menggunakan ini sebagai fungsi CHECK? Jika demikian, itu adalah createtable yang tidak-tidak: Saat ini, CHECK ekspresi tidak boleh memuat subkueri atau merujuk ke variabel selain kolom pada baris saat ini (lihat Bagian 5.4.1). Tabeloid kolom sistem dapat direferensikan, tetapi tidak pada kolom sistem lainnya.   -  person Adrian Klaver    schedule 21.08.2020
comment
Jangan merasa bodoh, membuat fungsi itu masuk akal IMO. Saya menduga fakta bahwa ini adalah fungsi language sql mengacaukan upaya algo untuk menemukan dependensi selama pg_backup.   -  person Mike Organek    schedule 21.08.2020


Jawaban (2)


Masalahnya adalah raise_err skema tidak memenuhi syarat dalam kode fungsi Anda.

Hal ini berpotensi berbahaya: pengguna jahat dapat membuat fungsinya sendiri raise_err dan menyetel search_path sehingga fungsi yang salah dipanggil.

Karena pg_restore biasanya dijalankan oleh pengguna super, ini bisa menjadi masalah keamanan. Bayangkan fungsi seperti itu digunakan dalam definisi indeks!

Karena alasan ini pg_dump dan pg_restore menyetel search_path kosong di versi PostgreSQL saat ini.

Solusi untuk masalah Anda adalah dengan menggunakan skema fungsi secara eksplisit dalam pernyataan SQL Anda.

person Laurenz Albe    schedule 21.08.2020

Saya akhirnya memecahkan 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;
person HelpMeExitVim    schedule 25.08.2020