2026년 06월 06일 | DBMS Error 가이드
이 글에서 다루는 내용
2201F 에러의 원인 분석, 해결 SQL, 예방 방법을 실무 관점에서 정리합니다.
2201F invalid argument for power function 는?
PostgreSQL 에러 코드 2201F는 power() 함수에 유효하지 않은 인수가 전달되었을 때 발생하는 에러입니다. 수학적으로 정의되지 않는 연산, 예를 들어 음수를 밑(base)으로 하고 비정수(non-integer)를 지수(exponent)로 사용하는 경우, 또는 0을 밑으로 하고 음수를 지수로 사용하는 경우에 이 에러가 트리거됩니다. 이 에러는 데이터 타입 자체가 올바르더라도 수학적 도메인(domain)을 벗어난 값 조합이 입력될 때 런타임 시점에 발생하기 때문에, 사전에 데이터 유효성 검사를 철저히 하지 않으면 운영 환경에서 예상치 못하게 마주칠 수 있습니다.
주요 발생 원인
1. 음수를 밑(base)으로 하고 비정수를 지수(exponent)로 사용
수학적으로 음수의 소수 지수 거듭제곱은 실수(real number) 범위에서 정의되지 않습니다. PostgreSQL의 power() 함수는 부동소수점 연산을 기반으로 하기 때문에, -2를 밑으로 하고 0.5를 지수로 계산하는 것은 허용되지 않으며, 이 상황에서 2201F 에러가 발생합니다. 실무에서는 사용자 입력 데이터나 집계된 중간 결과값이 음수가 될 수 있다는 점을 간과하여 이 에러를 맞닥뜨리는 경우가 많습니다.
2. 밑(base)이 0이고 지수(exponent)가 음수인 경우
0의 음수 지수는 수학적으로 1/0을 의미하므로 정의되지 않습니다. power(0, -1)과 같은 연산은 분모가 0이 되는 나눗셈과 동일하기 때문에, PostgreSQL은 이를 유효하지 않은 인수로 판단하고 2201F 에러를 반환합니다. 이 경우는 주로 동적으로 생성된 지수 값이 예상치 않게 음수가 되거나, 계산식의 역수 처리 로직에서 예외 케이스를 처리하지 않았을 때 발생합니다.
3. NaN(Not a Number) 또는 Infinity 값이 인수로 전달되는 경우
ETL 파이프라인이나 외부 시스템에서 데이터를 가져올 때, 결측값이나 계산 오류로 인해 NaN 또는 Infinity 값이 power() 함수의 인수로 유입될 수 있습니다. 특정 조합의 NaN과 Infinity 값은 수학적으로 정의되지 않는 결과를 초래하여 2201F 에러를 유발합니다. 특히 대규모 데이터 파이프라인에서는 이러한 엣지 케이스(edge case)를 놓치기 쉽기 때문에 주의가 필요합니다.
해결 방법
원인 1 해결: 음수 밑과 비정수 지수 처리
ABS() 함수를 사용하여 절댓값으로 변환하거나, CASE 문으로 음수 케이스를 사전에 필터링하는 방법을 사용합니다.
-- 문제가 되는 쿼리 (에러 발생)
SELECT power(-2.0, 0.5);
-- ERROR: invalid argument for power function
-- 해결책 1: ABS()로 절댓값 처리 후 부호 별도 관리
SELECT
CASE
WHEN base < 0 AND exponent != FLOOR(exponent) THEN NULL -- 정의 불가 케이스
WHEN base < 0 THEN -1 * power(ABS(base), exponent) -- 정수 지수인 경우
ELSE power(base, exponent)
END AS safe_power_result
FROM (VALUES (-2.0::float, 0.5::float)) AS t(base, exponent);
-- 해결책 2: 실제 데이터 처리 시 NULLIF와 CASE 결합
SELECT
id,
value,
exponent_val,
CASE
WHEN value < 0 AND exponent_val <> FLOOR(exponent_val) THEN NULL
WHEN value = 0 AND exponent_val < 0 THEN NULL
ELSE power(value, exponent_val)
END AS computed_power
FROM calculations_table;
원인 2 해결: 밑이 0이고 지수가 음수인 경우
NULLIF를 사용하여 밑이 0인 경우를 방어하거나, 사전 조건 체크 로직을 추가합니다.
-- 문제가 되는 쿼리 (에러 발생)
SELECT power(0, -1);
-- ERROR: invalid argument for power function
-- 해결책: CASE 문으로 방어 로직 추가
SELECT
CASE
WHEN base = 0 AND exponent < 0 THEN NULL -- 0의 음수 지수는 undefined
WHEN base = 0 AND exponent = 0 THEN 1 -- 0^0 은 관례적으로 1
ELSE power(base, exponent)
END AS safe_result
FROM (VALUES (0.0::float, -1.0::float)) AS t(base, exponent);
-- 실무 적용 예시: 레코드 단위 방어 처리
UPDATE financial_metrics
SET growth_factor = CASE
WHEN base_value = 0 AND exponent_val < 0 THEN 0
ELSE power(base_value, exponent_val)
END
WHERE calculation_date = CURRENT_DATE;
원인 3 해결: NaN 및 Infinity 값 필터링
IS NaN 조건이나 isfinite() 함수를 사용하여 비정상 값을 사전에 걸러냅니다.
-- NaN과 Infinity 체크를 포함한 안전한 power 계산 함수 생성
CREATE OR REPLACE FUNCTION safe_power(base FLOAT, exponent FLOAT)
RETURNS FLOAT
LANGUAGE plpgsql
AS $$
BEGIN
-- NaN 체크
IF base IS NULL OR exponent IS NULL THEN
RETURN NULL;
END IF;
-- Infinity 및 NaN 체크
IF base = 'NaN'::float OR exponent = 'NaN'::float THEN
RETURN NULL;
END IF;
-- 음수 밑 + 비정수 지수 체크
IF base < 0 AND exponent <> FLOOR(exponent) THEN
RETURN NULL;
END IF;
-- 0 밑 + 음수 지수 체크
IF base = 0 AND exponent < 0 THEN
RETURN NULL;
END IF;
RETURN power(base, exponent);
EXCEPTION WHEN OTHERS THEN
RETURN NULL;
END;
$$;
-- 함수 사용 예시
SELECT safe_power(-2.0, 0.5); -- NULL 반환 (안전하게 처리)
SELECT safe_power(0.0, -1.0); -- NULL 반환 (안전하게 처리)
SELECT safe_power(2.0, 10.0); -- 1024 반환 (정상 처리)
-- 테이블 데이터에 적용
SELECT
sensor_id,
reading_value,
safe_power(reading_value, 2.0) AS squared_value
FROM sensor_data
WHERE collected_at >= NOW() - INTERVAL '1 day';
예방 방법
1. 입력 데이터 검증을 위한 CHECK 제약 조건 및 트리거 활용
power() 함수가 사용되는 컬럼에 대해 데이터 삽입 또는 업데이트 시점에 CHECK 제약 조건이나 트리거를 활용하여 유효하지 않은 값이 저장되는 것을 원천 차단하는 것이 가장 효과적인 예방책입니다. 이렇게 하면 런타임 에러가 발생하기 전에 데이터 레이어에서 문제를 조기에 탐지할 수 있습니다.
-- CHECK 제약 조건으로 기본 방어
ALTER TABLE scientific_calculations
ADD CONSTRAINT chk_valid_base
CHECK (base_value >= 0 OR exponent_value = FLOOR(exponent_value));
-- 트리거를 활용한 동적 검증
CREATE OR REPLACE FUNCTION validate_power_inputs()
RETURNS TRIGGER
LANGUAGE plpgsql
AS $$
BEGIN
IF NEW.base_value < 0 AND NEW.exponent_value <> FLOOR(NEW.exponent_value) THEN
RAISE EXCEPTION 'Invalid power arguments: negative base (%) with non-integer exponent (%)',
NEW.base_value, NEW.exponent_value;
END IF;
IF NEW.base_value = 0 AND NEW.exponent_value < 0 THEN
RAISE EXCEPTION 'Invalid power arguments: zero base with negative exponent (%).',
NEW.exponent_value;
END IF;
RETURN NEW;
END;
$$;
CREATE TRIGGER trg_validate_power_inputs
BEFORE INSERT OR UPDATE ON scientific_calculations
FOR EACH ROW EXECUTE FUNCTION validate_power_inputs();
2. 재사용 가능한 래퍼(Wrapper) 함수 표준화
위에서 작성한 safe_power() 함수처럼, 조직 내 모든 power() 호출을 래퍼 함수로 통일하고, 코드 리뷰 가이드라인에 직접 power() 사용을 금지하는 규칙을 추가하는 것이 좋습니다. 이를 통해 개별 개발자가 예외 케이스를 매번 직접 처리하는 부담을 줄이고, 일관된 오류 처리 정책을 유지할 수 있습니다.
관련 에러
22012(division_by_zero):power(0, -1)과 같이 0의 음수 지수는 나눗셈의 분모가 0이 되는 상황과 유사하며, 맥락에 따라22012에러와 혼동될 수 있습니다.2201E(invalid_argument_for_logarithm):log()함수에 0 이하의 값을 전달했을 때 발생하는 에러로,power()함수와 함께 수학 함수 관련 에러 그룹에 속합니다.power()와log()는 내부적으로 연관된 연산을 수행하는 경우가 많아 함께 검토해야 합니다.2201G(invalid_argument_for_width_bucket_function): 동일한2201카테고리에 속하는 에러로, 수학/통계 함수의 인수 유효성 검사 실패 시 발생합니다.power()에러와 같은 맥락에서 입력값 검증 로직을 공유하여 처리할 수 있습니다.
주요 DBMS error code를 정리하는 시리즈입니다.
블로그 홈에서 다른 에러도 확인하세요.
본 포스트는 AI가 생성한 기술 가이드입니다. 운영 환경 적용 전 충분한 검토를 권장합니다.