2026년 07월 04일 | DBMS Error 가이드
이 글에서 다루는 내용
42846 에러의 원인 분석, 해결 SQL, 예방 방법을 실무 관점에서 정리합니다.
42846 cannot coerce 는?
PostgreSQL 에러 코드 42846 cannot coerce는 데이터 타입 간 변환(캐스팅)이 불가능할 때 발생하는 오류입니다. 즉, PostgreSQL이 특정 데이터 타입을 다른 데이터 타입으로 자동 또는 명시적으로 변환하려 할 때, 해당 변환 경로가 시스템 카탈로그에 정의되어 있지 않거나 지원되지 않을 경우에 발생합니다. 이 에러는 주로 함수 호출, 연산자 사용, INSERT/UPDATE 문에서 컬럼 타입과 값 타입이 맞지 않을 때 혹은 CAST 구문을 잘못 사용했을 때 자주 나타납니다.
주요 발생 원인
- 지원되지 않는 데이터 타입 간 직접 캐스팅 시도
PostgreSQL은 모든 데이터 타입 쌍 사이에 캐스팅 경로를 제공하지 않습니다. 예를 들어 boolean 타입을 integer로 직접 변환하는 것은 일부 버전이나 상황에서 오류를 유발할 수 있으며, json 타입을 xml 타입으로 바로 변환하려는 시도도 이 에러를 발생시킵니다. PostgreSQL의 pg_cast 시스템 카탈로그에 해당 변환 경로가 등록되어 있지 않으면 에러가 발생합니다.
- 함수 인자 타입 불일치
특정 함수는 엄격하게 정해진 인자 타입만 받을 수 있는데, 이와 맞지 않는 타입의 값을 넘기면 PostgreSQL이 묵시적 변환을 시도하다 실패하면서 42846 에러가 발생합니다. 예를 들어 to_timestamp() 함수에 integer 타입 대신 text 타입을 넘기거나, 사용자 정의 함수에 잘못된 타입의 인자를 전달하는 경우가 대표적입니다. 함수 오버로딩이 존재하더라도, 묵시적 캐스트 경로가 없으면 에러로 이어집니다.
- 복합 타입 또는 도메인 타입 변환 실패
사용자 정의 복합 타입(composite type)이나 도메인(domain) 타입을 기본 타입으로 또는 다른 복합 타입으로 변환하려 할 때 캐스트가 정의되어 있지 않으면 이 에러가 발생합니다. 특히 ORM 프레임워크나 마이그레이션 도구가 자동으로 생성한 쿼리에서 타입 변환을 명시하지 않은 채 실행될 때 자주 마주칩니다. 이 경우 개발자가 직접 CREATE CAST 구문으로 캐스트를 정의해야 합니다.
해결 방법
원인 1: 지원되지 않는 타입 간 캐스팅 — 중간 타입을 통한 우회 변환
직접 변환이 불가능한 경우, text와 같은 중간 타입을 경유하여 변환하는 방식이 가장 범용적인 해결책입니다.
-- 잘못된 예: json을 xml로 직접 변환 시도 (42846 에러 발생)
SELECT CAST('{"key": "value"}'::json AS xml);
-- 올바른 예: json → text → xml 순서로 단계적 변환
SELECT CAST(('{"key": "value"}'::json)::text AS xml);
-- 또는 xmlparse 함수를 활용한 명시적 변환
SELECT xmlparse(content '{"key": "value"}');
-- pg_cast 카탈로그에서 지원 가능한 변환 경로 확인
SELECT
pg_catalog.format_type(castsource, NULL) AS source_type,
pg_catalog.format_type(casttarget, NULL) AS target_type,
castcontext
FROM pg_catalog.pg_cast
WHERE pg_catalog.format_type(castsource, NULL) = 'json'
ORDER BY target_type;
원인 2: 함수 인자 타입 불일치 — 명시적 CAST 또는 타입 변환 함수 사용
함수에 전달하는 인자의 타입을 명시적으로 변환하여 올바른 타입을 넘겨야 합니다.
-- 잘못된 예: integer 타입의 unix timestamp를 text로 넘기는 경우
SELECT to_timestamp('1700000000'); -- 오류 가능성
-- 올바른 예: 명시적 CAST로 타입 지정
SELECT to_timestamp(1700000000::double precision);
-- 잘못된 예: 사용자 정의 함수에 잘못된 타입 전달
CREATE FUNCTION get_user_name(user_id integer) RETURNS text AS $$
SELECT name FROM users WHERE id = user_id;
$$ LANGUAGE sql;
SELECT get_user_name('42'); -- text를 넘기면 묵시적 변환 실패 가능
-- 올바른 예: 명시적 캐스팅으로 타입 맞추기
SELECT get_user_name('42'::integer);
SELECT get_user_name(CAST('42' AS integer));
-- 함수가 받는 인자 타입 확인 방법
SELECT
p.proname AS function_name,
pg_catalog.pg_get_function_arguments(p.oid) AS arguments
FROM pg_catalog.pg_proc p
WHERE p.proname = 'get_user_name';
원인 3: 복합/도메인 타입 변환 — 커스텀 CAST 정의
변환이 필요한 타입 쌍에 대해 CREATE CAST로 변환 경로를 명시적으로 등록합니다.
-- 예시: 사용자 정의 도메인 타입과 기본 타입 간 캐스트 정의
CREATE DOMAIN email_address AS text
CHECK (VALUE ~* '^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$');
-- 도메인 → text 변환 함수 생성
CREATE OR REPLACE FUNCTION email_to_text(email_address)
RETURNS text AS $$
SELECT $1::text;
$$ LANGUAGE sql IMMUTABLE STRICT;
-- 커스텀 캐스트 등록
CREATE CAST (email_address AS text)
WITH FUNCTION email_to_text(email_address)
AS IMPLICIT;
-- 이제 아래와 같이 자유롭게 변환 가능
SELECT 'user@example.com'::email_address::text;
-- INSERT 시 타입 불일치 문제 해결 예시
CREATE TABLE contacts (
id serial PRIMARY KEY,
email email_address
);
-- 명시적 캐스팅으로 안전하게 삽입
INSERT INTO contacts (email) VALUES ('user@example.com'::email_address);
-- 변환 가능 여부 사전 점검 (pg_cast 조회)
SELECT
src.typname AS source,
tgt.typname AS target,
CASE castcontext
WHEN 'i' THEN 'implicit'
WHEN 'a' THEN 'assignment'
WHEN 'e' THEN 'explicit only'
END AS cast_context
FROM pg_cast c
JOIN pg_type src ON c.castsource = src.oid
JOIN pg_type tgt ON c.casttarget = tgt.oid
WHERE src.typname = 'email_address';
예방 방법
- 스키마 설계 단계에서 타입 호환성을 사전 검증하라
테이블 컬럼 타입을 정의할 때, 애플리케이션 레이어에서 사용하는 데이터 타입과의 호환성을 미리 확인해야 합니다. pg_cast 카탈로그를 주기적으로 조회하여 사용 중인 커스텀 타입 간의 캐스트 경로가 올바르게 등록되어 있는지 점검하는 것이 좋습니다. 특히 도메인 타입이나 복합 타입을 도입할 때는 관련 캐스트 정의를 마이그레이션 스크립트에 함께 포함시켜, 배포 환경 전반에서 일관성을 유지하도록 하십시오.
- 묵시적 캐스트에 의존하지 말고 항상 명시적 타입 변환을 사용하라
SQL 코드 작성 시 묵시적 타입 변환에 의존하는 것은 PostgreSQL 버전 업그레이드나 설정 변경 시 예상치 못한 에러를 유발할 수 있습니다. 모든 타입 변환은 CAST(value AS type) 또는 value::type 구문을 사용하여 명시적으로 처리하고, 코드 리뷰 체크리스트에 “타입 변환 명시 여부”를 포함시켜 팀 전체가 이 원칙을 지키도록 문화화하는 것이 효과적입니다.
관련 에러
- 42883
undefined_function: 주어진 인자 타입에 맞는 함수가 존재하지 않을 때 발생하며, 42846과 유사하게 타입 불일치 문제에서 비롯됩니다. - 42804
datatype_mismatch: 연산자나 함수에서 기대하는 타입과 실제 타입이 일치하지 않을 때 발생하는 에러로, 42846과 함께 타입 관련 에러의 주요 군을 형성합니다. - 22P02
invalid_text_representation: 문자열을 다른 타입으로 변환할 때 형식이 맞지 않아 실패하는 경우로, 캐스팅 자체는 가능하지만 값 형식이 잘못된 경우입니다.
주요 DBMS error code를 정리하는 시리즈입니다.
블로그 홈에서 다른 에러도 확인하세요.
본 포스트는 AI가 생성한 기술 가이드입니다. 운영 환경 적용 전 충분한 검토를 권장합니다.