《flex&bison》之sql解析

来源:互联网 发布:成绩管理系统c语言 编辑:程序博客网 时间:2024/05/22 11:42
        大概上半年接了一本《深入理解MySQL》,看了个一知半解吧!这里不得不说这本书有点贪大求全了。什么存储引擎、sql解析、查询优化等等的内容都涉及。如果领悟能力高的话,可能对数据库有一种全局的把握。不然的话还是需要看看其他资料了。当时不懂sql编译原理(其实现在也不懂,这货太愁银了),以为sql解析应该是一个简单的事情。毕竟不需要生成最终机器代码嘛,其实不然呀!举个例子吧,使用flex和bison为ANSI C和SQL构建编译器。MySQL的SQL语法文件有一万多行,而ANSI C就几百行。我顿时感觉事情不是我想的那样了。SQL也不是吃素的呀!前面一直在啃《flex&bison》,虽说是讲工具的使用,但是毕竟是编译呀!尤其对我这样的原理爱好者,简直好折磨。不过一知半解怎么也比眼前一抹黑要好。
        在MySQL中,SQL语法分析器的输出是语法树;而在《flex&bison》中,分析器的输出是逆波兰式代码。不过大同小异吧,作用其实是一样的。这书里面主要实现了select语句,作者说select是SQL中最复杂的语句了,想想也是,数据库的最大的作用不就是提供查询服务嘛!
select_stmt: SELECT select_opts select_expr_list                        { emit("SELECTNODATA %d %d", $2, $3); } ;    | SELECT select_opts select_expr_list     FROM table_references     opt_where opt_groupby opt_having opt_orderby opt_limit     opt_into_list { emit("SELECT %d %d %d", $2, $3, $5); } ;;
        上面这段语法规则算是select语句的顶层规则了。第一个有不规则就不用看了,算是一个特例了。我们主要研究第二个规则。首先,SELECT是一个终结符,直接匹配select关键字;select_opts是一些查询的选项;select_expr_list是查询的目标。因为bison使用的是LALR(1)分析法,这是一个使用最左规约的方法。所以这个语法分析器分析出来的SQL是最后执行SELECT操作了。当然这并不一定,因为SQL解析可以有很多实现。我看网上的资料,很多情况下SELECT操作并不是最后执行的。 然后table_references是一个比较复杂的非终结符号。SQL支持SELECT嵌套,也就是说table_references可以是一个SELECT语句的执行结果。这可以在规则文件中明显的看出来。
table_references:    table_reference { $$ = 1; }    | table_references ',' table_reference { $$ = $1 + 1; }    ;table_reference:  table_factor  | join_table;table_factor:    NAME opt_as_alias index_hint { emit("TABLE %s", $1); free($1); }  | NAME '.' NAME opt_as_alias index_hint { emit("TABLE %s.%s", $1, $3);                               free($1); free($3); }  | table_subquery opt_as NAME { emit("SUBQUERYAS %s", $3); free($3); }  | '(' table_references ')' { emit("TABLEREFERENCES %d", $2); }  ;  table_subquery: '(' select_stmt ')' { emit("SUBQUERY"); }
       具体的逻辑就是table_references-->table_reference-->table_factor-->table_subquery-->( select_stmt )。

0 0