what is NamedTupleStore?

What

NamedTuplestore 按字面意思理解,就是一个有名字的 tuplestore, 那估计就不是一个正常的表。根据 PostgreSQL 的官方叫法,NamedTuplestoreScan 对应的表称为 Ephemeral Named Relation, 中文翻译为 短暂的命名关系.

When

在使用触发器的时候会使用到该特性

How

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;
$$;

-- `AFTER INSERT` and `STATEMENT` trigger
CREATE TRIGGER transition_table_base_ins_trig
  AFTER INSERT ON transition_table_base
  REFERENCING NEW TABLE AS newtable
  FOR EACH STATEMENT
  EXECUTE PROCEDURE transition_table_base_ins_func();

上面的 SQL 和 NamedTuplestore 关联的是 REFERENCING NEW TABLE AS newtable. newtable 表在触发器函数中被使用。与之关联的还有 OLD TABLE as oldtable, 但本例中使用的是 AFTER INSERT, 因 PG 限制,不能使用。

可以通过下面这条 SQL 查看表关联的触发器,

select * from pg_trigger where tgrelid = 'transition_table_base'::regclass::oid \gx

对于其他触发器类型也是可以的,

-- 先删除已有的触发器
drop trigger transition_table_base_ins_trig on transition_table_base;

-- `AFTER UPDATE` and `FOR EACH ROW` trigger
CREATE TRIGGER transition_table_base_ins_trig_row
  AFTER UPDATE ON transition_table_base
  REFERENCING OLD TABLE AS oldtable NEW TABLE AS newtable
  FOR EACH ROW
  EXECUTE PROCEDURE transition_table_base_ins_func();

上面新的触发器就可以使用 REFERENCING OLD TABLE AS oldtable NEW TABLE AS newtable.

Debug

可以将断点设置在 make_namedtuplestorescan 函数中判断是否会生成 NamedTuplestoreScan.

posted on 2024-07-08 09:51  winter-loo  阅读(7)  评论(0编辑  收藏  举报

导航