diff options
Diffstat (limited to 'sql/field_conv.cc')
-rw-r--r-- | sql/field_conv.cc | 161 |
1 files changed, 85 insertions, 76 deletions
diff --git a/sql/field_conv.cc b/sql/field_conv.cc index 2705d4f617b..11d0bb9cc82 100644 --- a/sql/field_conv.cc +++ b/sql/field_conv.cc @@ -14,11 +14,15 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -/* - Functions to copy data to or from fields - This could be done with a single short function but opencoding this - gives much more speed. - */ +/** + @file + + @brief + Functions to copy data to or from fields + + This could be done with a single short function but opencoding this + gives much more speed. +*/ #include "mysql_priv.h" #include <m_ctype.h> @@ -118,33 +122,32 @@ set_field_to_null(Field *field) return 0; } field->reset(); - if (current_thd->count_cuted_fields == CHECK_FIELD_WARN) + if (field->table->in_use->count_cuted_fields == CHECK_FIELD_WARN) { field->set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, 1); return 0; } - if (!current_thd->no_errors) + if (!field->table->in_use->no_errors) my_error(ER_BAD_NULL_ERROR, MYF(0), field->field_name); return -1; } -/* - Set field to NULL or TIMESTAMP or to next auto_increment number - - SYNOPSIS - set_field_to_null_with_conversions() - field Field to update - no_conversion Set to 1 if we should return 1 if field can't - take null values. - If set to 0 we will do store the 'default value' - if the field is a special field. If not we will - give an error. - - RETURN VALUES - 0 Field could take 0 or an automatic conversion was used - -1 Field could not take NULL and no conversion was used. - If no_conversion was not set, an error message is printed +/** + Set field to NULL or TIMESTAMP or to next auto_increment number. + + @param field Field to update + @param no_conversions Set to 1 if we should return 1 if field can't + take null values. + If set to 0 we will do store the 'default value' + if the field is a special field. If not we will + give an error. + + @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 @@ -164,7 +167,7 @@ set_field_to_null_with_conversions(Field *field, bool no_conversions) when set to NULL (TIMESTAMP fields which allow setting to NULL are handled by first check). */ - if (field->type() == FIELD_TYPE_TIMESTAMP) + if (field->type() == MYSQL_TYPE_TIMESTAMP) { ((Field_timestamp*) field)->set_time(); return 0; // Ok to set time to NULL @@ -175,12 +178,12 @@ 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() } - if (current_thd->count_cuted_fields == CHECK_FIELD_WARN) + if (field->table->in_use->count_cuted_fields == CHECK_FIELD_WARN) { field->set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_BAD_NULL_ERROR, 1); return 0; } - if (!current_thd->no_errors) + if (!field->table->in_use->no_errors) my_error(ER_BAD_NULL_ERROR, MYF(0), field->field_name); return -1; } @@ -283,7 +286,7 @@ static void do_conv_blob(Copy_field *copy) copy->tmp.charset()); } -/* Save blob in copy->tmp for GROUP BY */ +/** Save blob in copy->tmp for GROUP BY. */ static void do_save_blob(Copy_field *copy) { @@ -352,9 +355,9 @@ static void do_field_decimal(Copy_field *copy) } -/* +/** string copy for single byte characters set when to string is shorter than - from string + from string. */ static void do_cut_string(Copy_field *copy) @@ -364,8 +367,8 @@ static void do_cut_string(Copy_field *copy) /* Check if we loosed any important characters */ if (cs->cset->scan(cs, - copy->from_ptr + copy->to_length, - copy->from_ptr + copy->from_length, + (char*) copy->from_ptr + copy->to_length, + (char*) copy->from_ptr + copy->from_length, MY_SEQ_SPACES) < copy->from_length - copy->to_length) { copy->to_field->set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, @@ -374,17 +377,19 @@ static void do_cut_string(Copy_field *copy) } -/* +/** string copy for multi byte characters set when to string is shorter than - from string + from string. */ static void do_cut_string_complex(Copy_field *copy) { // Shorter string field int well_formed_error; CHARSET_INFO *cs= copy->from_field->charset(); - const char *from_end= copy->from_ptr + copy->from_length; - uint copy_length= cs->cset->well_formed_len(cs, copy->from_ptr, from_end, + const uchar *from_end= copy->from_ptr + copy->from_length; + uint copy_length= cs->cset->well_formed_len(cs, + (char*) copy->from_ptr, + (char*) from_end, copy->to_length / cs->mbmaxlen, &well_formed_error); if (copy->to_length < copy_length) @@ -393,7 +398,8 @@ static void do_cut_string_complex(Copy_field *copy) /* Check if we lost any important characters */ if (well_formed_error || - cs->cset->scan(cs, copy->from_ptr + copy_length, from_end, + cs->cset->scan(cs, (char*) copy->from_ptr + copy_length, + (char*) from_end, MY_SEQ_SPACES) < (copy->from_length - copy_length)) { copy->to_field->set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, @@ -401,7 +407,7 @@ static void do_cut_string_complex(Copy_field *copy) } if (copy_length < copy->to_length) - cs->cset->fill(cs, copy->to_ptr + copy_length, + cs->cset->fill(cs, (char*) copy->to_ptr + copy_length, copy->to_length - copy_length, ' '); } @@ -412,7 +418,7 @@ static void do_expand_binary(Copy_field *copy) { CHARSET_INFO *cs= copy->from_field->charset(); memcpy(copy->to_ptr,copy->from_ptr,copy->from_length); - cs->cset->fill(cs, copy->to_ptr+copy->from_length, + cs->cset->fill(cs, (char*) copy->to_ptr+copy->from_length, copy->to_length-copy->from_length, '\0'); } @@ -422,7 +428,7 @@ static void do_expand_string(Copy_field *copy) { CHARSET_INFO *cs= copy->from_field->charset(); memcpy(copy->to_ptr,copy->from_ptr,copy->from_length); - cs->cset->fill(cs, copy->to_ptr+copy->from_length, + cs->cset->fill(cs, (char*) copy->to_ptr+copy->from_length, copy->to_length-copy->from_length, ' '); } @@ -433,7 +439,7 @@ static void do_varstring1(Copy_field *copy) if (length > copy->to_length- 1) { length=copy->to_length - 1; - if (current_thd->count_cuted_fields) + if (copy->from_field->table->in_use->count_cuted_fields) copy->to_field->set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, 1); } @@ -447,9 +453,10 @@ static void do_varstring1_mb(Copy_field *copy) int well_formed_error; CHARSET_INFO *cs= copy->from_field->charset(); uint from_length= (uint) *(uchar*) copy->from_ptr; - const char *from_ptr= copy->from_ptr + 1; + const uchar *from_ptr= copy->from_ptr + 1; uint to_char_length= (copy->to_length - 1) / cs->mbmaxlen; - uint length= cs->cset->well_formed_len(cs, from_ptr, from_ptr + from_length, + uint length= cs->cset->well_formed_len(cs, (char*) from_ptr, + (char*) from_ptr + from_length, to_char_length, &well_formed_error); if (length < from_length) { @@ -457,7 +464,7 @@ static void do_varstring1_mb(Copy_field *copy) copy->to_field->set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, 1); } - *(uchar*) copy->to_ptr= (uchar) length; + *copy->to_ptr= (uchar) length; memcpy(copy->to_ptr + 1, from_ptr, length); } @@ -468,7 +475,7 @@ static void do_varstring2(Copy_field *copy) if (length > copy->to_length- HA_KEY_BLOB_LENGTH) { length=copy->to_length-HA_KEY_BLOB_LENGTH; - if (current_thd->count_cuted_fields) + if (copy->from_field->table->in_use->count_cuted_fields) copy->to_field->set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, 1); } @@ -484,8 +491,9 @@ static void do_varstring2_mb(Copy_field *copy) CHARSET_INFO *cs= copy->from_field->charset(); uint char_length= (copy->to_length - HA_KEY_BLOB_LENGTH) / cs->mbmaxlen; uint from_length= uint2korr(copy->from_ptr); - const char *from_beg= copy->from_ptr + HA_KEY_BLOB_LENGTH; - uint length= cs->cset->well_formed_len(cs, from_beg, from_beg + from_length, + const uchar *from_beg= copy->from_ptr + HA_KEY_BLOB_LENGTH; + uint length= cs->cset->well_formed_len(cs, (char*) from_beg, + (char*) from_beg + from_length, char_length, &well_formed_error); if (length < from_length) { @@ -502,7 +510,7 @@ static void do_varstring2_mb(Copy_field *copy) ** The different functions that fills in a Copy_field class ***************************************************************************/ -/* +/** copy of field to maybe null string. If field is null then the all bytes are set to 0. if field is not null then the first byte is set to 1 and the rest of the @@ -510,7 +518,7 @@ static void do_varstring2_mb(Copy_field *copy) The 'to' buffer should have a size of field->pack_length()+1 */ -void Copy_field::set(char *to,Field *from) +void Copy_field::set(uchar *to,Field *from) { from_ptr=from->ptr; to_ptr=to; @@ -555,7 +563,7 @@ void Copy_field::set(char *to,Field *from) */ void Copy_field::set(Field *to,Field *from,bool save) { - if (to->type() == FIELD_TYPE_NULL) + if (to->type() == MYSQL_TYPE_NULL) { to_null_ptr=0; // For easy debugging to_ptr=0; @@ -589,7 +597,7 @@ void Copy_field::set(Field *to,Field *from,bool save) } else { - if (to_field->type() == FIELD_TYPE_TIMESTAMP) + if (to_field->type() == MYSQL_TYPE_TIMESTAMP) do_copy= do_copy_timestamp; // Automatic timestamp else if (to_field == to_field->table->next_number_field) do_copy= do_copy_next_number; @@ -615,7 +623,8 @@ void Copy_field::set(Field *to,Field *from,bool save) } -void (*Copy_field::get_copy_func(Field *to,Field *from))(Copy_field*) +Copy_field::Copy_func * +Copy_field::get_copy_func(Field *to,Field *from) { bool compatible_db_low_byte_first= (to->table->s->db_low_byte_first == from->table->s->db_low_byte_first); @@ -633,8 +642,8 @@ void (*Copy_field::get_copy_func(Field *to,Field *from))(Copy_field*) } else { - if (to->real_type() == FIELD_TYPE_BIT || - from->real_type() == FIELD_TYPE_BIT) + if (to->real_type() == MYSQL_TYPE_BIT || + from->real_type() == MYSQL_TYPE_BIT) return do_field_int; if (to->result_type() == DECIMAL_RESULT) return do_field_decimal; @@ -658,17 +667,17 @@ void (*Copy_field::get_copy_func(Field *to,Field *from))(Copy_field*) !compatible_db_low_byte_first || ((to->table->in_use->variables.sql_mode & (MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE | MODE_INVALID_DATES)) && - to->type() == FIELD_TYPE_DATE || - to->type() == FIELD_TYPE_DATETIME)) + to->type() == MYSQL_TYPE_DATE || + to->type() == MYSQL_TYPE_DATETIME)) { - if (from->real_type() == FIELD_TYPE_ENUM || - from->real_type() == FIELD_TYPE_SET) + if (from->real_type() == MYSQL_TYPE_ENUM || + from->real_type() == MYSQL_TYPE_SET) if (to->result_type() != STRING_RESULT) return do_field_int; // Convert SET to number return do_field_string; } - if (to->real_type() == FIELD_TYPE_ENUM || - to->real_type() == FIELD_TYPE_SET) + if (to->real_type() == MYSQL_TYPE_ENUM || + to->real_type() == MYSQL_TYPE_SET) { if (!to->eq_def(from)) { @@ -698,7 +707,7 @@ void (*Copy_field::get_copy_func(Field *to,Field *from))(Copy_field*) do_cut_string : do_cut_string_complex); else if (to_length > from_length) { - if ((to->flags & BINARY_FLAG) != 0) + if (to->charset() == &my_charset_bin) return do_expand_binary; else return do_expand_string; @@ -709,7 +718,7 @@ void (*Copy_field::get_copy_func(Field *to,Field *from))(Copy_field*) to_length != from_length || !compatible_db_low_byte_first) { - if (to->real_type() == FIELD_TYPE_DECIMAL || + if (to->real_type() == MYSQL_TYPE_DECIMAL || to->result_type() == STRING_RESULT) return do_field_string; if (to->result_type() == INT_RESULT) @@ -720,7 +729,7 @@ void (*Copy_field::get_copy_func(Field *to,Field *from))(Copy_field*) { if (!to->eq_def(from) || !compatible_db_low_byte_first) { - if (to->real_type() == FIELD_TYPE_DECIMAL) + if (to->real_type() == MYSQL_TYPE_DECIMAL) return do_field_string; if (to->result_type() == INT_RESULT) return do_field_int; @@ -742,27 +751,27 @@ void (*Copy_field::get_copy_func(Field *to,Field *from))(Copy_field*) } -/* Simple quick field convert that is called on insert */ +/** Simple quick field convert that is called on insert. */ int field_conv(Field *to,Field *from) { if (to->real_type() == from->real_type() && - !(to->type() == FIELD_TYPE_BLOB && to->table->copy_blobs)) + !(to->type() == MYSQL_TYPE_BLOB && to->table->copy_blobs)) { if (to->pack_length() == from->pack_length() && !(to->flags & UNSIGNED_FLAG && !(from->flags & UNSIGNED_FLAG)) && - to->real_type() != FIELD_TYPE_ENUM && - to->real_type() != FIELD_TYPE_SET && - to->real_type() != FIELD_TYPE_BIT && - (to->real_type() != FIELD_TYPE_NEWDECIMAL || + to->real_type() != MYSQL_TYPE_ENUM && + to->real_type() != MYSQL_TYPE_SET && + to->real_type() != MYSQL_TYPE_BIT && + (to->real_type() != MYSQL_TYPE_NEWDECIMAL || (to->field_length == from->field_length && (((Field_num*)to)->dec == ((Field_num*)from)->dec))) && from->charset() == to->charset() && to->table->s->db_low_byte_first == from->table->s->db_low_byte_first && (!(to->table->in_use->variables.sql_mode & (MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE | MODE_INVALID_DATES)) || - to->type() != FIELD_TYPE_DATE && - to->type() != FIELD_TYPE_DATETIME) && + to->type() != MYSQL_TYPE_DATE && + to->type() != MYSQL_TYPE_DATETIME) && (from->real_type() != MYSQL_TYPE_VARCHAR || ((Field_varstring*)from)->length_bytes == ((Field_varstring*)to)->length_bytes)) @@ -775,7 +784,7 @@ int field_conv(Field *to,Field *from) return 0; } } - if (to->type() == FIELD_TYPE_BLOB) + if (to->type() == MYSQL_TYPE_BLOB) { // Be sure the value is stored Field_blob *blob=(Field_blob*) to; from->val_str(&blob->value); @@ -790,8 +799,8 @@ int field_conv(Field *to,Field *from) blob->value.copy(); return blob->store(blob->value.ptr(),blob->value.length(),from->charset()); } - if (from->real_type() == FIELD_TYPE_ENUM && - to->real_type() == FIELD_TYPE_ENUM && + if (from->real_type() == MYSQL_TYPE_ENUM && + to->real_type() == MYSQL_TYPE_ENUM && from->val_int() == 0) { ((Field_enum *)(to))->store_type(0); @@ -799,9 +808,9 @@ int field_conv(Field *to,Field *from) } else if ((from->result_type() == STRING_RESULT && (to->result_type() == STRING_RESULT || - (from->real_type() != FIELD_TYPE_ENUM && - from->real_type() != FIELD_TYPE_SET))) || - to->type() == FIELD_TYPE_DECIMAL) + (from->real_type() != MYSQL_TYPE_ENUM && + from->real_type() != MYSQL_TYPE_SET))) || + to->type() == MYSQL_TYPE_DECIMAL) { char buff[MAX_FIELD_WIDTH]; String result(buff,sizeof(buff),from->charset()); |