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

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

Wiki / SQLSTATE

42P01 — undefined_table:未定义的表或关系

引用的表、视图或其他关系不存在。

英文手册覆盖始于 PostgreSQL 8.1. 来源历史与运行验证各自保留独立版本边界。

当前阅读 PG 18·选择有来源记录的版本

aliases
未知
class name
Syntax Error or Access Rule Violation
condition name
undefined_table
lang
en
sqlstate
42P01

版本定义 PG 18

速览 {#at-a-glance}

42P01 是 PostgreSQL 类别 42 syntax_error_or_access_rule_violation 中的 undefined_table 条件。这个名称沿袭已久;无法解析的引用可以是表、视图、物化视图、外部表或其他关系名称。

普通诊断是未限定引用的 relation "%s" does not exist,或限定引用的 relation "%s.%s" does not exist。解析器在查询执行前报告 SQLSTATE;自动提交连接不会因为这个查询错误留下失败事务。

代表性案例查询不存在的模式限定关系,再创建有效关系并读取它。PostgreSQL 18.6 和隔离的 PostgreSQL 10.21 目标均返回 42P01,连接保持 IDLE,修正后的查询成功。run ID 和断言见公开证据 JSON。

含义与触发路径 {#meaning}

解析阶段会根据当前命名空间和 search_path 解析每个关系。如果限定名称不存在,parse_relation.c 产生两部分名称报文;如果未限定名称不存在,则产生一部分名称报文。拼写错误、迁移尚未执行、连接了错误数据库、search_path 不同,或者带引号标识符大小写不一致,都可能产生这个 SQLSTATE。

这是名称解析错误,不等于物理表一定被删除。关系可能存在于另一个模式或数据库中,角色也可能缺少查看或使用它所需的权限。反过来,按猜测的名称创建表会掩盖部署或引用错误。

解析器还会在某些无效 FROM 项引用和 CTE 前向引用中使用 42P01,但 detail 或 hint 可能不同。应结合完整报文和上下文,将这些形式与缺少关系区分开。

报文与诊断 {#messages}

runner 的操作先限定模式查询,再查询修正后的关系。隔离 harness 提供临时模式;查询形状如下:

SELECT * FROM does_not_exist;
CREATE TABLE exists(id integer PRIMARY KEY);
SELECT count(*) FROM exists;

PostgreSQL 18.6 返回:

SQLSTATE: 42P01
severity: ERROR
message_primary: relation "c42p01_missing_relation.does_not_exist" does not exist
source: parse_relation.c / parserOpenTable / line 1480

PG10 目标返回相同的主报文,对应源码行号为 1159。限定形式会在报文中保留模式和关系名称。未限定引用使用固定源码模板 relation "%s" does not exist;CTE 前向引用或无效 FROM 引用可能附带 detail 或 hint。

诊断 {#diagnosis}

记录 SQLSTATE、主报文、detail、hint、语句位置、当前数据库、角色和 search_path。检查应用使用的准确拼写与引用方式。通过有权限的管理连接查询 pg_class/pg_namespace 或使用 to_regclass(),确认关系实际存在的位置。

对照已部署迁移版本、连接数据库和模式。连接池中的 session 可能带有不同于建表连接的 search_path。如果对象预期是临时对象,应确认查询仍在创建它的同一个 session 中执行。

代表性错误发生在自动提交下,连接保持 IDLE;修正后的查询返回 count 0 并仍为 IDLE。如果缺少关系的引用发生在显式事务中,事务仍可能进入 INERROR,因此应记录实际状态,不要假定所有 42P01 都不会影响周围工作。

处理与修复 {#response}

按部署和应用配置修复名称解析原因:

  • 明确选择目标模式,或为 session 设置并验证 search_path。
  • 在提供查询前于正确数据库执行缺少的迁移。
  • 对大小写敏感的标识符保留准确的双引号;检查依赖后再按统一约定重命名。
  • 只有在缺少对象是预期分支时才使用 to_regclass() 等预检;意外部署失败不应静默创建替代关系。

修正关系后重新执行原查询,并验证返回值和事务状态。成功执行 CREATE TABLE 或打开新连接,都不能证明所有应用 session 解析到同一个对象。

版本与边界 {#versions}

目录在 PostgreSQL 7.4 的锁定定义中已观察到 42P01,并持续到 8.4.22 的 pre-9.0 定义;随后在列出的所有正式快照直到 PostgreSQL 18.6 以及 PostgreSQL 19 Beta 3 预览中存在。这是 definition_only 的存在边界,不是确切实现引入版本或运行时使用断言。扫描范围内没有记录该条件的定义变化。

缺少关系案例在 PostgreSQL 18.6 和 10.21 上均通过。源码行号和解析器 hint 会因版本及引用形式变化。本页覆盖模式限定的缺少关系和有效后续查询,不覆盖所有使用 42P01 的命名空间或访问规则路径。

相关 {#related}

42P02 — undefined_parameter 处理缺少查询参数。3F000 — invalid_schema_name 处理无效模式名称。42501 — insufficient_privilege 是名称解析之后的访问失败。57014 — query_canceled 可能中断修复查询,但原因不同。

来源 {#sources}

结构化证据记录在公开证据 JSON中。源码记录固定到 PostgreSQL commit 724edf9bde9d356724ad384a2e196edc3c9f80f7;运行记录保留两个目标 ID 和结构化观察。

比较版本

SQLSTATE 证据与已记录的运行版本

cases · missing_relation
{
  "assertions": [
    "SQLSTATE is 42P01",
    "The missing relation is named in the diagnostic",
    "A valid query succeeds after correcting the relation name"
  ],
  "case_id": "missing_relation",
  "cleanup": "Drop the case schema with an owner connection.",
  "has_snippet": true,
  "position": 0,
  "preconditions": [
    "A disposable schema name that has no relation"
  ],
  "repair": "Check schema qualification, search_path, migrations, and case-sensitive quoting before creating or renaming objects.",
  "trigger": "Select from a relation that does not exist.",
  "versions": [
    "10",
    "18"
  ]
}
claims · identity.class-and-condition
{
  "claim_id": "identity.class-and-condition",
  "limits": "The historical condition name covers relation lookup failures beyond a literal table.",
  "method": "Read the Class 42 section and 42P01 row in the frozen errcodes.txt snapshot.",
  "position": 0,
  "runtime": [],
  "sources": [
    "src.errcodes.18.6"
  ],
  "statement": "42P01 is the undefined_table condition in Class 42 syntax_error_or_access_rule_violation."
}
claims · mechanism.relation-lookup
{
  "claim_id": "mechanism.relation-lookup",
  "limits": "The displayed relation name depends on qualification, search_path, quoting, and the parse context.",
  "method": "Trace namespace.c lookup and parserOpenTable qualified and unqualified error branches in the fixed source, then check the protocol field reference.",
  "position": 1,
  "runtime": [],
  "sources": [
    "src.namespace.18.6",
    "src.parse-relation.18.6",
    "doc.ddl.18.6",
    "doc.protocol.18"
  ],
  "statement": "The parser reports ERRCODE_UNDEFINED_TABLE with relation \"%s.%s\" does not exist for a qualified relation and relation \"%s\" does not exist for an unqualified relation."
}
claims · runtime.missing-relation-recovery
{
  "claim_id": "runtime.missing-relation-recovery",
  "limits": "This case does not distinguish migration races, search_path changes, permissions, or all relation kinds.",
  "method": "Execute the missing query, inspect diagnostics and status, create the schema-qualified relation, and assert a valid follow-up query.",
  "position": 2,
  "runtime": [],
  "sources": [
    "case-manifest.42P01",
    "snippet-registry.42P01.final",
    "runtime.42P01-registry-final-20260909.latest",
    "runtime.42P01-registry-final-20260909.pg10"
  ],
  "statement": "A missing relation query returned SQLSTATE 42P01 while autocommit remained IDLE; creating the intended relation and querying it returned count 0 on both targets."
}
claims · versions.catalogue-boundary
{
  "claim_id": "versions.catalogue-boundary",
  "limits": "The first scanned release is a lower bound, not an asserted introduction version.",
  "method": "Read the manifest snapshots and definition references for the code.",
  "position": 3,
  "runtime": [],
  "sources": [
    "manifest.42P01"
  ],
  "statement": "The locked catalogue records 42P01 in every listed formal snapshot from 9.0.23 through 18.6 and in 19beta3; pre-9.0 history is not scanned."
}
messages · message.qualified-relation
{
  "limits": "The qualified form is selected when the parser has a schema-qualified relation reference.",
  "message_id": "message.qualified-relation",
  "path": "",
  "position": 0,
  "raw": {
    "id": "message.qualified-relation",
    "limits": "The qualified form is selected when the parser has a schema-qualified relation reference.",
    "primary_template": "relation \"%s.%s\" does not exist",
    "severity_source": "explicit ERROR",
    "sources": [
      "src.parse-relation.18.6"
    ],
    "sqlstate": "42P01"
  },
  "severity": "explicit ERROR",
  "sources": [
    "src.parse-relation.18.6"
  ],
  "templates": [
    {
      "kind": "primary",
      "literal": "relation \" . \" does not exist",
      "position": 0,
      "role": "",
      "template": "relation \"%s.%s\" does not exist"
    }
  ]
}
messages · message.unqualified-relation
{
  "limits": "The unqualified form is selected when lookup through the active namespace fails.",
  "message_id": "message.unqualified-relation",
  "path": "",
  "position": 1,
  "raw": {
    "id": "message.unqualified-relation",
    "limits": "The unqualified form is selected when lookup through the active namespace fails.",
    "primary_template": "relation \"%s\" does not exist",
    "severity_source": "explicit ERROR",
    "sources": [
      "src.parse-relation.18.6"
    ],
    "sqlstate": "42P01"
  },
  "severity": "explicit ERROR",
  "sources": [
    "src.parse-relation.18.6"
  ],
  "templates": [
    {
      "kind": "primary",
      "literal": "relation \" \" does not exist",
      "position": 0,
      "role": "",
      "template": "relation \"%s\" does not exist"
    }
  ]
}
runtimes · runtime.42P01-registry-final-20260909.latest · 18.6 (Homebrew) · passed
{
  "cases": [
    "missing_relation"
  ],
  "limits": "",
  "position": 0,
  "raw": {
    "cases": [
      "missing_relation"
    ],
    "id": "runtime.42P01-registry-final-20260909.latest",
    "observed": {
      "diagnostic": {
        "message_primary": "relation \"c42p01_missing_relation.does_not_exist\" does not exist",
        "severity": "ERROR",
        "source_file": "parse_relation.c",
        "source_function": "parserOpenTable",
        "source_line": "1480",
        "sqlstate": "42P01"
      },
      "statuses": {
        "after_error": "IDLE",
        "after_valid_query": "IDLE"
      },
      "valid_count": 0
    },
    "raw": "verify/results/42P01-registry-final-20260909/latest/raw.jsonl",
    "raw_sha256": "c65e0596cb51d32791448e493b01de0bfda519bb35ed5d1153f07c156bd617ac",
    "run_id": "42P01-registry-final-20260909",
    "server_version": "18.6 (Homebrew)",
    "server_version_num": 180006,
    "snippet_registry": {
      "path": "verify/cases/42P01/snippets.json",
      "sha256": "f4eb28d6bc0d0d250d5dc548ed83a0783538eb73a07ab8b3670f218bcc21aba5"
    },
    "status": "passed",
    "summary": "verify/results/42P01-registry-final-20260909/latest/summary.json",
    "summary_sha256": "2b61950cb5a1a8f42fe130f2ad8407cb7cbaf4dfb396481fdf88d0d5769e3e37",
    "target": "latest"
  },
  "run_id": "42P01-registry-final-20260909",
  "runtime_id": "runtime.42P01-registry-final-20260909.latest",
  "server_version": "18.6 (Homebrew)",
  "status": "passed",
  "target": "latest"
}
runtimes · runtime.42P01-registry-final-20260909.pg10 · 10.21 (Debian 10.21-1.pgdg90+1) · passed
{
  "cases": [
    "missing_relation"
  ],
  "limits": "",
  "position": 1,
  "raw": {
    "cases": [
      "missing_relation"
    ],
    "id": "runtime.42P01-registry-final-20260909.pg10",
    "image": "postgres@sha256:b2baf8998630663d21370da06387c950e587071bdd307ee34e661cdcc7442bcc",
    "observed": {
      "diagnostic": {
        "message_primary": "relation \"c42p01_missing_relation.does_not_exist\" does not exist",
        "severity": "ERROR",
        "source_file": "parse_relation.c",
        "source_function": "parserOpenTable",
        "source_line": "1159",
        "sqlstate": "42P01"
      },
      "statuses": {
        "after_error": "IDLE",
        "after_valid_query": "IDLE"
      },
      "valid_count": 0
    },
    "raw": "verify/results/42P01-registry-final-20260909/pg10/raw.jsonl",
    "raw_sha256": "da4b4fcbbff2d04b8a03d0b7718cfe8b1954439f3bf3125cd8b79eaa88eeed79",
    "run_id": "42P01-registry-final-20260909",
    "server_version": "10.21 (Debian 10.21-1.pgdg90+1)",
    "server_version_num": 100021,
    "snippet_registry": {
      "path": "verify/cases/42P01/snippets.json",
      "sha256": "f4eb28d6bc0d0d250d5dc548ed83a0783538eb73a07ab8b3670f218bcc21aba5"
    },
    "status": "passed",
    "summary": "verify/results/42P01-registry-final-20260909/pg10/summary.json",
    "summary_sha256": "3049254a6a818ed4401abdaee428fee0f17c4d6e299a4353e880ad6fe37a38d9",
    "target": "pg10"
  },
  "run_id": "42P01-registry-final-20260909",
  "runtime_id": "runtime.42P01-registry-final-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": "",
  "location": "lines 372-378",
  "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.parse-relation.18.6
{
  "commit": "724edf9bde9d356724ad384a2e196edc3c9f80f7",
  "docs_url": "",
  "kind": "",
  "location": "lines 1473-1501",
  "path": "src/backend/parser/parse_relation.c",
  "position": 1,
  "sha256": "0d9c88f4a8def4c2d982c33f13208590e21ecf5e6f8cd9d7faa223dc771c9a9a",
  "source_id": "src.parse-relation.18.6",
  "tag": "REL_18_6",
  "url": "https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/parser/parse_relation.c#L1473-L1501"
}
sources · src.namespace.18.6
{
  "commit": "724edf9bde9d356724ad384a2e196edc3c9f80f7",
  "docs_url": "",
  "kind": "",
  "location": "lines 626-640",
  "path": "src/backend/catalog/namespace.c",
  "position": 2,
  "sha256": "8c9e6a99e84fa2cec8a9b1de2ecbe3966a13f4ad68c6ccfbfb8134a754d73e56",
  "source_id": "src.namespace.18.6",
  "tag": "REL_18_6",
  "url": "https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/catalog/namespace.c#L626-L640"
}
sources · doc.ddl.18.6
{
  "commit": "724edf9bde9d356724ad384a2e196edc3c9f80f7",
  "docs_url": "",
  "kind": "",
  "location": "schemas, search_path, and namespace resolution",
  "path": "doc/src/sgml/ddl.sgml",
  "position": 3,
  "sha256": "ce1919d9236f2e71672660e1a347146472e966e4d19b77fde5ae345dd1db6ec7",
  "source_id": "doc.ddl.18.6",
  "tag": "PG18-docs",
  "url": "https://www.postgresql.org/docs/18/ddl-schemas.html"
}
sources · doc.protocol.18
{
  "commit": "724edf9bde9d356724ad384a2e196edc3c9f80f7",
  "docs_url": "",
  "kind": "",
  "location": "ErrorResponse fields",
  "path": "doc/src/sgml/protocol.sgml",
  "position": 4,
  "sha256": "745339e07ebbc2bb67d98b258e25772ada644ef26011e3cd6b3fcbb435235f89",
  "source_id": "doc.protocol.18",
  "tag": "PG18-docs",
  "url": "https://www.postgresql.org/docs/18/protocol-error-fields.html"
}
sources · manifest.42P01
{
  "commit": "",
  "docs_url": "",
  "kind": "local_artifact",
  "location": "snapshots and definition_blobs entries for the 42P01 definition",
  "path": "sources/manifest.lock.json",
  "position": 5,
  "sha256": "1727a275f336988ff96b4f9990a4ca253080f73fc5d316e7def165c8cf3708a8",
  "source_id": "manifest.42P01",
  "tag": "",
  "url": "../sources/manifest.lock.json"
}
sources · case-manifest.42P01
{
  "commit": "",
  "docs_url": "",
  "kind": "local_artifact",
  "location": "missing_relation",
  "path": "verify/cases/42P01/cases.json",
  "position": 6,
  "sha256": "d0bd0702654b03dce66b733f5e4660b643db270682616c5927c9b10a12327088",
  "source_id": "case-manifest.42P01",
  "tag": "",
  "url": "../verify/cases/42P01/cases.json"
}
sources · snippet-registry.42P01.final
{
  "commit": "",
  "docs_url": "",
  "kind": "local_artifact",
  "location": "missing_relation ordered SQL",
  "path": "verify/cases/42P01/snippets.json",
  "position": 7,
  "sha256": "f4eb28d6bc0d0d250d5dc548ed83a0783538eb73a07ab8b3670f218bcc21aba5",
  "source_id": "snippet-registry.42P01.final",
  "tag": "",
  "url": "../verify/cases/42P01/snippets.json"
}

来源引用

完整定义与证据 JSON

定义来源

center · PostgreSQL 18 · english-manuals:a4976e32bb384e78721bdb7f657a935e0d83939bf0999c6e8a2bd26708e5e407

正文语言: zh-Hans · english-manuals:a4976e32bb384e78721bdb7f657a935e0d83939bf0999c6e8a2bd26708e5e407