summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksey Midenkov <midenok@gmail.com>2022-10-06 23:37:42 +0300
committerAleksey Midenkov <midenok@gmail.com>2022-10-06 23:37:42 +0300
commit37a86b933e8fc2489b32dff40e7e47d4d5c679ba (patch)
tree2a1a1c3727bd012b52e506f6011dd742e6cd76cd
parent3708bef60683dc7b6020ee76e90738528ccad18a (diff)
parent074e358213ac8f358fa01c2c03ed58e94c81baf8 (diff)
downloadmariadb-git-37a86b933e8fc2489b32dff40e7e47d4d5c679ba.tar.gz
Merge 10.3 into 10.4
-rw-r--r--mysql-test/main/create_or_replace.result9
-rw-r--r--mysql-test/main/create_or_replace.test12
-rw-r--r--mysql-test/main/partition_alter.result11
-rw-r--r--mysql-test/main/partition_alter.test11
-rw-r--r--sql/sql_list.h12
-rw-r--r--sql/sql_table.cc48
6 files changed, 97 insertions, 6 deletions
diff --git a/mysql-test/main/create_or_replace.result b/mysql-test/main/create_or_replace.result
index e41c67bceb4..9a99e42ce74 100644
--- a/mysql-test/main/create_or_replace.result
+++ b/mysql-test/main/create_or_replace.result
@@ -567,4 +567,13 @@ SELECT * FROM t3;
ERROR HY000: Table 't3' was not locked with LOCK TABLES
UNLOCK TABLES;
DROP TABLE t3;
+#
+# MDEV-29697 Assertion failure in Diagnostics_area::set_ok_status
+# upon CREATE OR REPLACE causing ER_UPDATE_TABLE_USED
+#
+CREATE TABLE t (a INT) ENGINE=MyISAM;
+CREATE TABLE tm (a INT) ENGINE=MERGE UNION(t);
+CREATE OR REPLACE TABLE t LIKE tm;
+ERROR HY000: Table 'tm' is specified twice, both as a target for 'CREATE' and as a separate source for data
+DROP TABLE IF EXISTS tm, t;
# End of 10.4 tests
diff --git a/mysql-test/main/create_or_replace.test b/mysql-test/main/create_or_replace.test
index 2b6f2ae4005..978296a4ea4 100644
--- a/mysql-test/main/create_or_replace.test
+++ b/mysql-test/main/create_or_replace.test
@@ -507,4 +507,16 @@ SELECT * FROM t3;
UNLOCK TABLES;
DROP TABLE t3;
+--echo #
+--echo # MDEV-29697 Assertion failure in Diagnostics_area::set_ok_status
+--echo # upon CREATE OR REPLACE causing ER_UPDATE_TABLE_USED
+--echo #
+CREATE TABLE t (a INT) ENGINE=MyISAM;
+CREATE TABLE tm (a INT) ENGINE=MERGE UNION(t);
+--error ER_UPDATE_TABLE_USED
+CREATE OR REPLACE TABLE t LIKE tm;
+
+# Cleanup
+DROP TABLE IF EXISTS tm, t;
+
--echo # End of 10.4 tests
diff --git a/mysql-test/main/partition_alter.result b/mysql-test/main/partition_alter.result
index 18142b63d10..2b0a09d2653 100644
--- a/mysql-test/main/partition_alter.result
+++ b/mysql-test/main/partition_alter.result
@@ -200,4 +200,15 @@ pk
2
delete from t1;
drop table t1;
+#
+# MDEV-28576 RENAME COLUMN with NOCOPY algorithm leads to corrupt partitioned table
+#
+create table t (a int, b int) partition by list (b) (partition p1 values in (1, 2));
+insert into t values (0, 1), (2, 2);
+alter table t change b f int, change a b int, algorithm=nocopy;
+check table t;
+Table Op Msg_type Msg_text
+test.t check status OK
+delete from t order by b limit 1;
+drop table t;
# End of 10.3 tests
diff --git a/mysql-test/main/partition_alter.test b/mysql-test/main/partition_alter.test
index 804b43dc3c2..7a80779e386 100644
--- a/mysql-test/main/partition_alter.test
+++ b/mysql-test/main/partition_alter.test
@@ -185,4 +185,15 @@ select * from t1 partition(p1);
delete from t1;
drop table t1;
+--echo #
+--echo # MDEV-28576 RENAME COLUMN with NOCOPY algorithm leads to corrupt partitioned table
+--echo #
+create table t (a int, b int) partition by list (b) (partition p1 values in (1, 2));
+insert into t values (0, 1), (2, 2);
+alter table t change b f int, change a b int, algorithm=nocopy;
+check table t;
+delete from t order by b limit 1;
+# cleanup
+drop table t;
+
--echo # End of 10.3 tests
diff --git a/sql/sql_list.h b/sql/sql_list.h
index 9d1c01a484d..2da682aee3a 100644
--- a/sql/sql_list.h
+++ b/sql/sql_list.h
@@ -119,8 +119,8 @@ struct list_node :public Sql_alloc
{
list_node *next;
void *info;
- list_node(void *info_par,list_node *next_par)
- :next(next_par),info(info_par)
+ list_node(const void *info_par, list_node *next_par)
+ :next(next_par), info(const_cast<void *>(info_par))
{}
list_node() /* For end_of_list */
{
@@ -385,7 +385,7 @@ public:
#endif // LIST_EXTRA_DEBUG
protected:
- void after(void *info,list_node *node)
+ void after(const void *info, list_node *node)
{
list_node *new_node=new list_node(info,node->next);
node->next=new_node;
@@ -446,11 +446,11 @@ public:
{
el= &list->first;
}
- inline void *replace(void *element)
+ inline void *replace(const void *element)
{ // Return old element
void *tmp=current->info;
DBUG_ASSERT(current->info != 0);
- current->info=element;
+ current->info= const_cast<void *>(element);
return tmp;
}
void *replace(base_list &new_list)
@@ -473,7 +473,7 @@ public:
el=prev;
current=0; // Safeguard
}
- void after(void *element) // Insert element after current
+ void after(const void *element) // Insert element after current
{
list->after(element,current);
current=current->next;
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 2436031200a..6aae927800e 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -5772,6 +5772,7 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table,
if ((duplicate= unique_table(thd, table, src_table, 0)))
{
update_non_unique_table_error(src_table, "CREATE", duplicate);
+ res= 1;
goto err;
}
}
@@ -8055,6 +8056,20 @@ void append_drop_column(THD *thd, String *str, Field *field)
}
+static inline
+void rename_field_in_list(Create_field *field, List<const char> *field_list)
+{
+ DBUG_ASSERT(field->change.str);
+ List_iterator<const char> it(*field_list);
+ while (const char *name= it++)
+ {
+ if (my_strcasecmp(system_charset_info, name, field->change.str))
+ continue;
+ it.replace(field->field_name.str);
+ }
+}
+
+
/**
Prepare column and key definitions for CREATE TABLE in ALTER TABLE.
@@ -8365,6 +8380,39 @@ mysql_prepare_alter_table(THD *thd, TABLE *table,
new_create_tail.push_back(def, thd->mem_root);
}
}
+
+#ifdef WITH_PARTITION_STORAGE_ENGINE
+ if (alter_info->flags & ALTER_RENAME_COLUMN)
+ {
+ if (thd->work_part_info)
+ {
+ partition_info *part_info= thd->work_part_info;
+ List_iterator<Create_field> def_it(column_rename_param.fields);
+ const bool part_field_list= !part_info->part_field_list.is_empty();
+ const bool subpart_field_list= !part_info->subpart_field_list.is_empty();
+ if (part_info->part_expr)
+ part_info->part_expr->walk(&Item::rename_fields_processor, 1,
+ &column_rename_param);
+ if (part_info->subpart_expr)
+ part_info->subpart_expr->walk(&Item::rename_fields_processor, 1,
+ &column_rename_param);
+ if (part_field_list || subpart_field_list)
+ {
+ while (Create_field *def= def_it++)
+ {
+ if (def->change.str)
+ {
+ if (part_field_list)
+ rename_field_in_list(def, &part_info->part_field_list);
+ if (subpart_field_list)
+ rename_field_in_list(def, &part_info->subpart_field_list);
+ } /* if (def->change.str) */
+ } /* while (def) */
+ } /* if (part_field_list || subpart_field_list) */
+ } /* if (part_info) */
+ }
+#endif
+
dropped_sys_vers_fields &= VERS_SYSTEM_FIELD;
if ((dropped_sys_vers_fields ||
alter_info->flags & ALTER_DROP_PERIOD) &&