diff options
author | Tor Didriksen <tor.didriksen@oracle.com> | 2014-04-23 17:01:35 +0200 |
---|---|---|
committer | Tor Didriksen <tor.didriksen@oracle.com> | 2014-04-23 17:01:35 +0200 |
commit | c006e3f27a840e46a3b187aa47ed9bdd68bab3a4 (patch) | |
tree | 7570a0f1f5fe6d1c94afcb659886f72b10036ade /sql | |
parent | b264c3e18d82d6dad2552ae2e4386657264bb756 (diff) | |
download | mariadb-git-c006e3f27a840e46a3b187aa47ed9bdd68bab3a4.tar.gz |
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.
Diffstat (limited to 'sql')
-rw-r--r-- | sql/sql_load.cc | 53 |
1 files changed, 31 insertions, 22 deletions
diff --git a/sql/sql_load.cc b/sql/sql_load.cc index 7f962520dd6..05571d49cc8 100644 --- a/sql/sql_load.cc +++ b/sql/sql_load.cc @@ -1,5 +1,5 @@ /* - 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 it under the terms of the GNU General Public License as published by @@ -65,7 +65,8 @@ class READ_INFO { *end_of_buff; /* Data in bufferts ends here */ uint buff_length, /* Length of buffert */ 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; int field_term_char,line_term_char,enclosed_char,escape_char; int *stack,*stack_pos; @@ -89,7 +90,7 @@ public: int read_fixed_length(void); int next_line(void); char unescape(char chr); - int terminator(char *ptr,uint length); + int terminator(const uchar *ptr, uint length); bool find_start_of_fields(); /* load xml */ List<XML_TAG> taglist; @@ -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)); // Extract exact Item value str->copy(); - pfields.append((char *)str->ptr()); + pfields.append(str->ptr()); str->free(); } /* @@ -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))) 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, - (char **)&fname_start, (char **)&fname_end); + &fname_start, &fname_end); strcpy(end, p); end += pl; Execute_load_query_log_event e(thd, load_data_query, end-load_data_query, - (uint) ((char*) fname_start - load_data_query - 1), - (uint) ((char*) fname_end - load_data_query), + static_cast<uint>(fname_start - load_data_query - 1), + static_cast<uint>(fname_end - load_data_query), (duplicates == DUP_REPLACE) ? LOAD_DUP_REPLACE : (ignore ? LOAD_DUP_IGNORE : LOAD_DUP_ERROR), transactional_table, FALSE, FALSE, errcode); @@ -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), 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(); - 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(); + level= 0; /* for load xml */ if (line_start.length() == 0) { @@ -1331,7 +1340,7 @@ READ_INFO::READ_INFO(File file_par, uint tot_length, CHARSET_INFO *cs, } else { - line_start_ptr=(char*) line_start.ptr(); + line_start_ptr= line_start.ptr(); line_start_end=line_start_ptr+line_start.length(); start_of_line= 1; } @@ -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)) { line_term_length=0; - line_term_ptr=(char*) ""; + line_term_ptr= NULL; } enclosed_char= (enclosed_length=enclosed_par.length()) ? (uchar) enclosed_par[0] : INT_MAX; - field_term_char= field_term_length ? (uchar) field_term_ptr[0] : INT_MAX; - line_term_char= line_term_length ? (uchar) line_term_ptr[0] : INT_MAX; + field_term_char= field_term_length ? field_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 */ @@ -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 uint i; @@ -1418,7 +1427,7 @@ inline int READ_INFO::terminator(char *ptr,uint length) return 1; PUSH(chr); while (i-- > 1) - PUSH((uchar) *--ptr); + PUSH(*--ptr); return 0; } @@ -1549,7 +1558,7 @@ int READ_INFO::read_field() if (my_mbcharlen(read_charset, chr) > 1 && to + my_mbcharlen(read_charset, chr) <= end_of_buff) { - uchar* p= (uchar*) to; + uchar* p= to; int ml, i; *to++ = chr; @@ -1574,7 +1583,7 @@ int READ_INFO::read_field() (const char *)to)) continue; for (i= 0; i < ml; i++) - PUSH((uchar) *--to); + PUSH(*--to); chr= GET; } #endif @@ -1723,7 +1732,7 @@ bool READ_INFO::find_start_of_fields() return 1; } } 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 if ((char) chr != *ptr) @@ -1731,7 +1740,7 @@ bool READ_INFO::find_start_of_fields() PUSH(chr); while (--ptr != line_start_ptr) { // Restart with next char - PUSH((uchar) *ptr); + PUSH( *ptr); } goto try_again; } @@ -1927,7 +1936,7 @@ int READ_INFO::read_xml() // row tag should be in ROWS IDENTIFIED BY '<row>' - stored in line_term 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", level,tag.c_ptr_safe(), line_term_ptr)); @@ -1989,7 +1998,7 @@ int READ_INFO::read_xml() } 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", level, tag.c_ptr_safe())); |