summaryrefslogtreecommitdiff
path: root/sql/field_conv.cc
diff options
context:
space:
mode:
authorAlexander Barkov <bar@mariadb.org>2015-12-29 19:37:11 +0400
committerAlexander Barkov <bar@mariadb.org>2015-12-29 19:37:11 +0400
commit2ba7ed77aab05004f0c853a77850e325b78a1892 (patch)
tree943659d76215e16d0d1946c28683c562debeff34 /sql/field_conv.cc
parent63f0669fd6dc430b60ffd5de0bff9854622a1c1a (diff)
parent1bb66ea88c4679d6bd3ad1472d75983e66f679ae (diff)
downloadmariadb-git-2ba7ed77aab05004f0c853a77850e325b78a1892.tar.gz
Merge remote-tracking branch 'origin/10.1' into 10.2
Diffstat (limited to 'sql/field_conv.cc')
-rw-r--r--sql/field_conv.cc105
1 files changed, 51 insertions, 54 deletions
diff --git a/sql/field_conv.cc b/sql/field_conv.cc
index 3d9c25a69d1..21f46bbbedb 100644
--- a/sql/field_conv.cc
+++ b/sql/field_conv.cc
@@ -116,8 +116,25 @@ 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)
+{
+ switch (field->table->in_use->count_cuted_fields) {
+ case CHECK_FIELD_WARN:
+ field->set_warning(Sql_condition::WARN_LEVEL_WARN, err, 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;
+}
+
+
+int set_field_to_null(Field *field)
{
if (field->table->null_catch_flags & CHECK_ROW_FOR_NULLS_TO_REJECT)
{
@@ -131,21 +148,39 @@ set_field_to_null(Field *field)
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);
- /* fall through */
- case CHECK_FIELD_IGNORE:
+ return set_bad_null_error(field, WARN_DATA_TRUNCATED);
+}
+
+
+/**
+ 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;
- 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;
-}
+ 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.
@@ -181,38 +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()
- }
- 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 convert_null_to_field_value_or_error(field);
}
@@ -333,9 +337,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)
@@ -710,12 +712,7 @@ Copy_field::get_copy_func(const Field *to, const 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 - portable_sizeof_char_ptr;
- from_ptr+= from_length - portable_sizeof_char_ptr;
return do_copy_blob;
- }
}
else
{