diff options
author | unknown <gshchepa/uchum@gleb.loc> | 2007-07-04 02:09:56 +0500 |
---|---|---|
committer | unknown <gshchepa/uchum@gleb.loc> | 2007-07-04 02:09:56 +0500 |
commit | c700a77623b790bf373795c80ac22cdced3a4076 (patch) | |
tree | 300828c93ebcb6bfe0b1e0304f1ab84659ed7f7c | |
parent | 81194444f81b60f1bb4a6c58f676f26c267660eb (diff) | |
parent | f57e4b99e794ef14a845fd4e73ccd1eb6a90d459 (diff) | |
download | mariadb-git-c700a77623b790bf373795c80ac22cdced3a4076.tar.gz |
Merge gleb.loc:/home/uchum/work/bk/4.1-opt
into gleb.loc:/home/uchum/work/bk/5.0-opt
sql/sql_class.cc:
Auto merged
sql/sql_class.h:
Auto merged
sql/sql_load.cc:
Auto merged
mysql-test/r/loaddata.result:
Merge with 4.1-opt.
mysql-test/t/loaddata.test:
Merge with 4.1-opt.
-rw-r--r-- | mysql-test/r/loaddata.result | 54 | ||||
-rw-r--r-- | mysql-test/t/loaddata.test | 35 | ||||
-rw-r--r-- | sql/sql_class.cc | 5 | ||||
-rw-r--r-- | sql/sql_class.h | 9 | ||||
-rw-r--r-- | sql/sql_load.cc | 1 |
5 files changed, 103 insertions, 1 deletions
diff --git a/mysql-test/r/loaddata.result b/mysql-test/r/loaddata.result index a02aaccf8f6..0aa95983264 100644 --- a/mysql-test/r/loaddata.result +++ b/mysql-test/r/loaddata.result @@ -86,6 +86,60 @@ field1 field2 a"b cd"ef a"b c"d"e drop table t1; +CREATE TABLE t1 ( +id INT AUTO_INCREMENT PRIMARY KEY, +c1 VARCHAR(255) +); +CREATE TABLE t2 ( +id INT, +c2 VARCHAR(255) +); +INSERT INTO t1 (c1) VALUES +('r'), ('rr'), ('rrr'), ('rrrr'), +('.r'), ('.rr'), ('.rrr'), ('.rrrr'), +('r.'), ('rr.'), ('rrr.'), ('rrrr.'), +('.r.'), ('.rr.'), ('.rrr.'), ('.rrrr.'); +SELECT * FROM t1; +id c1 +1 r +2 rr +3 rrr +4 rrrr +5 .r +6 .rr +7 .rrr +8 .rrrr +9 r. +10 rr. +11 rrr. +12 rrrr. +13 .r. +14 .rr. +15 .rrr. +16 .rrrr. +SELECT * INTO OUTFILE 'MYSQL_TEST_DIR/var/tmp/t1' FIELDS ENCLOSED BY 'r' FROM t1; +r1r rrrr +r2r rrrrrr +r3r rrrrrrrr +r4r rrrrrrrrrr +r5r r.rrr +r6r r.rrrrr +r7r r.rrrrrrr +r8r r.rrrrrrrrr +r9r rrr.r +r10r rrrrr.r +r11r rrrrrrr.r +r12r rrrrrrrrr.r +r13r r.rr.r +r14r r.rrrr.r +r15r r.rrrrrr.r +r16r r.rrrrrrrr.r +LOAD DATA INFILE 'MYSQL_TEST_DIR/var/tmp/t1' INTO TABLE t2 FIELDS ENCLOSED BY 'r'; +SELECT t1.id, c1, c2 FROM t1 LEFT JOIN t2 ON t1.id=t2.id WHERE c1 != c2; +id c1 c2 +SELECT t1.id, c1, c2 FROM t1 RIGHT JOIN t2 ON t1.id=t2.id WHERE c1 != c2; +id c1 c2 +DROP TABLE t1,t2; create table t1 (a int default 100, b int, c varchar(60)); load data infile '../std_data_ln/rpl_loaddata.dat' into table t1 (a, @b) set b=@b+10, c=concat("b=",@b); select * from t1; diff --git a/mysql-test/t/loaddata.test b/mysql-test/t/loaddata.test index 2757a37b881..c7f16fc303b 100644 --- a/mysql-test/t/loaddata.test +++ b/mysql-test/t/loaddata.test @@ -67,6 +67,41 @@ load data infile '../std_data_ln/loaddata_dq.dat' into table t1 fields terminate select * from t1; drop table t1; +# +# Bug #29294 SELECT INTO OUTFILE/LOAD DATA INFILE with special +# characters in the FIELDS ENCLOSED BY clause +# + +CREATE TABLE t1 ( + id INT AUTO_INCREMENT PRIMARY KEY, + c1 VARCHAR(255) +); + +CREATE TABLE t2 ( + id INT, + c2 VARCHAR(255) +); + +INSERT INTO t1 (c1) VALUES + ('r'), ('rr'), ('rrr'), ('rrrr'), + ('.r'), ('.rr'), ('.rrr'), ('.rrrr'), + ('r.'), ('rr.'), ('rrr.'), ('rrrr.'), + ('.r.'), ('.rr.'), ('.rrr.'), ('.rrrr.'); +SELECT * FROM t1; + +--exec rm -f $MYSQL_TEST_DIR/var/tmp/t1 +--replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR +eval SELECT * INTO OUTFILE '$MYSQL_TEST_DIR/var/tmp/t1' FIELDS ENCLOSED BY 'r' FROM t1; +--exec cat $MYSQL_TEST_DIR/var/tmp/t1 + +--replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR +eval LOAD DATA INFILE '$MYSQL_TEST_DIR/var/tmp/t1' INTO TABLE t2 FIELDS ENCLOSED BY 'r'; +SELECT t1.id, c1, c2 FROM t1 LEFT JOIN t2 ON t1.id=t2.id WHERE c1 != c2; +SELECT t1.id, c1, c2 FROM t1 RIGHT JOIN t2 ON t1.id=t2.id WHERE c1 != c2; + +--exec rm $MYSQL_TEST_DIR/var/tmp/t1 +DROP TABLE t1,t2; + # End of 4.1 tests # diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 788026d2f67..117c20352ce 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -1209,6 +1209,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= test(strchr(ESCAPE_CHARS, field_sep_char)); line_sep_char= (exchange->line_term->length() ? (*exchange->line_term)[0] : INT_MAX); if (!field_term_length) @@ -1349,7 +1350,9 @@ bool select_export::send_data(List<Item> &items) NEED_ESCAPING(pos[1]))) { 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)) diff --git a/sql/sql_class.h b/sql/sql_class.h index b005f956c28..f95a812ccad 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -1919,9 +1919,18 @@ public: }; +#define ESCAPE_CHARS "ntrb0ZN" // keep synchronous with READ_INFO::unescape + + class select_export :public select_to_file { uint field_term_length; int field_sep_char,escape_char,line_sep_char; + /* + The is_ambiguous_field_sep field is true if a value of the field_sep_char + field is one of the 'n', 't', 'r' etc characters + (see the READ_INFO::unescape method and the ESCAPE_CHARS constant value). + */ + bool is_ambiguous_field_sep; bool fixed_row_size; public: select_export(sql_exchange *ex) :select_to_file(ex) {} diff --git a/sql/sql_load.cc b/sql/sql_load.cc index c2267ba5dfc..7b1799baaad 100644 --- a/sql/sql_load.cc +++ b/sql/sql_load.cc @@ -847,6 +847,7 @@ continue_loop:; char READ_INFO::unescape(char chr) { + /* keep this switch synchornous with the ESCAPE_CHARS macro */ switch(chr) { case 'n': return '\n'; case 't': return '\t'; |