Skip to content

Commit

Permalink
Feat(parser): support create database (#103)
Browse files Browse the repository at this point in the history
* support create database

Signed-off-by: tuichenchuxin <[email protected]>

* support parse create database

Signed-off-by: tuichenchuxin <[email protected]>
  • Loading branch information
tuichenchuxin authored Jun 19, 2022
1 parent 2e4a733 commit 6ce5573
Show file tree
Hide file tree
Showing 5 changed files with 174 additions and 4 deletions.
58 changes: 58 additions & 0 deletions pisa-proxy/parser/mysql/src/ast/ddl.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
// Copyright 2022 SphereEx Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use lrpar::Span;

use crate::ast::{api::*, base::*};

#[derive(Debug, Clone)]
pub enum Create {
CreateDatabase(Box<CreateDatabase>),
}

#[derive(Debug, Clone)]
pub struct CreateDatabase {
pub is_not_exists: bool,
pub database_name: String,
pub opt_create_database_options: Vec<CreateDatabaseOption>,
}

#[derive(Debug, Clone)]
pub enum CreateDatabaseOption {
DefaultCollation(DefaultCollation),
DefaultCharset(DefaultCharset),
DefaultEncryption(DefaultEncryption),
}

#[derive(Debug, Clone)]
pub struct DefaultCollation {
pub is_default: bool,
pub is_equal: bool,
pub collation_name: String,
}

#[derive(Debug, Clone)]
pub struct DefaultCharset {
pub is_default: bool,
pub is_equal: bool,
pub charset_name: String,
}

#[derive(Debug, Clone)]
pub struct DefaultEncryption {
pub is_default: bool,
pub is_equal: bool,
pub encryption: String,
}

4 changes: 4 additions & 0 deletions pisa-proxy/parser/mysql/src/ast/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ pub use dml::*;
pub mod tcl;
pub use tcl::*;

pub mod ddl;
pub use ddl::*;

#[macro_use]
pub mod api;
pub use api::*;
Expand All @@ -41,6 +44,7 @@ pub enum SqlStmt {
Start(Start),
Commit(Commit),
Rollback(Rollback),
Create(Create),
None,
}

Expand Down
107 changes: 106 additions & 1 deletion pisa-proxy/parser/mysql/src/grammar.y
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,8 @@ sql_stmt -> SqlStmt:
| deallocate { SqlStmt::Deallocate($1) }
| show_databases_stmt { SqlStmt::ShowDatabasesStmt($1) }
| show_tables_stmt { SqlStmt::ShowTablesStmt($1) }
| start { SqlStmt::Start($1) }
| start { SqlStmt::Start($1) }
| create { SqlStmt::Create($1) }

;

Expand Down Expand Up @@ -6070,7 +6071,111 @@ opt_savepoint -> bool:
| 'SAVEPOINT' { true }
;
create -> Create:
'CREATE' 'DATABASE' opt_if_not_exists ident opt_create_database_options
{
Create::CreateDatabase(Box::new(
CreateDatabase{
is_not_exists: $3,
database_name: $4.0,
opt_create_database_options: $5,
}
))
}
;
opt_if_not_exists -> bool:
/* empty */ { false }
| 'IF' not 'EXISTS' { true }
;
opt_create_database_options -> Vec<CreateDatabaseOption>:
/* empty */ { vec![] }
| create_database_options { $1 }
;
create_database_options -> Vec<CreateDatabaseOption>:
create_database_option
{
vec![$1]
}
| create_database_options create_database_option
{
$1.push($2);
$1
}
;
create_database_option -> CreateDatabaseOption:
default_collation
{
$1
}
| default_charset
{
$1
}
| default_encryption
{
$1
}
;
default_collation -> CreateDatabaseOption:
opt_default 'COLLATE' opt_equal collation_name {
let is_default = match $1 {
Some(_) => true,
None => false,
};
let is_equal = match $3 {
Some(_) => true,
None => false,
};
CreateDatabaseOption::DefaultCollation(DefaultCollation{
is_default: is_default,
is_equal: is_equal,
collation_name: $4,
})
}
;
default_charset -> CreateDatabaseOption:
opt_default character_set opt_equal charset_name
{
let is_default = match $1 {
Some(_) => true,
None => false,
};
let is_equal = match $3 {
Some(_) => true,
None => false,
};
CreateDatabaseOption::DefaultCharset(DefaultCharset{
is_default: is_default,
is_equal: is_equal,
charset_name: $4,
})
}
;
default_encryption -> CreateDatabaseOption:
opt_default 'ENCRYPTION' opt_equal 'TEXT_STRING'
{
let is_default = match $1 {
Some(_) => true,
None => false,
};
let is_equal = match $3 {
Some(_) => true,
None => false,
};
CreateDatabaseOption::DefaultEncryption(DefaultEncryption{
is_default: is_default,
is_equal: is_equal,
encryption: String::from($lexer.span_str($4.as_ref().unwrap().span())),
})
}
;
%%
Expand Down
2 changes: 2 additions & 0 deletions pisa-proxy/parser/mysql/src/ident.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ macro_rules! keyword_size {
"CONVERT",
"COUNT",
"CPU",
"CREATE",
"CROSS",
"CUME_DIST",
"CURDATE",
Expand Down Expand Up @@ -813,6 +814,7 @@ macro_rules! keyword_size {
(T_CONVERT, 7),
(T_COUNT, 5),
(T_CPU, 3),
(T_CREATE, 6),
(T_CROSS, 5),
(T_CUME_DIST, 9),
(T_CURDATE, 7),
Expand Down
7 changes: 4 additions & 3 deletions pisa-proxy/parser/mysql/src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,12 +119,13 @@ mod test {
//"START TRANSACTION",
//"COMMIT",
//"ROLLBACK",
"set names utf8mb4",
// "set names utf8mb4",
//"SET character_set_connection = gbk;",
//"SET character_set_results = gbk;",
//"SET character_set_client = \"gbk\";",
"SET @@GLOBAL.character_set_client = gbk;",
"SET @@SESSION.character_set_client = gbk;",
//"SET @@GLOBAL.character_set_client = gbk;",
//"SET @@SESSION.character_set_client = gbk;",
"create database if not exists db CHARACTER SET = utf8;",
];

let p = Parser::new();
Expand Down

0 comments on commit 6ce5573

Please sign in to comment.