Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: support show views statement #4360

Merged
merged 1 commit into from
Jul 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/frontend/src/instance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -506,6 +506,9 @@ pub fn check_permission(
Statement::ShowIndex(stmt) => {
validate_db_permission!(stmt, query_ctx);
}
Statement::ShowViews(stmt) => {
validate_db_permission!(stmt, query_ctx);
}
Statement::ShowStatus(_stmt) => {}
Statement::DescribeTable(stmt) => {
validate_param(stmt.name(), query_ctx)?;
Expand Down
2 changes: 2 additions & 0 deletions src/operator/src/statement.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,8 @@ impl StatementExecutor {

Statement::ShowCharset(kind) => self.show_charset(kind, query_ctx).await,

Statement::ShowViews(stmt) => self.show_views(stmt, query_ctx).await,

Statement::Copy(sql::statements::copy::Copy::CopyTable(stmt)) => {
let req = to_copy_table_request(stmt, query_ctx.clone())?;
match req.direction {
Expand Down
13 changes: 12 additions & 1 deletion src/operator/src/statement/show.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ use sql::ast::Ident;
use sql::statements::create::Partitions;
use sql::statements::show::{
ShowColumns, ShowCreateFlow, ShowCreateView, ShowDatabases, ShowIndex, ShowKind,
ShowTableStatus, ShowTables, ShowVariables,
ShowTableStatus, ShowTables, ShowVariables, ShowViews,
};
use table::metadata::TableType;
use table::table_name::TableName;
Expand Down Expand Up @@ -152,6 +152,17 @@ impl StatementExecutor {
.context(error::ExecuteStatementSnafu)
}

#[tracing::instrument(skip_all)]
pub(super) async fn show_views(
&self,
stmt: ShowViews,
query_ctx: QueryContextRef,
) -> Result<Output> {
query::sql::show_views(stmt, &self.query_engine, &self.catalog_manager, query_ctx)
.await
.context(ExecuteStatementSnafu)
}

#[tracing::instrument(skip_all)]
pub async fn show_create_flow(
&self,
Expand Down
40 changes: 39 additions & 1 deletion src/query/src/sql.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ use std::sync::Arc;

use catalog::information_schema::{
columns, key_column_usage, schemata, tables, CHARACTER_SETS, COLLATIONS, COLUMNS,
KEY_COLUMN_USAGE, SCHEMATA, TABLES,
KEY_COLUMN_USAGE, SCHEMATA, TABLES, VIEWS,
};
use catalog::CatalogManagerRef;
use common_catalog::consts::{
Expand Down Expand Up @@ -55,6 +55,7 @@ use sql::parser::ParserContext;
use sql::statements::create::{CreateFlow, CreateView, Partitions};
use sql::statements::show::{
ShowColumns, ShowDatabases, ShowIndex, ShowKind, ShowTableStatus, ShowTables, ShowVariables,
ShowViews,
};
use sql::statements::statement::Statement;
use sqlparser::ast::ObjectName;
Expand All @@ -69,6 +70,7 @@ use crate::QueryEngineRef;
const SCHEMAS_COLUMN: &str = "Database";
const OPTIONS_COLUMN: &str = "Options";
const TABLES_COLUMN: &str = "Tables";
const VIEWS_COLUMN: &str = "Views";
const FIELD_COLUMN: &str = "Field";
const TABLE_TYPE_COLUMN: &str = "Table_type";
const COLUMN_NAME_COLUMN: &str = "Column";
Expand Down Expand Up @@ -725,6 +727,42 @@ pub fn show_create_view(
Ok(Output::new_with_record_batches(records))
}

/// Execute [`ShowViews`] statement and return the [`Output`] if success.
killme2008 marked this conversation as resolved.
Show resolved Hide resolved
pub async fn show_views(
stmt: ShowViews,
query_engine: &QueryEngineRef,
catalog_manager: &CatalogManagerRef,
query_ctx: QueryContextRef,
) -> Result<Output> {
let schema_name = if let Some(database) = stmt.database {
database
} else {
query_ctx.current_schema()
};

let projects = vec![(tables::TABLE_NAME, VIEWS_COLUMN)];
let filters = vec![
col(tables::TABLE_SCHEMA).eq(lit(schema_name.clone())),
col(tables::TABLE_CATALOG).eq(lit(query_ctx.current_catalog())),
];
let like_field = Some(tables::TABLE_NAME);
let sort = vec![col(tables::TABLE_NAME).sort(true, true)];

query_from_information_schema_table(
query_engine,
catalog_manager,
query_ctx,
VIEWS,
vec![],
projects,
filters,
like_field,
sort,
stmt.kind,
)
.await
}

pub fn show_create_flow(
flow_name: ObjectName,
flow_val: FlowInfoValue,
Expand Down
60 changes: 59 additions & 1 deletion src/sql/src/parsers/show_parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ use crate::error::{
use crate::parser::ParserContext;
use crate::statements::show::{
ShowColumns, ShowCreateFlow, ShowCreateTable, ShowCreateView, ShowDatabases, ShowIndex,
ShowKind, ShowStatus, ShowTableStatus, ShowTables, ShowVariables,
ShowKind, ShowStatus, ShowTableStatus, ShowTables, ShowVariables, ShowViews,
};
use crate::statements::statement::Statement;

Expand All @@ -44,6 +44,8 @@ impl<'a> ParserContext<'a> {
} else {
self.unsupported(self.peek_token_as_string())
}
} else if self.consume_token("VIEWS") {
self.parse_show_views()
} else if self.matches_keyword(Keyword::CHARSET) {
self.parser.next_token();
Ok(Statement::ShowCharset(self.parse_show_kind()?))
Expand Down Expand Up @@ -430,6 +432,28 @@ impl<'a> ParserContext<'a> {
_ => self.unsupported(self.peek_token_as_string()),
}
}

fn parse_show_views(&mut self) -> Result<Statement> {
let database = match self.parser.peek_token().token {
Token::EOF | Token::SemiColon => {
return Ok(Statement::ShowViews(ShowViews {
kind: ShowKind::All,
database: None,
}));
}

// SHOW VIEWS [in | FROM] [DATABASE]
Token::Word(w) => match w.keyword {
Keyword::IN | Keyword::FROM => self.parse_db_name()?,
_ => None,
},
_ => None,
};

let kind = self.parse_show_kind()?;

Ok(Statement::ShowViews(ShowViews { kind, database }))
}
}

#[cfg(test)]
Expand Down Expand Up @@ -942,4 +966,38 @@ mod tests {
);
assert_eq!(sql, stmts[0].to_string());
}

#[test]
pub fn test_show_views() {
let sql = "SHOW VIEWS";
let result =
ParserContext::create_with_dialect(sql, &GreptimeDbDialect {}, ParseOptions::default());
let stmts = result.unwrap();
assert_eq!(1, stmts.len());
assert_eq!(
stmts[0],
Statement::ShowViews(ShowViews {
kind: ShowKind::All,
database: None,
})
);
assert_eq!(sql, stmts[0].to_string());
}

#[test]
pub fn test_show_views_in_db() {
let sql = "SHOW VIEWS IN d1";
let result =
ParserContext::create_with_dialect(sql, &GreptimeDbDialect {}, ParseOptions::default());
let stmts = result.unwrap();
assert_eq!(1, stmts.len());
assert_eq!(
stmts[0],
Statement::ShowViews(ShowViews {
kind: ShowKind::All,
database: Some("d1".to_string()),
})
);
assert_eq!(sql, stmts[0].to_string());
}
}
62 changes: 62 additions & 0 deletions src/sql/src/statements/show.rs
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,25 @@ impl Display for ShowCreateView {
}
}

/// SQL structure for `SHOW VIEWS`.
#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut)]
pub struct ShowViews {
pub kind: ShowKind,
pub database: Option<String>,
}

impl Display for ShowViews {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "SHOW VIEWS")?;
if let Some(database) = &self.database {
write!(f, " IN {database}")?;
}
format_kind!(self, f);

Ok(())
}
}

/// SQL structure for `SHOW VARIABLES xxx`.
#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut)]
pub struct ShowVariables {
Expand Down Expand Up @@ -473,6 +492,49 @@ SHOW FULL TABLES"#,
}
}

#[test]
fn test_display_show_views() {
let sql = r"show views in d1;";
let stmts: Vec<Statement> =
ParserContext::create_with_dialect(sql, &GreptimeDbDialect {}, ParseOptions::default())
.unwrap();
assert_eq!(1, stmts.len());
assert_matches!(&stmts[0], Statement::ShowViews { .. });
match &stmts[0] {
Statement::ShowViews(show) => {
let new_sql = format!("\n{}", show);
assert_eq!(
r#"
SHOW VIEWS IN d1"#,
&new_sql
);
}
_ => {
unreachable!();
}
}

let sql = r"show views;";
let stmts: Vec<Statement> =
ParserContext::create_with_dialect(sql, &GreptimeDbDialect {}, ParseOptions::default())
.unwrap();
assert_eq!(1, stmts.len());
assert_matches!(&stmts[0], Statement::ShowViews { .. });
match &stmts[0] {
Statement::ShowViews(show) => {
let new_sql = format!("\n{}", show);
assert_eq!(
r#"
SHOW VIEWS"#,
&new_sql
);
}
_ => {
unreachable!();
}
}
}

#[test]
fn test_display_show_databases() {
let sql = r"show databases;";
Expand Down
5 changes: 4 additions & 1 deletion src/sql/src/statements/statement.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ use crate::statements::query::Query;
use crate::statements::set_variables::SetVariables;
use crate::statements::show::{
ShowColumns, ShowCreateFlow, ShowCreateTable, ShowCreateView, ShowDatabases, ShowIndex,
ShowKind, ShowStatus, ShowTableStatus, ShowTables, ShowVariables,
ShowKind, ShowStatus, ShowTableStatus, ShowTables, ShowVariables, ShowViews,
};
use crate::statements::tql::Tql;
use crate::statements::truncate::TruncateTable;
Expand Down Expand Up @@ -91,6 +91,8 @@ pub enum Statement {
ShowCreateView(ShowCreateView),
// SHOW STATUS
ShowStatus(ShowStatus),
// SHOW VIEWS
ShowViews(ShowViews),
// DESCRIBE TABLE
DescribeTable(DescribeTable),
// EXPLAIN QUERY
Expand Down Expand Up @@ -132,6 +134,7 @@ impl Display for Statement {
Statement::ShowCreateTable(s) => s.fmt(f),
Statement::ShowCreateFlow(s) => s.fmt(f),
Statement::ShowCreateView(s) => s.fmt(f),
Statement::ShowViews(s) => s.fmt(f),
Statement::ShowStatus(s) => s.fmt(f),
Statement::DescribeTable(s) => s.fmt(f),
Statement::Explain(s) => s.fmt(f),
Expand Down
13 changes: 13 additions & 0 deletions tests/cases/standalone/common/view/view.result
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,14 @@ CREATE VIEW v1 AS SELECT * FROM dontexist;

Error: 3000(PlanQuery), Failed to plan SQL: Error during planning: Table not found: greptime.public.dontexist

SHOW VIEWS;

+-------+
| Views |
+-------+
| v1 |
+-------+

DROP VIEW v1;

Affected Rows: 0
Expand Down Expand Up @@ -81,3 +89,8 @@ SHOW TABLES;
| numbers |
+---------+

SHOW VIEWS;

++
++

4 changes: 4 additions & 0 deletions tests/cases/standalone/common/view/view.sql
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ INSERT INTO v1 VALUES (1);

CREATE VIEW v1 AS SELECT * FROM dontexist;

SHOW VIEWS;

DROP VIEW v1;

SELECT * FROM v1;
Expand All @@ -42,3 +44,5 @@ DROP VIEW IF EXISTS v2;
DROP TABLE t1;

SHOW TABLES;

SHOW VIEWS;