MySQL扩展WITH语法

2018-11-26  本文已影响0人  王晓宇_xiaoyuwang

我们在扩展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?代码示例!

  1. 定义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; }
        ;
  1. gen_lex_token.cc,compute_tokens硬编码WITH_TWIN_SYM
/* With twin table */
set_token(WITH_TWIN_SYM, "WITH TWIN");
  1. 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;
}
上一篇 下一篇

猜你喜欢

热点阅读