Postgres 中的“转换表”是什么?

Bas*_*que 15 postgresql trigger table postgresql-10

描述Postgres 10 新功能的页面提到了“触发器的转换表”。

触发器的转换表

此功能AFTER STATEMENT通过适当地向查询公开旧行和新行,使触发器既实用又高效。在此功能之前,AFTER STATEMENT触发器无法直接访问这些,并且变通方法是拜占庭式的并且性能很差。现在可以将许多触发器逻辑编写为AFTER STATEMENT,从而避免需要在 FOR EACH ROW 触发器所需的每一行进行昂贵的上下文切换。

什么是过渡表?

Cra*_*ger 13

你知道触发器是如何存在OLDNEW记录变量的FOR EACH ROW吗?

转换表是FOR EACH STATEMENT等效的。它们是包含旧元组和新元组的表,因此您的触发器可以看到发生了什么变化。


Eva*_*oll 11

我真的很喜欢 Craig 对这个功能的解释。SQL-2011 规范在触发器的上下文中将它们定义为“被删除、插入或替换的行的集合称为转换表”。一个类似的解释是在文档提供,

虽然AFTER触发器的转换表REFERENCING是以标准方式使用子句指定的,但触发器中使用的行变量FOR EACH ROW可能不会在REFERENCING子句中指定。它们的可用方式取决于编写触发函数的语言。某些语言有效地表现得好像有一个REFERENCING子句包含OLD ROW AS OLD NEW ROW AS NEW.

本质上,它们使您可以使用整个语句的更改,这非常方便。作为参考,创建触发器上的 DDL 与转换表类似

REFERENCING OLD TABLE AS oldtable NEW TABLE AS newtable
Run Code Online (Sandbox Code Playgroud)

你可以在这里看到一个例子,这里是测试套件中的一个

CREATE TABLE transition_table_base (id int PRIMARY KEY, val text);

CREATE FUNCTION transition_table_base_ins_func()
  RETURNS trigger
  LANGUAGE plpgsql
AS $$
DECLARE
  t text;
  l text;
BEGIN
  t = '';
  FOR l IN EXECUTE
           $q$
             EXPLAIN (TIMING off, COSTS off, VERBOSE on)
             SELECT * FROM newtable
           $q$ LOOP
    t = t || l || E'\n';
  END LOOP;

  RAISE INFO '%', t;
  RETURN new;
END;
$$;

CREATE TRIGGER transition_table_base_ins_trig
  AFTER INSERT ON transition_table_base
  REFERENCING OLD TABLE AS oldtable NEW TABLE AS newtable
  FOR EACH STATEMENT
  EXECUTE PROCEDURE transition_table_base_ins_func();
Run Code Online (Sandbox Code Playgroud)

一些附加说明

  1. 它们仅在AFTER触发器上可用。
  2. 他们考虑到诸如ON CONFLICT.

重要的是要指出它并不完全确定在 PG 10 中可用转换表有很多未解决的问题。大多数都有补丁。有一些内讧,这是一种例行公事。看来这个重担是被别人挑起来的。该线程表明我们很快就会知道。

作者回应-似乎又要顺利了。