Carray() 테이블-값 함수
Carray() 테이블-값 함수
Carray()는 단일 컬럼(value)을 가진 테이블-값 함수랍니다. SQL 쿼리에 C언어 배열을 바인딩할 수 있는 편리한 메커니즘을 제공해요. C언어 배열을 SQL 쿼리에 직접 연결해서 쓰고 싶을 때 아주 유용하죠.
출처: 문서
본문
Carray()는 이름이 value인 컬럼 하나와 0개 이상의 행을 가진 테이블-값 함수예요. carray()의 각 행에 들어가는 value는 애플리케이션이 파라미터 바인딩을 통해 제공하는 C언어 배열에서 가져옵니다. 이렇게 해서 C언어 배열을 SQL 쿼리에 편리하게 바인딩할 수 있어요.
2. 사용 가능 여부
SQLite 3.51.0 (2025-11-04) 버전부터 carray() 확장은 amalgamation에 내장되어 있어요. 다만 기본적으로 비활성화되어 있고, -DSQLITE_ENABLE_CARRAY로 컴파일하지 않으면 동작하지 않아요. 3.51.0 이전에는 carray()가 별도 소스 파일에 있어서 독립적으로 컴파일한 뒤 로더블 확장으로 SQLite에 추가해야 했어요.
carray() 함수는 SQLite 3.14 (2016-08-08) 버전에서 처음 추가되었고, sqlite3_carray_bind() 인터페이스와 carray()의 단일-인자 변형은 3.34.0 (2020-12-01) 버전에 추가되었어요. BLOB로 해석되는 struct iovec 객체 배열을 바인딩하는 기능은 3.41.0 (2023-02-21) 버전에 추가되었죠.
3. 상세 사항
carray() 함수는 인자를 1개, 2개, 또는 3개 받아요. 1-인자 변형을 사용하는 걸 권장해요.
3.1. 단일-인자 CARRAY
carray()의 단일-인자 형태는 값을 붙이기 위해 sqlite3_carray_bind()라는 특별한 C언어 인터페이스가 필요해요:
int sqlite3_carray_bind(
sqlite3_stmt *pStmt, /* Statement containing the CARRAY */
int idx, /* Parameter number for CARRAY argument */
void *aData, /* Data array */
int nData, /* Number of entries in the array */
int mFlags, /* Datatype flag */
void (*xDestroy)(void*) /* Destructor for aData */
);
sqlite3_carray_bind()의 mFlags 파라미터는 다음 중 하나여야 해요:
#define SQLITE_CARRAY_INT32 0
#define SQLITE_CARRAY_INT64 1
#define SQLITE_CARRAY_DOUBLE 2
#define SQLITE_CARRAY_TEXT 3
#define SQLITE_CARRAY_BLOB 4
SQLITE_CARRAY_INT32 형은 배열이 int 배열임을 의미해요. SQLITE_CARRAY_INT64는 sqlite3_int64 배열, SQLITE_CARRAY_DOUBLE은 double 배열을 뜻하죠. SQLITE_CARRAY_TEXT는 각 요소가 NULL 포인터 또는 0으로 끝나는 문자열 포인터인 char* 배열을 의미해요.
SQLITE_CARRAY_BLOB 인자는 배열이 struct iovec 객체 배열임을 뜻해요. struct iovec 형은 표준 Posix 데이터 구조로, 보통 #include <sys/uio.h>로 선언해요. 형식은 다음과 같아요:
struct iovec {
void *iov_base; /* Starting address */
size_t iov_len; /* Number of bytes to transfer */
};
mFlags 파라미터의 하위 비트들은 지금은 모두 0이어야 하지만, 향후 개선에서 사용될 수 있어요.
sqlite3_carray_bind() 루틴의 xDestroy 인자는 입력 배열을 해제하는 함수 포인터예요. SQLite는 데이터 사용이 끝난 뒤 이 함수를 호출해요. xDestroy 인자는 "sqlite3.h"에 정의된 다음 상수 중 하나일 수도 있어요:
-
SQLITE_STATIC→ sqlite3_carray_bind()를 호출한 애플리케이션이 데이터 배열의 소유권을 갖는다는 뜻이에요. 애플리케이션은 prepared statement가 finalize될 때까지 데이터를 변경하거나 해제하지 않겠다고 SQLite에 약속해요. -
SQLITE_TRANSIENT→ 이 특수 값은 sqlite3_carray_bind() 인터페이스가 반환되기 전에 데이터의 개인 복사본을 만들라고 SQLite에 지시해요.
3.2. 다중-인자 CARRAY
원래 carray() 설계는 인자를 2개 또는 3개 받았어요. 이 방법은 하위 호환성을 위해 여전히 지원되지만, 새 애플리케이션은 위에서 설명한 단일-인자 carray() 설계를 사용하는 걸 권장해요.
2-인자 및 3-인자 버전의 carray()에서 첫 번째 인자는 배열에 대한 포인터예요. 포인터 값은 SQL에서 직접 지정할 수 없으므로, 첫 번째 인자는 sqlite3_bind_pointer() 인터페이스를 사용해 "carray" 포인터-형식으로 바인딩된 파라미터여야 해요. 두 번째 인자는 배열의 요소 수예요. 선택적인 세 번째 인자는 C언어 배열 요소의 데이터타입을 정하는 문자열이에요. 세 번째 인자에 허용되는 값은 다음과 같아요:
'int32''int64''double''char*''struct iovec'
기본 데이터타입은 'int32'예요. carray() 함수에 인자가 두 개뿐이면 'int32' 데이터타입으로 간주해요.
4. 사용법
carray() 함수는 쿼리의 FROM 절에서 사용할 수 있어요. 예를 들어, 주소 $PTR의 C언어 배열에서 가져온 rowid로 OBJ 테이블의 두 엔트리를 조회하려면 이렇게 해요:
SELECT obj.* FROM obj, carray($PTR) AS x
WHERE obj.rowid=x.value;
이 쿼리도 같은 결과를 줘요:
SELECT * FROM obj WHERE rowid IN carray($PTR);