translate: updated the command to more closely match SQLite semantics

the command for drop table translation has been updated so that it more closely matches the semantics of SQLite's drop table command.

there are a few more things missing like ephemeral tables, destroy etc.
This commit is contained in:
Zaid Humayun
2025-02-06 22:56:06 +05:30
parent 76e2d98381
commit b8bebf3fa3
4 changed files with 36 additions and 27 deletions

View File

@@ -651,20 +651,17 @@ fn translate_drop_table(
}
bail_parse_error!("No such table: {}", tbl_name.name.0.as_str());
}
let table = table.unwrap(); // safe to do since we have a check before this
let init_label = program.emit_init();
let start_offset = program.offset();
// 1. Drop the table BTree
program.emit_insn(Insn::DropBtree {
db: 0,
root: table.root_page,
});
let null_reg = program.alloc_register(); // r1
program.emit_null(null_reg);
let tbl_name_reg = program.alloc_register(); // r2
let table_reg = program.emit_string8_new_reg(tbl_name.name.0.clone()); // r3
let table_type = program.emit_string8_new_reg("trigger".to_string()); // r4
let row_id_reg = program.alloc_register(); // r5
// TODO: Drop indexes?
// 2. Delete table metadata from sqlite_schema
let table_name = "sqlite_schema";
let table = schema.get_table(&table_name).unwrap();
let sqlite_schema_cursor_id = program.alloc_cursor_id(
@@ -677,7 +674,7 @@ fn translate_drop_table(
});
program.emit_insn(Insn::OpenWriteAwait {});
// Rewind to the very beginning of the cursor
// loop to beginning of schema table
program.emit_insn(Insn::RewindAsync {
cursor_id: sqlite_schema_cursor_id,
});
@@ -686,26 +683,37 @@ fn translate_drop_table(
cursor_id: sqlite_schema_cursor_id,
pc_if_empty: end_metadata_label,
});
// start loop on schema table
let metadata_loop = program.allocate_label();
program.resolve_label(metadata_loop, program.offset());
// Load row details
let tbl_name_reg = program.alloc_register();
program.emit_insn(Insn::Column {
cursor_id: sqlite_schema_cursor_id,
column: 2,
dest: tbl_name_reg,
});
let string_reg = program.emit_string8_new_reg(tbl_name.name.0.clone());
let next_label = program.allocate_label();
program.emit_insn(Insn::Ne {
lhs: tbl_name_reg,
rhs: string_reg,
rhs: table_reg,
target_pc: next_label,
flags: CmpInsFlags::default(),
});
// Delete matching row
program.emit_insn(Insn::Column {
cursor_id: sqlite_schema_cursor_id,
column: 0,
dest: tbl_name_reg,
});
program.emit_insn(Insn::Eq {
lhs: tbl_name_reg,
rhs: table_type,
target_pc: next_label,
flags: CmpInsFlags::default(),
});
program.emit_insn(Insn::RowId {
cursor_id: sqlite_schema_cursor_id,
dest: row_id_reg,
});
program.emit_insn(Insn::DeleteAsync {
cursor_id: sqlite_schema_cursor_id,
});
@@ -713,7 +721,6 @@ fn translate_drop_table(
cursor_id: sqlite_schema_cursor_id,
});
// Move to next row
program.resolve_label(next_label, program.offset());
program.emit_insn(Insn::NextAsync {
cursor_id: sqlite_schema_cursor_id,
@@ -723,17 +730,19 @@ fn translate_drop_table(
pc_if_next: metadata_loop,
});
program.resolve_label(end_metadata_label, program.offset());
// end of loop on schema table
// Update schema
let parse_schema_where_clause = format!("tbl_name = {}", tbl_name.name.0);
program.emit_insn(Insn::ParseSchema {
// 2. Drop the table structure
program.emit_insn(Insn::DropTable {
db: 0,
where_clause: parse_schema_where_clause,
root: table.root_page,
});
// end of the program
program.emit_halt();
program.resolve_label(init_label, program.offset());
program.emit_transaction(true);
program.emit_goto(start_offset);
Ok(())

View File

@@ -1101,8 +1101,8 @@ pub fn insn_to_str(
0,
format!("r[{}]=root iDb={} flags={}", root, db, flags),
),
Insn::DropBtree { db, root } => (
"DropBtree",
Insn::DropTable { db, root } => (
"DropTable",
*db as i32,
*root as i32,
0,

View File

@@ -590,8 +590,8 @@ pub enum Insn {
flags: usize,
},
// Drop a b-tree
DropBtree {
// Drop a table
DropTable {
// The database within which this b-tree needs to be dropped (P1).
db: usize,
// The root page of this b-tree (P2).

View File

@@ -2688,7 +2688,7 @@ impl Program {
state.registers[*root] = OwnedValue::Integer(root_page as i64);
state.pc += 1;
}
Insn::DropBtree { db, root } => {
Insn::DropTable { db, root } => {
if *db > 0 {
todo!("temp databases not implemented yet");
}