summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--innobase/dict/dict0dict.c26
-rw-r--r--innobase/include/dict0dict.h5
-rw-r--r--innobase/include/row0mysql.h6
-rw-r--r--innobase/row/row0mysql.c8
-rw-r--r--sql/ha_innodb.cc61
5 files changed, 59 insertions, 47 deletions
diff --git a/innobase/dict/dict0dict.c b/innobase/dict/dict0dict.c
index 9580a80e7e7..5eee57c250b 100644
--- a/innobase/dict/dict0dict.c
+++ b/innobase/dict/dict0dict.c
@@ -2871,8 +2871,12 @@ dict_create_foreign_constraints_low(
table2 can be written also with the database
name before it: test.table2; the default
database is the database of parameter name */
- const char* name) /* in: table full name in the normalized form
+ const char* name, /* in: table full name in the normalized form
database_name/table_name */
+ ibool reject_fks)
+ /* in: if TRUE, fail with error code
+ DB_CANNOT_ADD_CONSTRAINT if any foreign
+ keys are found. */
{
dict_table_t* table;
dict_table_t* referenced_table;
@@ -2994,6 +2998,18 @@ loop:
}
if (*ptr == '\0') {
+ /* The proper way to reject foreign keys for temporary
+ tables would be to split the lexing and syntactical
+ analysis of foreign key clauses from the actual adding
+ of them, so that ha_innodb.cc could first parse the SQL
+ command, determine if there are any foreign keys, and
+ if so, immediately reject the command if the table is a
+ temporary one. For now, this kludge will work. */
+ if (reject_fks && (UT_LIST_GET_LEN(table->foreign_list) > 0))
+ {
+ return DB_CANNOT_ADD_CONSTRAINT;
+ }
+
/**********************************************************/
/* The following call adds the foreign key constraints
to the data dictionary system tables on disk */
@@ -3417,9 +3433,12 @@ dict_create_foreign_constraints(
name before it: test.table2; the
default database id the database of
parameter name */
- const char* name) /* in: table full name in the
+ const char* name, /* in: table full name in the
normalized form
database_name/table_name */
+ ibool reject_fks) /* in: if TRUE, fail with error
+ code DB_CANNOT_ADD_CONSTRAINT if
+ any foreign keys are found. */
{
char* str;
ulint err;
@@ -3428,7 +3447,8 @@ dict_create_foreign_constraints(
str = dict_strip_comments(sql_string);
heap = mem_heap_create(10000);
- err = dict_create_foreign_constraints_low(trx, heap, str, name);
+ err = dict_create_foreign_constraints_low(trx, heap, str, name,
+ reject_fks);
mem_heap_free(heap);
mem_free(str);
diff --git a/innobase/include/dict0dict.h b/innobase/include/dict0dict.h
index d9cda402bac..a1232acdca7 100644
--- a/innobase/include/dict0dict.h
+++ b/innobase/include/dict0dict.h
@@ -228,9 +228,12 @@ dict_create_foreign_constraints(
name before it: test.table2; the
default database id the database of
parameter name */
- const char* name); /* in: table full name in the
+ const char* name, /* in: table full name in the
normalized form
database_name/table_name */
+ ibool reject_fks); /* in: if TRUE, fail with error
+ code DB_CANNOT_ADD_CONSTRAINT if
+ any foreign keys are found. */
/**************************************************************************
Parses the CONSTRAINT id's to be dropped in an ALTER TABLE statement. */
diff --git a/innobase/include/row0mysql.h b/innobase/include/row0mysql.h
index 4e6ff73b0f8..a61705b90be 100644
--- a/innobase/include/row0mysql.h
+++ b/innobase/include/row0mysql.h
@@ -355,9 +355,13 @@ row_table_add_foreign_constraints(
FOREIGN KEY (a, b) REFERENCES table2(c, d),
table2 can be written also with the
database name before it: test.table2 */
- const char* name); /* in: table full name in the
+ const char* name, /* in: table full name in the
normalized form
database_name/table_name */
+ ibool reject_fks); /* in: if TRUE, fail with error
+ code DB_CANNOT_ADD_CONSTRAINT if
+ any foreign keys are found. */
+
/*************************************************************************
The master thread in srv0srv.c calls this regularly to drop tables which
we must drop in background after queries to them have ended. Such lazy
diff --git a/innobase/row/row0mysql.c b/innobase/row/row0mysql.c
index 29239210183..26aae117d1d 100644
--- a/innobase/row/row0mysql.c
+++ b/innobase/row/row0mysql.c
@@ -2088,9 +2088,12 @@ row_table_add_foreign_constraints(
FOREIGN KEY (a, b) REFERENCES table2(c, d),
table2 can be written also with the
database name before it: test.table2 */
- const char* name) /* in: table full name in the
+ const char* name, /* in: table full name in the
normalized form
database_name/table_name */
+ ibool reject_fks) /* in: if TRUE, fail with error
+ code DB_CANNOT_ADD_CONSTRAINT if
+ any foreign keys are found. */
{
ulint err;
@@ -2111,7 +2114,8 @@ row_table_add_foreign_constraints(
trx->dict_operation = TRUE;
- err = dict_create_foreign_constraints(trx, sql_string, name);
+ err = dict_create_foreign_constraints(trx, sql_string, name,
+ reject_fks);
if (err == DB_SUCCESS) {
/* Check that also referencing constraints are ok */
diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc
index aa53b69a617..4ed5fadb603 100644
--- a/sql/ha_innodb.cc
+++ b/sql/ha_innodb.cc
@@ -4687,13 +4687,7 @@ ha_innobase::create(
form->s->row_type != ROW_TYPE_REDUNDANT);
if (error) {
- innobase_commit_low(trx);
-
- row_mysql_unlock_data_dictionary(trx);
-
- trx_free_for_mysql(trx);
-
- DBUG_RETURN(error);
+ goto cleanup;
}
/* Look for a primary key */
@@ -4717,13 +4711,7 @@ ha_innobase::create(
error = create_clustered_index_when_no_primary(trx,
norm_name);
if (error) {
- innobase_commit_low(trx);
-
- row_mysql_unlock_data_dictionary(trx);
-
- trx_free_for_mysql(trx);
-
- DBUG_RETURN(error);
+ goto cleanup;
}
}
@@ -4732,13 +4720,7 @@ ha_innobase::create(
first */
if ((error = create_index(trx, form, norm_name,
(uint) primary_key_no))) {
- innobase_commit_low(trx);
-
- row_mysql_unlock_data_dictionary(trx);
-
- trx_free_for_mysql(trx);
-
- DBUG_RETURN(error);
+ goto cleanup;
}
}
@@ -4747,14 +4729,7 @@ ha_innobase::create(
if (i != (uint) primary_key_no) {
if ((error = create_index(trx, form, norm_name, i))) {
-
- innobase_commit_low(trx);
-
- row_mysql_unlock_data_dictionary(trx);
-
- trx_free_for_mysql(trx);
-
- DBUG_RETURN(error);
+ goto cleanup;
}
}
}
@@ -4767,21 +4742,18 @@ ha_innobase::create(
current_thd->query_length,
current_thd->charset())) {
error = HA_ERR_OUT_OF_MEM;
- } else {
- error = row_table_add_foreign_constraints(trx,
- q.str, norm_name);
-
- error = convert_error_code_to_mysql(error, NULL);
+
+ goto cleanup;
}
- if (error) {
- innobase_commit_low(trx);
-
- row_mysql_unlock_data_dictionary(trx);
+ error = row_table_add_foreign_constraints(trx,
+ q.str, norm_name,
+ create_info->options & HA_LEX_CREATE_TMP_TABLE);
- trx_free_for_mysql(trx);
+ error = convert_error_code_to_mysql(error, NULL);
- DBUG_RETURN(error);
+ if (error) {
+ goto cleanup;
}
}
@@ -4821,6 +4793,15 @@ ha_innobase::create(
trx_free_for_mysql(trx);
DBUG_RETURN(0);
+
+cleanup:
+ innobase_commit_low(trx);
+
+ row_mysql_unlock_data_dictionary(trx);
+
+ trx_free_for_mysql(trx);
+
+ DBUG_RETURN(error);
}
/*********************************************************************