Skip to content

Commit

Permalink
table renaming
Browse files Browse the repository at this point in the history
  • Loading branch information
dgllghr committed Feb 9, 2024
1 parent 5a6eb08 commit 18cbe54
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 9 deletions.
44 changes: 36 additions & 8 deletions src/Table.zig
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ table_static_arena: ArenaAllocator,

ctx: VtabCtx,

schema_manager: SchemaManager,
table_data: TableData,
blob_manager: BlobManager,
row_group_index: RowGroupIndex,
Expand Down Expand Up @@ -99,14 +100,18 @@ pub fn create(
const name = try self.table_static_arena.allocator().dupe(u8, args[2]);
self.ctx.base = VtabCtxSchemaless.init(conn, name);

var schema_mgr = SchemaManager.init(&self.ctx.base);
defer schema_mgr.deinit();
schema_mgr.table().create(cb_ctx.arena) catch |e| {
self.schema_manager = SchemaManager.init(&self.ctx.base);
errdefer self.schema_manager.deinit();
self.schema_manager.table().create(cb_ctx.arena) catch |e| {
cb_ctx.setErrorMessage("error creating columns table: {any}", .{e});
return e;
};

self.ctx.schema = schema_mgr.create(&self.table_static_arena, cb_ctx.arena, &def) catch |e| {
self.ctx.schema = self.schema_manager.create(
&self.table_static_arena,
cb_ctx.arena,
&def,
) catch |e| {
cb_ctx.setErrorMessage("error creating schema: {any}", .{e});
return e;
};
Expand Down Expand Up @@ -216,14 +221,14 @@ pub fn connect(
const name = try self.table_static_arena.allocator().dupe(u8, args[2]);
self.ctx.base = VtabCtxSchemaless.init(conn, name);

var schema_mgr = SchemaManager.init(&self.ctx.base);
defer schema_mgr.deinit();
schema_mgr.table().verifyExists(cb_ctx.arena) catch |e| {
self.schema_manager = SchemaManager.init(&self.ctx.base);
errdefer self.schema_manager.deinit();
self.schema_manager.table().verifyExists(cb_ctx.arena) catch |e| {
cb_ctx.setErrorMessage("columns shadow table does not exist: {any}", .{e});
return e;
};

self.ctx.schema = schema_mgr.load(&self.table_static_arena, cb_ctx.arena) catch |e| {
self.ctx.schema = self.schema_manager.load(&self.table_static_arena, cb_ctx.arena) catch |e| {
cb_ctx.setErrorMessage("error loading schema: {any}", .{e});
return e;
};
Expand Down Expand Up @@ -284,11 +289,13 @@ pub fn connect(
}

pub fn disconnect(self: *Self) void {
std.log.debug("disconnecting from table {s}", .{self.ctx.vtabName()});
self.row_group_creator.deinit();
self.pending_inserts.deinit();
self.row_group_index.deinit();
self.table_data.deinit();
self.blob_manager.deinit();
self.schema_manager.deinit();

self.table_static_arena.deinit();
}
Expand Down Expand Up @@ -318,6 +325,12 @@ pub fn destroy(self: *Self, cb_ctx: *vtab.CallbackContext) void {
.{ self.ctx.vtabName(), e },
);
};
self.schema_manager.table().drop(cb_ctx.arena) catch |e| {
std.log.err(
"failed to drop shadow table {s}_columns: {any}",
.{ self.ctx.vtabName(), e },
);
};

self.disconnect();
}
Expand All @@ -330,6 +343,21 @@ pub fn ddl(self: *Self, allocator: Allocator) ![:0]const u8 {
);
}

pub fn rename(self: *Self, cb_ctx: *vtab.CallbackContext, new_name: [:0]const u8) !void {
std.log.debug("renaming to {s}", .{new_name});
// TODO savepoint

try self.table_data.table().rename(cb_ctx.arena, new_name);
try self.pending_inserts.table().rename(cb_ctx.arena, new_name);
try self.row_group_index.table().rename(cb_ctx.arena, new_name);
try self.blob_manager.table().rename(cb_ctx.arena, new_name);
try self.schema_manager.table().rename(cb_ctx.arena, new_name);

// After a rename succeeds, the virtual table is disconnected, which means that other places
// that the name is stored (like in `ctx` or `blob_manager`) do not need to be updated.
return;
}

pub fn update(
self: *Self,
cb_ctx: *vtab.CallbackContext,
Expand Down
11 changes: 11 additions & 0 deletions src/shadow_table.zig
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,17 @@ pub fn ShadowTable(comptime VTabCtx: type, comptime ShadowTableDef: type) type {
return true;
}

/// `ctx` must have the existing name
pub fn rename(self: Self, tmp_arena: *ArenaAllocator, new_name: []const u8) !void {
const ddl = try fmt.allocPrintZ(
tmp_arena.allocator(),
\\ALTER TABLE "{s}_{s}" RENAME TO "{s}_{s}"
,
.{ self.ctx.vtabName(), ShadowTableDef.suffix, new_name, ShadowTableDef.suffix },
);
try self.ctx.conn().exec(ddl);
}

pub fn drop(self: Self, tmp_arena: *ArenaAllocator) !void {
const ddl = try fmt.allocPrintZ(
tmp_arena.allocator(),
Expand Down
21 changes: 20 additions & 1 deletion src/sqlite3/vtab.zig
Original file line number Diff line number Diff line change
Expand Up @@ -472,6 +472,25 @@ pub fn VirtualTable(comptime Table: type) type {
}
};

const Renamable = struct {
fn xRename(vtab: [*c]c.sqlite3_vtab, new_name: [*c]const u8) callconv(.C) c_int {
const state = @fieldParentPtr(State, "vtab", vtab);
var cb_ctx = state.cbCtx() catch {
std.log.err("error allocating arena for callback context. out of memory", .{});
return c.SQLITE_ERROR;
};
defer state.reclaimCbCtx(&cb_ctx);

const new_name_checked: [:0]const u8 = std.mem.span(new_name);
state.table.rename(&cb_ctx, new_name_checked) catch |e| {
std.log.err("error calling rename on table: {any}", .{e});
return c.SQLITE_ERROR;
};

return c.SQLITE_OK;
}
};

const HasShadowTables = struct {
fn xShadowName(name: [*c]const u8) callconv(.C) c_int {
const n: [:0]const u8 = std.mem.span(name);
Expand Down Expand Up @@ -502,7 +521,7 @@ pub fn VirtualTable(comptime Table: type) type {
.xCommit = if (tableHasDecl("commit")) Transactable.xCommit else null,
.xRollback = if (tableHasDecl("rollback")) Transactable.xRollback else null,
.xFindFunction = null,
.xRename = null,
.xRename = if (tableHasDecl("rename")) Renamable.xRename else null,
.xSavepoint = if (tableHasDecl("savepoint")) Transactable.xSavepoint else null,
.xRelease = if (tableHasDecl("release")) Transactable.xRelease else null,
.xRollbackTo = if (tableHasDecl("rollbackTo")) Transactable.xRollbackTo else null,
Expand Down

0 comments on commit 18cbe54

Please sign in to comment.