mirror of
https://github.com/aljazceru/turso.git
synced 2026-02-20 23:45:18 +01:00
Fix merge conflicts and adapt schema.rs to use RecordCursor
This commit is contained in:
@@ -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<Pager>,
|
||||
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<String, Vec<(String, usize)>> =
|
||||
@@ -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::<i64>(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::<i64>(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::<i64>(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) {
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user