summaryrefslogtreecommitdiff
path: root/storage/innobase
diff options
context:
space:
mode:
authorJan Lindström <jan.lindstrom@mariadb.com>2016-02-03 11:32:51 +0200
committerJan Lindström <jan.lindstrom@mariadb.com>2016-02-03 12:22:31 +0200
commitf66d01610f713a76f38de650464bfaea476b9f32 (patch)
tree81cea0f2531ad287365421dba75b0d93ce92c298 /storage/innobase
parent603c0960ba7e27dfa25c1b0297deb1c4c5ed6746 (diff)
downloadmariadb-git-f66d01610f713a76f38de650464bfaea476b9f32.tar.gz
MDEV-9471: Server crashes or returns an error while trying to alter partitioning on a table moved from Windows to Linux
At alter table when server renames the table to temporal name, old name uses normal partioned table naming rules. However, if tables are created on Windows and then transfered to Linux and lower-case-table-names=1 we should modify the old name on rename to lower case to be able to find it from the InnoDB dictionary.
Diffstat (limited to 'storage/innobase')
-rw-r--r--storage/innobase/row/row0mysql.c49
1 files changed, 49 insertions, 0 deletions
diff --git a/storage/innobase/row/row0mysql.c b/storage/innobase/row/row0mysql.c
index 181ca966451..1a11e398959 100644
--- a/storage/innobase/row/row0mysql.c
+++ b/storage/innobase/row/row0mysql.c
@@ -3838,6 +3838,7 @@ row_rename_table_for_mysql(
ibool old_is_tmp, new_is_tmp;
pars_info_t* info = NULL;
int retry;
+ char* is_part = NULL;
ut_a(old_name != NULL);
ut_a(new_name != NULL);
@@ -3872,6 +3873,54 @@ row_rename_table_for_mysql(
table = dict_table_get_low(old_name, DICT_ERR_IGNORE_NONE);
+ /* We look for pattern #P# to see if the table is partitioned
+ MySQL table. */
+#ifdef __WIN__
+ is_part = strstr(old_name, "#p#");
+#else
+ is_part = strstr(old_name, "#P#");
+#endif /* __WIN__ */
+
+ /* MySQL partition engine hard codes the file name
+ separator as "#P#". The text case is fixed even if
+ lower_case_table_names is set to 1 or 2. This is true
+ for sub-partition names as well. InnoDB always
+ normalises file names to lower case on Windows, this
+ can potentially cause problems when copying/moving
+ tables between platforms.
+
+ 1) If boot against an installation from Windows
+ platform, then its partition table name could
+ be all be in lower case in system tables. So we
+ will need to check lower case name when load table.
+
+ 2) If we boot an installation from other case
+ sensitive platform in Windows, we might need to
+ check the existence of table name without lowering
+ case them in the system table. */
+ if (!table &&
+ is_part &&
+ innobase_get_lower_case_table_names() == 1) {
+ char par_case_name[MAX_FULL_NAME_LEN + 1];
+#ifndef __WIN__
+ /* Check for the table using lower
+ case name, including the partition
+ separator "P" */
+ memcpy(par_case_name, old_name,
+ strlen(old_name));
+ par_case_name[strlen(old_name)] = 0;
+ innobase_casedn_str(par_case_name);
+#else
+ /* On Windows platfrom, check
+ whether there exists table name in
+ system table whose name is
+ not being normalized to lower case */
+ normalize_table_name_low(
+ par_case_name, old_name, FALSE);
+#endif
+ table = dict_table_get_low(par_case_name, DICT_ERR_IGNORE_NONE);
+ }
+
if (!table) {
err = DB_TABLE_NOT_FOUND;
ut_print_timestamp(stderr);