summaryrefslogtreecommitdiff
path: root/innobase/dict
diff options
context:
space:
mode:
authorunknown <monty@hundin.mysql.fi>2002-04-25 01:16:42 +0300
committerunknown <monty@hundin.mysql.fi>2002-04-25 01:16:42 +0300
commit0a03601fab2174e2a7590ff36d4ce2aee08adc5f (patch)
tree539e3f41736108728458d901c552313e5f058e8f /innobase/dict
parenta56d1215f52b8d6ed9428b358034f439e03cbf5b (diff)
parent64cc56125791c5e3773399b6d3a40be81510b460 (diff)
downloadmariadb-git-0a03601fab2174e2a7590ff36d4ce2aee08adc5f.tar.gz
merge
BitKeeper/etc/logging_ok: auto-union configure.in: Auto merged BitKeeper/deleted/.del-identity.result~e41453a364242503: Auto merged BitKeeper/deleted/.del-identity.test~326f469b59105404: Auto merged include/my_pthread.h: Auto merged innobase/dict/dict0crea.c: Auto merged innobase/dict/dict0dict.c: Auto merged innobase/dict/dict0load.c: Auto merged innobase/include/univ.i: Auto merged innobase/lock/lock0lock.c: Auto merged innobase/pars/pars0opt.c: Auto merged innobase/que/que0que.c: Auto merged innobase/row/row0ins.c: Auto merged innobase/row/row0mysql.c: Auto merged innobase/row/row0sel.c: Auto merged innobase/row/row0upd.c: Auto merged innobase/srv/srv0srv.c: Auto merged innobase/sync/sync0sync.c: Auto merged innobase/trx/trx0trx.c: Auto merged libmysql/libmysql.c: Auto merged myisam/myisampack.c: Auto merged mysql-test/t/func_test.test: Auto merged mysql-test/t/show_check.test: Auto merged mysql-test/t/variables.test: Auto merged mysys/my_pthread.c: Auto merged sql/item_cmpfunc.cc: Auto merged sql/item_func.cc: Auto merged sql/mysql_priv.h: Auto merged sql/share/danish/errmsg.txt: Auto merged sql/share/english/errmsg.txt: Auto merged sql/share/french/errmsg.txt: Auto merged sql/share/german/errmsg.txt: Auto merged sql/share/greek/errmsg.txt: Auto merged sql/share/hungarian/errmsg.txt: Auto merged sql/sql_show.cc: Auto merged sql/share/italian/errmsg.txt: Auto merged sql/share/japanese/errmsg.txt: Auto merged sql/share/korean/errmsg.txt: Auto merged sql/share/norwegian-ny/errmsg.txt: Auto merged sql/share/norwegian/errmsg.txt: Auto merged sql/share/polish/errmsg.txt: Auto merged sql/share/portuguese/errmsg.txt: Auto merged sql/share/romanian/errmsg.txt: Auto merged sql/share/russian/errmsg.txt: Auto merged sql/share/slovak/errmsg.txt: Auto merged sql/share/spanish/errmsg.txt: Auto merged sql/share/swedish/errmsg.txt: Auto merged sql/share/ukrainian/errmsg.txt: Auto merged
Diffstat (limited to 'innobase/dict')
-rw-r--r--innobase/dict/dict0crea.c3
-rw-r--r--innobase/dict/dict0dict.c161
-rw-r--r--innobase/dict/dict0load.c5
-rw-r--r--innobase/dict/dict0mem.c4
4 files changed, 136 insertions, 37 deletions
diff --git a/innobase/dict/dict0crea.c b/innobase/dict/dict0crea.c
index 69b1e7c61fd..0da59d39646 100644
--- a/innobase/dict/dict0crea.c
+++ b/innobase/dict/dict0crea.c
@@ -1201,7 +1201,8 @@ loop:
ut_dulint_get_low(id),
table->name,
foreign->referenced_table_name,
- foreign->n_fields);
+ foreign->n_fields
+ + (foreign->type << 24));
for (i = 0; i < foreign->n_fields; i++) {
diff --git a/innobase/dict/dict0dict.c b/innobase/dict/dict0dict.c
index 43589eb03fe..5f6d947bb92 100644
--- a/innobase/dict/dict0dict.c
+++ b/innobase/dict/dict0dict.c
@@ -1652,7 +1652,7 @@ dict_foreign_find_index(
->col->name;
if (ut_strlen(columns[i]) !=
ut_strlen(col_name)
- || 0 != ut_memcmp(columns[i],
+ || 0 != ut_cmp_in_lower_case(columns[i],
col_name,
ut_strlen(col_name))) {
break;
@@ -1857,8 +1857,9 @@ dict_scan_col(
ibool* success,/* out: TRUE if success */
dict_table_t* table, /* in: table in which the column is */
dict_col_t** column, /* out: pointer to column if success */
- char** column_name)/* out: pointer to column->name if
+ char** column_name,/* out: pointer to column->name if
success */
+ ulint* column_name_len)/* out: column name length */
{
dict_col_t* col;
char* old_ptr;
@@ -1886,20 +1887,28 @@ dict_scan_col(
ptr++;
}
- for (i = 0; i < dict_table_get_n_cols(table); i++) {
+ *column_name_len = (ulint)(ptr - old_ptr);
+
+ if (table == NULL) {
+ *success = TRUE;
+ *column = NULL;
+ *column_name = old_ptr;
+ } else {
+ for (i = 0; i < dict_table_get_n_cols(table); i++) {
- col = dict_table_get_nth_col(table, i);
+ col = dict_table_get_nth_col(table, i);
- if (ut_strlen(col->name) == (ulint)(ptr - old_ptr)
- && 0 == ut_cmp_in_lower_case(col->name, old_ptr,
+ if (ut_strlen(col->name) == (ulint)(ptr - old_ptr)
+ && 0 == ut_cmp_in_lower_case(col->name, old_ptr,
(ulint)(ptr - old_ptr))) {
- /* Found */
+ /* Found */
- *success = TRUE;
- *column = col;
- *column_name = col->name;
+ *success = TRUE;
+ *column = col;
+ *column_name = col->name;
- break;
+ break;
+ }
}
}
@@ -1918,14 +1927,18 @@ dict_scan_table_name(
/*=================*/
/* out: scanned to */
char* ptr, /* in: scanned to */
- dict_table_t** table, /* out: table object or NULL if error */
- char* name) /* in: foreign key table name */
+ dict_table_t** table, /* out: table object or NULL */
+ char* name, /* in: foreign key table name */
+ ibool* success,/* out: TRUE if ok name found */
+ char* second_table_name)/* in/out: buffer where to store
+ the referenced table name; must be at least
+ 2500 bytes */
{
char* dot_ptr = NULL;
char* old_ptr;
ulint i;
- char second_table_name[10000];
+ *success = FALSE;
*table = NULL;
while (isspace(*ptr)) {
@@ -1951,7 +1964,7 @@ dict_scan_table_name(
ptr++;
}
- if (ptr - old_ptr > 9000) {
+ if (ptr - old_ptr > 2000) {
return(old_ptr);
}
@@ -1982,6 +1995,8 @@ dict_scan_table_name(
second_table_name[ptr - old_ptr] = '\0';
}
+ *success = TRUE;
+
*table = dict_table_get_low(second_table_name);
if (*ptr == '`') {
@@ -2047,9 +2062,12 @@ dict_create_foreign_constraints(
ibool success;
ulint error;
ulint i;
- dict_col_t* columns[1000];
- char* column_names[1000];
-
+ ulint j;
+ dict_col_t* columns[500];
+ char* column_names[500];
+ ulint column_name_lens[500];
+ char referenced_table_name[2500];
+
ut_ad(mutex_own(&(dict_sys->mutex)));
table = dict_table_get_low(name);
@@ -2094,7 +2112,7 @@ loop:
/* Scan the columns in the first list */
col_loop1:
ptr = dict_scan_col(ptr, &success, table, columns + i,
- column_names + i);
+ column_names + i, column_name_lens + i);
if (!success) {
return(DB_CANNOT_ADD_CONSTRAINT);
}
@@ -2145,9 +2163,13 @@ col_loop1:
1 + ut_strlen(columns[i]->name));
}
- ptr = dict_scan_table_name(ptr, &referenced_table, name);
+ ptr = dict_scan_table_name(ptr, &referenced_table, name,
+ &success, referenced_table_name);
- if (!referenced_table) {
+ /* Note that referenced_table can be NULL if the user has suppressed
+ checking of foreign key constraints! */
+
+ if (!success || (!referenced_table && trx->check_foreigns)) {
dict_foreign_free(foreign);
return(DB_CANNOT_ADD_CONSTRAINT);
@@ -2165,7 +2187,7 @@ col_loop1:
col_loop2:
ptr = dict_scan_col(ptr, &success, referenced_table, columns + i,
- column_names + i);
+ column_names + i, column_name_lens + i);
i++;
if (!success) {
@@ -2187,43 +2209,104 @@ col_loop2:
return(DB_CANNOT_ADD_CONSTRAINT);
}
+ ptr = dict_accept(ptr, "ON", &success);
+
+ if (!success) {
+
+ goto try_find_index;
+ }
+
+ ptr = dict_accept(ptr, "DELETE", &success);
+
+ if (!success) {
+
+ goto try_find_index;
+ }
+
+ ptr = dict_accept(ptr, "CASCADE", &success);
+
+ if (success) {
+
+ foreign->type = DICT_FOREIGN_ON_DELETE_CASCADE;
+
+ goto try_find_index;
+ }
+
+ ptr = dict_accept(ptr, "SET", &success);
+
+ if (!success) {
+
+ goto try_find_index;
+ }
+
+ ptr = dict_accept(ptr, "NULL", &success);
+
+ if (success) {
+ for (j = 0; j < foreign->n_fields; j++) {
+ if ((dict_index_get_nth_type(
+ foreign->foreign_index, j)->prtype)
+ & DATA_NOT_NULL) {
+
+ /* It is not sensible to define SET NULL
+ if the column is not allowed to be NULL! */
+
+ dict_foreign_free(foreign);
+ return(DB_CANNOT_ADD_CONSTRAINT);
+ }
+ }
+
+ foreign->type = DICT_FOREIGN_ON_DELETE_SET_NULL;
+
+ goto try_find_index;
+ }
+
+try_find_index:
/* Try to find an index which contains the columns as the first fields
and in the right order, and the types are the same as in
foreign->foreign_index */
- index = dict_foreign_find_index(referenced_table, column_names, i,
+ if (referenced_table) {
+ index = dict_foreign_find_index(referenced_table,
+ column_names, i,
foreign->foreign_index);
-
- if (!index) {
- dict_foreign_free(foreign);
- return(DB_CANNOT_ADD_CONSTRAINT);
+ if (!index) {
+ dict_foreign_free(foreign);
+ return(DB_CANNOT_ADD_CONSTRAINT);
+ }
+ } else {
+ ut_a(trx->check_foreigns == FALSE);
+ index = NULL;
}
foreign->referenced_index = index;
foreign->referenced_table = referenced_table;
foreign->referenced_table_name = mem_heap_alloc(foreign->heap,
- 1 + ut_strlen(referenced_table->name));
+ 1 + ut_strlen(referenced_table_name));
- ut_memcpy(foreign->referenced_table_name, referenced_table->name,
- 1 + ut_strlen(referenced_table->name));
+ ut_memcpy(foreign->referenced_table_name, referenced_table_name,
+ 1 + ut_strlen(referenced_table_name));
foreign->referenced_col_names = mem_heap_alloc(foreign->heap,
i * sizeof(void*));
for (i = 0; i < foreign->n_fields; i++) {
foreign->referenced_col_names[i]
= mem_heap_alloc(foreign->heap,
- 1 + ut_strlen(columns[i]->name));
- ut_memcpy(
- foreign->referenced_col_names[i], columns[i]->name,
- 1 + ut_strlen(columns[i]->name));
+ 1 + column_name_lens[i]);
+ ut_memcpy(foreign->referenced_col_names[i], column_names[i],
+ column_name_lens[i]);
+ (foreign->referenced_col_names[i])[column_name_lens[i]] = '\0';
}
/* We found an ok constraint definition: add to the lists */
UT_LIST_ADD_LAST(foreign_list, table->foreign_list, foreign);
- UT_LIST_ADD_LAST(referenced_list, referenced_table->referenced_list,
+
+ if (referenced_table) {
+ UT_LIST_ADD_LAST(referenced_list,
+ referenced_table->referenced_list,
foreign);
+ }
goto loop;
}
@@ -3039,6 +3122,14 @@ dict_print_info_on_foreign_keys_in_create_format(
buf2 += sprintf(buf2, ")");
+ if (foreign->type == DICT_FOREIGN_ON_DELETE_CASCADE) {
+ buf2 += sprintf(buf2, " ON DELETE CASCADE");
+ }
+
+ if (foreign->type == DICT_FOREIGN_ON_DELETE_SET_NULL) {
+ buf2 += sprintf(buf2, " ON DELETE SET NULL");
+ }
+
foreign = UT_LIST_GET_NEXT(foreign_list, foreign);
}
diff --git a/innobase/dict/dict0load.c b/innobase/dict/dict0load.c
index 53ba09616f7..221a6c7dabb 100644
--- a/innobase/dict/dict0load.c
+++ b/innobase/dict/dict0load.c
@@ -946,6 +946,11 @@ dict_load_foreign(
foreign->n_fields = mach_read_from_4(rec_get_nth_field(rec, 5, &len));
ut_a(len == 4);
+
+ /* We store the type to the bits 24-31 of n_fields */
+
+ foreign->type = foreign->n_fields >> 24;
+ foreign->n_fields = foreign->n_fields & 0xFFFFFF;
foreign->id = mem_heap_alloc(foreign->heap, ut_strlen(id) + 1);
diff --git a/innobase/dict/dict0mem.c b/innobase/dict/dict0mem.c
index 1f9a44aca35..52f46062065 100644
--- a/innobase/dict/dict0mem.c
+++ b/innobase/dict/dict0mem.c
@@ -61,7 +61,8 @@ dict_mem_table_create(
table->mem_fix = 0;
table->n_mysql_handles_opened = 0;
-
+ table->n_foreign_key_checks_running = 0;
+
table->cached = FALSE;
table->cols = mem_heap_alloc(heap, (n_cols + DATA_N_SYS_COLS)
@@ -235,6 +236,7 @@ dict_mem_foreign_create(void)
foreign->id = NULL;
+ foreign->type = 0;
foreign->foreign_table_name = NULL;
foreign->foreign_table = NULL;
foreign->foreign_col_names = NULL;