它們能夠讓你更容易的解析複雜的語言,達成解析字串的目的。輸入字元流 ,發現某一段字元能夠匹配乙個關鍵字,就根據定義好的動作來執行。
%
%begin printf
("begin;\n");
executesql printf
("select * from t1;\n"
);
commit printf
("commit;\n");
%%
lex 的每一段是通過%%
分割的,這裡設定了 3 個關鍵字 :
begin
executesql
commit
讀取字元流時,遇到關鍵字 ,就會根據後面的指令去執行動作。比如遇到executesql
,會列印select * from t1 ;
如果匹配不到關鍵字 ,會正常輸出。
[2020/07/31 09:43:01]
[info]
[server.go:391]
["connection closed"]
[conn=4]
根據日誌中的元素,定義如下關鍵字
word > connection|conn|info|closed
date >
2020/07
/3109:
43:01filename > server.go
num >
391|4
leftbracket >
[rightbracket >
]colon >
:slash >
/equalsign >
=quotationmark > "
lex 分詞器
%
%[a−za−z]
[a−za−z0−9]*
return word
日期的正規表示式.手動狗頭 return date
\[a−za−z0−9\/
.−]+
return filename
\[0123456789]+
return num
\[return leftbracket
\]return rightbracket
\:return colon
\/return slash
\=return equalsign
\" return quotationmark
%%
經過 lex 分詞的結果就是
leftbracket date rightbracket
leftbracket word rightbracket
leftbracket filename colon num rightbracket
leftbracket quotationmark word word quotationmark rightbracket
leftbracket word equalsign num rightbracket
在tidb
中,類似的結構都存放在parser.y
中,
結構如下,
第一部分主要是定義token
的型別、優先順序、結合性等。
%
%union
ident string
expr ast.exprnode
statement ast.stmtnode
}%token
%type
%precedence empty
%left join straightjoin inner cross left right full natural
%start start
通過%%
分割,以上是第一部分,即定義段
%%
下部分是 sql 語法的產生式和每個規則對應的 action ,我們找乙個簡單的看看,
這應該是drop table
的 分詞結構,生成ast.droptablestmt
語法樹來執行
droptablestmt:
"drop" opttemporary tableortables ifexists tablenamelist restrictorcascadeopt
}
這裡有 5 個 token ,分別是
opttemporary
tableortables
ifexists
tablenamelist
restrictorcascadeopt
分別看一下這些 token 的定義,那兩個 table 巴拉巴拉就不看了
opttemporary
//應該是臨時表的 token ,如果有這個 token ,則會被解析。
//但也如邏輯中寫的,「tidb 目前不支援臨時表,雖然會被解析,但是不生效。」
opttemporary:
/* empty */
|"temporary"
if exists
// 是否有 if exists
ifexists:
|"if"
"exists"
restrict: 確保只有不存在相關檢視和完整性約束的表才能刪除cascade: 任何相關檢視和完整性約束都將一併被刪除
restrictorcascadeopt:
{}| "restrict"
| "cascade"
所以可以看出,在drop table
的時候,在這個語法結構中," 豐滿 " 的語句大概是
drop temporary table ifexists tablename restrict/cascade
之後就會生成一棵 ast 抽象語法ast.droptablestmt
。
ast/ddl.
gotype droptablestmt struct
這個具體的實現,比如這個
func
(n *droptablestmt)
restore
(ctx *format.restorectx)
error
else
else
}if n.ifexists
for index, table :=
range n.tables
if err := table.
restore
(ctx)
; err !=
nil}
return
nil}
先判斷了drop
的是view
還是table
, 如果走進了table
分支,也就大概判斷了是否是臨時表,是否有各種特殊的語法。
到這裡基本了解了 tidb 中對於 sql 解析的方式,當然,和行文的區別, tidb 用的是goyacc
,不過好像區別也不是很大,這篇希望可以給大家乙個參考。
TiDB基本架構簡單總結
和mysql不同,tidb是乙個分布式的資料庫而不是單個程序,所以整個tidb是由以下角色組成 tikv,pd,tidb,tispark。每個角色都是部署在多台機器上的程序組成的集群。tikv負責資料的儲存,對外而言,它就是乙個提供key value儲存的引擎。但它儲存的並不是離散的key,而在乙個...
從0理解設計模式《簡單工廠》
我在開始寫程式的時候經常會遇到一種情況,例如更改乙個字段,或者新增乙個小功能,就會把之前的廢棄掉,重寫單獨開乙個類,然後增加變數,方法 貼上複製那種 結果就單單改了其中的乙個功能而已,耗時耗力,如果你也遇到這種情況,那麼說明非常需要學習下設計模式了。我認為設計模式是 一種思想,一種模式,一種套路,一...
TiDB全量遷移,從MySql遷移到tidb
mydumper是乙個強大的資料遷移工具,具體可以參考 maxbube mydumper。你可以使用mydumper從 mysql 匯出資料,然後用 loader 將其匯入到 tidb。注意 雖然 tidb 也支援使用 mysql 官方的mysqldump工具來進行資料的遷移工作,但相比於mydum...