文档 / SQL 状态码 / Class 39 外部例程调用异常
39P01 trigger_protocol_violated
ERROR 源码确认 参考 未实测
- 条件名
trigger_protocol_violated- 宏名称
ERRCODE_E_R_I_E_TRIGGER_PROTOCOL_VIOLATED- 启用版本
- 7.4
- 状态
- 活跃
版本覆盖
速览
39P01 是 trigger_protocol_violated。固定源码确认它同时出现在核心 trigger manager、contrib/tcn 以及 PL/Perl trigger 返回值检查中,消息和严重级别取决于具体路径。
含义
这是 trigger 调用契约不成立:核心管理器可能报告 trigger function %u returned null value 或 BEFORE STATEMENT trigger cannot return a value;tcn 函数在错误的 timing/level/参数条件下被调用,或表没有主键;PL/Perl DELETE trigger 的修改可能被 WARNING 忽略,非法返回值则是 ERROR。
报文模板
源码里的格式串,不是某一次运行的输出。%s 之类是占位符,实际报文会填入对象名与取值。适用范围一栏是核验时留下的原始英文记录,未经翻译。
trigger function %u returned null value
BEFORE STATEMENT trigger cannot return a value
triggered_change_notification: must be called as trigger
triggered_change_notification: must be called after the change
triggered_change_notification: must be called for each row
triggered_change_notification: must not be called with more than one parameter
triggered_change_notification: must be called on a table with a primary key
ignoring modified row in DELETE trigger
result of PL/Perl trigger function must be undef, "SKIP", or "MODIFY"
诊断
先按 message 区分来源:核心管理器检查 isnull 标志和 BEFORE STATEMENT 返回契约;tcn 要核对 AFTER、FOR EACH ROW、参数个数和主键;PL/Perl 要核对返回是否为 undef、SKIP 或 MODIFY。DELETE 修改被忽略的报文是 WARNING,非法返回报文是 ERROR;不要把所有 39P01 都归为同一个 trigger 类型。
处置
修正 trigger 的 timing、level、事件、参数和返回值契约;对 tcn 还要核对表主键和调用顺序。PL/Perl 的 WARNING 表示 DELETE 行修改被忽略,非法返回值则使调用失败;先确认原操作是否完成和业务是否接受该结果,再决定后续写入。修复契约后才重新执行。
版本
锁定目录从 7.4 记录该条件,并在正式快照及 19beta3 中出现;源码路径取 PostgreSQL 18.6。
来源
- 上游源码 src/backend/utils/errcodes.txt 第 311 行
- 上游源码 src/pl/plperl/plperl.c 第 2607–2618 行
- 上游源码 contrib/tcn/tcn.c 第 77–110 行
- 上游源码 src/backend/commands/trigger.c 第 2388–2394 行
- 核验材料 raw/calls/REL_18_6.jsonl
证据
断言
每条断言都写明了是怎么核实的,以及它不覆盖什么。这一层是核验时留下的原始英文记录,照原样呈现,未经翻译。
-
39P01 is trigger_protocol_violated in Class 39.
-
The core trigger manager reports this code when a trigger function sets the isnull flag, and for invalid BEFORE STATEMENT return values.
-
contrib/tcn checks trigger invocation context, AFTER timing, row level, argument count, and primary-key setup with this code.
-
PL/Perl has a WARNING variant for an ignored DELETE-row modification and an ERROR variant for an invalid trigger return value.
同类 SQL 状态码
| 状态码 | 条件名 | 宏名称 | 严重等级 | 版本 |
|---|---|---|---|---|
| 39000 | external_routine_invocation_exception | ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION |
ERROR | 7.4 |
| 外部例程调用异常,如 pgcrypto 的库失败。 | 活跃 | |||
| 39001 | invalid_sqlstate_returned | ERRCODE_E_R_I_E_INVALID_SQLSTATE_RETURNED |
ERROR | 7.4 |
| 外部例程返回了无效的 SQLSTATE。 | 活跃 | |||
| 39004 | null_value_not_allowed | ERRCODE_E_R_I_E_NULL_VALUE_NOT_ALLOWED |
ERROR | 7.4 |
| 外部例程调用中不允许出现 NULL 值。 | 活跃 | |||
| 39P01 | trigger_protocol_violated | ERRCODE_E_R_I_E_TRIGGER_PROTOCOL_VIOLATED |
ERROR | 7.4 |
| 触发器违反了返回值或调用协议。 | 活跃 | |||
| 39P02 | srf_protocol_violated | ERRCODE_E_R_I_E_SRF_PROTOCOL_VIOLATED |
ERROR | 7.4 |
| 集合返回函数违反了 SRF 调用协议。 | 活跃 | |||
| 39P03 | event_trigger_protocol_violated | ERRCODE_E_R_I_E_EVENT_TRIGGER_PROTOCOL_VIOLATED |
ERROR | 9.5 |
| 事件触发器辅助函数在错误的事件上下文调用。 | 活跃 | |||