Commit c76e29c8 authored by Tor Didriksen's avatar Tor Didriksen

Backport from trunk:

  Bug#18396916 MAIN.OUTFILE_LOADDATA TEST FAILS ON ARM, AARCH64, PPC/PPC64
  
  The recorded results for the failing tests were wrong.
  They were introduced by the patch for
  Bug#30946 mysqldump silently ignores --default-character-set when used with --tab
  
  Correct results were returned for platforms where 'char' is implemented as unsigned.
  This was reported as 
  Bug#46895 Test "outfile_loaddata" fails (reproducible)
  Bug#11755168 46895: TEST "OUTFILE_LOADDATA" FAILS (REPRODUCIBLE)
  The patch for that bug fixed only parts of the problem,
  leaving the incorrect results in the .result file.
  
  Solution: use 'uchar' for field_terminator and line_terminator on all platforms.
  Also: remove some un-necessary casts, leaving the ones we actually need.
parent 3d73cd23
...@@ -143,15 +143,16 @@ TRUNCATE t2; ...@@ -143,15 +143,16 @@ TRUNCATE t2;
LOAD DATA INFILE 'MYSQLTEST_VARDIR/tmp/t1.txt' INTO TABLE t2 CHARACTER SET binary FIELDS TERMINATED BY 'ъ'; LOAD DATA INFILE 'MYSQLTEST_VARDIR/tmp/t1.txt' INTO TABLE t2 CHARACTER SET binary FIELDS TERMINATED BY 'ъ';
Warnings: Warnings:
Warning 1638 Non-ASCII separator arguments are not fully supported Warning 1638 Non-ASCII separator arguments are not fully supported
Warning 1265 Data truncated for column 'a' at row 1
Warning 1261 Row 1 doesn't contain data for all columns
Warning 1261 Row 1 doesn't contain data for all columns
Warning 1265 Data truncated for column 'a' at row 2
Warning 1261 Row 2 doesn't contain data for all columns
Warning 1261 Row 2 doesn't contain data for all columns
SELECT * FROM t1 UNION SELECT * FROM t2 ORDER BY a, b, c; SELECT * FROM t1 UNION SELECT * FROM t2 ORDER BY a, b, c;
a b c a b c
1 NULL NULL 1 ABC-АБВ DEF-ÂÃÄ
2 NULL NULL
SELECT * FROM t1;
a b c
1 ABC-АБВ DEF-ÂÃÄ
2 NULL NULL
SELECT * FROM t2;
a b c
1 ABC-АБВ DEF-ÂÃÄ 1 ABC-АБВ DEF-ÂÃÄ
2 NULL NULL 2 NULL NULL
SELECT * FROM t1 INTO OUTFILE 'MYSQLTEST_VARDIR/tmp/t1.txt' LINES STARTING BY 'ъ'; SELECT * FROM t1 INTO OUTFILE 'MYSQLTEST_VARDIR/tmp/t1.txt' LINES STARTING BY 'ъ';
...@@ -181,7 +182,14 @@ Warning 1638 Non-ASCII separator arguments are not fully supported ...@@ -181,7 +182,14 @@ Warning 1638 Non-ASCII separator arguments are not fully supported
SELECT * FROM t1 UNION SELECT * FROM t2 ORDER BY a, b, c; SELECT * FROM t1 UNION SELECT * FROM t2 ORDER BY a, b, c;
a b c a b c
1 ABC-АБВ DEF-ÂÃÄ 1 ABC-АБВ DEF-ÂÃÄ
1 ABC-АБВ DEF-ÂÃÄÑŠ2 2 NULL NULL
SELECT * FROM t1;
a b c
1 ABC-АБВ DEF-ÂÃÄ
2 NULL NULL
SELECT * FROM t2;
a b c
1 ABC-АБВ DEF-ÂÃÄ
2 NULL NULL 2 NULL NULL
# Default (binary) charset: # Default (binary) charset:
SELECT * INTO OUTFILE 'MYSQLTEST_VARDIR/tmp/t1.txt' FROM t1; SELECT * INTO OUTFILE 'MYSQLTEST_VARDIR/tmp/t1.txt' FROM t1;
......
...@@ -169,6 +169,8 @@ TRUNCATE t2; ...@@ -169,6 +169,8 @@ TRUNCATE t2;
--eval LOAD DATA INFILE '$file' INTO TABLE t2 CHARACTER SET binary FIELDS TERMINATED BY 'ъ' --eval LOAD DATA INFILE '$file' INTO TABLE t2 CHARACTER SET binary FIELDS TERMINATED BY 'ъ'
--remove_file $file --remove_file $file
SELECT * FROM t1 UNION SELECT * FROM t2 ORDER BY a, b, c; SELECT * FROM t1 UNION SELECT * FROM t2 ORDER BY a, b, c;
SELECT * FROM t1;
SELECT * FROM t2;
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR --replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
--eval SELECT * FROM t1 INTO OUTFILE '$file' LINES STARTING BY 'ъ' --eval SELECT * FROM t1 INTO OUTFILE '$file' LINES STARTING BY 'ъ'
...@@ -191,6 +193,8 @@ TRUNCATE t2; ...@@ -191,6 +193,8 @@ TRUNCATE t2;
--eval LOAD DATA INFILE '$file' INTO TABLE t2 CHARACTER SET binary LINES TERMINATED BY 'ъ' --eval LOAD DATA INFILE '$file' INTO TABLE t2 CHARACTER SET binary LINES TERMINATED BY 'ъ'
--remove_file $file --remove_file $file
SELECT * FROM t1 UNION SELECT * FROM t2 ORDER BY a, b, c; SELECT * FROM t1 UNION SELECT * FROM t2 ORDER BY a, b, c;
SELECT * FROM t1;
SELECT * FROM t2;
--echo # Default (binary) charset: --echo # Default (binary) charset:
......
/* /*
Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
...@@ -65,7 +65,8 @@ class READ_INFO { ...@@ -65,7 +65,8 @@ class READ_INFO {
*end_of_buff; /* Data in bufferts ends here */ *end_of_buff; /* Data in bufferts ends here */
uint buff_length, /* Length of buffert */ uint buff_length, /* Length of buffert */
max_length; /* Max length of row */ max_length; /* Max length of row */
char *field_term_ptr,*line_term_ptr,*line_start_ptr,*line_start_end; const uchar *field_term_ptr,*line_term_ptr;
const char *line_start_ptr,*line_start_end;
uint field_term_length,line_term_length,enclosed_length; uint field_term_length,line_term_length,enclosed_length;
int field_term_char,line_term_char,enclosed_char,escape_char; int field_term_char,line_term_char,enclosed_char,escape_char;
int *stack,*stack_pos; int *stack,*stack_pos;
...@@ -89,7 +90,7 @@ public: ...@@ -89,7 +90,7 @@ public:
int read_fixed_length(void); int read_fixed_length(void);
int next_line(void); int next_line(void);
char unescape(char chr); char unescape(char chr);
int terminator(char *ptr,uint length); int terminator(const uchar *ptr, uint length);
bool find_start_of_fields(); bool find_start_of_fields();
/* load xml */ /* load xml */
List<XML_TAG> taglist; List<XML_TAG> taglist;
...@@ -751,7 +752,7 @@ static bool write_execute_load_query_log_event(THD *thd, sql_exchange* ex, ...@@ -751,7 +752,7 @@ static bool write_execute_load_query_log_event(THD *thd, sql_exchange* ex,
append_identifier(thd, &pfields, item->name, strlen(item->name)); append_identifier(thd, &pfields, item->name, strlen(item->name));
// Extract exact Item value // Extract exact Item value
str->copy(); str->copy();
pfields.append((char *)str->ptr()); pfields.append(str->ptr());
str->free(); str->free();
} }
/* /*
...@@ -767,17 +768,17 @@ static bool write_execute_load_query_log_event(THD *thd, sql_exchange* ex, ...@@ -767,17 +768,17 @@ static bool write_execute_load_query_log_event(THD *thd, sql_exchange* ex,
if (!(load_data_query= (char *)thd->alloc(lle.get_query_buffer_length() + 1 + pl))) if (!(load_data_query= (char *)thd->alloc(lle.get_query_buffer_length() + 1 + pl)))
return TRUE; return TRUE;
lle.print_query(FALSE, (const char *) ex->cs?ex->cs->csname:NULL, lle.print_query(FALSE, ex->cs ? ex->cs->csname : NULL,
load_data_query, &end, load_data_query, &end,
(char **)&fname_start, (char **)&fname_end); &fname_start, &fname_end);
strcpy(end, p); strcpy(end, p);
end += pl; end += pl;
Execute_load_query_log_event Execute_load_query_log_event
e(thd, load_data_query, end-load_data_query, e(thd, load_data_query, end-load_data_query,
(uint) ((char*) fname_start - load_data_query - 1), static_cast<uint>(fname_start - load_data_query - 1),
(uint) ((char*) fname_end - load_data_query), static_cast<uint>(fname_end - load_data_query),
(duplicates == DUP_REPLACE) ? LOAD_DUP_REPLACE : (duplicates == DUP_REPLACE) ? LOAD_DUP_REPLACE :
(ignore ? LOAD_DUP_IGNORE : LOAD_DUP_ERROR), (ignore ? LOAD_DUP_IGNORE : LOAD_DUP_ERROR),
transactional_table, FALSE, FALSE, errcode); transactional_table, FALSE, FALSE, errcode);
...@@ -1319,10 +1320,18 @@ READ_INFO::READ_INFO(File file_par, uint tot_length, CHARSET_INFO *cs, ...@@ -1319,10 +1320,18 @@ READ_INFO::READ_INFO(File file_par, uint tot_length, CHARSET_INFO *cs,
found_end_of_line(false), eof(false), need_end_io_cache(false), found_end_of_line(false), eof(false), need_end_io_cache(false),
error(false), line_cuted(false), found_null(false), read_charset(cs) error(false), line_cuted(false), found_null(false), read_charset(cs)
{ {
field_term_ptr=(char*) field_term.ptr(); /*
Field and line terminators must be interpreted as sequence of unsigned char.
Otherwise, non-ascii terminators will be negative on some platforms,
and positive on others (depending on the implementation of char).
*/
field_term_ptr=
static_cast<const uchar*>(static_cast<const void*>(field_term.ptr()));
field_term_length= field_term.length(); field_term_length= field_term.length();
line_term_ptr=(char*) line_term.ptr(); line_term_ptr=
static_cast<const uchar*>(static_cast<const void*>(line_term.ptr()));
line_term_length= line_term.length(); line_term_length= line_term.length();
level= 0; /* for load xml */ level= 0; /* for load xml */
if (line_start.length() == 0) if (line_start.length() == 0)
{ {
...@@ -1331,7 +1340,7 @@ READ_INFO::READ_INFO(File file_par, uint tot_length, CHARSET_INFO *cs, ...@@ -1331,7 +1340,7 @@ READ_INFO::READ_INFO(File file_par, uint tot_length, CHARSET_INFO *cs,
} }
else else
{ {
line_start_ptr=(char*) line_start.ptr(); line_start_ptr= line_start.ptr();
line_start_end=line_start_ptr+line_start.length(); line_start_end=line_start_ptr+line_start.length();
start_of_line= 1; start_of_line= 1;
} }
...@@ -1340,12 +1349,12 @@ READ_INFO::READ_INFO(File file_par, uint tot_length, CHARSET_INFO *cs, ...@@ -1340,12 +1349,12 @@ READ_INFO::READ_INFO(File file_par, uint tot_length, CHARSET_INFO *cs,
!memcmp(field_term_ptr,line_term_ptr,field_term_length)) !memcmp(field_term_ptr,line_term_ptr,field_term_length))
{ {
line_term_length=0; line_term_length=0;
line_term_ptr=(char*) ""; line_term_ptr= NULL;
} }
enclosed_char= (enclosed_length=enclosed_par.length()) ? enclosed_char= (enclosed_length=enclosed_par.length()) ?
(uchar) enclosed_par[0] : INT_MAX; (uchar) enclosed_par[0] : INT_MAX;
field_term_char= field_term_length ? (uchar) field_term_ptr[0] : INT_MAX; field_term_char= field_term_length ? field_term_ptr[0] : INT_MAX;
line_term_char= line_term_length ? (uchar) line_term_ptr[0] : INT_MAX; line_term_char= line_term_length ? line_term_ptr[0] : INT_MAX;
/* Set of a stack for unget if long terminators */ /* Set of a stack for unget if long terminators */
...@@ -1403,7 +1412,7 @@ READ_INFO::~READ_INFO() ...@@ -1403,7 +1412,7 @@ READ_INFO::~READ_INFO()
} }
inline int READ_INFO::terminator(char *ptr,uint length) inline int READ_INFO::terminator(const uchar *ptr,uint length)
{ {
int chr=0; // Keep gcc happy int chr=0; // Keep gcc happy
uint i; uint i;
...@@ -1418,7 +1427,7 @@ inline int READ_INFO::terminator(char *ptr,uint length) ...@@ -1418,7 +1427,7 @@ inline int READ_INFO::terminator(char *ptr,uint length)
return 1; return 1;
PUSH(chr); PUSH(chr);
while (i-- > 1) while (i-- > 1)
PUSH((uchar) *--ptr); PUSH(*--ptr);
return 0; return 0;
} }
...@@ -1549,7 +1558,7 @@ int READ_INFO::read_field() ...@@ -1549,7 +1558,7 @@ int READ_INFO::read_field()
if (my_mbcharlen(read_charset, chr) > 1 && if (my_mbcharlen(read_charset, chr) > 1 &&
to + my_mbcharlen(read_charset, chr) <= end_of_buff) to + my_mbcharlen(read_charset, chr) <= end_of_buff)
{ {
uchar* p= (uchar*) to; uchar* p= to;
int ml, i; int ml, i;
*to++ = chr; *to++ = chr;
...@@ -1574,7 +1583,7 @@ int READ_INFO::read_field() ...@@ -1574,7 +1583,7 @@ int READ_INFO::read_field()
(const char *)to)) (const char *)to))
continue; continue;
for (i= 0; i < ml; i++) for (i= 0; i < ml; i++)
PUSH((uchar) *--to); PUSH(*--to);
chr= GET; chr= GET;
} }
#endif #endif
...@@ -1723,7 +1732,7 @@ bool READ_INFO::find_start_of_fields() ...@@ -1723,7 +1732,7 @@ bool READ_INFO::find_start_of_fields()
return 1; return 1;
} }
} while ((char) chr != line_start_ptr[0]); } while ((char) chr != line_start_ptr[0]);
for (char *ptr=line_start_ptr+1 ; ptr != line_start_end ; ptr++) for (const char *ptr=line_start_ptr+1 ; ptr != line_start_end ; ptr++)
{ {
chr=GET; // Eof will be checked later chr=GET; // Eof will be checked later
if ((char) chr != *ptr) if ((char) chr != *ptr)
...@@ -1731,7 +1740,7 @@ bool READ_INFO::find_start_of_fields() ...@@ -1731,7 +1740,7 @@ bool READ_INFO::find_start_of_fields()
PUSH(chr); PUSH(chr);
while (--ptr != line_start_ptr) while (--ptr != line_start_ptr)
{ // Restart with next char { // Restart with next char
PUSH((uchar) *ptr); PUSH( *ptr);
} }
goto try_again; goto try_again;
} }
...@@ -1927,7 +1936,7 @@ int READ_INFO::read_xml() ...@@ -1927,7 +1936,7 @@ int READ_INFO::read_xml()
// row tag should be in ROWS IDENTIFIED BY '<row>' - stored in line_term // row tag should be in ROWS IDENTIFIED BY '<row>' - stored in line_term
if((tag.length() == line_term_length -2) && if((tag.length() == line_term_length -2) &&
(strncmp(tag.c_ptr_safe(), line_term_ptr + 1, tag.length()) == 0)) (memcmp(tag.ptr(), line_term_ptr + 1, tag.length()) == 0))
{ {
DBUG_PRINT("read_xml", ("start-of-row: %i %s %s", DBUG_PRINT("read_xml", ("start-of-row: %i %s %s",
level,tag.c_ptr_safe(), line_term_ptr)); level,tag.c_ptr_safe(), line_term_ptr));
...@@ -1989,7 +1998,7 @@ int READ_INFO::read_xml() ...@@ -1989,7 +1998,7 @@ int READ_INFO::read_xml()
} }
if((tag.length() == line_term_length -2) && if((tag.length() == line_term_length -2) &&
(strncmp(tag.c_ptr_safe(), line_term_ptr + 1, tag.length()) == 0)) (memcmp(tag.ptr(), line_term_ptr + 1, tag.length()) == 0))
{ {
DBUG_PRINT("read_xml", ("found end-of-row %i %s", DBUG_PRINT("read_xml", ("found end-of-row %i %s",
level, tag.c_ptr_safe())); level, tag.c_ptr_safe()));
......
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