Skip to content

Commit d34b399

Browse files
yoavcloudwugeer
authored andcommitted
Add support for SHOW DATABASES/SCHEMAS/TABLES/VIEWS in Hive (apache#1487)
1 parent 391e63d commit d34b399

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
},
@@ -4380,9 +4397,24 @@ impl fmt::Display for Statement {
43804397
}
43814398
Ok(())
43824399
}
4400+
Statement::ShowDatabases { filter } => {
4401+
write!(f, "SHOW DATABASES")?;
4402+
if let Some(filter) = filter {
4403+
write!(f, " {filter}")?;
4404+
}
4405+
Ok(())
4406+
}
4407+
Statement::ShowSchemas { filter } => {
4408+
write!(f, "SHOW SCHEMAS")?;
4409+
if let Some(filter) = filter {
4410+
write!(f, " {filter}")?;
4411+
}
4412+
Ok(())
4413+
}
43834414
Statement::ShowTables {
43844415
extended,
43854416
full,
4417+
clause: show_clause,
43864418
db_name,
43874419
filter,
43884420
} => {
@@ -4392,8 +4424,33 @@ impl fmt::Display for Statement {
43924424
extended = if *extended { "EXTENDED " } else { "" },
43934425
full = if *full { "FULL " } else { "" },
43944426
)?;
4427+
if let Some(show_clause) = show_clause {
4428+
write!(f, " {show_clause}")?;
4429+
}
4430+
if let Some(db_name) = db_name {
4431+
write!(f, " {db_name}")?;
4432+
}
4433+
if let Some(filter) = filter {
4434+
write!(f, " {filter}")?;
4435+
}
4436+
Ok(())
4437+
}
4438+
Statement::ShowViews {
4439+
materialized,
4440+
clause: show_clause,
4441+
db_name,
4442+
filter,
4443+
} => {
4444+
write!(
4445+
f,
4446+
"SHOW {}VIEWS",
4447+
if *materialized { "MATERIALIZED " } else { "" }
4448+
)?;
4449+
if let Some(show_clause) = show_clause {
4450+
write!(f, " {show_clause}")?;
4451+
}
43954452
if let Some(db_name) = db_name {
4396-
write!(f, " FROM {db_name}")?;
4453+
write!(f, " {db_name}")?;
43974454
}
43984455
if let Some(filter) = filter {
43994456
write!(f, " {filter}")?;
@@ -6085,6 +6142,7 @@ pub enum ShowStatementFilter {
60856142
Like(String),
60866143
ILike(String),
60876144
Where(Expr),
6145+
NoKeyword(String),
60886146
}
60896147

60906148
impl fmt::Display for ShowStatementFilter {
@@ -6094,6 +6152,25 @@ impl fmt::Display for ShowStatementFilter {
60946152
Like(pattern) => write!(f, "LIKE '{}'", value::escape_single_quote_string(pattern)),
60956153
ILike(pattern) => write!(f, "ILIKE {}", value::escape_single_quote_string(pattern)),
60966154
Where(expr) => write!(f, "WHERE {expr}"),
6155+
NoKeyword(pattern) => write!(f, "'{}'", value::escape_single_quote_string(pattern)),
6156+
}
6157+
}
6158+
}
6159+
6160+
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
6161+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
6162+
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
6163+
pub enum ShowClause {
6164+
IN,
6165+
FROM,
6166+
}
6167+
6168+
impl fmt::Display for ShowClause {
6169+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
6170+
use ShowClause::*;
6171+
match self {
6172+
FROM => write!(f, "FROM"),
6173+
IN => write!(f, "IN"),
60976174
}
60986175
}
60996176
}

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,
@@ -664,6 +665,7 @@ define_keywords!(
664665
SAFE_CAST,
665666
SAVEPOINT,
666667
SCHEMA,
668+
SCHEMAS,
667669
SCOPE,
668670
SCROLL,
669671
SEARCH,
@@ -824,6 +826,7 @@ define_keywords!(
824826
VERSION,
825827
VERSIONING,
826828
VIEW,
829+
VIEWS,
827830
VIRTUAL,
828831
VOLATILE,
829832
WAREHOUSE,

src/parser/mod.rs

Lines changed: 46 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9598,6 +9598,10 @@ impl<'a> Parser<'a> {
95989598
Ok(self.parse_show_columns(extended, full)?)
95999599
} else if self.parse_keyword(Keyword::TABLES) {
96009600
Ok(self.parse_show_tables(extended, full)?)
9601+
} else if self.parse_keywords(&[Keyword::MATERIALIZED, Keyword::VIEWS]) {
9602+
Ok(self.parse_show_views(true)?)
9603+
} else if self.parse_keyword(Keyword::VIEWS) {
9604+
Ok(self.parse_show_views(false)?)
96019605
} else if self.parse_keyword(Keyword::FUNCTIONS) {
96029606
Ok(self.parse_show_functions()?)
96039607
} else if extended || full {
@@ -9624,13 +9628,29 @@ impl<'a> Parser<'a> {
96249628
session,
96259629
global,
96269630
})
9631+
} else if self.parse_keyword(Keyword::DATABASES) {
9632+
self.parse_show_databases()
9633+
} else if self.parse_keyword(Keyword::SCHEMAS) {
9634+
self.parse_show_schemas()
96279635
} else {
96289636
Ok(Statement::ShowVariable {
96299637
variable: self.parse_identifiers()?,
96309638
})
96319639
}
96329640
}
96339641

9642+
fn parse_show_databases(&mut self) -> Result<Statement, ParserError> {
9643+
Ok(Statement::ShowDatabases {
9644+
filter: self.parse_show_statement_filter()?,
9645+
})
9646+
}
9647+
9648+
fn parse_show_schemas(&mut self) -> Result<Statement, ParserError> {
9649+
Ok(Statement::ShowSchemas {
9650+
filter: self.parse_show_statement_filter()?,
9651+
})
9652+
}
9653+
96349654
pub fn parse_show_create(&mut self) -> Result<Statement, ParserError> {
96359655
let obj_type = match self.expect_one_of_keywords(&[
96369656
Keyword::TABLE,
@@ -9686,14 +9706,31 @@ impl<'a> Parser<'a> {
96869706
extended: bool,
96879707
full: bool,
96889708
) -> Result<Statement, ParserError> {
9689-
let db_name = match self.parse_one_of_keywords(&[Keyword::FROM, Keyword::IN]) {
9690-
Some(_) => Some(self.parse_identifier(false)?),
9691-
None => None,
9709+
let (clause, db_name) = match self.parse_one_of_keywords(&[Keyword::FROM, Keyword::IN]) {
9710+
Some(Keyword::FROM) => (Some(ShowClause::FROM), Some(self.parse_identifier(false)?)),
9711+
Some(Keyword::IN) => (Some(ShowClause::IN), Some(self.parse_identifier(false)?)),
9712+
_ => (None, None),
96929713
};
96939714
let filter = self.parse_show_statement_filter()?;
96949715
Ok(Statement::ShowTables {
96959716
extended,
96969717
full,
9718+
clause,
9719+
db_name,
9720+
filter,
9721+
})
9722+
}
9723+
9724+
fn parse_show_views(&mut self, materialized: bool) -> Result<Statement, ParserError> {
9725+
let (clause, db_name) = match self.parse_one_of_keywords(&[Keyword::FROM, Keyword::IN]) {
9726+
Some(Keyword::FROM) => (Some(ShowClause::FROM), Some(self.parse_identifier(false)?)),
9727+
Some(Keyword::IN) => (Some(ShowClause::IN), Some(self.parse_identifier(false)?)),
9728+
_ => (None, None),
9729+
};
9730+
let filter = self.parse_show_statement_filter()?;
9731+
Ok(Statement::ShowViews {
9732+
materialized,
9733+
clause,
96979734
db_name,
96989735
filter,
96999736
})
@@ -9723,7 +9760,12 @@ impl<'a> Parser<'a> {
97239760
} else if self.parse_keyword(Keyword::WHERE) {
97249761
Ok(Some(ShowStatementFilter::Where(self.parse_expr()?)))
97259762
} else {
9726-
Ok(None)
9763+
self.maybe_parse(|parser| -> Result<String, ParserError> {
9764+
parser.parse_literal_string()
9765+
})?
9766+
.map_or(Ok(None), |filter| {
9767+
Ok(Some(ShowStatementFilter::NoKeyword(filter)))
9768+
})
97279769
}
97289770
}
97299771

tests/sqlparser_common.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11379,6 +11379,27 @@ fn test_try_convert() {
1137911379
dialects.verified_expr("TRY_CONVERT('foo', VARCHAR(MAX))");
1138011380
}
1138111381

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+
}
11402+
1138211403
#[test]
1138311404
fn parse_listen_channel() {
1138411405
let dialects = all_dialects_where(|d| d.supports_listen());

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)