mirror of
https://github.com/tursodatabase/limbo.git
synced 2025-08-04 18:18:03 +00:00
Add read implementation of user_version pragma with ReadCookie opcode
This commit is contained in:
parent
098da0794f
commit
98e9d33478
9 changed files with 73 additions and 6 deletions
|
@ -160,7 +160,7 @@ The current status of Limbo is:
|
||||||
| PRAGMA temp_store_directory | Not Needed | deprecated in SQLite |
|
| PRAGMA temp_store_directory | Not Needed | deprecated in SQLite |
|
||||||
| PRAGMA threads | No | |
|
| PRAGMA threads | No | |
|
||||||
| PRAGMA trusted_schema | No | |
|
| PRAGMA trusted_schema | No | |
|
||||||
| PRAGMA user_version | No | |
|
| PRAGMA user_version | Partial | Only read implemented |
|
||||||
| PRAGMA vdbe_addoptrace | No | |
|
| PRAGMA vdbe_addoptrace | No | |
|
||||||
| PRAGMA vdbe_debug | No | |
|
| PRAGMA vdbe_debug | No | |
|
||||||
| PRAGMA vdbe_listing | No | |
|
| PRAGMA vdbe_listing | No | |
|
||||||
|
@ -514,7 +514,7 @@ Modifiers:
|
||||||
| PrevAsync | Yes | |
|
| PrevAsync | Yes | |
|
||||||
| PrevAwait | Yes | |
|
| PrevAwait | Yes | |
|
||||||
| Program | No | |
|
| Program | No | |
|
||||||
| ReadCookie | No | |
|
| ReadCookie | Partial| no temp databases, only user_version supported |
|
||||||
| Real | Yes | |
|
| Real | Yes | |
|
||||||
| RealAffinity | Yes | |
|
| RealAffinity | Yes | |
|
||||||
| Remainder | Yes | |
|
| Remainder | Yes | |
|
||||||
|
|
|
@ -128,7 +128,7 @@ pub struct DatabaseHeader {
|
||||||
text_encoding: u32,
|
text_encoding: u32,
|
||||||
|
|
||||||
/// The "user version" as read and set by the user_version pragma.
|
/// The "user version" as read and set by the user_version pragma.
|
||||||
user_version: u32,
|
pub user_version: u32,
|
||||||
|
|
||||||
/// True (non-zero) for incremental-vacuum mode. False (zero) otherwise.
|
/// True (non-zero) for incremental-vacuum mode. False (zero) otherwise.
|
||||||
incremental_vacuum_enabled: u32,
|
incremental_vacuum_enabled: u32,
|
||||||
|
@ -232,7 +232,7 @@ impl Default for DatabaseHeader {
|
||||||
default_page_cache_size: 500, // pages
|
default_page_cache_size: 500, // pages
|
||||||
vacuum_mode_largest_root_page: 0,
|
vacuum_mode_largest_root_page: 0,
|
||||||
text_encoding: 1, // utf-8
|
text_encoding: 1, // utf-8
|
||||||
user_version: 1,
|
user_version: 0,
|
||||||
incremental_vacuum_enabled: 0,
|
incremental_vacuum_enabled: 0,
|
||||||
application_id: 0,
|
application_id: 0,
|
||||||
reserved_for_expansion: [0; 20],
|
reserved_for_expansion: [0; 20],
|
||||||
|
|
|
@ -11,7 +11,7 @@ use crate::storage::sqlite3_ondisk::{DatabaseHeader, MIN_PAGE_CACHE_SIZE};
|
||||||
use crate::storage::wal::CheckpointMode;
|
use crate::storage::wal::CheckpointMode;
|
||||||
use crate::util::normalize_ident;
|
use crate::util::normalize_ident;
|
||||||
use crate::vdbe::builder::{ProgramBuilder, ProgramBuilderOpts, QueryMode};
|
use crate::vdbe::builder::{ProgramBuilder, ProgramBuilderOpts, QueryMode};
|
||||||
use crate::vdbe::insn::Insn;
|
use crate::vdbe::insn::{Cookie, Insn};
|
||||||
use crate::vdbe::BranchOffset;
|
use crate::vdbe::BranchOffset;
|
||||||
use crate::{bail_parse_error, Pager};
|
use crate::{bail_parse_error, Pager};
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
@ -148,6 +148,10 @@ fn update_pragma(
|
||||||
query_pragma(PragmaName::PageCount, schema, None, header, program)?;
|
query_pragma(PragmaName::PageCount, schema, None, header, program)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
PragmaName::UserVersion => {
|
||||||
|
// TODO: Implement updating user_version
|
||||||
|
todo!("updating user_version not yet implemented")
|
||||||
|
}
|
||||||
PragmaName::TableInfo => {
|
PragmaName::TableInfo => {
|
||||||
// because we need control over the write parameter for the transaction,
|
// because we need control over the write parameter for the transaction,
|
||||||
// this should be unreachable. We have to force-call query_pragma before
|
// this should be unreachable. We have to force-call query_pragma before
|
||||||
|
@ -241,6 +245,15 @@ fn query_pragma(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
PragmaName::UserVersion => {
|
||||||
|
program.emit_transaction(false);
|
||||||
|
program.emit_insn(Insn::ReadCookie {
|
||||||
|
db: 0,
|
||||||
|
dest: register,
|
||||||
|
cookie: Cookie::UserVersion,
|
||||||
|
});
|
||||||
|
program.emit_result_row(register, 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
@ -1232,6 +1232,15 @@ pub fn insn_to_str(
|
||||||
0,
|
0,
|
||||||
"".to_string(),
|
"".to_string(),
|
||||||
),
|
),
|
||||||
|
Insn::ReadCookie { db, dest, cookie } => (
|
||||||
|
"ReadCookie",
|
||||||
|
*db as i32,
|
||||||
|
*dest as i32,
|
||||||
|
*cookie as i32,
|
||||||
|
OwnedValue::build_text(Rc::new("".to_string())),
|
||||||
|
0,
|
||||||
|
"".to_string(),
|
||||||
|
),
|
||||||
};
|
};
|
||||||
format!(
|
format!(
|
||||||
"{:<4} {:<17} {:<4} {:<4} {:<4} {:<13} {:<2} {}",
|
"{:<4} {:<17} {:<4} {:<4} {:<4} {:<13} {:<2} {}",
|
||||||
|
|
|
@ -639,6 +639,29 @@ pub enum Insn {
|
||||||
db: usize,
|
db: usize,
|
||||||
dest: usize,
|
dest: usize,
|
||||||
},
|
},
|
||||||
|
/// Read cookie number P3 from database P1 and write it into register P2
|
||||||
|
ReadCookie {
|
||||||
|
db: usize,
|
||||||
|
dest: usize,
|
||||||
|
cookie: Cookie,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Add remaining cookies.
|
||||||
|
#[derive(Description, Debug, Clone, Copy)]
|
||||||
|
pub enum Cookie {
|
||||||
|
/// The schema cookie.
|
||||||
|
SchemaVersion = 1,
|
||||||
|
/// The schema format number. Supported schema formats are 1, 2, 3, and 4.
|
||||||
|
DatabaseFormat = 2,
|
||||||
|
/// Default page cache size.
|
||||||
|
DefaultPageCacheSize = 3,
|
||||||
|
/// The page number of the largest root b-tree page when in auto-vacuum or incremental-vacuum modes, or zero otherwise.
|
||||||
|
LargestRootPageNumber = 4,
|
||||||
|
/// The database text encoding. A value of 1 means UTF-8. A value of 2 means UTF-16le. A value of 3 means UTF-16be.
|
||||||
|
DatabaseTextEncoding = 5,
|
||||||
|
/// The "user version" as read and set by the user_version pragma.
|
||||||
|
UserVersion = 6,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn cast_text_to_numerical(value: &str) -> OwnedValue {
|
fn cast_text_to_numerical(value: &str) -> OwnedValue {
|
||||||
|
|
|
@ -55,7 +55,7 @@ use crate::{resolve_ext_path, Connection, Result, TransactionState, DATABASE_VER
|
||||||
use insn::{
|
use insn::{
|
||||||
exec_add, exec_and, exec_bit_and, exec_bit_not, exec_bit_or, exec_boolean_not, exec_concat,
|
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_divide, exec_multiply, exec_or, exec_remainder, exec_shift_left, exec_shift_right,
|
||||||
exec_subtract,
|
exec_subtract, Cookie,
|
||||||
};
|
};
|
||||||
use likeop::{construct_like_escape_arg, exec_glob, exec_like_with_escape};
|
use likeop::{construct_like_escape_arg, exec_glob, exec_like_with_escape};
|
||||||
use rand::distributions::{Distribution, Uniform};
|
use rand::distributions::{Distribution, Uniform};
|
||||||
|
@ -2662,6 +2662,18 @@ impl Program {
|
||||||
parse_schema_rows(Some(stmt), &mut schema, conn.pager.io.clone())?;
|
parse_schema_rows(Some(stmt), &mut schema, conn.pager.io.clone())?;
|
||||||
state.pc += 1;
|
state.pc += 1;
|
||||||
}
|
}
|
||||||
|
Insn::ReadCookie { db, dest, cookie } => {
|
||||||
|
if *db > 0 {
|
||||||
|
// TODO: implement temp databases
|
||||||
|
todo!("temp databases not implemented yet");
|
||||||
|
}
|
||||||
|
let cookie_value = match cookie {
|
||||||
|
Cookie::UserVersion => pager.db_header.borrow().user_version.into(),
|
||||||
|
cookie => todo!("{cookie:?} is not yet implement for ReadCookie"),
|
||||||
|
};
|
||||||
|
state.registers[*dest] = OwnedValue::Integer(cookie_value);
|
||||||
|
state.pc += 1;
|
||||||
|
}
|
||||||
Insn::ShiftRight { lhs, rhs, dest } => {
|
Insn::ShiftRight { lhs, rhs, dest } => {
|
||||||
state.registers[*dest] =
|
state.registers[*dest] =
|
||||||
exec_shift_right(&state.registers[*lhs], &state.registers[*rhs]);
|
exec_shift_right(&state.registers[*lhs], &state.registers[*rhs]);
|
||||||
|
|
|
@ -41,3 +41,11 @@ do_execsql_test_on_specific_db ":memory:" pragma-page-count-table {
|
||||||
CREATE TABLE foo(bar);
|
CREATE TABLE foo(bar);
|
||||||
PRAGMA page_count
|
PRAGMA page_count
|
||||||
} {2}
|
} {2}
|
||||||
|
|
||||||
|
do_execsql_test_on_specific_db "testing/testing_user_version_10.db" pragma-user-version-user-set {
|
||||||
|
PRAGMA user_version
|
||||||
|
} {10}
|
||||||
|
|
||||||
|
do_execsql_test_on_specific_db ":memory:" pragma-user-version-default {
|
||||||
|
PRAGMA user_version
|
||||||
|
} {0}
|
BIN
testing/testing_user_version_10.db
Normal file
BIN
testing/testing_user_version_10.db
Normal file
Binary file not shown.
|
@ -1598,6 +1598,8 @@ pub enum PragmaName {
|
||||||
PageCount,
|
PageCount,
|
||||||
/// returns information about the columns of a table
|
/// returns information about the columns of a table
|
||||||
TableInfo,
|
TableInfo,
|
||||||
|
/// Returns the user version of the database file.
|
||||||
|
UserVersion,
|
||||||
/// trigger a checkpoint to run on database(s) if WAL is enabled
|
/// trigger a checkpoint to run on database(s) if WAL is enabled
|
||||||
WalCheckpoint,
|
WalCheckpoint,
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue