22013 — invalid_preceding_or_following_size
速览
固定的 ROWS 或 GROUPS 窗口执行路径遇到负的窗口帧偏移。PostgreSQL 18.6 以 SQLSTATE 22013 报告 frame starting offset must not be negative 或 frame ending offset must not be negative。
| 字段 | 值 |
|---|---|
| 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 |
| 别名 | — |
含义
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,因此帧模式和解析后的偏移类型都是诊断条件。
诊断
阅读帧模式、primary 指出的端点和偏移表达式的实际值。在 ROWS/GROUPS 中,起点或终点为负就是本码。在 RANGE 中,应按解析后的偏移类型判断:负整数或 interval,以及被拒绝的 NaN/负 numeric 或浮点值,都进入同一代码。起点或终点为 NULL 属于 22004,不是 22013。这是帧边界校验失败,不是一般算术溢出。
处理
对于 ROWS 或 GROUPS 端点,提供非负且可转为 int8 的偏移;对于 RANGE,提供符合解析后类型 in_range helper 要求的值。如果实际问题是 NULL,则提供非 NULL 值。引用的 guard 抛出 ERROR,因此显式事务需先 ROLLBACK 或回到已有保存点后再重试,自动提交只重试修正后的语句。
报文
- 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。
版本
锁定目录从 11.0 起记录该条件;固定源码覆盖 PostgreSQL 18.6。引用的执行器 guard 覆盖 ROWS/GROUPS;引用的按类型 in_range helper 也覆盖了代表性的 RANGE 偏移。
相关
来源
src/backend/executor/nodeWindowAgg.c#L2144-L2210包含起始/结束表达式计算、NULL 的22004guard,以及负ROWS/GROUPS偏移的22013guard。- 代表性的
RANGEhelper 使用同一个 primary:int8.c#L400-L420拒绝负整数偏移;numeric.c#L2690-L2715拒绝 NaN、负无穷和负 numeric 偏移;float.c#L1105-L1125拒绝 NaN 或负浮点偏移;timestamp.c#L3860-L3885拒绝负 interval 偏移。
运行核验为 not_run;上述源码证据不是运行观察。结构化证据记录保留两个端点变体、RANGE 通用 primary 及其范围。