Mysql源码学习――打造专属语法(三)

2014-11-24 10:35:16 · 作者: · 浏览: 6
(lip->m_thd->variables.sql_mode & MODE_HIGH_NOT_PRECEDENCE))

return NOT2_SYM;

if ((symbol->tok == OR_OR_SYM) &&

!(lip->m_thd->variables.sql_mode & MODE_PIPES_AS_CONCAT))

return OR2_SYM;

return symbol->tok;

}

return 0;

}

static SYMBOL *get_hash_symbol(const char *s,

unsigned int len,bool function)

{

register uchar *hash_map;

register const char *cur_str= s;

if (len == 0) {

DBUG_PRINT("warning", ("get_hash_symbol() received a request for a zero-length symbol, which is probably a mistake."));

return(NULL);

}

if (function){

if (len>sql_functions_max_len) return 0;

hash_map= sql_functions_map;

register uint32 cur_struct= uint4korr(hash_map+((len-1)*4));

for (;;){

register uchar first_char= (uchar)cur_struct;

if (first_char == 0)

{

register int16 ires= (int16)(cur_struct>>16);

if (ires==array_elements(symbols)) return 0;

register SYMBOL *res;

if (ires>=0)

res= symbols+ires;

else

res= sql_functions-ires-1;

register uint count= (uint) (cur_str - s);

return lex_casecmp(cur_str,res->name+count,len-count) 0 : res;

}

register uchar cur_char= (uchar)to_upper_lex[(uchar)*cur_str];

if (cur_char

cur_struct>>=8;

if (cur_char>(uchar)cur_struct) return 0;

cur_struct>>=8;

cur_struct= uint4korr(hash_map+

(((uint16)cur_struct + cur_char - first_char)*4));

cur_str++;

}

}else{

if (len>symbols_max_len) return 0;

hash_map= symbols_map;

register uint32 cur_struct= uint4korr(hash_map+((len-1)*4));

for (;;){

register uchar first_char= (uchar)cur_struct;

if (first_char==0){

register int16 ires= (int16)(cur_struct>>16);

if (ires==array_elements(symbols)) return 0;

register SYMBOL *res= symbols+ires;

register uint count= (uint) (cur_str - s);

return lex_casecmp(cur_str,res->name+count,len-count)!=0 0 : res;

}

register uchar cur_char= (uchar)to_upper_lex[(uchar)*cur_str];

if (cur_char

cur_struct>>=8;

if (cur_char>(uchar)cur_struct) return 0;

cur_struct>>=8;

cur_struct= uint4korr(hash_map+

(((uint16)cur_struct + cur_char - first_char)*4));

cur_str++;

}

}

}

其中的get_hash_symbol便是去系统中查找关键字,第三个参数function代表是否去查找系统函数,我们这里是系统变量,不是函数,故为FALSE。所有的关键字都挂在了hash_map上,即symbols_map上。symbols_maps又是一堆处理过的数据:

static uchar symbols_map[11828]= {

'<', '>', 29, 0,

'!', '|', 32, 0,

'<', 'X', 150, 0,

'B', 'Y', 11, 1,

'A', 'W', 147, 2,

'A', 'V', 0, 4,

...

看一下这个文件的最上面的注释吧,看看有啥有用的信息,果然被找到了:

1

2

/* Do not edit this file! This is generated by gen_lex_hash.cc

that seeks for a perfect hash function */

看到了这个注释,心中豁然开朗,原来lex_hash.h是由gen_lex_hash.cc进行生成的,大家千万不要自己进行编辑此文件啊!!

来gen_lex_hash.cc看下吧,看到了个main函数,里面是一些生成文件的操作,在generate_find_structs函数中找到了insert_symbols,

这应该是初始化我们的symbols_map数组了吧。

void insert_symbols()

{

size_t i= 0;

SYMBOL *cur;

for (cur= symbols; i

hash_lex_struct *root=

get_hash_struct_by_len(&root_by_len,cur->length,&max_len);

insert_into_hash(root,cur->name,0,(uint) i,0);

}

}

看到函数的实现是循环取数组symbols,找