Skip to content

Commit

Permalink
feat: add show create table for pg in parser
Browse files Browse the repository at this point in the history
  • Loading branch information
sunng87 committed Dec 10, 2024
1 parent 3133f3f commit 5ebbe1a
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 7 deletions.
13 changes: 11 additions & 2 deletions src/operator/src/statement.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ use set::set_query_timeout;
use snafu::{ensure, OptionExt, ResultExt};
use sql::statements::copy::{CopyDatabase, CopyDatabaseArgument, CopyTable, CopyTableArgument};
use sql::statements::set_variables::SetVariables;
use sql::statements::show::ShowCreateTableVariant;
use sql::statements::statement::Statement;
use sql::statements::OptionMap;
use sql::util::format_raw_object_name;
Expand Down Expand Up @@ -317,8 +318,16 @@ impl StatementExecutor {
.context(TableNotFoundSnafu { table_name: &table })?;
let table_name = TableName::new(catalog, schema, table);

self.show_create_table(table_name, table_ref, query_ctx)
.await
match show.variant {
ShowCreateTableVariant::Original => {
self.show_create_table(table_name, table_ref, query_ctx)
.await
}
ShowCreateTableVariant::PostgresForeignTable => {
self.show_create_table_for_pg(table_name, table_ref, query_ctx)
.await
}
}
}
Statement::ShowCreateFlow(show) => self.show_create_flow(show, query_ctx).await,
Statement::ShowCreateView(show) => self.show_create_view(show, query_ctx).await,
Expand Down
31 changes: 31 additions & 0 deletions src/operator/src/statement/show.rs
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,37 @@ impl StatementExecutor {
.context(ExecuteStatementSnafu)
}

#[tracing::instrument(skip_all)]
pub async fn show_create_table_for_pg(
&self,
table_name: TableName,
table: TableRef,
query_ctx: QueryContextRef,
) -> Result<Output> {
let table_info = table.table_info();
if table_info.table_type != TableType::Base {
return error::ShowCreateTableBaseOnlySnafu {
table_name: table_name.to_string(),
table_type: table_info.table_type,
}
.fail();
}

let schema_options = self
.table_metadata_manager
.schema_manager()
.get(SchemaNameKey {
catalog: &table_name.catalog_name,
schema: &table_name.schema_name,
})
.await
.context(TableMetadataManagerSnafu)?
.map(|v| v.into_inner());

query::sql::show_create_table(table, schema_options, None, query_ctx)
.context(ExecuteStatementSnafu)
}

#[tracing::instrument(skip_all)]
pub async fn show_create_view(
&self,
Expand Down
20 changes: 16 additions & 4 deletions src/sql/src/parsers/show_parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ use crate::error::{
};
use crate::parser::ParserContext;
use crate::statements::show::{
ShowColumns, ShowCreateDatabase, ShowCreateFlow, ShowCreateTable, ShowCreateView,
ShowDatabases, ShowFlows, ShowIndex, ShowKind, ShowStatus, ShowTableStatus, ShowTables,
ShowVariables, ShowViews,
ShowColumns, ShowCreateDatabase, ShowCreateFlow, ShowCreateTable, ShowCreateTableVariant,
ShowCreateView, ShowDatabases, ShowFlows, ShowIndex, ShowKind, ShowStatus, ShowTableStatus,
ShowTables, ShowVariables, ShowViews,
};
use crate::statements::statement::Statement;

Expand Down Expand Up @@ -146,7 +146,19 @@ impl ParserContext<'_> {
name: table_name.to_string(),
}
);
Ok(Statement::ShowCreateTable(ShowCreateTable { table_name }))
let mut variant = ShowCreateTableVariant::Original;
if self.consume_token("FOR") {
if self.consume_token("POSTGRES_FOREIGN_TABLE") {
variant = ShowCreateTableVariant::PostgresForeignTable;
} else {
self.unsupported(self.peek_token_as_string())?;
}
}

Ok(Statement::ShowCreateTable(ShowCreateTable {
table_name,
variant,
}))
}

fn parse_show_create_flow(&mut self) -> Result<Statement> {
Expand Down
46 changes: 45 additions & 1 deletion src/sql/src/statements/show.rs
Original file line number Diff line number Diff line change
Expand Up @@ -178,12 +178,26 @@ impl Display for ShowCreateDatabase {
#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut)]
pub struct ShowCreateTable {
pub table_name: ObjectName,
pub variant: ShowCreateTableVariant,
}

/// Variant of a show create table
#[derive(Default, Debug, Clone, PartialEq, Eq, Visit, VisitMut)]
pub enum ShowCreateTableVariant {
#[default]
Original,
PostgresForeignTable,
}

impl Display for ShowCreateTable {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let table_name = &self.table_name;
write!(f, r#"SHOW CREATE TABLE {table_name}"#)
write!(f, r#"SHOW CREATE TABLE {table_name}"#)?;
if let ShowCreateTableVariant::PostgresForeignTable = self.variant {
write!(f, " FOR POSTGRES_FOREIGN_TABLE")?;
}

Ok(())
}
}

Expand Down Expand Up @@ -343,12 +357,31 @@ mod tests {
Statement::ShowCreateTable(show) => {
let table_name = show.table_name.to_string();
assert_eq!(table_name, "test");
assert_eq!(show.variant, ShowCreateTableVariant::Original);
}
_ => {
unreachable!();
}
}

let sql = "SHOW CREATE TABLE test FOR POSTGRES_FOREIGN_TABLE";
let stmts: Vec<Statement> =
ParserContext::create_with_dialect(sql, &GreptimeDbDialect {}, ParseOptions::default())
.unwrap();
assert_eq!(1, stmts.len());
assert_matches!(&stmts[0], Statement::ShowCreateTable { .. });
match &stmts[0] {
Statement::ShowCreateTable(show) => {
let table_name = show.table_name.to_string();
assert_eq!(table_name, "test");
assert_eq!(show.variant, ShowCreateTableVariant::PostgresForeignTable);
}
_ => {
unreachable!();
}
}
}

#[test]
pub fn test_show_create_missing_table_name() {
let sql = "SHOW CREATE TABLE";
Expand All @@ -360,6 +393,17 @@ mod tests {
.is_err());
}

#[test]
pub fn test_show_create_unknown_for() {
let sql = "SHOW CREATE TABLE t FOR UNKNOWN";
assert!(ParserContext::create_with_dialect(
sql,
&GreptimeDbDialect {},
ParseOptions::default()
)
.is_err());
}

#[test]
pub fn test_show_create_flow() {
let sql = "SHOW CREATE FLOW test";
Expand Down

0 comments on commit 5ebbe1a

Please sign in to comment.