searchusermenu
  • 发布文章
  • 消息中心
点赞
收藏
评论
分享
原创

mysql存储过程实现详解

2024-09-18 09:21:36
5
0

mysql存储过程实现详解

一、解析

语法树如下:

sp_tail:

  PROCEDURE_SYM

  opt_if_not_exists

  sp_name

  ‘( sp_pdparam_list )

  sp_c_chistics

  sp_proc_stmt:

    sp_proc_stmt_statement:

      simple_statement

    sp_proc_stmt_return

    sp_proc_stmt_if

    case_stmt_specification

    sp_labeled_block

    sp_unlabeled_block:

      sp_block_content:

        BEGIN_SYM

        sp_decls:

          sp_decls

            sp_decl:

              DECLARE_SYM

              sp_decl_idents

              type

              opt_collate

              sp_opt_default

         | DECLARE_SYM

              ident

              CONDITION_SYM

              FOR_SYM

              sp_cond

         | DECLARE_SYM

              sp_handler_type

              HANDLER_SYM

              FOR_SYM

           sp_hcond_list

           sp_proc_stmt

        | DECLARE_SYM

           ident

          CURSOR_SYM

          FOR_SYM

          select_stmt

         ‘;

      sp_proc_stmts:

        sp_proc_stmts

        sp_proc_stmt

        ';'

      END

    sp_labeled_control:

      label_ident :

      sp_unlabeled_control:

         LOOP_SYM sp_proc_stmts1 END LOOP_SYM

      | WHILE_SYM expr DO_SYM sp_proc_stmts1 END WHILE_SYM

      | REPEAT_SYM sp_proc_stmts1 UNTIL_SYM expr END REPEAT_SYM

      sp_opt_label

    sp_proc_stmt_unlabeled

    sp_proc_stmt_leave

    sp_proc_stmt_iterate

    sp_proc_stmt_open

    sp_proc_stmt_fetch

    sp_proc_stmt_close

  除非是单语句的存储过程,否则一般情况下至少使用sp_unlabeled_block -> sp_block_content来定义函数体,然后在这里面编写复数语句。语句大致分为传统语句和控制语句两类,这些语句最终会被解析为如下指令集,并保存在数据字典中。

  存储过程函数体的解析仍然依赖原本的解析过程,即仍然使用create语句的文法,在THD的视角这就是一句完成的语句,只调用了一次MYSQLparse,只不过多进行了几次exprsimple_statement的规约而已。但这个过程又存在Lex的上下文切换,以simple_statement为例,完成simple_statement的规约后以parse_tree_root为根的解析树已经建好,进一步规约为sp_proc_stmt_statement时,就会切换Lex的上下文,如下图:

  所以从Lex的角度来看,这就是分别解析了多个语句,上图MAKE_CMD便是对这一说法的印证,这里make_sql_cmd的执行并非像往常一样安排在MYSQLparse之后,而是规约的过程中生成了一系列的Sql_cmd。总结起来,create procedure语句的解析是单句输入(THD),多句输出(LexSql_cmd)。

      create procedure语句本身的执行过程本文略过不谈,与数据字典和权限相关的内容较多,而且过于细节,最关键的因素是,与其它create类语句似乎亦并无二至,其本质上应分属DDL的研究领域。

一、调用

存储过程的调用是解释执行存储在数据字典中的指令序列,附带参数的指令会在执行过程中prepare,控制指令一般用jump实现,这一部分在逻辑上使用(ip,nextp)的自动机实现,并不复杂,参数的求值依赖Itemval求值体系,prepare时会对Item执行fix_fields操作确定Item的数据来源,与往常的SQL执行一致。真正关键的是传统SQL语句的执行,解析为sp_instr_stmt指令,细节很多,主要流程是在切换上下文(包括arenadasp_pcontext)后调用mysql_execute_command,参考下图。

0条评论
作者已关闭评论
曾****江
5文章数
1粉丝数
曾****江
5 文章 | 1 粉丝
原创

mysql存储过程实现详解

2024-09-18 09:21:36
5
0

mysql存储过程实现详解

一、解析

语法树如下:

sp_tail:

  PROCEDURE_SYM

  opt_if_not_exists

  sp_name

  ‘( sp_pdparam_list )

  sp_c_chistics

  sp_proc_stmt:

    sp_proc_stmt_statement:

      simple_statement

    sp_proc_stmt_return

    sp_proc_stmt_if

    case_stmt_specification

    sp_labeled_block

    sp_unlabeled_block:

      sp_block_content:

        BEGIN_SYM

        sp_decls:

          sp_decls

            sp_decl:

              DECLARE_SYM

              sp_decl_idents

              type

              opt_collate

              sp_opt_default

         | DECLARE_SYM

              ident

              CONDITION_SYM

              FOR_SYM

              sp_cond

         | DECLARE_SYM

              sp_handler_type

              HANDLER_SYM

              FOR_SYM

           sp_hcond_list

           sp_proc_stmt

        | DECLARE_SYM

           ident

          CURSOR_SYM

          FOR_SYM

          select_stmt

         ‘;

      sp_proc_stmts:

        sp_proc_stmts

        sp_proc_stmt

        ';'

      END

    sp_labeled_control:

      label_ident :

      sp_unlabeled_control:

         LOOP_SYM sp_proc_stmts1 END LOOP_SYM

      | WHILE_SYM expr DO_SYM sp_proc_stmts1 END WHILE_SYM

      | REPEAT_SYM sp_proc_stmts1 UNTIL_SYM expr END REPEAT_SYM

      sp_opt_label

    sp_proc_stmt_unlabeled

    sp_proc_stmt_leave

    sp_proc_stmt_iterate

    sp_proc_stmt_open

    sp_proc_stmt_fetch

    sp_proc_stmt_close

  除非是单语句的存储过程,否则一般情况下至少使用sp_unlabeled_block -> sp_block_content来定义函数体,然后在这里面编写复数语句。语句大致分为传统语句和控制语句两类,这些语句最终会被解析为如下指令集,并保存在数据字典中。

  存储过程函数体的解析仍然依赖原本的解析过程,即仍然使用create语句的文法,在THD的视角这就是一句完成的语句,只调用了一次MYSQLparse,只不过多进行了几次exprsimple_statement的规约而已。但这个过程又存在Lex的上下文切换,以simple_statement为例,完成simple_statement的规约后以parse_tree_root为根的解析树已经建好,进一步规约为sp_proc_stmt_statement时,就会切换Lex的上下文,如下图:

  所以从Lex的角度来看,这就是分别解析了多个语句,上图MAKE_CMD便是对这一说法的印证,这里make_sql_cmd的执行并非像往常一样安排在MYSQLparse之后,而是规约的过程中生成了一系列的Sql_cmd。总结起来,create procedure语句的解析是单句输入(THD),多句输出(LexSql_cmd)。

      create procedure语句本身的执行过程本文略过不谈,与数据字典和权限相关的内容较多,而且过于细节,最关键的因素是,与其它create类语句似乎亦并无二至,其本质上应分属DDL的研究领域。

一、调用

存储过程的调用是解释执行存储在数据字典中的指令序列,附带参数的指令会在执行过程中prepare,控制指令一般用jump实现,这一部分在逻辑上使用(ip,nextp)的自动机实现,并不复杂,参数的求值依赖Itemval求值体系,prepare时会对Item执行fix_fields操作确定Item的数据来源,与往常的SQL执行一致。真正关键的是传统SQL语句的执行,解析为sp_instr_stmt指令,细节很多,主要流程是在切换上下文(包括arenadasp_pcontext)后调用mysql_execute_command,参考下图。

文章来自个人专栏
文章 | 订阅
0条评论
作者已关闭评论
作者已关闭评论
0
0