出于测试目的,我提供了我自己的 now() 功能是 public.now().使用 search_path 复盖默认值 pg_catalog.now() 与我自己的版本大多工作,但我有一个表与默认表达式的表 now().显示该表会产生类似于以下内容的内容:

 start_date   | date    | not null default now()

但是,在模式保存和还原(到测试数据库)后,会生成相同的显示表

 start_date   | date    | not null default pg_catalog.now()

我从中假设,最初默认表达式中的函数不绑定到任何模式,search_path将用于查找正确的模式。但是,转储或还原操作似乎将函数"绑定"到当前函数。

我对函数的"绑定状态"的理解是否正确?有没有办法保持跨转储/恢复边界的函数的未绑定性?

有帮助吗?

解决方案

默认值在创建时解析(早期绑定!).您在psql,pgAdmin或其他客户端中看到的是文本表示,但实际上, OID 的功能 now() 在创建列时,默认值存储在系统目录中 pg_attrdef.我引用:

adbin   pg_node_tree  The internal representation of the column default value
adsrc   text          A human-readable representation of the default value

当你改变 search_path, ,这会导致Postgres显示函数schema限定的名称,因为它不会被正确解析与当前 search_path.

转储和还原与您的自定义无关 search_path 设置。他们明确地设置了它。所以你看到的与转储/恢复周期无关。

复盖内置函数

配售 public 以前 pg_catalogsearch_path 是一个 危险游戏.弱势用户(包括你自己)通常被允许在那里编写并创建可能无意中复盖系统功能的函数-具有任意(或恶意)结果。

你想要一个 具有受限访问权限的专用架构 复盖内置函数。用这样的东西代替:

SET search_path = 复盖,pg_catalog, public;

详情请参阅 有关答案dba.SE.

其他提示

默认函数在创建默认约束时为"绑定"。显示非限定名称的视图只是缩写它。

这可以通过在阴影函数之前和之后插入行来证明:

Set search_path to public,pg_catalog;

Create Temp Table foo (
    test date not null default now()
);

Insert Into foo default values;

Create Function public.now() Returns timestamp with time zone Language SQL As $$ 
     -- No idea why I chose this date.
     Select '1942-05-09'::timestamp with time zone;
$$;

Insert Into foo default values;

Select * from foo;

请注意,两行(在函数创建之前和之后插入)都包含今天的日期,而不是假日期。

此外,创建一个具有上述函数的表已经在作用域中,然后尝试删除该函数,会导致依赖性错误:

Set search_path to public,pg_catalog;

Create Function public.now() Returns timestamp with time zone Language SQL As $$ 
    Select '1942-05-09'::timestamp with time zone;
$$;

Create Temp Table bar (
    test date not null default now()
);

Insert Into bar default values;

Select * from bar;
-- Single row containing the dummy date rather than today

Drop Function public.now();
-- ERROR:  cannot drop function now() because other objects depend on it

如果绑定只发生在insert上,则不会有这样的依赖关系。

别那么麻烦了。Postgres有时会在编译之后编写weired东西。特别是观点经常被改变超过认可。

和:now()和pg_catalog。现在()通常是一样的。见:

CREATE OR REPLACE FUNCTION now()
    RETURNS timestamp with time zone AS
'now'
    LANGUAGE internal STABLE STRICT
 COST 1;
 ALTER FUNCTION now()
    OWNER TO postgres;
 COMMENT ON FUNCTION now() IS 'current transaction time';

别担心。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top