summaryrefslogtreecommitdiff
path: root/sql/sql_class.cc
diff options
context:
space:
mode:
authorunknown <gshchepa/uchum@gleb.loc>2007-07-03 19:37:46 +0500
committerunknown <gshchepa/uchum@gleb.loc>2007-07-03 19:37:46 +0500
commit166d3c9186539e4ebd738e368be453bdee119cc2 (patch)
tree225544d55fd087e00370cd901b8bd353467a3e62 /sql/sql_class.cc
parent7fbf6303d264a84bd225e0113a910459a067e3d0 (diff)
downloadmariadb-git-166d3c9186539e4ebd738e368be453bdee119cc2.tar.gz
Fixed bug #29294.
The `SELECT 'r' INTO OUTFILE ... FIELDS ENCLOSED BY 'r' ' statement encoded the 'r' string to a 4 byte string of value x'725c7272' (sequence of 4 characters: r\rr). The LOAD DATA statement decoded this string to a 1 byte string of value x'0d' (ASCII Carriage Return character) instead of the original 'r' character. The same error also happened with the FIELDS ENCLOSED BY clause followed by special characters: 'n', 't', 'r', 'b', '0', 'Z' and 'N'. NOTE 1: This is a result of the undocumented feature: the LOAD DATA INFILE recognises 2-byte input sequences like \n, \t, \r and \Z in addition to documented 2-byte sequences: \0 and \N. This feature should be documented (here backspace character is a default ESCAPED BY character, in the real-life example it may be any ESCAPED BY character). NOTE 2, changed behaviour: Now the `SELECT INTO OUTFILE' statement with the `FIELDS ENCLOSED BY' clause followed by one of: 'n', 't', 'r', 'b', '0', 'Z' or 'N' characters encodes this special character itself by doubling it ('r' --> 'rr'), not by prepending it with an escape character. sql/sql_class.h: Fixed bug #29294. The ESCAPE_CHARS macro constant is defined to enumerate symbolic names of espace-sequences like '\n', '\t' etc. The select_export::is_ambiguous_field_sep field has been added to distinguish special values of the field_sep field from another values (see ESCAPE_CHARS). sql/sql_class.cc: Fixed bug #29294. The select_export::send_data method has been modified to encode special values of the field_sep field by doubling of those values instead of prepending them with a value of the escape_char field. Example: The SELECT 'r' INTO OUTFILE FIELDS ENCLOSED BY 'r' now produces the 'rr' output string instead of x'5c72' (i.e. instead of sequence of 2 bytes: \ and r). sql/sql_load.cc: Fixed bug #29294. Added commentary for the READ_INFO::unescape method. mysql-test/t/loaddata.test: Updated test case for bug #29294. mysql-test/r/loaddata.result: Updated test case for bug #29294.
Diffstat (limited to 'sql/sql_class.cc')
-rw-r--r--sql/sql_class.cc5
1 files changed, 4 insertions, 1 deletions
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index b187d29021a..0f58f96cf57 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -1020,6 +1020,7 @@ select_export::prepare(List<Item> &list, SELECT_LEX_UNIT *u)
field_sep_char= (exchange->enclosed->length() ? (*exchange->enclosed)[0] :
field_term_length ? (*exchange->field_term)[0] : INT_MAX);
escape_char= (exchange->escaped->length() ? (*exchange->escaped)[0] : -1);
+ is_ambiguous_field_sep= strchr(ESCAPE_CHARS, field_sep_char);
line_sep_char= (exchange->line_term->length() ?
(*exchange->line_term)[0] : INT_MAX);
if (!field_term_length)
@@ -1113,7 +1114,9 @@ bool select_export::send_data(List<Item> &items)
(int) *pos == line_sep_char || !*pos)
{
char tmp_buff[2];
- tmp_buff[0]= escape_char;
+ tmp_buff[0]= ((int) *pos == field_sep_char &&
+ is_ambiguous_field_sep) ?
+ field_sep_char : escape_char;
tmp_buff[1]= *pos ? *pos : '0';
if (my_b_write(&cache,(byte*) start,(uint) (pos-start)) ||
my_b_write(&cache,(byte*) tmp_buff,2))