Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
107 changes: 106 additions & 1 deletion sqlite-vec.c
Original file line number Diff line number Diff line change
Expand Up @@ -8915,6 +8915,111 @@ static int vec0Rollback(sqlite3_vtab *pVTab) {
return SQLITE_OK;
}

static int vec0Rename(sqlite3_vtab *pVTab, const char *zName) {
vec0_vtab *p = (vec0_vtab *)pVTab;
sqlite3_stmt *stmt;
int rc;
const char *zSql;

vec0_free_resources(p);

zSql = sqlite3_mprintf("ALTER TABLE " VEC0_SHADOW_CHUNKS_NAME " RENAME TO \"%w_chunks\"",
p->schemaName, p->tableName, zName);
rc = sqlite3_prepare_v2(p->db, zSql, -1, &stmt, 0);
sqlite3_free((void *)zSql);
if ((rc != SQLITE_OK) || (sqlite3_step(stmt) != SQLITE_DONE)) {
rc = SQLITE_ERROR;
vtab_set_error(pVTab, "could not rename chunks shadow table");
goto done;
}
sqlite3_finalize(stmt);

zSql = sqlite3_mprintf("ALTER TABLE " VEC0_SHADOW_INFO_NAME " RENAME TO \"%w_info\"", p->schemaName,
p->tableName, zName);
rc = sqlite3_prepare_v2(p->db, zSql, -1, &stmt, 0);
sqlite3_free((void *)zSql);
if ((rc != SQLITE_OK) || (sqlite3_step(stmt) != SQLITE_DONE)) {
rc = SQLITE_ERROR;
vtab_set_error(pVTab, "could not rename info shadow table");
goto done;
}
sqlite3_finalize(stmt);

zSql = sqlite3_mprintf("ALTER TABLE " VEC0_SHADOW_ROWIDS_NAME " RENAME TO \"%w_rowids\"", p->schemaName,
p->tableName, zName);
rc = sqlite3_prepare_v2(p->db, zSql, -1, &stmt, 0);
sqlite3_free((void *)zSql);
if ((rc != SQLITE_OK) || (sqlite3_step(stmt) != SQLITE_DONE)) {
rc = SQLITE_ERROR;
vtab_set_error(pVTab, "could not rename rowids shadow table");
goto done;
}
sqlite3_finalize(stmt);

for (int i = 0; i < p->numVectorColumns; i++) {
char *newShadowVectorChunksName = sqlite3_mprintf("%s_vector_chunks%02d", zName, i);
if (!newShadowVectorChunksName) {
return SQLITE_NOMEM;
}
zSql = sqlite3_mprintf("ALTER TABLE \"%w\".\"%w\" RENAME TO \"%w\"", p->schemaName,
p->shadowVectorChunksNames[i], newShadowVectorChunksName);
rc = sqlite3_prepare_v2(p->db, zSql, -1, &stmt, 0);
sqlite3_free((void *)zSql);
if ((rc != SQLITE_OK) || (sqlite3_step(stmt) != SQLITE_DONE)) {
rc = SQLITE_ERROR;
vtab_set_error(pVTab, "could not rename vector_chunks shadow table");
goto done;
}
sqlite3_finalize(stmt);
}

if(p->numAuxiliaryColumns > 0) {
zSql = sqlite3_mprintf("ALTER TABLE " VEC0_SHADOW_AUXILIARY_NAME " RENAME TO \"%w_auxiliary\"",
p->schemaName, p->tableName, zName);
rc = sqlite3_prepare_v2(p->db, zSql, -1, &stmt, 0);
sqlite3_free((void *)zSql);
if ((rc != SQLITE_OK) || (sqlite3_step(stmt) != SQLITE_DONE)) {
rc = SQLITE_ERROR;
vtab_set_error(pVTab, "could not rename auxiliary shadow table");
goto done;
}
sqlite3_finalize(stmt);
}

for (int i = 0; i < p->numMetadataColumns; i++) {
zSql = sqlite3_mprintf("ALTER TABLE " VEC0_SHADOW_METADATA_N_NAME " RENAME TO \"%w_metadatachunks%02d\"",
p->schemaName, p->tableName, i, zName, i);
rc = sqlite3_prepare_v2(p->db, zSql, -1, &stmt, 0);
sqlite3_free((void *)zSql);
if ((rc != SQLITE_OK) || (sqlite3_step(stmt) != SQLITE_DONE)) {
rc = SQLITE_ERROR;
vtab_set_error(pVTab, "could not rename metadatachunks shadow table");
goto done;
}
sqlite3_finalize(stmt);

if(p->metadata_columns[i].kind == VEC0_METADATA_COLUMN_KIND_TEXT) {
zSql = sqlite3_mprintf("ALTER TABLE " VEC0_SHADOW_METADATA_TEXT_DATA_NAME " RENAME TO \"%w_metadatatext%02d\"",
p->schemaName, p->tableName, i, zName, i);
rc = sqlite3_prepare_v2(p->db, zSql, -1, &stmt, 0);
sqlite3_free((void *)zSql);
if ((rc != SQLITE_OK) || (sqlite3_step(stmt) != SQLITE_DONE)) {
rc = SQLITE_ERROR;
vtab_set_error(pVTab, "could not rename metadatatext shadow table");
goto done;
}
sqlite3_finalize(stmt);
}
}

stmt = NULL;
rc = SQLITE_OK;

done:
sqlite3_finalize(stmt);
return rc;
}

static sqlite3_module vec0Module = {
/* iVersion */ 3,
/* xCreate */ vec0Create,
Expand All @@ -8935,7 +9040,7 @@ static sqlite3_module vec0Module = {
/* xCommit */ vec0Commit,
/* xRollback */ vec0Rollback,
/* xFindFunction */ 0,
/* xRename */ 0, // https://github.com/asg017/sqlite-vec/issues/43
/* xRename */ vec0Rename,
/* xSavepoint */ 0,
/* xRelease */ 0,
/* xRollbackTo */ 0,
Expand Down
86 changes: 86 additions & 0 deletions tests/__snapshots__/test-auxiliary.ambr
Original file line number Diff line number Diff line change
Expand Up @@ -392,6 +392,92 @@
]),
})
# ---
# name: test_renames
OrderedDict({
'sql': 'select rowid, * from v',
'rows': list([
OrderedDict({
'rowid': 1,
'vector': b'\x00\x00\x80?',
'name': 'alex',
}),
OrderedDict({
'rowid': 2,
'vector': b'\x00\x00\x00@',
'name': 'brian',
}),
OrderedDict({
'rowid': 3,
'vector': b'\x00\x00@@',
'name': 'craig',
}),
]),
})
# ---
# name: test_renames.1
dict({
'v_auxiliary': OrderedDict({
'sql': 'select * from v_auxiliary',
'rows': list([
OrderedDict({
'rowid': 1,
'value00': 'alex',
}),
OrderedDict({
'rowid': 2,
'value00': 'brian',
}),
OrderedDict({
'rowid': 3,
'value00': 'craig',
}),
]),
}),
'v_chunks': OrderedDict({
'sql': 'select * from v_chunks',
'rows': list([
OrderedDict({
'chunk_id': 1,
'size': 8,
'validity': b'\x07',
'rowids': b'\x01\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
}),
]),
}),
'v_rowids': OrderedDict({
'sql': 'select * from v_rowids',
'rows': list([
OrderedDict({
'rowid': 1,
'id': None,
'chunk_id': 1,
'chunk_offset': 0,
}),
OrderedDict({
'rowid': 2,
'id': None,
'chunk_id': 1,
'chunk_offset': 1,
}),
OrderedDict({
'rowid': 3,
'id': None,
'chunk_id': 1,
'chunk_offset': 2,
}),
]),
}),
'v_vector_chunks00': OrderedDict({
'sql': 'select * from v_vector_chunks00',
'rows': list([
OrderedDict({
'rowid': 1,
'vectors': b'\x00\x00\x80?\x00\x00\x00@\x00\x00@@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
}),
]),
}),
})
# ---
# name: test_types
OrderedDict({
'sql': 'select * from v',
Expand Down
144 changes: 144 additions & 0 deletions tests/__snapshots__/test-metadata.ambr
Original file line number Diff line number Diff line change
Expand Up @@ -1925,6 +1925,150 @@
]),
})
# ---
# name: test_renames
OrderedDict({
'sql': 'insert into v(rowid, vector, b, n, f, t) values (?, ?, ?, ?, ?, ?)',
'rows': list([
]),
})
# ---
# name: test_renames.1
OrderedDict({
'sql': 'insert into v(rowid, vector, b, n, f, t) values (?, ?, ?, ?, ?, ?)',
'rows': list([
]),
})
# ---
# name: test_renames.2
OrderedDict({
'sql': 'insert into v(rowid, vector, b, n, f, t) values (?, ?, ?, ?, ?, ?)',
'rows': list([
]),
})
# ---
# name: test_renames.3
OrderedDict({
'sql': 'select * from v',
'rows': list([
OrderedDict({
'rowid': 1,
'vector': b'\x11\x11\x11\x11',
'b': 1,
'n': 1,
'f': 1.1,
't': 'test1',
}),
OrderedDict({
'rowid': 2,
'vector': b'""""',
'b': 1,
'n': 2,
'f': 2.2,
't': 'test2',
}),
OrderedDict({
'rowid': 3,
'vector': b'3333',
'b': 1,
'n': 3,
'f': 3.3,
't': '1234567890123',
}),
]),
})
# ---
# name: test_renames.4
dict({
'v_chunks': OrderedDict({
'sql': 'select * from v_chunks',
'rows': list([
OrderedDict({
'chunk_id': 1,
'size': 8,
'validity': b'\x07',
'rowids': b'\x01\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
}),
]),
}),
'v_metadatachunks00': OrderedDict({
'sql': 'select * from v_metadatachunks00',
'rows': list([
OrderedDict({
'rowid': 1,
'data': b'\x07',
}),
]),
}),
'v_metadatachunks01': OrderedDict({
'sql': 'select * from v_metadatachunks01',
'rows': list([
OrderedDict({
'rowid': 1,
'data': b'\x01\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
}),
]),
}),
'v_metadatachunks02': OrderedDict({
'sql': 'select * from v_metadatachunks02',
'rows': list([
OrderedDict({
'rowid': 1,
'data': b'\x9a\x99\x99\x99\x99\x99\xf1?\x9a\x99\x99\x99\x99\x99\x01@ffffff\n@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
}),
]),
}),
'v_metadatachunks03': OrderedDict({
'sql': 'select * from v_metadatachunks03',
'rows': list([
OrderedDict({
'rowid': 1,
'data': b'\x05\x00\x00\x00test1\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00test2\x00\x00\x00\x00\x00\x00\x00\r\x00\x00\x00123456789012\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
}),
]),
}),
'v_metadatatext03': OrderedDict({
'sql': 'select * from v_metadatatext03',
'rows': list([
OrderedDict({
'rowid': 3,
'data': '1234567890123',
}),
]),
}),
'v_rowids': OrderedDict({
'sql': 'select * from v_rowids',
'rows': list([
OrderedDict({
'rowid': 1,
'id': None,
'chunk_id': 1,
'chunk_offset': 0,
}),
OrderedDict({
'rowid': 2,
'id': None,
'chunk_id': 1,
'chunk_offset': 1,
}),
OrderedDict({
'rowid': 3,
'id': None,
'chunk_id': 1,
'chunk_offset': 2,
}),
]),
}),
'v_vector_chunks00': OrderedDict({
'sql': 'select * from v_vector_chunks00',
'rows': list([
OrderedDict({
'rowid': 1,
'vectors': b'\x11\x11\x11\x11""""3333\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
}),
]),
}),
})
# ---
# name: test_stress
dict({
'vec_movies_auxiliary': OrderedDict({
Expand Down
18 changes: 18 additions & 0 deletions tests/test-auxiliary.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,24 @@ def test_deletes(db, snapshot):
assert vec0_shadow_table_contents(db, "v") == snapshot()


def test_renames(db, snapshot):
db.execute(
"create virtual table v using vec0(vector float[1], +name text, chunk_size=8)"
)
db.executemany(
"insert into v(vector, name) values (?, ?)",
[("[1]", "alex"), ("[2]", "brian"), ("[3]", "craig")],
)
assert exec(db, "select rowid, * from v") == snapshot()
assert vec0_shadow_table_contents(db, "v") == snapshot()

res = exec(db, "select rowid, * from v")
db.execute(
"alter table v rename to v1"
)
assert exec(db, "select rowid, * from v1")["rows"] == res["rows"]


def test_knn(db, snapshot):
db.execute("create virtual table v using vec0(vector float[1], +name text)")
db.executemany(
Expand Down
Loading