mirror of
https://github.com/apache/datafusion-sqlparser-rs.git
synced 2025-08-23 07:24:10 +00:00
Add support for SHOW DATABASES/SCHEMAS/TABLES/VIEWS in Hive (#1487)
This commit is contained in:
parent
8de3cb0074
commit
e2197eeca9
5 changed files with 157 additions and 7 deletions
|
@ -2782,12 +2782,29 @@ pub enum Statement {
|
||||||
filter: Option<ShowStatementFilter>,
|
filter: Option<ShowStatementFilter>,
|
||||||
},
|
},
|
||||||
/// ```sql
|
/// ```sql
|
||||||
|
/// SHOW DATABASES [LIKE 'pattern']
|
||||||
|
/// ```
|
||||||
|
ShowDatabases { filter: Option<ShowStatementFilter> },
|
||||||
|
/// ```sql
|
||||||
|
/// SHOW SCHEMAS [LIKE 'pattern']
|
||||||
|
/// ```
|
||||||
|
ShowSchemas { filter: Option<ShowStatementFilter> },
|
||||||
|
/// ```sql
|
||||||
/// SHOW TABLES
|
/// SHOW TABLES
|
||||||
/// ```
|
/// ```
|
||||||
/// Note: this is a MySQL-specific statement.
|
|
||||||
ShowTables {
|
ShowTables {
|
||||||
extended: bool,
|
extended: bool,
|
||||||
full: bool,
|
full: bool,
|
||||||
|
clause: Option<ShowClause>,
|
||||||
|
db_name: Option<Ident>,
|
||||||
|
filter: Option<ShowStatementFilter>,
|
||||||
|
},
|
||||||
|
/// ```sql
|
||||||
|
/// SHOW VIEWS
|
||||||
|
/// ```
|
||||||
|
ShowViews {
|
||||||
|
materialized: bool,
|
||||||
|
clause: Option<ShowClause>,
|
||||||
db_name: Option<Ident>,
|
db_name: Option<Ident>,
|
||||||
filter: Option<ShowStatementFilter>,
|
filter: Option<ShowStatementFilter>,
|
||||||
},
|
},
|
||||||
|
@ -4363,9 +4380,24 @@ impl fmt::Display for Statement {
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
Statement::ShowDatabases { filter } => {
|
||||||
|
write!(f, "SHOW DATABASES")?;
|
||||||
|
if let Some(filter) = filter {
|
||||||
|
write!(f, " {filter}")?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
Statement::ShowSchemas { filter } => {
|
||||||
|
write!(f, "SHOW SCHEMAS")?;
|
||||||
|
if let Some(filter) = filter {
|
||||||
|
write!(f, " {filter}")?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
Statement::ShowTables {
|
Statement::ShowTables {
|
||||||
extended,
|
extended,
|
||||||
full,
|
full,
|
||||||
|
clause: show_clause,
|
||||||
db_name,
|
db_name,
|
||||||
filter,
|
filter,
|
||||||
} => {
|
} => {
|
||||||
|
@ -4375,8 +4407,33 @@ impl fmt::Display for Statement {
|
||||||
extended = if *extended { "EXTENDED " } else { "" },
|
extended = if *extended { "EXTENDED " } else { "" },
|
||||||
full = if *full { "FULL " } else { "" },
|
full = if *full { "FULL " } else { "" },
|
||||||
)?;
|
)?;
|
||||||
|
if let Some(show_clause) = show_clause {
|
||||||
|
write!(f, " {show_clause}")?;
|
||||||
|
}
|
||||||
if let Some(db_name) = db_name {
|
if let Some(db_name) = db_name {
|
||||||
write!(f, " FROM {db_name}")?;
|
write!(f, " {db_name}")?;
|
||||||
|
}
|
||||||
|
if let Some(filter) = filter {
|
||||||
|
write!(f, " {filter}")?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
Statement::ShowViews {
|
||||||
|
materialized,
|
||||||
|
clause: show_clause,
|
||||||
|
db_name,
|
||||||
|
filter,
|
||||||
|
} => {
|
||||||
|
write!(
|
||||||
|
f,
|
||||||
|
"SHOW {}VIEWS",
|
||||||
|
if *materialized { "MATERIALIZED " } else { "" }
|
||||||
|
)?;
|
||||||
|
if let Some(show_clause) = show_clause {
|
||||||
|
write!(f, " {show_clause}")?;
|
||||||
|
}
|
||||||
|
if let Some(db_name) = db_name {
|
||||||
|
write!(f, " {db_name}")?;
|
||||||
}
|
}
|
||||||
if let Some(filter) = filter {
|
if let Some(filter) = filter {
|
||||||
write!(f, " {filter}")?;
|
write!(f, " {filter}")?;
|
||||||
|
@ -6057,6 +6114,7 @@ pub enum ShowStatementFilter {
|
||||||
Like(String),
|
Like(String),
|
||||||
ILike(String),
|
ILike(String),
|
||||||
Where(Expr),
|
Where(Expr),
|
||||||
|
NoKeyword(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for ShowStatementFilter {
|
impl fmt::Display for ShowStatementFilter {
|
||||||
|
@ -6066,6 +6124,25 @@ impl fmt::Display for ShowStatementFilter {
|
||||||
Like(pattern) => write!(f, "LIKE '{}'", value::escape_single_quote_string(pattern)),
|
Like(pattern) => write!(f, "LIKE '{}'", value::escape_single_quote_string(pattern)),
|
||||||
ILike(pattern) => write!(f, "ILIKE {}", value::escape_single_quote_string(pattern)),
|
ILike(pattern) => write!(f, "ILIKE {}", value::escape_single_quote_string(pattern)),
|
||||||
Where(expr) => write!(f, "WHERE {expr}"),
|
Where(expr) => write!(f, "WHERE {expr}"),
|
||||||
|
NoKeyword(pattern) => write!(f, "'{}'", value::escape_single_quote_string(pattern)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||||
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
|
||||||
|
pub enum ShowClause {
|
||||||
|
IN,
|
||||||
|
FROM,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for ShowClause {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
use ShowClause::*;
|
||||||
|
match self {
|
||||||
|
FROM => write!(f, "FROM"),
|
||||||
|
IN => write!(f, "IN"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -217,6 +217,7 @@ define_keywords!(
|
||||||
CYCLE,
|
CYCLE,
|
||||||
DATA,
|
DATA,
|
||||||
DATABASE,
|
DATABASE,
|
||||||
|
DATABASES,
|
||||||
DATA_RETENTION_TIME_IN_DAYS,
|
DATA_RETENTION_TIME_IN_DAYS,
|
||||||
DATE,
|
DATE,
|
||||||
DATE32,
|
DATE32,
|
||||||
|
@ -662,6 +663,7 @@ define_keywords!(
|
||||||
SAFE_CAST,
|
SAFE_CAST,
|
||||||
SAVEPOINT,
|
SAVEPOINT,
|
||||||
SCHEMA,
|
SCHEMA,
|
||||||
|
SCHEMAS,
|
||||||
SCOPE,
|
SCOPE,
|
||||||
SCROLL,
|
SCROLL,
|
||||||
SEARCH,
|
SEARCH,
|
||||||
|
@ -822,6 +824,7 @@ define_keywords!(
|
||||||
VERSION,
|
VERSION,
|
||||||
VERSIONING,
|
VERSIONING,
|
||||||
VIEW,
|
VIEW,
|
||||||
|
VIEWS,
|
||||||
VIRTUAL,
|
VIRTUAL,
|
||||||
VOLATILE,
|
VOLATILE,
|
||||||
WAREHOUSE,
|
WAREHOUSE,
|
||||||
|
|
|
@ -9579,6 +9579,10 @@ impl<'a> Parser<'a> {
|
||||||
Ok(self.parse_show_columns(extended, full)?)
|
Ok(self.parse_show_columns(extended, full)?)
|
||||||
} else if self.parse_keyword(Keyword::TABLES) {
|
} else if self.parse_keyword(Keyword::TABLES) {
|
||||||
Ok(self.parse_show_tables(extended, full)?)
|
Ok(self.parse_show_tables(extended, full)?)
|
||||||
|
} else if self.parse_keywords(&[Keyword::MATERIALIZED, Keyword::VIEWS]) {
|
||||||
|
Ok(self.parse_show_views(true)?)
|
||||||
|
} else if self.parse_keyword(Keyword::VIEWS) {
|
||||||
|
Ok(self.parse_show_views(false)?)
|
||||||
} else if self.parse_keyword(Keyword::FUNCTIONS) {
|
} else if self.parse_keyword(Keyword::FUNCTIONS) {
|
||||||
Ok(self.parse_show_functions()?)
|
Ok(self.parse_show_functions()?)
|
||||||
} else if extended || full {
|
} else if extended || full {
|
||||||
|
@ -9605,6 +9609,10 @@ impl<'a> Parser<'a> {
|
||||||
session,
|
session,
|
||||||
global,
|
global,
|
||||||
})
|
})
|
||||||
|
} else if self.parse_keyword(Keyword::DATABASES) {
|
||||||
|
self.parse_show_databases()
|
||||||
|
} else if self.parse_keyword(Keyword::SCHEMAS) {
|
||||||
|
self.parse_show_schemas()
|
||||||
} else {
|
} else {
|
||||||
Ok(Statement::ShowVariable {
|
Ok(Statement::ShowVariable {
|
||||||
variable: self.parse_identifiers()?,
|
variable: self.parse_identifiers()?,
|
||||||
|
@ -9612,6 +9620,18 @@ impl<'a> Parser<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn parse_show_databases(&mut self) -> Result<Statement, ParserError> {
|
||||||
|
Ok(Statement::ShowDatabases {
|
||||||
|
filter: self.parse_show_statement_filter()?,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_show_schemas(&mut self) -> Result<Statement, ParserError> {
|
||||||
|
Ok(Statement::ShowSchemas {
|
||||||
|
filter: self.parse_show_statement_filter()?,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
pub fn parse_show_create(&mut self) -> Result<Statement, ParserError> {
|
pub fn parse_show_create(&mut self) -> Result<Statement, ParserError> {
|
||||||
let obj_type = match self.expect_one_of_keywords(&[
|
let obj_type = match self.expect_one_of_keywords(&[
|
||||||
Keyword::TABLE,
|
Keyword::TABLE,
|
||||||
|
@ -9667,14 +9687,31 @@ impl<'a> Parser<'a> {
|
||||||
extended: bool,
|
extended: bool,
|
||||||
full: bool,
|
full: bool,
|
||||||
) -> Result<Statement, ParserError> {
|
) -> Result<Statement, ParserError> {
|
||||||
let db_name = match self.parse_one_of_keywords(&[Keyword::FROM, Keyword::IN]) {
|
let (clause, db_name) = match self.parse_one_of_keywords(&[Keyword::FROM, Keyword::IN]) {
|
||||||
Some(_) => Some(self.parse_identifier(false)?),
|
Some(Keyword::FROM) => (Some(ShowClause::FROM), Some(self.parse_identifier(false)?)),
|
||||||
None => None,
|
Some(Keyword::IN) => (Some(ShowClause::IN), Some(self.parse_identifier(false)?)),
|
||||||
|
_ => (None, None),
|
||||||
};
|
};
|
||||||
let filter = self.parse_show_statement_filter()?;
|
let filter = self.parse_show_statement_filter()?;
|
||||||
Ok(Statement::ShowTables {
|
Ok(Statement::ShowTables {
|
||||||
extended,
|
extended,
|
||||||
full,
|
full,
|
||||||
|
clause,
|
||||||
|
db_name,
|
||||||
|
filter,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_show_views(&mut self, materialized: bool) -> Result<Statement, ParserError> {
|
||||||
|
let (clause, db_name) = match self.parse_one_of_keywords(&[Keyword::FROM, Keyword::IN]) {
|
||||||
|
Some(Keyword::FROM) => (Some(ShowClause::FROM), Some(self.parse_identifier(false)?)),
|
||||||
|
Some(Keyword::IN) => (Some(ShowClause::IN), Some(self.parse_identifier(false)?)),
|
||||||
|
_ => (None, None),
|
||||||
|
};
|
||||||
|
let filter = self.parse_show_statement_filter()?;
|
||||||
|
Ok(Statement::ShowViews {
|
||||||
|
materialized,
|
||||||
|
clause,
|
||||||
db_name,
|
db_name,
|
||||||
filter,
|
filter,
|
||||||
})
|
})
|
||||||
|
@ -9704,7 +9741,12 @@ impl<'a> Parser<'a> {
|
||||||
} else if self.parse_keyword(Keyword::WHERE) {
|
} else if self.parse_keyword(Keyword::WHERE) {
|
||||||
Ok(Some(ShowStatementFilter::Where(self.parse_expr()?)))
|
Ok(Some(ShowStatementFilter::Where(self.parse_expr()?)))
|
||||||
} else {
|
} else {
|
||||||
Ok(None)
|
self.maybe_parse(|parser| -> Result<String, ParserError> {
|
||||||
|
parser.parse_literal_string()
|
||||||
|
})?
|
||||||
|
.map_or(Ok(None), |filter| {
|
||||||
|
Ok(Some(ShowStatementFilter::NoKeyword(filter)))
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11378,3 +11378,24 @@ fn test_try_convert() {
|
||||||
all_dialects_where(|d| d.supports_try_convert() && !d.convert_type_before_value());
|
all_dialects_where(|d| d.supports_try_convert() && !d.convert_type_before_value());
|
||||||
dialects.verified_expr("TRY_CONVERT('foo', VARCHAR(MAX))");
|
dialects.verified_expr("TRY_CONVERT('foo', VARCHAR(MAX))");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_show_dbs_schemas_tables_views() {
|
||||||
|
verified_stmt("SHOW DATABASES");
|
||||||
|
verified_stmt("SHOW DATABASES LIKE '%abc'");
|
||||||
|
verified_stmt("SHOW SCHEMAS");
|
||||||
|
verified_stmt("SHOW SCHEMAS LIKE '%abc'");
|
||||||
|
verified_stmt("SHOW TABLES");
|
||||||
|
verified_stmt("SHOW TABLES IN db1");
|
||||||
|
verified_stmt("SHOW TABLES IN db1 'abc'");
|
||||||
|
verified_stmt("SHOW VIEWS");
|
||||||
|
verified_stmt("SHOW VIEWS IN db1");
|
||||||
|
verified_stmt("SHOW VIEWS IN db1 'abc'");
|
||||||
|
verified_stmt("SHOW VIEWS FROM db1");
|
||||||
|
verified_stmt("SHOW VIEWS FROM db1 'abc'");
|
||||||
|
verified_stmt("SHOW MATERIALIZED VIEWS");
|
||||||
|
verified_stmt("SHOW MATERIALIZED VIEWS IN db1");
|
||||||
|
verified_stmt("SHOW MATERIALIZED VIEWS IN db1 'abc'");
|
||||||
|
verified_stmt("SHOW MATERIALIZED VIEWS FROM db1");
|
||||||
|
verified_stmt("SHOW MATERIALIZED VIEWS FROM db1 'abc'");
|
||||||
|
}
|
||||||
|
|
|
@ -329,6 +329,7 @@ fn parse_show_tables() {
|
||||||
Statement::ShowTables {
|
Statement::ShowTables {
|
||||||
extended: false,
|
extended: false,
|
||||||
full: false,
|
full: false,
|
||||||
|
clause: None,
|
||||||
db_name: None,
|
db_name: None,
|
||||||
filter: None,
|
filter: None,
|
||||||
}
|
}
|
||||||
|
@ -338,6 +339,7 @@ fn parse_show_tables() {
|
||||||
Statement::ShowTables {
|
Statement::ShowTables {
|
||||||
extended: false,
|
extended: false,
|
||||||
full: false,
|
full: false,
|
||||||
|
clause: Some(ShowClause::FROM),
|
||||||
db_name: Some(Ident::new("mydb")),
|
db_name: Some(Ident::new("mydb")),
|
||||||
filter: None,
|
filter: None,
|
||||||
}
|
}
|
||||||
|
@ -347,6 +349,7 @@ fn parse_show_tables() {
|
||||||
Statement::ShowTables {
|
Statement::ShowTables {
|
||||||
extended: true,
|
extended: true,
|
||||||
full: false,
|
full: false,
|
||||||
|
clause: None,
|
||||||
db_name: None,
|
db_name: None,
|
||||||
filter: None,
|
filter: None,
|
||||||
}
|
}
|
||||||
|
@ -356,6 +359,7 @@ fn parse_show_tables() {
|
||||||
Statement::ShowTables {
|
Statement::ShowTables {
|
||||||
extended: false,
|
extended: false,
|
||||||
full: true,
|
full: true,
|
||||||
|
clause: None,
|
||||||
db_name: None,
|
db_name: None,
|
||||||
filter: None,
|
filter: None,
|
||||||
}
|
}
|
||||||
|
@ -365,6 +369,7 @@ fn parse_show_tables() {
|
||||||
Statement::ShowTables {
|
Statement::ShowTables {
|
||||||
extended: false,
|
extended: false,
|
||||||
full: false,
|
full: false,
|
||||||
|
clause: None,
|
||||||
db_name: None,
|
db_name: None,
|
||||||
filter: Some(ShowStatementFilter::Like("pattern".into())),
|
filter: Some(ShowStatementFilter::Like("pattern".into())),
|
||||||
}
|
}
|
||||||
|
@ -374,13 +379,15 @@ fn parse_show_tables() {
|
||||||
Statement::ShowTables {
|
Statement::ShowTables {
|
||||||
extended: false,
|
extended: false,
|
||||||
full: false,
|
full: false,
|
||||||
|
clause: None,
|
||||||
db_name: None,
|
db_name: None,
|
||||||
filter: Some(ShowStatementFilter::Where(
|
filter: Some(ShowStatementFilter::Where(
|
||||||
mysql_and_generic().verified_expr("1 = 2")
|
mysql_and_generic().verified_expr("1 = 2")
|
||||||
)),
|
)),
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
mysql_and_generic().one_statement_parses_to("SHOW TABLES IN mydb", "SHOW TABLES FROM mydb");
|
mysql_and_generic().verified_stmt("SHOW TABLES IN mydb");
|
||||||
|
mysql_and_generic().verified_stmt("SHOW TABLES FROM mydb");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue