• MySQL源码 解析器


      sql请求发送到server端,需要经过解析器生成内部的数据结构对象,以方便进行优化和生成执行计划。解析器主要做了两件事情,词法分析和语法分析。
    词法和语法分析:mysql使用lex词法分析器,yacc语法分析器进行分析,最后保存到lex对象结构中。
     
    例如:     select id, name from xpchild where id=1
     
    1. 在mysql_parse函数中使用lex_start初始化thd->lex对象,然后调用yacc中的MYSQLparse函数进行词法和语法分析。
          sql_yacc.cc是yacc在编译后生成出来的源文件,而在sql_yacc.yy文件中定义了大量的语法规则。下面找到select的语法定义。
     
    2. 语法解析部分:
      根据词法分析器的分析后的结果,应用下面的语法规则
      
     %token  SELECT_SYM
    
         select:
              select_init
              {
                LEX *lex= Lex;
                lex->sql_command= SQLCOM_SELECT;
              };
    
         select_item_list:
              select_item_list ',' select_item
            | select_item
            | '*'
              {
                THD *thd= YYTHD;
                Item *item= new (thd->mem_root) Item_field(&thd->lex->current_select->context,NULL, NULL, "*");
                if (item == NULL)
                  MYSQL_YYABORT;
                if (add_item_to_list(thd, item))
                  MYSQL_YYABORT;
                (thd->lex->current_select->with_wild)++;
              };
    
    where_clause:
              /* empty */  { Select->where= 0; }
            | WHERE
              {
                Select->parsing_place= IN_WHERE;
              }
              expr
              {
                SELECT_LEX *select= Select;
                select->where= $3;
                select->parsing_place= NO_MATTER;
                if ($3)
                  $3->top_level_item();
              };
    可以看到,上面的sql语句被解析出来的几个部分:(保存在lex结构中)
         1. sql_command=SQLCOM_SELECT;
         2. where子句:select_lex->where
         3. table列表:select_lex->table_list
         4. 字段列表:select_lex->item_list
    具体内容:
         1.  table_list 
      
         (gdb) print select_lex->table_list  
         $33 = {
                <Sql_alloc> = {<No data fields>},
                     members of SQL_I_List<TABLE_LIST>:
                     elements = 1,
                     first = 0x8ca04818,
                     next = 0x8ca04818
      只有一个table, db = 0x8ca04bc8 "test", table_name = 0x8ca047f0 "xpchild"
     
      2.   where
              (gdb) print select_lex->where->type()
                        $32 = Item::FUNC_ITEM
              (gdb) p select_lex->where)->args))->type()
                        $30 = Item::FIELD_ITEM
              (gdb) p select_lex->where)->args++))->type()
                        $29 = Item::INT_ITEM

        结构如下:

    where
         |-->FUNC_ITEM
             |-->FIELD_ITEM("id")
             |-->INT_ITEM(1)

      3.   item_list

              (gdb) print *(Item_field*)(select_lex->item_list->first->info)
                             name = 0x8ca04758 "id",
              (gdb) print *(Item_field*)(select_lex->item_list->first->next->info)
                              name = 0x8cb047f8 "name", 

        结构如下:

    item_list:
         |-->Item_field("id")
         |-->Item_field("name")
  • 相关阅读:
    HBase常用Shell命令
    在Eclipse中创建Maven多模块项目
    在IntelliJ IDEA中创建Maven多模块项目
    在IntelliJ IDEA中创建Web项目
    【Python】如何安装easy_install?
    RabbitMQ从入门到精通
    Erlang语言入门
    Eclipse背景颜色改动
    导出Excel1
    计算机概述
  • 原文地址:https://www.cnblogs.com/xpchild/p/3730079.html
Copyright © 2020-2023  润新知