23P01 — 排除约束冲突(exclusion_violation)
排除约束发现新行与已有行冲突,如范围重叠。
英文手册覆盖始于 PostgreSQL 8.1. 来源历史与运行验证各自保留独立版本边界。
当前阅读 PG 18·选择有来源记录的版本
- aliases
- 未知
- class name
- Integrity Constraint Violation
- condition name
- exclusion_violation
- lang
- en
- sqlstate
- 23P01
版本定义 PG 18
23P01 — 排除约束冲突
速览 {#at-a-glance}
23P01 表示排除约束发现已有行与新行在所有配置运算符上冲突。本案例使用 && 检查范围重叠,因此拒绝的是重叠而不只是相等值。
含义 {#meaning}
排除约束结合索引访问方法和运算符;[5,12) 与 [1,10) 重叠,而半开范围 [10,12) 在 10 处不重叠。运算符类和约束配置的运算符组合决定冲突;DEFERRABLE 会改变检查时点。
诊断 {#diagnosis}
记录约束名、DETAIL 中的键值,以及约束是否延迟。按相同运算符检查现有行,不能只做相等比较。立即约束在语句边界报错,DEFERRABLE 约束可能在 SET CONSTRAINTS 或 COMMIT 时才报错。本案例是立即检查、自动提交,错误后连接为 IDLE。
处理 {#response}
选择不冲突的值,或按应用并发策略协调冲突的预订或资源。自动提交时,失败语句结束自己的事务边界,连接可以继续使用。显式事务中,无论立即检查还是延迟检查报错,都可能使事务进入失败状态;重试前应执行 ROLLBACK,若应用刻意用保存点隔离该操作,则可执行 ROLLBACK TO SAVEPOINT 保留外层事务。DEFERRABLE 冲突可能在 SET CONSTRAINTS 或 COMMIT 才报告,因此应从该检查时点要求的干净边界重做完整操作;只有冲突确实可能消失且操作安全时才重试。不要脱离业务规则随意改范围端点。
实测诊断 {#messages}
18.6 (Homebrew) / latest:SQLSTATE 23P01;primary conflicting key value violates exclusion constraint "bookings_no_overlap";DETAIL Key (during)=([5,12)) conflicts with existing key (during)=([1,10)).;status_after_error IDLE。
10.21 (Debian 10.21-1.pgdg90+1) / pg10:SQLSTATE 23P01;primary conflicting key value violates exclusion constraint "bookings_no_overlap";DETAIL Key (during)=([5,12)) conflicts with existing key (during)=([1,10)).;status_after_error IDLE。
代表案例 {#case}
本例第二个预订与已有范围重叠;把下界移到已有范围的上界即可修复。完整 setup、断言与清理见案例导出:
-- create
CREATE TABLE bookings(id integer PRIMARY KEY, during int4range NOT NULL, CONSTRAINT bookings_no_overlap EXCLUDE USING gist (during WITH &&));
-- seed
INSERT INTO bookings VALUES (1, int4range(1, 10));
-- trigger
INSERT INTO bookings VALUES (2, int4range(5, 12));
-- repair
INSERT INTO bookings VALUES (2, int4range(10, 12));
-- verify
SELECT id, during::text FROM bookings ORDER BY id;
本案例对应的 SQLSTATE、诊断、事务状态和修复断言均来自经核对的案例 registry;见结构化证据和案例导出。
作者证据 ID:identity, mechanism, runtime。选定运行记录:runtime.23P01-batch1-latest-20260909.latest, runtime.23P01-batch1-pg10-20260909.pg10。
版本与边界 {#versions}
锁定目录从 9.0.0 起观察到 23P01,并在列出的正式快照中均存在。选定的立即范围案例在 18.6 与 10.21 通过;未测试延迟或并发排除检查。
相关 {#related}
对比 23505 唯一约束冲突、23514 CHECK 冲突 和 23001 RESTRICT 冲突。
来源 {#sources}
src.errcodes.18.6(SHA-2566e8de346643ba84aa3c9c6a73360acfc7b2dfb89162c06c08ce9bf5bcd5bbcba)src.calls.REL_18_6(SHA-2569ee8a0e81d8f0825c5c1ae45583439859a26e602bdd4ce2f2a62aa278867ccbf)src.execIndexing.18.6(SHA-25624c80553ab4b28d7d2a288dd9196c8db9459c7f308853cd8c8c939485e15f199)doc.rangetypes.18.6(SHA-256cfeffb134d2acc2ec45141726583b041410665c4a2f8ecf66cd3f9484a7f0014) · 官方文档
比较版本
SQLSTATE 证据与已记录的运行版本
cases · overlapping_range_exclusion
{
"assertions": [
"SQLSTATE is 23P01",
"The exclusion constraint is identified",
"A non-overlapping range can be inserted afterward"
],
"case_id": "overlapping_range_exclusion",
"cleanup": "Drop the case schema with an owner connection.",
"has_snippet": true,
"position": 0,
"preconditions": [
"A range column has a GiST exclusion constraint using \u0026\u0026",
"The second range overlaps the committed first range"
],
"repair": "Choose a non-overlapping interval or resolve the conflicting reservation according to business rules; do not treat exclusion as a generic duplicate-key check.",
"trigger": "Insert an overlapping range.",
"versions": [
"10",
"18"
]
}claims · identity
{
"claim_id": "identity",
"limits": "The exclusion operator may compare more than equality; the operator class and constraint definition determine the conflict.",
"method": "Read the fixed errcodes row.",
"position": 0,
"runtime": [],
"sources": [
"src.errcodes.18.6"
],
"statement": "23P01 is exclusion_violation in Class 23."
}claims · mechanism
{
"claim_id": "mechanism",
"limits": "A half-open range [10,12) does not overlap [1,10); changing bounds is a business rule, not a blanket retry.",
"method": "Trace check_exclusion_or_unique_constraint and the range exclusion documentation.",
"position": 1,
"runtime": [],
"sources": [
"src.execIndexing.18.6",
"doc.rangetypes.18.6",
"src.calls.REL_18_6"
],
"statement": "An exclusion constraint rejects a row when the configured operator comparisons are all true against an existing row; the range example uses \u0026\u0026 for overlap."
}claims · runtime
{
"claim_id": "runtime",
"limits": "This case does not test DEFERRABLE exclusion constraints, concurrent waits, or every operator class.",
"method": "Read the selected summaries and raw diagnostics.",
"position": 2,
"runtime": [],
"sources": [
"runtime.23P01-batch1-latest-20260909.latest",
"runtime.23P01-batch1-pg10-20260909.pg10"
],
"statement": "The selected immediate GiST range case returned 23P01 on PG18.6 and PG10.21, identified bookings_no_overlap, stayed IDLE, and committed a non-overlapping [10,12) range."
}messages · conflict
{
"limits": "The detail is dynamically built from the conflicting key values; the fallback is “Key conflicts with existing key.”",
"message_id": "conflict",
"path": "",
"position": 0,
"raw": {
"detail_template": "Key %s conflicts with existing key %s.",
"id": "conflict",
"limits": "The detail is dynamically built from the conflicting key values; the fallback is “Key conflicts with existing key.”",
"primary_template": "conflicting key value violates exclusion constraint \"%s\"",
"severity_source": "ERROR",
"sources": [
"src.execIndexing.18.6"
],
"sqlstate": "23P01"
},
"severity": "ERROR",
"sources": [
"src.execIndexing.18.6"
],
"templates": [
{
"kind": "primary",
"literal": "conflicting key value violates exclusion constraint \" \"",
"position": 0,
"role": "",
"template": "conflicting key value violates exclusion constraint \"%s\""
},
{
"kind": "detail",
"literal": "Key conflicts with existing key .",
"position": 1,
"role": "",
"template": "Key %s conflicts with existing key %s."
}
]
}runtimes · runtime.23P01-batch1-latest-20260909.latest · 18.6 (Homebrew) · passed
{
"cases": [
"overlapping_range_exclusion"
],
"limits": "",
"position": 0,
"raw": {
"case_manifest": {
"path": "verify/cases/23P01/cases.json",
"sha256": "6dcb833ed64435a75016520f520cbb1abffc7d8751eb9195dc8ad5ffa2a9680e"
},
"cases": [
"overlapping_range_exclusion"
],
"id": "runtime.23P01-batch1-latest-20260909.latest",
"observed": {
"constraint": "bookings_no_overlap",
"detail": "Key (during)=([5,12)) conflicts with existing key (during)=([1,10)).",
"primary": "conflicting key value violates exclusion constraint \"bookings_no_overlap\"",
"rows": [
[
1,
"[1,10)"
],
[
2,
"[10,12)"
]
],
"sqlstate": "23P01",
"status_after_error": "IDLE"
},
"raw": "verify/results/23P01-batch1-latest-20260909/latest/raw.jsonl",
"raw_sha256": "b4e9ebe13743c12d84be1113ebdcec01c12ae79368e9b85b4ff1e01179dc7880",
"run_id": "23P01-batch1-latest-20260909",
"server_version": "18.6 (Homebrew)",
"server_version_num": 180006,
"snippet_registry": {
"path": "verify/cases/23P01/snippets.json",
"sha256": "475f58dda688a5864436d67e18f16abfbfae0b178acecaabe66ebaca7ab3c585"
},
"status": "passed",
"summary": "verify/results/23P01-batch1-latest-20260909/latest/summary.json",
"summary_sha256": "5e613eec8134801dfb3a603e7926418ee5d73b585546fd1aaa9004eeec553ef4",
"target": "latest"
},
"run_id": "23P01-batch1-latest-20260909",
"runtime_id": "runtime.23P01-batch1-latest-20260909.latest",
"server_version": "18.6 (Homebrew)",
"status": "passed",
"target": "latest"
}runtimes · runtime.23P01-batch1-pg10-20260909.pg10 · 10.21 (Debian 10.21-1.pgdg90+1) · passed
{
"cases": [
"overlapping_range_exclusion"
],
"limits": "",
"position": 1,
"raw": {
"case_manifest": {
"path": "verify/cases/23P01/cases.json",
"sha256": "6dcb833ed64435a75016520f520cbb1abffc7d8751eb9195dc8ad5ffa2a9680e"
},
"cases": [
"overlapping_range_exclusion"
],
"id": "runtime.23P01-batch1-pg10-20260909.pg10",
"observed": {
"constraint": "bookings_no_overlap",
"detail": "Key (during)=([5,12)) conflicts with existing key (during)=([1,10)).",
"primary": "conflicting key value violates exclusion constraint \"bookings_no_overlap\"",
"rows": [
[
1,
"[1,10)"
],
[
2,
"[10,12)"
]
],
"sqlstate": "23P01",
"status_after_error": "IDLE"
},
"raw": "verify/results/23P01-batch1-pg10-20260909/pg10/raw.jsonl",
"raw_sha256": "1975e9348838d73f3433c2da02a3f3972dc3670e24bc89d73d631cd35b219165",
"run_id": "23P01-batch1-pg10-20260909",
"server_version": "10.21 (Debian 10.21-1.pgdg90+1)",
"server_version_num": 100021,
"snippet_registry": {
"path": "verify/cases/23P01/snippets.json",
"sha256": "475f58dda688a5864436d67e18f16abfbfae0b178acecaabe66ebaca7ab3c585"
},
"status": "passed",
"summary": "verify/results/23P01-batch1-pg10-20260909/pg10/summary.json",
"summary_sha256": "2b071d07ad5977b4fd9133f9815a92fc3fca27980659f26654b8dc3793abd767",
"target": "pg10"
},
"run_id": "23P01-batch1-pg10-20260909",
"runtime_id": "runtime.23P01-batch1-pg10-20260909.pg10",
"server_version": "10.21 (Debian 10.21-1.pgdg90+1)",
"status": "passed",
"target": "pg10"
}sources · src.errcodes.18.6
{
"commit": "724edf9bde9d356724ad384a2e196edc3c9f80f7",
"docs_url": "",
"kind": "upstream_source",
"location": "",
"path": "src/backend/utils/errcodes.txt",
"position": 0,
"sha256": "6e8de346643ba84aa3c9c6a73360acfc7b2dfb89162c06c08ce9bf5bcd5bbcba",
"source_id": "src.errcodes.18.6",
"tag": "REL_18_6",
"url": "https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/utils/errcodes.txt"
}sources · src.calls.REL_18_6
{
"commit": "",
"docs_url": "",
"kind": "local_artifact",
"location": "",
"path": "raw/calls/REL_18_6.jsonl",
"position": 1,
"sha256": "9ee8a0e81d8f0825c5c1ae45583439859a26e602bdd4ce2f2a62aa278867ccbf",
"source_id": "src.calls.REL_18_6",
"tag": "",
"url": ""
}sources · src.execIndexing.18.6
{
"commit": "724edf9bde9d356724ad384a2e196edc3c9f80f7",
"docs_url": "",
"kind": "upstream_source",
"location": "",
"path": "src/backend/executor/execIndexing.c",
"position": 2,
"sha256": "24c80553ab4b28d7d2a288dd9196c8db9459c7f308853cd8c8c939485e15f199",
"source_id": "src.execIndexing.18.6",
"tag": "REL_18_6",
"url": "https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/executor/execIndexing.c#L917-L937"
}sources · doc.rangetypes.18.6
{
"commit": "724edf9bde9d356724ad384a2e196edc3c9f80f7",
"docs_url": "https://www.postgresql.org/docs/18/rangetypes.html#RANGETYPES-CONSTRAINT",
"kind": "upstream_source",
"location": "",
"path": "doc/src/sgml/rangetypes.sgml",
"position": 3,
"sha256": "cfeffb134d2acc2ec45141726583b041410665c4a2f8ecf66cd3f9484a7f0014",
"source_id": "doc.rangetypes.18.6",
"tag": "REL_18_6",
"url": "https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/doc/src/sgml/rangetypes.sgml#L540-L573"
}来源引用
定义来源
center · PostgreSQL 18 · english-manuals:8c95fb3325400efbfd8c98cece0651616cd3c09eb7bcdf360341f55f98d82f92
正文语言: zh-Hans · english-manuals:8c95fb3325400efbfd8c98cece0651616cd3c09eb7bcdf360341f55f98d82f92