MDEV-7769 MY_CHARSET_INFO refactoring# On branch 10.2

Part 3 (final): removing MY_CHARSET_HANDLER::well_formed_len().
This commit is contained in:
Alexander Barkov 2016-10-10 14:36:09 +04:00
parent a6f032af57
commit 5058ced5df
34 changed files with 130 additions and 342 deletions

View File

@ -397,7 +397,6 @@ typedef struct
*/ */
typedef struct typedef struct
{ {
MY_STRCOPY_STATUS m_native_copy_status;
const char *m_cannot_convert_error_pos; const char *m_cannot_convert_error_pos;
} MY_STRCONV_STATUS; } MY_STRCONV_STATUS;
@ -410,9 +409,6 @@ struct my_charset_handler_st
size_t (*numchars)(CHARSET_INFO *, const char *b, const char *e); size_t (*numchars)(CHARSET_INFO *, const char *b, const char *e);
size_t (*charpos)(CHARSET_INFO *, const char *b, const char *e, size_t (*charpos)(CHARSET_INFO *, const char *b, const char *e,
size_t pos); size_t pos);
size_t (*well_formed_len)(CHARSET_INFO *,
const char *b,const char *e,
size_t nchars, int *error);
size_t (*lengthsp)(CHARSET_INFO *, const char *ptr, size_t length); size_t (*lengthsp)(CHARSET_INFO *, const char *ptr, size_t length);
size_t (*numcells)(CHARSET_INFO *, const char *b, const char *e); size_t (*numcells)(CHARSET_INFO *, const char *b, const char *e);
@ -817,8 +813,6 @@ int my_wildcmp_bin(CHARSET_INFO *,
size_t my_numchars_8bit(CHARSET_INFO *, const char *b, const char *e); size_t my_numchars_8bit(CHARSET_INFO *, const char *b, const char *e);
size_t my_numcells_8bit(CHARSET_INFO *, const char *b, const char *e); size_t my_numcells_8bit(CHARSET_INFO *, const char *b, const char *e);
size_t my_charpos_8bit(CHARSET_INFO *, const char *b, const char *e, size_t pos); size_t my_charpos_8bit(CHARSET_INFO *, const char *b, const char *e, size_t pos);
size_t my_well_formed_len_8bit(CHARSET_INFO *, const char *b, const char *e,
size_t pos, int *error);
size_t my_well_formed_char_length_8bit(CHARSET_INFO *cs, size_t my_well_formed_char_length_8bit(CHARSET_INFO *cs,
const char *b, const char *e, const char *b, const char *e,
size_t nchars, size_t nchars,
@ -850,8 +844,6 @@ int my_wildcmp_mb(CHARSET_INFO *,
size_t my_numchars_mb(CHARSET_INFO *, const char *b, const char *e); size_t my_numchars_mb(CHARSET_INFO *, const char *b, const char *e);
size_t my_numcells_mb(CHARSET_INFO *, const char *b, const char *e); size_t my_numcells_mb(CHARSET_INFO *, const char *b, const char *e);
size_t my_charpos_mb(CHARSET_INFO *, const char *b, const char *e, size_t pos); size_t my_charpos_mb(CHARSET_INFO *, const char *b, const char *e, size_t pos);
size_t my_well_formed_len_mb(CHARSET_INFO *, const char *b, const char *e,
size_t pos, int *error);
uint my_instr_mb(CHARSET_INFO *, uint my_instr_mb(CHARSET_INFO *,
const char *b, size_t b_length, const char *b, size_t b_length,
const char *s, size_t s_length, const char *s, size_t s_length,
@ -994,7 +986,9 @@ uint32 my_convert_using_func(char *to, uint32 to_length, CHARSET_INFO *to_cs,
*/ */
size_t my_convert_fix(CHARSET_INFO *dstcs, char *dst, size_t dst_length, size_t my_convert_fix(CHARSET_INFO *dstcs, char *dst, size_t dst_length,
CHARSET_INFO *srccs, const char *src, size_t src_length, CHARSET_INFO *srccs, const char *src, size_t src_length,
size_t nchars, MY_STRCONV_STATUS *status); size_t nchars,
MY_STRCOPY_STATUS *copy_status,
MY_STRCONV_STATUS *conv_status);
#define _MY_U 01 /* Upper case */ #define _MY_U 01 /* Upper case */
#define _MY_L 02 /* Lower case */ #define _MY_L 02 /* Lower case */
@ -1089,6 +1083,22 @@ uint my_charlen_fix(CHARSET_INFO *cs, const char *str, const char *end)
} }
/*
A compatibility replacement pure C function for the former
cs->cset->well_formed_len().
In C++ code please use Well_formed_prefix::length() instead.
*/
static inline size_t
my_well_formed_length(CHARSET_INFO *cs, const char *b, const char *e,
size_t nchars, int *error)
{
MY_STRCOPY_STATUS status;
(void) cs->cset->well_formed_char_length(cs, b, e, nchars, &status);
*error= status.m_well_formed_error_pos == NULL ? 0 : 1;
return status.m_source_end_pos - b;
}
#define my_caseup_str(s, a) ((s)->cset->caseup_str((s), (a))) #define my_caseup_str(s, a) ((s)->cset->caseup_str((s), (a)))
#define my_casedn_str(s, a) ((s)->cset->casedn_str((s), (a))) #define my_casedn_str(s, a) ((s)->cset->casedn_str((s), (a)))
#define my_strntol(s, a, b, c, d, e) ((s)->cset->strntol((s),(a),(b),(c),(d),(e))) #define my_strntol(s, a, b, c, d, e) ((s)->cset->strntol((s),(a),(b),(c),(d),(e)))

View File

@ -7902,12 +7902,9 @@ int Field_blob::copy_value(Field_blob *from)
from->get_ptr(&data); from->get_ptr(&data);
if (packlength < from->packlength) if (packlength < from->packlength)
{ {
int well_formed_errors;
set_if_smaller(length, Field_blob::max_data_length()); set_if_smaller(length, Field_blob::max_data_length());
length= field_charset->cset->well_formed_len(field_charset, length= (uint32) Well_formed_prefix(field_charset,
(const char *) data, (const char *) data, length).length();
(const char *) data + length,
length, &well_formed_errors);
rc= report_if_important_data((const char *) data + length, rc= report_if_important_data((const char *) data + length,
(const char *) data + from->get_length(), (const char *) data + from->get_length(),
true); true);
@ -7943,9 +7940,8 @@ int Field_blob::store(const char *from,uint length,CHARSET_INFO *cs)
copy_length= table->in_use->variables.group_concat_max_len; copy_length= table->in_use->variables.group_concat_max_len;
if (new_length > copy_length) if (new_length > copy_length)
{ {
int well_formed_error; new_length= Well_formed_prefix(cs,
new_length= cs->cset->well_formed_len(cs, from, from + copy_length, from, copy_length, new_length).length();
new_length, &well_formed_error);
table->blob_storage->set_truncated_value(true); table->blob_storage->set_truncated_value(true);
} }
if (!(tmp= table->blob_storage->store(from, new_length))) if (!(tmp= table->blob_storage->store(from, new_length)))

View File

@ -467,20 +467,19 @@ static void do_cut_string(Copy_field *copy)
static void do_cut_string_complex(Copy_field *copy) static void do_cut_string_complex(Copy_field *copy)
{ // Shorter string field { // Shorter string field
int well_formed_error;
CHARSET_INFO *cs= copy->from_field->charset(); CHARSET_INFO *cs= copy->from_field->charset();
const uchar *from_end= copy->from_ptr + copy->from_length; const uchar *from_end= copy->from_ptr + copy->from_length;
uint copy_length= cs->cset->well_formed_len(cs, Well_formed_prefix prefix(cs,
(char*) copy->from_ptr, (char*) copy->from_ptr,
(char*) from_end, (char*) from_end,
copy->to_length / cs->mbmaxlen, copy->to_length / cs->mbmaxlen);
&well_formed_error); uint copy_length= prefix.length();
if (copy->to_length < copy_length) if (copy->to_length < copy_length)
copy_length= copy->to_length; copy_length= copy->to_length;
memcpy(copy->to_ptr, copy->from_ptr, copy_length); memcpy(copy->to_ptr, copy->from_ptr, copy_length);
/* Check if we lost any important characters */ /* Check if we lost any important characters */
if (well_formed_error || if (prefix.well_formed_error_pos() ||
cs->cset->scan(cs, (char*) copy->from_ptr + copy_length, cs->cset->scan(cs, (char*) copy->from_ptr + copy_length,
(char*) from_end, (char*) from_end,
MY_SEQ_SPACES) < (copy->from_length - copy_length)) MY_SEQ_SPACES) < (copy->from_length - copy_length))
@ -534,22 +533,19 @@ static void do_varstring1(Copy_field *copy)
static void do_varstring1_mb(Copy_field *copy) static void do_varstring1_mb(Copy_field *copy)
{ {
int well_formed_error;
CHARSET_INFO *cs= copy->from_field->charset(); CHARSET_INFO *cs= copy->from_field->charset();
uint from_length= (uint) *(uchar*) copy->from_ptr; uint from_length= (uint) *(uchar*) copy->from_ptr;
const uchar *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 to_char_length= (copy->to_length - 1) / cs->mbmaxlen;
uint length= cs->cset->well_formed_len(cs, (char*) from_ptr, Well_formed_prefix prefix(cs, (char*) from_ptr, from_length, to_char_length);
(char*) from_ptr + from_length, if (prefix.length() < from_length)
to_char_length, &well_formed_error);
if (length < from_length)
{ {
if (current_thd->count_cuted_fields) if (current_thd->count_cuted_fields)
copy->to_field->set_warning(Sql_condition::WARN_LEVEL_WARN, copy->to_field->set_warning(Sql_condition::WARN_LEVEL_WARN,
WARN_DATA_TRUNCATED, 1); WARN_DATA_TRUNCATED, 1);
} }
*copy->to_ptr= (uchar) length; *copy->to_ptr= (uchar) prefix.length();
memcpy(copy->to_ptr + 1, from_ptr, length); memcpy(copy->to_ptr + 1, from_ptr, prefix.length());
} }
@ -572,22 +568,19 @@ static void do_varstring2(Copy_field *copy)
static void do_varstring2_mb(Copy_field *copy) static void do_varstring2_mb(Copy_field *copy)
{ {
int well_formed_error;
CHARSET_INFO *cs= copy->from_field->charset(); CHARSET_INFO *cs= copy->from_field->charset();
uint char_length= (copy->to_length - HA_KEY_BLOB_LENGTH) / cs->mbmaxlen; uint char_length= (copy->to_length - HA_KEY_BLOB_LENGTH) / cs->mbmaxlen;
uint from_length= uint2korr(copy->from_ptr); uint from_length= uint2korr(copy->from_ptr);
const uchar *from_beg= copy->from_ptr + HA_KEY_BLOB_LENGTH; const uchar *from_beg= copy->from_ptr + HA_KEY_BLOB_LENGTH;
uint length= cs->cset->well_formed_len(cs, (char*) from_beg, Well_formed_prefix prefix(cs, (char*) from_beg, from_length, char_length);
(char*) from_beg + from_length, if (prefix.length() < from_length)
char_length, &well_formed_error);
if (length < from_length)
{ {
if (current_thd->count_cuted_fields) if (current_thd->count_cuted_fields)
copy->to_field->set_warning(Sql_condition::WARN_LEVEL_WARN, copy->to_field->set_warning(Sql_condition::WARN_LEVEL_WARN,
WARN_DATA_TRUNCATED, 1); WARN_DATA_TRUNCATED, 1);
} }
int2store(copy->to_ptr, length); int2store(copy->to_ptr, prefix.length());
memcpy(copy->to_ptr+HA_KEY_BLOB_LENGTH, from_beg, length); memcpy(copy->to_ptr+HA_KEY_BLOB_LENGTH, from_beg, prefix.length());
} }

View File

@ -3156,21 +3156,18 @@ int dump_leaf_key(void* key_arg, element_count count __attribute__((unused)),
/* stop if length of result more than max_length */ /* stop if length of result more than max_length */
if (result->length() > max_length) if (result->length() > max_length)
{ {
int well_formed_error;
CHARSET_INFO *cs= item->collation.collation; CHARSET_INFO *cs= item->collation.collation;
const char *ptr= result->ptr(); const char *ptr= result->ptr();
uint add_length;
THD *thd= current_thd; THD *thd= current_thd;
/* /*
It's ok to use item->result.length() as the fourth argument It's ok to use item->result.length() as the fourth argument
as this is never used to limit the length of the data. as this is never used to limit the length of the data.
Cut is done with the third argument. Cut is done with the third argument.
*/ */
add_length= cs->cset->well_formed_len(cs, uint add_length= Well_formed_prefix(cs,
ptr + old_length, ptr + old_length,
ptr + max_length, ptr + max_length,
result->length(), result->length()).length();
&well_formed_error);
result->length(old_length + add_length); result->length(old_length + add_length);
item->warning_for_row= TRUE; item->warning_for_row= TRUE;
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,

View File

@ -2468,13 +2468,9 @@ String *Item_char_typecast::val_str(String *str)
if (!charset_conversion) if (!charset_conversion)
{ {
// Try to reuse the original string (if well formed). // Try to reuse the original string (if well formed).
MY_STRCOPY_STATUS status; Well_formed_prefix prefix(cs, res->ptr(), res->end(), cast_length);
cs->cset->well_formed_char_length(cs, res->ptr(), res->end(), if (!prefix.well_formed_error_pos())
cast_length, &status); res= reuse(res, prefix.length());
if (!status.m_well_formed_error_pos)
{
res= reuse(res, status.m_source_end_pos - res->ptr());
}
goto end; goto end;
} }
// Character set conversion, or bad bytes were found. // Character set conversion, or bad bytes were found.

View File

@ -12030,14 +12030,9 @@ static ulong parse_client_handshake_packet(MPVIO_EXT *mpvio,
mostly for backward compatibility (to truncate long usernames, as mostly for backward compatibility (to truncate long usernames, as
old 5.1 did) old 5.1 did)
*/ */
{ user_len= Well_formed_prefix(system_charset_info, user, user_len,
CHARSET_INFO *cs= system_charset_info; username_char_length).length();
int err;
user_len= (uint) cs->cset->well_formed_len(cs, user, user + user_len,
username_char_length, &err);
user[user_len]= '\0'; user[user_len]= '\0';
}
Security_context *sctx= thd->security_ctx; Security_context *sctx= thd->security_ctx;

View File

@ -9614,11 +9614,8 @@ bool check_string_char_length(LEX_STRING *str, uint err_msg,
uint max_char_length, CHARSET_INFO *cs, uint max_char_length, CHARSET_INFO *cs,
bool no_error) bool no_error)
{ {
int well_formed_error; Well_formed_prefix prefix(cs, str->str, str->length, max_char_length);
uint res= cs->cset->well_formed_len(cs, str->str, str->str + str->length, if (!prefix.well_formed_error_pos() && str->length == prefix.length())
max_char_length, &well_formed_error);
if (!well_formed_error && str->length == res)
return FALSE; return FALSE;
if (!no_error) if (!no_error)

View File

@ -1018,10 +1018,10 @@ String_copier::well_formed_copy(CHARSET_INFO *to_cs,
{ {
m_cannot_convert_error_pos= NULL; m_cannot_convert_error_pos= NULL;
return to_cs->cset->copy_fix(to_cs, to, to_length, from, from_length, return to_cs->cset->copy_fix(to_cs, to, to_length, from, from_length,
nchars, &m_native_copy_status); nchars, this);
} }
return my_convert_fix(to_cs, to, to_length, from_cs, from, from_length, return my_convert_fix(to_cs, to, to_length, from_cs, from, from_length,
nchars, this); nchars, this, this);
} }

View File

@ -44,13 +44,48 @@ inline uint32 copy_and_convert(char *to, uint32 to_length,
} }
class String_copier: private MY_STRCONV_STATUS class String_copy_status: protected MY_STRCOPY_STATUS
{ {
public: public:
const char *source_end_pos() const const char *source_end_pos() const
{ return m_native_copy_status.m_source_end_pos; } { return m_source_end_pos; }
const char *well_formed_error_pos() const const char *well_formed_error_pos() const
{ return m_native_copy_status.m_well_formed_error_pos; } { return m_well_formed_error_pos; }
};
class Well_formed_prefix_status: public String_copy_status
{
public:
Well_formed_prefix_status(CHARSET_INFO *cs,
const char *str, const char *end, size_t nchars)
{ cs->cset->well_formed_char_length(cs, str, end, nchars, this); }
};
class Well_formed_prefix: public Well_formed_prefix_status
{
const char *m_str; // The beginning of the string
public:
Well_formed_prefix(CHARSET_INFO *cs, const char *str, const char *end,
size_t nchars)
:Well_formed_prefix_status(cs, str, end, nchars), m_str(str)
{ }
Well_formed_prefix(CHARSET_INFO *cs, const char *str, size_t length,
size_t nchars)
:Well_formed_prefix_status(cs, str, str + length, nchars), m_str(str)
{ }
Well_formed_prefix(CHARSET_INFO *cs, const char *str, size_t length)
:Well_formed_prefix_status(cs, str, str + length, length), m_str(str)
{ }
size_t length() const { return m_source_end_pos - m_str; }
};
class String_copier: public String_copy_status,
protected MY_STRCONV_STATUS
{
public:
const char *cannot_convert_error_pos() const const char *cannot_convert_error_pos() const
{ return m_cannot_convert_error_pos; } { return m_cannot_convert_error_pos; }
const char *most_important_error_pos() const const char *most_important_error_pos() const
@ -67,7 +102,7 @@ public:
uint nchars) uint nchars)
{ {
return my_convert_fix(dstcs, dst, dst_length, return my_convert_fix(dstcs, dst, dst_length,
srccs, src, src_length, nchars, this); srccs, src, src_length, nchars, this, this);
} }
/* /*
Copy a string. Fix bad bytes/characters to '?'. Copy a string. Fix bad bytes/characters to '?'.
@ -606,9 +641,7 @@ public:
} }
uint well_formed_length() const uint well_formed_length() const
{ {
int dummy_error; return (uint) Well_formed_prefix(charset(), ptr(), length()).length();
return charset()->cset->well_formed_len(charset(), ptr(), ptr() + length(),
length(), &dummy_error);
} }
bool is_ascii() const bool is_ascii() const
{ {

View File

@ -14371,10 +14371,7 @@ IDENT_sys:
if (thd->charset_is_system_charset) if (thd->charset_is_system_charset)
{ {
CHARSET_INFO *cs= system_charset_info; CHARSET_INFO *cs= system_charset_info;
int dummy_error; uint wlen= Well_formed_prefix(cs, $1.str, $1.length).length();
uint wlen= cs->cset->well_formed_len(cs, $1.str,
$1.str+$1.length,
$1.length, &dummy_error);
if (wlen < $1.length) if (wlen < $1.length)
{ {
ErrConvString err($1.str, $1.length, &my_charset_bin); ErrConvString err($1.str, $1.length, &my_charset_bin);

View File

@ -2172,7 +2172,7 @@ ib_col_set_value(
if (len > 0 && cs->mbmaxlen > 1) { if (len > 0 && cs->mbmaxlen > 1) {
true_len = (ulint) true_len = (ulint)
cs->cset->well_formed_len( my_well_formed_length(
cs, cs,
(const char*)src, (const char*)src,
(const char*)src + len, (const char*)src + len,

View File

@ -2404,7 +2404,7 @@ innobase_check_identifier_length(
CHARSET_INFO *cs = system_charset_info; CHARSET_INFO *cs = system_charset_info;
DBUG_ENTER("innobase_check_identifier_length"); DBUG_ENTER("innobase_check_identifier_length");
size_t len = cs->cset->well_formed_len( size_t len = my_well_formed_length(
cs, id, id + strlen(id), cs, id, id + strlen(id),
NAME_CHAR_LEN, &well_formed_error); NAME_CHAR_LEN, &well_formed_error);
@ -7962,7 +7962,7 @@ wsrep_store_key_val_for_row(
the true length of the key */ the true length of the key */
if (len > 0 && cs->mbmaxlen > 1) { if (len > 0 && cs->mbmaxlen > 1) {
true_len = (ulint) cs->cset->well_formed_len(cs, true_len = (ulint) my_well_formed_length(cs,
(const char *) data, (const char *) data,
(const char *) data + len, (const char *) data + len,
(uint) (key_len / (uint) (key_len /
@ -8048,7 +8048,7 @@ wsrep_store_key_val_for_row(
the true length of the key */ the true length of the key */
if (blob_len > 0 && cs->mbmaxlen > 1) { if (blob_len > 0 && cs->mbmaxlen > 1) {
true_len = (ulint) cs->cset->well_formed_len(cs, true_len = (ulint) my_well_formed_length(cs,
(const char *) blob_data, (const char *) blob_data,
(const char *) blob_data (const char *) blob_data
+ blob_len, + blob_len,
@ -8137,7 +8137,7 @@ wsrep_store_key_val_for_row(
if (key_len > 0 && cs->mbmaxlen > 1) { if (key_len > 0 && cs->mbmaxlen > 1) {
true_len = (ulint) true_len = (ulint)
cs->cset->well_formed_len(cs, my_well_formed_length(cs,
(const char *)src_start, (const char *)src_start,
(const char *)src_start (const char *)src_start
+ key_len, + key_len,

View File

@ -253,12 +253,9 @@ void table_events_statements_common::make_row_part_1(PFS_events_statements *stat
{ {
if (cs->mbmaxlen > 1) if (cs->mbmaxlen > 1)
{ {
int well_formed_error; valid_length= Well_formed_prefix(cs,
valid_length= cs->cset->well_formed_len(cs,
statement->m_sqltext, statement->m_sqltext,
statement->m_sqltext + valid_length, valid_length).length();
valid_length,
&well_formed_error);
} }
} }

View File

@ -2334,7 +2334,7 @@ ib_col_set_value(
if (len > 0 && cs->mbmaxlen > 1) { if (len > 0 && cs->mbmaxlen > 1) {
true_len = (ulint) true_len = (ulint)
cs->cset->well_formed_len( my_well_formed_length(
cs, cs,
(const char*)src, (const char*)src,
(const char*)src + len, (const char*)src + len,

View File

@ -2424,7 +2424,7 @@ innobase_check_identifier_length(
CHARSET_INFO *cs = system_charset_info; CHARSET_INFO *cs = system_charset_info;
DBUG_ENTER("innobase_check_identifier_length"); DBUG_ENTER("innobase_check_identifier_length");
size_t len = cs->cset->well_formed_len( size_t len = my_well_formed_length(
cs, id, id + strlen(id), cs, id, id + strlen(id),
NAME_CHAR_LEN, &well_formed_error); NAME_CHAR_LEN, &well_formed_error);
@ -7434,7 +7434,7 @@ wsrep_store_key_val_for_row(
the true length of the key */ the true length of the key */
if (len > 0 && cs->mbmaxlen > 1) { if (len > 0 && cs->mbmaxlen > 1) {
true_len = (ulint) cs->cset->well_formed_len(cs, true_len = (ulint) my_well_formed_length(cs,
(const char *) data, (const char *) data,
(const char *) data + len, (const char *) data + len,
(uint) (key_len / (uint) (key_len /
@ -7521,7 +7521,7 @@ wsrep_store_key_val_for_row(
the true length of the key */ the true length of the key */
if (blob_len > 0 && cs->mbmaxlen > 1) { if (blob_len > 0 && cs->mbmaxlen > 1) {
true_len = (ulint) cs->cset->well_formed_len(cs, true_len = (ulint) my_well_formed_length(cs,
(const char *) blob_data, (const char *) blob_data,
(const char *) blob_data (const char *) blob_data
+ blob_len, + blob_len,
@ -7610,7 +7610,7 @@ wsrep_store_key_val_for_row(
if (key_len > 0 && cs->mbmaxlen > 1) { if (key_len > 0 && cs->mbmaxlen > 1) {
true_len = (ulint) true_len = (ulint)
cs->cset->well_formed_len(cs, my_well_formed_length(cs,
(const char *)src_start, (const char *)src_start,
(const char *)src_start (const char *)src_start
+ key_len, + key_len,
@ -7745,7 +7745,7 @@ ha_innobase::store_key_val_for_row(
the true length of the key */ the true length of the key */
if (len > 0 && cs->mbmaxlen > 1) { if (len > 0 && cs->mbmaxlen > 1) {
true_len = (ulint) cs->cset->well_formed_len(cs, true_len = (ulint) my_well_formed_length(cs,
(const char*) data, (const char*) data,
(const char*) data + len, (const char*) data + len,
(uint) (key_len / cs->mbmaxlen), (uint) (key_len / cs->mbmaxlen),
@ -7816,7 +7816,7 @@ ha_innobase::store_key_val_for_row(
the true length of the key */ the true length of the key */
if (blob_len > 0 && cs->mbmaxlen > 1) { if (blob_len > 0 && cs->mbmaxlen > 1) {
true_len = (ulint) cs->cset->well_formed_len(cs, true_len = (ulint) my_well_formed_length(cs,
(const char*) blob_data, (const char*) blob_data,
(const char*) blob_data (const char*) blob_data
+ blob_len, + blob_len,
@ -7888,7 +7888,7 @@ ha_innobase::store_key_val_for_row(
if (key_len > 0 && cs->mbmaxlen > 1) { if (key_len > 0 && cs->mbmaxlen > 1) {
true_len = (ulint) true_len = (ulint)
cs->cset->well_formed_len(cs, my_well_formed_length(cs,
(const char*) src_start, (const char*) src_start,
(const char*) src_start (const char*) src_start
+ key_len, + key_len,

View File

@ -6775,7 +6775,6 @@ static MY_CHARSET_HANDLER my_charset_big5_handler=
NULL, /* init */ NULL, /* init */
my_numchars_mb, my_numchars_mb,
my_charpos_mb, my_charpos_mb,
my_well_formed_len_big5,
my_lengthsp_8bit, my_lengthsp_8bit,
my_numcells_8bit, my_numcells_8bit,
my_mb_wc_big5, /* mb_wc */ my_mb_wc_big5, /* mb_wc */

View File

@ -535,7 +535,6 @@ static MY_CHARSET_HANDLER my_charset_handler=
NULL, /* init */ NULL, /* init */
my_numchars_8bit, my_numchars_8bit,
my_charpos_8bit, my_charpos_8bit,
my_well_formed_len_8bit,
my_lengthsp_binary, my_lengthsp_binary,
my_numcells_8bit, my_numcells_8bit,
my_mb_wc_bin, my_mb_wc_bin,

View File

@ -34731,7 +34731,6 @@ static MY_CHARSET_HANDLER my_charset_handler=
NULL, /* init */ NULL, /* init */
my_numchars_mb, my_numchars_mb,
my_charpos_mb, my_charpos_mb,
my_well_formed_len_cp932,
my_lengthsp_8bit, my_lengthsp_8bit,
my_numcells_cp932, my_numcells_cp932,
my_mb_wc_cp932, /* mb_wc */ my_mb_wc_cp932, /* mb_wc */

View File

@ -10021,7 +10021,6 @@ static MY_CHARSET_HANDLER my_charset_handler=
NULL, /* init */ NULL, /* init */
my_numchars_mb, my_numchars_mb,
my_charpos_mb, my_charpos_mb,
my_well_formed_len_euckr,
my_lengthsp_8bit, my_lengthsp_8bit,
my_numcells_8bit, my_numcells_8bit,
my_mb_wc_euc_kr, /* mb_wc */ my_mb_wc_euc_kr, /* mb_wc */

View File

@ -67559,7 +67559,6 @@ static MY_CHARSET_HANDLER my_charset_handler=
NULL, /* init */ NULL, /* init */
my_numchars_mb, my_numchars_mb,
my_charpos_mb, my_charpos_mb,
my_well_formed_len_eucjpms,
my_lengthsp_8bit, my_lengthsp_8bit,
my_numcells_eucjpms, my_numcells_eucjpms,
my_mb_wc_eucjpms, /* mb_wc */ my_mb_wc_eucjpms, /* mb_wc */

View File

@ -6426,7 +6426,6 @@ static MY_CHARSET_HANDLER my_charset_handler=
NULL, /* init */ NULL, /* init */
my_numchars_mb, my_numchars_mb,
my_charpos_mb, my_charpos_mb,
my_well_formed_len_gb2312,
my_lengthsp_8bit, my_lengthsp_8bit,
my_numcells_8bit, my_numcells_8bit,
my_mb_wc_gb2312, /* mb_wc */ my_mb_wc_gb2312, /* mb_wc */

View File

@ -10708,7 +10708,6 @@ static MY_CHARSET_HANDLER my_charset_handler=
NULL, /* init */ NULL, /* init */
my_numchars_mb, my_numchars_mb,
my_charpos_mb, my_charpos_mb,
my_well_formed_len_gbk,
my_lengthsp_8bit, my_lengthsp_8bit,
my_numcells_8bit, my_numcells_8bit,
my_mb_wc_gbk, my_mb_wc_gbk,

View File

@ -398,7 +398,6 @@ static MY_CHARSET_HANDLER my_charset_handler=
NULL, /* init */ NULL, /* init */
my_numchars_8bit, my_numchars_8bit,
my_charpos_8bit, my_charpos_8bit,
my_well_formed_len_8bit,
my_lengthsp_8bit, my_lengthsp_8bit,
my_numcells_8bit, my_numcells_8bit,
my_mb_wc_latin1, my_mb_wc_latin1,

View File

@ -401,28 +401,6 @@ size_t my_charpos_mb(CHARSET_INFO *cs __attribute__((unused)),
} }
size_t my_well_formed_len_mb(CHARSET_INFO *cs, const char *b, const char *e,
size_t pos, int *error)
{
const char *b_start= b;
*error= 0;
while (pos)
{
my_wc_t wc;
int mb_len;
if ((mb_len= cs->cset->mb_wc(cs, &wc, (uchar*) b, (uchar*) e)) <= 0)
{
*error= b < e ? 1 : 0;
break;
}
b+= mb_len;
pos--;
}
return (size_t) (b - b_start);
}
/* /*
Append a badly formed piece of string. Append a badly formed piece of string.
Bad bytes are fixed to '?'. Bad bytes are fixed to '?'.

View File

@ -30,7 +30,6 @@
#ifdef DEFINE_ASIAN_ROUTINES #ifdef DEFINE_ASIAN_ROUTINES
#define DEFINE_WELL_FORMED_LEN
#define DEFINE_WELL_FORMED_CHAR_LENGTH #define DEFINE_WELL_FORMED_CHAR_LENGTH
#define DEFINE_CHARLEN #define DEFINE_CHARLEN
#define DEFINE_NATIVE_TO_MB_VARLEN #define DEFINE_NATIVE_TO_MB_VARLEN
@ -96,73 +95,7 @@ MY_FUNCTION_NAME(charlen)(CHARSET_INFO *cs __attribute__((unused)),
/* Wrong byte sequence */ /* Wrong byte sequence */
return MY_CS_ILSEQ; return MY_CS_ILSEQ;
} }
#endif /* DEFINE_WELL_FORMED_LEN */ #endif /* DEFINE_CHARLEN */
#ifdef DEFINE_WELL_FORMED_LEN
/**
Returns well formed length of a character string with
variable character length for character sets with:
- mbminlen == 1
- mbmaxlen == 2, 3, or 4
*/
static size_t
MY_FUNCTION_NAME(well_formed_len)(CHARSET_INFO *cs __attribute__((unused)),
const char *b, const char *e,
size_t nchars, int *error)
{
const char *b0= b;
DBUG_ASSERT(cs->mbminlen == 1);
DBUG_ASSERT(cs->mbmaxlen <= 4);
for (*error= 0 ; b < e && nchars-- ; )
{
if ((uchar) b[0] < 128)
{
b++; /* Single byte ASCII character */
continue;
}
if (b + 2 <= e && IS_MB2_CHAR(b[0], b[1]))
{
b+= 2; /* Double byte character */
continue;
}
#ifdef IS_MB3_CHAR
if (b + 3 <= e && IS_MB3_CHAR(b[0], b[1], b[2]))
{
b+= 3; /* Three-byte character */
continue;
}
#endif
#ifdef IS_MB4_CHAR
if (b + 4 <= e && IS_MB4_CHAR(b[0], b[1], b[2], b[3]))
{
b+= 4; /* Four-byte character */
continue;
}
#endif
#ifdef IS_8BIT_CHAR
if (IS_8BIT_CHAR(b[0]))
{
b++; /* Single byte non-ASCII character, e.g. half width kana in sjis */
continue;
}
#endif
/* Wrong byte sequence */
*error= 1;
break;
}
return b - b0;
}
#endif /* DEFINE_WELL_FORMED_LEN */
#ifdef DEFINE_WELL_FORMED_CHAR_LENGTH #ifdef DEFINE_WELL_FORMED_CHAR_LENGTH

View File

@ -1143,16 +1143,6 @@ size_t my_charpos_8bit(CHARSET_INFO *cs __attribute__((unused)),
} }
size_t my_well_formed_len_8bit(CHARSET_INFO *cs __attribute__((unused)),
const char *start, const char *end,
size_t nchars, int *error)
{
size_t nbytes= (size_t) (end-start);
*error= 0;
return MY_MIN(nbytes, nchars);
}
size_t size_t
my_well_formed_char_length_8bit(CHARSET_INFO *cs __attribute__((unused)), my_well_formed_char_length_8bit(CHARSET_INFO *cs __attribute__((unused)),
const char *start, const char *end, const char *start, const char *end,
@ -2064,7 +2054,6 @@ MY_CHARSET_HANDLER my_charset_8bit_handler=
my_cset_init_8bit, my_cset_init_8bit,
my_numchars_8bit, my_numchars_8bit,
my_charpos_8bit, my_charpos_8bit,
my_well_formed_len_8bit,
my_lengthsp_8bit, my_lengthsp_8bit,
my_numcells_8bit, my_numcells_8bit,
my_mb_wc_8bit, my_mb_wc_8bit,

View File

@ -34110,7 +34110,6 @@ static MY_CHARSET_HANDLER my_charset_handler=
NULL, /* init */ NULL, /* init */
my_numchars_mb, my_numchars_mb,
my_charpos_mb, my_charpos_mb,
my_well_formed_len_sjis,
my_lengthsp_8bit, my_lengthsp_8bit,
my_numcells_sjis, my_numcells_sjis,
my_mb_wc_sjis, /* mb_wc */ my_mb_wc_sjis, /* mb_wc */

View File

@ -880,7 +880,6 @@ static MY_CHARSET_HANDLER my_charset_handler=
NULL, /* init */ NULL, /* init */
my_numchars_8bit, my_numchars_8bit,
my_charpos_8bit, my_charpos_8bit,
my_well_formed_len_8bit,
my_lengthsp_8bit, my_lengthsp_8bit,
my_numcells_8bit, my_numcells_8bit,
my_mb_wc_tis620, /* mb_wc */ my_mb_wc_tis620, /* mb_wc */

View File

@ -1490,27 +1490,6 @@ my_charpos_utf16(CHARSET_INFO *cs,
} }
static size_t
my_well_formed_len_utf16(CHARSET_INFO *cs,
const char *b, const char *e,
size_t nchars, int *error)
{
const char *b0= b;
uint charlen;
*error= 0;
for ( ; nchars; b+= charlen, nchars--)
{
if (!(charlen= my_ismbchar(cs, b, e)))
{
*error= b < e ? 1 : 0;
break;
}
}
return (size_t) (b - b0);
}
static int static int
my_wildcmp_utf16_ci(CHARSET_INFO *cs, my_wildcmp_utf16_ci(CHARSET_INFO *cs,
const char *str,const char *str_end, const char *str,const char *str_end,
@ -1629,7 +1608,6 @@ MY_CHARSET_HANDLER my_charset_utf16_handler=
NULL, /* init */ NULL, /* init */
my_numchars_utf16, my_numchars_utf16,
my_charpos_utf16, my_charpos_utf16,
my_well_formed_len_utf16,
my_lengthsp_mb2, my_lengthsp_mb2,
my_numcells_mb, my_numcells_mb,
my_utf16_uni, /* mb_wc */ my_utf16_uni, /* mb_wc */
@ -1963,7 +1941,6 @@ static MY_CHARSET_HANDLER my_charset_utf16le_handler=
NULL, /* init */ NULL, /* init */
my_numchars_utf16, my_numchars_utf16,
my_charpos_utf16, my_charpos_utf16,
my_well_formed_len_utf16,
my_lengthsp_utf16le, my_lengthsp_utf16le,
my_numcells_mb, my_numcells_mb,
my_utf16le_uni, /* mb_wc */ my_utf16le_uni, /* mb_wc */
@ -2636,34 +2613,6 @@ my_charpos_utf32(CHARSET_INFO *cs __attribute__((unused)),
} }
static size_t
my_well_formed_len_utf32(CHARSET_INFO *cs __attribute__((unused)),
const char *b, const char *e,
size_t nchars, int *error)
{
/* Ensure string length is divisible by 4 */
const char *b0= b;
size_t length= e - b;
DBUG_ASSERT((length % 4) == 0);
*error= 0;
nchars*= 4;
if (length > nchars)
{
length= nchars;
e= b + nchars;
}
for (; b < e; b+= 4)
{
if (!IS_UTF32_MBHEAD4(b[0], b[1]))
{
*error= 1;
return b - b0;
}
}
return length;
}
static static
void my_fill_utf32(CHARSET_INFO *cs, void my_fill_utf32(CHARSET_INFO *cs,
char *s, size_t slen, int fill) char *s, size_t slen, int fill)
@ -2809,7 +2758,6 @@ MY_CHARSET_HANDLER my_charset_utf32_handler=
NULL, /* init */ NULL, /* init */
my_numchars_utf32, my_numchars_utf32,
my_charpos_utf32, my_charpos_utf32,
my_well_formed_len_utf32,
my_lengthsp_utf32, my_lengthsp_utf32,
my_numcells_mb, my_numcells_mb,
my_utf32_uni, my_utf32_uni,
@ -3248,19 +3196,6 @@ size_t my_charpos_ucs2(CHARSET_INFO *cs __attribute__((unused)),
} }
static
size_t my_well_formed_len_ucs2(CHARSET_INFO *cs __attribute__((unused)),
const char *b, const char *e,
size_t nchars, int *error)
{
/* Ensure string length is dividable with 2 */
size_t nbytes= ((size_t) (e-b)) & ~(size_t) 1;
*error= 0;
nchars*= 2;
return MY_MIN(nbytes, nchars);
}
static size_t static size_t
my_well_formed_char_length_ucs2(CHARSET_INFO *cs __attribute__((unused)), my_well_formed_char_length_ucs2(CHARSET_INFO *cs __attribute__((unused)),
const char *b, const char *e, const char *b, const char *e,
@ -3403,7 +3338,6 @@ MY_CHARSET_HANDLER my_charset_ucs2_handler=
NULL, /* init */ NULL, /* init */
my_numchars_ucs2, my_numchars_ucs2,
my_charpos_ucs2, my_charpos_ucs2,
my_well_formed_len_ucs2,
my_lengthsp_mb2, my_lengthsp_mb2,
my_numcells_mb, my_numcells_mb,
my_ucs2_uni, /* mb_wc */ my_ucs2_uni, /* mb_wc */

View File

@ -67303,7 +67303,6 @@ static MY_CHARSET_HANDLER my_charset_handler=
NULL, /* init */ NULL, /* init */
my_numchars_mb, my_numchars_mb,
my_charpos_mb, my_charpos_mb,
my_well_formed_len_ujis,
my_lengthsp_8bit, my_lengthsp_8bit,
my_numcells_eucjp, my_numcells_eucjp,
my_mb_wc_euc_jp, /* mb_wc */ my_mb_wc_euc_jp, /* mb_wc */

View File

@ -5421,27 +5421,6 @@ int my_charlen_utf8(CHARSET_INFO *cs __attribute__((unused)),
return MY_CS_ILSEQ; return MY_CS_ILSEQ;
} }
static size_t
my_well_formed_len_utf8(CHARSET_INFO *cs, const char *b, const char *e,
size_t pos, int *error)
{
const char *b_start= b;
*error= 0;
while (pos)
{
int mb_len;
if ((mb_len= my_charlen_utf8(cs, (uchar*) b, (uchar*) e)) <= 0)
{
*error= b < e ? 1 : 0;
break;
}
b+= mb_len;
pos--;
}
return (size_t) (b - b_start);
}
#define MY_FUNCTION_NAME(x) my_ ## x ## _utf8 #define MY_FUNCTION_NAME(x) my_ ## x ## _utf8
#define CHARLEN(cs,str,end) my_charlen_utf8(cs,str,end) #define CHARLEN(cs,str,end) my_charlen_utf8(cs,str,end)
@ -5656,7 +5635,6 @@ MY_CHARSET_HANDLER my_charset_utf8_handler=
NULL, /* init */ NULL, /* init */
my_numchars_mb, my_numchars_mb,
my_charpos_mb, my_charpos_mb,
my_well_formed_len_utf8,
my_lengthsp_8bit, my_lengthsp_8bit,
my_numcells_mb, my_numcells_mb,
my_utf8_uni, my_utf8_uni,
@ -7276,7 +7254,6 @@ static MY_CHARSET_HANDLER my_charset_filename_handler=
NULL, /* init */ NULL, /* init */
my_numchars_mb, my_numchars_mb,
my_charpos_mb, my_charpos_mb,
my_well_formed_len_mb,
my_lengthsp_8bit, my_lengthsp_8bit,
my_numcells_mb, my_numcells_mb,
my_mb_wc_filename, my_mb_wc_filename,
@ -7885,29 +7862,6 @@ my_charlen_utf8mb4(CHARSET_INFO *cs __attribute__((unused)),
} }
static
size_t my_well_formed_len_utf8mb4(CHARSET_INFO *cs,
const char *b, const char *e,
size_t pos, int *error)
{
const char *b_start= b;
*error= 0;
while (pos)
{
int mb_len;
if ((mb_len= my_charlen_utf8mb4(cs, (uchar*) b, (uchar*) e)) <= 0)
{
*error= b < e ? 1 : 0;
break;
}
b+= mb_len;
pos--;
}
return (size_t) (b - b_start);
}
#define MY_FUNCTION_NAME(x) my_ ## x ## _utf8mb4 #define MY_FUNCTION_NAME(x) my_ ## x ## _utf8mb4
#define CHARLEN(cs,str,end) my_charlen_utf8mb4(cs,str,end) #define CHARLEN(cs,str,end) my_charlen_utf8mb4(cs,str,end)
#define DEFINE_WELL_FORMED_CHAR_LENGTH_USING_CHARLEN #define DEFINE_WELL_FORMED_CHAR_LENGTH_USING_CHARLEN
@ -8033,7 +7987,6 @@ MY_CHARSET_HANDLER my_charset_utf8mb4_handler=
NULL, /* init */ NULL, /* init */
my_numchars_mb, my_numchars_mb,
my_charpos_mb, my_charpos_mb,
my_well_formed_len_utf8mb4,
my_lengthsp_8bit, my_lengthsp_8bit,
my_numcells_mb, my_numcells_mb,
my_mb_wc_utf8mb4, my_mb_wc_utf8mb4,

View File

@ -1138,7 +1138,9 @@ my_convert(char *to, uint32 to_length, CHARSET_INFO *to_cs,
size_t size_t
my_convert_fix(CHARSET_INFO *to_cs, char *to, size_t to_length, my_convert_fix(CHARSET_INFO *to_cs, char *to, size_t to_length,
CHARSET_INFO *from_cs, const char *from, size_t from_length, CHARSET_INFO *from_cs, const char *from, size_t from_length,
size_t nchars, MY_STRCONV_STATUS *status) size_t nchars,
MY_STRCOPY_STATUS *copy_status,
MY_STRCONV_STATUS *conv_status)
{ {
int cnvres; int cnvres;
my_wc_t wc; my_wc_t wc;
@ -1151,8 +1153,8 @@ my_convert_fix(CHARSET_INFO *to_cs, char *to, size_t to_length,
DBUG_ASSERT(to_cs != &my_charset_bin); DBUG_ASSERT(to_cs != &my_charset_bin);
DBUG_ASSERT(from_cs != &my_charset_bin); DBUG_ASSERT(from_cs != &my_charset_bin);
status->m_native_copy_status.m_well_formed_error_pos= NULL; copy_status->m_well_formed_error_pos= NULL;
status->m_cannot_convert_error_pos= NULL; conv_status->m_cannot_convert_error_pos= NULL;
for ( ; nchars; nchars--) for ( ; nchars; nchars--)
{ {
@ -1161,8 +1163,8 @@ my_convert_fix(CHARSET_INFO *to_cs, char *to, size_t to_length,
from+= cnvres; from+= cnvres;
else if (cnvres == MY_CS_ILSEQ) else if (cnvres == MY_CS_ILSEQ)
{ {
if (!status->m_native_copy_status.m_well_formed_error_pos) if (!copy_status->m_well_formed_error_pos)
status->m_native_copy_status.m_well_formed_error_pos= from; copy_status->m_well_formed_error_pos= from;
from++; from++;
wc= '?'; wc= '?';
} }
@ -1172,8 +1174,8 @@ my_convert_fix(CHARSET_INFO *to_cs, char *to, size_t to_length,
A correct multibyte sequence detected A correct multibyte sequence detected
But it doesn't have Unicode mapping. But it doesn't have Unicode mapping.
*/ */
if (!status->m_cannot_convert_error_pos) if (!conv_status->m_cannot_convert_error_pos)
status->m_cannot_convert_error_pos= from; conv_status->m_cannot_convert_error_pos= from;
from+= (-cnvres); from+= (-cnvres);
wc= '?'; wc= '?';
} }
@ -1182,8 +1184,8 @@ my_convert_fix(CHARSET_INFO *to_cs, char *to, size_t to_length,
if ((uchar *) from >= from_end) if ((uchar *) from >= from_end)
break; // End of line break; // End of line
// Incomplete byte sequence // Incomplete byte sequence
if (!status->m_native_copy_status.m_well_formed_error_pos) if (!copy_status->m_well_formed_error_pos)
status->m_native_copy_status.m_well_formed_error_pos= from; copy_status->m_well_formed_error_pos= from;
from++; from++;
wc= '?'; wc= '?';
} }
@ -1192,8 +1194,8 @@ outp:
to+= cnvres; to+= cnvres;
else if (cnvres == MY_CS_ILUNI && wc != '?') else if (cnvres == MY_CS_ILUNI && wc != '?')
{ {
if (!status->m_cannot_convert_error_pos) if (!conv_status->m_cannot_convert_error_pos)
status->m_cannot_convert_error_pos= from_prev; conv_status->m_cannot_convert_error_pos= from_prev;
wc= '?'; wc= '?';
goto outp; goto outp;
} }
@ -1203,6 +1205,6 @@ outp:
break; break;
} }
} }
status->m_native_copy_status.m_source_end_pos= from; copy_status->m_source_end_pos= from;
return to - to_start; return to - to_start;
} }

View File

@ -205,8 +205,7 @@ static char *process_str_arg(CHARSET_INFO *cs, char *to, const char *end,
plen= strnlen(par, width); plen= strnlen(par, width);
if (left_len <= plen) if (left_len <= plen)
plen = left_len - 1; plen = left_len - 1;
plen= cs->cset->well_formed_len(cs, par, par + plen, plen= my_well_formed_length(cs, par, par + plen, width, &well_formed_error);
width, &well_formed_error);
if (print_type & ESCAPED_ARG) if (print_type & ESCAPED_ARG)
to= backtick_string(cs, to, end, par, plen, '`'); to= backtick_string(cs, to, end, par, plen, '`');
else else

View File

@ -31,10 +31,10 @@ test_like_range_for_charset(CHARSET_INFO *cs, const char *src, size_t src_len)
cs->coll->like_range(cs, src, src_len, '\\', '_', '%', cs->coll->like_range(cs, src, src_len, '\\', '_', '%',
sizeof(min_str), min_str, max_str, &min_len, &max_len); sizeof(min_str), min_str, max_str, &min_len, &max_len);
diag("min_len=%d\tmax_len=%d\t%s", (int) min_len, (int) max_len, cs->name); diag("min_len=%d\tmax_len=%d\t%s", (int) min_len, (int) max_len, cs->name);
min_well_formed_len= cs->cset->well_formed_len(cs, min_well_formed_len= my_well_formed_length(cs,
min_str, min_str + min_len, min_str, min_str + min_len,
10000, &error); 10000, &error);
max_well_formed_len= cs->cset->well_formed_len(cs, max_well_formed_len= my_well_formed_length(cs,
max_str, max_str + max_len, max_str, max_str + max_len,
10000, &error); 10000, &error);
if (min_len != min_well_formed_len) if (min_len != min_well_formed_len)