2026년 07월 07일 | DBMS Error 가이드
이 글에서 다루는 내용
42P18 에러의 원인 분석, 해결 SQL, 예방 방법을 실무 관점에서 정리합니다.
42P18 indeterminate datatype 는?
PostgreSQL 에러 코드 42P18 indeterminate datatype은 쿼리 실행 시 PostgreSQL이 특정 표현식 또는 파라미터의 데이터 타입을 결정할 수 없을 때 발생합니다. 주로 타입 정보가 없는 리터럴 값(예: NULL, 또는 타입이 명시되지 않은 파라미터)을 사용할 때 옵티마이저가 해당 값의 타입을 추론하지 못해 발생합니다. 이 에러는 동적 SQL, 준비된 구문(Prepared Statement), 또는 함수 오버로딩 환경에서 특히 자주 목격됩니다.
주요 발생 원인
1. 타입 캐스트 없이 NULL 또는 타입 미지정 리터럴 사용
가장 흔한 원인으로, NULL 값이나 타입이 명시되지 않은 리터럴 값을 함수 인자나 UNION, CASE 등의 표현식에 직접 사용할 때 발생합니다. PostgreSQL은 문맥(context)으로부터 타입을 유추하려 시도하지만, 유추할 수 있는 충분한 정보가 없으면 이 에러를 발생시킵니다. 예를 들어, SELECT $1처럼 준비된 구문에서 파라미터만 단독으로 선택하면 PostgreSQL은 $1의 타입을 알 수 없습니다.
2. 오버로딩된 함수에 모호한 인자 전달
PostgreSQL은 동일한 이름의 함수를 인자 타입에 따라 다르게 동작하도록 오버로딩을 지원합니다. 하지만 타입이 명확하지 않은 값을 인자로 전달하면, PostgreSQL이 어떤 함수 시그니처를 선택해야 할지 결정하지 못해 42P18 에러가 발생할 수 있습니다. 이는 사용자 정의 함수(UDF)뿐만 아니라 내장 함수에서도 동일하게 나타납니다.
3. PREPARE 구문에서 파라미터 타입 미지정
PREPARE 구문을 사용할 때 파라미터의 타입을 명시하지 않고, 쿼리 문맥으로부터도 타입을 추론할 수 없는 경우 이 에러가 발생합니다. 특히 ORM이나 드라이버가 내부적으로 PREPARE를 사용하는 경우, 개발자가 인지하지 못한 상태에서 이 에러가 발생하기도 합니다. 파라미터가 SELECT $1처럼 단독으로 노출되거나, 타입을 강제할 수 없는 위치에 놓이는 경우가 대표적입니다.
해결 방법
해결 1: 명시적 타입 캐스트(Type Cast) 사용
타입이 불명확한 값에 대해 ::타입 또는 CAST(값 AS 타입) 구문을 사용하여 명시적으로 타입을 지정합니다.
-- 에러 발생: NULL의 타입을 알 수 없음
SELECT COALESCE(NULL, NULL);
-- ERROR: 42P18: cannot determine type of parameter $1
-- 해결: 명시적 타입 캐스트 적용
SELECT COALESCE(NULL::INTEGER, NULL::INTEGER);
-- 또는
SELECT COALESCE(CAST(NULL AS TEXT), CAST(NULL AS TEXT));
-- 준비된 구문에서 파라미터 타입 지정
PREPARE my_plan (INTEGER) AS
SELECT * FROM users WHERE id = $1;
EXECUTE my_plan(42);
해결 2: UNION 또는 CASE 표현식에서 타입 명시
UNION, CASE WHEN 등의 표현식에서 모든 분기의 반환 타입이 일치해야 합니다. 타입 추론이 불가한 경우 명시적 캐스트를 추가합니다.
-- 에러 발생: 두 SELECT의 타입이 불명확
SELECT NULL
UNION ALL
SELECT NULL;
-- ERROR: 42P18: indeterminate datatype
-- 해결: 각 항목에 타입 명시
SELECT NULL::TEXT
UNION ALL
SELECT NULL::TEXT;
-- CASE 표현식 예제
SELECT
CASE
WHEN active = true THEN 'active'::TEXT
ELSE NULL::TEXT
END AS status
FROM users;
해결 3: 오버로딩 함수 호출 시 인자 타입 명시
오버로딩된 함수를 호출할 때는 인자에 타입 캐스트를 추가하여 PostgreSQL이 올바른 함수 시그니처를 선택할 수 있도록 합니다.
-- 에러 발생: 어떤 to_json 계열 함수를 호출해야 할지 모호
SELECT to_json(NULL);
-- ERROR: 42P18: could not determine data type of argument
-- 해결: 인자에 명시적 타입 캐스트 추가
SELECT to_json(NULL::TEXT);
SELECT to_json(NULL::INTEGER);
SELECT to_json(NULL::JSONB);
-- 사용자 정의 함수 예제
CREATE OR REPLACE FUNCTION process_value(val TEXT) RETURNS TEXT AS $$
BEGIN
RETURN UPPER(val);
END;
$$ LANGUAGE plpgsql;
CREATE OR REPLACE FUNCTION process_value(val INTEGER) RETURNS INTEGER AS $$
BEGIN
RETURN val * 2;
END;
$$ LANGUAGE plpgsql;
-- 모호한 호출 (에러 가능)
-- SELECT process_value(NULL);
-- 명확한 호출
SELECT process_value(NULL::TEXT);
SELECT process_value(NULL::INTEGER);
해결 4: 동적 SQL 및 드라이버 수준 처리
애플리케이션 드라이버(예: psycopg2, JDBC)를 사용할 때는 파라미터에 타입 힌트를 제공하거나, 서버 측 바인딩 대신 클라이언트 측 포맷팅을 사용하는 방법도 고려할 수 있습니다.
-- PL/pgSQL 동적 SQL에서 타입 명시
DO $$
DECLARE
result TEXT;
input_val ANYELEMENT;
BEGIN
-- EXECUTE 구문에서 타입 명시
EXECUTE 'SELECT $1::TEXT' INTO result USING 'hello'::TEXT;
RAISE NOTICE 'Result: %', result;
END;
$$;
-- 타입이 불분명한 상황에서 ANYELEMENT 대신 명시적 타입 사용
CREATE OR REPLACE FUNCTION safe_coalesce(a TEXT, b TEXT) RETURNS TEXT AS $$
BEGIN
RETURN COALESCE(a, b);
END;
$$ LANGUAGE plpgsql;
SELECT safe_coalesce(NULL, 'default_value');
예방 방법
1. 코드 리뷰 시 타입 캐스트 검토 의무화
팀 내 코딩 컨벤션에 “모든 NULL 값과 파라미터에 명시적 타입 캐스트를 적용한다”는 규칙을 추가하세요. 특히 UNION, COALESCE, CASE WHEN, PREPARE 구문이 포함된 코드는 반드시 타입 명시 여부를 코드 리뷰 체크리스트에 포함시켜야 합니다. 정적 분석 도구(예: sqlfluff, pgTAP)를 CI/CD 파이프라인에 통합하면 이러한 실수를 사전에 방지할 수 있습니다.
2. Prepared Statement 사용 시 파라미터 타입 명시 습관화
PREPARE 구문 또는 ORM/드라이버의 Prepared Statement 기능을 사용할 때는 항상 파라미터 타입을 명시적으로 선언하세요. ORM을 사용하는 경우에도 원시 쿼리(raw query) 작성 시 파라미터 타입 힌트를 드라이버 API를 통해 전달하는 방법을 숙지하고 적용해야 합니다. 이 습관 하나만으로도 42P18 에러의 대부분을 예방할 수 있습니다.
관련 에러
42883undefined_function: 오버로딩된 함수에서 타입 불일치로 함수 자체를 찾지 못할 때 발생합니다.42P18과 유사한 상황에서 함께 나타날 수 있습니다.42804datatype_mismatch: 타입은 결정되었지만 기대하는 타입과 실제 타입이 불일치할 때 발생합니다.42P18과 달리 타입 자체는 인식된 상태입니다.42P08ambiguous_parameter: 파라미터가 모호하게 사용된 경우로,42P18과 밀접하게 연관된 에러입니다.42601syntax_error: 타입 캐스트 구문이 잘못 작성되어 파서가 에러를 발생시키는 경우,42P18해결 시도 중 간접적으로 마주칠 수 있습니다.
주요 DBMS error code를 정리하는 시리즈입니다.
블로그 홈에서 다른 에러도 확인하세요.
본 포스트는 AI가 생성한 기술 가이드입니다. 운영 환경 적용 전 충분한 검토를 권장합니다.