为了进行测试,我提供了自己的now()函数实现public.now()。使用我自己的版本search_path覆盖默认值pg_catalog.now()通常可以,但是我有一个表,其表的默认表达式为now()。显示该表会产生类似于以下内容的信息:
now()
public.now()
search_path
pg_catalog.now()
start_date | date | not null default now()
但是,在保存和还原架构(到测试数据库)之后,将生成相同的show table
start_date | date | not null default pg_catalog.now()
我以此为前提,最初,默认表达式中的函数未绑定到任何模式,并且search_path将用于查找正确的函数。但是,转储或还原操作似乎将功能“绑定”到当前功能。
我对函数的“绑定状态”的理解正确吗?有没有办法在转储/还原边界之间保持函数的非绑定性?
默认值在创建时进行解析(早期绑定!)。你在psql里,pgAdmin的或其他客户看到的是一个文本表示,但事实上,该OID功能now()在创建列默认的时间存储在系统目录中pg_attrdef。我引用:
OID
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显示限定模式的函数的名称,因为使用current不能再正确解析该函数的名称search_path。
转储和还原与您的自定义search_path设置无关。他们明确地设置了它。因此,您所看到的与转储/还原周期无关。
配售public前pg_catalog的search_path是一个 危险的游戏 。特权不足的用户(包括您自己)通常被允许在此处编写和创建可能无意中否决系统功能的功能-结果是任意的(或恶意的)。
public
pg_catalog
您希望 具有受限访问权限 的 专用架构 覆盖内置函数。使用类似这样的东西:
SET search_path = **override, pg_catalog** , public;