summaryrefslogtreecommitdiff
path: root/sql/sql_class.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/sql_class.cc')
-rw-r--r--sql/sql_class.cc60
1 files changed, 60 insertions, 0 deletions
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index 9db86214a6b..a9c399e15de 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -1790,6 +1790,8 @@ select_export::prepare(List<Item> &list, SELECT_LEX_UNIT *u)
if ((uint) strlen(exchange->file_name) + NAME_LEN >= FN_REFLEN)
strmake(path,exchange->file_name,FN_REFLEN-1);
+ write_cs= exchange->cs ? exchange->cs : &my_charset_bin;
+
if ((file= create_file(thd, path, exchange, &cache)) < 0)
return 1;
/* Check if there is any blobs in data */
@@ -1809,6 +1811,31 @@ select_export::prepare(List<Item> &list, SELECT_LEX_UNIT *u)
non_string_results= TRUE;
}
}
+ if (exchange->escaped->numchars() > 1 || exchange->enclosed->numchars() > 1)
+ {
+ my_error(ER_WRONG_FIELD_TERMINATORS, MYF(0));
+ return TRUE;
+ }
+ if (exchange->escaped->length() > 1 || exchange->enclosed->length() > 1 ||
+ !my_isascii(exchange->escaped->ptr()[0]) ||
+ !my_isascii(exchange->enclosed->ptr()[0]) ||
+ !exchange->field_term->is_ascii() || !exchange->line_term->is_ascii() ||
+ !exchange->line_start->is_ascii())
+ {
+ /*
+ Current LOAD DATA INFILE recognizes field/line separators "as is" without
+ converting from client charset to data file charset. So, it is supposed,
+ that input file of LOAD DATA INFILE consists of data in one charset and
+ separators in other charset. For the compatibility with that [buggy]
+ behaviour SELECT INTO OUTFILE implementation has been saved "as is" too,
+ but the new warning message has been added:
+
+ Non-ASCII separator arguments are not fully supported
+ */
+ push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+ WARN_NON_ASCII_SEPARATOR_NOT_IMPLEMENTED,
+ ER(WARN_NON_ASCII_SEPARATOR_NOT_IMPLEMENTED));
+ }
field_term_length=exchange->field_term->length();
field_term_char= field_term_length ?
(int) (uchar) (*exchange->field_term)[0] : INT_MAX;
@@ -1858,6 +1885,8 @@ bool select_export::send_data(List<Item> &items)
DBUG_ENTER("select_export::send_data");
char buff[MAX_FIELD_WIDTH],null_buff[2],space[MAX_FIELD_WIDTH];
+ char cvt_buff[MAX_FIELD_WIDTH];
+ String cvt_str(cvt_buff, sizeof(cvt_buff), write_cs);
bool space_inited=0;
String tmp(buff,sizeof(buff),&my_charset_bin),*res;
tmp.length(0);
@@ -1881,6 +1910,37 @@ bool select_export::send_data(List<Item> &items)
bool enclosed = (exchange->enclosed->length() &&
(!exchange->opt_enclosed || result_type == STRING_RESULT));
res=item->str_result(&tmp);
+ if (res && !my_charset_same(write_cs, res->charset()) &&
+ !my_charset_same(write_cs, &my_charset_bin))
+ {
+ const char *well_formed_error_pos;
+ const char *cannot_convert_error_pos;
+ const char *from_end_pos;
+ const char *error_pos;
+ uint32 bytes;
+ bytes= well_formed_copy_nchars(write_cs, cvt_buff, sizeof(cvt_buff),
+ res->charset(), res->ptr(), res->length(),
+ sizeof(cvt_buff),
+ &well_formed_error_pos,
+ &cannot_convert_error_pos,
+ &from_end_pos);
+ error_pos= well_formed_error_pos ? well_formed_error_pos
+ : cannot_convert_error_pos;
+ if (error_pos)
+ {
+ char printable_buff[32];
+ convert_to_printable(printable_buff, sizeof(printable_buff),
+ error_pos, res->ptr() + res->length() - error_pos,
+ res->charset(), 6);
+ push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+ ER_TRUNCATED_WRONG_VALUE_FOR_FIELD,
+ ER(ER_TRUNCATED_WRONG_VALUE_FOR_FIELD),
+ "string", printable_buff,
+ item->name, row_count);
+ }
+ cvt_str.length(bytes);
+ res= &cvt_str;
+ }
if (res && enclosed)
{
if (my_b_write(&cache,(uchar*) exchange->enclosed->ptr(),