Skip to content

Commit dbcdcce

Browse files
committed
Added support for SHOW DATABASES/SCHEMAS/VIEWS and extended SHOW TABLES for hive dialect
1 parent 8e0d26a commit dbcdcce

File tree

5 files changed

+140
-10
lines changed

5 files changed

+140
-10
lines changed

src/ast/mod.rs

Lines changed: 64 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,9 @@ pub use self::value::{
7373
TrimWhereField, Value,
7474
};
7575

76-
use crate::ast::helpers::stmt_data_loading::{
77-
DataLoadingOptions, StageLoadSelectItem, StageParamsObject,
76+
use crate::{
77+
ast::helpers::stmt_data_loading::{DataLoadingOptions, StageLoadSelectItem, StageParamsObject},
78+
keywords::Keyword,
7879
};
7980
#[cfg(feature = "visitor")]
8081
pub use visitor::*;
@@ -2782,12 +2783,30 @@ pub enum Statement {
27822783
filter: Option<ShowStatementFilter>,
27832784
},
27842785
/// ```sql
2786+
/// SHOW DATABASES [LIKE 'pattern']
2787+
/// ```
2788+
ShowDatabases { pattern: Option<String> },
2789+
/// ```sql
2790+
/// SHOW SCHEMAS [LIKE 'pattern']
2791+
/// ```
2792+
ShowSchemas { pattern: Option<String> },
2793+
/// ```sql
27852794
/// SHOW TABLES
27862795
/// ```
2787-
/// Note: this is a MySQL-specific statement.
27882796
ShowTables {
27892797
extended: bool,
27902798
full: bool,
2799+
// The keyword used to indicate the DB name (IN/FROM)
2800+
db_name_keyword: Option<Keyword>,
2801+
db_name: Option<Ident>,
2802+
filter: Option<ShowStatementFilter>,
2803+
},
2804+
/// ```sql
2805+
/// SHOW VIEWS
2806+
/// ```
2807+
ShowViews {
2808+
// The keyword used to indicate the DB name (IN/FROM)
2809+
db_name_keyword: Option<Keyword>,
27912810
db_name: Option<Ident>,
27922811
filter: Option<ShowStatementFilter>,
27932812
},
@@ -4363,9 +4382,24 @@ impl fmt::Display for Statement {
43634382
}
43644383
Ok(())
43654384
}
4385+
Statement::ShowDatabases { pattern } => {
4386+
write!(f, "SHOW DATABASES")?;
4387+
if let Some(pattern) = pattern {
4388+
write!(f, " LIKE '{}'", pattern)?;
4389+
}
4390+
Ok(())
4391+
}
4392+
Statement::ShowSchemas { pattern } => {
4393+
write!(f, "SHOW SCHEMAS")?;
4394+
if let Some(pattern) = pattern {
4395+
write!(f, " LIKE '{}'", pattern)?;
4396+
}
4397+
Ok(())
4398+
}
43664399
Statement::ShowTables {
43674400
extended,
43684401
full,
4402+
db_name_keyword,
43694403
db_name,
43704404
filter,
43714405
} => {
@@ -4376,7 +4410,31 @@ impl fmt::Display for Statement {
43764410
full = if *full { "FULL " } else { "" },
43774411
)?;
43784412
if let Some(db_name) = db_name {
4379-
write!(f, " FROM {db_name}")?;
4413+
let keyword = match &db_name_keyword {
4414+
Some(Keyword::FROM) => "FROM",
4415+
Some(Keyword::IN) => "IN",
4416+
_ => "", // unexpected
4417+
};
4418+
write!(f, " {} {db_name}", keyword)?;
4419+
}
4420+
if let Some(filter) = filter {
4421+
write!(f, " {filter}")?;
4422+
}
4423+
Ok(())
4424+
}
4425+
Statement::ShowViews {
4426+
db_name_keyword,
4427+
db_name,
4428+
filter
4429+
} => {
4430+
write!(f, "SHOW VIEWS")?;
4431+
if let Some(db_name) = db_name {
4432+
let keyword = match &db_name_keyword {
4433+
Some(Keyword::FROM) => "FROM",
4434+
Some(Keyword::IN) => "IN",
4435+
_ => "", // unexpected
4436+
};
4437+
write!(f, " {} {db_name}", keyword)?;
43804438
}
43814439
if let Some(filter) = filter {
43824440
write!(f, " {filter}")?;
@@ -6057,6 +6115,7 @@ pub enum ShowStatementFilter {
60576115
Like(String),
60586116
ILike(String),
60596117
Where(Expr),
6118+
NoKeyword(String),
60606119
}
60616120

60626121
impl fmt::Display for ShowStatementFilter {
@@ -6066,6 +6125,7 @@ impl fmt::Display for ShowStatementFilter {
60666125
Like(pattern) => write!(f, "LIKE '{}'", value::escape_single_quote_string(pattern)),
60676126
ILike(pattern) => write!(f, "ILIKE {}", value::escape_single_quote_string(pattern)),
60686127
Where(expr) => write!(f, "WHERE {expr}"),
6128+
NoKeyword(pattern) => write!(f, "'{}'", value::escape_single_quote_string(pattern)),
60696129
}
60706130
}
60716131
}

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: 50 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9579,6 +9579,8 @@ 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_keyword(Keyword::VIEWS) {
9583+
Ok(self.parse_show_views()?)
95829584
} else if self.parse_keyword(Keyword::FUNCTIONS) {
95839585
Ok(self.parse_show_functions()?)
95849586
} else if extended || full {
@@ -9605,13 +9607,35 @@ impl<'a> Parser<'a> {
96059607
session,
96069608
global,
96079609
})
9610+
} else if self.parse_keyword(Keyword::DATABASES) {
9611+
self.parse_show_databases()
9612+
} else if self.parse_keyword(Keyword::SCHEMAS) {
9613+
self.parse_show_schemas()
96089614
} else {
96099615
Ok(Statement::ShowVariable {
96109616
variable: self.parse_identifiers()?,
96119617
})
96129618
}
96139619
}
96149620

9621+
fn parse_show_databases(&mut self) -> Result<Statement, ParserError> {
9622+
let pattern = if self.parse_keyword(Keyword::LIKE) {
9623+
Some(self.parse_literal_string()?)
9624+
} else {
9625+
None
9626+
};
9627+
Ok(Statement::ShowDatabases { pattern })
9628+
}
9629+
9630+
fn parse_show_schemas(&mut self) -> Result<Statement, ParserError> {
9631+
let pattern = if self.parse_keyword(Keyword::LIKE) {
9632+
Some(self.parse_literal_string()?)
9633+
} else {
9634+
None
9635+
};
9636+
Ok(Statement::ShowSchemas { pattern })
9637+
}
9638+
96159639
pub fn parse_show_create(&mut self) -> Result<Statement, ParserError> {
96169640
let obj_type = match self.expect_one_of_keywords(&[
96179641
Keyword::TABLE,
@@ -9667,14 +9691,30 @@ impl<'a> Parser<'a> {
96679691
extended: bool,
96689692
full: bool,
96699693
) -> 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,
9673-
};
9694+
let (db_name_keyword, db_name) =
9695+
match self.parse_one_of_keywords(&[Keyword::FROM, Keyword::IN]) {
9696+
Some(keyword) => (Some(keyword), Some(self.parse_identifier(false)?)),
9697+
None => (None, None),
9698+
};
96749699
let filter = self.parse_show_statement_filter()?;
96759700
Ok(Statement::ShowTables {
96769701
extended,
96779702
full,
9703+
db_name_keyword,
9704+
db_name,
9705+
filter,
9706+
})
9707+
}
9708+
9709+
fn parse_show_views(&mut self) -> Result<Statement, ParserError> {
9710+
let (db_name_keyword, db_name) =
9711+
match self.parse_one_of_keywords(&[Keyword::FROM, Keyword::IN]) {
9712+
Some(keyword) => (Some(keyword), Some(self.parse_identifier(false)?)),
9713+
None => (None, None),
9714+
};
9715+
let filter = self.parse_show_statement_filter()?;
9716+
Ok(Statement::ShowViews {
9717+
db_name_keyword,
96789718
db_name,
96799719
filter,
96809720
})
@@ -9704,7 +9744,12 @@ impl<'a> Parser<'a> {
97049744
} else if self.parse_keyword(Keyword::WHERE) {
97059745
Ok(Some(ShowStatementFilter::Where(self.parse_expr()?)))
97069746
} else {
9707-
Ok(None)
9747+
match self.peek_token().token {
9748+
Token::SingleQuotedString(_) | Token::DoubleQuotedString(_) => Ok(Some(
9749+
ShowStatementFilter::NoKeyword(self.parse_literal_string()?),
9750+
)),
9751+
_ => Ok(None),
9752+
}
97089753
}
97099754
}
97109755

tests/sqlparser_hive.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -534,6 +534,20 @@ fn parse_use() {
534534
);
535535
}
536536

537+
#[test]
538+
fn test_show() {
539+
hive().verified_stmt("SHOW DATABASES");
540+
hive().verified_stmt("SHOW DATABASES LIKE '%abc'");
541+
hive().verified_stmt("SHOW SCHEMAS");
542+
hive().verified_stmt("SHOW SCHEMAS LIKE '%abc'");
543+
hive().verified_stmt("SHOW TABLES");
544+
hive().verified_stmt("SHOW TABLES IN db1");
545+
hive().verified_stmt("SHOW TABLES IN db1 'abc'");
546+
hive().verified_stmt("SHOW VIEWS");
547+
hive().verified_stmt("SHOW VIEWS IN db1");
548+
hive().verified_stmt("SHOW VIEWS IN db1 'abc'");
549+
}
550+
537551
fn hive() -> TestedDialects {
538552
TestedDialects::new(vec![Box::new(HiveDialect {})])
539553
}

tests/sqlparser_mysql.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ use matches::assert_matches;
2424
use sqlparser::ast::MysqlInsertPriority::{Delayed, HighPriority, LowPriority};
2525
use sqlparser::ast::*;
2626
use sqlparser::dialect::{GenericDialect, MySqlDialect};
27+
use sqlparser::keywords::Keyword;
2728
use sqlparser::parser::{ParserError, ParserOptions};
2829
use sqlparser::tokenizer::Token;
2930
use test_utils::*;
@@ -329,6 +330,7 @@ fn parse_show_tables() {
329330
Statement::ShowTables {
330331
extended: false,
331332
full: false,
333+
db_name_keyword: None,
332334
db_name: None,
333335
filter: None,
334336
}
@@ -338,6 +340,7 @@ fn parse_show_tables() {
338340
Statement::ShowTables {
339341
extended: false,
340342
full: false,
343+
db_name_keyword: Some(Keyword::FROM),
341344
db_name: Some(Ident::new("mydb")),
342345
filter: None,
343346
}
@@ -347,6 +350,7 @@ fn parse_show_tables() {
347350
Statement::ShowTables {
348351
extended: true,
349352
full: false,
353+
db_name_keyword: None,
350354
db_name: None,
351355
filter: None,
352356
}
@@ -356,6 +360,7 @@ fn parse_show_tables() {
356360
Statement::ShowTables {
357361
extended: false,
358362
full: true,
363+
db_name_keyword: None,
359364
db_name: None,
360365
filter: None,
361366
}
@@ -365,6 +370,7 @@ fn parse_show_tables() {
365370
Statement::ShowTables {
366371
extended: false,
367372
full: false,
373+
db_name_keyword: None,
368374
db_name: None,
369375
filter: Some(ShowStatementFilter::Like("pattern".into())),
370376
}
@@ -374,13 +380,15 @@ fn parse_show_tables() {
374380
Statement::ShowTables {
375381
extended: false,
376382
full: false,
383+
db_name_keyword: None,
377384
db_name: None,
378385
filter: Some(ShowStatementFilter::Where(
379386
mysql_and_generic().verified_expr("1 = 2")
380387
)),
381388
}
382389
);
383-
mysql_and_generic().one_statement_parses_to("SHOW TABLES IN mydb", "SHOW TABLES FROM mydb");
390+
mysql_and_generic().verified_stmt("SHOW TABLES IN mydb");
391+
mysql_and_generic().verified_stmt( "SHOW TABLES FROM mydb");
384392
}
385393

386394
#[test]

0 commit comments

Comments
 (0)