# 22013 — invalid_preceding_or_following_size

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

## 速览 {#at-a-glance}
固定的 `ROWS` 或 `GROUPS` 窗口执行路径遇到负的窗口帧偏移。PostgreSQL 18.6 以 SQLSTATE `22013` 报告 `frame starting offset must not be negative` 或 `frame ending offset must not be negative`。

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

| 字段 | 值 |
| --- | --- |
| SQLSTATE | `22013` |
| 条件名 | `invalid_preceding_or_following_size` |
| 状态 | `有效` |
| 已知存在于 | `11.0` |
| 锁定快照 | `11.22, 12.22, 13.23, 14.24, 15.19, 16.15, 17.11, 18.6, 19beta3` |
| 宏 | `ERRCODE_INVALID_PRECEDING_OR_FOLLOWING_SIZE` |
| 别名 | `—` |

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

## 含义 {#meaning}
`calculate_frame_offsets` 为一次窗口扫描计算起始和结束表达式。复制非 NULL 值后，`ROWS` 和 `GROUPS` 分支把它解释为 `int8` 偏移；负值进入 `22013` guard。NULL guard 使用 `22004` 和不同的 primary。`RANGE` 帧使用按类型实现的 `in_range` helper：整数 helper 拒绝负偏移，numeric 拒绝 NaN、负无穷或负值，浮点 helper 拒绝 NaN 或负值，带 interval 的 timestamp helper 拒绝负 interval。这些 helper 使用同一个 `22013` primary，因此帧模式和解析后的偏移类型都是诊断条件。

## 诊断 {#diagnosis}
阅读帧模式、primary 指出的端点和偏移表达式的实际值。在 `ROWS`/`GROUPS` 中，起点或终点为负就是本码。在 `RANGE` 中，应按解析后的偏移类型判断：负整数或 interval，以及被拒绝的 NaN/负 numeric 或浮点值，都进入同一代码。起点或终点为 NULL 属于 `22004`，不是 `22013`。这是帧边界校验失败，不是一般算术溢出。

## 处理 {#response}
对于 `ROWS` 或 `GROUPS` 端点，提供非负且可转为 `int8` 的偏移；对于 `RANGE`，提供符合解析后类型 `in_range` helper 要求的值。如果实际问题是 NULL，则提供非 NULL 值。引用的 guard 抛出 `ERROR`，因此显式事务需先 `ROLLBACK` 或回到已有保存点后再重试，自动提交只重试修正后的语句。

## 报文 {#messages}
- Primary，`ERROR`：`frame starting offset must not be negative`。
- Primary，`ERROR`：`frame ending offset must not be negative`。
- Primary，`ERROR`：`invalid preceding or following size in window function`，用于引用的按类型 `RANGE` 偏移 guard。
- 引用的 guard 没有附加 DETAIL 或 HINT。NULL 端点使用 SQLSTATE `22004`，primary 分别为 `frame starting offset must not be null` 和 `frame ending offset must not be null`。

## 版本 {#versions}
锁定目录从 11.0 起记录该条件；固定源码覆盖 PostgreSQL 18.6。引用的执行器 guard 覆盖 `ROWS`/`GROUPS`；引用的按类型 `in_range` helper 也覆盖了代表性的 `RANGE` 偏移。

## 相关 {#related}
[`22004`](../22004/)、[`22012`](../22012/)、[`22003`](../22003/)

## 来源 {#sources}
- [`src/backend/executor/nodeWindowAgg.c#L2144-L2210`](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/executor/nodeWindowAgg.c#L2144-L2210) 包含起始/结束表达式计算、NULL 的 `22004` guard，以及负 `ROWS`/`GROUPS` 偏移的 `22013` guard。
- 代表性的 `RANGE` helper 使用同一个 primary：[`int8.c#L400-L420`](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/utils/adt/int8.c#L400-L420) 拒绝负整数偏移；[`numeric.c#L2690-L2715`](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/utils/adt/numeric.c#L2690-L2715) 拒绝 NaN、负无穷和负 numeric 偏移；[`float.c#L1105-L1125`](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/utils/adt/float.c#L1105-L1125) 拒绝 NaN 或负浮点偏移；[`timestamp.c#L3860-L3885`](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/utils/adt/timestamp.c#L3860-L3885) 拒绝负 interval 偏移。

运行核验为 `not_run`；上述源码证据不是运行观察。结构化[证据记录](../../data/evidence/22013.json)保留两个端点变体、`RANGE` 通用 primary 及其范围。
