summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <tsmith@sita.local>2007-07-09 01:21:22 -0600
committerunknown <tsmith@sita.local>2007-07-09 01:21:22 -0600
commitee7519a5d5ca7df345e301cb982c07b03b4d178e (patch)
tree7c157ce34ebf561ed89a66821fd51804fde72a89
parent53c8af88b6881d8c42c94b11fc8528082a41a077 (diff)
parent95e4b2e36515c4077b808b5df992eb23ed6203cc (diff)
downloadmariadb-git-ee7519a5d5ca7df345e301cb982c07b03b4d178e.tar.gz
Merge sita.local:/Users/tsmith/m/bk/41
into sita.local:/Users/tsmith/m/bk/maint/41
-rw-r--r--mysql-test/r/loaddata.result56
-rw-r--r--mysql-test/t/loaddata.test37
-rw-r--r--sql/sql_class.cc5
-rw-r--r--sql/sql_class.h9
-rw-r--r--sql/sql_load.cc1
5 files changed, 105 insertions, 3 deletions
diff --git a/mysql-test/r/loaddata.result b/mysql-test/r/loaddata.result
index e1076cd3072..83a0788b793 100644
--- a/mysql-test/r/loaddata.result
+++ b/mysql-test/r/loaddata.result
@@ -1,4 +1,4 @@
-drop table if exists t1;
+drop table if exists t1,t2;
create table t1 (a date, b date, c date not null, d date);
load data infile '../../std_data/loaddata1.dat' into table t1 fields terminated by ',';
Warnings:
@@ -85,3 +85,57 @@ 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;
diff --git a/mysql-test/t/loaddata.test b/mysql-test/t/loaddata.test
index e989cb0b2ac..14f33c6b396 100644
--- a/mysql-test/t/loaddata.test
+++ b/mysql-test/t/loaddata.test
@@ -3,7 +3,7 @@
#
--disable_warnings
-drop table if exists t1;
+drop table if exists t1,t2;
--enable_warnings
create table t1 (a date, b date, c date not null, d date);
@@ -67,4 +67,39 @@ load data infile '../../std_data/loaddata5.dat' into table t1 fields terminated
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 b187d29021a..3e918a6a07c 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= test(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))
diff --git a/sql/sql_class.h b/sql/sql_class.h
index db6f65cab55..eb2c8637651 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -1224,9 +1224,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 10124e5f5ff..bac981651c3 100644
--- a/sql/sql_load.cc
+++ b/sql/sql_load.cc
@@ -611,6 +611,7 @@ read_sep_field(THD *thd,COPY_INFO &info,TABLE *table,
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';