summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorunknown <gshchepa/uchum@gleb.loc>2007-10-26 18:05:46 +0500
committerunknown <gshchepa/uchum@gleb.loc>2007-10-26 18:05:46 +0500
commitd2a986b00a586875aacb049caf95b8bc2563308c (patch)
tree89a767a9921239f50bf52cb8dd7248f0f29817c9 /sql
parent611a8972b8e36373cbc642dee881131de0c4dfd7 (diff)
parent3f3e5bac53fde3d26b2ba13581dee044238d3f20 (diff)
downloadmariadb-git-d2a986b00a586875aacb049caf95b8bc2563308c.tar.gz
Merge gleb.loc:/home/uchum/work/bk/5.0-opt
into gleb.loc:/home/uchum/work/bk/5.1-opt mysql-test/r/select.result: Auto merged mysql-test/r/type_decimal.result: Auto merged mysql-test/t/select.test: Auto merged mysql-test/t/type_decimal.test: Auto merged sql/item.cc: Auto merged sql/sql_class.cc: Auto merged sql/sql_class.h: Auto merged sql/sql_yacc.yy: Auto merged sql/share/errmsg.txt: Merge with 5.0-opt
Diffstat (limited to 'sql')
-rw-r--r--sql/item.cc2
-rw-r--r--sql/share/errmsg.txt2
-rw-r--r--sql/sql_class.cc44
-rw-r--r--sql/sql_class.h7
-rw-r--r--sql/sql_yacc.yy6
5 files changed, 51 insertions, 10 deletions
diff --git a/sql/item.cc b/sql/item.cc
index 95c8cd582cd..565081a600a 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -4649,7 +4649,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);
}
diff --git a/sql/share/errmsg.txt b/sql/share/errmsg.txt
index 8fad09eb221..37e384e0ffd 100644
--- a/sql/share/errmsg.txt
+++ b/sql/share/errmsg.txt
@@ -5658,6 +5658,8 @@ 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"
ER_FOREIGN_SERVER_EXISTS
eng "The foreign server, %s, you are trying to create already exists."
ER_FOREIGN_SERVER_DOESNT_EXIST
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index ffbf0649961..1cba93a5bd5 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -1540,6 +1540,7 @@ int
select_export::prepare(List<Item> &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);
@@ -1557,13 +1558,18 @@ select_export::prepare(List<Item> &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));
@@ -1575,12 +1581,25 @@ select_export::prepare(List<Item> &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))
@@ -1609,8 +1628,10 @@ bool select_export::send_data(List<Item> &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,(uchar*) exchange->enclosed->ptr(),
exchange->enclosed->length()))
@@ -1701,11 +1722,16 @@ bool select_export::send_data(List<Item> &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 &&
@@ -1744,7 +1770,7 @@ bool select_export::send_data(List<Item> &items)
goto err;
}
}
- if (res && (!exchange->opt_enclosed || result_type == STRING_RESULT))
+ if (res && enclosed)
{
if (my_b_write(&cache, (uchar*) exchange->enclosed->ptr(),
exchange->enclosed->length()))
diff --git a/sql/sql_class.h b/sql/sql_class.h
index c286a87653c..0a045885593 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -2070,6 +2070,7 @@ 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
@@ -2077,6 +2078,12 @@ class select_export :public select_to_file {
*/
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
(see the NUMERIC_CHARS constant value).
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index 109e8f5434f..cc7ab0a9ca0 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -6323,6 +6323,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);
}