Skip to content

Commit

Permalink
Merge 'Pagecount' from Glauber Costa
Browse files Browse the repository at this point in the history
This PR implements the Pagecount pragma, as well as its associated
bytecode opcode

Reviewed-by: Pere Diaz Bou <[email protected]>

Closes #819
  • Loading branch information
penberg committed Feb 2, 2025
2 parents 635c45a + a3387cf commit dbb7d1a
Show file tree
Hide file tree
Showing 7 changed files with 52 additions and 2 deletions.
4 changes: 2 additions & 2 deletions COMPAT.md
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ The current status of Limbo is:
| PRAGMA mmap_size | No | |
| PRAGMA module_list | No | |
| PRAGMA optimize | No | |
| PRAGMA page_count | No | |
| PRAGMA page_count | Yes | |
| PRAGMA page_size | No | |
| PRAGMA parser_trace | No | |
| PRAGMA pragma_list | Yes | |
Expand Down Expand Up @@ -504,7 +504,7 @@ Modifiers:
| OpenWriteAsync | Yes | |
| OpenWriteAwait | Yes | |
| Or | Yes | |
| Pagecount | No | |
| Pagecount | Partial| no temp databases |
| Param | No | |
| ParseSchema | No | |
| Permutation | No | |
Expand Down
11 changes: 11 additions & 0 deletions core/translate/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -640,6 +640,10 @@ fn update_pragma(
query_pragma(PragmaName::WalCheckpoint, schema, None, header, program)?;
Ok(())
}
PragmaName::PageCount => {
query_pragma(PragmaName::PageCount, schema, None, header, program)?;
Ok(())
}
PragmaName::TableInfo => {
// because we need control over the write parameter for the transaction,
// this should be unreachable. We have to force-call query_pragma before
Expand Down Expand Up @@ -681,6 +685,13 @@ fn query_pragma(
});
program.emit_result_row(register, 3);
}
PragmaName::PageCount => {
program.emit_insn(Insn::PageCount {
db: 0,
dest: register,
});
program.emit_result_row(register, 1);
}
PragmaName::TableInfo => {
let table = match value {
Some(ast::Expr::Name(name)) => {
Expand Down
9 changes: 9 additions & 0 deletions core/vdbe/explain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1163,6 +1163,15 @@ pub fn insn_to_str(
0,
String::new(),
),
Insn::PageCount { db, dest } => (
"Pagecount",
*db as i32,
*dest as i32,
0,
OwnedValue::build_text(Rc::new("".to_string())),
0,
"".to_string(),
),
};
format!(
"{:<4} {:<17} {:<4} {:<4} {:<4} {:<13} {:<2} {}",
Expand Down
5 changes: 5 additions & 0 deletions core/vdbe/insn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -605,6 +605,11 @@ pub enum Insn {
dest: usize,
},
Noop,
/// Write the current number of pages in database P1 to memory cell P2.
PageCount {
db: usize,
dest: usize,
},
}

fn cast_text_to_numerical(value: &str) -> OwnedValue {
Expand Down
14 changes: 14 additions & 0 deletions core/vdbe/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2406,6 +2406,20 @@ impl Program {
state.pc += 1;
}
}
Insn::PageCount { db, dest } => {
if *db > 0 {
// TODO: implement temp databases
todo!("temp databases not implemented yet");
}
// SQLite returns "0" on an empty database, and 2 on the first insertion,
// so we'll mimick that behavior.
let mut pages = pager.db_header.borrow().database_size.into();
if pages == 1 {
pages = 0;
}
state.registers[*dest] = OwnedValue::Integer(pages);
state.pc += 1;
}
Insn::ParseSchema {
db: _,
where_clause,
Expand Down
9 changes: 9 additions & 0 deletions testing/pragma.test
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,12 @@ do_execsql_test pragma-table-info-call-syntax {
do_execsql_test pragma-table-info-invalid-table {
PRAGMA table_info=pekka
} {}

do_execsql_test_on_specific_db ":memory:" pragma-page-count-empty {
PRAGMA page_count
} {0}

do_execsql_test_on_specific_db ":memory:" pragma-page-count-table {
CREATE TABLE foo(bar);
PRAGMA page_count
} {2}
2 changes: 2 additions & 0 deletions vendored/sqlite3-parser/src/parser/ast/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1594,6 +1594,8 @@ pub enum PragmaName {
CacheSize,
/// `journal_mode` pragma
JournalMode,
/// Return the total number of pages in the database file.
PageCount,
/// returns information about the columns of a table
TableInfo,
/// trigger a checkpoint to run on database(s) if WAL is enabled
Expand Down

0 comments on commit dbb7d1a

Please sign in to comment.