选择 打开 改范围 完整检索页

pgsql.cc 提供对 postgresql.org 官网内容的中文翻译,由 Pigsty 团队维护。

文档 / SQL 状态码 / Class 39 外部例程调用异常

39P01 trigger_protocol_violated

ERROR 源码确认 参考 未实测

类别
Class 39 外部例程调用异常
严重等级
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 valueBEFORE STATEMENT trigger cannot return a value;tcn 函数在错误的 timing/level/参数条件下被调用,或表没有主键;PL/Perl DELETE trigger 的修改可能被 WARNING 忽略,非法返回值则是 ERROR。

报文模板

源码里的格式串,不是某一次运行的输出。%s 之类是占位符,实际报文会填入对象名与取值。适用范围一栏是核验时留下的原始英文记录,未经翻译。

主消息 trigger function %u returned null value

来源:src/backend/commands/trigger.c @ REL_18_6

主消息 BEFORE STATEMENT trigger cannot return a value

来源:src/backend/commands/trigger.c @ REL_18_6

主消息 triggered_change_notification: must be called as trigger

来源:contrib/tcn/tcn.c @ REL_18_6

主消息 triggered_change_notification: must be called after the change

来源:contrib/tcn/tcn.c @ REL_18_6

主消息 triggered_change_notification: must be called for each row

来源:contrib/tcn/tcn.c @ REL_18_6

主消息 triggered_change_notification: must not be called with more than one parameter

来源:contrib/tcn/tcn.c @ REL_18_6

主消息 triggered_change_notification: must be called on a table with a primary key

来源:contrib/tcn/tcn.c @ REL_18_6

主消息 ignoring modified row in DELETE trigger

来源:src/pl/plperl/plperl.c @ REL_18_6

主消息 result of PL/Perl trigger function must be undef, "SKIP", or "MODIFY"

来源:src/pl/plperl/plperl.c @ REL_18_6

诊断

先按 message 区分来源:核心管理器检查 isnull 标志和 BEFORE STATEMENT 返回契约;tcn 要核对 AFTER、FOR EACH ROW、参数个数和主键;PL/Perl 要核对返回是否为 undefSKIPMODIFY。DELETE 修改被忽略的报文是 WARNING,非法返回报文是 ERROR;不要把所有 39P01 都归为同一个 trigger 类型。

处置

修正 trigger 的 timing、level、事件、参数和返回值契约;对 tcn 还要核对表主键和调用顺序。PL/Perl 的 WARNING 表示 DELETE 行修改被忽略,非法返回值则使调用失败;先确认原操作是否完成和业务是否接受该结果,再决定后续写入。修复契约后才重新执行。

版本

锁定目录从 7.4 记录该条件,并在正式快照及 19beta3 中出现;源码路径取 PostgreSQL 18.6。

来源

证据

断言

每条断言都写明了是怎么核实的,以及它不覆盖什么。这一层是核验时留下的原始英文记录,照原样呈现,未经翻译。

  • 39P01 is trigger_protocol_violated in Class 39.

    核实方式Read the fixed definition row.

    来源src/backend/utils/errcodes.txt

  • The core trigger manager reports this code when a trigger function sets the isnull flag, and for invalid BEFORE STATEMENT return values.

    核实方式Read each fixed trigger-manager context and its message.

    来源src/backend/commands/trigger.c

  • contrib/tcn checks trigger invocation context, AFTER timing, row level, argument count, and primary-key setup with this code.

    核实方式Read the complete tcn checks around each report.

    来源contrib/tcn/tcn.c

  • PL/Perl has a WARNING variant for an ignored DELETE-row modification and an ERROR variant for an invalid trigger return value.

    核实方式Compare ereport levels and exact messages.

    来源src/pl/plperl/plperl.c

同类 SQL 状态码

状态码 条件名 宏名称 严重等级 版本
Class 39 外部例程调用异常 External Routine Invocation Exception 6 个
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
事件触发器辅助函数在错误的事件上下文调用。 活跃