Skip to main content
Rust SDK는 알파 단계입니다 — 릴리스 간에 호환성이 깨지는 API 변경이 발생할 수 있습니다. 함수 전용 확장, 집계 함수, 가변 인자 함수, 그리고 사용자 정의 타입(encode, decode, compare, hash)이 지원되며, sys_var, status_var, thread_worker, keyring 미리보기 기능도 지원됩니다. 컬럼 저장 ABI는 현재 C++ 전용입니다 — 이 기능이 필요하다면 C++ SDK를 사용하세요.
이 페이지는 villagesql 크레이트 API에 대한 참조입니다. 시작하기 가이드는 Rust로 확장 만들기를 참조하세요. 사용자 정의 타입에 대해서는 Rust에서의 사용자 정의 타입을 참조하세요.

InValue

InValue는 서버가 각 함수 인수에 대해 전달하는 열거형입니다. 함수는 args: &[InValue]를 받으며, 값을 사용하기 전에 각 인수를 확인해야 합니다.
항상 Null을 명시적으로 매치해야 합니다. .unwrap()을 호출하거나 값 배리언트만 패턴 매칭하는 것은 버그입니다 — SQL NULL은 오류가 아닌 정상적인 입력입니다.

VdfReturn

VdfReturn은 함수가 서버에 반환하는 것입니다. 연관 함수 중 하나로 구성합니다: 경고 vs 오류: 사용자 입력 검증 실패 시 결과 집합의 나머지 부분을 계속 처리하는 것이 합리적인 경우 warning을 사용하세요. 엄격 모드에서는 MySQL이 INSERTUPDATE에서 경고를 오류로 승격시킵니다. 데이터가 손상되거나 내부 불변 조건 위반과 같은 안전하지 않은 상황에서는 error를 사용하세요. 치명적 오류는 전체 문을 중단합니다.

extension! 매크로

extension!은 서버가 VEB 파일을 로드할 때 호출하는 VEF 엔트리 포인트를 생성합니다. 이는 크레이트 내에서 정확히 한 번만 나타나야 합니다.
types:requires:는 각각 단독으로는 선택 사항이지만, funcs:는 항상 존재해야 합니다 — 타입만 있는 확장에는 funcs: []를 작성하세요. 순수 함수 확장은 types:를 생략합니다. funcs: []가 있고 타입이 없는 extension! 블록은 유효하지만 아무 작업도 하지 않는 확장을 생성합니다. requires:는 확장이 사용하는 Rust에서의 미리보기 기능static 기능 객체에 대한 참조로 선언합니다. 이는 funcs: 섹션 뒤에 마지막으로 와야 합니다 — 확장이 함수를 등록하지 않는다면 funcs: []를 포함하세요.

func! 매크로

func!는 SQL 호출 가능한 함수를 선언합니다. 여섯 가지 형태가 있습니다 — 문장별 상태가 없는 네 가지(매개변수 없음, buffer_size만, deterministic만, 둘 다)와 prerun 함수를 통해 문장별 상태를 붙이는 두 가지입니다:
buffer_size 매개변수는 villagesql 크레이트 0.0.2 이상을 요구합니다. 현재 crates.io 릴리스 (0.0.1)는 이를 노출하지 않습니다 — 0.0.2가 출시되기 전까지는 buffer_size 없는 형태를 사용하세요.
타입 상수 (func!에서 사용):

문장별 상태

일부 함수는 단일 문장의 모든 행에 걸치는 상태를 필요로 합니다 — 호출 카운터, 누산기 같은 것입니다. 상태 타입은 state:로, 설정 함수는 prerun:으로 선언합니다. prerun 함수는 첫 번째 행 이전에 한 번 실행되고, 그다음 행 함수가 그 상태에 대한 &mut 접근 권한을 가지고 행마다 한 번씩 실행됩니다. prerun 함수의 서명은 fn(PrerunArgs, PrerunResult<T>)이며, 이 함수가 공급하는 행 함수는 상태를 먼저 받습니다: fn(state: &mut T, args: &[InValue]) -> VdfReturn. Tstate:가 지정한 타입이며, 컴파일러는 prerun 함수와 행 함수가 그 타입에 대해 일치하는지 확인합니다. PrerunArgs::len()은 각 행이 받게 될 인수의 개수이며, PrerunArgs::is_empty()는 함수가 인수 없이 호출되었을 때 참입니다. 상태를 직접 해제해서는 안 됩니다: func!가 문장이 끝날 때 상태를 드롭하는 postrun을 생성합니다. 이는 postrun에서 delete_state<T>()를 호출해야 하는 C++ SDK와는 반대입니다 — 문장별 상태를 참조하세요.
stateprerun 매개변수는 아직 게시된 릴리스에 포함되어 있지 않습니다. 현재 crates.io 릴리스 (0.0.1)는 이를 노출하지 않습니다.
문장 내에서 자신의 호출 인덱스를 반환하는 함수를 가진 완전한 확장입니다:
Rust로 확장 만들기에 설명된 대로 빌드하고 설치한 다음:
테이블에 세 개의 행이 있으므로 call_index()는 세 번 실행되어 1, 그다음 2, 그다음 3을 반환합니다 — 행마다 하나의 값입니다. SUM은 이 세 값을 더하여 6을 만듭니다. 두 번째 SELECT는 첫 번째보다 큰 값이 아니라 동일한 합계를 반환합니다: 카운터는 하나의 문장에 대해 할당되고 그 문장이 끝나면 삭제됩니다.

agg_func! 매크로

agg_func!는 집계 SQL 함수를 선언합니다 — 행마다 한 번씩이 아니라 각 그룹의 행 전체에 대해 호출되는 SUM/COUNT 스타일의 함수입니다. 두 가지 형태가 있습니다:
agg_func!는 아직 게시된 릴리스에 포함되어 있지 않습니다. 현재 crates.io 릴리스 (0.0.1)는 이를 노출하지 않습니다.
누산기는 문장마다 한 번 할당되고 문장이 끝나면 드롭됩니다 — agg_func!가 누산기를 생성하는 prerun과 드롭하는 postrun을 모두 생성하므로, 둘 중 어느 것도 직접 작성하지 않습니다. 그룹별 동작을 만들어 주는 것이 clear_fn입니다: GROUP BY에서는 같은 누산기가 그룹 사이에서 재사용되므로, 그룹 간에 누출되어서는 안 되는 필드는 반드시 여기에서 재설정해야 합니다. SDK 리포지토리의 vsql_agg_sum 예제인, 완전한 SUM 대응 집계입니다:
accumulateInValue::Int만 매치하는 것이 NULL을 건너뛰게 하며, 이는 내장 SUM과 동일한 동작입니다. seen 플래그는 전부 NULL인 그룹과 빈 그룹이 0이 아니라 NULL을 반환하게 만듭니다:

varargs_func! 매크로

varargs_func!는 임의 개수의, 임의 타입의 인수를 받는 VDF를 선언합니다. 매개변수 목록은 [..]로 씁니다 — 이는 필수 리터럴이며, 인수가 없는 func!에 쓰는 []와는 다릅니다.
서버는 가변 인자 VDF에 대해 인수 개수 검증도 인수 타입 검증도 수행하지 않습니다. 호출을 대조할 선언된 매개변수 목록이 없으므로, 인수가 0개인 호출과 전혀 예상하지 못한 타입을 포함해 SQL 텍스트가 전달한 모든 것이 그대로 함수에 도달합니다. 검증은 전적으로 prerun 훅의 몫입니다. 또한 가변 인자 등록은 VEF 프로토콜 3을 필요로 합니다 — 이전 서버는 설치 시 확장을 거부합니다. 이는 C++ SDK와 동일하며, C++에서도 프레임워크가 가변 인자 VDF의 인자 개수 또는 타입을 검증할 수 없습니다.
여섯 가지 형태 — 세 가지 모양이 있고, 각각 축약형과 buffer_sizedeterministic을 (단독이 아니라) 함께 추가하는 전체형이 있습니다:
기본(bare) 형태는 검증이 없고 인수가 0개인 호출도 받아들입니다 — 모든 입력에 대해 정의되는 함수라면 정당한 선택이지만, 이는 전달될 수 있는 모든 입력을 행 함수 혼자 책임진다는 뜻입니다. 문장별 상태를 할당하고 드롭하는 것은 state: 형태뿐입니다. prerun 전용 형태는 PrerunResult<()>를 사용하고 아무것도 저장하지 않으므로 그에 대한 postrun도 없습니다 — 그런 prerun은 PrerunResulterrorrequest_buffer_size에만 사용하며, set_state는 절대 호출하지 않습니다.

prerun에서의 인수 타입 검사

서버가 아무것도 검증하지 않으므로, 가변 인자 prerun은 첫 번째 행이 실행되기 전에 인수 타입을 볼 수 있어야 합니다. PrerunArgs::type_at이 그 시야를 제공하며, len()/is_empty()문장별 상태에서 설명한 PrerunResult 메서드와 함께 사용합니다. 정확히 하나의 사용자 정의 타입만 받아들이려면 is_custom()custom_name()과 짝지으세요: is_custom()만으로는 서버의 모든 사용자 정의 타입을 받아들입니다.
varargs_func!PrerunArgs::type_at은 아직 게시된 릴리스에 포함되어 있지 않습니다. 현재 crates.io 릴리스(0.0.1)는 이를 노출하지 않습니다.
SDK 리포지토리의 vsql_varargs 예제는 형태마다 함수를 하나씩 선언합니다. prerun에서 검증하고 문장별 호출 카운터를 유지하는, 상태 있는 가변 인자 함수입니다:
prerun이 모든 인수가 문자열임을 증명했는데도 str_join은 여전히 행 함수에서 InValue를 매치합니다: prerun이 보는 것은 값이 아니라 선언된 타입이며, STRING 컬럼은 어느 행에서든 NULL을 담을 수 있습니다.
이 예제는 describe(인수가 0개이거나 스칼라가 아닌 인수를 거부한 다음, 이질적인 인수 목록을 형식화하는 prerun 전용 함수)와 point_path(is_custom()custom_name()으로 검증)도 선언합니다. Rust SDK 리포지토리examples/vsql_varargs/src/lib.rs를 참조하세요.

custom_type! 매크로

custom_type!은 새로운 열 타입을 등록합니다. type_name, persisted_length, max_decode_buffer_length, encode, decode, compare는 필수이며, hashdefault는 선택적이지만 권장됩니다.
default 필드는 열 기본값이 아닙니다 — 시작 확인입니다. 서버는 확장 프로그램을 로드할 때 encode(default)를 호출하여 콜백이 작동하는지 확인합니다. encode가 기본값에 대해 Err를 반환하면 확장 프로그램이 로드되지 않습니다.

custom! 매크로

villagesql::custom!("type_name")func! 선언에서 사용자 정의 타입을 이름으로 참조합니다:
villagesql::Type::*이 매개변수 목록이나 반환 타입 위치에 나타나는 곳이라면 어디서든 사용할 수 있습니다. 문자열은 해당 custom_type!에서 선언된 type_name과 일치해야 합니다.

manifest.json 필드

모든 확장 프로그램은 Cargo.toml과 함께 manifest.json이 필요합니다:
name 검증 규칙: 첫 글자는 알파벳, 마지막 글자는 알파벳 또는 숫자여야 하며, 최대 64자입니다. 유효하지 않은 매니페스트는 INSTALL EXTENSION을 실패시킵니다.