From 0a063abac9eb67d173e5f8f579ae10b350ceca16 Mon Sep 17 00:00:00 2001 From: LucaCappelletti94 Date: Sun, 25 Oct 2026 17:37:57 +0100 Subject: [PATCH] Spark: Share CACHE TABLE parsing --- src/parser/mod.rs | 91 +++++++++++---------------------------- tests/sqlparser_common.rs | 25 +++++++++++ 2 files changed, 49 insertions(+), 67 deletions(-) diff --git a/src/parser/mod.rs b/src/parser/mod.rs index eafe4d621e..7e27c1b8f9 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -5755,78 +5755,35 @@ impl<'a> Parser<'a> { /// Parse a CACHE TABLE statement pub fn parse_cache_table(&mut self) -> Result { - let (mut table_flag, mut options, mut has_as, mut query) = (None, vec![], false, None); - if self.parse_keyword(Keyword::TABLE) { - let table_name = self.parse_object_name(false)?; - if self.peek_token_ref().token != Token::EOF { - if let Token::Word(word) = &self.peek_token_ref().token { - if word.keyword == Keyword::OPTIONS { - options = self.parse_options(Keyword::OPTIONS)? - } - }; - - if self.peek_token_ref().token != Token::EOF { - let (a, q) = self.parse_as_query()?; - has_as = a; - query = Some(q); - } - - Ok(Statement::Cache { - table_flag, - table_name, - has_as, - options, - query, - }) - } else { - Ok(Statement::Cache { - table_flag, - table_name, - has_as, - options, - query, - }) - } + let table_flag = if self.parse_keyword(Keyword::TABLE) { + None } else { - table_flag = Some(self.parse_object_name(false)?); - if self.parse_keyword(Keyword::TABLE) { - let table_name = self.parse_object_name(false)?; - if self.peek_token_ref().token != Token::EOF { - if let Token::Word(word) = &self.peek_token_ref().token { - if word.keyword == Keyword::OPTIONS { - options = self.parse_options(Keyword::OPTIONS)? - } - }; - - if self.peek_token_ref().token != Token::EOF { - let (a, q) = self.parse_as_query()?; - has_as = a; - query = Some(q); - } - - Ok(Statement::Cache { - table_flag, - table_name, - has_as, - options, - query, - }) - } else { - Ok(Statement::Cache { - table_flag, - table_name, - has_as, - options, - query, - }) - } - } else { + let flag = self.parse_object_name(false)?; + if !self.parse_keyword(Keyword::TABLE) { if self.peek_token_ref().token == Token::EOF { self.prev_token(); } - self.expected_ref("a `TABLE` keyword", self.peek_token_ref()) + return self.expected_ref("a `TABLE` keyword", self.peek_token_ref()); } - } + Some(flag) + }; + + let table_name = self.parse_object_name(false)?; + let options = self.parse_options(Keyword::OPTIONS)?; + let (has_as, query) = if self.peek_token_ref().token == Token::EOF { + (false, None) + } else { + let (has_as, query) = self.parse_as_query()?; + (has_as, Some(query)) + }; + + Ok(Statement::Cache { + table_flag, + table_name, + has_as, + options, + query, + }) } /// Parse 'AS' before as query,such as `WITH XXX AS SELECT XXX` oer `CACHE TABLE AS SELECT XXX` diff --git a/tests/sqlparser_common.rs b/tests/sqlparser_common.rs index 71c050fe80..637f2a686c 100644 --- a/tests/sqlparser_common.rs +++ b/tests/sqlparser_common.rs @@ -22039,3 +22039,28 @@ fn parse_qualified_literal_prefix_requires_adjacent_period() { dialects.tokenizes_to(sql, vec![token]); } } + +#[test] +fn parse_cache_table_options_without_flag() { + let dialects = all_dialects(); + for (suffix, has_as) in [("", false), (" SELECT 1", false), (" AS SELECT 1", true)] { + let query = if suffix.is_empty() { + None + } else { + Some(dialects.verified_query("SELECT 1").into()) + }; + assert_eq!( + dialects.verified_stmt(&format!("CACHE TABLE t OPTIONS('k' = 'v'){suffix}")), + Statement::Cache { + table_flag: None, + table_name: ObjectName::from(vec![Ident::new("t")]), + has_as, + options: vec![SqlOption::KeyValue { + key: Ident::with_quote('\'', "k"), + value: Expr::Value(Value::SingleQuotedString("v".into()).with_empty_span()), + }], + query, + } + ); + } +}