Prz*_*mek 5 postgresql postgresql-9.6
我有一个存储过程,它在其主体中使用一个临时表。尝试使用此过程创建物化视图,例如
CREATE MATERIALIZED VIEW my_view AS SELECT * FROM my_function;
Run Code Online (Sandbox Code Playgroud)
给我一个错误:
ERROR: cannot create temporary table within security-restricted operation
Run Code Online (Sandbox Code Playgroud)
它在源代码的注释中进行了解释:
/*
* Security check: disallow creating temp tables from security-restricted
* code. This is needed because calling code might not expect untrusted
* tables to appear in pg_temp at the front of its search path.
*/
Run Code Online (Sandbox Code Playgroud)
除了重新处理存储过程本身以不使用临时表之外,还有其他解决方法吗?
此限制背后的想法是防止刷新物化视图后会话状态的更改。这实际上在您从源代码中添加的注释中进行了解释(尽管它可能会令人困惑)。
换句话说,这意味着即使已存在同名的常规表,查询也可能会选取一个新的临时表(您可以在函数中创建)。查找表时pg_temp隐式添加架构SEARCH PATH。
我能想到的解决方法有两种:
UNLOGGED以获得更好的性能。示例代码:
CREATE FUNCTION my_function()
RETURNS BOOLEAN
LANGUAGE 'plpgsql'
AS '
BEGIN
DROP TABLE IF EXISTS my_tmp_table;
CREATE UNLOGGED TABLE my_tmp_table(a int); -- regular unlogged table
RETURN TRUE;
END';
CREATE MATERIALIZED VIEW my_view AS SELECT * FROM my_function(); -- materialized view
Run Code Online (Sandbox Code Playgroud)
示例代码:
CREATE FUNCTION my_function()
RETURNS BOOLEAN
LANGUAGE 'plpgsql'
AS '
BEGIN
DROP TABLE IF EXISTS my_tmp_table;
CREATE TEMP TABLE my_tmp_table(a int); -- temp table
RETURN TRUE;
END';
CREATE TABLE my_view AS SELECT * FROM my_function(); -- table, not a view
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1756 次 |
| 最近记录: |