Commit 60277b8b authored by Alexander Barkov's avatar Alexander Barkov

MDEV-7287 VIEW: CREATE IF NOT EXISTS

Forgot to do "git add" for a number of files in the previous commit.
parent acdc3834
......@@ -27,3 +27,34 @@ Log_name Pos Event_type Server_id End_log_pos Info
# # Query 1 # DROP DATABASE IF EXISTS d1
RESET MASTER;
USE test;
CREATE OR REPLACE VIEW v1 AS SELECT 1;
CREATE OR REPLACE VIEW v1 AS SELECT 1;
DROP VIEW v1;
CREATE VIEW IF NOT EXISTS v1 AS SELECT 1;
CREATE VIEW IF NOT EXISTS v1 AS SELECT 1;
Warnings:
Note 1050 Table 'test' already exists
DROP VIEW IF EXISTS v1;
DROP VIEW IF EXISTS v1;
Warnings:
Note 1051 Unknown table 'test.v1'
SHOW BINLOG EVENTS;
Log_name Pos Event_type Server_id End_log_pos Info
# # Format_desc 1 # VER
# # Gtid_list 1 # []
# # Binlog_checkpoint 1 # master-bin.000001
# # Gtid 1 # GTID #-#-#
# # Query 1 # use `test`; CREATE OR REPLACE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS SELECT 1
# # Gtid 1 # GTID #-#-#
# # Query 1 # use `test`; CREATE OR REPLACE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS SELECT 1
# # Gtid 1 # GTID #-#-#
# # Query 1 # use `test`; DROP VIEW v1
# # Gtid 1 # GTID #-#-#
# # Query 1 # use `test`; CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW IF NOT EXISTS `v1` AS SELECT 1
# # Gtid 1 # GTID #-#-#
# # Query 1 # use `test`; CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW IF NOT EXISTS `v1` AS SELECT 1
# # Gtid 1 # GTID #-#-#
# # Query 1 # use `test`; DROP VIEW IF EXISTS v1
# # Gtid 1 # GTID #-#-#
# # Query 1 # use `test`; DROP VIEW IF EXISTS v1
RESET MASTER;
......@@ -18,3 +18,16 @@ DROP DATABASE IF EXISTS d1;
--enable_query_log
RESET MASTER;
USE test;
CREATE OR REPLACE VIEW v1 AS SELECT 1;
CREATE OR REPLACE VIEW v1 AS SELECT 1;
DROP VIEW v1;
CREATE VIEW IF NOT EXISTS v1 AS SELECT 1;
CREATE VIEW IF NOT EXISTS v1 AS SELECT 1;
DROP VIEW IF EXISTS v1;
DROP VIEW IF EXISTS v1;
--replace_column 1 # 2 # 5 #
--replace_regex /xid=[0-9]+/xid=XX/ /GTID [0-9]+-[0-9]+-[0-9]+/GTID #-#-#/ /Server.ver.*/VER/
SHOW BINLOG EVENTS;
RESET MASTER;
......@@ -2830,18 +2830,27 @@ struct LEX: public Query_tables_list
set_command(command, options);
create_info.options|= scope; // HA_LEX_CREATE_TMP_TABLE or 0
}
bool set_command_with_check(enum_sql_command command,
uint scope,
DDL_options_st options)
bool check_create_options(DDL_options_st options)
{
if (options.or_replace() && options.if_not_exists())
{
my_error(ER_WRONG_USAGE, MYF(0), "OR REPLACE", "IF NOT EXISTS");
return true;
}
set_command(command, scope, options);
return false;
}
bool add_create_options_with_check(DDL_options_st options)
{
create_info.add(options);
return check_create_options(create_info);
}
bool set_command_with_check(enum_sql_command command,
uint scope,
DDL_options_st options)
{
set_command(command, scope, options);
return check_create_options(options);
}
/*
DROP shares lex->create_info to store TEMPORARY and IF EXISTS options
to save on extra initialization in lex_start().
......
......@@ -635,6 +635,11 @@ bool mysql_create_view(THD *thd, TABLE_LIST *views,
command[thd->lex->create_view_mode].length);
view_store_options(thd, views, &buff);
buff.append(STRING_WITH_LEN("VIEW "));
/* Appending IF NOT EXISTS if present in the query */
if (lex->create_info.if_not_exists())
buff.append(STRING_WITH_LEN("IF NOT EXISTS "));
/* Test if user supplied a db (ie: we did not use thd->db) */
if (views->db && views->db[0] &&
(thd->db == NULL || strcmp(views->db, thd->db)))
......@@ -857,6 +862,14 @@ static int mysql_register_view(THD *thd, TABLE_LIST *view,
view->definer.host= lex->definer->host;
view->view_suid= lex->create_view_suid;
view->with_check= lex->create_view_check;
DBUG_EXECUTE_IF("simulate_register_view_failure",
{
my_error(ER_OUT_OF_RESOURCES, MYF(0));
error= -1;
goto err;
});
if ((view->updatable_view= (can_be_merged &&
view->algorithm != VIEW_ALGORITHM_TMPTABLE)))
{
......@@ -909,7 +922,14 @@ loop_out:
if (ha_table_exists(thd, view->db, view->table_name, NULL))
{
if (mode == VIEW_CREATE_NEW)
if (lex->create_info.if_not_exists())
{
push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE,
ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR),
view->db, view->table_name);
DBUG_RETURN(0);
}
else if (mode == VIEW_CREATE_NEW)
{
my_error(ER_TABLE_EXISTS_ERROR, MYF(0), view->alias);
error= -1;
......
......@@ -2552,6 +2552,7 @@ create:
}
| 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;
......@@ -2559,6 +2560,7 @@ create:
}
view_or_trigger_or_sp_or_event
{
// TODO: remove this when "MDEV-5359 CREATE OR REPLACE..." is done
if ($1.or_replace() && Lex->sql_command != SQLCOM_CREATE_VIEW)
{
my_error(ER_WRONG_USAGE, MYF(0), "OR REPLACE",
......@@ -16059,12 +16061,14 @@ view_suid:
;
view_tail:
view_suid VIEW_SYM table_ident
view_suid VIEW_SYM opt_if_not_exists table_ident
{
LEX *lex= thd->lex;
if (lex->add_create_options_with_check($3))
MYSQL_YYABORT;
lex->sql_command= SQLCOM_CREATE_VIEW;
/* first table in list is target VIEW name */
if (!lex->select_lex.add_table_to_list(thd, $3, NULL,
if (!lex->select_lex.add_table_to_list(thd, $4, NULL,
TL_OPTION_UPDATING,
TL_IGNORE,
MDL_EXCLUSIVE))
......
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