出于测试目的,我提供了自己now()
函数的实现,即public.now()
。使用search_path
覆盖我自己版本的默认pg_catalog.now()
大部分都有效,但我有一个表格,其表格的默认表达式为now()
。显示该表会产生类似于以下内容的内容:
start_date | date | not null default now()
但是,在架构保存和恢复(到测试数据库)之后,同一个show table会生成
start_date | date | not null default pg_catalog.now()
我假设,最初默认表达式中的函数没有绑定到任何模式,search_path将用于查找正确的模式。但是,转储或恢复操作似乎"绑定"当前的功能。
我对"绑定状态的理解"功能正确吗? 有没有办法在转储/恢复边界之间保持函数的非绑定性?
答案 0 :(得分:2)
在创建时解析默认值(早期绑定!)。您在psql,pgAdmin或其他客户端中看到的是文本表示,但实际上,在创建列默认值时,函数OID
的{{1}}存储在系统目录{{3 }}。我引用:
now()
当您更改pg_attrdef
时,会导致Postgres显示符合模式的函数的名称,因为使用当前adbin pg_node_tree The internal representation of the column default value
adsrc text A human-readable representation of the default value
无法正确解析它。
转储和恢复与您的自定义search_path
设置无关。他们明确地设定了它。所以你看到的与转储/恢复周期无关。
在search_path
public
之前放置pg_catalog
是危险游戏。弱势用户(包括你自己)经常被允许在那里写作并创建可能无意中否决系统功能的功能 - 具有任意(或恶意)结果。
您希望专用架构具有受限访问权限来覆盖内置函数。请改用这样的东西:
search_path
此search_path
中的详细信息。
答案 1 :(得分:2)
默认功能是"绑定"在创建默认约束时。显示不合格名称的视图只是缩写它。
这可以通过在遮蔽函数之前和之后插入行来证明:
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
如果绑定仅发生在插入上,则不存在此类依赖关系。
答案 2 :(得分:-3)
而且:now()和pg_catalog.now()通常是一样的。参见:
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';
不要担心。