# 42P18 — 无法确定数据类型

> PostgreSQL SQLSTATE 42P18：来源与诊断参考。
---

# 42P18 — 无法确定数据类型

## 速览 {#at-a-glance}

`42P18`（**indeterminate_datatype**）表达式或协议参数没有确定类型时，类型推断会失败。

<!-- BEGIN SQLSTATE FACTS: generated by scripts/generate.py; do not edit -->

| 字段 | 值 |
| --- | --- |
| SQLSTATE | `42P18` |
| 条件名 | `indeterminate_datatype` |
| 状态 | `有效` |
| 已知存在于 | `7.4` |
| 锁定快照 | `9.0.23, 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_INDETERMINATE_DATATYPE` |
| 别名 | `—` |

<!-- source facts: data/errcodes/42P18.json -->
<!-- END SQLSTATE FACTS -->

## 含义 {#meaning}

解析器无法为表达式或协议参数确定唯一类型。18.6 核心明确报告空 `ARRAY[]`；`pg_analyze_and_rewrite_varparams` 还会在最后检查每个仍为 `InvalidOid` 或 `UNKNOWNOID` 的参数，例如没有任何上下文约束的 `$1`。这不同于 42P08（输入暗示了互相不兼容的类型）和 42P02（参数引用本身不存在）。

## 诊断 {#diagnosis}

根据响应中的位置或参数编号定位问题。对于 `ARRAY[]`，检查周围表达式并转换到预期元素类型；对于 `$n`，检查 Parse/扩展查询的参数类型以及应当约束它的所有上下文，再确认最后的参数类型检查能够得到 OID。客户端不发送类型 OID 时，服务器可能无法完成推断。互相冲突的推断属于 42P08；引用未声明参数属于 42P02。

## 处理 {#response}

添加语义正确的显式转换或参数类型信息，然后确认运算符和结果列仍是预期类型。不要把所有值都转成 text 来掩盖错误，这会改变索引使用以及函数/运算符选择；确认定义修正后再重试解析或语句。如果 ERROR 发生在显式事务中，发送修正语句前先 `ROLLBACK` 或回滚到错误前的保存点。

## 消息 {#messages}

固定源码中的代表性消息包括：message: `cannot determine type of empty array`; HINT: `Explicitly cast to the desired type, for example ARRAY[]::integer[].`；message: `could not determine data type of parameter $%d`。占位符由实际对象、列或参数填充。

## 版本 {#versions}

锁定目录显示该条件最早见于 PostgreSQL 7.4；行为说明固定在 PostgreSQL 18.6 源码，目录存在范围不等于每条消息或功能都从该版本开始。

## 相关 {#related}

- [`42P08`](../42p08/)
- [`42P02`](../42p02/)

## 来源 {#sources}

源码消息、行号和证据边界见 [作者证据](../../data/evidence/42p18.json)。

- `src/backend/parser/parse_expr.c:2102-2107` ([fixed source](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/parser/parse_expr.c#L2102-L2107))
- `src/backend/tcop/postgres.c:733-736` ([fixed source](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/tcop/postgres.c#L733-L736))
