From e020ba3dfe97e49e85652d9f36320a5c347ba576 Mon Sep 17 00:00:00 2001 From: PThorpe92 Date: Sun, 30 Mar 2025 16:16:55 -0400 Subject: [PATCH] Add enum for interpreting a value as a register or literal for insns --- core/translate/index.rs | 8 +++----- core/translate/insert.rs | 7 +++---- core/translate/main_loop.rs | 18 ++++++------------ core/translate/schema.rs | 10 ++++------ core/vdbe/execute.rs | 17 ++++++++++++++--- core/vdbe/explain.rs | 7 +++++-- core/vdbe/insn.rs | 20 +++++++++++++++----- 7 files changed, 50 insertions(+), 37 deletions(-) diff --git a/core/translate/index.rs b/core/translate/index.rs index 6f1a02c3c..c9a474cab 100644 --- a/core/translate/index.rs +++ b/core/translate/index.rs @@ -6,7 +6,7 @@ use crate::{ util::normalize_ident, vdbe::{ builder::{CursorType, ProgramBuilder, QueryMode}, - insn::{IdxInsertFlags, Insn}, + insn::{IdxInsertFlags, Insn, RegisterOrLiteral}, }, OwnedValue, }; @@ -97,8 +97,7 @@ pub fn translate_create_index( // open the sqlite schema table for writing and create a new entry for the index program.emit_insn(Insn::OpenWriteAsync { cursor_id: sqlite_schema_cursor_id, - root_page: sqlite_table.root_page, - is_new_idx: false, + root_page: RegisterOrLiteral::Literal(sqlite_table.root_page), }); program.emit_insn(Insn::OpenWriteAwait {}); let sql = create_idx_stmt_to_sql(&tbl_name, &idx_name, unique_if_not_exists, &columns); @@ -197,8 +196,7 @@ pub fn translate_create_index( // newly sorted index records. program.emit_insn(Insn::OpenWriteAsync { cursor_id: btree_cursor_id, - root_page: root_page_reg, - is_new_idx: true, + root_page: RegisterOrLiteral::Register(root_page_reg), }); program.emit_insn(Insn::OpenWriteAwait {}); diff --git a/core/translate/insert.rs b/core/translate/insert.rs index d6faeb2c8..371d85be1 100644 --- a/core/translate/insert.rs +++ b/core/translate/insert.rs @@ -9,6 +9,7 @@ use crate::error::SQLITE_CONSTRAINT_PRIMARYKEY; use crate::schema::Table; use crate::util::normalize_ident; use crate::vdbe::builder::{ProgramBuilderOpts, QueryMode}; +use crate::vdbe::insn::RegisterOrLiteral; use crate::vdbe::BranchOffset; use crate::{ schema::{Column, Schema}, @@ -152,8 +153,7 @@ pub fn translate_insert( program.emit_insn(Insn::OpenWriteAsync { cursor_id, - root_page, - is_new_idx: false, + root_page: RegisterOrLiteral::Literal(root_page), }); program.emit_insn(Insn::OpenWriteAwait {}); @@ -169,8 +169,7 @@ pub fn translate_insert( // Single row - populate registers directly program.emit_insn(Insn::OpenWriteAsync { cursor_id, - root_page, - is_new_idx: false, + root_page: RegisterOrLiteral::Literal(root_page), }); program.emit_insn(Insn::OpenWriteAwait {}); diff --git a/core/translate/main_loop.rs b/core/translate/main_loop.rs index d9b7d6a36..e7235e8f0 100644 --- a/core/translate/main_loop.rs +++ b/core/translate/main_loop.rs @@ -102,8 +102,7 @@ pub fn init_loop( let root_page = btree.root_page; program.emit_insn(Insn::OpenWriteAsync { cursor_id, - root_page, - is_new_idx: false, + root_page: root_page.into(), }); program.emit_insn(Insn::OpenWriteAwait {}); } @@ -111,8 +110,7 @@ pub fn init_loop( let root_page = btree.root_page; program.emit_insn(Insn::OpenWriteAsync { cursor_id, - root_page, - is_new_idx: false, + root_page: root_page.into(), }); program.emit_insn(Insn::OpenWriteAwait {}); } @@ -146,16 +144,14 @@ pub fn init_loop( OperationMode::DELETE => { program.emit_insn(Insn::OpenWriteAsync { cursor_id: table_cursor_id, - root_page: table.table.get_root_page(), - is_new_idx: false, + root_page: table.table.get_root_page().into(), }); program.emit_insn(Insn::OpenWriteAwait {}); } OperationMode::UPDATE => { program.emit_insn(Insn::OpenWriteAsync { cursor_id: table_cursor_id, - root_page: table.table.get_root_page(), - is_new_idx: false, + root_page: table.table.get_root_page().into(), }); program.emit_insn(Insn::OpenWriteAwait {}); } @@ -181,16 +177,14 @@ pub fn init_loop( OperationMode::DELETE => { program.emit_insn(Insn::OpenWriteAsync { cursor_id: index_cursor_id, - root_page: index.root_page, - is_new_idx: false, + root_page: index.root_page.into(), }); program.emit_insn(Insn::OpenWriteAwait {}); } OperationMode::UPDATE => { program.emit_insn(Insn::OpenWriteAsync { cursor_id: index_cursor_id, - root_page: index.root_page, - is_new_idx: false, + root_page: index.root_page.into(), }); program.emit_insn(Insn::OpenWriteAwait {}); } diff --git a/core/translate/schema.rs b/core/translate/schema.rs index 6f87937c9..eea0868d0 100644 --- a/core/translate/schema.rs +++ b/core/translate/schema.rs @@ -7,6 +7,7 @@ use crate::translate::ProgramBuilderOpts; use crate::translate::QueryMode; use crate::util::PRIMARY_KEY_AUTOMATIC_INDEX_NAME_PREFIX; use crate::vdbe::builder::CursorType; +use crate::vdbe::insn::RegisterOrLiteral; use crate::vdbe::insn::{CmpInsFlags, Insn}; use crate::LimboError; use crate::{bail_parse_error, Result}; @@ -103,8 +104,7 @@ pub fn translate_create_table( ); program.emit_insn(Insn::OpenWriteAsync { cursor_id: sqlite_schema_cursor_id, - root_page: 1, - is_new_idx: false, + root_page: 1usize.into(), }); program.emit_insn(Insn::OpenWriteAwait {}); @@ -501,8 +501,7 @@ pub fn translate_create_virtual_table( ); program.emit_insn(Insn::OpenWriteAsync { cursor_id: sqlite_schema_cursor_id, - root_page: 1, - is_new_idx: false, + root_page: 1usize.into(), }); program.emit_insn(Insn::OpenWriteAwait {}); @@ -581,8 +580,7 @@ pub fn translate_drop_table( ); program.emit_insn(Insn::OpenWriteAsync { cursor_id: sqlite_schema_cursor_id, - root_page: 1, - is_new_idx: false, + root_page: 1usize.into(), }); program.emit_insn(Insn::OpenWriteAwait {}); diff --git a/core/vdbe/execute.rs b/core/vdbe/execute.rs index 89bd26859..968fea4eb 100644 --- a/core/vdbe/execute.rs +++ b/core/vdbe/execute.rs @@ -29,7 +29,7 @@ use crate::{info, MvCursor, RefValue, Row, StepResult, TransactionState}; use super::insn::{ exec_add, exec_and, exec_bit_and, exec_bit_not, exec_bit_or, exec_boolean_not, exec_concat, exec_divide, exec_multiply, exec_or, exec_remainder, exec_shift_left, exec_shift_right, - exec_subtract, Cookie, + exec_subtract, Cookie, RegisterOrLiteral, }; use super::HaltState; use rand::thread_rng; @@ -3979,12 +3979,23 @@ pub fn op_open_write_async( else { unreachable!("unexpected Insn {:?}", insn) }; + let root_page = match root_page { + RegisterOrLiteral::Literal(lit) => *lit as u64, + RegisterOrLiteral::Register(reg) => match &state.registers[*reg].get_owned_value() { + OwnedValue::Integer(val) => *val as u64, + _ => { + return Err(LimboError::InternalError( + "OpenWriteAsync: the value in root_page is not an integer".into(), + )); + } + }, + }; let (_, cursor_type) = program.cursor_ref.get(*cursor_id).unwrap(); let mut cursors = state.cursors.borrow_mut(); let is_index = cursor_type.is_index(); let mv_cursor = match state.mv_tx_id { Some(tx_id) => { - let table_id = *root_page as u64; + let table_id = root_page; let mv_store = mv_store.unwrap().clone(); let mv_cursor = Rc::new(RefCell::new( MvCursor::new(mv_store.clone(), tx_id, table_id).unwrap(), @@ -3993,7 +4004,7 @@ pub fn op_open_write_async( } None => None, }; - let cursor = BTreeCursor::new(mv_cursor, pager.clone(), *root_page); + let cursor = BTreeCursor::new(mv_cursor, pager.clone(), root_page as usize); if is_index { cursors .get_mut(*cursor_id) diff --git a/core/vdbe/explain.rs b/core/vdbe/explain.rs index f80a442f1..66c68d9c0 100644 --- a/core/vdbe/explain.rs +++ b/core/vdbe/explain.rs @@ -1,4 +1,4 @@ -use crate::vdbe::builder::CursorType; +use crate::vdbe::{builder::CursorType, insn::RegisterOrLiteral}; use super::{Insn, InsnReference, OwnedValue, Program}; use crate::function::{Func, ScalarFunc}; @@ -1134,7 +1134,10 @@ pub fn insn_to_str( } => ( "OpenWriteAsync", *cursor_id as i32, - *root_page as i32, + match root_page { + RegisterOrLiteral::Literal(i) => *i as _, + RegisterOrLiteral::Register(i) => *i as _, + }, 0, OwnedValue::build_text(""), 0, diff --git a/core/vdbe/insn.rs b/core/vdbe/insn.rs index 5ce68f14a..4a6bc1ea4 100644 --- a/core/vdbe/insn.rs +++ b/core/vdbe/insn.rs @@ -76,6 +76,18 @@ impl IdxInsertFlags { } } +#[derive(Clone, Copy, Debug)] +pub enum RegisterOrLiteral { + Register(usize), + Literal(T), +} + +impl From for RegisterOrLiteral { + fn from(value: PageIdx) -> Self { + RegisterOrLiteral::Literal(value) + } +} + #[derive(Description, Debug)] pub enum Insn { /// Initialize the program state and jump to the given PC. @@ -640,8 +652,7 @@ pub enum Insn { OpenWriteAsync { cursor_id: CursorID, - root_page: PageIdx, - is_new_idx: bool, + root_page: RegisterOrLiteral, }, OpenWriteAwait {}, @@ -1296,8 +1307,6 @@ impl Insn { Insn::IdxGT { .. } => execute::op_idx_gt, Insn::IdxLE { .. } => execute::op_idx_le, Insn::IdxLT { .. } => execute::op_idx_lt, - Insn::IdxInsertAsync { .. } => execute::op_idx_insert_async, - Insn::IdxInsertAwait { .. } => execute::op_idx_insert_await, Insn::DecrJumpZero { .. } => execute::op_decr_jump_zero, Insn::AggStep { .. } => execute::op_agg_step, @@ -1315,7 +1324,8 @@ impl Insn { Insn::Yield { .. } => execute::op_yield, Insn::InsertAsync { .. } => execute::op_insert_async, Insn::InsertAwait { .. } => execute::op_insert_await, - + Insn::IdxInsertAsync { .. } => execute::op_idx_insert_async, + Insn::IdxInsertAwait { .. } => execute::op_idx_insert_await, Insn::DeleteAsync { .. } => execute::op_delete_async, Insn::DeleteAwait { .. } => execute::op_delete_await,