↑↓ 选择↵ 打开⌫ 切换范围完整搜索

PG.CENTER 连接 PostgreSQL 文档、百科与生态知识。由 Pigsty 维护。

Wiki / SQLSTATE

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-256 6e8de346643ba84aa3c9c6a73360acfc7b2dfb89162c06c08ce9bf5bcd5bbcba)
  • src.calls.REL_18_6 (SHA-256 9ee8a0e81d8f0825c5c1ae45583439859a26e602bdd4ce2f2a62aa278867ccbf)
  • src.execIndexing.18.6 (SHA-256 24c80553ab4b28d7d2a288dd9196c8db9459c7f308853cd8c8c939485e15f199)
  • doc.rangetypes.18.6 (SHA-256 cfeffb134d2acc2ec45141726583b041410665c4a2f8ecf66cd3f9484a7f0014) · 官方文档

比较版本

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"
}

来源引用

完整定义与证据 JSON

定义来源

center · PostgreSQL 18 · english-manuals:8c95fb3325400efbfd8c98cece0651616cd3c09eb7bcdf360341f55f98d82f92

正文语言: zh-Hans · english-manuals:8c95fb3325400efbfd8c98cece0651616cd3c09eb7bcdf360341f55f98d82f92