summaryrefslogtreecommitdiff
path: root/sql/sql_table.cc
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2019-05-10 08:02:21 +0300
committerMarko Mäkelä <marko.makela@mariadb.com>2019-05-10 08:02:21 +0300
commitb2f3755c8e174ec5385c9a56783f0a77f054c562 (patch)
treebb00279f39334fb1a9afceca99da2c3179ec94df /sql/sql_table.cc
parent136a27d9f16fd19f0196a798d752a3dcf0fe57c2 (diff)
parent3e8cab51cb78f3e60e139af944eef8f25502fc81 (diff)
downloadmariadb-git-b2f3755c8e174ec5385c9a56783f0a77f054c562.tar.gz
Merge 10.1 into 10.2
Diffstat (limited to 'sql/sql_table.cc')
-rw-r--r--sql/sql_table.cc95
1 files changed, 46 insertions, 49 deletions
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index bb6945c7e01..e2c44fa9af3 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -1,6 +1,6 @@
/*
Copyright (c) 2000, 2016, Oracle and/or its affiliates.
- Copyright (c) 2010, 2018, MariaDB
+ Copyright (c) 2010, 2019, MariaDB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -8504,6 +8504,50 @@ static bool fk_prepare_copy_alter_table(THD *thd, TABLE *table,
}
}
+ /*
+ Normally, an attempt to modify an FK parent table will cause
+ FK children to be prelocked, so the table-being-altered cannot
+ be modified by a cascade FK action, because ALTER holds a lock
+ and prelocking will wait.
+
+ But if a new FK is being added by this very ALTER, then the target
+ table is not locked yet (it's a temporary table). So, we have to
+ lock FK parents explicitly.
+ */
+ if (alter_info->flags & Alter_info::ADD_FOREIGN_KEY)
+ {
+ List_iterator<Key> fk_list_it(alter_info->key_list);
+
+ while (Key *key= fk_list_it++)
+ {
+ if (key->type != Key::FOREIGN_KEY)
+ continue;
+
+ Foreign_key *fk= static_cast<Foreign_key*>(key);
+ char dbuf[NAME_LEN];
+ char tbuf[NAME_LEN];
+ const char *ref_db= fk->ref_db.str ? fk->ref_db.str : alter_ctx->new_db;
+ const char *ref_table= fk->ref_table.str;
+ MDL_request mdl_request;
+
+ if (lower_case_table_names)
+ {
+ strmake_buf(dbuf, ref_db);
+ my_casedn_str(system_charset_info, dbuf);
+ strmake_buf(tbuf, ref_table);
+ my_casedn_str(system_charset_info, tbuf);
+ ref_db= dbuf;
+ ref_table= tbuf;
+ }
+
+ mdl_request.init(MDL_key::TABLE, ref_db, ref_table, MDL_SHARED_NO_WRITE,
+ MDL_TRANSACTION);
+ if (thd->mdl_context.acquire_lock(&mdl_request,
+ thd->variables.lock_wait_timeout))
+ DBUG_RETURN(true);
+ }
+ }
+
DBUG_RETURN(false);
}
@@ -9504,6 +9548,7 @@ do_continue:;
/* Mark that we have created table in storage engine. */
no_ha_table= false;
+ DEBUG_SYNC(thd, "alter_table_intermediate_table_created");
new_table=
thd->create_and_open_tmp_table(new_db_type, &frm, alter_ctx.get_tmp_path(),
@@ -9517,54 +9562,6 @@ do_continue:;
/* in case of alter temp table send the tracker in OK packet */
SESSION_TRACKER_CHANGED(thd, SESSION_STATE_CHANGE_TRACKER, NULL);
}
- else
- {
- /*
- Normally, an attempt to modify an FK parent table will cause
- FK children to be prelocked, so the table-being-altered cannot
- be modified by a cascade FK action, because ALTER holds a lock
- and prelocking will wait.
-
- But if a new FK is being added by this very ALTER, then the target
- table is not locked yet (it's a temporary table). So, we have to
- lock FK parents explicitly.
- */
- if (alter_info->flags & Alter_info::ADD_FOREIGN_KEY)
- {
- List <FOREIGN_KEY_INFO> fk_list;
- List_iterator<FOREIGN_KEY_INFO> fk_list_it(fk_list);
- FOREIGN_KEY_INFO *fk;
-
- /* tables_opened can be > 1 only for MERGE tables */
- DBUG_ASSERT(tables_opened == 1);
- DBUG_ASSERT(&table_list->next_global == thd->lex->query_tables_last);
-
- new_table->file->get_foreign_key_list(thd, &fk_list);
- while ((fk= fk_list_it++))
- {
- MDL_request mdl_request;
-
- if (lower_case_table_names)
- {
- char buf[NAME_LEN];
- uint len;
- strmake_buf(buf, fk->referenced_db->str);
- len = my_casedn_str(files_charset_info, buf);
- thd->make_lex_string(fk->referenced_db, buf, len);
- strmake_buf(buf, fk->referenced_table->str);
- len = my_casedn_str(files_charset_info, buf);
- thd->make_lex_string(fk->referenced_table, buf, len);
- }
-
- mdl_request.init(MDL_key::TABLE,
- fk->referenced_db->str, fk->referenced_table->str,
- MDL_SHARED_NO_WRITE, MDL_TRANSACTION);
- if (thd->mdl_context.acquire_lock(&mdl_request,
- thd->variables.lock_wait_timeout))
- goto err_new_table_cleanup;
- }
- }
- }
/*
Note: In case of MERGE table, we do not attach children. We do not