Error de pg_restore: la función raise_err (desconocida) no existe
Ejecuto una copia de seguridad diaria de mi base de datos usando pg_dump y pg_restore que recientemente dejaron de funcionar después de presionar una actualización.
Tengo una función validate_id
que es una Case/When
declaración solo como una verificación rápida de algunos datos que tienen problemas de integridad. Se parece a esto:
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;
Desde que agregué esta función, cuando vuelco usando este comando:
pg_dump -U postgres -h ipaddress -p 5432 -w -F t databaseName > backupsfolder/databaseName.tar
Cuando uso este comando:
pg_restore -U postgres -h localhost -p 5432 -d postgres -C "backupsfolder/databaseName.tar"
Hace dos días, esto ahora arroja un error:
pg_restore: error: could not execute query: ERROR: function raise_err(unknown) does not exist
Estoy bastante perdido sobre qué hacer. Creo que lo que podría estar sucediendo es que está tratando de restaurar esta función antes de restaurar la raise_err
función. Lo que pensé que estaba integrado en postgres (puedo SELECT raise_err('Hello, World');
). es posible? ¿Es mi CASE
declaración porque necesito devolver solo booleanos? Todos los permisos parecen correctos y la restauración con copias de seguridad anteriores funciona bien.
Respuestas
El problema es que raise_err
no está calificado por esquema en su código de función.
Esto es potencialmente peligroso: un usuario malintencionado podría crear su propia función raise_err
y configurarla search_path
para que se llame a la función incorrecta.
Dado pg_restore
que normalmente lo ejecuta un superusuario, esto puede ser un problema de seguridad. ¡Imagínese que se utiliza una función de este tipo en una definición de índice!
Por estas razones pg_dump
y pg_restore
establezca un vacío search_path
en las versiones actuales de PostgreSQL.
La solución a su problema es utilizar explícitamente el esquema de la función en su declaración SQL.
Terminé resolviendo este problema estableciendo explícitamente las rutas de búsqueda para ambas funciones raise_err()
y validate_id()
para public
:
ALTER FUNCTION validate_id(text,text) SET search_path=public;
ALTER FUNCTION raise_err(text,text) SET search_path=public;