从 PostgreSQL 服务器版本 9 迁移到8.4后,我遇到了非常奇怪的错误。
简短描述:如果在插入或更新之前
对给定表的每一行都有触发器,并且在条件语句(if-else)TG_OP 值检查和OLD对象中使用,则在执行INSERT时会引发以下错误:
ERROR: record "old" is not assigned yet
DETAIL: The tuple structure of a not-yet-assigned record is indeterminate.
详细描述:
有以下DB结构:
CREATE TABLE table1
(
id serial NOT NULL,
name character varying(256),
CONSTRAINT table1_pkey PRIMARY KEY (id)
)
WITH (OIDS=FALSE);
CREATE OR REPLACE FUNCTION exemplary_function()
RETURNS trigger AS
$BODY$ BEGIN
IF TG_OP = 'INSERT' OR OLD.name <> NEW.name THEN
NEW.name = 'someName';
END IF;
RETURN NEW;
END;
$BODY$
LANGUAGE plpgsql VOLATILE COST 100;
CREATE TRIGGER trigger1
BEFORE INSERT OR UPDATE
ON table1
FOR EACH ROW EXECUTE PROCEDURE exemplary_function();
并遵循触发错误的 SQL 查询:
INSERT INTO table1 (name) VALUES ('other name')
似乎解析器没有按TG_OP = 'INSERT'
条件停止(它应该,因为它是真的)而是检查另一个并触发错误。有趣的是,我只能在 8.4 版上重现它。