42P21 — 排序规则不匹配
42P21 — 排序规则不匹配
速览
42P21(collation_mismatch)需要得到兼容结果时,不同排序规则选择可能发生冲突。
| 字段 | 值 |
|---|---|
| SQLSTATE | 42P21 |
| 条件名 | collation_mismatch |
| 状态 | 有效 |
| 已知存在于 | 9.1.0 |
| 锁定快照 | 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_COLLATION_MISMATCH |
| 别名 | — |
含义
当固定源码路径需要一个兼容的排序规则,却得到不兼容的选择时,会报 42P21。隐式选择会先记录为 COLLATE_CONFLICT;调用方允许没有共同排序规则时可以返回 InvalidOid,只有确实需要排序规则的调用方才把隐式冲突变成 ERROR。显式 COLLATE 冲突则立即失败。同一条件还覆盖递归 CTE 输出、继承或子表列定义,以及外键键列兼容性。
诊断
遇到隐式排序规则消息时保留两个名称,并检查调用方是否要求共同排序规则;不同的隐式操作数不会全部立即抛出 42P21。遇到显式排序规则消息时,找出两个 COLLATE 子句并统一预期选择。递归查询要比较非递归项与整体列排序规则。继承或分区子表错误要比较父表与子表列定义。外键要比较引用表和被引用表的键列:固定源码允许两边都是确定性排序规则时使用不同排序规则;只要任一排序规则不确定,两边就必须相同。保留 DETAIL 中的名称,不要把它笼统当成转成 text 就能解决的问题。
处理
表达式冲突应在表达式边界明确指定一个有意选择的 COLLATE,或统一显式子句及递归非递归项的排序规则。重试 DDL 前先对齐继承列或子表列定义。外键应选择兼容的键列排序规则;只要一侧不确定,就满足两边相同的严格要求,然后重新核对相等比较和索引语义。如果该 ERROR 发生在显式事务中,修正语句前先 ROLLBACK,或回滚到错误前的保存点;自动提交模式下连接回到空闲后再重试。
消息
固定源码中的代表性消息包括:
- ERROR message:
collation mismatch between implicit collations "%s" and "%s"; HINT:You can choose the collation by applying the COLLATE clause to one or both expressions. - ERROR message:
collation mismatch between explicit collations "%s" and "%s" - ERROR message:
recursive query "%s" column %d has collation "%s" in non-recursive term but collation "%s" overall; HINT:Use the COLLATE clause to set the collation of the non-recursive term. - ERROR message:
column "%s" has a collation conflict; DETAIL:"%s" versus "%s" - ERROR message:
inherited column "%s" has a collation conflict; DETAIL:"%s" versus "%s" - ERROR message:
child table "%s" has different collation for column "%s"; DETAIL:"%s" versus "%s" - ERROR message:
foreign key constraint "%s" cannot be implemented; DETAIL:Key columns "%s" of the referencing table and "%s" of the referenced table have incompatible collations: "%s" and "%s". If either collation is nondeterministic, then both collations have to be the same.
占位符由实际对象、列或参数填充。
版本
锁定目录显示该条件最早见于 PostgreSQL 9.1.0;行为说明固定在 PostgreSQL 18.6 源码,目录存在范围不等于每条消息或功能都从该版本开始。
相关
来源
源码消息、行号和证据边界见 作者证据。
src/backend/parser/parse_collate.c:208-234(fixed source)src/backend/parser/parse_collate.c:804-835(fixed source)src/backend/parser/parse_cte.c:394-401(fixed source)src/backend/commands/tablecmds.c:3297-3303(fixed source)src/backend/commands/tablecmds.c:3463-3469(fixed source)src/backend/commands/tablecmds.c:7292-7298(fixed source)src/backend/commands/tablecmds.c:10474-10483(fixed source)