Merge 'Pragma list' from Glauber Costa

Closes #841
This commit is contained in:
Pekka Enberg
2025-01-31 18:32:21 +02:00
6 changed files with 71 additions and 17 deletions

View File

@@ -138,7 +138,7 @@ The current status of Limbo is:
| PRAGMA page_count | No | |
| PRAGMA page_size | No | |
| PRAGMA parser_trace | No | |
| PRAGMA pragma_list | No | |
| PRAGMA pragma_list | Yes | |
| PRAGMA query_only | No | |
| PRAGMA quick_check | No | |
| PRAGMA read_uncommitted | No | |

25
Cargo.lock generated
View File

@@ -1588,6 +1588,7 @@ dependencies = [
"serde",
"sieve-cache",
"sqlite3-parser",
"strum",
"tempfile",
"thiserror 1.0.69",
]
@@ -2704,6 +2705,8 @@ dependencies = [
"phf",
"phf_codegen",
"phf_shared",
"strum",
"strum_macros",
"uncased",
]
@@ -2731,6 +2734,28 @@ version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
[[package]]
name = "strum"
version = "0.26.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06"
dependencies = [
"strum_macros",
]
[[package]]
name = "strum_macros"
version = "0.26.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be"
dependencies = [
"heck",
"proc-macro2",
"quote",
"rustversion",
"syn 2.0.96",
]
[[package]]
name = "supports-color"
version = "3.0.2"

View File

@@ -66,6 +66,7 @@ limbo_vector = { path = "../extensions/vector", optional = true, features = ["st
limbo_regexp = { path = "../extensions/regexp", optional = true, features = ["static"] }
limbo_percentile = { path = "../extensions/percentile", optional = true, features = ["static"] }
miette = "7.4.0"
strum = "0.26"
[build-dependencies]
chrono = "0.4.38"

View File

@@ -29,6 +29,7 @@ use crate::storage::wal::CheckpointMode;
use crate::translate::delete::translate_delete;
use crate::util::{normalize_ident, PRIMARY_KEY_AUTOMATIC_INDEX_NAME_PREFIX};
use crate::vdbe::builder::CursorType;
use crate::vdbe::BranchOffset;
use crate::vdbe::{builder::ProgramBuilder, insn::Insn, Program};
use crate::{bail_parse_error, Connection, LimboError, Result, SymbolTable};
use insert::translate_insert;
@@ -38,6 +39,7 @@ use std::cell::RefCell;
use std::fmt::Display;
use std::rc::{Rc, Weak};
use std::str::FromStr;
use strum::IntoEnumIterator;
/// Translate SQL statement into bytecode program.
pub fn translate(
@@ -531,6 +533,36 @@ enum PrimaryKeyDefinitionType<'a> {
Composite,
}
fn list_pragmas(
program: &mut ProgramBuilder,
init_label: BranchOffset,
start_offset: BranchOffset,
) {
let mut pragma_strings: Vec<String> = PragmaName::iter().map(|x| x.to_string()).collect();
pragma_strings.sort();
let register = program.alloc_register();
for pragma in &pragma_strings {
program.emit_insn(Insn::String8 {
value: pragma.to_string(),
dest: register,
});
program.emit_insn(Insn::ResultRow {
start_reg: register,
count: 1,
});
}
program.emit_insn(Insn::Halt {
err_code: 0,
description: String::new(),
});
program.resolve_label(init_label, program.offset());
program.emit_constant_insns();
program.emit_insn(Insn::Goto {
target_pc: start_offset,
});
}
fn translate_pragma(
program: &mut ProgramBuilder,
schema: &Schema,
@@ -546,9 +578,14 @@ fn translate_pragma(
let start_offset = program.offset();
let mut write = false;
if name.name.0.to_lowercase() == "pragma_list" {
list_pragmas(program, init_label, start_offset);
return Ok(());
}
let pragma = match PragmaName::from_str(&name.name.0) {
Ok(pragma) => pragma,
Err(()) => bail_parse_error!("Not a valid pragma name"),
Err(_) => bail_parse_error!("Not a valid pragma name"),
};
match body {

View File

@@ -32,6 +32,8 @@ bitflags = "2.0"
uncased = "0.9.10"
indexmap = "2.0"
miette = "7.4.0"
strum = { version = "0.26", features = ["derive"] }
strum_macros = "0.26"
[dev-dependencies]
env_logger = { version = "0.11", default-features = false }

View File

@@ -7,6 +7,8 @@ use std::num::ParseIntError;
use std::ops::Deref;
use std::str::{self, Bytes, FromStr};
use strum_macros::{EnumIter, EnumString};
use fmt::{ToTokens, TokenStream};
use indexmap::{IndexMap, IndexSet};
@@ -1585,7 +1587,8 @@ pub type PragmaValue = Expr; // TODO
/// `PRAGMA` value
// https://sqlite.org/pragma.html
#[derive(Clone, Debug, PartialEq, Eq)]
#[derive(Clone, Debug, PartialEq, Eq, EnumIter, EnumString, strum::Display)]
#[strum(serialize_all = "snake_case")]
pub enum PragmaName {
/// `cache_size` pragma
CacheSize,
@@ -1597,20 +1600,6 @@ pub enum PragmaName {
TableInfo,
}
impl FromStr for PragmaName {
type Err = ();
fn from_str(input: &str) -> Result<Self, Self::Err> {
match input {
"cache_size" => Ok(PragmaName::CacheSize),
"wal_checkpoint" => Ok(PragmaName::WalCheckpoint),
"journal_mode" => Ok(PragmaName::JournalMode),
"table_info" => Ok(PragmaName::TableInfo),
_ => Err(()),
}
}
}
/// `CREATE TRIGGER` time
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum TriggerTime {