# 55P04 — unsafe_new_enum_value_usage

> PostgreSQL SQLSTATE 55P04 的来源与诊断参考。
---

# 55P04

## 速览 {#at-a-glance}

`55P04` 保护“新加入的 enum 值必须先提交再使用”的规则。它发生在 PostgreSQL 找到仍未提交且被标记为不安全的 enum tuple 后，不是标签语法错误。

<!-- BEGIN SQLSTATE FACTS: generated by scripts/generate.py; do not edit -->

| 字段 | 值 |
| --- | --- |
| SQLSTATE | `55P04` |
| 条件名 | `unsafe_new_enum_value_usage` |
| 状态 | `有效` |
| 已知存在于 | `12.0` |
| 锁定快照 | `12.22, 13.23, 14.24, 15.19, 16.15, 17.11, 18.6, 19beta3` |
| 宏 | `ERRCODE_UNSAFE_NEW_ENUM_VALUE_USAGE` |
| 别名 | `—` |

<!-- source facts: data/errcodes/55P04.json -->
<!-- END SQLSTATE FACTS -->

## 含义 {#meaning}

固定 `enum.c` guard 先接受已经标记为 committed 的 tuple，再直接检查 tuple 的事务 ID；如果该值不在 `EnumUncommitted()` 列表中，也会接受，因为它不可能比所属类型存活更短。只有剩余的未提交新值才会报此码。因此，同一未提交事务中的 `ALTER TYPE ... ADD VALUE` 与使用新标签可能触发 `55P04`，已经提交的标签则不会触发这条 guard。

## 消息 {#messages}

- Primary 模板：`unsafe use of new value "%s" of enum type %s`
- Detail：本调用组没有 detail。
- Hint：`New enum values must be committed before they can be used.`

两个 `%s` 分别是 enum 标签和格式化后的 enum 类型名，只提供诊断信息，不是值格式规则。

## 诊断 {#diagnosis}

保留 enum 标签、类型名、SQLSTATE、severity 和事务状态，检查该值是否由同一仍未提交的事务刚刚加入，以及失败使用是否是 enum input/cast 或解析为该 enum 的其他表达式。把这个 guard 与无效 enum 标签（`22P02`）区分开；`22P04` 是 COPY 文件格式条件，不是这条 enum guard。还要与重复 `ADD VALUE` 区分。

## 处理 {#response}

先从 `ERROR` 恢复事务：执行 `ROLLBACK`；若 savepoint 的位置合适、能够保留此前的 `ADD VALUE`，则执行 `ROLLBACK TO SAVEPOINT`。新增值仍未提交时不能使用。如果完整回滚或回滚到 savepoint 已丢弃 `ADD VALUE`，就在新事务中重新执行并 `COMMIT`；若 savepoint 保留了它，也要先提交该事务，再在能看到已提交 catalog 行的事务中使用新标签。autocommit 下修正提交边界后重试输入，不要重复同一未提交流程。

## 版本 {#versions}

锁定目录从 12.0 记录此条件；固定源码覆盖 PostgreSQL 18.6。目录边界不表示更早不存在私有或未解析实现。

## 相关 {#related}

[`22P02`](../22p02/)、[`25006`](../25006/)、[`23505`](../23505/)

## 来源 {#sources}

[src/backend/utils/adt/enum.c#L68-102](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/utils/adt/enum.c#L68)

结构化[证据记录](../../data/evidence/55p04.json)保存精确 guard 和消息组；未声称有自然运行案例。
