PL/SQL parser (MDEV-10142)

[MDEV-13197] Parser refactoring for CREATE VIEW,TRIGGER,SP,UDF,EVENT Created: 2017-06-28  Updated: 2018-08-31  Resolved: 2017-07-01

Status: Closed
Project: MariaDB Server
Component/s: Parser, Views
Affects Version/s: 10.3
Fix Version/s: 10.3.1

Type: Technical task Priority: Major
Reporter: Alexander Barkov Assignee: Alexander Barkov
Resolution: Fixed Votes: 0
Labels: refactoring

Issue Links:
Blocks
blocks MDEV-10591 Oracle-style packages Closed
Sprint: 10.2.2-3, 10.2.2-1, 10.2.2-2, 10.2.2-4, 10.1.18

 Description   

This task is intended to simplify the work for CREATE PACKAGE (see MDEV-10591), as well as to fix minor known problems in the underlying parser grammar.

There are a few difficulties in the grammar for CREATE for VIEW, TRIGGER, EVENT, PROCEDURE, FUNCTION.

  • The grammar for the mentioned objects is implemented with help of the rule view_or_trigger_or_sp_or_event. The grammar for all other object types is implemented directly in the create: rule. This makes the grammar non-symmetric for various object types, which is hard to read and understand.
  • We'll add CREATE PACKAGE soon. It will require the DEFINER clause. In the current grammar, it will have to go to view_or_trigger_or_sp_or_event again, and make the things even more complex.
  • LEX::create_view_mode, LEX::create_view_algorithm, LEX::create_view_suid are initialized for all objects described in view_or_trigger_or_sp_or_event. For non-VIEW objects this initialization is redundant.

            | create_or_replace
              {
                Lex->create_info.set($1);
                Lex->create_view_mode= ($1.or_replace() ? VIEW_CREATE_OR_REPLACE :
                                                          VIEW_CREATE_NEW);
                Lex->create_view_algorithm= DTYPE_ALGORITHM_UNDEFINED;
                Lex->create_view_suid= TRUE;
              }
              view_or_trigger_or_sp_or_event { }
    

  • The grammar erroneously accepts these weird query:

    ALTER VIEW IF NOT EXISTS v1 AS SELECT 1;
    

    It's really senseless to ALTER something that NOT EXISTS.
    The IF NOT EXISTS clause is accepted because both CREATE VIEW and ALTER VIEW grammar reuses the view_tail rule.

Under terms of this task we'll do the following:

  • For stricter data type control: introduce a new enum instead of pre-processor constants:

enum enum_view_suid
{
  VIEW_SUID_INVOKER= 0,
  VIEW_SUID_DEFINER= 1,
  VIEW_SUID_DEFAULT= 2
};

  • Introduce a new class:

class Create_view_info: public Sql_alloc
{
public:
  LEX_CSTRING select;              // The SELECT statement of CREATE VIEW
  enum enum_view_create_mode mode;
  uint16 algorithm;
  uint8 check;
  enum enum_view_suid suid;
  Create_view_info(enum_view_create_mode mode_arg,
                   uint16 algorithm_arg,
                   enum_view_suid suid_arg)
   :select(null_clex_str),
    mode(mode_arg),
    algorithm(algorithm_arg),
    check(VIEW_CHECK_NONE),  
    suid(suid_arg)
  { }
}; 

  • Remove the same members from LEX and add a pointer to Create_view_info instead. Create_view_info will be allocated on THD memory root only for CREATE VIEW or ALTER VIEW queries.
  • Reduce the amount of duplicate C++ code used in .yy files by adding new methods in LEX:

  bool add_alter_view(THD *thd, uint16 algorithm, enum_view_suid suid,
                      Table_ident *table_ident);
  bool add_create_view(THD *thd, DDL_options_st ddl,
                       uint16 algorithm, enum_view_suid suid,
                       Table_ident *table_ident);

  • In sql_yacc.yy: remove grammar rules view_or_trigger_or_sp_or_event, definer_tail, no_definer_tail, view_tail
  • In sql_yacc.yy: add new grammar branches directly into the create: rules, for VIEW, TRIGGER, PROCEDURE, FUNCTION, EVENT.
    Note, when we add the CREATE PACKAGE statement later (see MDEV-10591), it will also be added directly to create:, together with its optional DEFINER clause.
  • In sql_yacc.yy: fix the rules view_algorithm, view_suid, view_check_options to return values in $$, instead of setting thd->lex members directly. This is needed to pass these values to the new methods LEX::add_alter_view() and LEX::add_create_view().
  • Do corresponding changes in sql_yacc_ora.yy.

Generated at Thu Feb 08 08:03:40 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.