24.4.2 새로운 사용자 정의 함수 추가
UDF의 메커니즘이 작동하기 위해서는 함수를 C 또는 C ++로 작성하고 운영 체제가 동적로드를 지원해야합니다. MySQL 소스 배포판에는 5 개의 UDF 함수를 정의하고있는 sql/udf_example.cc
파일이 포함되어 있습니다. UDF 호출 규칙의 구조를 이해하려면이 파일을 참조하십시오. include/mysql_com.h
헤더 파일은 UDF 관련 기호 및 데이터 구조가 정의되어 있습니다 만,이 헤더 파일을 직접 포함 할 필요는없고, mysql.h
의해 포함됩니다.
UDF에 포함되어있는 코드는 실행중인 서버의 일부가되기 위해 UDF를 작성할 때 서버 코드를 작성할 때 적용되는 모든 제한 사항을 준수해야합니다. 예를 들어 libstdc++
라이브러리의 함수를 사용하려고하면 문제가 발생할 수 있습니다. 이러한 제약은 향후 서버 버전에서 변경 될 수 있으므로 서버를 업그레이드 할 때 기존 서버에 원래 작성된 UDF를 개정 할 필요가있는 경우가 있습니다. 이러한 제한 사항은 섹션 2.9.4 "MySQL 소스 구성 옵션" 및 섹션 2.9.5 "MySQL의 컴파일에 관한 문제" 를 참조하십시오.
UDF를 사용할 수 있도록하려면 mysqld를 동적으로 링크해야합니다. mysqld에서 심볼에 액세스 할 필요가있는 UDF를 사용하는 경우 (예를 들어, sql/udf_example.cc
의 metaphone
함수는 default_charset_info
을 사용합니다)는 -rdynamic
을 지정하여 프로그램을 링크해야합니다 ( man dlopen
를 참조하십시오).
SQL 문에서 사용하는 각 함수는 해당 C (또는 C ++) 함수를 정의합니다. 이후의 설명에서는 "xxx"라는 이름을 함수 이름의 예로 사용합니다. SQL과 C / C ++에서 사용을 구별하기 위해, XXX()
(대문자)는 SQL 함수 호출을 나타내며, xxx()
(소문자)는 C / C ++ 함수 호출을 보여줍니다.
C ++를 사용하는 경우는 C 함수를 다음과 같이 캡슐화 할 수 있습니다.
extern "C" { ... }
이렇게하면 완성 된 UDF에서 C ++ 함수 이름이 읽을 수있는 상태로 유지됩니다.
다음 목록은 XXX()
라는 함수의 인터페이스를 구현하기 위해 작성하는 C / C ++ 함수에 대해 설명하고 있습니다. 주요 함수 xxx()
가 필요합니다. 또한 섹션 24.3.2.6 "사용자 정의 함수 보안 예방 조치" 에 설명되어있는 이유로 UDF는 여기에서 설명하고있는 적어도 1 개 외의 함수가 필요합니다.
xxx()
메인 함수. 여기서 함수의 결과가 계산됩니다. SQL 함수의 데이터 형과 C / C ++ 함수의 반환형과의 대응을 보여줍니다.
SQLType C / C ++ Type STRING
char *
INTEGER
long long
REAL
double
DECIMAL
함수를 선언 할 수 있습니다 만, 현재 값은 문자열로 반환되므로STRING
함수의 경우와 마찬가지로 UDF를 작성합니다.ROW
함수는 구현되어 있지 않습니다.xxx_init()
xxx()
초기화 함수. 존재하는 경우는 다음의 목적으로 사용할 수 있습니다.XXX()
에 인수의 개수를 체크한다.인수가 원하는 형태임을 확인하거나 메인 함수를 호출 할 때 인수를 원하는 형태로 강제로 변경하도록 MySQL에 지시한다.
메인 함수가 필요로하는 메모리를 할당한다.
결과의 최대 길이를 지정한다.
결과 소수점 이하의 최대 자릿수를 지정 (
REAL
함수의 경우).결과로
NULL
을 허용할지 여부를 지정한다.
xxx_deinit()
xxx()
초기화 해제 함수. 존재하는 경우, 초기화 함수에 의해 할당 된 모든 메모리를 할당 해제합니다.
SQL 문이 XXX()
가 호출되면, MySQL은 초기화 함수 xxx_init()
를 호출하여 인수 검사 메모리 할당 등의 필요한 설치 프로그램을 실행시킵니다. xxx_init()
가 오류를 반환하면 MySQL 오류 메시지를 출력하여 SQL 문을 중단하고 메인 함수 나 초기화 해제 함수를 호출하지 않습니다. 그렇지 않으면, MySQL은 주요 함수 xxx()
을 행마다 1 회씩 호출합니다. 모든 행이 처리되면 MySQL은 초기화 해제 함수 xxx_deinit()
를 호출하여 필요한 정리 작업이 실행됩니다.
SUM()
처럼 작동하는 집계 함수의 경우 다음의 함수도 작성해야합니다.
xxx_clear()
현재 집계 값을 재설정하지만 새 그룹에 대한 초기 집계 값으로 인수를 삽입하지 않습니다.
xxx_add()
현재의 집계 값에 인수를 추가합니다.
MySQL은 집계 UDF를 다음과 같이 처리합니다.
xxx_init()
를 호출하여 집계 함수가 결과를 저장하는 데 필요한 메모리를 할당합니다.GROUP BY
식에 따라 테이블을 정렬합니다.새 그룹이 될 때마다 첫 번째 줄
xxx_clear()
를 호출합니다.같은 그룹에 속하는 각 행에 대해
xxx_add()
를 호출합니다.그룹이 변경된 경우 또는 마지막 행이 처리 된 후,
xxx()
를 호출하여 집계 결과를 가져옵니다.모든 행이 처리 될 때까지 3 단계에서 5 단계를 반복합니다.
xxx_deinit()
를 호출하여 UDF가 할당 된 메모리를 해제합니다.
모든 함수는 스레드로부터 안전해야합니다. 여기에는 주요 기능뿐만 아니라 초기화 함수 및 초기화 해제 함수 외에도 집계 함수에 의해 요구되는 추가 기능도 포함되어 있습니다. 이 요구 사항은 변화하는 글로벌 변수 나 정적 변수를 할당 할 수 없습니다. 메모리가 필요한 경우 메모리를 xxx_init()
에서 할당 xxx_deinit()
에서 방출하도록하십시오.