Auto-merge

This commit is contained in:
Ramil Kalimullin 2009-02-26 14:11:46 +04:00
commit ce78a8bd50
2 changed files with 25 additions and 12 deletions

View File

@ -616,7 +616,8 @@ bool Protocol::send_fields(List<Item> *list, uint flags)
else else
{ {
/* With conversion */ /* With conversion */
uint max_char_len; ulonglong max_length;
uint32 field_length;
int2store(pos, thd_charset->number); int2store(pos, thd_charset->number);
/* /*
For TEXT/BLOB columns, field_length describes the maximum data For TEXT/BLOB columns, field_length describes the maximum data
@ -627,12 +628,21 @@ bool Protocol::send_fields(List<Item> *list, uint flags)
char_count * mbmaxlen, where character count is taken from the char_count * mbmaxlen, where character count is taken from the
definition of the column. In other words, the maximum number definition of the column. In other words, the maximum number
of characters here is limited by the column definition. of characters here is limited by the column definition.
When one has a LONG TEXT column with a single-byte
character set, and the connection character set is multi-byte, the
client may get fields longer than UINT_MAX32, due to
<character set column> -> <character set connection> conversion.
In that case column max length does not fit into the 4 bytes
reserved for it in the protocol.
*/ */
max_char_len= (field.type >= (int) MYSQL_TYPE_TINY_BLOB && max_length= (field.type >= MYSQL_TYPE_TINY_BLOB &&
field.type <= (int) MYSQL_TYPE_BLOB) ? field.type <= MYSQL_TYPE_BLOB) ?
field.length / item->collation.collation->mbminlen : field.length / item->collation.collation->mbminlen :
field.length / item->collation.collation->mbmaxlen; field.length / item->collation.collation->mbmaxlen;
int4store(pos+2, max_char_len * thd_charset->mbmaxlen); max_length*= thd_charset->mbmaxlen;
field_length= (max_length > UINT_MAX32) ? UINT_MAX32 : max_length;
int4store(pos + 2, field_length);
} }
pos[6]= field.type; pos[6]= field.type;
int2store(pos+7,field.flags); int2store(pos+7,field.flags);

View File

@ -714,6 +714,7 @@ static void do_verify_prepare_field(MYSQL_RES *result,
{ {
MYSQL_FIELD *field; MYSQL_FIELD *field;
CHARSET_INFO *cs; CHARSET_INFO *cs;
ulonglong expected_field_length;
if (!(field= mysql_fetch_field_direct(result, no))) if (!(field= mysql_fetch_field_direct(result, no)))
{ {
@ -722,6 +723,8 @@ static void do_verify_prepare_field(MYSQL_RES *result,
} }
cs= get_charset(field->charsetnr, 0); cs= get_charset(field->charsetnr, 0);
DIE_UNLESS(cs); DIE_UNLESS(cs);
if ((expected_field_length= length * cs->mbmaxlen) > UINT_MAX32)
expected_field_length= UINT_MAX32;
if (!opt_silent) if (!opt_silent)
{ {
fprintf(stdout, "\n field[%d]:", no); fprintf(stdout, "\n field[%d]:", no);
@ -736,8 +739,8 @@ static void do_verify_prepare_field(MYSQL_RES *result,
fprintf(stdout, "\n org_table:`%s`\t(expected: `%s`)", fprintf(stdout, "\n org_table:`%s`\t(expected: `%s`)",
field->org_table, org_table); field->org_table, org_table);
fprintf(stdout, "\n database :`%s`\t(expected: `%s`)", field->db, db); fprintf(stdout, "\n database :`%s`\t(expected: `%s`)", field->db, db);
fprintf(stdout, "\n length :`%lu`\t(expected: `%lu`)", fprintf(stdout, "\n length :`%lu`\t(expected: `%llu`)",
field->length, length * cs->mbmaxlen); field->length, expected_field_length);
fprintf(stdout, "\n maxlength:`%ld`", field->max_length); fprintf(stdout, "\n maxlength:`%ld`", field->max_length);
fprintf(stdout, "\n charsetnr:`%d`", field->charsetnr); fprintf(stdout, "\n charsetnr:`%d`", field->charsetnr);
fprintf(stdout, "\n default :`%s`\t(expected: `%s`)", fprintf(stdout, "\n default :`%s`\t(expected: `%s`)",
@ -773,11 +776,11 @@ static void do_verify_prepare_field(MYSQL_RES *result,
as utf8. Field length is calculated as number of characters * maximum as utf8. Field length is calculated as number of characters * maximum
number of bytes a character can occupy. number of bytes a character can occupy.
*/ */
if (length && field->length != length * cs->mbmaxlen) if (length && (field->length != expected_field_length))
{ {
fprintf(stderr, "Expected field length: %d, got length: %d\n", fprintf(stderr, "Expected field length: %llu, got length: %lu\n",
(int) (length * cs->mbmaxlen), (int) field->length); expected_field_length, field->length);
DIE_UNLESS(field->length == length * cs->mbmaxlen); DIE_UNLESS(field->length == expected_field_length);
} }
if (def) if (def)
DIE_UNLESS(strcmp(field->def, def) == 0); DIE_UNLESS(strcmp(field->def, def) == 0);