From e3fef6da12424d6dc4d6bb6c0b69e484d3aa4192 Mon Sep 17 00:00:00 2001 From: taichong Date: Thu, 14 Apr 2022 15:49:11 +0800 Subject: [PATCH] Support Keyword `DATABASE` synonym `SCHEMA` Link to ISSUE #4854 --- .../00-ddl/10-database/ddl-create-database.md | 4 +++- .../00-ddl/10-database/ddl-drop-database.md | 4 +++- .../30-sql/40-show/show-create-database.md | 24 +++++++++++++++++++ query/src/sql/sql_parser.rs | 6 ++--- query/tests/it/sql/parsers/parser_database.rs | 13 ++++++++++ query/tests/it/sql/parsers/parser_show.rs | 11 +++++++++ query/tests/it/sql/sql_parser.rs | 17 +++++++++++++ .../05_ddl/05_0001_ddl_create_database.result | 1 + .../05_ddl/05_0001_ddl_create_database.sql | 16 +++++++++++++ .../05_ddl/05_0001_ddl_drop_database.sql | 9 +++++++ .../06_show/06_0000_show_databases.result | 3 +++ .../06_show/06_0000_show_databases.sql | 1 + .../06_0002_show_create_database.result | 3 +++ .../06_show/06_0002_show_create_database.sql | 8 +++++++ 14 files changed, 115 insertions(+), 5 deletions(-) create mode 100644 docs/doc/30-reference/30-sql/40-show/show-create-database.md diff --git a/docs/doc/30-reference/30-sql/00-ddl/10-database/ddl-create-database.md b/docs/doc/30-reference/30-sql/00-ddl/10-database/ddl-create-database.md index 740163e9ed43b..e075097f98309 100644 --- a/docs/doc/30-reference/30-sql/00-ddl/10-database/ddl-create-database.md +++ b/docs/doc/30-reference/30-sql/00-ddl/10-database/ddl-create-database.md @@ -7,9 +7,11 @@ Create a database. ## Syntax ```sql -CREATE DATABASE +CREATE { DATABASE | SCHEMA } [IF NOT EXISTS] ``` +`CREATE SCHEMA` is a synonym for `CREATE DATABASE`. + ## Examples ```sql title='msyql>' diff --git a/docs/doc/30-reference/30-sql/00-ddl/10-database/ddl-drop-database.md b/docs/doc/30-reference/30-sql/00-ddl/10-database/ddl-drop-database.md index 9f2dab59d6120..3dd21301f0286 100644 --- a/docs/doc/30-reference/30-sql/00-ddl/10-database/ddl-drop-database.md +++ b/docs/doc/30-reference/30-sql/00-ddl/10-database/ddl-drop-database.md @@ -7,9 +7,11 @@ Drop a database. ## Syntax ```sql -DROP DATABASE [IF EXISTS] +DROP { DATABASE | SCHEMA } [IF EXISTS] ``` +`DROP SCHEMA` is a synonym for `DROP DATABASE`. + ## Examples ```sql title='mysql>' diff --git a/docs/doc/30-reference/30-sql/40-show/show-create-database.md b/docs/doc/30-reference/30-sql/40-show/show-create-database.md new file mode 100644 index 0000000000000..2dbf7e790477e --- /dev/null +++ b/docs/doc/30-reference/30-sql/40-show/show-create-database.md @@ -0,0 +1,24 @@ +--- +title: SHOW CREATE DATABASE +--- + +Shows the CREATE DATABASE statement that creates the named database. + +## Syntax + +``` +SHOW CREATE { DATABASE | SCHEMA } database_name +``` + +`SHOW CREATE SCHEMA` is a synonym for `SHOW CREATE DATABASE`. + +## Examples + +```sql +mysql> SHOW CREATE DATABASE default; ++----------+---------------------------+ +| Database | Create Database | ++----------+---------------------------+ +| default | CREATE DATABASE `default` | ++----------+---------------------------+ +``` diff --git a/query/src/sql/sql_parser.rs b/query/src/sql/sql_parser.rs index f62e90c2bbbe3..c25057685693a 100644 --- a/query/src/sql/sql_parser.rs +++ b/query/src/sql/sql_parser.rs @@ -212,7 +212,7 @@ impl<'a> DfParser<'a> { //TODO:make stage to sql parser keyword match w.keyword { Keyword::TABLE => self.parse_create_table(), - Keyword::DATABASE => self.parse_create_database(), + Keyword::DATABASE | Keyword::SCHEMA => self.parse_create_database(), Keyword::USER => self.parse_create_user(), Keyword::ROLE => self.parse_create_role(), Keyword::FUNCTION => self.parse_create_udf(), @@ -311,7 +311,7 @@ impl<'a> DfParser<'a> { fn parse_drop(&mut self) -> Result, ParserError> { match self.parser.next_token() { Token::Word(w) => match w.keyword { - Keyword::DATABASE => self.parse_drop_database(), + Keyword::DATABASE | Keyword::SCHEMA => self.parse_drop_database(), Keyword::TABLE => self.parse_drop_table(), Keyword::USER => self.parse_drop_user(), Keyword::ROLE => self.parse_drop_role(), @@ -359,7 +359,7 @@ impl<'a> DfParser<'a> { match self.parser.next_token() { Token::Word(w) => match w.keyword { Keyword::TABLE => self.parse_show_create_table(), - Keyword::DATABASE => self.parse_show_create_database(), + Keyword::DATABASE | Keyword::SCHEMA => self.parse_show_create_database(), _ => self.expected("show create statement", Token::Word(w)), }, unexpected => self.expected("show create statement", unexpected), diff --git a/query/tests/it/sql/parsers/parser_database.rs b/query/tests/it/sql/parsers/parser_database.rs index 00be35cde42d4..dd633302059fb 100644 --- a/query/tests/it/sql/parsers/parser_database.rs +++ b/query/tests/it/sql/parsers/parser_database.rs @@ -36,6 +36,7 @@ fn create_database() -> Result<()> { }); expect_parse_ok(sql, expected)?; } + expect_synonym_parse_eq("CREATE DATABASE db1", "CREATE SCHEMA db1")?; { let sql = "CREATE DATABASE db1 engine = github"; @@ -48,6 +49,10 @@ fn create_database() -> Result<()> { }); expect_parse_ok(sql, expected)?; } + expect_synonym_parse_eq( + "CREATE DATABASE db1 engine = github", + "CREATE SCHEMA db1 engine = github", + )?; { let sql = "CREATE DATABASE IF NOT EXISTS db1"; @@ -60,6 +65,10 @@ fn create_database() -> Result<()> { }); expect_parse_ok(sql, expected)?; } + expect_synonym_parse_eq( + "CREATE DATABASE IF NOT EXISTS db1", + "CREATE SCHEMA IF NOT EXISTS db1", + )?; Ok(()) } @@ -74,6 +83,8 @@ fn drop_database() -> Result<()> { }); expect_parse_ok(sql, expected)?; } + expect_synonym_parse_eq("DROP DATABASE db1", "DROP SCHEMA db1")?; + { let sql = "DROP DATABASE IF EXISTS db1"; let expected = DfStatement::DropDatabase(DfDropDatabase { @@ -82,6 +93,7 @@ fn drop_database() -> Result<()> { }); expect_parse_ok(sql, expected)?; } + expect_synonym_parse_eq("DROP DATABASE IF EXISTS db1", "DROP SCHEMA IF EXISTS db1")?; Ok(()) } @@ -94,6 +106,7 @@ fn show_create_database_test() -> Result<()> { name: ObjectName(vec![Ident::new("test")]), }), )?; + expect_synonym_parse_eq("SHOW CREATE DATABASE test", "SHOW CREATE SCHEMA test")?; Ok(()) } diff --git a/query/tests/it/sql/parsers/parser_show.rs b/query/tests/it/sql/parsers/parser_show.rs index 3707de9194a50..743d30ba05053 100644 --- a/query/tests/it/sql/parsers/parser_show.rs +++ b/query/tests/it/sql/parsers/parser_show.rs @@ -238,11 +238,13 @@ fn show_databases_test() -> Result<()> { "SHOW DATABASES", DfStatement::ShowDatabases(DfShowDatabases::create(DfShowKind::All)), )?; + expect_synonym_parse_eq("SHOW DATABASES", "SHOW SCHEMAS")?; expect_parse_ok( "SHOW DATABASES;", DfStatement::ShowDatabases(DfShowDatabases::create(DfShowKind::All)), )?; + expect_synonym_parse_eq("SHOW DATABASES;", "SHOW SCHEMAS;")?; expect_parse_ok( "SHOW DATABASES WHERE Database = 'ss'", @@ -250,6 +252,10 @@ fn show_databases_test() -> Result<()> { parse_sql_to_expr("Database = 'ss'"), ))), )?; + expect_synonym_parse_eq( + "SHOW DATABASES WHERE Database = 'ss'", + "SHOW SCHEMAS WHERE Database = 'ss'", + )?; expect_parse_ok( "SHOW DATABASES WHERE Database Like 'ss%'", @@ -257,6 +263,10 @@ fn show_databases_test() -> Result<()> { parse_sql_to_expr("Database Like 'ss%'"), ))), )?; + expect_synonym_parse_eq( + "SHOW DATABASES WHERE Database Like 'ss%'", + "SHOW SCHEMAS WHERE Database Like 'ss%'", + )?; expect_parse_ok( "SHOW DATABASES LIKE 'ss%'", @@ -264,6 +274,7 @@ fn show_databases_test() -> Result<()> { Ident::with_quote('\'', "ss%"), ))), )?; + expect_synonym_parse_eq("SHOW DATABASES LIKE 'ss%'", "SHOW SCHEMAS LIKE 'ss%'")?; Ok(()) } diff --git a/query/tests/it/sql/sql_parser.rs b/query/tests/it/sql/sql_parser.rs index ceac9c3ed6aee..f72922919cc14 100644 --- a/query/tests/it/sql/sql_parser.rs +++ b/query/tests/it/sql/sql_parser.rs @@ -33,6 +33,23 @@ pub fn expect_parse_ok(sql: &str, expected: DfStatement) -> Result<()> { Ok(()) } +pub fn expect_synonym_parse_eq(sql: &str, sql2: &str) -> Result<()> { + let (statements, _) = DfParser::parse_sql(sql)?; + assert_eq!( + statements.len(), + 1, + "Expected to parse exactly one statement" + ); + let (statements2, _) = DfParser::parse_sql(sql2)?; + assert_eq!( + statements2.len(), + 1, + "Expected to parse exactly one statement" + ); + assert_eq!(statements[0], statements2[0]); + Ok(()) +} + pub fn expect_parse_err(sql: &str, expected: String) -> Result<()> { let result = DfParser::parse_sql(sql); assert!(result.is_err(), "'{}' SHOULD BE '{}'", sql, expected); diff --git a/tests/suites/0_stateless/05_ddl/05_0001_ddl_create_database.result b/tests/suites/0_stateless/05_ddl/05_0001_ddl_create_database.result index d00491fd7e5bb..6ed281c757a96 100644 --- a/tests/suites/0_stateless/05_ddl/05_0001_ddl_create_database.result +++ b/tests/suites/0_stateless/05_ddl/05_0001_ddl_create_database.result @@ -1 +1,2 @@ 1 +1 diff --git a/tests/suites/0_stateless/05_ddl/05_0001_ddl_create_database.sql b/tests/suites/0_stateless/05_ddl/05_0001_ddl_create_database.sql index f2a74ed715923..fa1fe03b400f2 100644 --- a/tests/suites/0_stateless/05_ddl/05_0001_ddl_create_database.sql +++ b/tests/suites/0_stateless/05_ddl/05_0001_ddl_create_database.sql @@ -13,3 +13,19 @@ CREATE DATABASE system; -- {ErrorCode 2301} DROP DATABASE system; -- {ErrorCode 1002} CREATE DATABASE db.t; -- {ErrorCode 1005} + +DROP SCHEMA IF EXISTS db; + +CREATE SCHEMA db; +CREATE TABLE db.t(c1 int) ENGINE = Null; +SELECT COUNT(1) from system.tables where name = 't' and database = 'db'; + +CREATE SCHEMA IF NOT EXISTS db; +CREATE SCHEMA db; -- {ErrorCode 2301} + +DROP SCHEMA IF EXISTS db; + +CREATE SCHEMA system; -- {ErrorCode 2301} +DROP SCHEMA system; -- {ErrorCode 1002} + +CREATE SCHEMA db.t; -- {ErrorCode 1005} diff --git a/tests/suites/0_stateless/05_ddl/05_0001_ddl_drop_database.sql b/tests/suites/0_stateless/05_ddl/05_0001_ddl_drop_database.sql index c4e53175cfe36..a65525319a9ca 100644 --- a/tests/suites/0_stateless/05_ddl/05_0001_ddl_drop_database.sql +++ b/tests/suites/0_stateless/05_ddl/05_0001_ddl_drop_database.sql @@ -6,3 +6,12 @@ DROP DATABASE db; DROP DATABASE IF EXISTS db; DROP DATABASE db; -- {ErrorCode 1003} + +DROP SCHEMA IF EXISTS db; + +CREATE SCHEMA db; +DROP SCHEMA db; + +DROP SCHEMA IF EXISTS db; + +DROP SCHEMA db; -- {ErrorCode 1003} \ No newline at end of file diff --git a/tests/suites/0_stateless/06_show/06_0000_show_databases.result b/tests/suites/0_stateless/06_show/06_0000_show_databases.result index f90d6af706be6..6ba83c33b6720 100644 --- a/tests/suites/0_stateless/06_show/06_0000_show_databases.result +++ b/tests/suites/0_stateless/06_show/06_0000_show_databases.result @@ -1,3 +1,6 @@ ss ss1 ss2 +ss +ss1 +ss2 diff --git a/tests/suites/0_stateless/06_show/06_0000_show_databases.sql b/tests/suites/0_stateless/06_show/06_0000_show_databases.sql index 4e9dcd36e97d9..118858eea7a8e 100644 --- a/tests/suites/0_stateless/06_show/06_0000_show_databases.sql +++ b/tests/suites/0_stateless/06_show/06_0000_show_databases.sql @@ -7,6 +7,7 @@ CREATE DATABASE ss1; CREATE DATABASE ss2; SHOW DATABASES like 'ss%'; +SHOW SCHEMAS like 'ss%'; DROP DATABASE IF EXISTS ss; DROP DATABASE IF EXISTS ss1; diff --git a/tests/suites/0_stateless/06_show/06_0002_show_create_database.result b/tests/suites/0_stateless/06_show/06_0002_show_create_database.result index 5a347b6354628..01479282c0fc1 100644 --- a/tests/suites/0_stateless/06_show/06_0002_show_create_database.result +++ b/tests/suites/0_stateless/06_show/06_0002_show_create_database.result @@ -1,3 +1,6 @@ system CREATE DATABASE `system` ENGINE=SYSTEM test CREATE DATABASE `test` datafuselabs CREATE DATABASE `datafuselabs` ENGINE=GITHUB(token='xxx') +system CREATE DATABASE `system` ENGINE=SYSTEM +test CREATE DATABASE `test` +datafuselabs CREATE DATABASE `datafuselabs` ENGINE=GITHUB(token='xxx') diff --git a/tests/suites/0_stateless/06_show/06_0002_show_create_database.sql b/tests/suites/0_stateless/06_show/06_0002_show_create_database.sql index dd1aee0319450..1144660ed92cc 100644 --- a/tests/suites/0_stateless/06_show/06_0002_show_create_database.sql +++ b/tests/suites/0_stateless/06_show/06_0002_show_create_database.sql @@ -6,3 +6,11 @@ DROP DATABASE `test`; CREATE DATABASE `datafuselabs` ENGINE=github(token='xxx'); -- {ErrorCode 1073} SHOW CREATE DATABASE `datafuselabs`; DROP DATABASE `datafuselabs`; +SHOW CREATE SCHEMA `system`; +DROP SCHEMA IF EXISTS `test`; +CREATE SCHEMA `test`; +SHOW CREATE SCHEMA `test`; +DROP SCHEMA `test`; +CREATE SCHEMA `datafuselabs` ENGINE=github(token='xxx'); -- {ErrorCode 1073} +SHOW CREATE SCHEMA `datafuselabs`; +DROP SCHEMA `datafuselabs`;