Commit d75ef02a authored by Alexander Barkov's avatar Alexander Barkov

MDEV-32220 sql_yacc.yy: unify the drop_routine rule

- Removing two copies of the drop_routine.
  Adding a shared and much simplified version.

- Removing LEX metods:
      bool stmt_drop_function(const DDL_options_st &options,
                              const Lex_ident_sys_st &db,
                              const Lex_ident_sys_st &name);

      bool stmt_drop_function(const DDL_options_st &options,
                              const Lex_ident_sys_st &name);

      bool stmt_drop_procedure(const DDL_options_st &options,
                               sp_name *name);

  The code inside the methods was very similar.
  Adding one method instead:

      bool stmt_drop_routine(const Sp_handler *sph,
                          const DDL_options_st &options,
                          const Lex_ident_sys_st &db,
                          const Lex_ident_sys_st &name);

- Adding a new virtual method Sp_handler:sqlcom_drop().
  It helped to unify the code inside the new stmt_drop_routine().
parent 19885128
......@@ -157,6 +157,7 @@ class Sp_handler
}
virtual enum_sp_type type() const= 0;
virtual LEX_CSTRING type_lex_cstring() const= 0;
virtual enum_sql_command sqlcom_drop() const= 0;
virtual LEX_CSTRING empty_body_lex_cstring(sql_mode_t mode) const
{
static LEX_CSTRING m_empty_body= {STRING_WITH_LEN("???")};
......@@ -256,6 +257,7 @@ class Sp_handler_procedure: public Sp_handler
static LEX_CSTRING m_type_str= { STRING_WITH_LEN("PROCEDURE")};
return m_type_str;
}
enum_sql_command sqlcom_drop() const { return SQLCOM_DROP_PROCEDURE; }
LEX_CSTRING empty_body_lex_cstring(sql_mode_t mode) const;
const char *show_create_routine_col1_caption() const
{
......@@ -306,6 +308,7 @@ class Sp_handler_function: public Sp_handler
static LEX_CSTRING m_type_str= { STRING_WITH_LEN("FUNCTION")};
return m_type_str;
}
enum_sql_command sqlcom_drop() const { return SQLCOM_DROP_FUNCTION; }
LEX_CSTRING empty_body_lex_cstring(sql_mode_t mode) const;
const char *show_create_routine_col1_caption() const
{
......@@ -375,6 +378,7 @@ class Sp_handler_package_spec: public Sp_handler_package
static LEX_CSTRING m_type_str= {STRING_WITH_LEN("PACKAGE")};
return m_type_str;
}
enum_sql_command sqlcom_drop() const { return SQLCOM_DROP_PACKAGE; }
LEX_CSTRING empty_body_lex_cstring(sql_mode_t mode) const
{
static LEX_CSTRING m_empty_body= {STRING_WITH_LEN("BEGIN END")};
......@@ -408,6 +412,7 @@ class Sp_handler_package_body: public Sp_handler_package
static LEX_CSTRING m_type_str= {STRING_WITH_LEN("PACKAGE BODY")};
return m_type_str;
}
enum_sql_command sqlcom_drop() const { return SQLCOM_DROP_PACKAGE_BODY; }
LEX_CSTRING empty_body_lex_cstring(sql_mode_t mode) const
{
static LEX_CSTRING m_empty_body= {STRING_WITH_LEN("BEGIN END")};
......@@ -441,6 +446,7 @@ class Sp_handler_trigger: public Sp_handler
static LEX_CSTRING m_type_str= { STRING_WITH_LEN("TRIGGER")};
return m_type_str;
}
enum_sql_command sqlcom_drop() const { return SQLCOM_DROP_TRIGGER; }
MDL_key::enum_mdl_namespace get_mdl_type() const
{
DBUG_ASSERT(0);
......
......@@ -11487,54 +11487,68 @@ bool LEX::stmt_create_stored_function_start(const DDL_options_st &options,
}
bool LEX::stmt_drop_function(const DDL_options_st &options,
const Lex_ident_sys_st &db,
const Lex_ident_sys_st &name)
/*
Process a drop routine statement:
DROP {FUNCTION|PROCEDURE|PACKAGE|PACKAGE BODY}
[IF NOT EXISTS ] [db.]name;
@param sph - The stored routine
@param options - The IF EXISTS clause
@param db - The database name.
It can be {NULL,0}, which means the routine name
is not qualified with the database name.
@param name - The routine name
@returns - false ok success, true on error.
*/
bool LEX::stmt_drop_routine(const Sp_handler *sph,
const DDL_options_st &options,
const Lex_ident_sys_st &db,
const Lex_ident_sys_st &name)
{
DBUG_ASSERT(db.str);
DBUG_ASSERT(name.str);
const Lex_ident_db db_int= thd->to_ident_db_internal_with_error(db);
if (unlikely(!db_int.str))
return true;
if (unlikely(sphead))
{
my_error(ER_SP_NO_DROP_SP, MYF(0), "FUNCTION");
my_error(ER_SP_NO_DROP_SP, MYF(0), sph->type_lex_cstring().str);
return true;
}
set_command(SQLCOM_DROP_FUNCTION, options);
spname= new (thd->mem_root) sp_name(&db_int, &name, true);
return spname == NULL;
}
bool LEX::stmt_drop_function(const DDL_options_st &options,
const Lex_ident_sys_st &name)
{
LEX_CSTRING db= {0, 0};
if (unlikely(sphead))
{
my_error(ER_SP_NO_DROP_SP, MYF(0), "FUNCTION");
if (check_routine_name(&name))
return true;
enum_sql_command sqlcom= sph->sqlcom_drop();
LEX_CSTRING db_int= {0, 0};
if (db.str)
{
// An explicit database name is given
if (!(db_int= thd->to_ident_db_internal_with_error(db)).str)
return true;
}
if (thd->db.str && unlikely(copy_db_to(&db)))
return true;
set_command(SQLCOM_DROP_FUNCTION, options);
spname= new (thd->mem_root) sp_name(&db, &name, false);
return spname == NULL;
}
bool LEX::stmt_drop_procedure(const DDL_options_st &options,
sp_name *name)
{
if (unlikely(sphead))
else if (thd->db.str || sqlcom != SQLCOM_DROP_FUNCTION)
{
my_error(ER_SP_NO_DROP_SP, MYF(0), "PROCEDURE");
return true;
/*
There is no an explicit database name in the DROP statement.
Two cases are possible:
a. The current database is not NULL.
copy_db_to() copies the current database to db_int.
b. The current database is NULL and the command is either of these:
- DROP PACKAGE
- DROP PACKAGE BODY
- DROP PROCEDURE
copy_db_to() raises ER_NO_DB_ERROR.
*/
if (copy_db_to(&db_int))
return true;
}
set_command(SQLCOM_DROP_PROCEDURE, options);
spname= name;
else
{
/*
This is a "DROP FUNCTION name" statement.
There is no an explicit database name given.
The current database is not set.
It can still be a valid DROP FUNCTION - for an UDF.
Keep db_int=={NULL,0}.
*/
}
set_command(sqlcom, options);
spname= new (thd->mem_root) sp_name(&db_int, &name, db.str != NULL);
return false;
}
......
......@@ -4852,15 +4852,10 @@ struct LEX: public Query_tables_list
Item_result return_type,
const LEX_CSTRING &soname);
bool stmt_drop_function(const DDL_options_st &options,
const Lex_ident_sys_st &db,
const Lex_ident_sys_st &name);
bool stmt_drop_function(const DDL_options_st &options,
const Lex_ident_sys_st &name);
bool stmt_drop_procedure(const DDL_options_st &options,
sp_name *name);
bool stmt_drop_routine(const Sp_handler *sph,
const DDL_options_st &options,
const Lex_ident_sys_st &db,
const Lex_ident_sys_st &name);
bool stmt_alter_function_start(sp_name *name);
bool stmt_alter_procedure_start(sp_name *name);
......
......@@ -3016,6 +3016,20 @@ sp_handler:
;
drop_routine:
DROP sp_handler opt_if_exists ident '.' ident
{
if (Lex->stmt_drop_routine($2, $3, $4, $6))
MYSQL_YYABORT;
}
| DROP sp_handler opt_if_exists ident
{
if (Lex->stmt_drop_routine($2, $3, Lex_ident_sys(), $4))
MYSQL_YYABORT;
}
;
sp_name:
ident '.' ident
{
......@@ -18441,25 +18455,6 @@ sp_tail_standalone:
}
;
drop_routine:
DROP FUNCTION_SYM opt_if_exists ident '.' ident
{
if (Lex->stmt_drop_function($3, $4, $6))
MYSQL_YYABORT;
}
| DROP FUNCTION_SYM opt_if_exists ident
{
if (Lex->stmt_drop_function($3, $4))
MYSQL_YYABORT;
}
| DROP PROCEDURE_SYM opt_if_exists sp_name
{
if (Lex->stmt_drop_procedure($3, $4))
MYSQL_YYABORT;
}
;
create_routine:
create_or_replace definer_opt PROCEDURE_SYM opt_if_not_exists
{
......@@ -19346,40 +19341,6 @@ sp_tail_standalone:
}
;
drop_routine:
DROP FUNCTION_SYM opt_if_exists ident '.' ident
{
if (Lex->stmt_drop_function($3, $4, $6))
MYSQL_YYABORT;
}
| DROP FUNCTION_SYM opt_if_exists ident
{
if (Lex->stmt_drop_function($3, $4))
MYSQL_YYABORT;
}
| DROP PROCEDURE_SYM opt_if_exists sp_name
{
if (Lex->stmt_drop_procedure($3, $4))
MYSQL_YYABORT;
}
| DROP PACKAGE_ORACLE_SYM opt_if_exists sp_name
{
LEX *lex= Lex;
lex->set_command(SQLCOM_DROP_PACKAGE, $3);
if (unlikely(lex->sphead))
my_yyabort_error((ER_SP_NO_DROP_SP, MYF(0), "PACKAGE"));
lex->spname= $4;
}
| DROP PACKAGE_ORACLE_SYM BODY_ORACLE_SYM opt_if_exists sp_name
{
LEX *lex= Lex;
lex->set_command(SQLCOM_DROP_PACKAGE_BODY, $4);
if (unlikely(lex->sphead))
my_yyabort_error((ER_SP_NO_DROP_SP, MYF(0), "PACKAGE BODY"));
lex->spname= $5;
}
;
create_routine:
create_or_replace definer_opt PROCEDURE_SYM opt_if_not_exists
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment