2026년 07월 06일 | DBMS Error 가이드
이 글에서 다루는 내용
42939 에러의 원인 분석, 해결 SQL, 예방 방법을 실무 관점에서 정리합니다.
42939 reserved name 는?
PostgreSQL 에러 코드 42939는 reserved name으로, 사용자가 PostgreSQL 내부에서 예약된 이름을 객체(테이블, 컬럼, 함수, 타입 등)의 이름으로 사용하려 할 때 발생합니다. PostgreSQL은 시스템 내부 동작을 위해 특정 이름들을 미리 예약해두고 있으며, 이 예약어를 일반 식별자로 사용하는 경우 해당 에러가 발생합니다. 주로 커스텀 타입, 함수, 연산자 클래스, 또는 시스템 카탈로그 관련 객체를 생성할 때 자주 마주치는 에러입니다.
주요 발생 원인
- PostgreSQL 내장 타입 또는 시스템 예약어를 객체 이름으로 사용
PostgreSQL은 int, text, boolean, timestamp, array, record 등 수십 가지 내장 타입 이름을 시스템 수준에서 예약하고 있습니다. 사용자가 이와 동일한 이름으로 커스텀 타입이나 도메인을 생성하려 하면 42939 에러가 발생합니다. 특히 신규 PostgreSQL 버전으로 마이그레이션하거나 외부 익스텐션을 도입할 때 기존 객체 이름이 충돌하는 경우가 많습니다.
- 예약된 함수 또는 연산자 이름 재정의 시도
now(), current_date, user, session_user 등 PostgreSQL이 시스템 함수로 예약한 이름을 사용자 정의 함수 이름으로 생성하려 할 때 에러가 발생할 수 있습니다. PostgreSQL은 이러한 이름들을 SQL 표준 또는 내부 동작과 연관된 특수 식별자로 취급하기 때문에, 재정의를 허용하지 않는 경우가 있습니다. 특히 CREATE FUNCTION이나 CREATE AGGREGATE 구문에서 자주 발생합니다.
- 시스템 카탈로그 또는 내부 스키마와 충돌하는 이름 사용
pg_catalog, information_schema와 같은 시스템 스키마에 속하는 객체 이름이나, 내부적으로 예약된 스키마 이름을 사용자가 재생성하려 할 때 이 에러가 발생합니다. PostgreSQL 내부에서 pg_로 시작하는 이름들은 시스템 전용으로 예약되어 있으며, 사용자가 이러한 prefix를 가진 객체를 생성하면 에러 또는 경고가 발생할 수 있습니다.
해결 방법
원인 1 해결: 예약된 타입 이름 충돌 해결
예약된 이름 대신 명확한 접두사(prefix)나 도메인 특화 이름을 사용하세요.
-- 잘못된 예: 'record'는 PostgreSQL 내부 예약어
CREATE TYPE record AS (
id INTEGER,
name TEXT
);
-- ERROR: 42939 - type name "record" is reserved
-- 올바른 예: 의미 있는 접두사 추가
CREATE TYPE app_record AS (
id INTEGER,
name TEXT
);
-- 또는 스키마를 분리하여 관리
CREATE SCHEMA myapp;
CREATE TYPE myapp.record_info AS (
id INTEGER,
name TEXT
);
원인 2 해결: 예약된 함수 이름 충돌 해결
시스템 예약 함수와 동일한 이름 대신, 기능을 명확히 나타내는 이름을 사용하세요.
-- 잘못된 예: 'now'는 시스템 예약 함수
CREATE OR REPLACE FUNCTION now()
RETURNS TIMESTAMP AS $$
BEGIN
RETURN CURRENT_TIMESTAMP;
END;
$$ LANGUAGE plpgsql;
-- ERROR: 42939 - function name "now" is reserved
-- 올바른 예: 명확한 네이밍으로 변경
CREATE OR REPLACE FUNCTION get_current_timestamp()
RETURNS TIMESTAMP AS $$
BEGIN
RETURN CURRENT_TIMESTAMP;
END;
$$ LANGUAGE plpgsql;
-- 또는 스키마를 이용한 네임스페이스 분리
CREATE SCHEMA app_functions;
CREATE OR REPLACE FUNCTION app_functions.get_now()
RETURNS TIMESTAMP AS $$
BEGIN
RETURN CURRENT_TIMESTAMP;
END;
$$ LANGUAGE plpgsql;
원인 3 해결: 시스템 카탈로그 충돌 해결
pg_ prefix로 시작하는 이름이나 시스템 스키마 이름을 피하고, 전용 애플리케이션 스키마를 사용하세요.
-- 잘못된 예: pg_ prefix 사용
CREATE TABLE pg_custom_log (
log_id SERIAL PRIMARY KEY,
log_message TEXT,
created_at TIMESTAMP DEFAULT NOW()
);
-- WARNING 또는 ERROR: pg_ prefix는 시스템 예약 prefix
-- 올바른 예: 애플리케이션 전용 스키마와 네이밍 규칙 사용
CREATE SCHEMA app_schema;
CREATE TABLE app_schema.custom_log (
log_id SERIAL PRIMARY KEY,
log_message TEXT,
created_at TIMESTAMP DEFAULT NOW()
);
-- 현재 예약된 이름 목록 조회 (참고용)
SELECT typname
FROM pg_catalog.pg_type
WHERE typname = 'your_type_name';
-- 예약어 여부를 사전에 확인하는 쿼리
SELECT word, reserved
FROM pg_get_keywords()
WHERE word = 'your_keyword'
AND reserved = true;
예방 방법
- 명명 규칙(Naming Convention) 표준화 및 문서화
팀 내에서 모든 데이터베이스 객체에 대한 명명 규칙을 사전에 정의하고 문서화하세요. 예를 들어, 테이블은 tbl_, 커스텀 타입은 typ_, 함수는 fn_과 같은 애플리케이션 고유 접두사를 사용하면 시스템 예약어와 충돌할 가능성을 원천 차단할 수 있습니다. 또한 DDL 스크립트를 실행하기 전에 반드시 pg_get_keywords() 함수와 pg_catalog.pg_type 카탈로그를 조회하여 예약어 충돌 여부를 자동으로 검사하는 CI/CD 파이프라인을 구성하는 것을 강력히 권장합니다.
“`sql
— 네이밍 충돌 사전 검사 쿼리
SELECT word, catcode, catdesc
FROM pg_get_keywords()
WHERE reserved = true
ORDER BY word;
“`
- 전용 애플리케이션 스키마 사용 의무화
모든 사용자 정의 객체는 반드시 전용 스키마(예: app, myservice, domain_name) 안에 배치하는 정책을 시행하세요. public 스키마나 pg_catalog 스키마에 직접 객체를 생성하는 행위를 금지하고, 데이터베이스 롤(Role) 권한을 통해 이를 강제하면 예약어 충돌 에러를 포함한 다양한 네이밍 충돌 문제를 예방할 수 있습니다. 스키마 분리는 유지보수성과 보안성 향상에도 큰 도움이 됩니다.
“`sql
— 전용 스키마 생성 및 권한 설정 예시
CREATE SCHEMA app_domain;
GRANT USAGE ON SCHEMA app_domain TO app_user;
GRANT CREATE ON SCHEMA app_domain TO app_admin;
— public 스키마 생성 권한 제거 (예방 조치)
REVOKE CREATE ON SCHEMA public FROM PUBLIC;
“`
관련 에러
- 42601 (syntax_error): SQL 문법 자체가 잘못된 경우로, 예약어를 식별자로 사용할 때 파서 단계에서 먼저 발생할 수 있습니다.
- 42701 (duplicate_column): 동일 이름의 컬럼을 중복 정의할 때 발생하며, 네이밍 충돌 관련 에러 중 하나입니다.
- 42710 (duplicate_object): 이미 존재하는 객체와 동일한 이름으로 객체를 생성하려 할 때 발생합니다.
- 42P07 (duplicate_table): 동일한 이름의 테이블이 이미 존재할 때 발생하는 에러로,
42939와 함께 객체 생성 시 자주 마주칠 수 있습니다. - 0A000 (feature_not_supported): 특정 시스템 예약 기능을 재정의하거나 지원되지 않는 방식으로 사용하려 할 때 발생할 수 있습니다.
주요 DBMS error code를 정리하는 시리즈입니다.
블로그 홈에서 다른 에러도 확인하세요.
본 포스트는 AI가 생성한 기술 가이드입니다. 운영 환경 적용 전 충분한 검토를 권장합니다.