This is an automated email from the ASF dual-hosted git repository. LucaCappelletti94 pushed a commit to branch fix-table-command-parsing in repository https://gitbox.apache.org/repos/asf/datafusion-sqlparser-rs.git
commit 055cbc279752e1eb0e75264326612567ee7fc646 Author: LucaCappelletti94 <[email protected]> AuthorDate: Tue Sep 22 08:50:46 2026 +0200 Fix TABLE command identifier quoting and token consumption --- src/parser/mod.rs | 40 ++++++---------------------------------- tests/sqlparser_common.rs | 41 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 34 deletions(-) diff --git a/src/parser/mod.rs b/src/parser/mod.rs index 15f135ff..fe47d965 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -15625,44 +15625,16 @@ impl<'a> Parser<'a> { /// Parse `CREATE TABLE x AS TABLE y` pub fn parse_as_table(&mut self) -> Result<Table, ParserError> { - let token1 = self.next_token(); - let token2 = self.next_token(); - let token3 = self.next_token(); - - let table_name; - let schema_name; - if token2 == Token::Period { - match token1.token { - Token::Word(w) => { - schema_name = w.value; - } - _ => { - return self.expected("Schema name", token1); - } - } - match token3.token { - Token::Word(w) => { - table_name = w.value; - } - _ => { - return self.expected("Table name", token3); - } - } + let first_name = self.parse_identifier()?.to_string(); + if self.consume_token(&Token::Period) { + let second_name = self.parse_identifier()?.to_string(); Ok(Table { - table_name: Some(table_name), - schema_name: Some(schema_name), + table_name: Some(second_name), + schema_name: Some(first_name), }) } else { - match token1.token { - Token::Word(w) => { - table_name = w.value; - } - _ => { - return self.expected("Table name", token1); - } - } Ok(Table { - table_name: Some(table_name), + table_name: Some(first_name), schema_name: None, }) } diff --git a/tests/sqlparser_common.rs b/tests/sqlparser_common.rs index c4aa607d..5ff4a2cc 100644 --- a/tests/sqlparser_common.rs +++ b/tests/sqlparser_common.rs @@ -20080,3 +20080,44 @@ fn parse_unary_minus_never_renders_line_comment() { all_dialects().verified_stmt("SELECT -1"); all_dialects().verified_stmt("SELECT -x"); } + +#[test] +fn parse_table_preserves_quotes_and_trailing_tokens() { + let dialects = TestedDialects::new(vec![ + Box::new(AnsiDialect {}), + Box::new(GenericDialect {}), + Box::new(PostgreSqlDialect {}), + Box::new(DuckDbDialect {}), + Box::new(SnowflakeDialect {}), + ]); + dialects.verified_stmt(r#"CREATE TABLE new_table AS TABLE "old_table""#); + dialects.verified_stmt(r#"CREATE TABLE new_table AS TABLE "schema_name"."old_table""#); + dialects.verified_stmt("CREATE TABLE new_table AS TABLE old_table ORDER BY x"); + dialects.verified_stmt("CREATE TABLE new_table AS TABLE old_table LIMIT 10"); + dialects.verified_stmt("SELECT * FROM (TABLE old_table ORDER BY x)"); + + let backtick_dialects = TestedDialects::new(vec![ + Box::new(AnsiDialect {}), + Box::new(GenericDialect {}), + Box::new(MySqlDialect {}), + ]); + backtick_dialects.verified_stmt("CREATE TABLE new_table AS TABLE `old_table`"); + backtick_dialects.verified_stmt("CREATE TABLE new_table AS TABLE `%mpty`"); + backtick_dialects.verified_stmt("INSERT INTO t TABLE `%mpty`"); + + let err = dialects + .parse_sql_statements("CREATE TABLE new_table AS TABLE %mpty") + .unwrap_err(); + assert_eq!( + ParserError::ParserError("Expected: identifier, found: %".to_string()), + err + ); + + let err = backtick_dialects + .parse_sql_statements("CREATE TABLE new_table AS TABLE `x` ORE") + .unwrap_err(); + assert_eq!( + ParserError::ParserError("Expected: end of statement, found: ORE".to_string()), + err + ); +} --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
