百科 / 错误代码 / Class 22 数据异常
22P02 invalid_text_representation
文本表示无效
ERROR 已实测 详解 实测通过
- 条件名
invalid_text_representation- 宏名称
ERRCODE_INVALID_TEXT_REPRESENTATION- 启用版本
- 7.4
- 状态
- 活跃
版本覆盖
速览
22P02 表示文本输入例程无法把值解释为目标类型。本页选择普通整数输入路径,同时标出 COPY/文本边界;COPY、枚举、扩展和 contrib 调用可能使用不同主报文。
含义
cast、赋值或文本 COPY 字段由目标类型的输入例程判断文本是否合法。PostgreSQL 18.6 使用 invalid input syntax for type integer: "%s",锁定的 PostgreSQL 10.23 源码使用 invalid input syntax for integer: "%s";两者都是动态模板,也不是统一的本地化字符串。其他固定调用者还包括 COPY reject-limit、枚举输入和扩展校验,因此 primary 文本和上下文可能不同。
诊断
记录目标类型、客户端编码和参数绑定后的原始值,并确认操作是 cast、赋值、文本 COPY 字段、枚举输入还是其他类型包装。把坏文本(22P02)与数值越界(22003)、日期时间语法错误(22007)、二进制表示无效(22P03)以及 COPY 文件/头部或 framing 错误(22P04)区分开。二进制 COPY payload 不能只按文本输入报文诊断。
处理
在输入边界校验并保持预期目标类型。只有修正值后才重试;除非业务规则明确要求,不要静默截断或把值变成 NULL。显式事务中的输入 ERROR 会使事务进入中止状态(25P02);继续前执行 ROLLBACK,或使用 ROLLBACK TO SAVEPOINT convert_input。COPY 出错后也必须先恢复事务,再执行下一条命令。
可复现案例
在一次性实例上执行过的场景。其中 1 个附有可执行 SQL,正文相应小节里给出。
invalid_integer_text PG 10 / 18 有 SQL
前置条件
- A runner-owned disposable target is provisioned.
触发
Cast non-numeric text to integer, then cast a valid integer text on the same connection.
断言
- SQLSTATE is 22P02 with ERROR severity
- The primary diagnostic identifies invalid integer input and the supplied text
- The failed autocommit session remains IDLE
- A valid integer text returns 42 afterward
处置
Validate or reject input before casting; if the input is valid, cast it to the intended type and keep the business validation separate from syntax recovery.
清理
Close all runner connections and drop the case schema with an owner connection.
实测诊断
普通整数路径固定为 ERROR,并有上述版本差异的动态主报文。选定实测记录了精确值:"not-an-integer" 产生 22P02,同一自动提交会话随后把合法 "42" 转换为 42。
报文模板
源码里的格式串,不是某一次运行的输出。%s 之类是占位符,实际报文会填入对象名与取值。适用范围一栏是核验时留下的原始英文记录,未经翻译。
skipped more than REJECT_LIMIT (%" PRId64 ") rows due to data type incompatibility
来源:src/backend/commands/copyfrom.c @ REL_18_6 · contrib/file_fdw/file_fdw.c @ REL_18_6
cannot cast EAN13(%s) to %s for number: "%s"
invalid character in extension owner: must not contain any of "%s"
invalid input syntax for type integer: "%s"
invalid input syntax for integer: "%s"
代表案例
共享注册表在自动提交下先发送一次无效文本 cast,检查真实诊断和 IDLE 状态,再在同一连接发送合法整数文本。这个实测恢复不同于显式事务;后者必须先回滚或回滚到保存点。页面 SQL 与运行器来自同一注册表,没有隐藏的第二定义。
SELECT 'not-an-integer'::integer;
SELECT '42'::integer
选定的 PostgreSQL 18.6 与 10.21 运行均通过 SQLSTATE、严重级别、状态或断开恢复、修复、清理和一次性实例停止断言。详见 案例 JSON 与 作者证据。
版本
锁定目录从 7.4 起记录 22P02。18.6 与 10.21 的有界运行均通过,但主报文措辞如上有所不同;这不能推广到所有 22P02 调用方或所有中间版本。
来源
- 上游源码 src/backend/utils/errcodes.txt 第 206 行
- 上游源码 src/backend/utils/adt/numutils.c 第 59–62 行
- 上游源码 src/backend/utils/adt/numutils.c 第 614–618 行
- 上游源码 src/backend/commands/copyfrom.c 第 1169 行
- 上游源码 contrib/file_fdw/file_fdw.c 第 799 行
- 上游源码 contrib/isn/isn.c 第 409 行
- 上游源码 src/backend/commands/extension.c 第 1366 行
- 核验材料 verify/cases/22P02/cases.json
- 核验材料 verify/cases/22P02/snippets.json
- 核验材料 raw/calls/REL_10_23.jsonl
- 核验材料 raw/calls/REL_18_6.jsonl
证据
断言
每条断言都写明了是怎么核实的,以及它不覆盖什么。这一层是核验时留下的原始英文记录,照原样呈现,未经翻译。
-
22P02 is invalid_text_representation in SQLSTATE Class 22.
-
The cited PostgreSQL 18.6 source paths support the representative mechanisms and message boundaries described.
-
The locked catalogue records 22P02 from 7.4; that boundary does not prove exact implementation introduction.
-
The selected ordinary cast path reports invalid integer text through the numeric input routine; PostgreSQL 18 and 10 use different fixed wording around the type name.
-
The invalid_integer_text case passed on isolated PostgreSQL 18.6 and 10.21 targets, with IDLE recovery and a same-session valid value of 42.
运行记录
| 目标 | 服务器版本 | 结果 | 覆盖案例 |
|---|---|---|---|
| latest | 18.6 (Homebrew) | passed | invalid_integer_text |
| pg10 | 10.21 (Debian 10.21-1.pgdg90+1) | passed | invalid_integer_text |
同类错误代码
Class 22 数据异常 下的其他成员。
22000data_exception22001string_data_right_truncation22002null_value_no_indicator_parameter22003numeric_value_out_of_range22004null_value_not_allowed22005error_in_assignment22007invalid_datetime_format22008datetime_field_overflow22009invalid_time_zone_displacement_value2200Bescape_character_conflict2200Cinvalid_use_of_escape_character2200Dinvalid_escape_octet2200Fzero_length_character_string2200Gmost_specific_type_mismatch2200Hsequence_generator_limit_exceeded2200Lnot_an_xml_document2200Minvalid_xml_document2200Ninvalid_xml_content2200Sinvalid_xml_comment2200Tinvalid_xml_processing_instruction22010invalid_indicator_parameter_value22011substring_error22012division_by_zero22013invalid_preceding_or_following_size22014invalid_argument_for_ntile_function22015interval_field_overflow22016invalid_argument_for_nth_value_function22018invalid_character_value_for_cast22019invalid_escape_character2201Binvalid_regular_expression2201Einvalid_argument_for_logarithm2201Finvalid_argument_for_power_function2201Ginvalid_argument_for_width_bucket_function2201Winvalid_row_count_in_limit_clause2201Xinvalid_row_count_in_result_offset_clause22021character_not_in_repertoire22022indicator_overflow22023invalid_parameter_value22024unterminated_c_string22025invalid_escape_sequence22026string_data_length_mismatch22027trim_error2202Earray_subscript_error2202Ginvalid_tablesample_repeat2202Hinvalid_tablesample_argument22030duplicate_json_object_key_value22031invalid_argument_for_sql_json_datetime_function22032invalid_json_text22033invalid_sql_json_subscript22034more_than_one_sql_json_item22035no_sql_json_item22036non_numeric_sql_json_item22037non_unique_keys_in_a_json_object22038singleton_sql_json_item_required22039sql_json_array_not_found2203Asql_json_member_not_found2203Bsql_json_number_not_found2203Csql_json_object_not_found2203Dtoo_many_json_array_elements2203Etoo_many_json_object_members2203Fsql_json_scalar_required2203Gsql_json_item_cannot_be_cast_to_target_type22P01floating_point_exception22P03invalid_binary_representation22P04bad_copy_file_format22P05untranslatable_character22P06nonstandard_use_of_escape_character