mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
A fix and a test case for Bug#15613 "libmysqlclient API function
mysql_stmt_prepare returns wrong field length" sql/protocol.cc: A fix for Bug#15613: make sure that result set column length is evaluated correctly for BLOB/TEXT columns. tests/mysql_client_test.c: A test case for Bug#15613
This commit is contained in:
@ -565,9 +565,23 @@ bool Protocol::send_fields(List<Item> *list, uint flag)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* With conversion */
|
/* With conversion */
|
||||||
|
uint max_char_len;
|
||||||
int2store(pos, thd_charset->number);
|
int2store(pos, thd_charset->number);
|
||||||
uint char_len= field.length / item->collation.collation->mbmaxlen;
|
/*
|
||||||
int4store(pos+2, char_len * thd_charset->mbmaxlen);
|
For TEXT/BLOB columns, field_length describes the maximum data
|
||||||
|
length in bytes. There is no limit to the number of characters
|
||||||
|
that a TEXT column can store, as long as the data fits into
|
||||||
|
the designated space.
|
||||||
|
For the rest of textual columns, field_length is evaluated as
|
||||||
|
char_count * mbmaxlen, where character count is taken from the
|
||||||
|
definition of the column. In other words, the maximum number
|
||||||
|
of characters here is limited by the column definition.
|
||||||
|
*/
|
||||||
|
max_char_len= (field.type >= (int) MYSQL_TYPE_TINY_BLOB &&
|
||||||
|
field.type <= (int) MYSQL_TYPE_BLOB) ?
|
||||||
|
field.length / item->collation.collation->mbminlen :
|
||||||
|
field.length / item->collation.collation->mbmaxlen;
|
||||||
|
int4store(pos+2, max_char_len * thd_charset->mbmaxlen);
|
||||||
}
|
}
|
||||||
pos[6]= field.type;
|
pos[6]= field.type;
|
||||||
int2store(pos+7,field.flags);
|
int2store(pos+7,field.flags);
|
||||||
|
@ -11772,6 +11772,70 @@ static void test_bug16144()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Bug #15613: "libmysqlclient API function mysql_stmt_prepare returns wrong
|
||||||
|
field length"
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void test_bug15613()
|
||||||
|
{
|
||||||
|
MYSQL_STMT *stmt;
|
||||||
|
const char *stmt_text;
|
||||||
|
MYSQL_RES *metadata;
|
||||||
|
MYSQL_FIELD *field;
|
||||||
|
int rc;
|
||||||
|
myheader("test_bug15613");
|
||||||
|
|
||||||
|
/* I. Prepare the table */
|
||||||
|
rc= mysql_query(mysql, "set names latin1");
|
||||||
|
myquery(rc);
|
||||||
|
mysql_query(mysql, "drop table if exists t1");
|
||||||
|
rc= mysql_query(mysql,
|
||||||
|
"create table t1 (t text character set utf8, "
|
||||||
|
"tt tinytext character set utf8, "
|
||||||
|
"mt mediumtext character set utf8, "
|
||||||
|
"lt longtext character set utf8, "
|
||||||
|
"vl varchar(255) character set latin1,"
|
||||||
|
"vb varchar(255) character set binary,"
|
||||||
|
"vu varchar(255) character set utf8)");
|
||||||
|
myquery(rc);
|
||||||
|
|
||||||
|
stmt= mysql_stmt_init(mysql);
|
||||||
|
|
||||||
|
/* II. Check SELECT metadata */
|
||||||
|
stmt_text= ("select t, tt, mt, lt, vl, vb, vu from t1");
|
||||||
|
rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
|
||||||
|
metadata= mysql_stmt_result_metadata(stmt);
|
||||||
|
field= mysql_fetch_fields(metadata);
|
||||||
|
if (!opt_silent)
|
||||||
|
{
|
||||||
|
printf("Field lengths (client character set is latin1):\n"
|
||||||
|
"text character set utf8:\t\t%lu\n"
|
||||||
|
"tinytext character set utf8:\t\t%lu\n"
|
||||||
|
"mediumtext character set utf8:\t\t%lu\n"
|
||||||
|
"longtext character set utf8:\t\t%lu\n"
|
||||||
|
"varchar(255) character set latin1:\t%lu\n"
|
||||||
|
"varchar(255) character set binary:\t%lu\n"
|
||||||
|
"varchar(255) character set utf8:\t%lu\n",
|
||||||
|
field[0].length, field[1].length, field[2].length, field[3].length,
|
||||||
|
field[4].length, field[5].length, field[6].length);
|
||||||
|
}
|
||||||
|
DIE_UNLESS(field[0].length == 65535);
|
||||||
|
DIE_UNLESS(field[1].length == 255);
|
||||||
|
DIE_UNLESS(field[2].length == 16777215);
|
||||||
|
DIE_UNLESS(field[3].length == 4294967295UL);
|
||||||
|
DIE_UNLESS(field[4].length == 255);
|
||||||
|
DIE_UNLESS(field[5].length == 255);
|
||||||
|
DIE_UNLESS(field[6].length == 255);
|
||||||
|
|
||||||
|
/* III. Cleanup */
|
||||||
|
rc= mysql_query(mysql, "drop table t1");
|
||||||
|
myquery(rc);
|
||||||
|
rc= mysql_query(mysql, "set names default");
|
||||||
|
myquery(rc);
|
||||||
|
mysql_stmt_close(stmt);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Read and parse arguments and MySQL options from my.cnf
|
Read and parse arguments and MySQL options from my.cnf
|
||||||
*/
|
*/
|
||||||
@ -11994,6 +12058,7 @@ static struct my_tests_st my_tests[]= {
|
|||||||
{ "test_bug11718", test_bug11718 },
|
{ "test_bug11718", test_bug11718 },
|
||||||
{ "test_bug12925", test_bug12925 },
|
{ "test_bug12925", test_bug12925 },
|
||||||
{ "test_bug16144", test_bug16144 },
|
{ "test_bug16144", test_bug16144 },
|
||||||
|
{ "test_bug15613", test_bug15613 },
|
||||||
{ 0, 0 }
|
{ 0, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user