Commit 96d1cdec authored by Alexander Barkov's avatar Alexander Barkov

MDEV-13197 Parser refactoring for CREATE VIEW,TRIGGER,SP,UDF,EVENT

parent 505a11d9
...@@ -6501,3 +6501,14 @@ DROP VIEW v; ...@@ -6501,3 +6501,14 @@ DROP VIEW v;
# #
# End of 10.2 tests # End of 10.2 tests
# #
#
# Start of 10.3 tests
#
#
# MDEV-13197 Parser refactoring for CREATE VIEW,TRIGGER,SP,UDF,EVENT
#
ALTER VIEW IF NOT EXISTS v1 AS SELECT 1;
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'IF NOT EXISTS v1 AS SELECT 1' at line 1
#
# End of 10.3 tests
#
...@@ -6213,3 +6213,19 @@ DROP VIEW v; ...@@ -6213,3 +6213,19 @@ DROP VIEW v;
--echo # --echo #
--echo # End of 10.2 tests --echo # End of 10.2 tests
--echo # --echo #
--echo #
--echo # Start of 10.3 tests
--echo #
--echo #
--echo # MDEV-13197 Parser refactoring for CREATE VIEW,TRIGGER,SP,UDF,EVENT
--echo #
--error ER_PARSE_ERROR
ALTER VIEW IF NOT EXISTS v1 AS SELECT 1;
--echo #
--echo # End of 10.3 tests
--echo #
...@@ -689,6 +689,7 @@ void LEX::start(THD *thd_arg) ...@@ -689,6 +689,7 @@ void LEX::start(THD *thd_arg)
curr_with_clause= 0; curr_with_clause= 0;
with_clauses_list= 0; with_clauses_list= 0;
with_clauses_list_last_next= &with_clauses_list; with_clauses_list_last_next= &with_clauses_list;
create_view= NULL;
value_list.empty(); value_list.empty();
update_list.empty(); update_list.empty();
set_var_list.empty(); set_var_list.empty();
...@@ -7057,3 +7058,49 @@ bool LEX::sp_add_cfetch(THD *thd, const LEX_CSTRING *name) ...@@ -7057,3 +7058,49 @@ bool LEX::sp_add_cfetch(THD *thd, const LEX_CSTRING *name)
return true; return true;
return false; return false;
} }
bool LEX::create_or_alter_view_finalize(THD *thd, Table_ident *table_ident)
{
sql_command= SQLCOM_CREATE_VIEW;
/* first table in list is target VIEW name */
if (!select_lex.add_table_to_list(thd, table_ident, NULL,
TL_OPTION_UPDATING,
TL_IGNORE,
MDL_EXCLUSIVE))
return true;
query_tables->open_strategy= TABLE_LIST::OPEN_STUB;
return false;
}
bool LEX::add_alter_view(THD *thd, uint16 algorithm,
enum_view_suid suid,
Table_ident *table_ident)
{
if (sphead)
{
my_error(ER_SP_BADSTATEMENT, MYF(0), "ALTER VIEW");
return true;
}
if (!(create_view= new (thd->mem_root)
Create_view_info(VIEW_ALTER, algorithm, suid)))
return true;
return create_or_alter_view_finalize(thd, table_ident);
}
bool LEX::add_create_view(THD *thd, DDL_options_st ddl,
uint16 algorithm, enum_view_suid suid,
Table_ident *table_ident)
{
if (set_create_options_with_check(ddl))
return true;
if (!(create_view= new (thd->mem_root)
Create_view_info(ddl.or_replace() ?
VIEW_CREATE_OR_REPLACE :
VIEW_CREATE_NEW,
algorithm, suid)))
return true;
return create_or_alter_view_finalize(thd, table_ident);
}
...@@ -75,6 +75,14 @@ enum sub_select_type ...@@ -75,6 +75,14 @@ enum sub_select_type
GLOBAL_OPTIONS_TYPE, DERIVED_TABLE_TYPE, OLAP_TYPE GLOBAL_OPTIONS_TYPE, DERIVED_TABLE_TYPE, OLAP_TYPE
}; };
enum unit_common_op {OP_MIX, OP_UNION, OP_INTERSECT, OP_EXCEPT}; enum unit_common_op {OP_MIX, OP_UNION, OP_INTERSECT, OP_EXCEPT};
enum enum_view_suid
{
VIEW_SUID_INVOKER= 0,
VIEW_SUID_DEFINER= 1,
VIEW_SUID_DEFAULT= 2
};
/* These may not be declared yet */ /* These may not be declared yet */
class Table_ident; class Table_ident;
class sql_exchange; class sql_exchange;
...@@ -98,7 +106,6 @@ struct sql_digest_state; ...@@ -98,7 +106,6 @@ struct sql_digest_state;
class With_clause; class With_clause;
class my_var; class my_var;
#define ALLOC_ROOT_SET 1024 #define ALLOC_ROOT_SET 1024
#ifdef MYSQL_SERVER #ifdef MYSQL_SERVER
...@@ -239,6 +246,27 @@ enum enum_view_create_mode ...@@ -239,6 +246,27 @@ enum enum_view_create_mode
VIEW_CREATE_OR_REPLACE // check only that there are not such table VIEW_CREATE_OR_REPLACE // check only that there are not such table
}; };
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)
{ }
};
enum enum_drop_mode enum enum_drop_mode
{ {
DROP_DEFAULT, // mode is not specified DROP_DEFAULT, // mode is not specified
...@@ -2607,6 +2635,8 @@ struct LEX: public Query_tables_list ...@@ -2607,6 +2635,8 @@ struct LEX: public Query_tables_list
*/ */
With_clause **with_clauses_list_last_next; With_clause **with_clauses_list_last_next;
Create_view_info *create_view;
/* Query Plan Footprint of a currently running select */ /* Query Plan Footprint of a currently running select */
Explain_query *explain; Explain_query *explain;
...@@ -2630,9 +2660,6 @@ struct LEX: public Query_tables_list ...@@ -2630,9 +2660,6 @@ struct LEX: public Query_tables_list
DYNAMIC_ARRAY plugins; DYNAMIC_ARRAY plugins;
plugin_ref plugins_static_buffer[INITIAL_LEX_PLUGIN_LIST_SIZE]; plugin_ref plugins_static_buffer[INITIAL_LEX_PLUGIN_LIST_SIZE];
/** SELECT of CREATE VIEW statement */
LEX_CSTRING create_view_select;
uint number_of_selects; // valid only for view uint number_of_selects; // valid only for view
/** Start of 'ON table', in trigger statements. */ /** Start of 'ON table', in trigger statements. */
...@@ -2759,7 +2786,6 @@ struct LEX: public Query_tables_list ...@@ -2759,7 +2786,6 @@ struct LEX: public Query_tables_list
bool with_persistent_for_clause; // uses PERSISTENT FOR clause (in ANALYZE) bool with_persistent_for_clause; // uses PERSISTENT FOR clause (in ANALYZE)
}; };
enum enum_var_type option_type; enum enum_var_type option_type;
enum enum_view_create_mode create_view_mode;
enum enum_drop_mode drop_mode; enum enum_drop_mode drop_mode;
uint profile_query_id; uint profile_query_id;
...@@ -2785,8 +2811,6 @@ struct LEX: public Query_tables_list ...@@ -2785,8 +2811,6 @@ struct LEX: public Query_tables_list
DERIVED_SUBQUERY and DERIVED_VIEW). DERIVED_SUBQUERY and DERIVED_VIEW).
*/ */
uint8 derived_tables; uint8 derived_tables;
uint16 create_view_algorithm;
uint8 create_view_check;
uint8 context_analysis_only; uint8 context_analysis_only;
bool local_file; bool local_file;
bool check_exists; bool check_exists;
...@@ -2827,10 +2851,6 @@ struct LEX: public Query_tables_list ...@@ -2827,10 +2851,6 @@ struct LEX: public Query_tables_list
rexecuton rexecuton
*/ */
bool empty_field_list_on_rset; bool empty_field_list_on_rset;
/*
view created to be run from definer (standard behaviour)
*/
uint8 create_view_suid;
/* Characterstics of trigger being created */ /* Characterstics of trigger being created */
st_trg_chistics trg_chistics; st_trg_chistics trg_chistics;
/* /*
...@@ -3582,6 +3602,11 @@ struct LEX: public Query_tables_list ...@@ -3582,6 +3602,11 @@ struct LEX: public Query_tables_list
} }
return false; return false;
} }
bool set_create_options_with_check(DDL_options_st options)
{
create_info.set(options);
return check_create_options(create_info);
}
bool add_create_options_with_check(DDL_options_st options) bool add_create_options_with_check(DDL_options_st options)
{ {
create_info.add(options); create_info.add(options);
...@@ -3613,6 +3638,12 @@ struct LEX: public Query_tables_list ...@@ -3613,6 +3638,12 @@ struct LEX: public Query_tables_list
SELECT_LEX *exclude_last_select(); SELECT_LEX *exclude_last_select();
bool add_unit_in_brackets(SELECT_LEX *nselect); bool add_unit_in_brackets(SELECT_LEX *nselect);
void check_automatic_up(enum sub_select_type type); void check_automatic_up(enum sub_select_type type);
bool create_or_alter_view_finalize(THD *thd, Table_ident *table_ident);
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);
}; };
......
...@@ -6033,10 +6033,10 @@ mysql_execute_command(THD *thd) ...@@ -6033,10 +6033,10 @@ mysql_execute_command(THD *thd)
{ {
/* /*
Note: SQLCOM_CREATE_VIEW also handles 'ALTER VIEW' commands Note: SQLCOM_CREATE_VIEW also handles 'ALTER VIEW' commands
as specified through the thd->lex->create_view_mode flag. as specified through the thd->lex->create_view->mode flag.
*/ */
WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL) WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL)
res= mysql_create_view(thd, first_table, thd->lex->create_view_mode); res= mysql_create_view(thd, first_table, thd->lex->create_view->mode);
break; break;
} }
case SQLCOM_DROP_VIEW: case SQLCOM_DROP_VIEW:
......
...@@ -2072,7 +2072,7 @@ static bool mysql_test_create_view(Prepared_statement *stmt) ...@@ -2072,7 +2072,7 @@ static bool mysql_test_create_view(Prepared_statement *stmt)
TABLE_LIST *view= lex->unlink_first_table(&link_to_local); TABLE_LIST *view= lex->unlink_first_table(&link_to_local);
TABLE_LIST *tables= lex->query_tables; TABLE_LIST *tables= lex->query_tables;
if (create_view_precheck(thd, tables, view, lex->create_view_mode)) if (create_view_precheck(thd, tables, view, lex->create_view->mode))
goto err; goto err;
/* /*
...@@ -2448,7 +2448,7 @@ static bool check_prepared_statement(Prepared_statement *stmt) ...@@ -2448,7 +2448,7 @@ static bool check_prepared_statement(Prepared_statement *stmt)
} }
break; break;
case SQLCOM_CREATE_VIEW: case SQLCOM_CREATE_VIEW:
if (lex->create_view_mode == VIEW_ALTER) if (lex->create_view->mode == VIEW_ALTER)
{ {
my_message(ER_UNSUPPORTED_PS, ER_THD(thd, ER_UNSUPPORTED_PS), MYF(0)); my_message(ER_UNSUPPORTED_PS, ER_THD(thd, ER_UNSUPPORTED_PS), MYF(0));
goto error; goto error;
......
...@@ -225,10 +225,10 @@ fill_defined_view_parts (THD *thd, TABLE_LIST *view) ...@@ -225,10 +225,10 @@ fill_defined_view_parts (THD *thd, TABLE_LIST *view)
view->definer.user= decoy.definer.user; view->definer.user= decoy.definer.user;
lex->definer= &view->definer; lex->definer= &view->definer;
} }
if (lex->create_view_algorithm == VIEW_ALGORITHM_INHERIT) if (lex->create_view->algorithm == VIEW_ALGORITHM_INHERIT)
lex->create_view_algorithm= (uint8) decoy.algorithm; lex->create_view->algorithm= (uint8) decoy.algorithm;
if (lex->create_view_suid == VIEW_SUID_DEFAULT) if (lex->create_view->suid == VIEW_SUID_DEFAULT)
lex->create_view_suid= decoy.view_suid ? lex->create_view->suid= decoy.view_suid ?
VIEW_SUID_DEFINER : VIEW_SUID_INVOKER; VIEW_SUID_DEFINER : VIEW_SUID_INVOKER;
return FALSE; return FALSE;
...@@ -647,8 +647,8 @@ bool mysql_create_view(THD *thd, TABLE_LIST *views, ...@@ -647,8 +647,8 @@ bool mysql_create_view(THD *thd, TABLE_LIST *views,
{ C_STRING_WITH_LEN("ALTER ") }, { C_STRING_WITH_LEN("ALTER ") },
{ C_STRING_WITH_LEN("CREATE OR REPLACE ") }}; { C_STRING_WITH_LEN("CREATE OR REPLACE ") }};
buff.append(command[thd->lex->create_view_mode].str, buff.append(command[thd->lex->create_view->mode].str,
command[thd->lex->create_view_mode].length); command[thd->lex->create_view->mode].length);
view_store_options(thd, views, &buff); view_store_options(thd, views, &buff);
buff.append(STRING_WITH_LEN("VIEW ")); buff.append(STRING_WITH_LEN("VIEW "));
...@@ -934,7 +934,7 @@ static int mysql_register_view(THD *thd, TABLE_LIST *view, ...@@ -934,7 +934,7 @@ static int mysql_register_view(THD *thd, TABLE_LIST *view,
DBUG_PRINT("info", ("View: %.*s", view_query.length(), view_query.ptr())); DBUG_PRINT("info", ("View: %.*s", view_query.length(), view_query.ptr()));
/* fill structure */ /* fill structure */
view->source= thd->lex->create_view_select; view->source= thd->lex->create_view->select;
if (!thd->make_lex_string(&view->select_stmt, view_query.ptr(), if (!thd->make_lex_string(&view->select_stmt, view_query.ptr(),
view_query.length())) view_query.length()))
...@@ -959,18 +959,18 @@ static int mysql_register_view(THD *thd, TABLE_LIST *view, ...@@ -959,18 +959,18 @@ static int mysql_register_view(THD *thd, TABLE_LIST *view,
} }
view->md5.length= 32; view->md5.length= 32;
can_be_merged= lex->can_be_merged(); can_be_merged= lex->can_be_merged();
if (lex->create_view_algorithm == VIEW_ALGORITHM_MERGE && if (lex->create_view->algorithm == VIEW_ALGORITHM_MERGE &&
!lex->can_be_merged()) !lex->can_be_merged())
{ {
push_warning(thd, Sql_condition::WARN_LEVEL_WARN, ER_WARN_VIEW_MERGE, push_warning(thd, Sql_condition::WARN_LEVEL_WARN, ER_WARN_VIEW_MERGE,
ER_THD(thd, ER_WARN_VIEW_MERGE)); ER_THD(thd, ER_WARN_VIEW_MERGE));
lex->create_view_algorithm= DTYPE_ALGORITHM_UNDEFINED; lex->create_view->algorithm= DTYPE_ALGORITHM_UNDEFINED;
} }
view->algorithm= lex->create_view_algorithm; view->algorithm= lex->create_view->algorithm;
view->definer.user= lex->definer->user; view->definer.user= lex->definer->user;
view->definer.host= lex->definer->host; view->definer.host= lex->definer->host;
view->view_suid= lex->create_view_suid; view->view_suid= lex->create_view->suid;
view->with_check= lex->create_view_check; view->with_check= lex->create_view->check;
DBUG_EXECUTE_IF("simulate_register_view_failure", DBUG_EXECUTE_IF("simulate_register_view_failure",
{ {
......
This diff is collapsed.
This diff is collapsed.
...@@ -1626,10 +1626,6 @@ class IS_table_read_plan; ...@@ -1626,10 +1626,6 @@ class IS_table_read_plan;
#define JOIN_TYPE_RIGHT 2U #define JOIN_TYPE_RIGHT 2U
#define JOIN_TYPE_OUTER 4U /* Marker that this is an outer join */ #define JOIN_TYPE_OUTER 4U /* Marker that this is an outer join */
#define VIEW_SUID_INVOKER 0
#define VIEW_SUID_DEFINER 1
#define VIEW_SUID_DEFAULT 2
/* view WITH CHECK OPTION parameter options */ /* view WITH CHECK OPTION parameter options */
#define VIEW_CHECK_NONE 0 #define VIEW_CHECK_NONE 0
#define VIEW_CHECK_LOCAL 1 #define VIEW_CHECK_LOCAL 1
......
...@@ -1331,8 +1331,8 @@ create_view_query(THD *thd, uchar** buf, size_t* buf_len) ...@@ -1331,8 +1331,8 @@ create_view_query(THD *thd, uchar** buf, size_t* buf_len)
{ C_STRING_WITH_LEN("ALTER ") }, { C_STRING_WITH_LEN("ALTER ") },
{ C_STRING_WITH_LEN("CREATE OR REPLACE ") }}; { C_STRING_WITH_LEN("CREATE OR REPLACE ") }};
buff.append(command[thd->lex->create_view_mode].str, buff.append(command[thd->lex->create_view->mode].str,
command[thd->lex->create_view_mode].length); command[thd->lex->create_view->mode].length);
LEX_USER *definer; LEX_USER *definer;
...@@ -1360,9 +1360,9 @@ create_view_query(THD *thd, uchar** buf, size_t* buf_len) ...@@ -1360,9 +1360,9 @@ create_view_query(THD *thd, uchar** buf, size_t* buf_len)
return 1; return 1;
} }
views->algorithm = lex->create_view_algorithm; views->algorithm = lex->create_view->algorithm;
views->view_suid = lex->create_view_suid; views->view_suid = lex->create_view->suid;
views->with_check = lex->create_view_check; views->with_check = lex->create_view->check;
view_store_options(thd, views, &buff); view_store_options(thd, views, &buff);
buff.append(STRING_WITH_LEN("VIEW ")); buff.append(STRING_WITH_LEN("VIEW "));
...@@ -1391,8 +1391,8 @@ create_view_query(THD *thd, uchar** buf, size_t* buf_len) ...@@ -1391,8 +1391,8 @@ create_view_query(THD *thd, uchar** buf, size_t* buf_len)
} }
buff.append(STRING_WITH_LEN(" AS ")); buff.append(STRING_WITH_LEN(" AS "));
//buff.append(views->source.str, views->source.length); //buff.append(views->source.str, views->source.length);
buff.append(thd->lex->create_view_select.str, buff.append(thd->lex->create_view->select.str,
thd->lex->create_view_select.length); thd->lex->create_view->select.length);
//int errcode= query_error_code(thd, TRUE); //int errcode= query_error_code(thd, TRUE);
//if (thd->binlog_query(THD::STMT_QUERY_TYPE, //if (thd->binlog_query(THD::STMT_QUERY_TYPE,
// buff.ptr(), buff.length(), FALSE, FALSE, FALSE, errcod // buff.ptr(), buff.length(), FALSE, FALSE, FALSE, errcod
......
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