CREATE OPERATOR
CREATE OPERATOR
새 연산자(operator)를 정의하는 명령이에요. +, == 같은 기호에 사용자 정의 함수를 연결해 나만의 연산자를 만들 수 있습니다.
출처: PostgreSQL 문서
본문
문법 (Synopsis)
CREATE OPERATOR name (
{FUNCTION|PROCEDURE} = function_name
[, LEFTARG = left_type ] [, RIGHTARG = right_type ]
[, COMMUTATOR = com_op ] [, NEGATOR = neg_op ]
[, RESTRICT = res_proc ] [, JOIN = join_proc ]
[, HASHES ] [, MERGES ]
)
설명 (Description)
CREATE OPERATOR는 새 연산자 name을 정의해요. 연산자를 정의한 사용자가 그 소유자가 됩니다. 스키마 이름이 주어지면 그 스키마에 만들어지고, 아니면 현재 스키마에 만들어집니다.
연산자 이름은 다음 문자 목록으로 이루어진, 최대 NAMEDATALEN-1(기본 63)자 길이의 문자열이에요:
+ - * / < > = ~ ! @ # % ^ & | ` ?
이름을 고를 때 몇 가지 제한이 있습니다:
--와/*는 주석 시작으로 해석되므로 연산자 이름 어디에도 올 수 없어요.- 여러 문자로 된 연산자 이름은
+나-로 끝날 수 없어요. 단,~ ! @ # % ^ & | \?중 하나 이상을 포함하면 예외입니다. 예를 들어@-는 허용되지만*-`는 안 돼요. 이 제한 덕분에 PostgreSQL은 토큰 사이에 공백 없이도 SQL 준수 명령을 파싱할 수 있습니다. =>기호는 SQL 문법에 예약되어 있어 연산자 이름으로 쓸 수 없어요.
연산자 !=는 입력 시 <>로 매핑되므로, 이 두 이름은 항상 동등합니다.
이항 연산자(이진 연산자)는 LEFTARG와 RIGHTARG가 모두 정의돼야 하고, 전위 연산자(prefix operator)는 RIGHTARG만 정의하면 돼요. function_name 함수는 CREATE FUNCTION로 이전에 정의되어 있어야 하며, 지정된 타입의 인자를 정확히 (하나 또는 두 개) 받도록 정의돼야 합니다.
CREATE OPERATOR 문법에서 FUNCTION과 PROCEDURE 키워드는 동등하지만, 참조하는 함수는 어쨌든 함수여야 하며 프로시저는 안 돼요. 여기서 PROCEDURE 키워드를 쓰는 것은 역사적인 이유이며 폐기 예정입니다.
다른 절들은 선택적인 연산자 최적화 속성을 지정해요. 그 의미는 36.15절에 자세히 나와 있습니다.
연산자를 만들려면 인자 타입과 반환 타입에 대한 USAGE 권한과, 밑바탕 함수에 대한 EXECUTE 권한이 있어야 해요. 커뮤터(commutator)나 네게이터(negator) 연산자를 지정하면 그 연산자들을 소유해야 합니다.
파라미터 (Parameters)
name— 정의할 연산자의 이름. 위에서 말한 허용 문자를 따릅니다. 스키마 한정이 가능해요. 예:CREATE OPERATOR myschema.+ (...). 한정하지 않으면 현재 스키마에 만들어집니다. 같은 스키마의 두 연산자는 서로 다른 데이터 타입에 동작하면 같은 이름을 가질 수 있는데, 이를 오버로딩(overloading)이라고 해요.function_name— 이 연산자를 구현하는 함수.left_type— 연산자 왼쪽 피연산자의 데이터 타입(있는 경우). 전위 연산자에서는 생략됩니다.right_type— 연산자 오른쪽 피연산자의 데이터 타입.com_op— 이 연산자의 커뮤터(교환 연산자).neg_op— 이 연산자의 네게이터(부정 연산자).res_proc— 이 연산자의 제한 선택도 추정(restriction selectivity estimator) 함수.join_proc— 이 연산자의 조인 선택도 추정(join selectivity estimator) 함수.HASHES— 이 연산자가 해시 조인을 지원할 수 있음을 나타냄.MERGES— 이 연산자가 병합 조인을 지원할 수 있음을 나타냄.
com_op나 다른 선택 인자에 스키마 한정 연산자 이름을 주려면 OPERATOR() 문법을 사용하세요:
COMMUTATOR = OPERATOR(myschema.===) ,
주의 사항 (Notes)
자세한 내용은 36.14절과 36.15절을 참고하세요.
자기 자신과 교환되는(자기 커뮤터인) 연산자를 정의할 때는 그냥 하면 돼요. 한 쌍의 교환 연산자를 정의할 때는 좀 까다로운데, 먼저 정의되는 연산자가 아직 정의되지 않은 다른 연산자를 어떻게 가리킬까요? 이 문제에는 세 가지 해법이 있어요:
- 첫 연산자에서는
COMMUTATOR절을 생략하고, 두 번째 연산자 정의에서 제공하는 방법. PostgreSQL은 교환 연산자가 쌍으로 온다는 걸 알고 있으므로, 두 번째 정의를 볼 때 자동으로 돌아가 첫 정의의 빠진COMMUTATOR절을 채워 넣습니다. - 더 단순한 다른 방법은 두 정의 모두에
COMMUTATOR절을 포함하는 것. PostgreSQL이 첫 정의를 처리하다COMMUTATOR가 존재하지 않는 연산자를 가리킨다는 걸 알아차리면, 그 연산자에 대해 시스템 카탈로그에 더미(dummy) 항목을 만듭니다. 이 더미 항목은 연산자 이름, 좌우 피연산자 타입, 소유자에 대해서만 유효한 데이터를 가지는데, 그게 PostgreSQL이 그 시점에 추론할 수 있는 전부이기 때문이에요. 첫 연산자의 카탈로그 항목이 이 더미 항목과 연결됩니다. 나중에 두 번째 연산자를 정의하면 시스템이 두 번째 정의의 추가 정보로 더미 항목을 갱신합니다. 더미 연산자가 채워지기 전에 쓰려고 하면 그냥 오류 메시지를 받게 돼요. - 또는 두 연산자를
COMMUTATOR절 없이 정의한 뒤ALTER OPERATOR로 커뮤터 링크를 설정하는 방법. 쌍 중 하나만ALTER해도 충분합니다.
세 경우 모두, 두 연산자를 커뮤터로 표시하려면 두 연산자를 모두 소유해야 해요.
네게이터 쌍도 커뮤터 쌍과 같은 방법으로 정의할 수 있습니다.
파서의 우선순위(연산자의 어휘적 우선순위)는 하드와이어되어 있어서 CREATE OPERATOR에서 지정할 수 없어요. 우선순위에 대한 자세한 내용은 4.1.6절을 참고하세요.
폐기된 옵션 SORT1, SORT2, LTCMP, GTCMP는 한때 병합-조인 가능한 연산자와 연관된 정렬 연산자의 이름을 지정하는 데 쓰였어요. 이제는 관련 연산자 정보를 B-트리 연산자 패밀리를 보고 찾으므로 더 이상 필요하지 않습니다. 이 옵션 중 하나가 주어지면, 암묵적으로 MERGES를 참으로 설정하는 것 외에는 무시됩니다.
데이터베이스에서 사용자 정의 연산자를 삭제하려면 DROP OPERATOR를, 수정하려면 ALTER OPERATOR를 사용하세요.
예제 (Examples)
box 데이터 타입을 위한 새 연산자, 영역-동등(area-equality) 연산자를 정의하는 명령:
CREATE OPERATOR === (
LEFTARG = box,
RIGHTARG = box,
FUNCTION = area_equal_function,
COMMUTATOR = ===,
NEGATOR = !==,
RESTRICT = area_restriction_function,
JOIN = area_join_function,
HASHES, MERGES
);
호환성 (Compatibility)
CREATE OPERATOR는 PostgreSQL 확장 기능이에요. SQL 표준에는 사용자 정의 연산자에 대한 규정이 없습니다.
함께 보기 (See Also)
ALTER OPERATOR, CREATE OPERATOR CLASS, DROP OPERATOR
더 알아보기 (Learn more)
CREATE OPERATOR CLASS: 인덱스 메서드에서 연산자를 사용하는 방법을 정의하는 연산자 클래스를 만드는 명령.ALTER OPERATOR: 기존 연산자를 수정하는 명령.