diff options
Diffstat (limited to 'sql')
-rw-r--r-- | sql/field.h | 1 | ||||
-rw-r--r-- | sql/field_conv.cc | 55 | ||||
-rw-r--r-- | sql/item.cc | 42 | ||||
-rw-r--r-- | sql/item.h | 3 |
4 files changed, 78 insertions, 23 deletions
diff --git a/sql/field.h b/sql/field.h index b138eb772d8..e822f6a71d6 100644 --- a/sql/field.h +++ b/sql/field.h @@ -1043,6 +1043,7 @@ Field *make_field(char *ptr, uint32 field_length, uint pack_length_to_packflag(uint type); uint32 calc_pack_length(enum_field_types type,uint32 length); bool set_field_to_null(Field *field); +bool set_field_to_null_with_conversions(Field *field); uint find_enum(TYPELIB *typelib,const char *x, uint length); ulonglong find_set(TYPELIB *typelib,const char *x, uint length); bool test_if_int(const char *str,int length); diff --git a/sql/field_conv.cc b/sql/field_conv.cc index 606edd84c74..dab96a9b827 100644 --- a/sql/field_conv.cc +++ b/sql/field_conv.cc @@ -112,35 +112,52 @@ static void do_outer_field_to_null_str(Copy_field *copy) bool set_field_to_null(Field *field) { - if (field->maybe_null()) + if (field->real_maybe_null()) { field->set_null(); field->reset(); + return 0; } - else + return 1; +} + + +bool +set_field_to_null_with_conversions(Field *field) +{ + if (field->real_maybe_null()) { - if (field->type() == FIELD_TYPE_TIMESTAMP) - { - ((Field_timestamp*) field)->set_time(); - return 0; // Ok to set time to NULL - } + field->set_null(); field->reset(); - if (field == field->table->next_number_field) - return 0; // field is set in handler.cc - if (current_thd->count_cuted_fields) - { - current_thd->cuted_fields++; // Increment error counter - return 0; - } - if (!current_thd->no_errors) - my_printf_error(ER_BAD_NULL_ERROR,ER(ER_BAD_NULL_ERROR),MYF(0), - field->field_name); - return 1; + return 0; + } + + /* + Check if this is a special type, which will get a special walue + when set to NULL + */ + if (field->type() == FIELD_TYPE_TIMESTAMP) + { + ((Field_timestamp*) field)->set_time(); + return 0; // Ok to set time to NULL + } + field->reset(); + if (field == field->table->next_number_field) + return 0; // field is set in handler.cc + if (current_thd->count_cuted_fields) + { + current_thd->cuted_fields++; // Increment error counter + return 0; } - return 0; + if (!current_thd->no_errors) + my_printf_error(ER_BAD_NULL_ERROR,ER(ER_BAD_NULL_ERROR),MYF(0), + field->field_name); + return 1; } + + static void do_skip(Copy_field *copy __attribute__((unused))) { } diff --git a/sql/item.cc b/sql/item.cc index 0ce37cdd593..9b4274ab71d 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -383,7 +383,7 @@ void Item_field::save_org_in_field(Field *to) if (field->is_null()) { null_value=1; - set_field_to_null(to); + set_field_to_null_with_conversions(to); } else { @@ -398,7 +398,7 @@ bool Item_field::save_in_field(Field *to) if (result_field->is_null()) { null_value=1; - return set_field_to_null(to); + return set_field_to_null_with_conversions(to); } else { @@ -409,9 +409,42 @@ bool Item_field::save_in_field(Field *to) return 0; } +/* + Store null in field + + SYNOPSIS + save_in_field() + field Field where we want to store NULL + + DESCRIPTION + This is used on INSERT. + Allow NULL to be inserted in timestamp and auto_increment values + + RETURN VALUES + 0 ok + 1 Field doesn't support NULL values and can't handle 'field = NULL' +*/ bool Item_null::save_in_field(Field *field) { + return set_field_to_null_with_conversions(field); +} + + +/* + Store null in field + + SYNOPSIS + save_safe_in_field() + field Field where we want to store NULL + + RETURN VALUES + 0 ok + 1 Field doesn't support NULL values +*/ + +bool Item_null::save_safe_in_field(Field *field) +{ return set_field_to_null(field); } @@ -427,7 +460,7 @@ bool Item::save_in_field(Field *field) str_value.set_quick(buff,sizeof(buff)); result=val_str(&str_value); if (null_value) - return set_field_to_null(field); + return set_field_to_null_with_conversions(field); field->set_notnull(); field->store(result->ptr(),result->length()); str_value.set_quick(0, 0); @@ -444,13 +477,14 @@ bool Item::save_in_field(Field *field) { longlong nr=val_int(); if (null_value) - return set_field_to_null(field); + return set_field_to_null_with_conversions(field); field->set_notnull(); field->store(nr); } return 0; } + bool Item_string::save_in_field(Field *field) { String *result; diff --git a/sql/item.h b/sql/item.h index b8903756027..408010d211a 100644 --- a/sql/item.h +++ b/sql/item.h @@ -55,6 +55,8 @@ public: virtual bool save_in_field(Field *field); virtual void save_org_in_field(Field *field) { (void) save_in_field(field); } + virtual bool save_safe_in_field(Field *field) + { return save_in_field(field); } virtual bool send(String *str); virtual bool eq(const Item *, bool binary_cmp) const; virtual Item_result result_type () const { return REAL_RESULT; } @@ -144,6 +146,7 @@ public: String *val_str(String *str); void make_field(Send_field *field); bool save_in_field(Field *field); + bool save_safe_in_field(Field *field); enum Item_result result_type () const { return STRING_RESULT; } bool send(String *str); |