我创建了两个Postgres数据库。版本9.5.4。第一个数据库称为持久性。我正在使用PostGrest的一些示例代码进行身份验证。该代码效果很好,这是我的持久数据库定义:
create schema localschema;
grant all on schema localschema to postgres;
create table localschema.users (
email text primary key check ( email ~* '^.+@.+..+$' ),
pass text not null check (length(pass) < 512),
role name not null check (length(role) < 512),
verified boolean not null default false
-- If you like add more columns, or a json column
);
create or replace function
localschema.encrypt_pass() returns trigger
language plpgsql
as $$
declare
mvar text;
begin
if tg_op = 'INSERT' or new.pass <> old.pass then
new.pass = crypt(new.pass, gen_salt('bf'::text));
end if;
return new;
end
$$;
drop trigger if exists encrypt_pass on localschema.users;
create trigger encrypt_pass
before insert or update on localschema.users
for each row
execute procedure localschema.encrypt_pass();
相当简单,在这里我将插入件插入表,然后选择一个选择,您可以看到通过触发/函数cencrypt_pass crypter的通行证使用:
persist=# insert into localschema.users values('g@l.com','123123','postgres');
persist=# select * from localschema.users;
email | pass | role | verified
---------+--------------------------------------------------------------+----------+----------
g@l.com | $2a$06$5p5eM6sJAfxZ4qSv0Jgx..GlflYkNeE7aY.D4kR9K0glRZv2wU7ue | postgres | f
(1 row)
效果很好。下一步是postgres_fdw,我将外国架构导入远程数据库中的其他数据库:
CREATE EXTENSION IF NOT EXISTS "postgres_fdw";
create server self foreign data wrapper postgres_fdw options(host '127.0.0.1', dbname 'persist', port '5432');
create user mapping for postgres server self options (user 'postgres');
create schema "localschema";
grant all on schema localschema to postgres;
import foreign schema localschema from server self into "localschema" options ( import_default 'true');
然后选择证明它正在工作:
cache=# select * from localschema.users;
email | pass | role | verified
---------+--------------------------------------------------------------+----------+----------
g@l.com | $2a$06$5p5eM6sJAfxZ4qSv0Jgx..GlflYkNeE7aY.D4kR9K0glRZv2wU7ue | postgres | f
(1 row)
问题是我无法将其插入此表中。这是行动中的错误:
cache=# insert into localschema.users values ('f@l.com','234234','postgres');
ERROR: function gen_salt(text) does not exist
HINT: No function matches the given name and argument types. You might need to add explicit type casts.
CONTEXT: Remote SQL command: INSERT INTO localschema.users(email, pass, role, verified) VALUES ($1, $2, $3, $4)
PL/pgSQL function localschema.encrypt_pass() line 6 at assignment
这很奇怪,找不到任何功能,而不仅仅是gen_salt。我已经在持久的一边放了一些加薪的异常语句,以验证我的当前_user确实是邮政。那么,当我通过postgres_fdw执行时,为什么我的所有功能都会消失?
我想念什么?我很确定我已经有工作了,但是在我所有的设置/拆除中,我以某种方式失去了适当的咒语。
这个答案最初是在问题本身内发布的:
我终于在发布此问题后立即弄清楚了这个问题。ang。从postgres_fdw手册postgres-fdw:
在postgres_fdw打开的远程会话中,search_path参数仅设置为pg_catalog,因此只有内置对象是无模式资格可见。这不是查询的问题由postgres_fdw本身生成,因为它总是提供这样的资格。但是,这可能会对功能构成危险通过触发器或远程表上的规则在远程服务器上执行。例如,如果远程表实际上是一个视图,则使用的任何功能在此视图中,将使用受限的搜索路径执行。这是推荐将这些功能中的所有名称合格验证,否则附加SET SEER SERCH_PATH选项(请参阅创建功能)到此类功能建立他们预期的搜索路径环境。
我更改了功能,以便它使用完整的路径到达所谓的内容:
create or replace function
localschema.encrypt_pass() returns trigger
language plpgsql
as $$
declare
mvar text;
begin
if tg_op = 'INSERT' or new.pass <> old.pass then
new.pass = public.crypt(new.pass, public.gen_salt('bf'::text));
end if;
return new;
end
$$;