MySQL Lists are EOL. Please join:

List:Internals« Previous MessageNext Message »
From:Osku Salerma Date:September 23 2005 1:22pm
Subject:bk commit into 5.0 tree (osku:1.2001) BUG#3443
View as plain text  
Below is the list of changes that have just been committed into a local
5.0 repository of osku. When osku does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html

ChangeSet
  1.2001 05/09/23 16:22:27 osku@127.(none) +15 -0
  Fix bug #3443, better foreign key error messsages.

  sql/share/errmsg.txt
    1.46 05/09/23 16:22:23 osku@127.(none) +4 -0
    Add ER_ROW_IS_REFERENCED_2 and ER_NO_REFERENCED_ROW_2.

  sql/handler.cc
    1.193 05/09/23 16:22:23 osku@127.(none) +14 -6
    Add special case code in print_error for HA_ERR_ROW_IS_REFERENCED and
    HA_ERR_NO_REFERENCED_ROW.
    
    Change SETMSG to point to new error messages.

  sql/ha_innodb.h
    1.104 05/09/23 16:22:23 osku@127.(none) +2 -0
    Add get_error_message.

  sql/ha_innodb.cc
    1.259 05/09/23 16:22:23 osku@127.(none) +16 -0
    Add get_error_message.
    
    Clear trx->detailed_error in start_stmt and external_lock.

  mysql-test/t/innodb.test
    1.110 05/09/23 16:22:23 osku@127.(none) +39 -3
    Add new tests, adapt existing ones whose output was changed.

  mysql-test/r/innodb.result
    1.136 05/09/23 16:22:23 osku@127.(none) +26 -3
    Add new tests, adapt existing ones whose output was changed.

  innobase/ut/ut0mem.c
    1.28 05/09/23 16:22:23 osku@127.(none) +25 -0
    Add ut_strlcpy.

  innobase/trx/trx0trx.c
    1.61 05/09/23 16:22:23 osku@127.(none) +27 -0
    Add trx_set_detailed_error and trx_set_detailed_error_from_file.
    
    Clear trx->detailed_error in trx_create.

  innobase/row/row0ins.c
    1.70 05/09/23 16:22:23 osku@127.(none) +36 -4
    Add row_ins_set_detailed function and call it when needed.
    
    Adapt to changes in dict_print_info_on_foreign_key_in_create_format.

  innobase/os/os0file.c
    1.111 05/09/23 16:22:23 osku@127.(none) +23 -0
    Add os_file_read_string.

  innobase/include/ut0mem.h
    1.18 05/09/23 16:22:23 osku@127.(none) +12 -0
    Add ut_strlcpy.

  innobase/include/trx0trx.h
    1.54 05/09/23 16:22:23 osku@127.(none) +19 -0
    Add trx_set_detailed_error and trx_set_detailed_error_from_file functions
    and a detailed_error field to trx_struct.

  innobase/include/os0file.h
    1.39 05/09/23 16:22:23 osku@127.(none) +11 -0
    Add os_file_read_string.

  innobase/include/dict0dict.h
    1.35 05/09/23 16:22:23 osku@127.(none) +4 -3
    Add 'add_newline' parameter to dict_print_info_on_foreign_key_in_create_format.

  innobase/dict/dict0dict.c
    1.67 05/09/23 16:22:23 osku@127.(none) +16 -6
    Add 'add_newline' parameter to dict_print_info_on_foreign_key_in_create_format.

# This is a BitKeeper patch.  What follows are the unified diffs for the
# set of deltas contained in the patch.  The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User:	osku
# Host:	127.(none)
# Root:	/home/osku/mysql/5.0/3443

--- 1.192/sql/handler.cc	2005-09-23 05:46:10 +03:00
+++ 1.193/sql/handler.cc	2005-09-23 16:22:23 +03:00
@@ -344,8 +344,8 @@
   SETMSG(HA_ERR_READ_ONLY_TRANSACTION,  ER(ER_READ_ONLY_TRANSACTION));
   SETMSG(HA_ERR_LOCK_DEADLOCK,          ER(ER_LOCK_DEADLOCK));
   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_ROW_IS_REFERENCED,      ER(ER_ROW_IS_REFERENCED));
+  SETMSG(HA_ERR_NO_REFERENCED_ROW,      ER(ER_NO_REFERENCED_ROW_2));
+  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_NON_UNIQUE_BLOCK_SIZE,  "Non unique key block size");
   SETMSG(HA_ERR_NO_SUCH_TABLE,          "No such table: '%.64s'");
@@ -1798,11 +1798,19 @@
     textno=ER_CANNOT_ADD_FOREIGN;
     break;
   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:
-    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:
     textno=ER_TABLE_DEF_CHANGED;
     break;

--- 1.45/sql/share/errmsg.txt	2005-09-16 18:13:14 +03:00
+++ 1.46/sql/share/errmsg.txt	2005-09-23 16:22:23 +03:00
@@ -5415,3 +5415,7 @@
         eng "There is not %-.64s@%-.64s registered"
 ER_FORBID_SCHEMA_CHANGE
 	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)"

--- 1.66/innobase/dict/dict0dict.c	2005-09-06 14:38:17 +03:00
+++ 1.67/innobase/dict/dict0dict.c	2005-09-23 16:22:23 +03:00
@@ -2189,7 +2189,7 @@
 	dict_foreign_error_report_low(file, fk->foreign_table_name);
 	fputs(msg, 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) {
 		fputs("\nThe index in the foreign key in table is ", file);
 		ut_print_name(file, NULL, fk->foreign_index->name);
@@ -4330,9 +4330,10 @@
 void
 dict_print_info_on_foreign_key_in_create_format(
 /*============================================*/
-	FILE*		file,	/* in: file where to print */
-	trx_t*		trx,	/* in: transaction */
-	dict_foreign_t*	foreign)/* in: foreign key constraint */
+	FILE*		file,		/* in: file where to print */
+	trx_t*		trx,		/* in: transaction */
+	dict_foreign_t*	foreign,	/* in: foreign key constraint */
+	ibool		add_newline)	/* in: whether to add a newline */
 {
 	const char*	stripped_id;
 	ulint	i;
@@ -4345,7 +4346,16 @@
 		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);
 	fputs(" FOREIGN KEY (", file);
 
@@ -4447,7 +4457,7 @@
 	while (foreign != NULL) {
 		if (create_table_format) {
 			dict_print_info_on_foreign_key_in_create_format(
-						file, trx, foreign);
+						file, trx, foreign, TRUE);
 		} else {
 			ulint	i;
 			fputs("; (", file);

--- 1.34/innobase/include/dict0dict.h	2005-09-06 14:38:17 +03:00
+++ 1.35/innobase/include/dict0dict.h	2005-09-23 16:22:23 +03:00
@@ -375,9 +375,10 @@
 void
 dict_print_info_on_foreign_key_in_create_format(
 /*============================================*/
-	FILE*		file,	/* in: file where to print */
-	trx_t*		trx,	/* in: transaction */
-	dict_foreign_t*	foreign);/* in: foreign key constraint */
+	FILE*		file,		/* in: file where to print */
+	trx_t*		trx,		/* in: transaction */
+	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. */
 void

--- 1.38/innobase/include/os0file.h	2005-07-26 14:21:32 +03:00
+++ 1.39/innobase/include/os0file.h	2005-09-23 16:22:23 +03:00
@@ -432,6 +432,17 @@
 				offset */
 	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
 any error handling. In case of error it returns FALSE. */
 

--- 1.53/innobase/include/trx0trx.h	2005-08-12 11:29:56 +03:00
+++ 1.54/innobase/include/trx0trx.h	2005-09-23 16:22:23 +03:00
@@ -56,6 +56,22 @@
 trx_search_latch_release_if_reserved(
 /*=================================*/
         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. */
 
@@ -649,6 +665,9 @@
 	trx_undo_arr_t*	undo_no_arr;	/* array of undo numbers of undo log
 					records which are currently processed
 					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

--- 1.17/innobase/include/ut0mem.h	2004-11-26 00:09:39 +02:00
+++ 1.18/innobase/include/ut0mem.h	2005-09-23 16:22:23 +03:00
@@ -119,6 +119,18 @@
 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)). */
 UNIV_INLINE
 ulint

--- 1.110/innobase/os/os0file.c	2005-07-26 14:21:32 +03:00
+++ 1.111/innobase/os/os0file.c	2005-09-23 16:22:23 +03:00
@@ -2249,6 +2249,29 @@
 }
 
 /***********************************************************************
+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. */
 
 ibool

--- 1.69/innobase/row/row0ins.c	2005-08-12 11:29:56 +03:00
+++ 1.70/innobase/row/row0ins.c	2005-09-23 16:22:23 +03:00
@@ -579,6 +579,30 @@
 }
 
 /*************************************************************************
+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
 parent table index entry. */
 static
@@ -598,6 +622,8 @@
 	FILE*	ef	= dict_foreign_err_file;
 	trx_t*	trx	= thr_get_trx(thr);
 
+	row_ins_set_detailed(trx, foreign);
+
 	mutex_enter(&dict_foreign_err_mutex);
 	rewind(ef);
 	ut_print_timestamp(ef);
@@ -607,7 +633,8 @@
 	fputs("Foreign key constraint fails for table ", ef);
 	ut_print_name(ef, trx, foreign->foreign_table_name);
 	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);
 	fputs(errstr, ef);
 	fputs(" in parent table, in index ", ef);
@@ -648,7 +675,9 @@
 					child table */
 {
 	FILE*	ef	= dict_foreign_err_file;
-
+	
+	row_ins_set_detailed(trx, foreign);
+	
 	mutex_enter(&dict_foreign_err_mutex);
 	rewind(ef);
 	ut_print_timestamp(ef);
@@ -657,7 +686,8 @@
 	fputs("Foreign key constraint fails for table ", ef);
 	ut_print_name(ef, trx, foreign->foreign_table_name);
 	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);
 	ut_print_name(ef, trx, foreign->foreign_index->name);
 	if (entry) {
@@ -1223,6 +1253,8 @@
 
 	if (check_table == NULL || check_table->ibd_file_missing) {
 		if (check_ref) {
+			row_ins_set_detailed(trx, foreign);
+			
 			FILE*	ef = dict_foreign_err_file;
 			mutex_enter(&dict_foreign_err_mutex);
 			rewind(ef);
@@ -1233,7 +1265,7 @@
 			ut_print_name(ef, trx, foreign->foreign_table_name);
 			fputs(":\n", ef);
 			dict_print_info_on_foreign_key_in_create_format(ef,
-					trx, foreign);
+					trx, foreign, TRUE);
 			fputs("\nTrying to add to index ", ef);
 			ut_print_name(ef, trx, foreign->foreign_index->name);
 			fputs(" tuple:\n", ef);

--- 1.60/innobase/trx/trx0trx.c	2005-08-12 11:29:57 +03:00
+++ 1.61/innobase/trx/trx0trx.c	2005-09-23 16:22:23 +03:00
@@ -52,6 +52,32 @@
         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. */
 
@@ -130,6 +156,7 @@
 	trx->undo_no_arr = NULL;
 	
 	trx->error_state = DB_SUCCESS;
+	trx->detailed_error[0] = '\0';
 
 	trx->sess = sess;
 	trx->que_state = TRX_QUE_RUNNING;

--- 1.27/innobase/ut/ut0mem.c	2005-03-07 09:41:45 +02:00
+++ 1.28/innobase/ut/ut0mem.c	2005-09-23 16:22:23 +03:00
@@ -343,6 +343,31 @@
 }
 
 /**************************************************************************
+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
 quotes will not be included; only embedded quotes will be escaped.
 See also ut_strlenq() and ut_memcpyq(). */

--- 1.135/mysql-test/r/innodb.result	2005-09-21 18:38:03 +03:00
+++ 1.136/mysql-test/r/innodb.result	2005-09-23 16:22:23 +03:00
@@ -1378,9 +1378,9 @@
 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 ) ;
 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;
-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;
 ERROR 42S22: Unknown column 't1.id' in 'where clause'
 drop table t3,t2,t1;
@@ -1392,7 +1392,7 @@
 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);
 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=0;
 drop table t1;
@@ -2559,3 +2559,26 @@
 ) ENGINE=InnoDB;
 Got one of the listed errors
 DROP TABLE t1;
+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;

--- 1.109/mysql-test/t/innodb.test	2005-09-21 14:19:20 +03:00
+++ 1.110/mysql-test/t/innodb.test	2005-09-23 16:22:23 +03:00
@@ -978,9 +978,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;
 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;
---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;
 --error 1054
 update t3 set  t3.id=7  where t1.id =1 and t2.id = t1.id and t3.id = t2.id;
@@ -996,7 +996,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),
 	(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=15;
 delete from t1 where id=0;
@@ -1482,3 +1482,39 @@
  FOREIGN KEY (b) REFERENCES test.t1(id)
 ) ENGINE=InnoDB;
 DROP TABLE t1;
+
+#
+# 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;

--- 1.258/sql/ha_innodb.cc	2005-09-20 21:24:21 +03:00
+++ 1.259/sql/ha_innodb.cc	2005-09-23 16:22:23 +03:00
@@ -6065,6 +6065,8 @@
 		}
 	}
 
+	trx->detailed_error[0] = '\0';
+
 	/* Set the MySQL flag to mark that there is an active transaction */
         if (trx->active_trans == 0) {
 
@@ -6138,6 +6140,8 @@
 	if (lock_type != F_UNLCK) {
 		/* MySQL is setting a new table lock */
 
+		trx->detailed_error[0] = '\0';
+		
 		/* Set the MySQL flag to mark that there is an active
 		transaction */
                 if (trx->active_trans == 0) {
@@ -6939,6 +6943,18 @@
 	dict_table_autoinc_initialize(prebuilt->table, value);
 
 	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;
 }
 
 /***********************************************************************

--- 1.103/sql/ha_innodb.h	2005-09-22 13:09:03 +03:00
+++ 1.104/sql/ha_innodb.h	2005-09-23 16:22:23 +03:00
@@ -174,6 +174,8 @@
 	void init_table_handle_for_HANDLER(); 
 	ulonglong get_auto_increment();
 	int reset_auto_increment(ulonglong value);
+
+	virtual bool get_error_message(int error, String *buf);
 	
         uint8 table_cache_type() { return HA_CACHE_TBL_ASKTRANSACT; }
         /*
Thread
bk commit into 5.0 tree (osku:1.2001) BUG#3443Osku Salerma23 Sep