함수
함수 (Functions)
CQL은 두 가지 주요 함수 범주를 지원해요:
- 스칼라 함수(scalar functions): 여러 값을 받아 하나의 출력을 생성
- 집계 함수(aggregate functions): SELECT 문에서 나온 여러 행을 집계
두 경우 모두 CQL은 여러 네이티브 "하드코딩된" 함수와, 새 사용자 정의 함수를 만들 수 있는 기능을 제공합니다.
기본적으로 사용자 정의 함수는 보안 문제로 비활성화되어 있습니다(활성화하더라도 사용자 정의 함수의 실행은 샌드박스 처리되고 "불량" 함수가 악의적인 일을 하지 못해야 하지만, 완벽한 샌드박스는 없으므로 사용자 정의 함수 사용은 opt-in입니다). 이들을 활성화하려면
cassandra.yaml의user_defined_functions_enabled를 참고하세요.
함수는 이름으로 식별됩니다:
function_name ::= [ keyspace_name'.' ] name
출처: 문서
본문
스칼라 함수 (Scalar functions)
네이티브 함수
Cast
cast 함수는 네이티브 데이터 타입을 다른 타입으로 변환하는 데 사용할 수 있어요.
다음 표는 cast 함수가 지원하는 변환을 설명합니다. Cassandra는 데이터 타입을 자기 자신의 타입으로 변환하는 캐스트는 조용히 무시합니다.
| From | To |
|---|---|
| ascii | text, varchar |
| bigint | tinyint, smallint, int, float, double, decimal, varint, text, varchar |
| boolean | text, varchar |
| counter | tinyint, smallint, int, bigint, float, double, decimal, varint, text, varchar |
| date | timestamp |
| decimal | tinyint, smallint, int, bigint, float, double, varint, text, varchar |
| double | tinyint, smallint, int, bigint, float, decimal, varint, text, varchar |
| float | tinyint, smallint, int, bigint, double, decimal, varint, text, varchar |
| inet | text, varchar |
| int | tinyint, smallint, bigint, float, double, decimal, varint, text, varchar |
| smallint | tinyint, int, bigint, float, double, decimal, varint, text, varchar |
| time | text, varchar |
| timestamp | date, text, varchar |
| timeuuid | timestamp, date, text, varchar |
| tinyint | tinyint, smallint, int, bigint, float, double, decimal, varint, text, varchar |
| uuid | text, varchar |
| varint | tinyint, smallint, int, bigint, float, double, decimal, text, varchar |
변환은 엄격히 Java의 의미론에 의존합니다. 예를 들어 double 값 1은 text 값 '1.0'으로 변환됩니다. 예를 들어:
SELECT avg(cast(count as double)) FROM myTable
Token
token 함수는 주어진 파티션 키에 대한 토큰을 계산합니다. token 함수의 정확한 시그니처는 관련된 테이블과 클러스터가 사용하는 파티셔너에 따라 다릅니다.
token의 인자 타입은 파티션 키 컬럼 타입에 따라 달라집니다. 반환 타입은 정의된 파티셔너에 따라 달라요:
| 파티셔너 | 반환 타입 |
|---|---|
| Murmur3Partitioner | bigint |
| RandomPartitioner | varint |
| ByteOrderedPartitioner | blob |
예를 들어 다음 테이블을 생각해 봅시다:
CREATE TABLE users (
userid text PRIMARY KEY,
username text,
);
테이블은 기본 Murmur3Partitioner를 사용합니다. 파티션 키가 text 타입의 userid이므로 token 함수는 단일 인자 text를 사용합니다. 반환 타입은 bigint입니다.
Uuid
uuid 함수는 파라미터를 받지 않고 INSERT 또는 UPDATE 문에서 사용하기에 적합한 랜덤 type 4 uuid를 생성합니다.
Timeuuid 함수
now now 함수는 인자를 받지 않고, 조정자 노드에서 함수가 호출되는 시점에 새 고유 timeuuid를 생성합니다. 이 메서드는 삽입에 유용하지만 WHERE 절에서는 대체로 무의미하다는 점에 유의하세요.
예를 들어 다음 형태의 쿼리는:
SELECT * FROM myTable WHERE t = now();
by design으로 결과를 반환하지 않습니다. now()가 반환하는 값이 고유함이 보장되기 때문이에요.
current_timeuuid는 now의 별칭입니다.
min_timeuuid 및 max_timeuuid min_timeuuid 함수는 timestamp 값 t(타임스탬프 또는 날짜 문자열)를 받습니다. 타임스탬프 t에 대한 가능한 가장 작은 timeuuid에 해당하는 가짜 timeuuid를 반환합니다. max_timeuuid도 유사하게 동작하지만 가능한 가장 큰 timeuuid를 반환합니다.
예를 들어:
SELECT * FROM myTable
WHERE t > max_timeuuid('2013-01-01 00:05+0000')
AND t < min_timeuuid('2013-02-02 10:00+0000');
는 timeuuid 컬럼 t가 '2013-01-01 00:05+0000'보다 늦고 '2013-02-02 10:00+0000'보다 이른 모든 행을 선택합니다. t >= maxTimeuuid('2013-01-01 00:05+0000') 절은 정확히 '2013-01-01 00:05+0000'에 생성된 timeuuid를 여전히 선택하지 않으며, 본질적으로 t > maxTimeuuid('2013-01-01 00:05+0000')와 동등합니다.
min_timeuuid와 max_timeuuid가 생성하는 값은 IETF RFC 4122가 지정한 시간 기반 UUID 생성 과정을 따르지 않기 때문에 가짜 UUID라고 불립니다. 특히 이 두 메서드가 반환하는 값은 고유하지 않습니다. 따라서 가능한 데이터 덮어쓰기를 방지하기 위해 이 메서드들은 삽입이 아니라 쿼리에만 사용하세요.
날짜/시간 함수 (Datetime functions)
현재 날짜/시간 가져오기 함수가 호출되는 시점에 날짜/시간을 가져오는 데 다음 함수를 사용할 수 있습니다:
| 함수 이름 | 출력 타입 |
|---|---|
| current_timestamp | timestamp |
| current_date | date |
| current_time | time |
| current_timeuuid | timeUUID |
예를 들어 지난 이틀간의 데이터는 다음으로 가져올 수 있습니다:
SELECT * FROM myTable WHERE date >= current_date() - 2d;
시간 변환 함수 timeuuid, timestamp, date를 다른 네이티브 타입으로 변환하는 여러 함수가 제공됩니다.
| 함수 이름 | 입력 타입 | 설명 |
|---|---|---|
| to_date | timeuuid | timeuuid 인자를 date 타입으로 변환 |
| to_date | timestamp | timestamp 인자를 date 타입으로 변환 |
| to_timestamp | timeuuid | timeuuid 인자를 timestamp 타입으로 변환 |
| to_timestamp | date | date 인자를 timestamp 타입으로 변환 |
| to_unix_timestamp | timeuuid | timeuuid 인자를 bigInt 원시 값으로 변환 |
| to_unix_timestamp | timestamp | timestamp 인자를 bigInt 원시 값으로 변환 |
| to_unix_timestamp | date | date 인자를 bigInt 원시 값으로 변환 |
Blob 변환 함수
CQL이 지원하는 모든 타입에 대해, type_as_blob 함수는 type 타입의 인자를 받아 blob으로 반환합니다. 반대로 blob_as_type 함수는 64비트 blob 인자를 받아 bigint 값으로 변환합니다. 예를 들어 bigint_as_blob(3)은 0x0000000000000003을 반환하고 blob_as_bigint(0x0000000000000003)은 3을 반환합니다.
수학 함수 (Math Functions)
CQL은 abs, exp, log, log10, round 수학 함수를 제공합니다. 이 함수들의 반환 타입은 항상 입력 타입과 같습니다.
| 함수 이름 | 설명 |
|---|---|
| abs | 입력의 절대값 반환 |
| exp | e의 입력 제곱 반환 |
| log | 입력의 자연 로그 반환 |
| log10 | 입력의 밑 10 로그 반환 |
| round | HALF_UP 반올림 모드를 사용해 입력을 가장 가까운 정수로 반올림 |
컬렉션 함수 (Collection functions)
컬렉션 컬럼에 대해 동작하는 여러 함수가 제공됩니다.
| 함수 이름 | 입력 타입 | 설명 |
|---|---|---|
| map_keys | map | map 인자의 키를 가져와 set으로 반환 |
| map_values | map | map 인자의 값을 가져와 list로 반환 |
| collection_count | map, set 또는 list | 컬렉션 인자의 요소 수 가져옴 |
| collection_min | set 또는 list | 컬렉션 인자의 최소 요소 가져옴 |
| collection_max | set 또는 list | 컬렉션 인자의 최대 요소 가져옴 |
| collection_sum | 숫자 set 또는 list | 컬렉션 인자 요소들의 합 계산. 반환 값은 입력 컬렉션 요소와 같은 타입이므로, 값의 합이 타입이 표현할 수 있는 최대 값을 초과하면 데이터 타입이 오버플로될 위험이 있음 |
| collection_avg | 숫자 set 또는 list | 컬렉션 인자 요소들의 평균 계산. 빈 컬렉션의 평균은 0을 반환. 반환 값은 입력 컬렉션 요소와 같은 타입이라 반올림과 잘림을 포함할 수 있음. 예: collection_avg([1, 2])는 1.5 대신 1을 반환 |
데이터 마스킹 함수 (Data masking functions)
민감한 데이터를 포함하는 컬럼의 실제 내용을 가릴 수 있는 여러 함수가 있습니다.
| 함수 | 설명 |
|---|---|
| mask_null(value) | 첫 번째 인자를 null 컬럼으로 대체. 반환 값은 항상 존재하지 않는 컬럼이며, null 값을 나타내는 not-null 컬럼이 아님. 예: mask_null('Alice') → null, mask_null(123) → null |
| mask_default(value) | 그 인자를 같은 타입의 임의의 고정 기본값으로 대체. text 값은 ****, 숫자는 0, 불리언은 false 등. 고정 길이 다중 값 타입(튜플, UDT, 벡터)은 각 값을 값 타입의 기본 마스킹 값으로 대체해 마스킹됨. 예: mask_default('Alice') → '****', mask_default(123) → 0, mask_default((list<int>) [1, 2, 3]) → [], mask_default((vector<int, 3>) [1, 2, 3]) → [0, 0, 0] |
| mask_replace(value, replacement) | 첫 번째 인자를 두 번째 인자의 대체 값으로 대체. 대체 값은 대체되는 값과 같은 타입이어야 함. 예: mask_replace('Alice', 'REDACTED') → 'REDACTED', mask_replace(123, -1) → -1 |
| mask_inner(value, begin, end, [padding]) | 첫 번째 text, varchar, ascii 인자의 사본을 반환하며, 첫 번째와 마지막을 제외한 각 문자를 패딩 문자로 대체. 두 번째와 세 번째 인자는 노출되는 접두사와 접미사 크기. 선택적 네 번째 인자는 패딩 문자로 기본은 *. 예: mask_inner('Alice', 1, 2) → 'Ace', mask_inner('Alice', 1, null) → 'A', mask_inner('Alice', null, 2) → '*ce', mask_inner('Alice', 2, 1, '#') → 'Al##e' |
| mask_outer(value, begin, end, [padding]) | 첫 번째 text, varchar, ascii 인자의 사본을 반환하며, 첫 번째와 마지막 문자를 패딩 문자로 대체. 두 번째와 세 번째 인자는 노출되는 접두사와 접미사 크기. 선택적 네 번째 인자는 패딩 문자로 기본은 *. 예: mask_outer('Alice', 1, 2) → '*li', mask_outer('Alice', 1, null) → '*lice', mask_outer('Alice', null, 2) → 'Ali', mask_outer('Alice', 2, 1, '#') → '##ic#' |
| mask_hash(value, [algorithm]) | 첫 번째 인자의 해시를 포함하는 blob 반환. 선택적 두 번째 인자는 사용할 해싱 알고리즘으로, 사용 가능한 Java 보안 공급자에 따름. 기본 해싱 알고리즘은 SHA-256. 예: mask_hash('Alice'), mask_hash('Alice', 'SHA-512') |
벡터 유사도 함수 (Vector similarity functions) float 벡터 간의 유사도 점수를 얻을 수 있는 여러 함수가 있습니다.
| 함수 | 설명 |
|---|---|
| similarity_cosine(vector, vector) | 같은 차원의 두 float 벡터 간 코사인 유사도 점수 계산. 예: similarity_cosine([0.1, 0.2], null) → null, similarity_cosine([0.1, 0.2], [0.1, 0.2]) → 1, similarity_cosine([0.1, 0.2], [-0.1, -0.2]) → 0, similarity_cosine([0.1, 0.2], [0.9, 0.8]) → 0.964238 |
| similarity_euclidean(vector, vector) | 같은 차원의 두 float 벡터 간 유클리드 거리 계산. 예: similarity_euclidean([0.1, 0.2], null) → null, similarity_euclidean([0.1, 0.2], [0.1, 0.2]) → 1, similarity_euclidean([0.1, 0.2], [-0.1, -0.2]) → 0.833333, similarity_euclidean([0.1, 0.2], [0.9, 0.8]) → 0.5 |
| similarity_dot_product(vector, vector) | 같은 차원의 두 float 벡터 간 내적(dot product) 계산. 예: similarity_dot_product([0.1, 0.2], null) → null, similarity_dot_product([0.1, 0.2], [0.1, 0.2]) → 0.525, similarity_dot_product([0.1, 0.2], [-0.1, -0.2]) → 0.475, similarity_dot_product([0.1, 0.2], [0.9, 0.8]) → 0.625 |
사용자 정의 함수 (User-defined functions)
사용자 정의 함수(UDF)는 Cassandra에서 사용자 제공 코드를 실행합니다. 기본적으로 Cassandra는 Java로 함수를 정의하는 것을 지원합니다.
UDF는 Cassandra 스키마의 일부이며 클러스터의 모든 노드에 자동으로 전파됩니다. UDF는 오버로드될 수 있어 서로 다른 인자 타입을 가진 여러 UDF가 같은 함수 이름을 가질 수 있어요.
JavaScript 사용자 정의 함수는 Cassandra 4.1에서 더 이상 사용되지 않았습니다(deprecated). Cassandra 5.0 준비 차원에서 그 제거가 이미 진행 중입니다. 자세한 내용은 CASSANDRA-17281, CASSANDRA-18252 참고.
예를 들어:
CREATE FUNCTION sample ( arg int ) ...;
CREATE FUNCTION sample ( arg text ) ...;
UDF는 선택한 프로그래밍 언어의 모든 일반적인 문제에 취약합니다. 따라서 구현은 null 포인터 예외, 잘못된 인자, 또는 다른 잠재적 예외 소스에 대해 안전해야 해요. 함수 실행 중 예외가 발생하면 전체 문이 실패합니다. UDF 사용에 유효한 쿼리는 SELECT, INSERT, UPDATE 문입니다.
컬렉션, 튜플 타입, 사용자 정의 타입 같은 복잡한 타입은 UDF에서 유효한 인자 및 반환 타입입니다. 튜플 타입과 사용자 정의 타입은 DataStax Java Driver 변환 함수를 사용합니다. 튜플 타입과 사용자 정의 타입 처리에 대한 자세한 내용은 Java Driver 문서를 참고하세요.
함수 인자는 리터럴 또는 term이 될 수 있습니다. Prepared statement 자리 표시자도 사용할 수 있어요.
UDF 소스 코드를 감싸려면 이중 달러 기호 문법($$)을 사용합니다.
예를 들어:
CREATE FUNCTION some_function ( arg int )
RETURNS NULL ON NULL INPUT
RETURNS int
LANGUAGE java
AS $$ return arg; $$;
SELECT some_function(column) FROM atable ...;
UPDATE atable SET col = some_function(?) ...;
CREATE TYPE custom_type (txt text, i int);
CREATE FUNCTION fct_using_udt ( udtarg frozen )
RETURNS NULL ON NULL INPUT
RETURNS text
LANGUAGE java
AS $$ return udtarg.getString("txt"); $$;
암시적으로 사용 가능한 udfContext 필드(또는 스크립트 UDF용 바인딩)는 새 UDT 및 튜플 값을 만드는 데 필요한 기능을 제공합니다:
CREATE TYPE custom_type (txt text, i int);
CREATE FUNCTION fct\_using\_udt ( somearg int )
RETURNS NULL ON NULL INPUT
RETURNS custom_type
LANGUAGE java
AS $$
UDTValue udt = udfContext.newReturnUDTValue();
udt.setString("txt", "some string");
udt.setInt("i", 42);
return udt;
$$;
UDFContext 인터페이스의 정의는 Apache Cassandra 소스 코드의 org.apache.cassandra.cql3.functions.UDFContext에서 찾을 수 있어요.
public interface UDFContext
{
UDTValue newArgUDTValue(String argName);
UDTValue newArgUDTValue(int argNum);
UDTValue newReturnUDTValue();
UDTValue newUDTValue(String udtName);
TupleValue newArgTupleValue(String argName);
TupleValue newArgTupleValue(int argNum);
TupleValue newReturnTupleValue();
TupleValue newTupleValue(String cqlDefinition);
}
Java UDF에는 이미 공통 인터페이스와 클래스에 대한 몇 가지 import가 정의되어 있습니다. 이 import는:
import java.nio.ByteBuffer;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.cassandra.cql3.functions.UDFContext;
import com.datastax.driver.core.TypeCodec;
import com.datastax.driver.core.TupleValue;
import com.datastax.driver.core.UDTValue;
이 편의 import는 스크립트 UDF에는 사용할 수 없다는 점을 유의하세요.
CREATE FUNCTION 문
새 사용자 정의 함수를 만드는 것은 CREATE FUNCTION 문을 사용합니다:
create_function_statement::= CREATE [ OR REPLACE ] FUNCTION [ IF NOT EXISTS]
function_name '(' arguments_declaration ')'
[ CALLED | RETURNS NULL ] ON NULL INPUT
RETURNS cql_type
LANGUAGE identifier
AS string arguments_declaration: identifier cql_type ( ',' identifier cql_type )*
예를 들어:
CREATE OR REPLACE FUNCTION somefunction(somearg int, anotherarg text, complexarg frozen<someUDT>, listarg list)
RETURNS NULL ON NULL INPUT
RETURNS text
LANGUAGE java
AS $$
// some Java code
$$;
CREATE FUNCTION IF NOT EXISTS akeyspace.fname(someArg int)
CALLED ON NULL INPUT
RETURNS text
LANGUAGE java
AS $$
// some Java code
$$;
선택적 OR REPLACE 키워드가 있는 CREATE FUNCTION은 함수를 만들거나 같은 시그니처의 기존 함수를 대체합니다. OR REPLACE 없는 CREATE FUNCTION은 같은 시그니처의 함수가 이미 존재하면 실패합니다. 선택적 IF NOT EXISTS 키워드를 사용하면 같은 시그니처의 다른 함수가 존재하지 않을 때에만 함수가 만들어집니다. OR REPLACE와 IF NOT EXISTS는 함께 사용할 수 없어요.
각 함수에 대해 null 입력 값의 동작이 정의되어야 합니다:
RETURNS NULL ON NULL INPUT은 입력 인자 중 하나라도 null이면 함수가 항상 null을 반환함을 선언합니다.CALLED ON NULL INPUT은 함수가 항상 실행됨을 선언합니다.
함수 시그니처
시그니처는 개별 함수를 구분하는 데 사용됩니다. 시그니처는 <keyspace>.<function_name>의 완전히 자격을 갖춘 함수 이름과 모든 인자 타입의 연결된 목록으로 구성됩니다.
키스페이스 이름, 함수 이름, 인자 타입은 기본 명명 규칙과 대소문자 구분 규칙의 적용을 받습니다.
함수는 키스페이스에 속합니다. 키스페이스가 지정되지 않으면 현재 키스페이스가 사용됩니다. 사용자 정의 함수는 시스템 키스페이스에는 허용되지 않습니다.
DROP FUNCTION 문
함수 삭제는 DROP FUNCTION 문을 사용합니다:
drop_function_statement::= DROP FUNCTION [ IF EXISTS ] function_name [ '(' arguments_signature ')' ]
arguments_signature::= cql_type ( ',' cql_type )*
예를 들어:
DROP FUNCTION myfunction;
DROP FUNCTION mykeyspace.afunction;
DROP FUNCTION afunction ( int );
DROP FUNCTION afunction ( text );
같은 이름이지만 다른 시그니처를 가진 여러 오버로드된 함수가 있다면 drop 명령에서 함수의 인자 타입인 arguments_signature를 지정해야 합니다. 선택적 IF EXISTS 키워드가 있는 DROP FUNCTION은 함수가 존재하면 삭제하지만, 존재하지 않아도 오류를 던지지 않습니다.
집계 함수 (Aggregate functions)
집계 함수는 일련의 행에 대해 동작합니다. 집계된 행 집합에 대해 단일 값을 반환하기 위해 각 행의 값이 입력됩니다.
일반 컬럼, 스칼라 함수, UDT 필드, writetime, ttl이 집계 함수와 함께 선택되면, 그 값들은 쿼리와 일치하는 첫 번째 행의 값으로 반환됩니다.
네이티브 집계
Count
count 함수는 쿼리가 반환하는 행 수를 세는 데 사용할 수 있어요.
예를 들어:
SELECT COUNT (*) FROM plays;
SELECT COUNT (1) FROM plays;
주어진 컬럼의 non-null 값도 셀 수 있습니다:
SELECT COUNT (scores) FROM plays;
Max and Min
max와 min 함수는 주어진 컬럼에 대해 쿼리가 반환하는 최대값과 최소값을 계산합니다.
예를 들어:
SELECT MIN (players), MAX (players) FROM plays WHERE game = 'quake';
Sum
sum 함수는 주어진 컬럼에 대해 쿼리가 반환하는 모든 값을 합산합니다.
반환 값은 입력 컬렉션 요소와 같은 타입이므로, 값의 합이 타입이 표현할 수 있는 최대 값을 초과하면 오버플로 위험이 있습니다.
예를 들어:
SELECT SUM (players) FROM plays;
반환 값은 입력 값과 같은 타입이므로 값의 합이 타입이 표현할 수 있는 최대 값을 초과하면 타입이 오버플로될 위험이 있어요. 타입 캐스팅을 사용해 입력 값을 타입을 담을 만큼 큰 타입으로 캐스팅할 수 있습니다. 예를 들어:
SELECT SUM (CAST (players AS VARINT)) FROM plays;
Avg
avg 함수는 주어진 컬럼에 대해 쿼리가 반환하는 모든 값의 평균을 계산합니다.
예를 들어:
SELECT AVG (players) FROM plays;
빈 컬렉션의 평균은 0을 반환합니다.
반환 값은 입력 값과 같은 타입이며, 반올림과 잘림을 포함할 수 있어요. 예를 들어 collection_avg([1, 2])는 1.5 대신 1을 반환합니다. 타입 캐스팅을 사용해 원하는 소수 정밀도를 가진 타입으로 캐스팅할 수 있어요. 예를 들어:
SELECT AVG (CAST (players AS FLOAT)) FROM plays;
사용자 정의 집계 (UDAs)
사용자 정의 집계는 커스텀 집계 함수를 만들 수 있게 합니다. 사용자 정의 집계는 SELECT 문에서 사용될 수 있어요.
각 집계는 INITCOND 값(기본값: null)으로 정의된 STYPE 타입의 초기 상태를 요구합니다. 상태 함수의 첫 번째 인자는 STYPE 타입이어야 합니다. 상태 함수의 나머지 인자는 사용자 정의 집계 인자의 타입과 일치해야 합니다. 상태 함수는 각 행에 대해 한 번 호출되고, 상태 함수가 반환하는 값이 새 상태가 됩니다. 모든 행이 처리된 후 선택적 FINALFUNC가 마지막 상태 값을 인자로 실행됩니다.
STYPE 값은 집계 생성 후 오버로드가 나타날 수 있으므로, 상태 및/또는 최종 함수의 가능한 오버로드 버전을 구분하기 위해 필수입니다.
사용자 정의 집계에 대한 완전한 작동 예제(USE 문으로 키스페이스가 선택되었다고 가정):
CREATE OR REPLACE FUNCTION test.averageState(state tuple<int,bigint>, val int)
CALLED ON NULL INPUT
RETURNS tuple
LANGUAGE java
AS $$
if (val != null) {
state.setInt(0, state.getInt(0)+1);
state.setLong(1, state.getLong(1)+val.intValue());
}
return state;
$$;
CREATE OR REPLACE FUNCTION test.averageFinal (state tuple<int,bigint>)
CALLED ON NULL INPUT
RETURNS double
LANGUAGE java
AS $$
double r = 0;
if (state.getInt(0) == 0) return null;
r = state.getLong(1);
r /= state.getInt(0);
return Double.valueOf(r);
$$;
CREATE OR REPLACE AGGREGATE test.average(int)
SFUNC averageState
STYPE tuple
FINALFUNC averageFinal
INITCOND (0, 0);
CREATE TABLE test.atable (
pk int PRIMARY KEY,
val int
);
INSERT INTO test.atable (pk, val) VALUES (1,1);
INSERT INTO test.atable (pk, val) VALUES (2,2);
INSERT INTO test.atable (pk, val) VALUES (3,3);
INSERT INTO test.atable (pk, val) VALUES (4,4);
SELECT test.average(val) FROM atable;
CREATE AGGREGATE 문
사용자 정의 집계 함수를 만들거나 대체하는 것은 CREATE AGGREGATE 문을 사용합니다:
create_aggregate_statement ::= CREATE [ OR REPLACE ] AGGREGATE [ IF NOT EXISTS ]
function_name '(' arguments_signature')'
SFUNC function_name
STYPE cql_type:
[ FINALFUNC function_name]
[ INITCOND term ]
완전한 예제는 위를 참고하세요.
선택적 OR REPLACE 키워드가 있는 CREATE AGGREGATE 명령은 집계를 만들거나 같은 시그니처의 기존 집계를 대체합니다. OR REPLACE 없는 CREATE AGGREGATE는 같은 시그니처의 집계가 이미 존재하면 실패합니다. 선택적 IF NOT EXISTS 키워드가 있는 CREATE AGGREGATE 명령은 집계가 아직 존재하지 않으면 집계를 만듭니다. OR REPLACE와 IF NOT EXISTS 문구는 함께 사용할 수 없습니다.
STYPE 값은 상태 값의 타입을 정의하며 지정해야 합니다. 선택적 INITCOND는 집계의 초기 상태 값을 정의하며 기본값은 null입니다. RETURNS NULL ON NULL INPUT으로 선언된 상태 함수에는 non-null INITCOND를 지정해야 합니다.
SFUNC 값은 상태 수정 함수로 사용할 기존 함수를 참조합니다. 상태 함수의 첫 번째 인자는 STYPE 타입이어야 합니다. 상태 함수의 나머지 인자는 사용자 정의 집계 인자의 타입과 일치해야 합니다. 상태 함수는 각 행에 대해 한 번 호출되고 상태 함수가 반환하는 값이 새 상태가 됩니다. RETURNS NULL ON NULL INPUT으로 선언되고 null로 호출된 상태 함수는 상태를 업데이트하지 않습니다. 모든 행이 처리된 후 선택적 FINALFUNC가 마지막 상태 값을 인자로 실행됩니다. STYPE 타입의 인자 하나만 받아야 하지만 FINALFUNC의 반환 타입은 다른 타입일 수 있어요. RETURNS NULL ON NULL INPUT으로 선언된 최종 함수는 마지막 상태가 null이면 집계의 반환 값이 null임을 의미합니다.
FINALFUNC가 정의되지 않으면 집계 함수의 전체 반환 타입은 STYPE입니다. FINALFUNC가 정의되면 그 함수의 반환 타입입니다.
DROP AGGREGATE 문
사용자 정의 집계 함수를 삭제하는 것은 DROP AGGREGATE 문을 사용합니다:
drop_aggregate_statement::= DROP AGGREGATE [ IF EXISTS ] function_name[ '(' arguments_signature ')' ]
예를 들어:
DROP AGGREGATE myAggregate;
DROP AGGREGATE myKeyspace.anAggregate;
DROP AGGREGATE someAggregate ( int );
DROP AGGREGATE someAggregate ( text );
DROP AGGREGATE 문은 CREATE AGGREGATE로 만든 집계를 제거합니다. 같은 이름이지만 다른 시그니처를 가진 여러 오버로드된 집계가 있다면 삭제할 집계의 인자 타입을 지정해야 합니다.
선택적 IF EXISTS 키워드가 있는 DROP AGGREGATE 명령은 집계가 존재하면 삭제하고, 그 시그니처의 함수가 존재하지 않으면 아무것도 하지 않습니다.
더 알아보기 (Learn more)
- 데이터 타입 — timeuuid, 벡터 등 타입
- 데이터 조작(DML) — SELECT 문 함수 사용