PostgreSQL 42725 오류 원인과 해결 방법 완벽 가이드

42725
2026년 07월 12일 | DBMS Error 가이드

이 글에서 다루는 내용

42725 에러의 원인 분석, 해결 SQL, 예방 방법을 실무 관점에서 정리합니다.

42725 ambiguous function 란?

PostgreSQL 에러 코드 42725, ambiguous function은 함수 호출 시 PostgreSQL이 어떤 함수를 실행해야 할지 명확하게 결정하지 못할 때 발생합니다. 주로 함수 오버로딩(Function Overloading) 환경에서 동일한 이름을 가진 여러 함수가 존재하고, 전달된 인자의 데이터 타입이 여러 함수에 동시에 적용 가능할 때 이 에러가 발생합니다. 쉽게 말해, PostgreSQL의 함수 결정 알고리즘(Function Resolution)이 최적의 후보 함수를 단 하나로 좁히지 못한 상태를 의미하며, 명시적인 타입 캐스팅이나 함수 시그니처 정리를 통해 해결해야 합니다.


주요 발생 원인

1. 동일 이름의 오버로딩된 함수 간 타입 모호성

가장 빈번한 원인입니다. 같은 스키마 내에 동일한 이름이지만 서로 다른 파라미터 타입을 가진 함수가 여러 개 존재할 때, 호출 시 넘기는 인자의 타입이 두 개 이상의 함수에 동시에 암묵적으로 변환(implicit cast)될 수 있으면 PostgreSQL은 어느 함수를 선택해야 할지 결정하지 못합니다. 예를 들어 integerbigint를 각각 받는 두 함수가 있을 때 numeric 타입 값을 넘기면 두 후보 모두 유효하여 에러가 발생합니다.

2. 검색 경로(search_path)에 여러 스키마가 포함되어 동일 함수명 충돌

search_path에 여러 스키마가 등록되어 있고, 각 스키마에 동일한 이름과 유사한 파라미터 시그니처를 가진 함수가 중복 존재하는 경우입니다. 스키마 한정자(schema qualifier) 없이 함수를 호출하면 PostgreSQL은 search_path 순서대로 탐색하다가 동등한 우선순위의 후보를 여럿 발견하고 모호성 에러를 반환합니다. 운영 환경에서 여러 팀이 각자의 스키마에 유틸리티 함수를 배포할 때 자주 발생하는 패턴입니다.

3. 익명 타입(Unknown Type) 리터럴 사용

SQL 쿼리에서 단순 문자열 리터럴('some_value')을 인자로 전달하면 PostgreSQL은 해당 값을 unknown 타입으로 취급합니다. unknown 타입은 다양한 타입으로 암묵적 변환이 가능하기 때문에, 여러 오버로딩 함수 후보가 모두 유효한 것으로 판단되어 모호성 에러가 발생할 수 있습니다. 특히 text, varchar, char 등 문자열 계열 타입을 파라미터로 받는 함수가 여럿 존재할 때 이 문제가 두드러집니다.


해결 방법

원인 1 해결: 명시적 타입 캐스팅 사용

호출 인자에 명시적으로 타입을 지정하여 PostgreSQL이 단 하나의 함수 후보를 선택하도록 유도합니다.

-- 문제 상황: calculate_tax 함수가 integer 버전과 numeric 버전 둘 다 존재
-- 아래 호출은 42725 에러 발생 가능
SELECT calculate_tax(1500.00);

-- 해결책 1: :: 연산자를 이용한 명시적 캐스팅
SELECT calculate_tax(1500.00::numeric);

-- 해결책 2: CAST 함수 사용
SELECT calculate_tax(CAST(1500.00 AS integer));

-- 해결책 3: 타입이 명확한 변수 또는 컬럼 직접 사용
DO $$
DECLARE
    v_amount numeric := 1500.00;
BEGIN
    PERFORM calculate_tax(v_amount);
END;
$$;

원인 2 해결: 스키마 한정자(Schema Qualifier) 명시

함수 호출 시 스키마 이름을 명시하여 어느 스키마의 함수를 호출할지 확실하게 지정합니다.

-- 문제 상황: public과 app 스키마 양쪽에 format_phone 함수가 존재
-- search_path: app, public
SELECT format_phone('01012345678'); -- 42725 에러 발생

-- 해결책: 스키마 한정자 명시
SELECT public.format_phone('01012345678');
SELECT app.format_phone('01012345678');

-- search_path 확인
SHOW search_path;

-- 특정 세션의 search_path 임시 변경
SET search_path TO app, public;

-- 현재 데이터베이스의 기본 search_path 변경 (영구 적용)
ALTER DATABASE mydb SET search_path TO app, public;

원인 3 해결: 문자열 리터럴에 타입 지정

unknown 타입 리터럴 대신 타입이 명확한 표현을 사용합니다.

-- 문제 상황: process_code 함수가 text, varchar(10), char(10) 버전으로 오버로딩
SELECT process_code('A001'); -- unknown 타입으로 모호성 발생

-- 해결책 1: 타입 캐스팅
SELECT process_code('A001'::text);
SELECT process_code('A001'::varchar(10));

-- 해결책 2: 표준 SQL 타입 명시 문법
SELECT process_code(text 'A001');

-- 해결책 3: 중복 함수 정리 - 불필요한 오버로딩 함수 제거
-- 현재 등록된 동일 이름 함수 목록 조회
SELECT
    n.nspname AS schema_name,
    p.proname AS function_name,
    pg_catalog.pg_get_function_arguments(p.oid) AS arguments,
    pg_catalog.pg_get_function_result(p.oid) AS return_type
FROM
    pg_catalog.pg_proc p
    JOIN pg_catalog.pg_namespace n ON n.oid = p.pronamespace
WHERE
    p.proname = 'process_code'
ORDER BY
    n.nspname, p.proname;

-- 불필요한 오버로딩 함수 제거
DROP FUNCTION IF EXISTS public.process_code(char);
DROP FUNCTION IF EXISTS public.process_code(varchar);

원인 통합 해결: 함수 시그니처 표준화

함수를 새로 설계하거나 리팩토링할 때는 오버로딩 대신 파라미터 이름과 기본값을 활용합니다.

-- 오버로딩 대신 단일 함수로 통합 (권장 패턴)
CREATE OR REPLACE FUNCTION calculate_tax(
    p_amount    numeric,
    p_rate      numeric DEFAULT 0.1,
    p_currency  text    DEFAULT 'KRW'
)
RETURNS numeric
LANGUAGE plpgsql
AS $$
BEGIN
    RETURN p_amount * p_rate;
END;
$$;

-- 다양한 방식으로 호출 가능
SELECT calculate_tax(10000);
SELECT calculate_tax(10000, 0.15);
SELECT calculate_tax(p_amount := 10000, p_currency := 'USD');

예방 방법

1. 함수 오버로딩 최소화 및 명명 규칙 수립

실무에서 함수 오버로딩은 편리하지만 타입 모호성의 근본 원인이 됩니다. 팀 내에서 오버로딩 대신 파라미터 기본값(DEFAULT value)과 명명된 파라미터(Named Parameter)를 적극 활용하는 코딩 컨벤션을 수립하세요. 불가피하게 오버로딩이 필요한 경우에는 함수명에 타입 힌트를 접미사로 붙이는 방식(calculate_tax_int, calculate_tax_numeric)을 고려하고, CI/CD 파이프라인에서 동일 이름 함수의 중복 등록 여부를 자동 검사하는 스크립트를 추가하는 것이 좋습니다.

-- 함수 중복 등록 여부 모니터링 쿼리 (정기 점검용)
SELECT
    n.nspname AS schema,
    p.proname AS function_name,
    COUNT(*) AS overload_count
FROM
    pg_catalog.pg_proc p
    JOIN pg_catalog.pg_namespace n ON n.oid = p.pronamespace
WHERE
    n.nspname NOT IN ('pg_catalog', 'information_schema')
GROUP BY
    n.nspname, p.proname
HAVING
    COUNT(*) > 1
ORDER BY
    overload_count DESC, n.nspname, p.proname;

2. 애플리케이션 코드에서 항상 명시적 타입 캐스팅 사용

ORM이나 드라이버를 통해 함수를 호출할 때도 파라미터 타입을 명시적으로 지정하는 습관을 들이세요. 특히 Python의 psycopg2, Java의 JDBC, Node.js의 pg 라이브러리 등에서 바인딩 파라미터를 사용할 때 타입 어댑터(Type Adapter)나 타입 힌트를 반드시 설정하고, 개발/스테이징 환경에서 log_min_messages = DEBUG5 설정으로 함수 결정 과정을 로그로 남겨 사전에 모호성 문제를 감지하는 것이 효과적입니다.


관련 에러

  • 42883 (undefined_function): 함수가 아예 존재하지 않을 때 발생하는 에러로, 42725와 반대 상황입니다. 오타나 잘못된 스키마 경로로 인해 발생하며 함께 점검해야 합니다.
  • 42804 (datatype_mismatch): 함수 파라미터에 전달된 값의 타입이 선언된 타입과 맞지 않을 때 발생합니다. 명시적 캐스팅으로 42725를 해결하는 과정에서 잘못된 타입으로 캐스팅하면 이 에러를 만날 수 있습니다.
  • 42P13 (invalid_function_definition): 함수 정의 자체가 잘못되었을 때 발생하며, 오버로딩 함수 정리 작업 중 CREATE OR REPLACE 사용 시 시그니처 불일치로 마주칠 수 있습니다.

DBMS 에러 코드 시리즈

주요 DBMS error code를 정리하는 시리즈입니다.
블로그 홈에서 다른 에러도 확인하세요.

본 포스트는 AI가 생성한 기술 가이드입니다. 운영 환경 적용 전 충분한 검토를 권장합니다.

댓글 남기기