Alex取了個號,客戶經理小張負責辦理alex的服務。
## 1)服務清單
? 小張:“先生,我可以為你服務什么么?”
? Alex:“厄,我要一碗紅燒肉。”
? 小張:“沒有”
? Alex:“厄,那來碗拉面”
? 小張:“沒有”
? Alex:“那有些啥?”
? 小張:“可以查看sql目錄下sql_yacc.yy文件,不過你用的這個5.1.7沒有該文件,只有相對應的sql_yacc.cpp文件。你可以使用5.1的其它版本的該文件,比如5.1.34。這里有個6.0.4的sql_yacc.yy文件,你先看下。”
? Alex:“啊?那不是要先看lex與yacc。”
? 小張:“推薦你不必看lex與yacc,我大概給你說說,只要看語法規則就可以了。
每條語法規則包括一個左部和一個右部,左右部之間用冒號’:’來分隔,規則結尾處要用分號”;”標記,所以一條語法規則的格式如下:
nonterminal : BODY;
其中nonterminal是一個非終結符,右部的BODY是一個由終結符和非終結符組成的串、可以為空,請看幾個例子,語法1:
create: CREATE opt_table_options TABLE_SYM opt_if_not_exists table_ident create2
語法2:
create: CREATE DATABASE opt_if_not_exists ident opt_create_database_options
從中,我們可以看出語法1是創建表的,語法是創建數據庫的。正常情況下,小寫字母表示非終結符,用大寫字母表示終結符,終結符是前面定義的。
%token? CREATE??????????????? ????????/* SQL-2003-R */
這兩個create語法可以合并成一個,中間用‘|’分割,表示’或’:
create: CREATE opt_table_options TABLE_SYM opt_if_not_exists table_ident create2
| CREATE DATABASE opt_if_not_exists ident opt_create_database_options
非終結進一步往下進行擴展,比如看下
opt_if_not_exists:
???? ?????/* empty */
??????? | IF not EXISTS;
/*empty*/這一行表示用戶用戶沒有輸入該子句,看下這個語句:
Create table t1(id int,varchar(20));
“Create”被create語法中的“CREATE”命中,“table”被“TABLE_SYM”命中,opt_if_not_exists對應的為空。而下面一個語句就會命中:
Create table if not exists t1(id int,varchar(20));
”
??Alex:“多謝,也就是說,符合規范的語句就會被識別,從而被執行,是這樣么。”
? 小張:“可以勉強這么講”
## 2)語言的轉換
? Alex:“小張,我問你哈,語句后面的大括號是什么意思啊。”
? 小張:“括號里面表示的是觸發了語義動作,設置了ts_cmd_type的值為創建表空間。
~~~
create:
?????? ???? //省略了一些內容
??????? | CREATE TABLESPACE tablespace_info
????????? {
??????????? Lex->alter_tablespace_info->ts_cmd_type= CREATE_TABLESPACE;
????????? }
??? ????//省略了一些內容
~~~
”
alex:“我看到里面有$$,$1,這些是什么含義啊”
小張:“你看下面一個表達式。
A :B C D
其中A的語義值為$$,B、C、D的語義值依次為$1,$2,$3。為了表達得更清晰,看下面的表達式,左邊的expr的值應該等于右邊的expr的值
~~~
expr: '(' expr ')'
?? {$$=$2;}
~~~
”
? Alex:“不太對啊,你看下這個表達式,$3從哪里來的,只有兩個值啊:get_select_lex、derived_table_list。
~~~
select_derived:
????????? get_select_lex
????????? {
??????????? LEX *lex= Lex;
??????????? if ($1->init_nested_join(lex->thd))
????????????? MYSQL_YYABORT;
????????? }
????????? derived_table_list
????????? {
??????????? LEX *lex= Lex;
??????????? /* for normal joins, $3 != NULL and end_nested_join() != NULL,
?????????????? for derived tables, both must equal NULL */
?
??????????? if (!($$= $1->end_nested_join(lex->thd)) && $3)
?????????? ???MYSQL_YYABORT;
??????????? if (!$3 && $$)
??????????? {
????????????? my_parse_error(ER(ER_SYNTAX_ERROR));
????????????? MYSQL_YYABORT;
??????????? }
????????? }
??????? ;
~~~
”
? 小張:“這個情況我們要講下,有些語法需要在識別出句型的一部分時就完成一些動作,這里我們看到了第一個大括號。Yacc會自動設置一個非終結符$ACT,該$ACT解析為空。
select_derived: get_select_lex $ACT derived_table_list
因此第二個大括號里面的$3就是derived_table_list
”
? Alex:“謝謝,我明白一點了。其實yy文件產生的作用就是語句串轉化為Lex語法結構。然后系統根據Lex語法結構進行處理。那么是不是可以說,只要通過語句,就可以執行。”
? 小張:“早著呢,還有語義檢查,比如查詢的列名不存在,以及權限檢查,優化等等。要確保安全,不然你直接來句查了bingxi有多少存款,這可不行。”
?
3)所謂的5級安全
? Alex:“這個安全,是不是所謂的5級安全,B1,B2等等啥的。”
? 小張:“這兩個沒有關聯,不過你提到了,我就給你提提。
1級安全:以前啊,公司老總算了算,就像DBA。獨自管著賬本呢,不安全。
2級安全:董事會覺得不安全,就加了個審計員。很多數據庫里面都有。但是呢,也不安全,老總把審計員搞定了。合謀合謀。
3級安全:搞了個三權分離,所謂的安全員,保衛科。賬本鎖起來。不過也不安全,保存賬本的安全室不結識,打個洞就進去了。
4級安全:結構化編程,于是進不去了。
5級安全:沒有最安全,只有更安全,沒有達到這個的。
”
? Alex:“有點意思,小張,我要開個戶,你給講講這個的流程吧。”
? 小張:“你帶身份證了”
? Alex:“沒帶”
? 小張:“那明天吧”
? Alex:“ok”