#At file:///Users/tnurnberg/forest/48525_/51-48525_/ based on revid:li-bing.song@stripped
3431 Tatiana A. Nurnberg 2010-03-29
Bug#48525: trigger changes "Column 'id' cannot be null" behaviour
CHECK_FIELD_IGNORE was treated as CHECK_FIELD_ERROR_FOR_NULL;
UPDATE...SET...NULL on NOT NULL fields behaved differently after
a trigger.
Now distinguishes between IGNORE and ERROR_FOR_NULL and save/restores
check-field options.
@ mysql-test/r/trigger.result
Show that UPDATE...SET...NULL on NOT NULL columns doesn't behave differently
when run after a trigger.
@ mysql-test/t/trigger.test
Show that UPDATE...SET...NULL on NOT NULL columns doesn't behave differently
when run after a trigger.
@ sql/field_conv.cc
CHECK_FIELD_IGNORE was treated as CHECK_FIELD_ERROR_FOR_NULL.
Distinguish between the two.
@ sql/sp_head.cc
Raise error as needed.
@ sql/sql_class.cc
Save and restore check-fields options.
@ sql/sql_class.h
Make room so we can save check-fields options.
@ sql/sql_insert.cc
Raise error as needed.
modified:
mysql-test/r/trigger.result
mysql-test/t/trigger.test
sql/field_conv.cc
sql/sp_head.cc
sql/sql_class.cc
sql/sql_class.h
sql/sql_insert.cc
=== modified file 'mysql-test/r/trigger.result'
--- a/mysql-test/r/trigger.result 2010-03-09 21:55:08 +0000
+++ b/mysql-test/r/trigger.result 2010-03-29 02:32:30 +0000
@@ -2111,4 +2111,21 @@ SET @bug51650 = 1;
INSERT IGNORE INTO t2 SET a = '777';
DROP TRIGGER trg1;
DROP TABLE t1, t2;
+CREATE TABLE t1 (id INT NOT NULL);
+CREATE TABLE t2 (id INT NOT NULL);
+INSERT t1 VALUES (1),(2),(3);
+UPDATE t1 SET id=NULL;
+Warnings:
+Warning 1048 Column 'id' cannot be null
+Warning 1048 Column 'id' cannot be null
+Warning 1048 Column 'id' cannot be null
+CREATE TRIGGER t1_bu BEFORE UPDATE ON t1 FOR EACH ROW
+INSERT INTO t2 VALUES (3);
+UPDATE t1 SET id=NULL;
+Warnings:
+Warning 1048 Column 'id' cannot be null
+Warning 1048 Column 'id' cannot be null
+Warning 1048 Column 'id' cannot be null
+DROP TRIGGER t1_bu;
+DROP TABLE t1,t2;
End of 5.1 tests.
=== modified file 'mysql-test/t/trigger.test'
--- a/mysql-test/t/trigger.test 2010-03-09 21:55:08 +0000
+++ b/mysql-test/t/trigger.test 2010-03-29 02:32:30 +0000
@@ -2426,4 +2426,17 @@ INSERT IGNORE INTO t2 SET a = '777';
DROP TRIGGER trg1;
DROP TABLE t1, t2;
+#
+# Bug #48525: trigger changes "Column 'id' cannot be null" behaviour
+#
+CREATE TABLE t1 (id INT NOT NULL);
+CREATE TABLE t2 (id INT NOT NULL);
+INSERT t1 VALUES (1),(2),(3);
+UPDATE t1 SET id=NULL;
+CREATE TRIGGER t1_bu BEFORE UPDATE ON t1 FOR EACH ROW
+ INSERT INTO t2 VALUES (3);
+UPDATE t1 SET id=NULL;
+DROP TRIGGER t1_bu;
+DROP TABLE t1,t2;
+
--echo End of 5.1 tests.
=== modified file 'sql/field_conv.cc'
--- a/sql/field_conv.cc 2010-02-22 16:58:56 +0000
+++ b/sql/field_conv.cc 2010-03-29 02:32:30 +0000
@@ -122,13 +122,18 @@ set_field_to_null(Field *field)
return 0;
}
field->reset();
- if (field->table->in_use->count_cuted_fields == CHECK_FIELD_WARN)
- {
+ switch (field->table->in_use->count_cuted_fields) {
+ case CHECK_FIELD_WARN:
field->set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, 1);
+ /* fall through */
+ case CHECK_FIELD_IGNORE:
return 0;
+ case CHECK_FIELD_ERROR_FOR_NULL:
+ if (!field->table->in_use->no_errors)
+ my_error(ER_BAD_NULL_ERROR, MYF(0), field->field_name);
+ return -1;
}
- if (!field->table->in_use->no_errors)
- my_error(ER_BAD_NULL_ERROR, MYF(0), field->field_name);
+ DBUG_ASSERT(0); // impossible
return -1;
}
@@ -178,13 +183,18 @@ set_field_to_null_with_conversions(Field
field->table->auto_increment_field_not_null= FALSE;
return 0; // field is set in fill_record()
}
- if (field->table->in_use->count_cuted_fields == CHECK_FIELD_WARN)
- {
+ switch (field->table->in_use->count_cuted_fields) {
+ case CHECK_FIELD_WARN:
field->set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_BAD_NULL_ERROR, 1);
+ /* fall through */
+ case CHECK_FIELD_IGNORE:
return 0;
+ case CHECK_FIELD_ERROR_FOR_NULL:
+ if (!field->table->in_use->no_errors)
+ my_error(ER_BAD_NULL_ERROR, MYF(0), field->field_name);
+ return -1;
}
- if (!field->table->in_use->no_errors)
- my_error(ER_BAD_NULL_ERROR, MYF(0), field->field_name);
+ DBUG_ASSERT(0); // impossible
return -1;
}
=== modified file 'sql/sp_head.cc'
--- a/sql/sp_head.cc 2010-02-22 16:58:56 +0000
+++ b/sql/sp_head.cc 2010-03-29 02:32:30 +0000
@@ -3009,6 +3009,7 @@ int
sp_instr_set_trigger_field::execute(THD *thd, uint *nextp)
{
DBUG_ENTER("sp_instr_set_trigger_field::execute");
+ thd->count_cuted_fields= CHECK_FIELD_ERROR_FOR_NULL;
DBUG_RETURN(m_lex_keeper.reset_lex_and_exec_core(thd, nextp, TRUE, this));
}
=== modified file 'sql/sql_class.cc'
--- a/sql/sql_class.cc 2010-02-26 13:16:46 +0000
+++ b/sql/sql_class.cc 2010-03-29 02:32:30 +0000
@@ -3100,6 +3100,7 @@ void THD::reset_sub_statement_state(Sub_
}
#endif
+ backup->count_cuted_fields= count_cuted_fields;
backup->options= options;
backup->in_sub_stmt= in_sub_stmt;
backup->enable_slow_log= enable_slow_log;
@@ -3137,6 +3138,7 @@ void THD::reset_sub_statement_state(Sub_
void THD::restore_sub_statement_state(Sub_statement_state *backup)
{
+ DBUG_ENTER("THD::restore_sub_statement_state");
#ifndef EMBEDDED_LIBRARY
/* BUG#33029, if we are replicating from a buggy master, restore
auto_inc_intervals_forced so that the top statement can use the
@@ -3163,6 +3165,7 @@ void THD::restore_sub_statement_state(Su
/* ha_release_savepoint() never returns error. */
(void)ha_release_savepoint(this, sv);
}
+ count_cuted_fields= backup->count_cuted_fields;
transaction.savepoints= backup->savepoints;
options= backup->options;
in_sub_stmt= backup->in_sub_stmt;
@@ -3192,6 +3195,7 @@ void THD::restore_sub_statement_state(Su
*/
examined_row_count+= backup->examined_row_count;
cuted_fields+= backup->cuted_fields;
+ DBUG_VOID_RETURN;
}
=== modified file 'sql/sql_class.h'
--- a/sql/sql_class.h 2010-02-26 13:16:46 +0000
+++ b/sql/sql_class.h 2010-03-29 02:32:30 +0000
@@ -995,6 +995,7 @@ public:
bool enable_slow_log;
bool last_insert_id_used;
SAVEPOINT *savepoints;
+ enum enum_check_fields count_cuted_fields;
};
=== modified file 'sql/sql_insert.cc'
--- a/sql/sql_insert.cc 2010-02-22 16:58:56 +0000
+++ b/sql/sql_insert.cc 2010-03-29 02:32:30 +0000
@@ -3158,7 +3158,7 @@ bool select_insert::send_data(List<Item>
thd->count_cuted_fields= CHECK_FIELD_WARN; // Calculate cuted fields
store_values(values);
- thd->count_cuted_fields= CHECK_FIELD_IGNORE;
+ thd->count_cuted_fields= CHECK_FIELD_ERROR_FOR_NULL;
if (thd->is_error())
{
table->auto_increment_field_not_null= FALSE;
Attachment: [text/bzr-bundle] bzr/azundris@mysql.com-20100329023230-kgpoe9j8irm13kta.bundle
Thread |
---|
• bzr commit into mysql-5.1-bugteam branch (azundris:3431) Bug#48525 | Tatiana A. Nurnberg | 29 Mar |