CREATE FUNCTION
설명
이 문은 사용자 정의 함수를 생성하는 데 사용됩니다.
구문
CREATE [ GLOBAL ]
[{AGGREGATE | TABLES | ALIAS }] FUNCTION <function_name>
(<arg_type> [, ...])
[ RETURNS <ret_type> ]
[ INTERMEDIATE <inter_type> ]
[ WITH PARAMETER(<param> [,...]) AS <origin_function> ]
[ PROPERTIES ("<key>" = "<value>" [, ...]) ]
필수 매개변수
1. <function_name>
function_name에db1.my_func처럼 데이터베이스 이름이 포함되어 있으면 해당 데이터베이스에 사용자 정의 함수가 생성됩니다. 그렇지 않으면 현재 세션의 데이터베이스에 함수가 생성됩니다. 새 함수의 이름과 매개변수 조합은 현재 네임스페이스의 기존 함수와 같아서는 안 됩니다. 같으면 생성에 실패합니다.
2. <arg_type>
함수의 입력 매개변수 타입입니다. 고정 인수를 하나 이상 선언할 수 있습니다. 버전 4.1.5부터는
...를 사용한 가변 인자 함수 선언이 더 이상 지원되지 않습니다. 가변 개수의 값을 받으려면 대신ARRAY매개변수를 사용하세요.
3. <ret_type>
함수의 반환 타입입니다. 새 함수를 생성할 때 반드시 지정해야 하는 매개변수입니다. 기존 함수의 별칭을 생성하는 경우에는 이 매개변수가 필요하지 않습니다.
선택 매개변수
1. GLOBAL
지정하면 생성된 함수를 전역에서 사용할 수 있습니다.
2. AGGREGATE
지정하면 집계 함수가 생성됩니다.
3. TABLES
지정하면 테이블 함수가 생성됩니다.
4. ALIAS
지정하면 별칭 함수가 생성됩니다.
함수 유형을 나타내는 위 매개변수를 하나도 선택하지 않으면 스칼라 함수가 생성됩니다.
5. <inter_type>
집계 함수의 중간 단계에서 사용하는 데이터 타입을 나타냅니다.
6. <param>
별칭 함수의 매개변수를 나타내며, 하나 이상의 매개변수가 필요합니다.
7. <origin_function>
별칭 함수에 대응하는 원본 함수를 나타냅니다.
8. <properties>
file: 사용자 정의 함수(UDF)가 포함된 JAR 패키지를 나타냅니다. 여러 머신으로 구성된 환경에서는 HTTP를 통해 다운로드할 수도 있습니다. 필수 매개변수입니다.symbol: UDF가 구현된 클래스 이름을 나타냅니다. 필수 매개변수입니다.type: UDF 호출 유형을 나타냅니다. 기본값은 Native입니다. Java UDF를 사용하는 경우 JAVA_UDF를 사용합니다.always_nullable: UDF 결과에 NULL 값이 포함될 수 있는지를 나타냅니다. 선택 매개변수이며 기본값은 true입니다.volatility: 함수 결과의 안정성을 나타냅니다. 이 매개변수는 4.1.2부터 지원됩니다. 선택 매개변수입니다. 기본값은 스칼라 UDF의 경우volatile이며, UDAF/UDTF의 경우immutable입니다. 유효한 값은 다음과 같습니다.
immutable: 같은 입력에 대해 항상 같은 출력을 반환합니다. 대부분의 결정적 UDF는immutable로 표시하여 옵티마이저가 실행 계획에 더 많은 최적화를 적용할 수 있도록 해야 합니다.stable: 하나의 SQL 문 내에서는 결과가 일정하지만 SQL 문이 달라지면 바뀔 수 있으며,now()와 유사합니다. 이 유형의 함수에는 SQL 캐시와 구체화된 뷰 재작성이 비활성화됩니다.volatile: 호출할 때마다 결과가 바뀔 수 있으며,random()과 유사합니다. 이 유형의 함수에는 SQL 캐시, 구체화된 뷰 재작성, 여러 옵티마이저 재작성 규칙이 비활성화됩니다.
접근 제어 요구 사항
이 명령을 실행하려면 사용자에게 ADMIN_PRIV 권한이 있어야 합니다.
예제
-
사용자 정의 UDF 함수를 생성합니다. 자세한 내용은 JAVA-UDF를 참조하세요.
CREATE FUNCTION java_udf_add_one(int) RETURNS int PROPERTIES (
"file"="file:///path/to/java-udf-demo-jar-with-dependencies.jar",
"symbol"="org.apache.doris.udf.AddOne",
"always_nullable"="true",
"type"="JAVA_UDF",
"volatility"="immutable"
); -
사용자 정의 UDAF 함수를 생성합니다.
CREATE AGGREGATE FUNCTION simple_sum(INT) RETURNS INT PROPERTIES (
"file"="file:///pathTo/java-udaf.jar",
"symbol"="org.apache.doris.udf.demo.SimpleDemo",
"always_nullable"="true",
"type"="JAVA_UDF"
); -
사용자 정의 UDTF 함수를 생성합니다.
CREATE TABLES FUNCTION java_udtf(string, string) RETURNS array<string> PROPERTIES (
"file"="file:///pathTo/java-udaf.jar",
"symbol"="org.apache.doris.udf.demo.UDTFStringTest",
"always_nullable"="true",
"type"="JAVA_UDF"
); -
사용자 정의 별칭 함수를 생성합니다. 자세한 내용은 별칭 함수를 참조하세요.
CREATE ALIAS FUNCTION id_masking(INT) WITH PARAMETER(id) AS CONCAT(LEFT(id, 3), '****', RIGHT(id, 4)); -
전역 사용자 정의 별칭 함수를 생성합니다.
CREATE GLOBAL ALIAS FUNCTION id_masking(INT) WITH PARAMETER(id) AS CONCAT(LEFT(id, 3), '****', RIGHT(id, 4)); -
volatile Python UDF를 생성합니다. 무작위성에 의존하는
uuid.uuid4()같은 함수는 기본값인volatility = volatile을 유지해야 하며,immutable로 잘못 표시해서는 안 됩니다.CREATE TABLE cte_uuid_seed (id INT) ENGINE=OLAP DUPLICATE KEY(id)
DISTRIBUTED BY HASH(id) BUCKETS 1 PROPERTIES ("replication_num" = "1");
INSERT INTO cte_uuid_seed VALUES (1),(2),(3);
DROP FUNCTION IF EXISTS py_uuid_token(INT);
CREATE FUNCTION py_uuid_token(INT)
RETURNS STRING
PROPERTIES (
"type" = "PYTHON_UDF",
"symbol" = "py_uuid_token_impl",
"always_nullable" = "false",
"runtime_version" = "3.12.11",
"volatility" = "volatile"
)
AS $$
import uuid
def py_uuid_token_impl(x):
return f"{x}-{uuid.uuid4()}"
$$;
SET enable_cte_materialize = true;
SET inline_cte_referenced_threshold = 10;
WITH cte AS (SELECT id, py_uuid_token(id) AS token FROM cte_uuid_seed)
SELECT id, COUNT(DISTINCT token) AS distinct_tokens
FROM (SELECT id, token FROM cte UNION ALL SELECT id, token FROM cte) u
GROUP BY id ORDER BY id;올바른 결과:
+------+-----------------+
| id | distinct_tokens |
+------+-----------------+
| 1 | 1 |
| 2 | 1 |
| 3 | 1 |
+------+-----------------+이 함수에 대해 다음 정의는 잘못된 것입니다.
DROP FUNCTION IF EXISTS py_uuid_token(INT);
CREATE FUNCTION py_uuid_token(INT)
RETURNS STRING
PROPERTIES (
"type" = "PYTHON_UDF",
"symbol" = "py_uuid_token_impl",
"always_nullable" = "false",
"runtime_version" = "3.12.11",
"volatility" = "immutable"
)
AS $$
import uuid
def py_uuid_token_impl(x):
return f"{x}-{uuid.uuid4()}"
$$;같은 쿼리를 다시 실행합니다.
WITH cte AS (SELECT id, py_uuid_token(id) AS token FROM cte_uuid_seed)
SELECT id, COUNT(DISTINCT token) AS distinct_tokens
FROM (SELECT id, token FROM cte UNION ALL SELECT id, token FROM cte) u
GROUP BY id ORDER BY id;잘못된 결과:
+------+-----------------+
| id | distinct_tokens |
+------+-----------------+
| 1 | 2 |
| 2 | 2 |
| 3 | 2 |
+------+-----------------+잘못된 이유:
py_uuid_token은 volatile 함수이므로uuid.uuid4()를 호출할 때마다 새 값이 생성됩니다. 함수를volatility = immutable로 잘못 표시하면, 옵티마이저는 반복 참조를 안전하게 재작성할 수 있다고 판단하고UNION ALL의 양쪽에서 UDF를 별도로 평가하는 실행 계획을 선택할 수 있습니다. 그 결과, 동일한id에서 서로 다른 두 개의token값이 생성될 수 있으며,COUNT(DISTINCT token)이1에서2로 바뀝니다.