规划日期:2026-09-09。目标目录:/Users/vonng/pgcenter/err-code。
建设一部以 SQLSTATE 为永久身份、英文与简体中文成对维护、由 Hugo + OINK 驱动的静态百科。每个错误码只有一个条目,分类、问题场景和版本都是通向条目的索引。读者首先能判断发生了什么、如何定位、如何处理,然后按需查看复现、源码和历史。
本轮交付的是规划与下一会话提示词,尚未创建站点、扫描全量错误码或执行数据库实验。原始三份材料完整保存在 references/,供评审和追溯;其中的指令不自动成为项目要求。
| 决策 | 具体做法 |
|---|---|
| 产品形态 | 一个可搜索的工具书首页,一组索引,所有 SQLSTATE 条目平铺 |
| 内容位置 | content/docs/<SQLSTATE>.md 与 <SQLSTATE>.zh.md,保留 OINK Docs 阅读界面 |
| 公共地址 | 英文 /23505/,中文 /zh/23505/;字母码统一小写 URL,如 /40p01/,展示和数据始终使用 40P01 |
| 版本组织 | 同一页展示适用版本与关键变化,不为每个大版本复制整套文章 |
| 基础范围 | PG 9.0 至执行时最新正式大版本,完整包含用户要求的 PG 10 起各版本 |
| 更早历史 | 对条目继续追索代码、条件名和机制的来历;查不到精确引入版本就展示已知下界 |
| 预发行版 | 单独纳入最新官方预发行快照,明确标记;不混入正式版覆盖统计 |
| 技术栈 | Hugo Extended + 固定版本 OINK Module + Python 数据工具;站点构建与阅读不依赖数据库或后端服务 |
| 内容真源 | 文章正文是 Markdown;机器事实来自结构化数据;采集器不得重写已编辑正文 |
| 完成标准 | 全量收录与有效内容分别验收;骨架全部生成不等于百科完成 |
这里把完整版本矩阵从最低要求 PG 10 延伸到 PG 9.0,是利用现有资料提高历史价值,而不是要求在所有旧版本上逐条运行全部实验。若早期材料存在无法补齐的缺口,应报告准确边界,不能把空缺默认为不存在。
应保留原方案的四个优点:先做权威代码目录、保留宏别名、用可复现案例校验报文、英文与中文同步交付。主要调整如下。
| 原方案的问题 | 调整后的规则 |
|---|---|
| 只扫描 PG 14–18 | 至少覆盖 PG 10,默认完整矩阵向前扩至 PG 9.0;代码历史继续向前追索 |
首次出现在采样版本,就填 since |
区分首次观察、已知某版存在、精确引入版本;只有排除更早版本并核实发布归属,才写精确引入 |
| 只用稳定分支当前文件做版本比较 | 正式发布标签固定 SHA;同一大版本内的补丁变化也要通过定义文件历史检查 |
没有直接 errcode(MACRO) 就等于从不抛出 |
记录有范围的使用证据;覆盖动态映射、默认码、语言实现和错误转发;无法证实的写未知 |
| 源码 grep 是唯一事实来源 | 目录身份、实现路径、行为契约、真实输出分别由目录文件、源码、官方文档、实验支撑 |
| 一个码配一个固定报文 | 同一码可以有多条消息模板与多种严重性,按版本、触发路径和消息域组织 |
| 每页强制复制全部大章节 | 保留通用核心章节;客户端、扩展、监控等按有价值且有证据的内容选用 |
| 大量判断都做全局枚举 | 事务后果、重试、紧迫性按场景说明;不把业务判断伪装成 SQLSTATE 固有属性 |
| 数据 JSON 是所有 front matter 的唯一真源 | JSON 管机器事实,Markdown 管读者叙述与本地化;减少两份正文中的重复元数据 |
| 非翻译白名单字段逐字节相同 | 按 schema 比较共享字段的解析值;中文自然语言字段允许翻译 |
| 每码跑固定网络查询并攒 12 条链接 | 官方资料先行;实际存在知识缺口时定向检索;链接有用比数量多更重要 |
| 未阅读链接藏在 HTML 注释里 | 未核资料只进研究区,不进入文章、搜索索引、Markdown 导出或 LLM 输出 |
| 每个码都用一段 SQL / 一只 PG 18 容器验证 | 区分单连接、并发、建连、配置、复制和异常资源场景;验证方式按机制选择 |
| 所有页面都必须实测才能称为已核验 | 内容审阅与运行验证分开记录;不可安全复现的内部故障允许明确标识的源码核验 |
| 做完五页必须停下来等人工 review | 先校准代表样本并形成检查报告,通过后继续批量推进;不人为增加批准等待点 |
以下不是对样例的全面技术审计,但足以说明它应当成为研究素材,而不是不可修改的格式与事实标准。
- 协议诊断字段与日志字段混为一谈。 协议错误响应可包含 schema、table、constraint 等对象字段;PG 18 的标准
csvlog/jsonlog字段列表并没有独立的 constraint name。页面应区分“驱动可以取到什么”和“日志实际记录什么”。依据:协议错误字段、日志格式。 - DDL 的报文不能直接套用 INSERT。 PG 18.6 的唯一索引构建路径使用
could not create unique index和相应重复键 DETAIL,与普通插入路径不同。依据:固定 SHA 的 tuplesortvariants.c。本轮已核对本地文件与该提交对应文件的 SHA-256 一致。 - 逻辑复制改报文不等于改 SQLSTATE。 PG 18.6 的
errcode_apply_conflict()对 insert/update 唯一冲突仍返回ERRCODE_UNIQUE_VIOLATION。依据:conflict.c。样例“不是裸的 23505”容易把报文与码混淆。 - “后续所有语句都报 25P02 直到 ROLLBACK”缺少事务上下文。 要区分自动提交、显式事务、保存点恢复和 PL/pgSQL 异常块。依据:事务与保存点、PL/pgSQL 异常处理。
- 重试不能规定为“恰好两种情况、只重试一次”。 官方明确讨论了可能需要重试的
23505,并要求重新执行整个事务及决定 SQL/键值的逻辑;实际重试上限是应用策略。依据:Serialization Failure Handling。 ON CONFLICT场景的前置数据不完整。 样例新建空表后插入一行,不会自动出现示意中的 phone 冲突。其“只作用于指定索引”的叙述还需要覆盖省略目标的DO NOTHING。依据:INSERT 的冲突处理。- 序列修复例子要重写并实测。
coalesce(max(id), 0)会在空表产生 0,对通常从 1 起的序列可能越界;还需考虑非默认步长、范围、is_called和并发写入,不能包装成万能修复语句。机制依据:序列函数。 - 审阅状态缺少证据。 两份样例标成
reviewed,却留有未验证中文报文、手写版本断言、未读链接和空翻译哈希;中文还翻译了要求逐字节一致的版本说明。这些应通过重新设计状态与双语字段解决。
首页直接提供 SQLSTATE / 条件名 / 报文关键词搜索、常用码入口,以及按 class 分组的紧凑列表。以查错效率为主,避免大幅宣传区和铺满屏幕的大卡片。
| 页面 | 用途 |
|---|---|
/ 与 /zh/ |
搜索、常用码、完整目录入口与当前覆盖范围 |
/codes/ |
按码排序的全量表,可按 class、存在版本和内容深度筛选 |
/classes/、/classes/23/ |
class 目录及该类的共同语义、全部成员;只有实际定义的码才建条目 |
/common/ |
人工策划的常用错误码,不冒充统计排名 |
/topics/ |
连接认证、约束冲突、事务重试、锁与超时、对象解析、资源与系统错误等入口 |
/versions/、/versions/18/ |
每个版本的代码集合与有证据的增删、别名、行为变化;预发行单独标识 |
/guides/ |
SQLSTATE 阅读方法、获取诊断信息、恢复事务、重试、日志、PL/pgSQL 自定义错误等共性说明 |
/coverage/、/methodology/ |
各版本覆盖、文章深度、证据范围、验证结果与数据方法 |
/<sqlstate>/ |
唯一条目;中文对应 /zh/<sqlstate>/ |
索引内容可由事实与条目摘要确定性生成,仍保存为 Markdown。少量自定义样式与静态筛选脚本只用于改善表格、版本条和搜索定位;关闭 JavaScript 后目录与正文仍可用。
搜索优先精确 SQLSTATE,再匹配 condition / macro / 中文名称,最后匹配正文和已核消息模板。输入 40P01 与 40p01 应返回同一条目。复用 OINK 本地搜索,先验证效果,确有缺口再做小范围增强。
保留 OINK 的移动导航、语言切换、目录、深浅色、复制代码、打印、Markdown 与 agent 输出。语言切换必须回到同一码;搜索和导出都不能携带未核研究笔记。独立站和子路径部署都要验证,不能依赖硬编码域名。
主集合是范围内所有正式发布标签中由 PostgreSQL 定义的 SQLSTATE 并集,不只是最新 Appendix A。已删除的码保留条目,宏别名合并到同一码;条件名不是唯一主键,同一个条件名可能对应多个码。
所有 SQLSTATE 都是五位大写字符串,前导零必须保留。包括成功、警告与无数据状态,不能把它们全部描述成失败。范围外的扩展自定义码、任意用户 RAISE 码、客户端自定义码用方法页说明,不扩张为无穷条目。客户端/扩展复用核心码的行为可以作为该条目的补充路径。官方 Appendix A
优先解析 src/backend/utils/errcodes.txt,支持可选 condition 和一对多宏关系。旧版本若无该文件,改从当时的 src/include/utils/errcodes.h 与文档表提取并交叉校验。本轮已确认 PG 9.0.23 源码树采用后一种布局;文件不存在不能解释为“该版没有这些错误码”。
每个采集来源记录 release、tag、commit SHA、文件路径、文件摘要、获取日期;预发行快照另加 channel。当前官方页面可见 PG 18.6 和 PG 19 Beta 3,但执行时应重新确认并锁定。PostgreSQL 文档版本入口
展示矩阵用每个大版本选定的发布快照;定义历史还要扫描范围内发布标签上的不同文件 blob,按 blob SHA 去重,避免漏掉补丁版新增或中途消失的码。具体补丁引入无法核实时只展示已证实范围。
版本记录至少区分:
present_in_snapshots:在哪些锁定快照中存在。known_present_by:至少在某版已经存在,页面显示“该版或更早”。introduced/removed:有发布边界证据时填写,允许多个存在区间。changes:定义、命名、报文、触发条件、诊断字段和处理手段的变化,逐项附证据。history_boundary/gaps:扫描下界、浅克隆限制、缺失标签与未证实部分。
同一码存在,不等于其语义、报文或解决方法在全部版本相同。正文以最新正式版为主,旧版本差异就近标注;不把 PG 15 新语法给 PG 10 读者当通用答案。
建议实施目录如下;这是目标布局,不表示本轮已创建这些产物。
err-code/
PROJECT-PLAN.md
CODEX-PROMPT.md
references/ 原始参考材料,不作为站点内容
hugo.yaml go.mod go.sum Makefile
content/docs/
_index.md _index.zh.md
23505.md 23505.zh.md 所有码在这一层平铺
40P01.md 40P01.zh.md
codes/ classes/ common/ topics/ versions/ guides/
coverage.md coverage.zh.md
methodology.md methodology.zh.md
sources/manifest.lock.json 冻结来源与工具版本
raw/ 下载快照、原始目录与全量调用点候选
evidence/<SQLSTATE>.json 核验过的路径、版本断言、引用与试验索引
data/errcodes/<SQLSTATE>.json 由目录与 evidence 合成的规范事实
data/classes.json
data/versions.json
schemas/ 少量必要的数据契约
scripts/ 采集、合成、更新索引、检查、运行案例
verify/cases/<SQLSTATE>/ setup / sessions / assertions / cleanup
verify/results/ 环境清单、结构化结果与原始输出
research/ 未核链接与问题清单,不发布
reports/ 覆盖、进度、源资料变更、验收
assets/ layouts/ 确有必要的站点级定制
static/data/ 派生的可下载公开数据
大型源码缓存不提交,公开内容只发布经过筛选的数据。采集数据与证据的最小快照应能从清单重建,并有摘要校验。常规 hugo 构建只读本地 Markdown、数据及已解析的主题依赖,不重新联网抓资料。
事实数据管理身份、别名、存在版本、消息变体、来源定位、验证记录。文章保存解释、诊断、处置和翻译。生成器只创建缺失页面、更新带明确标记的事实块与派生索引;已编辑的段落、场景和引用不被覆盖。首次确定自动区块边界后做一次重复生成无变化的检查。
front matter 保持精简:title、description、sqlstate、slug、translationKey、内容深度、审阅记录和翻译跟踪信息。共享事实从数据读取;如果为 Markdown 独立可读性镜像成表格或字段,必须能自动校验,不能形成第二真源。
证据应定位到具体断言,而不只写“source_grep”。至少可以沿着页面场景、消息变体或版本说明找到:哪个来源、哪个版本、哪个文件/章节、如何核验、有哪些限制。
固定核心锚点建议为 at-a-glance、meaning、diagnosis、response、versions、related、sources。适用时插入 messages、scenarios、retry、observability、clients、extensions。相同锚点在两种语言间保持稳定;不适用的可选章节不制造空壳。
核心阅读顺序:一句话解释 → 第一判断与处置 → 主要报文/触发条件 → 诊断与修复 → 复现和历史 → 参考证据。对定义但暂未证实使用的状态,明确说明检索范围和未知项,不编造现场。
| 深度 | 交付内容 |
|---|---|
stub |
中间产物:身份、class、存在版本、权威来源;不能作为完整百科的交付终点 |
reference |
每码的有效参考页:含义、适用上下文、诊断/处置或明确不适用说明、版本记录、相关码及来源 |
full |
对代表性和常用码增加机制、实测场景、修复验证、重试边界、关键版本变化和必要客户端信息 |
另设审阅与验证维度:editorial_review 可以是 pending / reviewed,runtime_verification 可以是 passed / failed / not_run / not_applicable,并绑定具体版本、案例与证据。源码核验不能自动变成实测通过;编辑器也不能仅改状态字段就提高可信度。
第一组校准建议选择 12 个码:23505、23503、40P01、40001、42P01、57014、53300、28P01、2202E、01000、P0001、XX000。它们分别覆盖约束、多会话、解析、取消、建连、别名、警告、自定义异常及默认内部错误。01000 等条目的优秀样本可以是短参考页,不能为了对齐篇幅而写成长文。
第二组以原 Tier 1 清单为候选,按使用价值和机制差异重新排序,并补充值得重点覆盖的新码,例如目录已确认的 25P04。清单是编辑优先级,不是“实际上会不会抛出”的证据,也不能限制最终目录全集。
英文是主稿,中文是完整对应版本;解释使用自然中文,官方条件名、API 标识和日志原文保留。中文摘要、版本说明、表格文字可翻译,执行 SQL 共用同一案例真源。翻译跟踪覆盖英文正文及可翻译元数据,不能只更新哈希而不更新译文。机器检查只证明结构与新旧关系,不能替代语义审阅。
- 代码目录:解析冻结版本,保留原始行;对照该版本官方 Appendix A,解释宏行与文档行数量差异。
- 源码调用:扫描
src/backend、src/pl、contrib、相关接口和测试;直接调用、宏别名、辅助函数、默认错误码、变量赋值及转发分别记录。返回候选后再确认属于哪个报告调用,不能只取附近数行拼消息。 - 消息变体:保存原始格式串、
errmsg/errdetail/errhint的角色、同一调用组关系、路径与版本。处理多行字符串、errmsg_internal、复数、%m、条件组装等;不能自动解析时保留未解析候选。 - 机制与行为:官方文档给行为契约,源码给实现证据,回归/隔离/TAP 测试给可借鉴案例;
.out不能直接宣称是本项目已运行过的独立复现。 - 翻译报文:从对应版本与消息域的官方 PO 目录提取,核对非 fuzzy、非废弃、非空译文及占位符。PO 匹配只标“目录确认”,运行中文 locale 后才标“实测”;没有译文就展示英文,不造官方译文。
- 客户端:先建立常见驱动的公共取码/诊断指南,再对重点码核对类和常量。锁定驱动版本或 SHA;区分 exception class、constant、通用字段及无映射,避免逐页机械堆出九种驱动和多个 ORM。
- 补充阅读:优先官方文档、源码、发布说明与邮件原文。社区资料用于补充现场解释,不反过来覆盖版本事实。正式链接必须阅读并判断适用范围。
usage_evidence 只回答证据范围内的情况,例如运行观察到、源码路径已确认、仅确认目录定义、未知。不要设 ever_raised: false 这种横跨所有历史、扩展与用户函数的绝对断言。PL/pgSQL 支持用户指定 SQLSTATE,更说明这种断言范围过大。RAISE 文档
一个案例应有稳定 ID、适用版本、权限与配置前提、准备、触发、预期诊断、修复、修复后断言和清理。页面中的可执行 SQL 与运行器共用这些案例;片段可以节选,但要链接到完整案例并标明前提。
| 场景类型 | 验证方式 |
|---|---|
| 单连接 DML/DDL | 独立数据库或 schema,捕获结构化诊断,检查错误发生阶段与修复后的数据 |
| 事务状态 | 分别检查自动提交、显式事务、保存点/异常块,以及恢复后连接可用性 |
| 死锁、并发与序列化 | 多连接协调或 PostgreSQL isolation test 思路;明确同步条件和超时,不只依赖 sleep |
| 认证与连接数 | 从建连阶段捕获异常,使用专用小实例及独立客户端;服务器未返回 SQLSTATE 时如实区分客户端错误 |
| 取消与超时 | 明确 statement timeout、lock timeout、取消请求、会话超时的触发者与不同后果 |
| 复制、FDW、配置 | 独立拓扑/配置案例,锁定组件版本;必要时做专项扩展批次 |
| 磁盘满、OOM、损坏与崩溃 | 不在用户实例或共享宿主制造故障;采用可控隔离实验或有范围的源码核验 |
运行器优先断言 SQLSTATE、必要诊断字段、事务/连接状态,以及修复是否成立;同时保存原始输出。预期报错的案例不能只看 psql 退出码,也不能把 ON_ERROR_STOP=0 后脚本跑完当通过。
报文模板与真实输出分开存。运行输出记录精确 server version、平台、locale、配置、客户端版本、容器镜像摘要或二进制来源。时间、PID 等可按明文规则规范化,但保留原始记录;不能把规范化后的文本伪装成原始日志。页中每个声称“实测”的块都必须能找到 run ID。
默认先在最新正式版跑代表案例,PG 10 上跑兼容的核心案例,对文章声称发生行为变化的版本跑边界对照。目录全版本覆盖不意味着运行全版本覆盖。中文 PO、历史码、资源故障等未实测部分分项报告,不能默认为通过。
人工 RAISE SQLSTATE '23505' 只能验证取码和捕获机制,不能证明已经复现唯一冲突;P0001 等条目自身讨论 RAISE 时例外。
| 阶段 | 主要交付 | 阶段完成依据 |
|---|---|---|
| A:资料冻结与约定 | 当前文件保护记录、来源清单、版本边界、数据 schema、条目模板、执行日志 | 全部目标版本有来源或明确缺口;样例修订清单已形成 |
| B:完整目录与最小站点 | 目录解析器、版本/别名数据、全量双语骨架、Oink 平铺路由、核心索引 | 去重集合等于来源并集,双语齐全,严格构建通过;此时只称目录骨架 |
| C:代表样本闭环 | 12 个代表条目、案例运行器、23505 修订版、双语/证据/路由检查 | 有实际运行结果与不可运行项说明,样例暴露的模型问题已修正,能本地浏览 |
| D:百科主体 | 按 class / 机制批次丰富所有条目,重点码做到 full,其余至少 reference | 无伪完成的 stub,无通用套话代替具体含义;优先清单与未核问题可审计 |
| E:历史与补充证据 | 定义变更、重要行为边界、条件翻译、驱动映射及定向阅读 | 关键版本断言可追溯,未知项如实披露,未核材料不进入发布输出 |
| F:整体验收与交接 | 完整构建、桌面/移动/双语 QA、覆盖报告、操作说明、可达预览 | 所有必需检查成功;内容、来源、实测覆盖分别报告;下一步发布边界清楚 |
阶段 C 是技术校准检查点,通过后主动继续阶段 D;不要求用户每批批准。每批约 8–12 个相关码便于检查和回滚,不要求预先创建多份远程 PR。阶段 D 与 E 可按同一批交错执行,避免正文完成后才发现历史材料推翻解释。
建议命令契约:make fetch 显式刷新来源;make catalogue 提取;make generate 更新允许生成的部分;make check 跑离线数据/双语/证据/链接检查;make verify-smoke 与 make verify 跑数据库案例;make build 严格构建;make serve 启动预览。初次依赖解析需要网络,此后普通内容构建不隐式刷新资料。
CI 将数据与构建、轻量运行验证、昂贵专项验证分开。正常检查不依赖实时搜索结果;外链检查区分失效与暂时不可达。解析器要用真实历史格式、别名、缺字段和版本边界编写有效测试,不用海量镜像实现的测试增加维护成本。
最终覆盖报告至少包含:每版定义数、SQLSTATE 并集数、宏别名数、实际条目数、EN/ZH 配对数、reference/full/stub 分布、待审条目、源码确认数、按版本成功/失败/跳过的案例数、来源缺口、翻译过期项、链接与构建结果。
“完整”指约定范围内全部定义已收录并有诚实可用的参考内容,重点条目有足够深度;不承诺证明一切源码路径或搜尽互联网。不能以“每个文件都存在”代替这个验收。
/Users/vonng/pgsty/oink:主题源码及当前 README;本轮观察到本地有未发布领先提交,执行时不能直接把工作树等同正式版本。/Users/vonng/pgsty/oink-starter:最小配置来源,本轮 pin 为v1.0.0;选择执行时可解析且验证通过的发行版并锁定。/Users/vonng/pgcenter/waitevent:Docs 源文件映射到根路径、双语和证据报告的参考。/Users/vonng/pgcenter/guc:旧版本提取和版本历史的参考。/Users/vonng/pgcenter/.cache/postgresql:本轮可见 PG 13.23 至 18.6 的若干源码快照;目录名称不能代替摘要验证。/Users/vonng/pgcenter/.cache/postgresql-git:有历史标签,但本轮确认是浅克隆,不能据此直接断言精确引入版本。
这些资产只读参考,不复制无关的完整站点,不修改兄弟目录。需要补齐 Git 历史就在项目自己的缓存中操作。/Users/vonng/pgcenter 本轮不是 Git 仓库,errorcode 是空目录;采用用户最后指定的 err-code,不移动或清理其他目录。
新会话的默认交付是本地完整项目、检查记录和预览。远程仓库、提交推送、PR、域名和正式发布不由原始材料中的 PR 节奏自动授权。域名未定不阻塞本地实现,配置使用可替换的开发基址。
执行入口见 CODEX-PROMPT.md。