diff --git a/core/storage/wal.rs b/core/storage/wal.rs index 9f4b63e74..f73838a27 100644 --- a/core/storage/wal.rs +++ b/core/storage/wal.rs @@ -4,6 +4,7 @@ use std::array; use std::cell::UnsafeCell; use std::collections::HashMap; +use strum::EnumString; use tracing::{instrument, Level}; use std::fmt::Formatter; @@ -60,7 +61,8 @@ impl CheckpointResult { } } -#[derive(Debug, Copy, Clone)] +#[derive(Debug, Copy, Clone, EnumString)] +#[strum(ascii_case_insensitive)] pub enum CheckpointMode { /// Checkpoint as many frames as possible without waiting for any database readers or writers to finish, then sync the database file if all frames in the log were checkpointed. Passive, diff --git a/core/translate/pragma.rs b/core/translate/pragma.rs index 8090a3e40..afd929725 100644 --- a/core/translate/pragma.rs +++ b/core/translate/pragma.rs @@ -70,7 +70,7 @@ pub fn translate_pragma( &mut program, )?; } - Some(ast::PragmaBody::Equals(value)) => match pragma { + Some(ast::PragmaBody::Equals(value) | ast::PragmaBody::Call(value)) => match pragma { PragmaName::TableInfo => { query_pragma( pragma, @@ -95,22 +95,6 @@ pub fn translate_pragma( )?; } }, - Some(ast::PragmaBody::Call(value)) => match pragma { - PragmaName::TableInfo => { - query_pragma( - pragma, - schema, - Some(value), - database_header.clone(), - pager, - connection, - &mut program, - )?; - } - _ => { - todo!() - } - }, }; program.epilogue(match write { false => super::emitter::TransactionMode::Read, @@ -156,7 +140,7 @@ fn update_pragma( query_pragma( PragmaName::WalCheckpoint, schema, - None, + Some(value), header, pager, connection, @@ -290,11 +274,26 @@ fn query_pragma( PragmaName::WalCheckpoint => { // Checkpoint uses 3 registers: P1, P2, P3. Ref Insn::Checkpoint for more info. // Allocate two more here as one was allocated at the top. - program.alloc_register(); - program.alloc_register(); + let mode = match value { + Some(ast::Expr::Name(name)) => { + let mode_name = normalize_ident(&name.0); + CheckpointMode::from_str(&mode_name).map_err(|e| { + LimboError::ParseError(format!("Unknown Checkpoint Mode: {}", e)) + })? + } + _ => CheckpointMode::Passive, + }; + + if !matches!(mode, CheckpointMode::Passive) { + return Err(LimboError::ParseError( + "only Passive mode supported".to_string(), + )); + } + + program.alloc_registers(2); program.emit_insn(Insn::Checkpoint { database: 0, - checkpoint_mode: CheckpointMode::Passive, + checkpoint_mode: mode, dest: register, }); program.emit_result_row(register, 3); @@ -317,11 +316,7 @@ fn query_pragma( }; let base_reg = register; - program.alloc_register(); - program.alloc_register(); - program.alloc_register(); - program.alloc_register(); - program.alloc_register(); + program.alloc_registers(5); if let Some(table) = table { for (i, column) in table.columns().iter().enumerate() { // cid