# 22003 — numeric_value_out_of_range

> PostgreSQL SQLSTATE 22003 的源码与诊断参考。
---

# 22003

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

22003 是 `numeric_value_out_of_range`。固定源码中的数值转换会报告 `integer out of range`，其他范围检查路径保留各自的操作上下文。

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

| 字段 | 值 |
| --- | --- |
| SQLSTATE | `22003` |
| 条件名 | `numeric_value_out_of_range` |
| 状态 | `有效` |
| 已知存在于 | `7.4` |
| 锁定快照 | `9.0.23, 9.1.24, 9.2.24, 9.3.25, 9.4.26, 9.5.25, 9.6.24, 10.23, 11.22, 12.22, 13.23, 14.24, 15.19, 16.15, 17.11, 18.6, 19beta3` |
| 宏 | `ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE` |
| 别名 | `—` |

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

共享案例把 `2147483648` cast 为 `integer` 以捕获范围错误，再把可表示的 `2147483647` 作为修复值。应分开发送两条 SELECT；第一条预期失败，之后再执行修复表达式。会话和清理由运行器负责，无需建立 schema。

<!-- BEGIN SQLSTATE SNIPPET: integer_out_of_range -->
```sql
SELECT '2147483648'::integer;
SELECT '2147483647'::integer;
```
<!-- END SQLSTATE SNIPPET -->

校准实测整数输入 `2147483648` 被拒绝并报告 `value "2147483648" is out of range for type integer`；`2147483647` 成功。PostgreSQL 18.6 使用 `pg_strtoint32_safe`，REL_10_23 源码路径使用 `pg_atoi`；运行器的两条自动提交会话均回到 `IDLE`。

## 报文 {#messages}

固定整数输入 guard 以 `ERROR` 严重性报告 primary：`value "%s" is out of range for type %s`。其他已确认源码路径使用 `value overflows numeric format`（numeric 阶乘）和 `integer out of range`（`width_bucket` 结果转换）。引用的源码组没有独立 DETAIL 或 HINT；本次运行只观察了整数输入模板。

## 含义 {#meaning}

`22003` 表示所选操作无法表示某个数值或范围。固定目录成员既用于整数转换，也用于精确 numeric 溢出和子系统检查；代表性消息包括 `integer out of range` 与 `value overflows numeric format`。其他源码路径也可能使用该 SQLSTATE 但消息不同，因此不能只凭 SQLSTATE 判断具体类型。

## 诊断 {#diagnosis}

先看 primary message 和 source object。本次观察只证明 int4 输入转换的边界，不能代表所有 numeric 表达式。整数转换要确认源/目标整数宽度，以及错误发生在输入、赋值、cast、算术还是扩展函数。numeric 要区分声明的 precision/scale、算术溢出和舍入语义，并保留操作数。值可以语法正确，却仍然超出目标范围。

## 处置 {#response}

在转换前校验范围，并选择符合业务契约的表示：拒绝值、显式缩放，或使用支持的更宽类型。算术要检查中间结果而不只看最终列。若消息指向特定子系统，应修复该子系统。本次固定案例使用自动提交，失败 cast 后会话仍为 `IDLE`；显式事务中应先回滚整个事务，或回滚到失败表达式前已有的保存点，再重试修正表达式。不要对确定性的范围错误做无条件重试，也不要静默截断金额、标识符或计数器。

## 版本 {#versions}

锁定目录从 7.4 记录该条件，并在列出的正式快照及 19beta3 中出现；固定源码覆盖为 PostgreSQL 18.6。

## 相关条件 {#related}

[`22001`](../22001/) 是字符串长度错误，[`22007`](../22007/) 是日期时间格式错误，[`22008`](../22008/) 是日期时间字段/范围越界。

## 来源 {#sources}

代表性固定路径包括整数输入的 [`numutils.c#L603-L612`](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/utils/adt/numutils.c#L603-L612)、numeric 溢出的 [`numeric.c#L3765-L3769`](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/utils/adt/numeric.c#L3765-L3769) 和 `width_bucket` 结果转换的 [`numeric.c#L2042-L2046`](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/utils/adt/numeric.c#L2042-L2046)。结构化[证据记录](../../data/evidence/22003.json)记录了固定消息族与源码哈希。
