small docs work

This commit is contained in:
Alex Garcia 2024-10-11 09:09:32 -07:00
parent b6245e21a2
commit cc12e44d4c

View file

@ -3179,6 +3179,8 @@ static sqlite3_module vec_npy_eachModule = {
typedef struct vec0_vtab vec0_vtab; typedef struct vec0_vtab vec0_vtab;
#define VEC0_MAX_VECTOR_COLUMNS 16 #define VEC0_MAX_VECTOR_COLUMNS 16
#define SQLITE_VEC_VEC0_MAX_DIMENSIONS 8192
struct vec0_vtab { struct vec0_vtab {
sqlite3_vtab base; sqlite3_vtab base;
@ -3213,7 +3215,7 @@ struct vec0_vtab {
struct VectorColumnDefinition vector_columns[VEC0_MAX_VECTOR_COLUMNS]; struct VectorColumnDefinition vector_columns[VEC0_MAX_VECTOR_COLUMNS];
// number of defined numVectorColumns columns. // number of defined vector columns.
int numVectorColumns; int numVectorColumns;
int chunk_size; int chunk_size;
@ -3275,6 +3277,11 @@ struct vec0_vtab {
sqlite3_stmt *stmtRowidsGetChunkPosition; sqlite3_stmt *stmtRowidsGetChunkPosition;
}; };
/**
* @brief Finalize all the sqlite3_stmt members in a vec0_vtab.
*
* @param p vec0_vtab pointer
*/
void vec0_free_resources(vec0_vtab *p) { void vec0_free_resources(vec0_vtab *p) {
sqlite3_finalize(p->stmtLatestChunk); sqlite3_finalize(p->stmtLatestChunk);
p->stmtLatestChunk = NULL; p->stmtLatestChunk = NULL;
@ -3287,6 +3294,12 @@ void vec0_free_resources(vec0_vtab *p) {
sqlite3_finalize(p->stmtRowidsGetChunkPosition); sqlite3_finalize(p->stmtRowidsGetChunkPosition);
p->stmtRowidsGetChunkPosition = NULL; p->stmtRowidsGetChunkPosition = NULL;
} }
/**
* @brief Free all memory and sqlite3_stmt members of a vec0_vtab
*
* @param p vec0_vtab pointer
*/
void vec0_free(vec0_vtab *p) { void vec0_free(vec0_vtab *p) {
vec0_free_resources(p); vec0_free_resources(p);
@ -3350,6 +3363,18 @@ int vec0_column_idx_to_vector_idx(vec0_vtab *pVtab, int column_idx) {
return column_idx - VEC0_COLUMN_VECTORN_START; return column_idx - VEC0_COLUMN_VECTORN_START;
} }
/**
* @brief Retrieve the chunk_id, chunk_offset, and possible "id" value
* of a vec0_vtab row with the provided rowid
*
* @param p vec0_vtab
* @param rowid the rowid of the row to query
* @param id output, optional sqlite3_value to provide the id.
* Useful for text PK rows. Must be freed with sqlite3_value_free()
* @param chunk_id output, the chunk_id the row belongs to
* @param chunk_offset output, the offset within the chunk the row belongs to
* @return SQLITE_ROW on success, error code otherwise. SQLITE_EMPTY if row DNE
*/
int vec0_get_chunk_position(vec0_vtab *p, i64 rowid, sqlite3_value **id, int vec0_get_chunk_position(vec0_vtab *p, i64 rowid, sqlite3_value **id,
i64 *chunk_id, i64 *chunk_offset) { i64 *chunk_id, i64 *chunk_offset) {
int rc; int rc;
@ -3375,7 +3400,7 @@ int vec0_get_chunk_position(vec0_vtab *p, i64 rowid, sqlite3_value **id,
sqlite3_bind_int64(p->stmtRowidsGetChunkPosition, 1, rowid); sqlite3_bind_int64(p->stmtRowidsGetChunkPosition, 1, rowid);
rc = sqlite3_step(p->stmtRowidsGetChunkPosition); rc = sqlite3_step(p->stmtRowidsGetChunkPosition);
// special case: when no results, return SQLITE_EMPTY to convene "that chunk // special case: when no results, return SQLITE_EMPTY to convey "that chunk
// position doesnt exist" // position doesnt exist"
if (rc == SQLITE_DONE) { if (rc == SQLITE_DONE) {
rc = SQLITE_EMPTY; rc = SQLITE_EMPTY;
@ -3769,6 +3794,7 @@ int vec0_rowids_update_position(vec0_vtab *p, i64 rowid, i64 chunk_rowid,
sqlite3_bind_int64(p->stmtRowidsUpdatePosition, 1, chunk_rowid); sqlite3_bind_int64(p->stmtRowidsUpdatePosition, 1, chunk_rowid);
sqlite3_bind_int64(p->stmtRowidsUpdatePosition, 2, chunk_offset); sqlite3_bind_int64(p->stmtRowidsUpdatePosition, 2, chunk_offset);
sqlite3_bind_int64(p->stmtRowidsUpdatePosition, 3, rowid); sqlite3_bind_int64(p->stmtRowidsUpdatePosition, 3, rowid);
rc = sqlite3_step(p->stmtRowidsUpdatePosition); rc = sqlite3_step(p->stmtRowidsUpdatePosition);
if (rc != SQLITE_DONE) { if (rc != SQLITE_DONE) {
// IMP: V21925_05995 // IMP: V21925_05995
@ -3890,12 +3916,14 @@ int vec0_new_chunk(vec0_vtab *p, i64 *chunk_rowid) {
typedef enum { typedef enum {
// Full scan, every row is queried. // Full scan, every row is queried.
SQLITE_VEC0_QUERYPLAN_FULLSCAN, SQLITE_VEC0_QUERYPLAN_FULLSCAN,
// A single row is queried by rowid/id // A single row is queried by rowid/id
SQLITE_VEC0_QUERYPLAN_POINT, SQLITE_VEC0_QUERYPLAN_POINT,
// A KNN-style query is made on a specific vector column. // A KNN-style query is made on a specific vector column.
// Requires 1) a MATCH/compatible distance contraint on // Requires
// a single vector column, 2) ORDER BY distance, and 3) // 1) a MATCH/compatible distance contraint on a single vector column
// either a 'LIMIT ?' or 'k=?' contraint // 2) either a 'LIMIT ?' or 'k=?' contraint
SQLITE_VEC0_QUERYPLAN_KNN, SQLITE_VEC0_QUERYPLAN_KNN,
} vec0_query_plan; } vec0_query_plan;
@ -3961,6 +3989,24 @@ struct vec0_cursor {
struct vec0_query_point_data *point_data; struct vec0_query_point_data *point_data;
}; };
void vec0_cursor_clear(vec0_cursor *pCur) {
if (pCur->fullscan_data) {
vec0_query_fullscan_data_clear(pCur->fullscan_data);
sqlite3_free(pCur->fullscan_data);
pCur->fullscan_data = NULL;
}
if (pCur->knn_data) {
vec0_query_knn_data_clear(pCur->knn_data);
sqlite3_free(pCur->knn_data);
pCur->knn_data = NULL;
}
if (pCur->point_data) {
vec0_query_point_data_clear(pCur->point_data);
sqlite3_free(pCur->point_data);
pCur->point_data = NULL;
}
}
#define VEC_CONSTRUCTOR_ERROR "vec0 constructor error: " #define VEC_CONSTRUCTOR_ERROR "vec0 constructor error: "
static int vec0_init(sqlite3 *db, void *pAux, int argc, const char *const *argv, static int vec0_init(sqlite3 *db, void *pAux, int argc, const char *const *argv,
sqlite3_vtab **ppVtab, char **pzErr, bool isCreate) { sqlite3_vtab **ppVtab, char **pzErr, bool isCreate) {
@ -4001,7 +4047,7 @@ static int vec0_init(sqlite3 *db, void *pAux, int argc, const char *const *argv,
VEC0_MAX_VECTOR_COLUMNS); VEC0_MAX_VECTOR_COLUMNS);
goto error; goto error;
} }
#define SQLITE_VEC_VEC0_MAX_DIMENSIONS 8192
if (c.dimensions > SQLITE_VEC_VEC0_MAX_DIMENSIONS) { if (c.dimensions > SQLITE_VEC_VEC0_MAX_DIMENSIONS) {
sqlite3_free(c.name); sqlite3_free(c.name);
*pzErr = sqlite3_mprintf( *pzErr = sqlite3_mprintf(
@ -4258,6 +4304,7 @@ static int vec0Destroy(sqlite3_vtab *pVtab) {
int rc; int rc;
const char *zSql; const char *zSql;
// Free up any sqlite3_stmt, otherwise DROPs on those tables will fail
vec0_free_resources(p); vec0_free_resources(p);
// later: can't evidence-of here, bc always gives "SQL logic error" instead of // later: can't evidence-of here, bc always gives "SQL logic error" instead of
@ -4300,6 +4347,7 @@ static int vec0Destroy(sqlite3_vtab *pVtab) {
done: done:
sqlite3_finalize(stmt); sqlite3_finalize(stmt);
vec0_free(p); vec0_free(p);
// If there was an error
if (rc == SQLITE_OK) { if (rc == SQLITE_OK) {
sqlite3_free(p); sqlite3_free(p);
} }
@ -4317,27 +4365,9 @@ static int vec0Open(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor) {
return SQLITE_OK; return SQLITE_OK;
} }
void vec0CursorClear(vec0_cursor *pCur) {
if (pCur->fullscan_data) {
vec0_query_fullscan_data_clear(pCur->fullscan_data);
sqlite3_free(pCur->fullscan_data);
pCur->fullscan_data = NULL;
}
if (pCur->knn_data) {
vec0_query_knn_data_clear(pCur->knn_data);
sqlite3_free(pCur->knn_data);
pCur->knn_data = NULL;
}
if (pCur->point_data) {
vec0_query_point_data_clear(pCur->point_data);
sqlite3_free(pCur->point_data);
pCur->point_data = NULL;
}
}
static int vec0Close(sqlite3_vtab_cursor *cur) { static int vec0Close(sqlite3_vtab_cursor *cur) {
vec0_cursor *pCur = (vec0_cursor *)cur; vec0_cursor *pCur = (vec0_cursor *)cur;
vec0CursorClear(pCur); vec0_cursor_clear(pCur);
sqlite3_free(pCur); sqlite3_free(pCur);
return SQLITE_OK; return SQLITE_OK;
} }
@ -4368,7 +4398,7 @@ static int vec0BestIndex(sqlite3_vtab *pVTab, sqlite3_index_info *pIdxInfo) {
int iRowidInTerm = -1; int iRowidInTerm = -1;
#ifdef SQLITE_VEC_DEBUG #ifdef SQLITE_VEC_DEBUG
printf("pIdxInfo->nOrderBy=%d\n", pIdxInfo->nOrderBy); printf("pIdxInfo->nOrderBy=%d, pIdxInfo->nConstraint=%d\n", pIdxInfo->nOrderBy, pIdxInfo->nConstraint);
#endif #endif
for (int i = 0; i < pIdxInfo->nConstraint; i++) { for (int i = 0; i < pIdxInfo->nConstraint; i++) {
@ -4454,6 +4484,7 @@ static int vec0BestIndex(sqlite3_vtab *pVTab, sqlite3_index_info *pIdxInfo) {
pIdxInfo->aConstraintUsage[iMatchTerm].argvIndex = 1; pIdxInfo->aConstraintUsage[iMatchTerm].argvIndex = 1;
pIdxInfo->aConstraintUsage[iMatchTerm].omit = 1; pIdxInfo->aConstraintUsage[iMatchTerm].omit = 1;
if (iLimitTerm >= 0) { if (iLimitTerm >= 0) {
pIdxInfo->aConstraintUsage[iLimitTerm].argvIndex = 2; pIdxInfo->aConstraintUsage[iLimitTerm].argvIndex = 2;
pIdxInfo->aConstraintUsage[iLimitTerm].omit = 1; pIdxInfo->aConstraintUsage[iLimitTerm].omit = 1;
@ -5202,7 +5233,7 @@ static int vec0Filter(sqlite3_vtab_cursor *pVtabCursor, int idxNum,
const char *idxStr, int argc, sqlite3_value **argv) { const char *idxStr, int argc, sqlite3_value **argv) {
vec0_vtab *p = (vec0_vtab *)pVtabCursor->pVtab; vec0_vtab *p = (vec0_vtab *)pVtabCursor->pVtab;
vec0_cursor *pCur = (vec0_cursor *)pVtabCursor; vec0_cursor *pCur = (vec0_cursor *)pVtabCursor;
vec0CursorClear(pCur); vec0_cursor_clear(pCur);
if (strcmp(idxStr, VEC0_QUERY_PLAN_FULLSCAN) == 0) { if (strcmp(idxStr, VEC0_QUERY_PLAN_FULLSCAN) == 0) {
return vec0Filter_fullscan(p, pCur); return vec0Filter_fullscan(p, pCur);
} else if (strncmp(idxStr, "knn:", 4) == 0) { } else if (strncmp(idxStr, "knn:", 4) == 0) {