●MYSQL的查询语句起始于:mysql_execute_command(THD *thd),(sql_http://www.doczj.com/doc/2e2a5f295f0e7cd18425367c.html 1858行),
在简单的预处理后,进入
case SQLCOM_SELECT:{}
●首先获取权限
ulong privileges_requested= lex->exchange ? SELECT_ACL | FILE_ACL : SELECT_ACL;
这边定义了28中权限,用1L<<0,1L<<1…..1L<<30,以及一些预定义的组合权限。
#define INSERT_ACL (1L << 1)
……
#define TABLE_ACLS \
(SELECT_ACL | INSERT_ACL | UPDATE_ACL | DELETE_ACL | CREATE_ACL | DROP_ACL | \
GRANT_ACL | REFERENCES_ACL | INDEX_ACL | ALTER_ACL | CREATE_VIEW_ACL | \ SHOW_VIEW_ACL | TRIGGER_ACL)
●然后校验权限,根据是否为全表操作,分别调用两种函数:
if (all_tables)
res= check_table_access(thd, privileges_requested, all_tables, FALSE, UINT_MAX, FALSE);
else
res= check_access(thd, privileges_requested, any_db, NULL, NULL, 0, 0);
●接着就调用执行函数了,execute_sqlcom_select():线程类THD中,有个成员类LEX
用于存储有关查询的信息。在查询开始的时候:
初始化一个结果集,存储在lex->result中:
select_result *result=lex->result;
接着锁定要操作的表:
res= open_and_lock_tables(thd, all_tables, TRUE, 0)
在查询之前,先查询一下cache,查看是否有缓存,如果没有调用handle_select()开始查询:
query_cache_store_query(thd, all_tables);
res= handle_select(thd, lex, result, 0);
●bool handle_select(THD *thd, LEX *lex, select_result *result,ulong setup_tables_done_
option)
这里有个条件判断
if (select_lex->master_unit()->is_union() ||
select_lex->master_unit()->fake_select_lex)
我觉得应该是判断本查询是否是要跨数据库,如果需要,调用mysql_union()不需要则调用mysql_select()
●mysql_select中主要又是一个关键类,JOIN,它定义了一个查询所涉及到的所有变量,
接着就是join成员的三个成员函数:
join->prepare(rref_pointer_array, tables, wild_num,
conds, og_num, order, group, having, proc_param,
select_lex, unit)
join->optimize();//用于优化查询语句
join->exec();
●exec()是一个长达千行的函数,在函数的前半段,主要做的工作就是解析SQL语句,规