我们在扩展MySQL语法时,可能需要额外的信息,以下面的方式由用户给出,比如:
CREATE TABLE t(a INT) WITH TWIN; //TWIN的语义可能是创建表t,再创建孪生表t_twin
那么我们就需要扩展WITH TWIN,然而如果按照下面的形式书写,会产生移进/规约冲突:
opt_with_subtable:
/* empty */ { $$= false; }
| WITH TWIN_SYM{ $$= true; }
;
如何扩展WITH TWIN?参考WITH_ROLLUP_SYM!(只列举关键代码)
1. gen_lex_token.cc文件,函数compute_tokens硬编码了WITH_ROLLUP_SYM;
2. sql_lex.cc文件,函数MySQLlex函数特别解析WITH,WITH_ROLLUP_SYM;
如何扩展WITH TWIN?代码示例!
- 定义WITH_TWIN_SYM,TWIN_SYM
1.1 sql/lex.h
在symbols[]末追加{ SYM("TWIN", TWIN_SYM) }而WITH_TWIN_SYM会被硬编码,不在此声明
1.2 sql/sql_yacc.yy
声明%token TWIN_SYM
声明%token WITH_TWIN_SYM
增加WITH_TWIN_SYM的解析逻辑,比如:
opt_with_twintable:
/* empty */ { $$= false; }
| WITH_TWIN_SYM { $$= true; }
;
- gen_lex_token.cc,compute_tokens硬编码WITH_TWIN_SYM
/* With twin table */
set_token(WITH_TWIN_SYM, "WITH TWIN");
- sql_lex.cc,MySQLlex特别解析WITH_TWIN_SYM
switch(token) {
case WITH:
token= lex_one_token(yylval, thd); //拿下一个token
switch(token) {
case ROLLUP_SYM:
...
return WITH_ROLLUP_SYM;
/* With twin table */
case TWIN_SYM: //如果下一个token是TWIN_SYM,那么返回解析token为WITH_TWIN_SYM
yylloc->cpp.end= lip->get_cpp_ptr();
yylloc->raw.end= lip->get_ptr();
lip->add_digest_token(WITH_TWIN_SYM, yylval);
return WITH_TWIN_SYM;
default:
...
return WITH;
}
break;
}
网友评论