Skip to content

Commit e2197ee

Browse files
authored
Add support for SHOW DATABASES/SCHEMAS/TABLES/VIEWS in Hive (apache#1487)
1 parent 8de3cb0 commit e2197ee

File tree

5 files changed

+157
-7
lines changed

5 files changed

+157
-7
lines changed

src/ast/mod.rs

Lines changed: 79 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2782,12 +2782,29 @@ pub enum Statement {
27822782
filter: Option<ShowStatementFilter>,
27832783
},
27842784
/// ```sql
2785+
/// SHOW DATABASES [LIKE 'pattern']
2786+
/// ```
2787+
ShowDatabases { filter: Option<ShowStatementFilter> },
2788+
/// ```sql
2789+
/// SHOW SCHEMAS [LIKE 'pattern']
2790+
/// ```
2791+
ShowSchemas { filter: Option<ShowStatementFilter> },
2792+
/// ```sql
27852793
/// SHOW TABLES
27862794
/// ```
2787-
/// Note: this is a MySQL-specific statement.
27882795
ShowTables {
27892796
extended: bool,
27902797
full: bool,
2798+
clause: Option<ShowClause>,
2799+
db_name: Option<Ident>,
2800+
filter: Option<ShowStatementFilter>,
2801+
},
2802+
/// ```sql
2803+
/// SHOW VIEWS
2804+
/// ```
2805+
ShowViews {
2806+
materialized: bool,
2807+
clause: Option<ShowClause>,
27912808
db_name: Option<Ident>,
27922809
filter: Option<ShowStatementFilter>,
27932810
},
@@ -4363,9 +4380,24 @@ impl fmt::Display for Statement {
43634380
}
43644381
Ok(())
43654382
}
4383+
Statement::ShowDatabases { filter } => {
4384+
write!(f, "SHOW DATABASES")?;
4385+
if let Some(filter) = filter {
4386+
write!(f, " {filter}")?;
4387+
}
4388+
Ok(())
4389+
}
4390+
Statement::ShowSchemas { filter } => {
4391+
write!(f, "SHOW SCHEMAS")?;
4392+
if let Some(filter) = filter {
4393+
write!(f, " {filter}")?;
4394+
}
4395+
Ok(())
4396+
}
43664397
Statement::ShowTables {
43674398
extended,
43684399
full,
4400+
clause: show_clause,
43694401
db_name,
43704402
filter,
43714403
} => {
@@ -4375,8 +4407,33 @@ impl fmt::Display for Statement {
43754407
extended = if *extended { "EXTENDED " } else { "" },
43764408
full = if *full { "FULL " } else { "" },
43774409
)?;
4410+
if let Some(show_clause) = show_clause {
4411+
write!(f, " {show_clause}")?;
4412+
}
4413+
if let Some(db_name) = db_name {
4414+
write!(f, " {db_name}")?;
4415+
}
4416+
if let Some(filter) = filter {
4417+
write!(f, " {filter}")?;
4418+
}
4419+
Ok(())
4420+
}
4421+
Statement::ShowViews {
4422+
materialized,
4423+
clause: show_clause,
4424+
db_name,
4425+
filter,
4426+
} => {
4427+
write!(
4428+
f,
4429+
"SHOW {}VIEWS",
4430+
if *materialized { "MATERIALIZED " } else { "" }
4431+
)?;
4432+
if let Some(show_clause) = show_clause {
4433+
write!(f, " {show_clause}")?;
4434+
}
43784435
if let Some(db_name) = db_name {
4379-
write!(f, " FROM {db_name}")?;
4436+
write!(f, " {db_name}")?;
43804437
}
43814438
if let Some(filter) = filter {
43824439
write!(f, " {filter}")?;
@@ -6057,6 +6114,7 @@ pub enum ShowStatementFilter {
60576114
Like(String),
60586115
ILike(String),
60596116
Where(Expr),
6117+
NoKeyword(String),
60606118
}
60616119

60626120
impl fmt::Display for ShowStatementFilter {
@@ -6066,6 +6124,25 @@ impl fmt::Display for ShowStatementFilter {
60666124
Like(pattern) => write!(f, "LIKE '{}'", value::escape_single_quote_string(pattern)),
60676125
ILike(pattern) => write!(f, "ILIKE {}", value::escape_single_quote_string(pattern)),
60686126
Where(expr) => write!(f, "WHERE {expr}"),
6127+
NoKeyword(pattern) => write!(f, "'{}'", value::escape_single_quote_string(pattern)),
6128+
}
6129+
}
6130+
}
6131+
6132+
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
6133+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
6134+
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
6135+
pub enum ShowClause {
6136+
IN,
6137+
FROM,
6138+
}
6139+
6140+
impl fmt::Display for ShowClause {
6141+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
6142+
use ShowClause::*;
6143+
match self {
6144+
FROM => write!(f, "FROM"),
6145+
IN => write!(f, "IN"),
60696146
}
60706147
}
60716148
}

src/keywords.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,7 @@ define_keywords!(
217217
CYCLE,
218218
DATA,
219219
DATABASE,
220+
DATABASES,
220221
DATA_RETENTION_TIME_IN_DAYS,
221222
DATE,
222223
DATE32,
@@ -662,6 +663,7 @@ define_keywords!(
662663
SAFE_CAST,
663664
SAVEPOINT,
664665
SCHEMA,
666+
SCHEMAS,
665667
SCOPE,
666668
SCROLL,
667669
SEARCH,
@@ -822,6 +824,7 @@ define_keywords!(
822824
VERSION,
823825
VERSIONING,
824826
VIEW,
827+
VIEWS,
825828
VIRTUAL,
826829
VOLATILE,
827830
WAREHOUSE,

src/parser/mod.rs

Lines changed: 46 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9579,6 +9579,10 @@ impl<'a> Parser<'a> {
95799579
Ok(self.parse_show_columns(extended, full)?)
95809580
} else if self.parse_keyword(Keyword::TABLES) {
95819581
Ok(self.parse_show_tables(extended, full)?)
9582+
} else if self.parse_keywords(&[Keyword::MATERIALIZED, Keyword::VIEWS]) {
9583+
Ok(self.parse_show_views(true)?)
9584+
} else if self.parse_keyword(Keyword::VIEWS) {
9585+
Ok(self.parse_show_views(false)?)
95829586
} else if self.parse_keyword(Keyword::FUNCTIONS) {
95839587
Ok(self.parse_show_functions()?)
95849588
} else if extended || full {
@@ -9605,13 +9609,29 @@ impl<'a> Parser<'a> {
96059609
session,
96069610
global,
96079611
})
9612+
} else if self.parse_keyword(Keyword::DATABASES) {
9613+
self.parse_show_databases()
9614+
} else if self.parse_keyword(Keyword::SCHEMAS) {
9615+
self.parse_show_schemas()
96089616
} else {
96099617
Ok(Statement::ShowVariable {
96109618
variable: self.parse_identifiers()?,
96119619
})
96129620
}
96139621
}
96149622

9623+
fn parse_show_databases(&mut self) -> Result<Statement, ParserError> {
9624+
Ok(Statement::ShowDatabases {
9625+
filter: self.parse_show_statement_filter()?,
9626+
})
9627+
}
9628+
9629+
fn parse_show_schemas(&mut self) -> Result<Statement, ParserError> {
9630+
Ok(Statement::ShowSchemas {
9631+
filter: self.parse_show_statement_filter()?,
9632+
})
9633+
}
9634+
96159635
pub fn parse_show_create(&mut self) -> Result<Statement, ParserError> {
96169636
let obj_type = match self.expect_one_of_keywords(&[
96179637
Keyword::TABLE,
@@ -9667,14 +9687,31 @@ impl<'a> Parser<'a> {
96679687
extended: bool,
96689688
full: bool,
96699689
) -> Result<Statement, ParserError> {
9670-
let db_name = match self.parse_one_of_keywords(&[Keyword::FROM, Keyword::IN]) {
9671-
Some(_) => Some(self.parse_identifier(false)?),
9672-
None => None,
9690+
let (clause, db_name) = match self.parse_one_of_keywords(&[Keyword::FROM, Keyword::IN]) {
9691+
Some(Keyword::FROM) => (Some(ShowClause::FROM), Some(self.parse_identifier(false)?)),
9692+
Some(Keyword::IN) => (Some(ShowClause::IN), Some(self.parse_identifier(false)?)),
9693+
_ => (None, None),
96739694
};
96749695
let filter = self.parse_show_statement_filter()?;
96759696
Ok(Statement::ShowTables {
96769697
extended,
96779698
full,
9699+
clause,
9700+
db_name,
9701+
filter,
9702+
})
9703+
}
9704+
9705+
fn parse_show_views(&mut self, materialized: bool) -> Result<Statement, ParserError> {
9706+
let (clause, db_name) = match self.parse_one_of_keywords(&[Keyword::FROM, Keyword::IN]) {
9707+
Some(Keyword::FROM) => (Some(ShowClause::FROM), Some(self.parse_identifier(false)?)),
9708+
Some(Keyword::IN) => (Some(ShowClause::IN), Some(self.parse_identifier(false)?)),
9709+
_ => (None, None),
9710+
};
9711+
let filter = self.parse_show_statement_filter()?;
9712+
Ok(Statement::ShowViews {
9713+
materialized,
9714+
clause,
96789715
db_name,
96799716
filter,
96809717
})
@@ -9704,7 +9741,12 @@ impl<'a> Parser<'a> {
97049741
} else if self.parse_keyword(Keyword::WHERE) {
97059742
Ok(Some(ShowStatementFilter::Where(self.parse_expr()?)))
97069743
} else {
9707-
Ok(None)
9744+
self.maybe_parse(|parser| -> Result<String, ParserError> {
9745+
parser.parse_literal_string()
9746+
})?
9747+
.map_or(Ok(None), |filter| {
9748+
Ok(Some(ShowStatementFilter::NoKeyword(filter)))
9749+
})
97089750
}
97099751
}
97109752

tests/sqlparser_common.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11378,3 +11378,24 @@ fn test_try_convert() {
1137811378
all_dialects_where(|d| d.supports_try_convert() && !d.convert_type_before_value());
1137911379
dialects.verified_expr("TRY_CONVERT('foo', VARCHAR(MAX))");
1138011380
}
11381+
11382+
#[test]
11383+
fn test_show_dbs_schemas_tables_views() {
11384+
verified_stmt("SHOW DATABASES");
11385+
verified_stmt("SHOW DATABASES LIKE '%abc'");
11386+
verified_stmt("SHOW SCHEMAS");
11387+
verified_stmt("SHOW SCHEMAS LIKE '%abc'");
11388+
verified_stmt("SHOW TABLES");
11389+
verified_stmt("SHOW TABLES IN db1");
11390+
verified_stmt("SHOW TABLES IN db1 'abc'");
11391+
verified_stmt("SHOW VIEWS");
11392+
verified_stmt("SHOW VIEWS IN db1");
11393+
verified_stmt("SHOW VIEWS IN db1 'abc'");
11394+
verified_stmt("SHOW VIEWS FROM db1");
11395+
verified_stmt("SHOW VIEWS FROM db1 'abc'");
11396+
verified_stmt("SHOW MATERIALIZED VIEWS");
11397+
verified_stmt("SHOW MATERIALIZED VIEWS IN db1");
11398+
verified_stmt("SHOW MATERIALIZED VIEWS IN db1 'abc'");
11399+
verified_stmt("SHOW MATERIALIZED VIEWS FROM db1");
11400+
verified_stmt("SHOW MATERIALIZED VIEWS FROM db1 'abc'");
11401+
}

tests/sqlparser_mysql.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,7 @@ fn parse_show_tables() {
329329
Statement::ShowTables {
330330
extended: false,
331331
full: false,
332+
clause: None,
332333
db_name: None,
333334
filter: None,
334335
}
@@ -338,6 +339,7 @@ fn parse_show_tables() {
338339
Statement::ShowTables {
339340
extended: false,
340341
full: false,
342+
clause: Some(ShowClause::FROM),
341343
db_name: Some(Ident::new("mydb")),
342344
filter: None,
343345
}
@@ -347,6 +349,7 @@ fn parse_show_tables() {
347349
Statement::ShowTables {
348350
extended: true,
349351
full: false,
352+
clause: None,
350353
db_name: None,
351354
filter: None,
352355
}
@@ -356,6 +359,7 @@ fn parse_show_tables() {
356359
Statement::ShowTables {
357360
extended: false,
358361
full: true,
362+
clause: None,
359363
db_name: None,
360364
filter: None,
361365
}
@@ -365,6 +369,7 @@ fn parse_show_tables() {
365369
Statement::ShowTables {
366370
extended: false,
367371
full: false,
372+
clause: None,
368373
db_name: None,
369374
filter: Some(ShowStatementFilter::Like("pattern".into())),
370375
}
@@ -374,13 +379,15 @@ fn parse_show_tables() {
374379
Statement::ShowTables {
375380
extended: false,
376381
full: false,
382+
clause: None,
377383
db_name: None,
378384
filter: Some(ShowStatementFilter::Where(
379385
mysql_and_generic().verified_expr("1 = 2")
380386
)),
381387
}
382388
);
383-
mysql_and_generic().one_statement_parses_to("SHOW TABLES IN mydb", "SHOW TABLES FROM mydb");
389+
mysql_and_generic().verified_stmt("SHOW TABLES IN mydb");
390+
mysql_and_generic().verified_stmt("SHOW TABLES FROM mydb");
384391
}
385392

386393
#[test]

0 commit comments

Comments
 (0)