From a7cc367c1ffb82df5a801b235cdc1df6f9c7d64b Mon Sep 17 00:00:00 2001 From: Glauber Costa Date: Thu, 30 Jan 2025 21:05:31 -0500 Subject: [PATCH] implement pragma pragma_list List all available pragmas (Except pragma_list) --- COMPAT.md | 2 +- Cargo.lock | 25 +++++++++++++++++++++++++ core/Cargo.toml | 1 + core/translate/mod.rs | 37 +++++++++++++++++++++++++++++++++++++ 4 files changed, 64 insertions(+), 1 deletion(-) diff --git a/COMPAT.md b/COMPAT.md index fb2da2d79..905de6c77 100644 --- a/COMPAT.md +++ b/COMPAT.md @@ -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 | | diff --git a/Cargo.lock b/Cargo.lock index af303d953..23a263f9c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -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" diff --git a/core/Cargo.toml b/core/Cargo.toml index 347602f57..d2172af34 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -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" diff --git a/core/translate/mod.rs b/core/translate/mod.rs index 04e0e3af2..c0190942b 100644 --- a/core/translate/mod.rs +++ b/core/translate/mod.rs @@ -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 = 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,6 +578,11 @@ 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"),