Skip to content

Commit 6ef20b0

Browse files
committed
fix: only require DESCRIBE TABLE for Snowflake and ClickHouse dialect
1 parent 8c4d30b commit 6ef20b0

File tree

8 files changed

+103
-32
lines changed

8 files changed

+103
-32
lines changed

src/dialect/clickhouse.rs

+4
Original file line numberDiff line numberDiff line change
@@ -33,4 +33,8 @@ impl Dialect for ClickHouseDialect {
3333
fn supports_select_wildcard_except(&self) -> bool {
3434
true
3535
}
36+
37+
fn describe_requires_table_keyword(&self) -> bool {
38+
true
39+
}
3640
}

src/dialect/mod.rs

+11
Original file line numberDiff line numberDiff line change
@@ -485,9 +485,20 @@ pub trait Dialect: Debug + Any {
485485
}
486486
}
487487

488+
/// Returns the precedence when the precedence is otherwise unknown
488489
fn prec_unknown(&self) -> u8 {
489490
0
490491
}
492+
493+
/// Returns true if this dialect requires the `TABLE` keyword after `DESCRIBE`
494+
///
495+
/// Defaults to false.
496+
///
497+
/// If true, the following statement is valid: `DESCRIBE TABLE my_table`
498+
/// If false, the following statement is valid: `DESCRIBE my_table`
499+
fn describe_requires_table_keyword(&self) -> bool {
500+
false
501+
}
491502
}
492503

493504
/// This represents the operators for which precedence must be defined

src/dialect/snowflake.rs

+4
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,10 @@ impl Dialect for SnowflakeDialect {
154154
_ => None,
155155
}
156156
}
157+
158+
fn describe_requires_table_keyword(&self) -> bool {
159+
true
160+
}
157161
}
158162

159163
/// Parse snowflake create table statement.

src/parser/mod.rs

+13-8
Original file line numberDiff line numberDiff line change
@@ -8185,15 +8185,20 @@ impl<'a> Parser<'a> {
81858185
format,
81868186
}),
81878187
_ => {
8188-
let mut hive_format = None;
8189-
match self.parse_one_of_keywords(&[Keyword::EXTENDED, Keyword::FORMATTED]) {
8190-
Some(Keyword::EXTENDED) => hive_format = Some(HiveDescribeFormat::Extended),
8191-
Some(Keyword::FORMATTED) => hive_format = Some(HiveDescribeFormat::Formatted),
8192-
_ => {}
8193-
}
8188+
let hive_format =
8189+
match self.parse_one_of_keywords(&[Keyword::EXTENDED, Keyword::FORMATTED]) {
8190+
Some(Keyword::EXTENDED) => Some(HiveDescribeFormat::Extended),
8191+
Some(Keyword::FORMATTED) => Some(HiveDescribeFormat::Formatted),
8192+
_ => None,
8193+
};
8194+
8195+
let has_table_keyword = if self.dialect.describe_requires_table_keyword() {
8196+
// only allow to use TABLE keyword for DESC|DESCRIBE statement
8197+
self.parse_keyword(Keyword::TABLE)
8198+
} else {
8199+
false
8200+
};
81948201

8195-
// only allow to use TABLE keyword for DESC|DESCRIBE statement
8196-
let has_table_keyword = self.parse_keyword(Keyword::TABLE);
81978202
let table_name = self.parse_object_name(false)?;
81988203
Ok(Statement::ExplainTable {
81998204
describe_alias,

tests/sqlparser_clickhouse.rs

+30
Original file line numberDiff line numberDiff line change
@@ -1376,6 +1376,36 @@ fn parse_select_table_function_settings() {
13761376
}
13771377
}
13781378

1379+
#[test]
1380+
fn explain_describe() {
1381+
clickhouse().verified_stmt("DESCRIBE test.table");
1382+
clickhouse().verified_stmt("DESCRIBE TABLE test.table");
1383+
}
1384+
1385+
#[test]
1386+
fn explain_desc() {
1387+
clickhouse().verified_stmt("DESC test.table");
1388+
clickhouse().verified_stmt("DESC TABLE test.table");
1389+
}
1390+
1391+
#[test]
1392+
fn parse_explain_table() {
1393+
match clickhouse().verified_stmt("EXPLAIN TABLE test_identifier") {
1394+
Statement::ExplainTable {
1395+
describe_alias,
1396+
hive_format,
1397+
has_table_keyword,
1398+
table_name,
1399+
} => {
1400+
pretty_assertions::assert_eq!(describe_alias, DescribeAlias::Explain);
1401+
pretty_assertions::assert_eq!(hive_format, None);
1402+
pretty_assertions::assert_eq!(has_table_keyword, true);
1403+
pretty_assertions::assert_eq!("test_identifier", table_name.to_string());
1404+
}
1405+
_ => panic!("Unexpected Statement, must be ExplainTable"),
1406+
}
1407+
}
1408+
13791409
fn clickhouse() -> TestedDialects {
13801410
TestedDialects {
13811411
dialects: vec![Box::new(ClickHouseDialect {})],

tests/sqlparser_common.rs

-13
Original file line numberDiff line numberDiff line change
@@ -4301,29 +4301,16 @@ fn parse_explain_table() {
43014301
validate_explain("EXPLAIN test_identifier", DescribeAlias::Explain, false);
43024302
validate_explain("DESCRIBE test_identifier", DescribeAlias::Describe, false);
43034303
validate_explain("DESC test_identifier", DescribeAlias::Desc, false);
4304-
validate_explain(
4305-
"EXPLAIN TABLE test_identifier",
4306-
DescribeAlias::Explain,
4307-
true,
4308-
);
4309-
validate_explain(
4310-
"DESCRIBE TABLE test_identifier",
4311-
DescribeAlias::Describe,
4312-
true,
4313-
);
4314-
validate_explain("DESC TABLE test_identifier", DescribeAlias::Desc, true);
43154304
}
43164305

43174306
#[test]
43184307
fn explain_describe() {
43194308
verified_stmt("DESCRIBE test.table");
4320-
verified_stmt("DESCRIBE TABLE test.table");
43214309
}
43224310

43234311
#[test]
43244312
fn explain_desc() {
43254313
verified_stmt("DESC test.table");
4326-
verified_stmt("DESC TABLE test.table");
43274314
}
43284315

43294316
#[test]

tests/sqlparser_hive.rs

+11-11
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ use sqlparser::ast::{
2121
UnaryOperator, Value,
2222
};
2323
use sqlparser::dialect::{GenericDialect, HiveDialect, MsSqlDialect};
24-
use sqlparser::parser::{ParserError, ParserOptions};
24+
use sqlparser::parser::ParserError;
2525
use sqlparser::test_utils::*;
2626

2727
#[test]
@@ -35,18 +35,11 @@ fn parse_table_create() {
3535
hive().verified_stmt(serdeproperties);
3636
}
3737

38-
fn generic(options: Option<ParserOptions>) -> TestedDialects {
39-
TestedDialects {
40-
dialects: vec![Box::new(GenericDialect {})],
41-
options,
42-
}
43-
}
44-
4538
#[test]
4639
fn parse_describe() {
47-
let describe = r#"DESCRIBE namespace.`table`"#;
48-
hive().verified_stmt(describe);
49-
generic(None).verified_stmt(describe);
40+
hive_and_generic().verified_stmt(r#"DESCRIBE namespace.`table`"#);
41+
hive_and_generic().verified_stmt(r#"DESCRIBE namespace.table"#);
42+
hive_and_generic().verified_stmt(r#"DESCRIBE table"#);
5043
}
5144

5245
#[test]
@@ -414,3 +407,10 @@ fn hive() -> TestedDialects {
414407
options: None,
415408
}
416409
}
410+
411+
fn hive_and_generic() -> TestedDialects {
412+
TestedDialects {
413+
dialects: vec![Box::new(HiveDialect {}), Box::new(GenericDialect {})],
414+
options: None,
415+
}
416+
}

tests/sqlparser_snowflake.rs

+30
Original file line numberDiff line numberDiff line change
@@ -2292,3 +2292,33 @@ fn test_parse_position() {
22922292
snowflake().verified_query("SELECT position('an', 'banana', 1)");
22932293
snowflake().verified_query("SELECT n, h, POSITION(n IN h) FROM pos");
22942294
}
2295+
2296+
#[test]
2297+
fn explain_describe() {
2298+
snowflake().verified_stmt("DESCRIBE test.table");
2299+
snowflake().verified_stmt("DESCRIBE TABLE test.table");
2300+
}
2301+
2302+
#[test]
2303+
fn explain_desc() {
2304+
snowflake().verified_stmt("DESC test.table");
2305+
snowflake().verified_stmt("DESC TABLE test.table");
2306+
}
2307+
2308+
#[test]
2309+
fn parse_explain_table() {
2310+
match snowflake().verified_stmt("EXPLAIN TABLE test_identifier") {
2311+
Statement::ExplainTable {
2312+
describe_alias,
2313+
hive_format,
2314+
has_table_keyword,
2315+
table_name,
2316+
} => {
2317+
assert_eq!(describe_alias, DescribeAlias::Explain);
2318+
assert_eq!(hive_format, None);
2319+
assert_eq!(has_table_keyword, true);
2320+
assert_eq!("test_identifier", table_name.to_string());
2321+
}
2322+
_ => panic!("Unexpected Statement, must be ExplainTable"),
2323+
}
2324+
}

0 commit comments

Comments
 (0)