[MDEV-21064] Add a new class sp_expr_lex and a new grammar rule expr_lex Created: 2019-11-15  Updated: 2020-01-23  Resolved: 2019-11-16

Status: Closed
Project: MariaDB Server
Component/s: Parser
Fix Version/s: 10.5.0

Type: Task Priority: Major
Reporter: Alexander Barkov Assignee: Alexander Barkov
Resolution: Fixed Votes: 0
Labels: None

Issue Links:
Blocks
blocks MDEV-12518 Unify sql_yacc.yy and sql_yacc_ora.yy Closed

 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.


Generated at Thu Feb 08 09:04:19 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.