From b8bebf3fa32fddf1ae2aff8cb2274766ea66d01d Mon Sep 17 00:00:00 2001 From: Zaid Humayun Date: Thu, 6 Feb 2025 22:56:06 +0530 Subject: [PATCH] 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. --- core/translate/mod.rs | 53 +++++++++++++++++++++++++------------------ core/vdbe/explain.rs | 4 ++-- core/vdbe/insn.rs | 4 ++-- core/vdbe/mod.rs | 2 +- 4 files changed, 36 insertions(+), 27 deletions(-) diff --git a/core/translate/mod.rs b/core/translate/mod.rs index 19d522813..46b9c26eb 100644 --- a/core/translate/mod.rs +++ b/core/translate/mod.rs @@ -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(()) diff --git a/core/vdbe/explain.rs b/core/vdbe/explain.rs index ac46a5362..be0e4f92a 100644 --- a/core/vdbe/explain.rs +++ b/core/vdbe/explain.rs @@ -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, diff --git a/core/vdbe/insn.rs b/core/vdbe/insn.rs index 0dbde7b8b..897842d4d 100644 --- a/core/vdbe/insn.rs +++ b/core/vdbe/insn.rs @@ -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). diff --git a/core/vdbe/mod.rs b/core/vdbe/mod.rs index 71a7f6531..b28a1faf9 100644 --- a/core/vdbe/mod.rs +++ b/core/vdbe/mod.rs @@ -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"); }