diff --git a/src/operator/src/statement.rs b/src/operator/src/statement.rs index f2d371b6d2..adac0a0f40 100644 --- a/src/operator/src/statement.rs +++ b/src/operator/src/statement.rs @@ -43,6 +43,7 @@ use snafu::{OptionExt, ResultExt}; use sql::statements::copy::{CopyDatabaseArgument, CopyTable, CopyTableArgument}; use sql::statements::statement::Statement; use sql::statements::OptionMap; +use sql::util::format_raw_object_name; use sqlparser::ast::ObjectName; use table::engine::TableReference; use table::requests::{CopyDatabaseRequest, CopyDirection, CopyTableRequest}; @@ -162,7 +163,7 @@ impl StatementExecutor { Statement::CreateDatabase(stmt) => { self.create_database( query_ctx.current_catalog(), - &stmt.name.to_string(), + &format_raw_object_name(&stmt.name), stmt.if_not_exists, ) .await diff --git a/src/operator/src/statement/describe.rs b/src/operator/src/statement/describe.rs index 0c19dc15b5..452388b701 100644 --- a/src/operator/src/statement/describe.rs +++ b/src/operator/src/statement/describe.rs @@ -17,6 +17,7 @@ use common_query::Output; use session::context::QueryContextRef; use snafu::{OptionExt, ResultExt}; use sql::statements::describe::DescribeTable; +use sql::util::format_raw_object_name; use crate::error::{ CatalogSnafu, DescribeStatementSnafu, ExternalSnafu, Result, TableNotFoundSnafu, @@ -40,7 +41,7 @@ impl StatementExecutor { .await .context(CatalogSnafu)? .with_context(|| TableNotFoundSnafu { - table_name: stmt.name().to_string(), + table_name: format_raw_object_name(stmt.name()), })?; query::sql::describe_table(table).context(DescribeStatementSnafu) diff --git a/src/sql/src/statements/describe.rs b/src/sql/src/statements/describe.rs index ee86509305..527777c32c 100644 --- a/src/sql/src/statements/describe.rs +++ b/src/sql/src/statements/describe.rs @@ -39,6 +39,7 @@ mod tests { use crate::dialect::GreptimeDbDialect; use crate::parser::ParserContext; use crate::statements::statement::Statement; + use crate::util::format_raw_object_name; #[test] pub fn test_describe_table() { @@ -49,7 +50,7 @@ mod tests { assert_matches!(&stmts[0], Statement::DescribeTable { .. }); match &stmts[0] { Statement::DescribeTable(show) => { - assert_eq!(show.name.to_string(), "test"); + assert_eq!(format_raw_object_name(&show.name), "test"); } _ => { unreachable!(); @@ -66,7 +67,7 @@ mod tests { assert_matches!(&stmts[0], Statement::DescribeTable { .. }); match &stmts[0] { Statement::DescribeTable(show) => { - assert_eq!(show.name.to_string(), "test_schema.test"); + assert_eq!(format_raw_object_name(&show.name), "test_schema.test"); } _ => { unreachable!(); @@ -83,7 +84,10 @@ mod tests { assert_matches!(&stmts[0], Statement::DescribeTable { .. }); match &stmts[0] { Statement::DescribeTable(show) => { - assert_eq!(show.name.to_string(), "test_catalog.test_schema.test"); + assert_eq!( + format_raw_object_name(&show.name), + "test_catalog.test_schema.test" + ); } _ => { unreachable!(); diff --git a/src/sql/src/util.rs b/src/sql/src/util.rs index f6e98a8648..3d29af6ad8 100644 --- a/src/sql/src/util.rs +++ b/src/sql/src/util.rs @@ -13,10 +13,11 @@ // limitations under the License. use std::collections::HashMap; +use std::fmt::{Display, Formatter}; use std::sync::LazyLock; use regex::Regex; -use sqlparser::ast::{SqlOption, Value}; +use sqlparser::ast::{ObjectName, SqlOption, Value}; static SQL_SECRET_PATTERNS: LazyLock> = LazyLock::new(|| { vec![ @@ -25,6 +26,27 @@ static SQL_SECRET_PATTERNS: LazyLock> = LazyLock::new(|| { ] }); +/// Format an [ObjectName] without any quote of its idents. +pub fn format_raw_object_name(name: &ObjectName) -> String { + struct Inner<'a> { + name: &'a ObjectName, + } + + impl<'a> Display for Inner<'a> { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + let mut delim = ""; + for ident in self.name.0.iter() { + write!(f, "{delim}")?; + delim = "."; + write!(f, "{}", ident.value)?; + } + Ok(()) + } + } + + format!("{}", Inner { name }) +} + pub fn parse_option_string(value: Value) -> Option { match value { Value::SingleQuotedString(v) | Value::DoubleQuotedString(v) => Some(v), diff --git a/tests/cases/standalone/common/create/create_database.result b/tests/cases/standalone/common/create/create_database.result new file mode 100644 index 0000000000..c684869e9d --- /dev/null +++ b/tests/cases/standalone/common/create/create_database.result @@ -0,0 +1,19 @@ +create database illegal-database; + +Error: 1001(Unsupported), SQL statement is not supported: create database illegal-database;, keyword: - + +create database 'illegal-database'; + +Affected Rows: 1 + +show databases; + ++--------------------+ +| Schemas | ++--------------------+ +| illegal-database | +| information_schema | +| public | +| test_public_schema | ++--------------------+ + diff --git a/tests/cases/standalone/common/create/create_database.sql b/tests/cases/standalone/common/create/create_database.sql new file mode 100644 index 0000000000..90f5de9edc --- /dev/null +++ b/tests/cases/standalone/common/create/create_database.sql @@ -0,0 +1,5 @@ +create database illegal-database; + +create database 'illegal-database'; + +show databases; diff --git a/tests/cases/standalone/common/show/show_databases_tables.result b/tests/cases/standalone/common/show/show_databases_tables.result index ec9f502306..c4e4f40260 100644 --- a/tests/cases/standalone/common/show/show_databases_tables.result +++ b/tests/cases/standalone/common/show/show_databases_tables.result @@ -3,6 +3,7 @@ show databases; +-----------------------+ | Schemas | +-----------------------+ +| illegal-database | | information_schema | | public | | test_public_schema |