From aaeec4d4f3a830a147f5db9c63f6ee7f587738ba Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Thu, 7 Aug 2025 23:49:07 +0530 Subject: [PATCH] Implement PRAGMA query_only logic --- core/pragma.rs | 4 ++ core/translate/pragma.rs | 40 ++++++++++++++++++- vendored/sqlite3-parser/src/parser/ast/mod.rs | 2 + 3 files changed, 45 insertions(+), 1 deletion(-) diff --git a/core/pragma.rs b/core/pragma.rs index b8d42a49f..ff00ed5c3 100644 --- a/core/pragma.rs +++ b/core/pragma.rs @@ -91,6 +91,10 @@ pub fn pragma_for(pragma: &PragmaName) -> Pragma { PragmaFlags::NeedSchema | PragmaFlags::Result0 | PragmaFlags::SchemaReq, &["mode", "table"], ), + QueryOnly => Pragma::new( + PragmaFlags::Result0 | PragmaFlags::NoColumns1, + &["query_only"], + ), } } diff --git a/core/translate/pragma.rs b/core/translate/pragma.rs index 748436ddc..ebbb96359 100644 --- a/core/translate/pragma.rs +++ b/core/translate/pragma.rs @@ -4,7 +4,7 @@ use chrono::Datelike; use std::rc::Rc; use std::sync::Arc; -use turso_sqlite3_parser::ast::{self, ColumnDefinition, Expr}; +use turso_sqlite3_parser::ast::{self, ColumnDefinition, Expr, Literal, Name}; use turso_sqlite3_parser::ast::{PragmaName, QualifiedName}; use crate::pragma::pragma_for; @@ -262,6 +262,14 @@ fn update_pragma( Ok((program, TransactionMode::Write)) } PragmaName::DatabaseList => unreachable!("database_list cannot be set"), + PragmaName::QueryOnly => query_pragma( + PragmaName::QueryOnly, + schema, + Some(value), + pager, + connection, + program, + ), } } @@ -482,6 +490,36 @@ fn query_pragma( program.add_pragma_result_column(pragma.columns[1].to_string()); Ok((program, TransactionMode::Read)) } + PragmaName::QueryOnly => { + if let Some(value_expr) = value { + let is_query_only = match value_expr { + ast::Expr::Literal(Literal::Numeric(i)) => i.parse::().unwrap() != 0, + ast::Expr::Literal(Literal::String(ref s)) => { + let s = s.to_lowercase(); + s == "1" || s == "on" || s == "true" + } + ast::Expr::Name(Name::Ident(s)) => { + let s = s.to_lowercase(); + s == "1" || s == "on" || s == "true" + } + _ => { + return Err(LimboError::ParseError(format!( + "Invalid value for PRAGMA query_only: {value_expr:?}" + ))); + } + }; + connection.set_query_only(is_query_only); + return Ok((program, TransactionMode::None)); + }; + + let register = program.alloc_register(); + let is_query_only = connection.get_query_only(); + program.emit_int(is_query_only as i64, register); + program.emit_result_row(register, 1); + program.add_pragma_result_column(pragma.to_string()); + + Ok((program, TransactionMode::None)) + } } } diff --git a/vendored/sqlite3-parser/src/parser/ast/mod.rs b/vendored/sqlite3-parser/src/parser/ast/mod.rs index 605840f31..1b5286a6e 100644 --- a/vendored/sqlite3-parser/src/parser/ast/mod.rs +++ b/vendored/sqlite3-parser/src/parser/ast/mod.rs @@ -1824,6 +1824,8 @@ pub enum PragmaName { UserVersion, /// trigger a checkpoint to run on database(s) if WAL is enabled WalCheckpoint, + /// make connection query only + QueryOnly, } /// `CREATE TRIGGER` time