diff --git a/src/parser/mod.rs b/src/parser/mod.rs index 6af0fb776..c5605e989 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -20167,15 +20167,34 @@ impl<'a> Parser<'a> { } fn parse_pragma_value(&mut self) -> Result { - let v = self.parse_value()?; + let span = self.peek_token_ref().span; + let v = match self.parse_one_of_keywords(&[ + Keyword::TRUE, + Keyword::FALSE, + Keyword::ON, + Keyword::OFF, + Keyword::YES, + Keyword::NO, + ]) { + Some(keyword) => Value::Boolean(matches!( + keyword, + Keyword::TRUE | Keyword::YES | Keyword::ON + )) + .with_span(span), + None => self.parse_value()?, + }; match &v.value { Value::SingleQuotedString(_) => Ok(v), Value::DoubleQuotedString(_) => Ok(v), Value::Number(_, _) => Ok(v), + Value::Boolean(_) => Ok(v), Value::Placeholder(_) => Ok(v), _ => { self.prev_token(); - self.expected_ref("number or string or ? placeholder", self.peek_token_ref()) + self.expected_ref( + "boolean, number, string, or ? placeholder", + self.peek_token_ref(), + ) } } } diff --git a/tests/sqlparser_sqlite.rs b/tests/sqlparser_sqlite.rs index a017562df..01fa97203 100644 --- a/tests/sqlparser_sqlite.rs +++ b/tests/sqlparser_sqlite.rs @@ -30,8 +30,8 @@ use sqlparser::ast::SelectItem::UnnamedExpr; use sqlparser::ast::Value::Placeholder; use sqlparser::ast::*; use sqlparser::dialect::{GenericDialect, SQLiteDialect}; -use sqlparser::parser::{ParserError, ParserOptions}; -use sqlparser::tokenizer::Token; +use sqlparser::parser::{Parser, ParserError, ParserOptions}; +use sqlparser::tokenizer::{Span, Token}; #[test] fn pragma_no_value() { @@ -971,3 +971,61 @@ fn sqlite_and_generic() -> TestedDialects { Box::new(GenericDialect {}), ]) } + +#[test] +fn pragma_boolean_values() { + for (spelling, expected) in [ + ("TRUE", true), + ("YES", true), + ("ON", true), + ("FALSE", false), + ("NO", false), + ("OFF", false), + ] { + let sql = format!("PRAGMA case_sensitive_like = {spelling}"); + let canonical = format!("PRAGMA case_sensitive_like = {expected}"); + let statement = sqlite_and_generic().one_statement_parses_to(&sql, &canonical); + assert!(matches!( + statement, + Statement::Pragma { + value: Some(ValueWithSpan { + value: Value::Boolean(actual), + .. + }), + is_eq: true, + .. + } if actual == expected + )); + } + let statements = + Parser::parse_sql(&SQLiteDialect {}, "PRAGMA case_sensitive_like = oN").unwrap(); + let [Statement::Pragma { + value: + Some(ValueWithSpan { + value: Value::Boolean(true), + span, + }), + is_eq: true, + .. + }] = statements.as_slice() + else { + panic!("Expected equality-form PRAGMA") + }; + assert_eq!(&Span::new((1, 30).into(), (1, 32).into()), span); + + let statement = sqlite_and_generic().one_statement_parses_to( + "PRAGMA case_sensitive_like(ON)", + "PRAGMA case_sensitive_like(true)", + ); + assert!(matches!( + statement, + Statement::Pragma { + value: Some(ValueWithSpan { + value: Value::Boolean(true), + .. + }), + is_eq: false, + .. + } + )); +}