villagesql 크레이트 API에 대한 참조입니다. 시작하기 가이드는 Rust로 확장 만들기를 참조하세요. 사용자 정의 타입에 대해서는 Rust에서의 사용자 정의 타입을 참조하세요.
InValue
InValue는 서버가 각 함수 인수에 대해 전달하는 열거형입니다. 함수는 args: &[InValue]를 받으며, 값을 사용하기 전에 각 인수를 확인해야 합니다.
항상
Null을 명시적으로 매치해야 합니다. .unwrap()을 호출하거나 값 배리언트만 패턴 매칭하는 것은 버그입니다 — SQL NULL은 오류가 아닌 정상적인 입력입니다.
VdfReturn
VdfReturn은 함수가 서버에 반환하는 것입니다. 연관 함수 중 하나로 구성합니다:
경고 vs 오류:
사용자 입력 검증 실패 시 결과 집합의 나머지 부분을 계속 처리하는 것이 합리적인 경우
warning을 사용하세요. 엄격 모드에서는 MySQL이 INSERT 및 UPDATE에서 경고를 오류로 승격시킵니다. 데이터가 손상되거나 내부 불변 조건 위반과 같은 안전하지 않은 상황에서는 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. T는 state:가 지정한 타입이며, 컴파일러는 prerun 함수와 행 함수가 그 타입에 대해 일치하는지 확인합니다.
PrerunArgs::len()은 각 행이 받게 될 인수의 개수이며, PrerunArgs::is_empty()는 함수가 인수 없이 호출되었을 때 참입니다.
상태를 직접 해제해서는 안 됩니다: func!가 문장이 끝날 때 상태를 드롭하는 postrun을 생성합니다. 이는 postrun에서 delete_state<T>()를 호출해야 하는 C++ SDK와는 반대입니다 — 문장별 상태를 참조하세요.
state 및 prerun 매개변수는 아직 게시된 릴리스에 포함되어 있지
않습니다. 현재 crates.io 릴리스
(0.0.1)는 이를 노출하지 않습니다.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 대응 집계입니다:
accumulate가 InValue::Int만 매치하는 것이 NULL을 건너뛰게 하며, 이는 내장 SUM과 동일한 동작입니다. seen 플래그는 전부 NULL인 그룹과 빈 그룹이 0이 아니라 NULL을 반환하게 만듭니다:
varargs_func! 매크로
varargs_func!는 임의 개수의, 임의 타입의 인수를 받는 VDF를 선언합니다. 매개변수 목록은 [..]로 씁니다 — 이는 필수 리터럴이며, 인수가 없는 func!에 쓰는 []와는 다릅니다.
여섯 가지 형태 — 세 가지 모양이 있고, 각각 축약형과 buffer_size 및 deterministic을 (단독이 아니라) 함께 추가하는 전체형이 있습니다:
기본(bare) 형태는 검증이 없고 인수가 0개인 호출도 받아들입니다 — 모든 입력에 대해 정의되는 함수라면 정당한 선택이지만, 이는 전달될 수 있는 모든 입력을 행 함수 혼자 책임진다는 뜻입니다. 문장별 상태를 할당하고 드롭하는 것은
state: 형태뿐입니다. prerun 전용 형태는 PrerunResult<()>를 사용하고 아무것도 저장하지 않으므로 그에 대한 postrun도 없습니다 — 그런 prerun은 PrerunResult를 error와 request_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)는 이를 노출하지 않습니다.vsql_varargs 예제는 형태마다 함수를 하나씩 선언합니다. 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는 필수이며, hash와 default는 선택적이지만 권장됩니다.
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을 실패시킵니다.
