Merge 'Implement pragma wal_checkpoint(<MODE>)' from Pedro Muniz

Only supported mode is PASSIVE

Reviewed-by: Jussi Saurio <jussi.saurio@gmail.com>

Closes #1765
This commit is contained in:
Pekka Enberg
2025-06-17 18:29:05 +03:00
2 changed files with 24 additions and 27 deletions

View File

@@ -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,

View File

@@ -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