From a79fe458db526cbbf282fae8e74fe6c6663f7965 Mon Sep 17 00:00:00 2001 From: Krishna Vishal Date: Sat, 12 Jul 2025 20:49:19 +0530 Subject: [PATCH] Fix merge conflicts and adapt schema.rs to use `RecordCursor` --- core/schema.rs | 86 ++++++++++++++++++++++++++++++++------------ core/vdbe/execute.rs | 11 +++--- 2 files changed, 70 insertions(+), 27 deletions(-) diff --git a/core/schema.rs b/core/schema.rs index 47eb0f2cc..33e992773 100644 --- a/core/schema.rs +++ b/core/schema.rs @@ -5,7 +5,7 @@ use crate::translate::plan::SelectPlan; use crate::types::CursorResult; use crate::util::{module_args_from_sql, module_name_from_sql, UnparsedFromSqlIndex}; use crate::{util::normalize_ident, Result}; -use crate::{LimboError, MvCursor, Pager, SymbolTable, VirtualTable}; +use crate::{LimboError, MvCursor, Pager, RefValue, SymbolTable, VirtualTable}; use core::fmt; use fallible_iterator::FallibleIterator; use std::cell::RefCell; @@ -148,7 +148,7 @@ impl Schema { pager: Rc, syms: &SymbolTable, ) -> Result<()> { - let mut cursor = BTreeCursor::new_table(mv_cursor, pager.clone(), 1); + let mut cursor = BTreeCursor::new_table(mv_cursor, pager.clone(), 1, 10); let mut from_sql_indexes = Vec::with_capacity(10); let mut automatic_indices: HashMap> = @@ -178,16 +178,32 @@ impl Schema { break; }; - let ty = row.get::<&str>(0)?; - match ty { + let mut record_cursor = cursor.record_cursor.borrow_mut(); + let ty_value = record_cursor.get_value(&row, 0)?; + let RefValue::Text(ty) = ty_value else { + return Err(LimboError::ConversionError("Expected text value".into())); + }; + match ty.as_str() { "table" => { - let root_page = row.get::(3)?; - let sql = row.get::<&str>(4)?; + let root_page_value = record_cursor.get_value(&row, 3)?; + let RefValue::Integer(root_page) = root_page_value else { + return Err(LimboError::ConversionError("Expected integer value".into())); + }; + let sql_value = record_cursor.get_value(&row, 4)?; + let RefValue::Text(sql_text) = sql_value else { + return Err(LimboError::ConversionError("Expected text value".into())); + }; + let sql = sql_text.as_str(); let create_virtual = "create virtual"; if root_page == 0 && sql[0..create_virtual.len()].eq_ignore_ascii_case(create_virtual) { - let name: &str = row.get::<&str>(1)?; + let name_value = record_cursor.get_value(&row, 1)?; + let RefValue::Text(name_text) = name_value else { + return Err(LimboError::ConversionError("Expected text value".into())); + }; + let name = name_text.as_str(); + // a virtual table is found in the sqlite_schema, but it's no // longer in the in-memory schema. We need to recreate it if // the module is loaded in the symbol table. @@ -210,36 +226,60 @@ impl Schema { self.add_btree_table(Rc::new(table)); } "index" => { - let root_page = row.get::(3)?; - match row.get::<&str>(4) { - Ok(sql) => { + let root_page_value = record_cursor.get_value(&row, 3)?; + let RefValue::Integer(root_page) = root_page_value else { + return Err(LimboError::ConversionError("Expected integer value".into())); + }; + match record_cursor.get_value(&row, 4) { + Ok(RefValue::Text(sql_text)) => { + let table_name_value = record_cursor.get_value(&row, 2)?; + let RefValue::Text(table_name_text) = table_name_value else { + return Err(LimboError::ConversionError( + "Expected text value".into(), + )); + }; + from_sql_indexes.push(UnparsedFromSqlIndex { - table_name: row.get::<&str>(2)?.to_string(), + table_name: table_name_text.as_str().to_string(), root_page: root_page as usize, - sql: sql.to_string(), + sql: sql_text.as_str().to_string(), }); } _ => { - // Automatic index on primary key and/or unique constraint, e.g. - // table|foo|foo|2|CREATE TABLE foo (a text PRIMARY KEY, b) - // index|sqlite_autoindex_foo_1|foo|3| - let index_name = row.get::<&str>(1)?.to_string(); - let table_name = row.get::<&str>(2)?.to_string(); - let root_page = row.get::(3)?; - match automatic_indices.entry(table_name) { + let index_name_value = record_cursor.get_value(&row, 1)?; + let RefValue::Text(index_name_text) = index_name_value else { + return Err(LimboError::ConversionError( + "Expected text value".into(), + )); + }; + + let table_name_value = record_cursor.get_value(&row, 2)?; + let RefValue::Text(table_name_text) = table_name_value else { + return Err(LimboError::ConversionError( + "Expected text value".into(), + )); + }; + + match automatic_indices.entry(table_name_text.as_str().to_string()) { Entry::Vacant(e) => { - e.insert(vec![(index_name, root_page as usize)]); + e.insert(vec![( + index_name_text.as_str().to_string(), + root_page as usize, + )]); } Entry::Occupied(mut e) => { - e.get_mut().push((index_name, root_page as usize)); + e.get_mut().push(( + index_name_text.as_str().to_string(), + root_page as usize, + )); } - }; + } } } } _ => {} }; - + drop(record_cursor); drop(row); if matches!(cursor.next()?, CursorResult::IO) { diff --git a/core/vdbe/execute.rs b/core/vdbe/execute.rs index 1abcfde24..75c6d6651 100644 --- a/core/vdbe/execute.rs +++ b/core/vdbe/execute.rs @@ -9,7 +9,9 @@ use crate::storage::sqlite3_ondisk::read_varint; use crate::storage::wal::DummyWAL; use crate::storage::{self, header_accessor}; use crate::translate::collate::CollationSeq; -use crate::types::{compare_records_generic, ImmutableRecord, Text, TextSubtype}; +use crate::types::{ + compare_immutable, compare_records_generic, ImmutableRecord, Text, TextSubtype, +}; use crate::util::normalize_ident; use crate::vdbe::registers_to_ref_values; use crate::{ @@ -4730,9 +4732,10 @@ pub fn op_idx_insert( // Cursor is pointing at a record; if the index has a rowid, exclude it from the comparison since it's a pointer to the table row; // UNIQUE indexes disallow duplicates like (a=1,b=2,rowid=1) and (a=1,b=2,rowid=2). let existing_key = if cursor.has_rowid() { - &record.get_values()[..record.count().saturating_sub(1)] + let count = cursor.record_cursor.borrow_mut().count(record); + record.get_values()[..count.saturating_sub(1)].to_vec() } else { - record.get_values() + record.get_values().to_vec() }; let inserted_key_vals = &record_to_insert.get_values(); if existing_key.len() != inserted_key_vals.len() { @@ -4740,7 +4743,7 @@ pub fn op_idx_insert( } let conflict = compare_immutable( - existing_key, + existing_key.as_slice(), inserted_key_vals, cursor.key_sort_order(), &cursor.collations,