欄位名稱有誤的sql解析
select * from test2 where kkk=2;
有興趣測了下這個kkk列不存在的時候什麼時候出錯已了解下對sql的解析過程
對應的**路徑:
breakpoint 1, dispatch_command (thd=0x7efac40124f0, com_data=0x7efb3a9e2d80, command=com_query)
at /root/mysql-5.7.25/sql/sql_parse.cc:1460
mysql_parse (thd=0x7efac40124f0, parser_state=0x7efb3a9e2610) at /root/mysql-5.7.25/sql/sql_parse.cc:5458
mysql_execute_command (thd=0x7efac40124f0, first_level=true) at /root/mysql-5.7.25/sql/sql_parse.cc:2445
execute_sqlcom_select (thd=0x7efac40124f0, all_tables=0x7efac4016bb0)
at /root/mysql-5.7.25/sql/sql_parse.cc:5099
st_select_lex::prepare (this=0x7efac4015cc0, thd=0x7efac40124f0) at /root/mysql-5.7.25/sql/sql_resolver.cc:97
97 dbug_enter("select_lex::prepare");
setup_fields (thd=0x7efac40124f0, ref_pointer_array=..., fields=..., want_privilege=1,
sum_func_list=0x7efac4015e20, allow_sum_func=true, column_update=false)
at /root/mysql-5.7.25/sql/sql_base.cc:8927
//這步裡面沒問題
st_select_lex::setup_conds (this=0x7f18ac0058d0, thd=0x7f18ac000b70)
at /root/mysql-5.7.25/sql/sql_resolver.cc:1154
1154 dbug_enter("select_lex::setup_conds");
item_func::fix_fields (this=0x7f18ac006e80, thd=0x7f18ac000b70, ref=0x7f18ac0059a8)
at /root/mysql-5.7.25/sql/item_func.cc:213
213 dbug_assert(fixed == 0 || basic_const_item());
item_field::fix_fields (this=0x7f18ac006d60, thd=0x7f18ac000b70, reference=0x7f18ac006f28)
at /root/mysql-5.7.25/sql/item.cc:5840
5840 dbug_assert(fixed == 0);
find_field_in_tables (thd=0x7f18ac000b70, item=0x7f18ac006d60, first_table=0x7f18ac0067c0, last_table=0x0,
ref=0x7f18ac006f28, report_error=ignore_except_non_unique, want_privilege=1, register_tree_change=true)
at /root/mysql-5.7.25/sql/sql_base.cc:7769
7772 const char *name= item->field_name;
(gdb) p item->field_name
$145 = 0x7f18ac006440 "kkk"
find_field_in_table_ref (thd=0x7f18ac000b70, table_list=0x7f18ac0067c0, name=0x7f18ac006440 "kkk", length=3,
item_name=0x7f18ac006440 "kkk", db_name=0x0, table_name=0x0, ref=0x7f18ac006f28, want_privilege=1,
allow_rowid=true, cached_field_index_ptr=0x7f18ac006e38, register_tree_change=true,
actual_table=0x7f192c0506a8) at /root/mysql-5.7.25/sql/sql_base.cc:7546
7546 dbug_enter("find_field_in_table_ref");
find_field_in_table (thd=0x7f18ac000b70, table=0x7f18ac00f6c0, name=0x7f18ac006440 "kkk", length=3,
allow_rowid=true, cached_field_index_ptr=0x7f18ac006e38) at /root/mysql-5.7.25/sql/sql_base.cc:7438
7438 uint cached_field_index= *cached_field_index_ptr;
field *cur_field=
find_field_in_table_ref(thd, cur_table, name, length,
item->item_name.ptr(), db, table_name, ref,
(thd->lex->sql_command == sqlcom_show_fields) ?
0 : want_privilege,
allow_rowid,
&(item->cached_field_index),
register_tree_change,
&actual_table);
這這裡迴圈查詢
(gdb) n
7464 for (; *field_ptr; ++field_ptr)
(gdb) n
7465 if (!my_strcasecmp(system_charset_info, (*field_ptr)->field_name, name))
(gdb) p (*field_ptr)->field_name
$160 = 0x7f18bc011564 "name"
(gdb) p name
$161 = 0x7f18ac006440 "kkk"
而且發現mysql 的解析器,優化器,執行器感覺**都在一塊。
在sql_parse.cc:7057 parse_sql() 我感覺可以理解是語法和詞法分析,但是這步並沒有對where 列的判斷。
而是在執行的「執行的這裡面判斷」 這執行的裡面還包含了對許可權,有沒有ddl 等判斷。還有優化。
這給人的感覺沒有明顯的**的區分,也不知道如何去分別。這部分感覺很亂,而且很複雜。
MySQL中一條SQL語句的執行過程
查詢語句的執行順序 客戶端通過tcp連線傳送連線請求到mysql聯結器,聯結器會對該請求進行許可權驗證及連線資源分配 max connections,8小時超時 建立連線後客戶端傳送一條語句,mysql收到該語句後,通過命令分發器判斷其是否是一條select語句,如果是,在開啟查詢快取的情況下,先在...
一條SQL語句的執行過程
1.1連線層 提供連線協議 tcp ip,socket 提供驗證 使用者 密碼 ip socket 提供專用連線線程 接收使用者sql,返回結果 通過以下語句可以檢視鏈結執行緒的基本情況 mysql show processlist 1.2sql層 重點 接收上層傳送的sql語句 語法驗證模組 驗證...
MYSQL 一條sql的執行過程
1 sql介面,負責接收處理收到的sql語句。2 查詢解析器,負責對sql語句進行解析,讓mysql能看懂sql語句,按照sql語法解析出這條sql要幹啥。3 查詢優化器,選擇最優的查詢路徑,指定執行計畫 全表掃瞄還是走索引 4 呼叫儲存引擎介面真正開始執行sql語句。儲存引擎就是用來執行sql的,...