From ad5db17e882fea36dcae6f6e61996b5f9bf28962 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Wed, 16 Dec 2015 12:12:01 +0100 Subject: cleanup * move common code to a new set_bad_null_error() function * move repeated comparison out of the loop * remove unused code * unused method Table_triggers_list::set_table * redundant condition (if (table) after table was dereferenced) * add an assert --- sql/field_conv.cc | 49 +++++++++++++++++++++---------------------------- 1 file changed, 21 insertions(+), 28 deletions(-) (limited to 'sql/field_conv.cc') diff --git a/sql/field_conv.cc b/sql/field_conv.cc index 0ad8cee0c3b..df4730a50ce 100644 --- a/sql/field_conv.cc +++ b/sql/field_conv.cc @@ -116,24 +116,11 @@ static void do_outer_field_to_null_str(Copy_field *copy) } -int -set_field_to_null(Field *field) +static int set_bad_null_error(Field *field, int err) { - if (field->table->null_catch_flags & CHECK_ROW_FOR_NULLS_TO_REJECT) - { - field->table->null_catch_flags|= REJECT_ROW_DUE_TO_NULL_FIELDS; - return -1; - } - if (field->real_maybe_null()) - { - field->set_null(); - field->reset(); - return 0; - } - field->reset(); switch (field->table->in_use->count_cuted_fields) { case CHECK_FIELD_WARN: - field->set_warning(Sql_condition::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, 1); + field->set_warning(Sql_condition::WARN_LEVEL_WARN, err, 1); /* fall through */ case CHECK_FIELD_IGNORE: return 0; @@ -147,6 +134,24 @@ set_field_to_null(Field *field) } +int set_field_to_null(Field *field) +{ + if (field->table->null_catch_flags & CHECK_ROW_FOR_NULLS_TO_REJECT) + { + field->table->null_catch_flags|= REJECT_ROW_DUE_TO_NULL_FIELDS; + return -1; + } + if (field->real_maybe_null()) + { + field->set_null(); + field->reset(); + return 0; + } + field->reset(); + return set_bad_null_error(field, WARN_DATA_TRUNCATED); +} + + /** Set field to NULL or TIMESTAMP or to next auto_increment number. @@ -200,19 +205,7 @@ set_field_to_null_with_conversions(Field *field, bool no_conversions) field->table->auto_increment_field_not_null= FALSE; return 0; // field is set in fill_record() } - switch (field->table->in_use->count_cuted_fields) { - case CHECK_FIELD_WARN: - field->set_warning(Sql_condition::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; - } - DBUG_ASSERT(0); // impossible - return -1; + return set_bad_null_error(field, ER_BAD_NULL_ERROR); } -- cgit v1.2.1 From 0686c34d22a5cbf93015012eaf77a4a977b63afb Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sat, 14 Nov 2015 22:51:54 +0100 Subject: MDEV-8605 MariaDB not use DEFAULT value even when inserted NULL for NOT NULLABLE column NOT NULL constraint must be checked *after* the BEFORE triggers. That is for INSERT and UPDATE statements even NOT NULL fields must be able to store a NULL temporarily at least while BEFORE INSERT/UPDATE triggers are running. --- sql/field_conv.cc | 51 +++++++++++++++++++++++++++++++-------------------- 1 file changed, 31 insertions(+), 20 deletions(-) (limited to 'sql/field_conv.cc') diff --git a/sql/field_conv.cc b/sql/field_conv.cc index df4730a50ce..0f6c85f50e8 100644 --- a/sql/field_conv.cc +++ b/sql/field_conv.cc @@ -152,6 +152,36 @@ int set_field_to_null(Field *field) } +/** + Set TIMESTAMP to NOW(), AUTO_INCREMENT to the next number, or report an error + + @param field Field to update + + @retval + 0 Field could take 0 or an automatic conversion was used + @retval + -1 Field could not take NULL and no conversion was used. + If no_conversion was not set, an error message is printed +*/ + +int convert_null_to_field_value_or_error(Field *field) +{ + if (field->type() == MYSQL_TYPE_TIMESTAMP) + { + ((Field_timestamp*) field)->set_time(); + return 0; + } + + field->reset(); // Note: we ignore any potential failure of reset() here. + + if (field == field->table->next_number_field) + { + field->table->auto_increment_field_not_null= FALSE; + return 0; // field is set in fill_record() + } + return set_bad_null_error(field, ER_BAD_NULL_ERROR); +} + /** Set field to NULL or TIMESTAMP or to next auto_increment number. @@ -186,26 +216,7 @@ set_field_to_null_with_conversions(Field *field, bool no_conversions) if (no_conversions) return -1; - /* - Check if this is a special type, which will get a special walue - when set to NULL (TIMESTAMP fields which allow setting to NULL - are handled by first check). - */ - if (field->type() == MYSQL_TYPE_TIMESTAMP) - { - ((Field_timestamp*) field)->set_time(); - return 0; // Ok to set time to NULL - } - - // Note: we ignore any potential failure of reset() here. - field->reset(); - - if (field == field->table->next_number_field) - { - field->table->auto_increment_field_not_null= FALSE; - return 0; // field is set in fill_record() - } - return set_bad_null_error(field, ER_BAD_NULL_ERROR); + return convert_null_to_field_value_or_error(field); } -- cgit v1.2.1 From e1b9be5417668b184893148adea5f1f0e3a8d00f Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Tue, 29 Dec 2015 14:17:31 +0400 Subject: MDEV-9319 ALTER from a bigger to a smaller blob type truncates too much data --- sql/field_conv.cc | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) (limited to 'sql/field_conv.cc') diff --git a/sql/field_conv.cc b/sql/field_conv.cc index d24f31e4fa1..3fdc1639266 100644 --- a/sql/field_conv.cc +++ b/sql/field_conv.cc @@ -332,9 +332,7 @@ static void do_copy_next_number(Copy_field *copy) static void do_copy_blob(Copy_field *copy) { - ulong length=((Field_blob*) copy->from_field)->get_length(); - ((Field_blob*) copy->to_field)->store_length(length); - memcpy(copy->to_ptr, copy->from_ptr, sizeof(char*)); + ((Field_blob*) copy->to_field)->copy_value(((Field_blob*) copy->from_field)); } static void do_conv_blob(Copy_field *copy) @@ -709,12 +707,7 @@ Copy_field::get_copy_func(Field *to,Field *from) if (!(from->flags & BLOB_FLAG) || from->charset() != to->charset()) return do_conv_blob; if (from_length != to_length) - { - // Correct pointer to point at char pointer - to_ptr+= to_length - to->table->s->blob_ptr_size; - from_ptr+= from_length- from->table->s->blob_ptr_size; return do_copy_blob; - } } else { -- cgit v1.2.1