From: Dmitry Shulga Date: August 10 2012 6:36am Subject: bzr push into mysql-trunk branch (Dmitry.Shulga:4192 to 4193) WL#6030 List-Archive: http://lists.mysql.com/commits/144538 Message-Id: <201208100634.q7A6YXVo030413@acsmt358.oracle.com> MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit 4193 Dmitry Shulga 2012-08-10 The follow-up for WL#6030. Added some doxygen-style comments. modified: sql/field.cc sql/field.h sql/sql_base.cc 4192 Dmitry Shulga 2012-08-08 This is core patch for WL#6030. This patch does the following things: - changes Field class so that it is possible to set NOT NULL fields temporary to NULL; - allows NOT NULL fields to accept NULL values temporarily during BEFORE-trigger processing; - checks that the NOT NULL constraint is enforced after BEFORE-trigger processing. modified: mysql-test/r/warnings.result mysql-test/suite/funcs_1/r/innodb_trig_09.result mysql-test/suite/funcs_1/r/memory_trig_09.result mysql-test/suite/funcs_1/r/myisam_trig_09.result sql/field.cc sql/field.h sql/field_conv.cc sql/item.cc sql/item_sum.cc sql/sql_base.cc === modified file 'sql/field.cc' --- a/sql/field.cc 2012-08-08 14:49:40 +0000 +++ b/sql/field.cc 2012-08-10 06:34:02 +0000 @@ -1425,6 +1425,12 @@ type_conversion_status Field::check_cons } +/** + Set field to value NULL. + + @param row_offset This is the offset between the row being updated + and table->record[0] +*/ void Field::set_null(my_ptrdiff_t row_offset) { if (real_maybe_null()) @@ -1439,6 +1445,12 @@ void Field::set_null(my_ptrdiff_t row_of } +/** + Set field to value NOT NULL. + + @param row_offset This is the offset between the row being updated + and table->record[0] +*/ void Field::set_notnull(my_ptrdiff_t row_offset) { if (real_maybe_null()) === modified file 'sql/field.h' --- a/sql/field.h 2012-08-08 14:49:40 +0000 +++ b/sql/field.h 2012-08-10 06:34:02 +0000 @@ -572,12 +572,31 @@ public: const char *field_name_arg); virtual ~Field() {} + /** + Turn on/off temporary nullability for the field. + + @param is_tmp_nullable NULLability flag: + true - turn on temporary NULLability + false - turn off temporary NULLability + */ void set_tmp_nullable(bool is_tmp_nullable) { m_is_tmp_nullable= is_tmp_nullable; } + /** + Return temporary NULLability flag. + + @return true - if NULL can be assigned temporary to the Field + false - if NULL can not be assigned temporary to the Field + */ bool is_tmp_nullable() const { return m_is_tmp_nullable; } + /** + Check whether Field has temporary value NULL. + + @return true - if the Field has temporary value NULL + false - if the Field's value is NOT NULL + */ bool is_tmp_null() const { return is_tmp_nullable() && m_is_tmp_null; } @@ -899,6 +918,12 @@ public: bool is_temporal_with_date_and_time() const { return is_temporal_type_with_date_and_time(type()); } + /** + Check whether the full table's row is NULL or the Field has value NULL. + + @return true if the full table's row is NULL or the Field has value NULL + false if neither table's row nor the Field has value NULL + */ bool is_null(my_ptrdiff_t row_offset= 0) const { /* @@ -918,6 +943,12 @@ public: is_real_null(row_offset); } + /** + Check whether the Field has value NULL (temporary or actual). + + @return true if the Field has value NULL (temporary or actual) + false if the Field has value NOT NULL. + */ bool is_real_null(my_ptrdiff_t row_offset= 0) const { if (real_maybe_null()) @@ -929,6 +960,13 @@ public: return false; } + /** + Check if the Field has value NULL or the record specified by argument + has value NULL for this Field. + + @return true if the Field has value NULL or the record has value NULL + for thois Field. + */ bool is_null_in_record(const uchar *record) const { if (real_maybe_null()) @@ -946,6 +984,13 @@ public: type_conversion_status check_constraints() const; + /** + Remember the value of THD::count_cuted_fields to handle possible + NOT-NULL constraint errors after BEFORE-trigger execution is finished. + We should save the value of THD::count_cuted_fields before starting + BEFORE-trigger processing since during triggers execution the + value of THD::count_cuted_fields could be changed. + */ void set_count_cuted_fields(enum_check_fields count_cuted_fields) { m_count_cuted_fields_saved= count_cuted_fields; } === modified file 'sql/sql_base.cc' --- a/sql/sql_base.cc 2012-08-08 14:49:40 +0000 +++ b/sql/sql_base.cc 2012-08-10 06:34:02 +0000 @@ -8979,6 +8979,11 @@ fill_record_n_invoke_before_triggers(THD Item_field *item_field= item->field_for_view_update(); if (!item_field) { + /** + Rewind iterator for table's fields, iterate along + all fields and reset temporary NULLability flag for + every fields before this one that fired an error. + */ it.rewind(); Item *item_to_restore; while ((item_to_restore= it++) && item_to_restore != item) No bundle (reason: useless for push emails).