mirror of
https://github.com/MariaDB/server.git
synced 2025-08-08 11:22:35 +03:00
Merge 127.(none):/home/osku/mysql/5.0/clean
into 127.(none):/home/osku/mysql/5.0/3443
This commit is contained in:
@@ -2189,7 +2189,7 @@ dict_foreign_error_report(
|
|||||||
dict_foreign_error_report_low(file, fk->foreign_table_name);
|
dict_foreign_error_report_low(file, fk->foreign_table_name);
|
||||||
fputs(msg, file);
|
fputs(msg, file);
|
||||||
fputs(" Constraint:\n", file);
|
fputs(" Constraint:\n", file);
|
||||||
dict_print_info_on_foreign_key_in_create_format(file, NULL, fk);
|
dict_print_info_on_foreign_key_in_create_format(file, NULL, fk, TRUE);
|
||||||
if (fk->foreign_index) {
|
if (fk->foreign_index) {
|
||||||
fputs("\nThe index in the foreign key in table is ", file);
|
fputs("\nThe index in the foreign key in table is ", file);
|
||||||
ut_print_name(file, NULL, fk->foreign_index->name);
|
ut_print_name(file, NULL, fk->foreign_index->name);
|
||||||
@@ -4330,9 +4330,10 @@ CREATE TABLE. */
|
|||||||
void
|
void
|
||||||
dict_print_info_on_foreign_key_in_create_format(
|
dict_print_info_on_foreign_key_in_create_format(
|
||||||
/*============================================*/
|
/*============================================*/
|
||||||
FILE* file, /* in: file where to print */
|
FILE* file, /* in: file where to print */
|
||||||
trx_t* trx, /* in: transaction */
|
trx_t* trx, /* in: transaction */
|
||||||
dict_foreign_t* foreign)/* in: foreign key constraint */
|
dict_foreign_t* foreign, /* in: foreign key constraint */
|
||||||
|
ibool add_newline) /* in: whether to add a newline */
|
||||||
{
|
{
|
||||||
const char* stripped_id;
|
const char* stripped_id;
|
||||||
ulint i;
|
ulint i;
|
||||||
@@ -4345,7 +4346,16 @@ dict_print_info_on_foreign_key_in_create_format(
|
|||||||
stripped_id = foreign->id;
|
stripped_id = foreign->id;
|
||||||
}
|
}
|
||||||
|
|
||||||
fputs(",\n CONSTRAINT ", file);
|
putc(',', file);
|
||||||
|
|
||||||
|
if (add_newline) {
|
||||||
|
/* SHOW CREATE TABLE wants constraints each printed nicely
|
||||||
|
on its own line, while error messages want no newlines
|
||||||
|
inserted. */
|
||||||
|
fputs("\n ", file);
|
||||||
|
}
|
||||||
|
|
||||||
|
fputs(" CONSTRAINT ", file);
|
||||||
ut_print_name(file, trx, stripped_id);
|
ut_print_name(file, trx, stripped_id);
|
||||||
fputs(" FOREIGN KEY (", file);
|
fputs(" FOREIGN KEY (", file);
|
||||||
|
|
||||||
@@ -4447,7 +4457,7 @@ dict_print_info_on_foreign_keys(
|
|||||||
while (foreign != NULL) {
|
while (foreign != NULL) {
|
||||||
if (create_table_format) {
|
if (create_table_format) {
|
||||||
dict_print_info_on_foreign_key_in_create_format(
|
dict_print_info_on_foreign_key_in_create_format(
|
||||||
file, trx, foreign);
|
file, trx, foreign, TRUE);
|
||||||
} else {
|
} else {
|
||||||
ulint i;
|
ulint i;
|
||||||
fputs("; (", file);
|
fputs("; (", file);
|
||||||
|
@@ -375,9 +375,10 @@ CREATE TABLE. */
|
|||||||
void
|
void
|
||||||
dict_print_info_on_foreign_key_in_create_format(
|
dict_print_info_on_foreign_key_in_create_format(
|
||||||
/*============================================*/
|
/*============================================*/
|
||||||
FILE* file, /* in: file where to print */
|
FILE* file, /* in: file where to print */
|
||||||
trx_t* trx, /* in: transaction */
|
trx_t* trx, /* in: transaction */
|
||||||
dict_foreign_t* foreign);/* in: foreign key constraint */
|
dict_foreign_t* foreign, /* in: foreign key constraint */
|
||||||
|
ibool add_newline); /* in: whether to add a newline */
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
Displays the names of the index and the table. */
|
Displays the names of the index and the table. */
|
||||||
void
|
void
|
||||||
|
@@ -432,6 +432,17 @@ os_file_read(
|
|||||||
offset */
|
offset */
|
||||||
ulint n); /* in: number of bytes to read */
|
ulint n); /* in: number of bytes to read */
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
|
Rewind file to its start, read at most size - 1 bytes from it to str, and
|
||||||
|
NUL-terminate str. All errors are silently ignored. This function is
|
||||||
|
mostly meant to be used with temporary files. */
|
||||||
|
|
||||||
|
void
|
||||||
|
os_file_read_string(
|
||||||
|
/*================*/
|
||||||
|
FILE* file, /* in: file to read from */
|
||||||
|
char* str, /* in: buffer where to read */
|
||||||
|
ulint size); /* in: size of buffer */
|
||||||
|
/***********************************************************************
|
||||||
Requests a synchronous positioned read operation. This function does not do
|
Requests a synchronous positioned read operation. This function does not do
|
||||||
any error handling. In case of error it returns FALSE. */
|
any error handling. In case of error it returns FALSE. */
|
||||||
|
|
||||||
|
@@ -56,6 +56,22 @@ void
|
|||||||
trx_search_latch_release_if_reserved(
|
trx_search_latch_release_if_reserved(
|
||||||
/*=================================*/
|
/*=================================*/
|
||||||
trx_t* trx); /* in: transaction */
|
trx_t* trx); /* in: transaction */
|
||||||
|
/**********************************************************************
|
||||||
|
Set detailed error message for the transaction. */
|
||||||
|
void
|
||||||
|
trx_set_detailed_error(
|
||||||
|
/*===================*/
|
||||||
|
trx_t* trx, /* in: transaction struct */
|
||||||
|
char* msg); /* in: detailed error message */
|
||||||
|
/*****************************************************************
|
||||||
|
Set detailed error message for the transaction from a file. Note that the
|
||||||
|
file is rewinded before reading from it. */
|
||||||
|
|
||||||
|
void
|
||||||
|
trx_set_detailed_error_from_file(
|
||||||
|
/*=============================*/
|
||||||
|
trx_t* trx, /* in: transaction struct */
|
||||||
|
FILE* file); /* in: file to read message from */
|
||||||
/********************************************************************
|
/********************************************************************
|
||||||
Retrieves the error_info field from a trx. */
|
Retrieves the error_info field from a trx. */
|
||||||
|
|
||||||
@@ -649,6 +665,9 @@ struct trx_struct{
|
|||||||
trx_undo_arr_t* undo_no_arr; /* array of undo numbers of undo log
|
trx_undo_arr_t* undo_no_arr; /* array of undo numbers of undo log
|
||||||
records which are currently processed
|
records which are currently processed
|
||||||
by a rollback operation */
|
by a rollback operation */
|
||||||
|
/*------------------------------*/
|
||||||
|
char detailed_error[256]; /* detailed error message for last
|
||||||
|
error, or empty. */
|
||||||
};
|
};
|
||||||
|
|
||||||
#define TRX_MAX_N_THREADS 32 /* maximum number of concurrent
|
#define TRX_MAX_N_THREADS 32 /* maximum number of concurrent
|
||||||
|
@@ -118,6 +118,18 @@ UNIV_INLINE
|
|||||||
int
|
int
|
||||||
ut_strcmp(const void* str1, const void* str2);
|
ut_strcmp(const void* str1, const void* str2);
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
Copies up to size - 1 characters from the NUL-terminated string src to
|
||||||
|
dst, NUL-terminating the result. Returns strlen(src), so truncation
|
||||||
|
occurred if the return value >= size. */
|
||||||
|
ulint
|
||||||
|
ut_strlcpy(
|
||||||
|
/*=======*/
|
||||||
|
/* out: strlen(src) */
|
||||||
|
char* dst, /* in: destination buffer */
|
||||||
|
const char* src, /* in: source buffer */
|
||||||
|
ulint size); /* in: size of destination buffer */
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
Compute strlen(ut_strcpyq(str, q)). */
|
Compute strlen(ut_strcpyq(str, q)). */
|
||||||
UNIV_INLINE
|
UNIV_INLINE
|
||||||
|
@@ -2248,6 +2248,29 @@ error_handling:
|
|||||||
return(FALSE);
|
return(FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
Rewind file to its start, read at most size - 1 bytes from it to str, and
|
||||||
|
NUL-terminate str. All errors are silently ignored. This function is
|
||||||
|
mostly meant to be used with temporary files. */
|
||||||
|
|
||||||
|
void
|
||||||
|
os_file_read_string(
|
||||||
|
/*================*/
|
||||||
|
FILE* file, /* in: file to read from */
|
||||||
|
char* str, /* in: buffer where to read */
|
||||||
|
ulint size) /* in: size of buffer */
|
||||||
|
{
|
||||||
|
size_t flen;
|
||||||
|
|
||||||
|
if (size == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
rewind(file);
|
||||||
|
flen = fread(str, 1, size - 1, file);
|
||||||
|
str[flen] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
Requests a synchronous write operation. */
|
Requests a synchronous write operation. */
|
||||||
|
|
||||||
|
@@ -578,6 +578,30 @@ row_ins_cascade_calc_update_vec(
|
|||||||
return(n_fields_updated);
|
return(n_fields_updated);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
Set detailed error message associated with foreign key errors for
|
||||||
|
the given transaction. */
|
||||||
|
static
|
||||||
|
void
|
||||||
|
row_ins_set_detailed(
|
||||||
|
/*=================*/
|
||||||
|
trx_t* trx, /* in: transaction */
|
||||||
|
dict_foreign_t* foreign) /* in: foreign key constraint */
|
||||||
|
{
|
||||||
|
|
||||||
|
FILE* tf = os_file_create_tmpfile();
|
||||||
|
|
||||||
|
ut_a(tf);
|
||||||
|
|
||||||
|
ut_print_name(tf, trx, foreign->foreign_table_name);
|
||||||
|
dict_print_info_on_foreign_key_in_create_format(tf, trx,
|
||||||
|
foreign, FALSE);
|
||||||
|
|
||||||
|
trx_set_detailed_error_from_file(trx, tf);
|
||||||
|
|
||||||
|
fclose(tf);
|
||||||
|
}
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
Reports a foreign key error associated with an update or a delete of a
|
Reports a foreign key error associated with an update or a delete of a
|
||||||
parent table index entry. */
|
parent table index entry. */
|
||||||
@@ -598,6 +622,8 @@ row_ins_foreign_report_err(
|
|||||||
FILE* ef = dict_foreign_err_file;
|
FILE* ef = dict_foreign_err_file;
|
||||||
trx_t* trx = thr_get_trx(thr);
|
trx_t* trx = thr_get_trx(thr);
|
||||||
|
|
||||||
|
row_ins_set_detailed(trx, foreign);
|
||||||
|
|
||||||
mutex_enter(&dict_foreign_err_mutex);
|
mutex_enter(&dict_foreign_err_mutex);
|
||||||
rewind(ef);
|
rewind(ef);
|
||||||
ut_print_timestamp(ef);
|
ut_print_timestamp(ef);
|
||||||
@@ -607,7 +633,8 @@ row_ins_foreign_report_err(
|
|||||||
fputs("Foreign key constraint fails for table ", ef);
|
fputs("Foreign key constraint fails for table ", ef);
|
||||||
ut_print_name(ef, trx, foreign->foreign_table_name);
|
ut_print_name(ef, trx, foreign->foreign_table_name);
|
||||||
fputs(":\n", ef);
|
fputs(":\n", ef);
|
||||||
dict_print_info_on_foreign_key_in_create_format(ef, trx, foreign);
|
dict_print_info_on_foreign_key_in_create_format(ef, trx, foreign,
|
||||||
|
TRUE);
|
||||||
putc('\n', ef);
|
putc('\n', ef);
|
||||||
fputs(errstr, ef);
|
fputs(errstr, ef);
|
||||||
fputs(" in parent table, in index ", ef);
|
fputs(" in parent table, in index ", ef);
|
||||||
@@ -648,7 +675,9 @@ row_ins_foreign_report_add_err(
|
|||||||
child table */
|
child table */
|
||||||
{
|
{
|
||||||
FILE* ef = dict_foreign_err_file;
|
FILE* ef = dict_foreign_err_file;
|
||||||
|
|
||||||
|
row_ins_set_detailed(trx, foreign);
|
||||||
|
|
||||||
mutex_enter(&dict_foreign_err_mutex);
|
mutex_enter(&dict_foreign_err_mutex);
|
||||||
rewind(ef);
|
rewind(ef);
|
||||||
ut_print_timestamp(ef);
|
ut_print_timestamp(ef);
|
||||||
@@ -657,7 +686,8 @@ row_ins_foreign_report_add_err(
|
|||||||
fputs("Foreign key constraint fails for table ", ef);
|
fputs("Foreign key constraint fails for table ", ef);
|
||||||
ut_print_name(ef, trx, foreign->foreign_table_name);
|
ut_print_name(ef, trx, foreign->foreign_table_name);
|
||||||
fputs(":\n", ef);
|
fputs(":\n", ef);
|
||||||
dict_print_info_on_foreign_key_in_create_format(ef, trx, foreign);
|
dict_print_info_on_foreign_key_in_create_format(ef, trx, foreign,
|
||||||
|
TRUE);
|
||||||
fputs("\nTrying to add in child table, in index ", ef);
|
fputs("\nTrying to add in child table, in index ", ef);
|
||||||
ut_print_name(ef, trx, foreign->foreign_index->name);
|
ut_print_name(ef, trx, foreign->foreign_index->name);
|
||||||
if (entry) {
|
if (entry) {
|
||||||
@@ -1223,6 +1253,8 @@ run_again:
|
|||||||
|
|
||||||
if (check_table == NULL || check_table->ibd_file_missing) {
|
if (check_table == NULL || check_table->ibd_file_missing) {
|
||||||
if (check_ref) {
|
if (check_ref) {
|
||||||
|
row_ins_set_detailed(trx, foreign);
|
||||||
|
|
||||||
FILE* ef = dict_foreign_err_file;
|
FILE* ef = dict_foreign_err_file;
|
||||||
mutex_enter(&dict_foreign_err_mutex);
|
mutex_enter(&dict_foreign_err_mutex);
|
||||||
rewind(ef);
|
rewind(ef);
|
||||||
@@ -1233,7 +1265,7 @@ run_again:
|
|||||||
ut_print_name(ef, trx, foreign->foreign_table_name);
|
ut_print_name(ef, trx, foreign->foreign_table_name);
|
||||||
fputs(":\n", ef);
|
fputs(":\n", ef);
|
||||||
dict_print_info_on_foreign_key_in_create_format(ef,
|
dict_print_info_on_foreign_key_in_create_format(ef,
|
||||||
trx, foreign);
|
trx, foreign, TRUE);
|
||||||
fputs("\nTrying to add to index ", ef);
|
fputs("\nTrying to add to index ", ef);
|
||||||
ut_print_name(ef, trx, foreign->foreign_index->name);
|
ut_print_name(ef, trx, foreign->foreign_index->name);
|
||||||
fputs(" tuple:\n", ef);
|
fputs(" tuple:\n", ef);
|
||||||
|
@@ -52,6 +52,32 @@ trx_start_if_not_started_noninline(
|
|||||||
trx_start_if_not_started(trx);
|
trx_start_if_not_started(trx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*****************************************************************
|
||||||
|
Set detailed error message for the transaction. */
|
||||||
|
|
||||||
|
void
|
||||||
|
trx_set_detailed_error(
|
||||||
|
/*===================*/
|
||||||
|
trx_t* trx, /* in: transaction struct */
|
||||||
|
char* msg) /* in: detailed error message */
|
||||||
|
{
|
||||||
|
ut_strlcpy(trx->detailed_error, msg, sizeof(trx->detailed_error));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************
|
||||||
|
Set detailed error message for the transaction from a file. Note that the
|
||||||
|
file is rewinded before reading from it. */
|
||||||
|
|
||||||
|
void
|
||||||
|
trx_set_detailed_error_from_file(
|
||||||
|
/*=============================*/
|
||||||
|
trx_t* trx, /* in: transaction struct */
|
||||||
|
FILE* file) /* in: file to read message from */
|
||||||
|
{
|
||||||
|
os_file_read_string(file, trx->detailed_error,
|
||||||
|
sizeof(trx->detailed_error));
|
||||||
|
}
|
||||||
|
|
||||||
/********************************************************************
|
/********************************************************************
|
||||||
Retrieves the error_info field from a trx. */
|
Retrieves the error_info field from a trx. */
|
||||||
|
|
||||||
@@ -130,6 +156,7 @@ trx_create(
|
|||||||
trx->undo_no_arr = NULL;
|
trx->undo_no_arr = NULL;
|
||||||
|
|
||||||
trx->error_state = DB_SUCCESS;
|
trx->error_state = DB_SUCCESS;
|
||||||
|
trx->detailed_error[0] = '\0';
|
||||||
|
|
||||||
trx->sess = sess;
|
trx->sess = sess;
|
||||||
trx->que_state = TRX_QUE_RUNNING;
|
trx->que_state = TRX_QUE_RUNNING;
|
||||||
|
@@ -342,6 +342,31 @@ ut_free_all_mem(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
Copies up to size - 1 characters from the NUL-terminated string src to
|
||||||
|
dst, NUL-terminating the result. Returns strlen(src), so truncation
|
||||||
|
occurred if the return value >= size. */
|
||||||
|
|
||||||
|
ulint
|
||||||
|
ut_strlcpy(
|
||||||
|
/*=======*/
|
||||||
|
/* out: strlen(src) */
|
||||||
|
char* dst, /* in: destination buffer */
|
||||||
|
const char* src, /* in: source buffer */
|
||||||
|
ulint size) /* in: size of destination buffer */
|
||||||
|
{
|
||||||
|
ulint src_size = strlen(src);
|
||||||
|
|
||||||
|
if (size != 0) {
|
||||||
|
ulint n = ut_min(src_size, size - 1);
|
||||||
|
|
||||||
|
memcpy(dst, src, n);
|
||||||
|
dst[n] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
return src_size;
|
||||||
|
}
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
Make a quoted copy of a NUL-terminated string. Leading and trailing
|
Make a quoted copy of a NUL-terminated string. Leading and trailing
|
||||||
quotes will not be included; only embedded quotes will be escaped.
|
quotes will not be included; only embedded quotes will be escaped.
|
||||||
|
@@ -1378,9 +1378,9 @@ insert into `t2`values ( 1 ) ;
|
|||||||
create table `t3` (`id` int( 11 ) not null default '0',key `id` ( `id` ) ,constraint `t2_id_fk` foreign key ( `id` ) references `t2` (`id` )) engine = innodb;
|
create table `t3` (`id` int( 11 ) not null default '0',key `id` ( `id` ) ,constraint `t2_id_fk` foreign key ( `id` ) references `t2` (`id` )) engine = innodb;
|
||||||
insert into `t3`values ( 1 ) ;
|
insert into `t3`values ( 1 ) ;
|
||||||
delete t3,t2,t1 from t1,t2,t3 where t1.id =1 and t2.id = t1.id and t3.id = t2.id;
|
delete t3,t2,t1 from t1,t2,t3 where t1.id =1 and t2.id = t1.id and t3.id = t2.id;
|
||||||
ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails
|
ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test/t2`, CONSTRAINT `t1_id_fk` FOREIGN KEY (`id`) REFERENCES `t1` (`id`))
|
||||||
update t1,t2,t3 set t3.id=5, t2.id=6, t1.id=7 where t1.id =1 and t2.id = t1.id and t3.id = t2.id;
|
update t1,t2,t3 set t3.id=5, t2.id=6, t1.id=7 where t1.id =1 and t2.id = t1.id and t3.id = t2.id;
|
||||||
ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails
|
ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test/t2`, CONSTRAINT `t1_id_fk` FOREIGN KEY (`id`) REFERENCES `t1` (`id`))
|
||||||
update t3 set t3.id=7 where t1.id =1 and t2.id = t1.id and t3.id = t2.id;
|
update t3 set t3.id=7 where t1.id =1 and t2.id = t1.id and t3.id = t2.id;
|
||||||
ERROR 42S22: Unknown column 't1.id' in 'where clause'
|
ERROR 42S22: Unknown column 't1.id' in 'where clause'
|
||||||
drop table t3,t2,t1;
|
drop table t3,t2,t1;
|
||||||
@@ -1392,7 +1392,7 @@ foreign key(pid) references t1(id) on delete cascade) engine=innodb;
|
|||||||
insert into t1 values(0,0),(1,0),(2,1),(3,2),(4,3),(5,4),(6,5),(7,6),
|
insert into t1 values(0,0),(1,0),(2,1),(3,2),(4,3),(5,4),(6,5),(7,6),
|
||||||
(8,7),(9,8),(10,9),(11,10),(12,11),(13,12),(14,13),(15,14);
|
(8,7),(9,8),(10,9),(11,10),(12,11),(13,12),(14,13),(15,14);
|
||||||
delete from t1 where id=0;
|
delete from t1 where id=0;
|
||||||
ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails
|
ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test/t1`, CONSTRAINT `t1_ibfk_1` FOREIGN KEY (`pid`) REFERENCES `t1` (`id`) ON DELETE CASCADE)
|
||||||
delete from t1 where id=15;
|
delete from t1 where id=15;
|
||||||
delete from t1 where id=0;
|
delete from t1 where id=0;
|
||||||
drop table t1;
|
drop table t1;
|
||||||
@@ -2593,3 +2593,26 @@ ERROR HY000: Can't create table './test/t4.frm' (errno: 139)
|
|||||||
create table t5 (col1 blob, index(col1(768)))
|
create table t5 (col1 blob, index(col1(768)))
|
||||||
character set = latin1 engine = innodb;
|
character set = latin1 engine = innodb;
|
||||||
ERROR HY000: Can't create table './test/t5.frm' (errno: 139)
|
ERROR HY000: Can't create table './test/t5.frm' (errno: 139)
|
||||||
|
CREATE TABLE t1
|
||||||
|
(
|
||||||
|
id INT PRIMARY KEY
|
||||||
|
) ENGINE=InnoDB;
|
||||||
|
CREATE TABLE t2
|
||||||
|
(
|
||||||
|
v INT,
|
||||||
|
CONSTRAINT c1 FOREIGN KEY (v) REFERENCES t1(id)
|
||||||
|
) ENGINE=InnoDB;
|
||||||
|
INSERT INTO t2 VALUES(2);
|
||||||
|
ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test/t2`, CONSTRAINT `c1` FOREIGN KEY (`v`) REFERENCES `t1` (`id`))
|
||||||
|
INSERT INTO t1 VALUES(1);
|
||||||
|
INSERT INTO t2 VALUES(1);
|
||||||
|
DELETE FROM t1 WHERE id = 1;
|
||||||
|
ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test/t2`, CONSTRAINT `c1` FOREIGN KEY (`v`) REFERENCES `t1` (`id`))
|
||||||
|
DROP TABLE t1;
|
||||||
|
ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails
|
||||||
|
SET FOREIGN_KEY_CHECKS=0;
|
||||||
|
DROP TABLE t1;
|
||||||
|
SET FOREIGN_KEY_CHECKS=1;
|
||||||
|
INSERT INTO t2 VALUES(3);
|
||||||
|
ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test/t2`, CONSTRAINT `c1` FOREIGN KEY (`v`) REFERENCES `t1` (`id`))
|
||||||
|
DROP TABLE t2;
|
||||||
|
@@ -978,9 +978,9 @@ create table `t2` (`id` int( 11 ) not null default '0',unique key `id` ( `id` )
|
|||||||
insert into `t2`values ( 1 ) ;
|
insert into `t2`values ( 1 ) ;
|
||||||
create table `t3` (`id` int( 11 ) not null default '0',key `id` ( `id` ) ,constraint `t2_id_fk` foreign key ( `id` ) references `t2` (`id` )) engine = innodb;
|
create table `t3` (`id` int( 11 ) not null default '0',key `id` ( `id` ) ,constraint `t2_id_fk` foreign key ( `id` ) references `t2` (`id` )) engine = innodb;
|
||||||
insert into `t3`values ( 1 ) ;
|
insert into `t3`values ( 1 ) ;
|
||||||
--error 1217
|
--error 1451
|
||||||
delete t3,t2,t1 from t1,t2,t3 where t1.id =1 and t2.id = t1.id and t3.id = t2.id;
|
delete t3,t2,t1 from t1,t2,t3 where t1.id =1 and t2.id = t1.id and t3.id = t2.id;
|
||||||
--error 1217
|
--error 1451
|
||||||
update t1,t2,t3 set t3.id=5, t2.id=6, t1.id=7 where t1.id =1 and t2.id = t1.id and t3.id = t2.id;
|
update t1,t2,t3 set t3.id=5, t2.id=6, t1.id=7 where t1.id =1 and t2.id = t1.id and t3.id = t2.id;
|
||||||
--error 1054
|
--error 1054
|
||||||
update t3 set t3.id=7 where t1.id =1 and t2.id = t1.id and t3.id = t2.id;
|
update t3 set t3.id=7 where t1.id =1 and t2.id = t1.id and t3.id = t2.id;
|
||||||
@@ -996,7 +996,7 @@ create table t1(
|
|||||||
foreign key(pid) references t1(id) on delete cascade) engine=innodb;
|
foreign key(pid) references t1(id) on delete cascade) engine=innodb;
|
||||||
insert into t1 values(0,0),(1,0),(2,1),(3,2),(4,3),(5,4),(6,5),(7,6),
|
insert into t1 values(0,0),(1,0),(2,1),(3,2),(4,3),(5,4),(6,5),(7,6),
|
||||||
(8,7),(9,8),(10,9),(11,10),(12,11),(13,12),(14,13),(15,14);
|
(8,7),(9,8),(10,9),(11,10),(12,11),(13,12),(14,13),(15,14);
|
||||||
-- error 1217
|
-- error 1451
|
||||||
delete from t1 where id=0;
|
delete from t1 where id=0;
|
||||||
delete from t1 where id=15;
|
delete from t1 where id=15;
|
||||||
delete from t1 where id=0;
|
delete from t1 where id=0;
|
||||||
@@ -1528,3 +1528,39 @@ create table t4 (col1 text, index(col1(768)))
|
|||||||
--error 1005
|
--error 1005
|
||||||
create table t5 (col1 blob, index(col1(768)))
|
create table t5 (col1 blob, index(col1(768)))
|
||||||
character set = latin1 engine = innodb;
|
character set = latin1 engine = innodb;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Test improved foreign key error messages (bug #3443)
|
||||||
|
#
|
||||||
|
|
||||||
|
CREATE TABLE t1
|
||||||
|
(
|
||||||
|
id INT PRIMARY KEY
|
||||||
|
) ENGINE=InnoDB;
|
||||||
|
|
||||||
|
CREATE TABLE t2
|
||||||
|
(
|
||||||
|
v INT,
|
||||||
|
CONSTRAINT c1 FOREIGN KEY (v) REFERENCES t1(id)
|
||||||
|
) ENGINE=InnoDB;
|
||||||
|
|
||||||
|
--error 1452
|
||||||
|
INSERT INTO t2 VALUES(2);
|
||||||
|
|
||||||
|
INSERT INTO t1 VALUES(1);
|
||||||
|
INSERT INTO t2 VALUES(1);
|
||||||
|
|
||||||
|
--error 1451
|
||||||
|
DELETE FROM t1 WHERE id = 1;
|
||||||
|
|
||||||
|
--error 1217
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
SET FOREIGN_KEY_CHECKS=0;
|
||||||
|
DROP TABLE t1;
|
||||||
|
SET FOREIGN_KEY_CHECKS=1;
|
||||||
|
|
||||||
|
--error 1452
|
||||||
|
INSERT INTO t2 VALUES(3);
|
||||||
|
|
||||||
|
DROP TABLE t2;
|
||||||
|
@@ -6074,6 +6074,8 @@ ha_innobase::start_stmt(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
trx->detailed_error[0] = '\0';
|
||||||
|
|
||||||
/* Set the MySQL flag to mark that there is an active transaction */
|
/* Set the MySQL flag to mark that there is an active transaction */
|
||||||
if (trx->active_trans == 0) {
|
if (trx->active_trans == 0) {
|
||||||
|
|
||||||
@@ -6147,6 +6149,8 @@ ha_innobase::external_lock(
|
|||||||
if (lock_type != F_UNLCK) {
|
if (lock_type != F_UNLCK) {
|
||||||
/* MySQL is setting a new table lock */
|
/* MySQL is setting a new table lock */
|
||||||
|
|
||||||
|
trx->detailed_error[0] = '\0';
|
||||||
|
|
||||||
/* Set the MySQL flag to mark that there is an active
|
/* Set the MySQL flag to mark that there is an active
|
||||||
transaction */
|
transaction */
|
||||||
if (trx->active_trans == 0) {
|
if (trx->active_trans == 0) {
|
||||||
@@ -6950,6 +6954,18 @@ ha_innobase::reset_auto_increment(ulonglong value)
|
|||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* See comment in handler.cc */
|
||||||
|
bool
|
||||||
|
ha_innobase::get_error_message(int error, String *buf)
|
||||||
|
{
|
||||||
|
trx_t* trx = check_trx_exists(current_thd);
|
||||||
|
|
||||||
|
buf->copy(trx->detailed_error, strlen(trx->detailed_error),
|
||||||
|
system_charset_info);
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
Compares two 'refs'. A 'ref' is the (internal) primary key value of the row.
|
Compares two 'refs'. A 'ref' is the (internal) primary key value of the row.
|
||||||
If there is no explicitly declared non-null unique key or a primary key, then
|
If there is no explicitly declared non-null unique key or a primary key, then
|
||||||
|
@@ -174,6 +174,8 @@ class ha_innobase: public handler
|
|||||||
void init_table_handle_for_HANDLER();
|
void init_table_handle_for_HANDLER();
|
||||||
ulonglong get_auto_increment();
|
ulonglong get_auto_increment();
|
||||||
int reset_auto_increment(ulonglong value);
|
int reset_auto_increment(ulonglong value);
|
||||||
|
|
||||||
|
virtual bool get_error_message(int error, String *buf);
|
||||||
|
|
||||||
uint8 table_cache_type() { return HA_CACHE_TBL_ASKTRANSACT; }
|
uint8 table_cache_type() { return HA_CACHE_TBL_ASKTRANSACT; }
|
||||||
/*
|
/*
|
||||||
|
@@ -344,8 +344,8 @@ static int ha_init_errors(void)
|
|||||||
SETMSG(HA_ERR_READ_ONLY_TRANSACTION, ER(ER_READ_ONLY_TRANSACTION));
|
SETMSG(HA_ERR_READ_ONLY_TRANSACTION, ER(ER_READ_ONLY_TRANSACTION));
|
||||||
SETMSG(HA_ERR_LOCK_DEADLOCK, ER(ER_LOCK_DEADLOCK));
|
SETMSG(HA_ERR_LOCK_DEADLOCK, ER(ER_LOCK_DEADLOCK));
|
||||||
SETMSG(HA_ERR_CANNOT_ADD_FOREIGN, ER(ER_CANNOT_ADD_FOREIGN));
|
SETMSG(HA_ERR_CANNOT_ADD_FOREIGN, ER(ER_CANNOT_ADD_FOREIGN));
|
||||||
SETMSG(HA_ERR_NO_REFERENCED_ROW, ER(ER_NO_REFERENCED_ROW));
|
SETMSG(HA_ERR_NO_REFERENCED_ROW, ER(ER_NO_REFERENCED_ROW_2));
|
||||||
SETMSG(HA_ERR_ROW_IS_REFERENCED, ER(ER_ROW_IS_REFERENCED));
|
SETMSG(HA_ERR_ROW_IS_REFERENCED, ER(ER_ROW_IS_REFERENCED_2));
|
||||||
SETMSG(HA_ERR_NO_SAVEPOINT, "No savepoint with that name");
|
SETMSG(HA_ERR_NO_SAVEPOINT, "No savepoint with that name");
|
||||||
SETMSG(HA_ERR_NON_UNIQUE_BLOCK_SIZE, "Non unique key block size");
|
SETMSG(HA_ERR_NON_UNIQUE_BLOCK_SIZE, "Non unique key block size");
|
||||||
SETMSG(HA_ERR_NO_SUCH_TABLE, "No such table: '%.64s'");
|
SETMSG(HA_ERR_NO_SUCH_TABLE, "No such table: '%.64s'");
|
||||||
@@ -1798,11 +1798,19 @@ void handler::print_error(int error, myf errflag)
|
|||||||
textno=ER_CANNOT_ADD_FOREIGN;
|
textno=ER_CANNOT_ADD_FOREIGN;
|
||||||
break;
|
break;
|
||||||
case HA_ERR_ROW_IS_REFERENCED:
|
case HA_ERR_ROW_IS_REFERENCED:
|
||||||
textno=ER_ROW_IS_REFERENCED;
|
{
|
||||||
break;
|
String str;
|
||||||
|
get_error_message(error, &str);
|
||||||
|
my_error(ER_ROW_IS_REFERENCED_2, MYF(0), str.c_ptr_safe());
|
||||||
|
DBUG_VOID_RETURN;
|
||||||
|
}
|
||||||
case HA_ERR_NO_REFERENCED_ROW:
|
case HA_ERR_NO_REFERENCED_ROW:
|
||||||
textno=ER_NO_REFERENCED_ROW;
|
{
|
||||||
break;
|
String str;
|
||||||
|
get_error_message(error, &str);
|
||||||
|
my_error(ER_NO_REFERENCED_ROW_2, MYF(0), str.c_ptr_safe());
|
||||||
|
DBUG_VOID_RETURN;
|
||||||
|
}
|
||||||
case HA_ERR_TABLE_DEF_CHANGED:
|
case HA_ERR_TABLE_DEF_CHANGED:
|
||||||
textno=ER_TABLE_DEF_CHANGED;
|
textno=ER_TABLE_DEF_CHANGED;
|
||||||
break;
|
break;
|
||||||
|
@@ -5415,3 +5415,7 @@ ER_NO_SUCH_USER
|
|||||||
eng "There is not %-.64s@%-.64s registered"
|
eng "There is not %-.64s@%-.64s registered"
|
||||||
ER_FORBID_SCHEMA_CHANGE
|
ER_FORBID_SCHEMA_CHANGE
|
||||||
eng "Changing schema from '%-.64s' to '%-.64s' is not allowed."
|
eng "Changing schema from '%-.64s' to '%-.64s' is not allowed."
|
||||||
|
ER_ROW_IS_REFERENCED_2 23000
|
||||||
|
eng "Cannot delete or update a parent row: a foreign key constraint fails (%.192s)"
|
||||||
|
ER_NO_REFERENCED_ROW_2 23000
|
||||||
|
eng "Cannot add or update a child row: a foreign key constraint fails (%.192s)"
|
||||||
|
Reference in New Issue
Block a user