2017-06-07 18 views
2

当我定义一个函数像这样:公共架构,则不在安全定义器功能的SEARCH_PATH定义,但它仍然是可以访问

create or replace function test_func_a() 
returns table(search_path name[], public_func_result text) as $$ 
    select current_schemas('true'), trim(' does it work '); 
$$ language sql stable security definer set search_path = pg_temp; 
select test_func_a(); 
       test_func_a     
------------------------------------------- 
("{pg_catalog,pg_temp_2}","does it work") 

为什么我仍然可以使用的功能在公共模式如修剪或current_schemas为此事?不应该只有在明确使用public.trim()时才有效?

我创建的模式中的函数不能以相同的方式工作。在这个例子中,我尝试使用在UTIL模式的功能,而不在SEARCH_PATH设置它:

create or replace function test_func_b() 
returns table(search_path name[], public_func_result text) as $$ 
    select current_schemas('true'), trim_whitespace(' does it work '); 
$$ language sql stable security definer set search_path = pg_temp; 
ERROR: function trim_whitespace(unknown) does not exist 
LINE 3: select current_schemas('true'), trim_whitespace(' does it ... 
             ^
HINT: No function matches the given name and argument types. You might need 
to add explicit type casts. 

之外的功能,我SEARCH_PATH设置为这样:

select current_schemas('true'); 
         current_schemas      
------------------------------------------------------------ 
{pg_temp_2,pg_catalog,public,util} 

回答

0

看你public架构内。你看到TRIM吗? current_schemas?不,他们不在那里。对此有https://www.postgresql.org/docs/current/static/ddl-schemas.html

在公共模式的读取:

默认情况下[...]表(以及其他对象)都自动投入 一个名为“公共”的模式。每个新的数据库都包含这样的模式。 [...]除了 默认存在以外,公共模式没有什么特别之处。它也可以被丢弃。

那么如何解决current_schemas

除了公众和用户创建的模式,每个数据库包含 一个pg_catalog模式,它包含系统表和内置数据类型,函数,和运营商的所有 。 pg_catalog始终是 有效的搜索路径的一部分。如果未在 中明确指定该路径,则在搜索路径的 模式之前隐式搜索该路径。这确保内置名称总是可找到的。 但是,如果您希望让用户定义的名称覆盖内置名称,则可以明确地将pg_catalog放在搜索末尾 路径的末尾。

看一看里面pg_catalog(在pgAdmin的Catalogs下),current_schemas是在功能列表存在。

而且内置函数TRIM是PG识别关键字,看到https://www.postgresql.org/docs/current/static/sql-keywords-appendix.html

+0

谢谢你的解释!我想我应该检查一下pg_catalog,考虑到它正在我的current_schemas中被返回......将头撞到墙上的奥秘。 – dusterdb88

相关问题