我有一个存储过程,该过程在其主体中使用一个临时表。尝试使用此过程创建实例化视图,例如
CREATE MATERIALIZED VIEW my_view AS SELECT * FROM my_function;
给我一个错误:
ERROR: cannot create temporary table within security-restricted operation
在源代码中的注释中对此进行了解释:
/*
* 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.
*/
除了重新整理存储过程本身不使用临时表之外,是否还有其他解决方法?
答案 0 :(得分:2)
此限制背后的思想是防止在刷新实例化视图后更改会话状态。实际上,您在源代码中添加的注释中对此进行了解释(尽管可能会造成混淆)。
换句话说,这意味着即使已经存在具有相同名称的常规表,查询也可能会选择一个新的临时表(可以在函数中创建)。查找表时,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
示例代码:
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