本文是基於MySQL5.7.22進行分析
1. SQL整體執行流程圖
經過上面圖,能夠從全局上了解SQL語句執行流程以及與其餘模塊交互html
1.1 SQL查詢執行流程sql
2. 語法解析
2.1 編程語言知識回顧
在介紹具體的MySQL數據庫解析SQL以前,先來回歸一下編程語言的知識點數據庫
2.2 概念與bison
2.1章節說明的概念跟bison又是一種什麼關係呢?
bison是屬於 GNU 項目的一個語法分析器生成器。
bison可以將上下文無文法解釋成語法分析表,因爲兼容yacc,而yacc是BNF進行描述文法規則的, 因此能夠理解爲bison可以解析以BNF描述上下文無關文法的語法分析器生成器.
2.3 MySQL與bison
MySQL使用bison做爲其解析SQL語句的語法分析器.
2.4 SQL解析相關文件及關聯
(1) 相關文件
SQL詞法解析文件:
sql/sql_lex.h、sql/lex_token.h、sql/lex.h、sql/lex_symbol.h
sql/gen_lex_token.cc、sql/sql_lex.cc
SQL語法解析文件:
sql/sql_yacc.yy、sql/sql_yacc.cc、sql/sql_yacc.h
SQL語句的hint語法解析文件:
sql/sql_hints.yy、sql/sql_hints.yy.cc編程
(2) 語法解析
3. sql/sql_yacc.yy
3.1 sql_yacc.yy描述
sql_yacc.cc規定了SQL語句語法規則,定義了SQL語句的關鍵字.
3.2 sql_yacc.yy文件結構bootstrap
%{
Prologue
%}數組Bison declarations閉包
%%
Grammar rules
%%編程語言Epilogueide
#include'來從頭文件獲取聲明. 若是你不須要任何的C聲明, 能夠省略這個部分的括號分隔符
%{'和`%}', 這部分被BISON原封不動地複製到輸出的.C文件中3.2 sql_yacc.yy文件解析
3.2.1 Prologue部分
該部分包含了C語言的頭文件,宏定義,該部分主要聲明和定義了2個關鍵函數,以下:
int yylex(void yylval, void yythd);詞法解析函數的聲明
void MYSQLerror(YYLTYPE , THD thd, const char *s);語法分析錯誤函數的定義。函數
3.2.2 Bison declatations部分
本部分與prologue部分使用 %% 進行分隔
3.2.3 Grammar Rules部分
本部分與Bison declatations部分,使用 %% 進行分隔
例子分析:
Bison產生式: result: components…;
下面的例子就是一個產生式
query是產生式的左端, 冒號後面是產生式的右端, | 表明或的意思, {}當query產生式推出右端狀況的時候所執行的動做,一個產生式結束要是 ;
其中, query verb_clause 都是非終止符, END_OF_INPUT 是終止符, 也就是說產生式推導到終止符就中止推導.
即query->END_OF_INPUT | verb_clause | verb_clause END_OF_INPUT
query:
- END_OF_INPUT
- { THD *thd= YYTHD;
- if (!thd->bootstrap &&!thd->m_parser_state->has_comment())
- {
- my_message(ER_EMPTY_QUERY, ER(ER_EMPTY_QUERY), MYF(0));
- MYSQL_YYABORT;
- }
- thd->lex->sql_command= SQLCOM_EMPTY_QUERY;
- YYLIP->found_semicolon= NULL;
- }
- | verb_clause
- { Lex_input_stream *lip = YYLIP;
- if (YYTHD->get_protocol()->has_client_capability(CLIENT_MULTI_QUERIE S)&& lip->multi_statements && !lip->eof())
- {
- lip->next_state= MY_LEX_END;
- lip->found_semicolon= lip->get_ptr();
- }
- else
- { lip->found_semicolon= NULL;}
- }
- ';'
- opt_end_of_input
- |verb_clause END_OF_INPUT
- {YYLIP->found_semicolon= NULL;}
參考資料
本文由京東商城數據庫技術部傅志宇提供。