是否记录了此临时表行为?

Jac*_*las 6 postgresql functions postgresql-9.3 temporary-tables

查询语言 (SQL) 和 PL/pgSQL 函数对临时表的处理方式不同:

begin;
create table foo(id) as values (1);
select * from foo;
/*
 id
----
  1
*/
savepoint s;
create function f() returns setof integer language sql as $$
  create temporary table foo(id) on commit drop as values (2);
  select id from foo;
$$;
select * from f();
/*
 f
---
 1
*/
rollback to s;
create function f() returns setof integer language plpgsql as $$
begin
  create temporary table foo(id) on commit drop as values (2);
  return query select id from foo;
end;
$$;
select * from f();
/*
 f
---
 2
*/
rollback;
Run Code Online (Sandbox Code Playgroud)

文档

...当临时表存在时,具有相同名称的现有永久表对当前会话不可见,除非它们被模式限定名称引用...

这并没有提到上面演示的异常。这在其他地方有记录吗?

Jac*_*las 4

这是因为在执行 SQL 函数时,会解析并执行整个函数体。但是用PLPGSQL函数逐条语句进行解析和执行。由于这个原因,SQL 函数无法看到函数执行期间创建的临时表。

换句话说,这适用于其他对象,而不仅仅是临时表。这也很容易证明:

begin;
--
create function pg_temp.f() returns integer language sql as $$select 1;$$;
create function g() returns integer language sql as $g$
  create or replace function pg_temp.f() returns integer language sql as $$select 2;$$;
  select pg_temp.f();
$g$;
--
select g();
/*
 g
---
 1
*/
select g();
/*
 g
---
 2
 */
--
rollback;
Run Code Online (Sandbox Code Playgroud)

甚至:

begin;
create schema stack;
set search_path to stack;
create temp table foo(id) on commit drop as values (1);
select * from foo;
/*
 id
----
  1
*/
savepoint s;
create function f() returns setof integer language sql set search_path = stack, pg_temp as $$
  create table foo(id) as values (2);
  select id from foo;
$$;
select * from f();
/*
 f
---
 1
*/
rollback to s;
create function f() returns setof integer language plpgsql set search_path = stack, pg_temp as $$
begin
  create table foo(id) as values (2);
  return query select id from foo;
end;
$$;
select * from f();
/*
 f
---
 2
*/
rollback;
Run Code Online (Sandbox Code Playgroud)

关于 pgsql-bugs 的建议是修改文档以明确此行为。


编辑:

显然已经提交了对文档的更改,但尚未在9.4 文档中显示