mirror of
https://github.com/tursodatabase/limbo.git
synced 2025-08-04 18:18:03 +00:00
refactor+fix: precompute default values from schema
This commit is contained in:
parent
7638b0dab7
commit
15e0cab8d8
13 changed files with 123 additions and 172 deletions
|
@ -10,6 +10,7 @@ use tracing::{instrument, Level};
|
|||
|
||||
use crate::{
|
||||
fast_lock::SpinLock,
|
||||
numeric::Numeric,
|
||||
parameters::Parameters,
|
||||
schema::{BTreeTable, Index, PseudoTable, Table},
|
||||
storage::sqlite3_ondisk::DatabaseHeader,
|
||||
|
@ -18,7 +19,8 @@ use crate::{
|
|||
emitter::TransactionMode,
|
||||
plan::{ResultSetColumn, TableReferences},
|
||||
},
|
||||
Connection, VirtualTable,
|
||||
types::Text,
|
||||
Connection, Value, VirtualTable,
|
||||
};
|
||||
pub struct TableRefIdCounter {
|
||||
next_free: TableInternalId,
|
||||
|
@ -791,6 +793,58 @@ impl ProgramBuilder {
|
|||
self.preassign_label_to_next_insn(loop_end);
|
||||
}
|
||||
|
||||
pub fn emit_column(&mut self, cursor_id: CursorID, column: usize, out: usize) {
|
||||
let (_, cursor_type) = self.cursor_ref.get(cursor_id).unwrap();
|
||||
|
||||
use crate::translate::expr::sanitize_string;
|
||||
|
||||
let default = 'value: {
|
||||
let default = match cursor_type {
|
||||
CursorType::BTreeTable(btree) => &btree.columns[column].default,
|
||||
CursorType::BTreeIndex(index) => &index.columns[column].default,
|
||||
_ => break 'value None,
|
||||
};
|
||||
|
||||
let Some(default) = default else {
|
||||
break 'value None;
|
||||
};
|
||||
|
||||
let ast::Expr::Literal(ref literal) = default else {
|
||||
panic!("column added by ALTER TABLE should be constant")
|
||||
};
|
||||
|
||||
Some(match literal {
|
||||
ast::Literal::Numeric(s) => match Numeric::from(s) {
|
||||
Numeric::Null => Value::Null,
|
||||
Numeric::Integer(v) => Value::Integer(v),
|
||||
Numeric::Float(v) => Value::Float(v.into()),
|
||||
},
|
||||
ast::Literal::Null => Value::Null,
|
||||
ast::Literal::String(s) => Value::Text(Text::from_str(sanitize_string(s))),
|
||||
ast::Literal::Blob(s) => Value::Blob(
|
||||
// Taken from `translate_expr`
|
||||
s.as_bytes()
|
||||
.chunks_exact(2)
|
||||
.map(|pair| {
|
||||
// We assume that sqlite3-parser has already validated that
|
||||
// the input is valid hex string, thus unwrap is safe.
|
||||
let hex_byte = std::str::from_utf8(pair).unwrap();
|
||||
u8::from_str_radix(hex_byte, 16).unwrap()
|
||||
})
|
||||
.collect(),
|
||||
),
|
||||
_ => break 'value None,
|
||||
})
|
||||
};
|
||||
|
||||
self.emit_insn(Insn::Column {
|
||||
cursor_id,
|
||||
column,
|
||||
dest: out,
|
||||
default,
|
||||
});
|
||||
}
|
||||
|
||||
pub fn build(
|
||||
mut self,
|
||||
database_header: Arc<SpinLock<DatabaseHeader>>,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue