# 22011 — substring_error

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

## 速览 {#at-a-glance}
文本子字符串路径收到无效的显式长度。固定的 PostgreSQL 18.6 代码中，`text_substring` 以 SQLSTATE `22011` 报告 `negative substring length not allowed`。

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

| 字段 | 值 |
| --- | --- |
| SQLSTATE | `22011` |
| 条件名 | `substring_error` |
| 状态 | `有效` |
| 已知存在于 | `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_SUBSTRING_ERROR` |
| 别名 | `—` |

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

## 含义 {#meaning}
三参数文本子字符串包装器把显式长度传给 `text_substring`；负长度会进入 `ERRCODE_SUBSTRING_ERROR` guard。无长度包装器则传入带有 `length_not_specified` 的哨兵值，返回剩余文本，不会进入负长度 guard。`OVERLAY` 的起点不为正时也复用这个报错。本证据针对文本路径；bytea、位串和基于模式的 substring 有各自的消费者，应以完整诊断识别。

## 诊断 {#diagnosis}
修改前先确认解析出的操作和数据类型。对文本路径，要区分显式负长度与零或负起点：源码把有效起点调整为 1，并按 SQL 规则调整长度。起点超过末尾会返回空串。起点加长度的 32 位计算溢出时，子串延伸到末尾，并不报本码。`OVERLAY` 的非正起点使用同一 primary，而起点加长度溢出则使用 `22003`。

## 处理 {#response}
传入非负的显式文本长度；若意图是取到末尾，则省略长度。保留预期的一基起点语义，并在修复前确认实际数据类型。该路径抛出 `ERROR`；显式事务需先 `ROLLBACK` 或回到已有保存点后再重试，自动提交只重试修正后的语句。

## 报文 {#messages}
- Primary，`ERROR`：显式文本子字符串 guard 和非正 `OVERLAY` 起点 guard 都是 `negative substring length not allowed`；这些路径没有固定 DETAIL 或 HINT。

## 版本 {#versions}
锁定目录从 7.4 起记录该条件；固定源码覆盖 PostgreSQL 18.6。引用的 guard 是当前版本的文本和 `OVERLAY` 路径，不推广到所有 substring 实现。

## 相关 {#related}
[`22000`](../22000/)、[`22001`](../22001/)、[`22003`](../22003/)

## 来源 {#sources}
- [`src/backend/utils/adt/varlena.c#L896-L1010`](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/utils/adt/varlena.c#L896-L1010) 包含文本包装器、起点调整、省略长度哨兵、显式负长度 `ERROR` 以及末尾/溢出处理。
- [`src/backend/utils/adt/varlena.c#L1166-L1186`](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/utils/adt/varlena.c#L1166-L1186) 包含 `OVERLAY` guard 及其独立的 `22003` 溢出分支。

运行核验为 `not_run`；上述源码证据不是运行观察。结构化[证据记录](../../data/evidence/22011.json)保留确切 primary 和源码范围。
