diff --git a/src/ast/mod.rs b/src/ast/mod.rs index cdc2e2049..d27baadc4 100644 --- a/src/ast/mod.rs +++ b/src/ast/mod.rs @@ -2699,6 +2699,11 @@ pub enum Statement { describe_alias: DescribeAlias, /// Hive style `FORMATTED | EXTENDED` hive_format: Option, + /// Snowflake and ClickHouse support `DESC|DESCRIBE TABLE ` syntax + /// + /// [Snowflake](https://docs.snowflake.com/en/sql-reference/sql/desc-table.html) + /// [ClickHouse](https://clickhouse.com/docs/en/sql-reference/statements/describe-table) + has_table_keyword: bool, /// Table name #[cfg_attr(feature = "visitor", visit(with = "visit_relation"))] table_name: ObjectName, @@ -2872,6 +2877,7 @@ impl fmt::Display for Statement { Statement::ExplainTable { describe_alias, hive_format, + has_table_keyword, table_name, } => { write!(f, "{describe_alias} ")?; @@ -2879,6 +2885,9 @@ impl fmt::Display for Statement { if let Some(format) = hive_format { write!(f, "{} ", format)?; } + if *has_table_keyword { + write!(f, "TABLE ")?; + } write!(f, "{table_name}") } diff --git a/src/parser/mod.rs b/src/parser/mod.rs index f8267a7cb..931033f7b 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -7972,10 +7972,13 @@ impl<'a> Parser<'a> { _ => {} } + // only allow to use TABLE keyword for DESC|DESCRIBE statement + let has_table_keyword = self.parse_keyword(Keyword::TABLE); let table_name = self.parse_object_name(false)?; Ok(Statement::ExplainTable { describe_alias, hive_format, + has_table_keyword, table_name, }) } diff --git a/tests/sqlparser_common.rs b/tests/sqlparser_common.rs index dd3ed0515..e68f25eb2 100644 --- a/tests/sqlparser_common.rs +++ b/tests/sqlparser_common.rs @@ -4186,31 +4186,49 @@ fn run_explain_analyze( #[test] fn parse_explain_table() { let validate_explain = - |query: &str, expected_describe_alias: DescribeAlias| match verified_stmt(query) { - Statement::ExplainTable { - describe_alias, - hive_format, - table_name, - } => { - assert_eq!(describe_alias, expected_describe_alias); - assert_eq!(hive_format, None); - assert_eq!("test_identifier", table_name.to_string()); + |query: &str, expected_describe_alias: DescribeAlias, expected_table_keyword| { + match verified_stmt(query) { + Statement::ExplainTable { + describe_alias, + hive_format, + has_table_keyword, + table_name, + } => { + assert_eq!(describe_alias, expected_describe_alias); + assert_eq!(hive_format, None); + assert_eq!(has_table_keyword, expected_table_keyword); + assert_eq!("test_identifier", table_name.to_string()); + } + _ => panic!("Unexpected Statement, must be ExplainTable"), } - _ => panic!("Unexpected Statement, must be ExplainTable"), }; - validate_explain("EXPLAIN test_identifier", DescribeAlias::Explain); - validate_explain("DESCRIBE test_identifier", DescribeAlias::Describe); + validate_explain("EXPLAIN test_identifier", DescribeAlias::Explain, false); + validate_explain("DESCRIBE test_identifier", DescribeAlias::Describe, false); + validate_explain("DESC test_identifier", DescribeAlias::Desc, false); + validate_explain( + "EXPLAIN TABLE test_identifier", + DescribeAlias::Explain, + true, + ); + validate_explain( + "DESCRIBE TABLE test_identifier", + DescribeAlias::Describe, + true, + ); + validate_explain("DESC TABLE test_identifier", DescribeAlias::Desc, true); } #[test] fn explain_describe() { verified_stmt("DESCRIBE test.table"); + verified_stmt("DESCRIBE TABLE test.table"); } #[test] fn explain_desc() { verified_stmt("DESC test.table"); + verified_stmt("DESC TABLE test.table"); } #[test]