Bug #53088: mysqldump with -T & --default-character-set set
truncates text/blob to 766 chars mysqldump and SELECT ... INTO OUTFILE truncated long BLOB/TEXT values to size of 766 bytes (MAX_FIELD_WIDTH or 255 * 3 + 1). The select_export::send_data method has been modified to reallocate a conversion buffer for long field data. mysql-test/r/mysqldump.result: Test case for bug #53088. mysql-test/r/outfile_loaddata.result: Test case for bug #53088. mysql-test/t/mysqldump.test: Test case for bug #53088. mysql-test/t/outfile_loaddata.test: Test case for bug #53088. sql/sql_class.cc: Bug #53088: mysqldump with -T & --default-character-set set truncates text/blob to 766 chars The select_export::send_data method has been modified to reallocate a conversion buffer for long field data.
This commit is contained in:
parent
addd0a3e67
commit
bd2a517b23
@ -4561,5 +4561,20 @@ a b c
|
||||
SET NAMES default;
|
||||
DROP TABLE t1, t2;
|
||||
#
|
||||
# Bug #53088: mysqldump with -T & --default-character-set set
|
||||
# truncates text/blob to 766 chars
|
||||
#
|
||||
# Also see outfile_loaddata.test
|
||||
#
|
||||
CREATE TABLE t1 (a BLOB) CHARSET latin1;
|
||||
CREATE TABLE t2 LIKE t1;
|
||||
INSERT INTO t1 VALUES (REPEAT('.', 800));
|
||||
LOAD DATA INFILE 'MYSQLTEST_VARDIR/tmp/t1.txt' INTO TABLE t2 CHARACTER SET latin1;
|
||||
# should be 800
|
||||
SELECT LENGTH(a) FROM t2;
|
||||
LENGTH(a)
|
||||
800
|
||||
DROP TABLE t1, t2;
|
||||
#
|
||||
# End of 5.1 tests
|
||||
#
|
||||
|
@ -239,4 +239,24 @@ a b c
|
||||
2 NULL NULL
|
||||
SET NAMES default;
|
||||
DROP TABLE t1, t2;
|
||||
#
|
||||
# Bug #53088: mysqldump with -T & --default-character-set set
|
||||
# truncates text/blob to 766 chars
|
||||
#
|
||||
# Also see mysqldump.test
|
||||
#
|
||||
CREATE TABLE t1 (a BLOB) CHARSET latin1;
|
||||
CREATE TABLE t2 LIKE t1;
|
||||
INSERT INTO t1 VALUES (REPEAT('.', 800));
|
||||
SELECT * INTO OUTFILE 'MYSQLTEST_VARDIR/tmp/bug53088.txt' CHARACTER SET latin1 FROM t1;
|
||||
# should be greater than 800
|
||||
SELECT LENGTH(LOAD_FILE('MYSQLTEST_VARDIR/tmp/bug53088.txt'));
|
||||
LENGTH(LOAD_FILE('MYSQLTEST_VARDIR/tmp/bug53088.txt'))
|
||||
801
|
||||
LOAD DATA INFILE 'MYSQLTEST_VARDIR/tmp/bug53088.txt' INTO TABLE t2;
|
||||
# should be 800
|
||||
SELECT LENGTH(a) FROM t2;
|
||||
LENGTH(a)
|
||||
800
|
||||
DROP TABLE t1, t2;
|
||||
# End of 5.1 tests.
|
||||
|
@ -2131,6 +2131,35 @@ SELECT * FROM t1 UNION SELECT * FROM t2 ORDER BY a, b, c;
|
||||
|
||||
SET NAMES default;
|
||||
|
||||
DROP TABLE t1, t2;
|
||||
###########################################################################
|
||||
|
||||
--echo #
|
||||
--echo # Bug #53088: mysqldump with -T & --default-character-set set
|
||||
--echo # truncates text/blob to 766 chars
|
||||
--echo #
|
||||
--echo # Also see outfile_loaddata.test
|
||||
--echo #
|
||||
|
||||
CREATE TABLE t1 (a BLOB) CHARSET latin1;
|
||||
CREATE TABLE t2 LIKE t1;
|
||||
|
||||
let $table= t1;
|
||||
let $dir= $MYSQLTEST_VARDIR/tmp;
|
||||
let $file= $dir/$table.txt;
|
||||
let $length= 800;
|
||||
|
||||
--eval INSERT INTO t1 VALUES (REPEAT('.', $length))
|
||||
|
||||
--exec $MYSQL_DUMP --character-sets-dir=$CHARSETSDIR --default-character-set=latin1 --tab=$dir/ test $table
|
||||
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
|
||||
|
||||
--eval LOAD DATA INFILE '$file' INTO TABLE t2 CHARACTER SET latin1
|
||||
--remove_file $file
|
||||
|
||||
--echo # should be $length
|
||||
SELECT LENGTH(a) FROM t2;
|
||||
|
||||
DROP TABLE t1, t2;
|
||||
|
||||
###########################################################################
|
||||
|
@ -251,6 +251,40 @@ SELECT * FROM t1 UNION SELECT * FROM t2 ORDER BY a, b, c;
|
||||
SET NAMES default;
|
||||
|
||||
DROP TABLE t1, t2;
|
||||
###########################################################################
|
||||
|
||||
--echo #
|
||||
--echo # Bug #53088: mysqldump with -T & --default-character-set set
|
||||
--echo # truncates text/blob to 766 chars
|
||||
--echo #
|
||||
--echo # Also see mysqldump.test
|
||||
--echo #
|
||||
|
||||
CREATE TABLE t1 (a BLOB) CHARSET latin1;
|
||||
CREATE TABLE t2 LIKE t1;
|
||||
|
||||
let $file= '$MYSQLTEST_VARDIR/tmp/bug53088.txt';
|
||||
let $length= 800;
|
||||
|
||||
--eval INSERT INTO t1 VALUES (REPEAT('.', $length))
|
||||
|
||||
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
|
||||
--eval SELECT * INTO OUTFILE $file CHARACTER SET latin1 FROM t1
|
||||
|
||||
--echo # should be greater than $length
|
||||
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
|
||||
--eval SELECT LENGTH(LOAD_FILE($file))
|
||||
|
||||
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
|
||||
--eval LOAD DATA INFILE $file INTO TABLE t2
|
||||
|
||||
--remove_file $MYSQLTEST_VARDIR/tmp/bug53088.txt
|
||||
|
||||
--echo # should be $length
|
||||
SELECT LENGTH(a) FROM t2;
|
||||
|
||||
DROP TABLE t1, t2;
|
||||
|
||||
|
||||
###########################################################################
|
||||
--echo # End of 5.1 tests.
|
||||
|
@ -1998,9 +1998,21 @@ bool select_export::send_data(List<Item> &items)
|
||||
const char *from_end_pos;
|
||||
const char *error_pos;
|
||||
uint32 bytes;
|
||||
bytes= well_formed_copy_nchars(write_cs, cvt_buff, sizeof(cvt_buff),
|
||||
uint64 estimated_bytes=
|
||||
((uint64) res->length() / res->charset()->mbminlen + 1) *
|
||||
write_cs->mbmaxlen + 1;
|
||||
set_if_smaller(estimated_bytes, UINT_MAX32);
|
||||
if (cvt_str.realloc((uint32) estimated_bytes))
|
||||
{
|
||||
my_error(ER_OUTOFMEMORY, MYF(0), (uint32) estimated_bytes);
|
||||
goto err;
|
||||
}
|
||||
|
||||
bytes= well_formed_copy_nchars(write_cs, (char *) cvt_str.ptr(),
|
||||
cvt_str.alloced_length(),
|
||||
res->charset(), res->ptr(), res->length(),
|
||||
sizeof(cvt_buff),
|
||||
UINT_MAX32, // copy all input chars,
|
||||
// i.e. ignore nchars parameter
|
||||
&well_formed_error_pos,
|
||||
&cannot_convert_error_pos,
|
||||
&from_end_pos);
|
||||
@ -2018,6 +2030,15 @@ bool select_export::send_data(List<Item> &items)
|
||||
"string", printable_buff,
|
||||
item->name, row_count);
|
||||
}
|
||||
else if (from_end_pos < res->ptr() + res->length())
|
||||
{
|
||||
/*
|
||||
result is longer than UINT_MAX32 and doesn't fit into String
|
||||
*/
|
||||
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
WARN_DATA_TRUNCATED, ER(WARN_DATA_TRUNCATED),
|
||||
item->full_name(), row_count);
|
||||
}
|
||||
cvt_str.length(bytes);
|
||||
res= &cvt_str;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user