Commit 0a91f285 authored by unknown's avatar unknown

Fixed bug #32533.

8bit escape characters, termination and enclosed characters
were silently ignored by SELECT INTO query, but LOAD DATA INFILE
algorithm is 8bit-clean, so data was corrupted during 
encoding.


sql/sql_class.cc:
  Fixed bug #32533.
  SELECT INTO OUTFILE encoding was not 8bit clear, it
  has been fixed for a symmetry with the LOAD DATA INFILE
  decoding algorithm.
mysql-test/t/outfile_loaddata.test:
  Added test case for bug #32533.
mysql-test/r/outfile_loaddata.result:
  Added test case for bug #32533.
parent 4b48eb6f
...@@ -82,4 +82,22 @@ c1 c2 ...@@ -82,4 +82,22 @@ c1 c2
-r- =raker= -r- =raker=
DROP TABLE t2; DROP TABLE t2;
DROP TABLE t1; DROP TABLE t1;
#
# Bug#32533: SELECT INTO OUTFILE never escapes multibyte character
#
CREATE TABLE t1 (c1 VARCHAR(256));
INSERT INTO t1 VALUES (0xC3);
SELECT HEX(c1) FROM t1;
HEX(c1)
C3
SELECT * INTO OUTFILE 'MYSQLTEST_VARDIR/tmp/bug32533.txt' FIELDS ENCLOSED BY 0xC3 FROM t1;
TRUNCATE t1;
SELECT HEX(LOAD_FILE('MYSQLTEST_VARDIR/tmp/bug32533.txt'));
HEX(LOAD_FILE('MYSQLTEST_VARDIR/tmp/bug32533.txt'))
C35CC3C30A
LOAD DATA INFILE 'MYSQLTEST_VARDIR/tmp/bug32533.txt' INTO TABLE t1 FIELDS ENCLOSED BY 0xC3;
SELECT HEX(c1) FROM t1;
HEX(c1)
C3
DROP TABLE t1;
# End of 5.0 tests. # End of 5.0 tests.
...@@ -86,4 +86,28 @@ DROP TABLE t2; ...@@ -86,4 +86,28 @@ DROP TABLE t2;
DROP TABLE t1; DROP TABLE t1;
--echo #
--echo # Bug#32533: SELECT INTO OUTFILE never escapes multibyte character
--echo #
CREATE TABLE t1 (c1 VARCHAR(256));
INSERT INTO t1 VALUES (0xC3);
SELECT HEX(c1) FROM t1;
--let $file=$MYSQLTEST_VARDIR/tmp/bug32533.txt
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
--eval SELECT * INTO OUTFILE '$file' FIELDS ENCLOSED BY 0xC3 FROM t1
TRUNCATE t1;
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
--eval SELECT HEX(LOAD_FILE('$file'))
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
--eval LOAD DATA INFILE '$file' INTO TABLE t1 FIELDS ENCLOSED BY 0xC3
SELECT HEX(c1) FROM t1;
--remove_file $file
DROP TABLE t1;
--echo # End of 5.0 tests. --echo # End of 5.0 tests.
...@@ -1219,16 +1219,18 @@ select_export::prepare(List<Item> &list, SELECT_LEX_UNIT *u) ...@@ -1219,16 +1219,18 @@ select_export::prepare(List<Item> &list, SELECT_LEX_UNIT *u)
} }
} }
field_term_length=exchange->field_term->length(); field_term_length=exchange->field_term->length();
field_term_char= field_term_length ? (*exchange->field_term)[0] : INT_MAX; field_term_char= field_term_length ?
(int) (uchar) (*exchange->field_term)[0] : INT_MAX;
if (!exchange->line_term->length()) if (!exchange->line_term->length())
exchange->line_term=exchange->field_term; // Use this if it exists exchange->line_term=exchange->field_term; // Use this if it exists
field_sep_char= (exchange->enclosed->length() ? (*exchange->enclosed)[0] : field_sep_char= (exchange->enclosed->length() ?
field_term_char); (int) (uchar) (*exchange->enclosed)[0] : field_term_char);
escape_char= (exchange->escaped->length() ? (*exchange->escaped)[0] : -1); escape_char= (exchange->escaped->length() ?
(int) (uchar) (*exchange->escaped)[0] : -1);
is_ambiguous_field_sep= test(strchr(ESCAPE_CHARS, field_sep_char)); is_ambiguous_field_sep= test(strchr(ESCAPE_CHARS, field_sep_char));
is_unsafe_field_sep= test(strchr(NUMERIC_CHARS, field_sep_char)); is_unsafe_field_sep= test(strchr(NUMERIC_CHARS, field_sep_char));
line_sep_char= (exchange->line_term->length() ? line_sep_char= (exchange->line_term->length() ?
(*exchange->line_term)[0] : INT_MAX); (int) (uchar) (*exchange->line_term)[0] : INT_MAX);
if (!field_term_length) if (!field_term_length)
exchange->opt_enclosed=0; exchange->opt_enclosed=0;
if (!exchange->enclosed->length()) if (!exchange->enclosed->length())
...@@ -1385,10 +1387,11 @@ bool select_export::send_data(List<Item> &items) ...@@ -1385,10 +1387,11 @@ bool select_export::send_data(List<Item> &items)
Don't escape field_term_char by doubling - doubling is only Don't escape field_term_char by doubling - doubling is only
valid for ENCLOSED BY characters: valid for ENCLOSED BY characters:
*/ */
(enclosed || !is_ambiguous_field_term || *pos != field_term_char)) (enclosed || !is_ambiguous_field_term ||
(int) (uchar) *pos != field_term_char))
{ {
char tmp_buff[2]; char tmp_buff[2];
tmp_buff[0]= ((int) *pos == field_sep_char && tmp_buff[0]= ((int) (uchar) *pos == field_sep_char &&
is_ambiguous_field_sep) ? is_ambiguous_field_sep) ?
field_sep_char : escape_char; field_sep_char : escape_char;
tmp_buff[1]= *pos ? *pos : '0'; tmp_buff[1]= *pos ? *pos : '0';
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment