From fb75d93bdd8e981ca7d7b510cb973d3939ac82e8 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 23 Oct 2007 16:16:59 +0500 Subject: Fixed bug #31663: if the FIELDS TERMINATED BY string in the SELECT INTO OUTFILE clause starts with a special character (one of n, t, r, b, 0, Z or N) and ENCLOSED BY is empty, every occurrence of this character within a field value is duplicated. Duplication has been avoided. New warning message has been added: "First character of the FIELDS TERMINATED string is ambiguous; please use non-optional and non-empty FIELDS ENCLOSED BY". mysql-test/r/outfile_loaddata.result: BitKeeper file /home/uchum/work/bk/5.0-opt-31663/mysql-test/r/outfile_loaddata.result Added test case for bug #31663. mysql-test/t/outfile_loaddata.test: BitKeeper file /home/uchum/work/bk/5.0-opt-31663/mysql-test/t/outfile_loaddata.test Added test case for bug #31663. sql/sql_class.h: Fixed bug #31663. The select_export::is_ambiguous_field_term field has been added. This field is true if select_export::field_sep_char contains the first char of the FIELDS TERMINATED BY (ENCLOSED BY is empty), and items can contain this character. The select_export::field_term_char field has been added (first char of the FIELDS TERMINATED BY string or INT_MAX). sql/sql_class.cc: Fixed bug #31663. The select_export::prepare method has been modified to calculate a value of the select_export::is_ambiguous_field_term field and to warn if this value is true. The select_export::send_data method has been modified to avoid escaping or duplication of the field_set_char if is_ambiguous_field_term is true. sql/share/errmsg.txt: Fixed bug #31663. The ER_AMBIGUOUS_FIELD_TERM warning has been added. --- sql/share/errmsg.txt | 2 ++ sql/sql_class.cc | 44 +++++++++++++++++++++++++++++++++++--------- sql/sql_class.h | 7 +++++++ 3 files changed, 44 insertions(+), 9 deletions(-) (limited to 'sql') diff --git a/sql/share/errmsg.txt b/sql/share/errmsg.txt index 709cd1fc0a9..9e6cf462113 100644 --- a/sql/share/errmsg.txt +++ b/sql/share/errmsg.txt @@ -5639,3 +5639,5 @@ ER_TOO_HIGH_LEVEL_OF_NESTING_FOR_SELECT eng "Too high level of nesting for select" ER_NAME_BECOMES_EMPTY eng "Name '%-.64s' has become ''" +ER_AMBIGUOUS_FIELD_TERM + eng "First character of the FIELDS TERMINATED string is ambiguous; please use non-optional and non-empty FIELDS ENCLOSED BY" diff --git a/sql/sql_class.cc b/sql/sql_class.cc index b67f63778dc..1836989f2fa 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -1194,6 +1194,7 @@ int select_export::prepare(List &list, SELECT_LEX_UNIT *u) { bool blob_flag=0; + bool string_results= FALSE, non_string_results= FALSE; unit= u; if ((uint) strlen(exchange->file_name) + NAME_LEN >= FN_REFLEN) strmake(path,exchange->file_name,FN_REFLEN-1); @@ -1211,13 +1212,18 @@ select_export::prepare(List &list, SELECT_LEX_UNIT *u) blob_flag=1; break; } + if (item->result_type() == STRING_RESULT) + string_results= TRUE; + else + non_string_results= TRUE; } } field_term_length=exchange->field_term->length(); + field_term_char= field_term_length ? (*exchange->field_term)[0] : INT_MAX; if (!exchange->line_term->length()) exchange->line_term=exchange->field_term; // Use this if it exists field_sep_char= (exchange->enclosed->length() ? (*exchange->enclosed)[0] : - field_term_length ? (*exchange->field_term)[0] : INT_MAX); + field_term_char); escape_char= (exchange->escaped->length() ? (*exchange->escaped)[0] : -1); is_ambiguous_field_sep= test(strchr(ESCAPE_CHARS, field_sep_char)); is_unsafe_field_sep= test(strchr(NUMERIC_CHARS, field_sep_char)); @@ -1229,12 +1235,25 @@ select_export::prepare(List &list, SELECT_LEX_UNIT *u) exchange->opt_enclosed=1; // A little quicker loop fixed_row_size= (!field_term_length && !exchange->enclosed->length() && !blob_flag); + if ((is_ambiguous_field_sep && exchange->enclosed->is_empty() && + (string_results || is_unsafe_field_sep)) || + (exchange->opt_enclosed && non_string_results && + field_term_length && strchr(NUMERIC_CHARS, field_term_char))) + { + push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, + ER_AMBIGUOUS_FIELD_TERM, ER(ER_AMBIGUOUS_FIELD_TERM)); + is_ambiguous_field_term= TRUE; + } + else + is_ambiguous_field_term= FALSE; + return 0; } #define NEED_ESCAPING(x) ((int) (uchar) (x) == escape_char || \ - (int) (uchar) (x) == field_sep_char || \ + (enclosed ? (int) (uchar) (x) == field_sep_char \ + : (int) (uchar) (x) == field_term_char) || \ (int) (uchar) (x) == line_sep_char || \ !(x)) @@ -1263,8 +1282,10 @@ bool select_export::send_data(List &items) while ((item=li++)) { Item_result result_type=item->result_type(); + bool enclosed = (exchange->enclosed->length() && + (!exchange->opt_enclosed || result_type == STRING_RESULT)); res=item->str_result(&tmp); - if (res && (!exchange->opt_enclosed || result_type == STRING_RESULT)) + if (res && enclosed) { if (my_b_write(&cache,(byte*) exchange->enclosed->ptr(), exchange->enclosed->length())) @@ -1355,11 +1376,16 @@ bool select_export::send_data(List &items) DBUG_ASSERT before the loop makes that sure. */ - if (NEED_ESCAPING(*pos) || - (check_second_byte && - my_mbcharlen(character_set_client, (uchar) *pos) == 2 && - pos + 1 < end && - NEED_ESCAPING(pos[1]))) + if ((NEED_ESCAPING(*pos) || + (check_second_byte && + my_mbcharlen(character_set_client, (uchar) *pos) == 2 && + pos + 1 < end && + NEED_ESCAPING(pos[1]))) && + /* + Don't escape field_term_char by doubling - doubling is only + valid for ENCLOSED BY characters: + */ + (enclosed || !is_ambiguous_field_term || *pos != field_term_char)) { char tmp_buff[2]; tmp_buff[0]= ((int) *pos == field_sep_char && @@ -1398,7 +1424,7 @@ bool select_export::send_data(List &items) goto err; } } - if (res && (!exchange->opt_enclosed || result_type == STRING_RESULT)) + if (res && enclosed) { if (my_b_write(&cache, (byte*) exchange->enclosed->ptr(), exchange->enclosed->length())) diff --git a/sql/sql_class.h b/sql/sql_class.h index e6d65f3133a..62b1008e59c 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -1992,12 +1992,19 @@ public: class select_export :public select_to_file { uint field_term_length; int field_sep_char,escape_char,line_sep_char; + int field_term_char; // first char of FIELDS TERMINATED BY or MAX_INT /* 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; + /* + The is_ambiguous_field_term is true if field_sep_char contains the first + char of the FIELDS TERMINATED BY (ENCLOSED BY is empty), and items can + contain this character. + */ + bool is_ambiguous_field_term; /* The is_unsafe_field_sep field is true if a value of the field_sep_char field is one of the '0'..'9', '+', '-', '.' and 'e' characters -- cgit v1.2.1 From 7c345d452cdbc0a12c749b1312c321f3294b00a5 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 23 Oct 2007 19:24:59 +0400 Subject: BUG#31450: Query causes error 1048 - Let Item::save_in_field() call set_field_to_null_with_conversions() for decimal type, like this is done for the other item result types. mysql-test/r/type_decimal.result: BUG#31450: Query causes error 1048: testcase mysql-test/t/type_decimal.test: BUG#31450: Query causes error 1048: testcase --- sql/item.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sql') diff --git a/sql/item.cc b/sql/item.cc index 83cbf261b8a..739fe7967e2 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -4548,7 +4548,7 @@ int Item::save_in_field(Field *field, bool no_conversions) my_decimal decimal_value; my_decimal *value= val_decimal(&decimal_value); if (null_value) - return set_field_to_null(field); + return set_field_to_null_with_conversions(field, no_conversions); field->set_notnull(); error=field->store_decimal(value); } -- cgit v1.2.1 From afa6e70a891b9bb9e5ba4d26f7c2c7d03b1c58a1 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 25 Oct 2007 10:32:52 +0500 Subject: Fixed bug #27695: View should not be allowed to have empty or all space column names. The parser has been modified to check VIEW column names with the check_column_name function and to report an error on empty and all space column names (same as for TABLE column names). sql/sql_yacc.yy: Fixed bug #27695. The parser has been modified to check VIEW column aliases with the check_column_name function and to report an error on empty columns and all space columns (same as for TABLE column names). mysql-test/t/select.test: Updated test case for bug #27695. mysql-test/r/select.result: Updated test case for bug #27695. --- sql/sql_yacc.yy | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'sql') diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 368ce5673e2..3401bf739b3 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -4305,6 +4305,12 @@ select_item: MYSQL_YYABORT; if ($4.str) { + if (Lex->sql_command == SQLCOM_CREATE_VIEW && + check_column_name($4.str)) + { + my_error(ER_WRONG_COLUMN_NAME, MYF(0), $4.str); + MYSQL_YYABORT; + } $2->is_autogenerated_name= FALSE; $2->set_name($4.str, $4.length, system_charset_info); } -- cgit v1.2.1