CREATE FUNCTION
CREATE FUNCTION
새 함수(function)를 정의하는 명령이에요. 인자를 받아 값을 반환하는 재사용 가능한 로직을 만들 때 사용합니다.
출처: PostgreSQL 문서
본문
문법 (Synopsis)
CREATE [ OR REPLACE ] FUNCTION
name ( [ [ argmode ] [ argname ] argtype [ { DEFAULT | = } default_expr ] [, ...] ] )
[ RETURNS rettype
| RETURNS TABLE ( column_name column_type [, ...] ) ]
{ LANGUAGE lang_name
| TRANSFORM { FOR TYPE type_name } [, ... ]
| WINDOW
| { IMMUTABLE | STABLE | VOLATILE }
| [ NOT ] LEAKPROOF
| { CALLED ON NULL INPUT | RETURNS NULL ON NULL INPUT | STRICT }
| { [ EXTERNAL ] SECURITY INVOKER | [ EXTERNAL ] SECURITY DEFINER }
| PARALLEL { UNSAFE | RESTRICTED | SAFE }
| COST execution_cost
| ROWS result_rows
| SUPPORT support_function
| SET configuration_parameter { TO value | = value | FROM CURRENT }
| AS 'definition'
| AS 'obj_file', 'link_symbol'
| sql_body
} ...
설명 (Description)
CREATE FUNCTION은 새 함수를 정의해요. CREATE OR REPLACE FUNCTION은 새 함수를 만들거나 기존 정의를 교체합니다. 함수를 정의하려면 사용자에게 그 언어에 대한 USAGE 권한이 있어야 해요.
스키마 이름이 포함되면 그 스키마에 함수가 만들어지고, 아니면 현재 스키마에 만들어집니다. 새 함수의 이름은 같은 스키마에서 같은 입력 인자 타입을 가진 기존 함수나 프로시저와 같으면 안 돼요. 다만 인자 타입이 다른 함수와 프로시저는 이름을 공유할 수 있습니다(이를 오버로딩이라고 해요).
기존 함수의 현재 정의를 교체하려면 CREATE OR REPLACE FUNCTION을 사용하세요. 이렇게 해서 함수의 이름이나 인자 타입을 바꿀 수는 없습니다. (그렇게 시도하면 실제로는 새롭고 별개의 함수를 만드는 셈이에요.) 또한 CREATE OR REPLACE FUNCTION은 기존 함수의 반환 타입을 바꿔주지 않아요. 그걸 하려면 함수를 삭제하고 다시 만들어야 합니다. (OUT 파라미터를 쓸 때는 함수를 삭제하지 않고는 어떤 OUT 파라미터의 타입도 바꿀 수 없다는 뜻입니다.)
CREATE OR REPLACE FUNCTION으로 기존 함수를 교체할 때 함수의 소유권과 권한은 바뀌지 않아요. 다른 함수 속성은 모두 명령에서 지정되거나 암시된 값으로 지정됩니다. 함수를 교체하려면 그 함수를 소유해야 합니다(소유 역할의 구성원인 것도 포함).
함수를 삭제하고 다시 만들면 새 함수는 옛 함수와 같은 개체가 아니에요. 옛 함수를 참조하는 기존 규칙, 뷰, 트리거 등을 삭제해야 합니다. 함수를 참조하는 객체를 깨뜨리지 않고 함수 정의를 바꾸려면 CREATE OR REPLACE FUNCTION을 사용하세요. 또한 ALTER FUNCTION으로 기존 함수의 대부분의 보조 속성을 바꿀 수 있습니다.
함수를 만든 사용자가 그 함수의 소유자가 됩니다.
함수를 만들려면 인자 타입과 반환 타입에 대한 USAGE 권한이 있어야 해요.
함수 작성에 대한 더 자세한 내용은 36.3절을 참고하세요.
파라미터 (Parameters)
name— 만들 함수의 이름(스키마 한정 가능).argmode— 인자의 모드:IN,OUT,INOUT,VARIADIC. 생략하면 기본은IN이에요.VARIADIC뒤에는OUT인자만 올 수 있습니다. 또한OUT과INOUT인자는RETURNS TABLE표기와 함께 쓸 수 없어요.argname— 인자의 이름. SQL과 PL/pgSQL을 포함한 일부 언어는 함수 본문에서 그 이름을 쓰게 해줍니다. 다른 언어에서 입력 인자의 이름은 함수 자체에 관해서는 그저 추가 문서일 뿐이지만, 함수를 호출할 때 입력 인자 이름을 써서 가독성을 높일 수 있어요(4.3절 참고). 어쨌든 출력 인자의 이름은 결과 행 타입의 컬럼 이름을 정의하므로 중요합니다. (출력 인자 이름을 생략하면 시스템이 기본 컬럼 이름을 고릅니다.)argtype— 함수 인자의 데이터 타입(들)(스키마 한정 가능). 인자 타입은 기본(base), 복합(composite), 도메인 타입이거나 테이블 컬럼의 타입을 가리킬 수 있어요. 구현 언어에 따라cstring같은 '의사 타입(pseudo-type)' 지정도 허용될 수 있습니다. 의사 타입은 실제 인자 타입이 완전히 지정되지 않았거나 일반 SQL 데이터 타입의 집합 밖임을 나타내요. 컬럼 타입은table_name.column_name%TYPE으로 써서 참조합니다. 이 기능을 쓰면 함수가 테이블 정의 변경과 무관해지는 데 도움이 될 때가 있습니다.default_expr— 파라미터가 지정되지 않았을 때 기본값으로 쓸 표현식. 그 표현식은 파라미터의 인자 타입으로 강제 변환 가능해야 해요. 입력(INOUT포함) 파라미터만 기본값을 가질 수 있습니다. 기본값이 있는 파라미터 뒤에 오는 모든 입력 파라미터도 기본값을 가져야 해요.rettype— 반환 데이터 타입(스키마 한정 가능). 반환 타입은 기본, 복합, 도메인 타입이거나 테이블 컬럼의 타입을 가리킬 수 있어요. 구현 언어에 따라cstring같은 '의사 타입' 지정도 허용될 수 있습니다. 함수가 값을 반환하지 않아야 한다면 반환 타입으로void를 지정하세요.OUT이나INOUT파라미터가 있으면RETURNS절을 생략할 수 있어요. 있으면 출력 파라미터가 암시하는 결과 타입과 일치해야 합니다. 출력 파라미터가 여러 개면RECORD, 단일 출력 파라미터면 그 타입.SETOF수식어는 함수가 단일 항목이 아니라 항목 집합을 반환함을 나타내요. 컬럼 타입은table_name.column_name%TYPE으로 써서 참조합니다.column_name—RETURNS TABLE문법에서 출력 컬럼의 이름. 명명된OUT파라미터를 선언하는 또 다른 방식이지만,RETURNS TABLE이RETURNS SETOF도 암시한다는 점이 다릅니다.column_type—RETURNS TABLE문법에서 출력 컬럼의 데이터 타입.lang_name— 함수가 구현된 언어의 이름.sql,c,internal또는plpgsql같은 사용자 정의 절차적 언어의 이름일 수 있어요.sql_body를 지정하면 기본은sql입니다. 이름을 작은따옴표로 감싸는 것은 폐기 예정이며 대소문자를 정확히 맞춰야 해요.TRANSFORM { FOR TYPE type_name } [, ... ]— 함수 호출에 적용해야 할 변환을 나열해요. 변환은 SQL 타입과 언어별 데이터 타입 사이를 변환합니다(see CREATE TRANSFORM). 절차적 언어 구현은 보통 내장 타입을 하드코딩으로 알고 있어서 여기에 나열할 필요가 없습니다. 절차적 언어 구현이 어떤 타입을 다루는 법을 모르고 변환도 제공되지 않으면 데이터 타입 변환을 위한 기본 동작으로 빠지는데, 이는 구현에 따라 달라요.WINDOW— 함수가 일반 함수가 아니라 윈도우 함수임을 나타냅니다. 현재는 C로 작성된 함수에만 유용해요. 기존 함수 정의를 교체할 때WINDOW속성은 바꿀 수 없습니다.IMMUTABLE/STABLE/VOLATILE— 이 속성들은 함수의 동작에 대해 쿼리 옵티마이저에 알려줘요. 최대 하나를 선택할 수 있습니다. 아무것도 지정하지 않으면VOLATILE이 기본 가정이에요.IMMUTABLE은 함수가 데이터베이스를 수정할 수 없고 같은 인자 값이 주어지면 항상 같은 결과를 반환함을 나타내요. 즉 데이터베이스 조회를 하지 않고 인자 목록에 직접 없는 정보도 사용하지 않습니다. 이 옵션이 주어지면 전부 상수인 인자로 된 함수 호출은 즉시 함수 값으로 대체될 수 있어요.STABLE은 함수가 데이터베이스를 수정할 수 없고, 한 번의 테이블 스캔 안에서는 같은 인자 값에 대해 일관되게 같은 결과를 반환하지만 그 결과가 SQL 문 사이에서는 바뀔 수 있음을 나타냅니다. 이는 결과가 데이터베이스 조회, 파라미터 변수(현재 시간대 같은) 등에 의존하는 함수에 적절한 선택이에요. (현재 명령이 수정한 행을 조회하려는AFTER트리거에는 부적절합니다.) 또한current_timestamp계열 함수는 그 값이 트랜잭션 안에서 바뀌지 않으므로 stable로 분류된다는 점도 참고하세요.VOLATILE은 함수 값이 한 번의 테이블 스캔 안에서도 바뀔 수 있어 최적화를 할 수 없음을 나타냅니다. 이런 의미로 volatile인 데이터베이스 함수는 상대적으로 드물며, 예로는random(),currval(),timeofday()가 있어요. 하지만 부작용이 있는 함수는 결과가 매우 예측 가능하더라도 호출이 최적화되어 사라지지 않게 하려고 반드시 volatile로 분류해야 합니다. 예로는setval()이 있습니다. 추가 세부 사항은 36.7절을 참고하세요.LEAKPROOF— 함수에 부작용이 없음을 나타냅니다. 반환값 외에는 인자에 대한 어떤 정보도 드러내지 않아요. 예를 들어 어떤 인자 값에 대해서는 오류 메시지를 내고 다른 값에는 내지 않는 함수나, 오류 메시지에 인자 값을 포함하는 함수는 leakproof가 아닙니다. 이는security_barrier옵션으로 만들어진 뷰나 행 수준 보안이 켜진 테이블에 대한 쿼리를 시스템이 실행하는 방식에 영향을 줘요. 시스템은 인자에 비-누수 방지 함수가 있는 사용자 제공 조건보다 먼저 보안 정책과 보안 배리어 뷰의 조건을 시행해 데이터의 우발적 노출을 막습니다. leakproof로 표시된 함수와 연산자는 신뢰할 수 있다고 가정되어 보안 정책과 보안 배리어 뷰의 조건보다 먼저 실행될 수 있어요. 또한 인자를 받지 않거나 보안 배리어 뷰·테이블에서 인자를 전달받지 않는 함수는 보안 조건보다 먼저 실행되도록 leakproof로 표시할 필요가 없습니다. CREATE VIEW와 39.5절을 참고하세요. 이 옵션은 슈퍼유저만 설정할 수 있어요.CALLED ON NULL INPUT/RETURNS NULL ON NULL INPUT/STRICT—CALLED ON NULL INPUT(기본)은 인자 중 일부가 null일 때 함수가 정상적으로 호출됨을 나타내요. 그러면 필요하다면 null 값을 검사하고 적절히 응답하는 것은 함수 작성자 책임입니다.RETURNS NULL ON NULL INPUT또는STRICT는 인자 중 하나라도 null이면 함수가 항상 null을 반환함을 나타냅니다. 이 파라미터를 지정하면 null 인자가 있을 때 함수가 실행되지 않고, 대신 null 결과가 자동으로 가정됩니다.[EXTERNAL] SECURITY INVOKER/[EXTERNAL] SECURITY DEFINER—SECURITY INVOKER는 함수가 호출한 사용자의 권한으로 실행돼야 함을 나타내며 그것이 기본이에요.SECURITY DEFINER는 함수가 그 소유자의 권한으로 실행돼야 함을 지정합니다.SECURITY DEFINER함수를 안전하게 작성하는 방법은 아래를 참고하세요.EXTERNAL키워드는 SQL 적합성을 위해 허용되지만, SQL과 달리 이 기능이 모든 함수에 적용되므로 선택사항이에요.PARALLEL UNSAFE/PARALLEL RESTRICTED/PARALLEL SAFE—PARALLEL UNSAFE는 함수가 병렬 모드에서 실행될 수 없음을 나타내며, SQL 문에 그런 함수가 있으면 직렬 실행 계획이 강제됩니다. 이것이 기본이에요.PARALLEL RESTRICTED는 함수가 병렬 모드에서 실행될 수 있지만 병렬 그룹 리더 프로세스에서만 가능함을 나타냅니다.PARALLEL SAFE는 함수가 병렬 워커 프로세스를 포함해 병렬 모드에서 제한 없이 실행돼도 안전함을 나타내요. 함수는 데이터베이스 상태를 수정하거나, 트랜잭션 상태를 바꾸거나(오류 복구를 위한 서브트랜잭션 사용 제외), 시퀀스에 접근하거나(예:currval호출), 설정을 영구적으로 바꾸면 parallel unsafe로 표시해야 합니다. 임시 테이블, 클라이언트 연결 상태, 커서, 준비된 문, 또는 시스템이 병렬 모드에서 동기화할 수 없는 기타 백엔드-로컬 상태에 접근하면 parallel restricted로 표시해야 해요(예:setseed는 다른 프로세스가 만든 변경이 리더에 반영되지 않으므로 그룹 리더 외에는 실행할 수 없습니다). 일반적으로 함수가 restricted나 unsafe인데 safe로 표시되거나, 실제로 unsafe인데 restricted로 표시되면 병렬 쿼리에서 오류를 던지거나 잘못된 답을 만들 수 있어요. C 언어 함수는 잘못 표시하면 이론적으로 완전히 정의되지 않은 동작을 보일 수 있는데, 임의의 C 코드에 대해 시스템이 스스로 보호할 방법이 없기 때문입니다. 하지만 대부분의 경우 결과는 다른 함수보다 나쁘지 않을 거예요. 확실하지 않으면 기본인UNSAFE로 표시해야 합니다.COST execution_cost— 함수의 예상 실행 비용을 cpu_operator_cost 단위로 주는 양수. 함수가 집합을 반환하면 반환 행당 비용이에요. 비용을 지정하지 않으면 C 언어와 internal 함수에는 1, 다른 모든 언어의 함수에는 100이 가정됩니다. 값이 클수록 플래너가 함수를 필요 이상으로 자주 평가하지 않으려고 합니다.ROWS result_rows— 플래너가 함수가 반환할 것으로 기대해야 할 예상 행 수를 주는 양수. 함수가 집합을 반환한다고 선언된 경우에만 허용돼요. 기본 가정은 1000행입니다.SUPPORT support_function— 이 함수에 사용할 플래너 지원 함수의 이름(스키마 한정 가능). 자세한 내용은 36.11절을 참고하세요. 이 옵션을 쓰려면 슈퍼유저여야 합니다.SET configuration_parameter { TO value | = value | FROM CURRENT }—SET절은 함수에 들어갈 때 지정한 구성 파라미터를 지정한 값으로 설정하고, 함수가 끝날 때 이전 값으로 복원되게 해요.SET FROM CURRENT는CREATE FUNCTION실행 시점에 현재인 파라미터 값을, 함수에 들어갈 때 적용될 값으로 저장합니다. 함수에SET절이 붙어 있으면, 함수 안에서 같은 변수에 대해 실행된SET LOCAL명령의 효과는 함수로 제한돼요. 즉 구성 파라미터의 이전 값이 여전히 함수 종료 시에 복원됩니다. 하지만LOCAL없는 일반SET명령은 이전SET LOCAL명령에서처럼SET절을 덮어써요. 그런 명령의 효과는 현재 트랜잭션이 롤백되지 않는 한 함수 종료 후에도 지속됩니다. 허용되는 파라미터 이름과 값에 대한 자세한 내용은 SET와 19장을 참고하세요.AS 'definition'— 함수를 정의하는 문자열 상수. 의미는 언어에 달려 있어요. 내부 함수 이름, 객체 파일 경로, SQL 명령, 또는 절차적 언어로 된 텍스트일 수 있습니다. 일반 작은따옴표 문법보다 달러 따옴표(dollar quoting, 4.1.2.4절 참고)로 함수 정의 문자열을 쓰는 게 도움이 될 때가 많아요. 달러 따옴표를 안 쓰면 함수 정의 안의 작은따옴표나 백슬래시를 두 배로 늘려 이스케이프해야 합니다.AS 'obj_file', 'link_symbol'— 이 형태의AS절은 C 언어 소스의 함수 이름이 SQL 함수의 이름과 다를 때 동적으로 로드되는 C 언어 함수에 쓰여요.obj_file문자열은 컴파일된 C 함수를 담은 공유 라이브러리 파일의 이름이며LOAD명령에서처럼 해석됩니다.link_symbol문자열은 함수의 링크 심볼, 즉 C 언어 소스의 함수 이름이에요. 링크 심볼을 생략하면 정의되는 SQL 함수의 이름과 같다고 가정합니다. 모든 함수의 C 이름은 서로 달라야 하므로 오버로딩된 C 함수에 다른 C 이름을 주어야 해요(예: C 이름의 일부로 인자 타입 사용). 반복된CREATE FUNCTION호출이 같은 객체 파일을 가리키면 그 파일은 세션당 한 번만 로드됩니다. 파일을 내렸다가 다시 올리려면(예를 들어 개발 중에) 새 세션을 시작하세요.sql_body—LANGUAGE SQL함수의 본문. 이는 단일 문expression또는 블록statement ...일 수 있어요. 함수 본문 텍스트를 문자열 상수로 쓰는 것(위의definition참고)과 비슷하지만 몇 가지 차이가 있어요. 이 형태는LANGUAGE SQL에서만 동작하고, 문자열 상수 형태는 모든 언어에서 동작합니다. 이 형태는 함수 정의 시점에 파싱되고, 문자열 상수 형태는 실행 시점에 파싱돼요. 따라서 이 형태는 다형성(polymorphic) 인자 타입이나 함수 정의 시점에 해석할 수 없는 다른 구조를 지원하지 못합니다. 이 형태는 함수와 함수 본문에서 쓰는 객체 사이의 의존성을 추적해서DROP ... CASCADE가 올바르게 동작하는 반면, 문자열 리터럴 형태는 매달린(dangling) 함수를 남길 수 있어요. 마지막으로 이 형태는 SQL 표준과 다른 SQL 구현과 더 호환됩니다.
오버로딩 (Overloading)
PostgreSQL은 함수 오버로딩을 허용해요. 즉 입력 인자 타입이 서로 다르다면 같은 이름을 여러 다른 함수에 쓸 수 있습니다. 쓰든 안 쓰든, 일부 사용자가 다른 사용자를 신뢰하지 않는 데이터베이스에서 함수를 호출할 때 이 능력은 보안 예방 조치를 수반합니다(10.3절 참고).
OUT 파라미터를 무시하고 이름과 입력 인자 타입이 같으면 두 함수는 같은 것으로 간주돼요. 예를 들어 다음 선언들은 충돌합니다:
CREATE FUNCTION foo(int) ...
CREATE FUNCTION foo(int, out text) ...
인자 타입 목록이 다른 함수들은 생성 시점에는 충돌하지 않는 것으로 간주되지만, 기본값이 제공되면 사용 시 충돌할 수 있어요. 예를 들어 다음을 생각해 보세요:
CREATE FUNCTION foo(int) ...
CREATE FUNCTION foo(int, int default 42) ...
호출 foo(10)은 어떤 함수를 호출해야 하는지 애매해서 실패하게 됩니다.
주의 사항 (Notes)
함수의 인자와 반환값을 선언할 때 전체 SQL 타입 문법이 허용돼요. 하지만 괄호로 된 타입 수식어(예: numeric 타입의 정밀도 필드)는 CREATE FUNCTION이 버립니다. 그래서 예를 들어 CREATE FUNCTION foo (varchar(10)) ...은 CREATE FUNCTION foo (varchar) ...과 정확히 같습니다.
CREATE OR REPLACE FUNCTION으로 기존 함수를 교체할 때 파라미터 이름 변경에는 제한이 있어요. 이미 할당된 어떤 입력 파라미터의 이름도 바꿀 수 없습니다(이전에 없던 파라미터에 이름을 추가하는 것은 가능). 출력 파라미터가 둘 이상이면 출력 파라미터 이름도 바꿀 수 없는데, 그러면 함수 결과를 설명하는 익명 복합 타입의 컬럼 이름이 바뀌기 때문이에요. 이런 제한은 함수를 교체해도 기존 호출이 중단되지 않게 하기 위한 것입니다.
함수가 VARIADIC 인자와 함께 STRICT로 선언되면, strictness 검사는 variadic 배열 전체가 null이 아닌지를 테스트합니다. 배열에 null 요소가 있어도 함수는 여전히 호출될 거예요.
예제 (Examples)
SQL 함수로 두 정수 더하기:
CREATE FUNCTION add(integer, integer) RETURNS integer
AS 'select $1 + $2;'
LANGUAGE SQL
IMMUTABLE
RETURNS NULL ON NULL INPUT;
같은 함수를 더 SQL 준수 스타일로, 인자 이름과 따옴표 없는 본문으로 쓰면:
CREATE FUNCTION add(a integer, b integer) RETURNS integer
LANGUAGE SQL
IMMUTABLE
RETURNS NULL ON NULL INPUT
RETURN a + b;
PL/pgSQL에서 인자 이름을 이용해 정수 증가시키기:
CREATE OR REPLACE FUNCTION increment(i integer) RETURNS integer AS $$
BEGIN
RETURN i + 1;
END;
$$ LANGUAGE plpgsql;
여러 출력 파라미터를 담은 레코드 반환하기:
CREATE FUNCTION dup(in int, out f1 int, out f2 text)
AS $$ SELECT $1, CAST($1 AS text) || ' is text' $$
LANGUAGE SQL;
SELECT * FROM dup(42);
명시적으로 이름 붙인 복합 타입으로 더 장황하게 같은 일을 할 수도 있어요:
CREATE TYPE dup_result AS (f1 int, f2 text);
CREATE FUNCTION dup(int) RETURNS dup_result
AS $$ SELECT $1, CAST($1 AS text) || ' is text' $$
LANGUAGE SQL;
SELECT * FROM dup(42);
여러 컬럼을 반환하는 또 다른 방법은 TABLE 함수를 쓰는 것입니다:
CREATE FUNCTION dup(int) RETURNS TABLE(f1 int, f2 text)
AS $$ SELECT $1, CAST($1 AS text) || ' is text' $$
LANGUAGE SQL;
SELECT * FROM dup(42);
다만 TABLE 함수는 앞 예제들과 다르게, 레코드 하나가 아니라 실제로 레코드 집합을 반환합니다.
SECURITY DEFINER 함수 안전하게 작성하기
SECURITY DEFINER 함수는 그 소유자의 권한으로 실행되므로, 함수가 오용되지 않도록 주의가 필요해요. 보안을 위해 search_path는 신뢰하지 않는 사용자가 쓸 수 있는 스키마를 제외하도록 설정해야 합니다. 이렇게 하면 악의적인 사용자가 함수가 쓰려는 객체를 가리는 객체(예: 테이블, 함수, 연산자)를 만드는 것을 막을 수 있어요. 이와 관련해 특히 중요한 것은 임시-테이블 스키마인데, 기본적으로 가장 먼저 검색되고 보통 누구나 쓸 수 있기 때문입니다. 임시 스키마를 마지막에 검색하도록 강제하면 안전한 배치를 얻을 수 있어요. 그러려면 search_path의 마지막 항목으로 pg_temp를 쓰세요. 다음 함수가 안전한 사용을 보여줍니다:
CREATE FUNCTION check_password(uname TEXT, pass TEXT)
RETURNS BOOLEAN AS $$
DECLARE passed BOOLEAN;
BEGIN
SELECT (pwd = $2) INTO passed
FROM pwds
WHERE username = $1;
RETURN passed;
END;
$$ LANGUAGE plpgsql
SECURITY DEFINER
-- Set a secure search_path: trusted schema(s), then 'pg_temp'.
SET search_path = admin, pg_temp;
이 함수의 의도는 admin.pwds 테이블에 접근하는 것이에요. 하지만 SET 절이 없거나 admin만 언급하는 SET 절이 있으면, pwds라는 임시 테이블을 만들어 이 함수를 약화시킬 수 있습니다.
security definer 함수가 역할을 만들려고 하고, 비슈퍼유저로 실행되고 있다면, SET 절로 createrole_self_grant도 알려진 값으로 설정해야 해요.
또 하나 명심할 점은 기본적으로 새로 만든 함수에 대해 실행 권한이 PUBLIC에 부여된다는 것입니다(더 자세한 내용은 5.8절 참고). security definer 함수의 사용을 특정 사용자에게만 제한하고 싶을 때가 자주 있어요. 그러려면 기본 PUBLIC 권한을 회수한 다음 선택적으로 실행 권한을 부여해야 합니다. 새 함수가 모두에게 접근 가능한 창(window)을 피하려면 단일 트랜잭션 안에서 함수를 만들고 권한을 설정하세요. 예를 들어:
BEGIN;
CREATE FUNCTION check_password(uname TEXT, pass TEXT) ... SECURITY DEFINER;
REVOKE ALL ON FUNCTION check_password(uname TEXT, pass TEXT) FROM PUBLIC;
GRANT EXECUTE ON FUNCTION check_password(uname TEXT, pass TEXT) TO admins;
COMMIT;
호환성 (Compatibility)
CREATE FUNCTION 명령은 SQL 표준에 정의되어 있어요. PostgreSQL 구현은 호환 가능한 방식으로 쓸 수 있지만 확장 기능이 많습니다. 반대로 SQL 표준은 PostgreSQL에서 구현되지 않은 여러 선택적 기능을 규정합니다.
중요한 호환성 이슈는 다음과 같습니다:
OR REPLACE는 PostgreSQL 확장이에요.- 일부 다른 데이터베이스 시스템과의 호환을 위해
argmode는argname앞이나 뒤에 쓸 수 있습니다. 하지만 표준을 따르는 것은 앞에 쓰는 방식뿐이에요. - 파라미터 기본값에 대해 SQL 표준은
DEFAULT키워드가 있는 문법만 규정합니다.=가 있는 문법은 T-SQL과 Firebird에서 쓰여요. SETOF수식어는 PostgreSQL 확장입니다.- 언어로 표준화된 것은
SQL뿐이에요. CALLED ON NULL INPUT과RETURNS NULL ON NULL INPUT을 제외한 다른 모든 속성은 표준화되지 않았습니다.LANGUAGE SQL함수의 본문에 대해 SQL 표준은sql_body형태만 규정해요.
단순한 LANGUAGE SQL 함수는 표준 준수이면서도 다른 구현으로 이식 가능한 방식으로 쓸 수 있습니다. 고급 기능, 최적화 속성, 또는 다른 언어를 쓰는 더 복잡한 함수는 상당 부분 PostgreSQL 특정적일 수밖에 없어요.
함께 보기 (See Also)
ALTER FUNCTION, DROP FUNCTION, GRANT, LOAD, REVOKE
더 알아보기 (Learn more)
CREATE PROCEDURE: 값을 반환하지 않아도 되는 프로시저를 정의하는 명령.ALTER FUNCTION: 기존 함수의 속성을 변경하는 명령.DROP FUNCTION: 함수를 제거하는 명령.