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 和结构化观察。
src.errcodes.18.6—errcodes.txtsrc.parse-relation.18.6—parse_relation.csrc.namespace.18.6—namespace.cdoc.ddl.18.6— 模式- Runtime:latest 与 pg10 均为
42P01-registry-final-20260909,结构化观察见公开证据 JSON
比较版本
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"
}来源引用
定义来源
center · PostgreSQL 18 · english-manuals:a4976e32bb384e78721bdb7f657a935e0d83939bf0999c6e8a2bd26708e5e407
正文语言: zh-Hans · english-manuals:a4976e32bb384e78721bdb7f657a935e0d83939bf0999c6e8a2bd26708e5e407