Uploaded image for project: 'MariaDB Server'
  1. MariaDB Server
  2. MDEV-21064

Add a new class sp_expr_lex and a new grammar rule expr_lex

    XMLWordPrintable

    Details

    • Type: Task
    • Status: Closed (View Workflow)
    • Priority: Major
    • Resolution: Fixed
    • Fix Version/s: 10.5.0
    • Component/s: Parser
    • Labels:
      None

      Description

      In some cases the code in *.yy files related to expression parsed in their own LEX is hard to modify: reset_lex() and its correspoding restore_lex() reside in different grammar rules or different LEX methods.

      In order to simplify this (and later join sql_yacc.yy and sql_yacc_ora.yy easier), let's add a class representing an expression (Item) pointer and its LEX (that was used to parse this expression).

      Additionally, let's

      • Move a few methods from LEX to sp_expr_lex
      • Add a new sp_expr_lex method sp_repeat_loop_finalize()
      • Add a new sp_expr_lex method sp_if_expr()

      The tentative class structure is:

      class sp_expr_lex: public sp_lex_local
      {
        Item *m_item;       // The expression
      public:
        sp_expr_lex(THD *thd, LEX *oldlex)
         :sp_lex_local(thd, oldlex),
          m_item(NULL)
        { }
        void set_item(Item *item)
        {
          m_item= item;
        }
        Item *get_item() const
        {
          return m_item;
        }
        // The following methods are to be moved from LEX
        bool sp_continue_when_statement(THD *thd);
        bool sp_continue_when_statement(THD *thd, const LEX_CSTRING *label_name);
        int case_stmt_action_expr();
        int case_stmt_action_when(bool simple);
        bool sp_while_loop_expression(THD *thd)
        {
          return LEX::sp_while_loop_expression(thd, get_item());
        }
        // The following methods are new, to simpify the code in *.yy:
        bool sp_repeat_loop_finalize(THD *thd);
        bool sp_if_expr(THD *thd);
      };
      

      The new rule that creates sp_expr_lex (i.e. LEX+Item) will look like this:

      expr_lex:
                {
                  DBUG_ASSERT(Lex->sphead);
                  if (unlikely(!($<expr_lex>$= new (thd->mem_root)
                                 sp_expr_lex(thd, thd->lex))))
                    MYSQL_YYABORT;
                  Lex->sphead->reset_lex(thd, $<expr_lex>$);
                }
                expr
                {
                  $$= $<expr_lex>1;
                  $$->sp_lex_in_use= true;
                  $$->set_item($2);
                  if ($$->sphead->restore_lex(thd))
                    MYSQL_YYABORT;
                }
              ;
      

      After these changes, it will be much easier to move grammar rules, because reset_lex() and its corresponding restore_lex() will reside inside the same rule expr_lex. A lot of restore_lex() calls will be gone.

        Attachments

          Issue Links

            Activity

              People

              Assignee:
              bar Alexander Barkov
              Reporter:
              bar Alexander Barkov
              Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

                Dates

                Created:
                Updated:
                Resolved: