mirror of
https://github.com/aljazceru/turso.git
synced 2025-12-30 06:24:21 +01:00
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:
@@ -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(())
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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).
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user