summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorgkodinov/kgeorge@rakia.gmz <>2006-11-28 15:47:53 +0200
committergkodinov/kgeorge@rakia.gmz <>2006-11-28 15:47:53 +0200
commitfb41ec6f221bb05ae2e5a3ad60665242c696d496 (patch)
tree3d1a267fd6979baf82fe7be97b67888c56e85298 /sql
parent0421d489fbcdd1b9f3286f1981b7b3a275597b50 (diff)
parent42cd956752be97efe01ed83825e5b320b98d56a3 (diff)
downloadmariadb-git-fb41ec6f221bb05ae2e5a3ad60665242c696d496.tar.gz
Merge gkodinov@bk-internal.mysql.com:/home/bk/mysql-5.0-opt
into rakia.gmz:/home/kgeorge/mysql/autopush/B11927-5.0-opt
Diffstat (limited to 'sql')
-rw-r--r--sql/field.cc60
-rw-r--r--sql/item.cc24
-rw-r--r--sql/item.h6
-rw-r--r--sql/item_func.h4
-rw-r--r--sql/item_subselect.h2
-rw-r--r--sql/item_sum.cc8
-rw-r--r--sql/item_sum.h4
-rw-r--r--sql/sql_string.h6
8 files changed, 90 insertions, 24 deletions
diff --git a/sql/field.cc b/sql/field.cc
index 1cfd0843179..e9c4435b9e1 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -47,6 +47,8 @@ uchar Field_null::null[1]={1};
const char field_separator=',';
#define DOUBLE_TO_STRING_CONVERSION_BUFFER_SIZE 320
+#define LONGLONG_TO_STRING_CONVERSION_BUFFER_SIZE 128
+#define DECIMAL_TO_STRING_CONVERSION_BUFFER_SIZE 128
#define BLOB_PACK_LENGTH_TO_MAX_LENGH(arg) \
((ulong) ((LL(1) << min(arg, 4) * 8) - LL(1)))
@@ -6056,19 +6058,49 @@ int Field_longstr::store_decimal(const my_decimal *d)
double Field_string::val_real(void)
{
- int not_used;
- char *end_not_used;
+ int error;
+ char *end;
CHARSET_INFO *cs= charset();
- return my_strntod(cs,ptr,field_length,&end_not_used,&not_used);
+ double result;
+
+ result= my_strntod(cs,ptr,field_length,&end,&error);
+ if (!table->in_use->no_errors &&
+ (error || (field_length != (uint32)(end - ptr) &&
+ !check_if_only_end_space(cs, end, ptr + field_length))))
+ {
+ char buf[DOUBLE_TO_STRING_CONVERSION_BUFFER_SIZE];
+ String tmp(buf, sizeof(buf), cs);
+ tmp.copy(ptr, field_length, cs);
+ push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+ ER_TRUNCATED_WRONG_VALUE,
+ ER(ER_TRUNCATED_WRONG_VALUE),
+ "DOUBLE", tmp.c_ptr());
+ }
+ return result;
}
longlong Field_string::val_int(void)
{
- int not_used;
- char *end_not_used;
- CHARSET_INFO *cs=charset();
- return my_strntoll(cs,ptr,field_length,10,&end_not_used,&not_used);
+ int error;
+ char *end;
+ CHARSET_INFO *cs= charset();
+ longlong result;
+
+ result= my_strntoll(cs,ptr,field_length,10,&end,&error);
+ if (!table->in_use->no_errors &&
+ (error || (field_length != (uint32)(end - ptr) &&
+ !check_if_only_end_space(cs, end, ptr + field_length))))
+ {
+ char buf[LONGLONG_TO_STRING_CONVERSION_BUFFER_SIZE];
+ String tmp(buf, sizeof(buf), cs);
+ tmp.copy(ptr, field_length, cs);
+ push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+ ER_TRUNCATED_WRONG_VALUE,
+ ER(ER_TRUNCATED_WRONG_VALUE),
+ "INTEGER", tmp.c_ptr());
+ }
+ return result;
}
@@ -6085,8 +6117,20 @@ String *Field_string::val_str(String *val_buffer __attribute__((unused)),
my_decimal *Field_string::val_decimal(my_decimal *decimal_value)
{
- str2my_decimal(E_DEC_FATAL_ERROR, ptr, field_length, charset(),
+ int err= str2my_decimal(E_DEC_FATAL_ERROR, ptr, field_length, charset(),
decimal_value);
+ if (!table->in_use->no_errors && err)
+ {
+ char buf[DECIMAL_TO_STRING_CONVERSION_BUFFER_SIZE];
+ CHARSET_INFO *cs= charset();
+ String tmp(buf, sizeof(buf), cs);
+ tmp.copy(ptr, field_length, cs);
+ push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+ ER_TRUNCATED_WRONG_VALUE,
+ ER(ER_TRUNCATED_WRONG_VALUE),
+ "DECIMAL", tmp.c_ptr());
+ }
+
return decimal_value;
}
diff --git a/sql/item.cc b/sql/item.cc
index 59d28c00416..2df85d9533e 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -2175,12 +2175,6 @@ void Item_string::print(String *str)
}
-inline bool check_if_only_end_space(CHARSET_INFO *cs, char *str, char *end)
-{
- return str+ cs->cset->scan(cs, str, end, MY_SEQ_SPACES) == end;
-}
-
-
double Item_string::val_real()
{
DBUG_ASSERT(fixed == 1);
@@ -4764,6 +4758,22 @@ bool Item_field::send(Protocol *protocol, String *buffer)
}
+void Item_field::update_null_value()
+{
+ /*
+ need to set no_errors to prevent warnings about type conversion
+ popping up.
+ */
+ THD *thd= field->table->in_use;
+ int no_errors;
+
+ no_errors= thd->no_errors;
+ thd->no_errors= 1;
+ Item::update_null_value();
+ thd->no_errors= no_errors;
+}
+
+
Item_ref::Item_ref(Name_resolution_context *context_arg,
Item **item, const char *table_name_arg,
const char *field_name_arg)
@@ -6120,7 +6130,7 @@ bool Item_cache_row::null_inside()
}
else
{
- values[i]->val_int();
+ values[i]->update_null_value();
if (values[i]->null_value)
return 1;
}
diff --git a/sql/item.h b/sql/item.h
index 63d89113ec1..e0451febb1e 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -704,6 +704,11 @@ public:
virtual bool is_null() { return 0; }
/*
+ Make sure the null_value member has a correct value.
+ */
+ virtual void update_null_value () { (void) val_int(); }
+
+ /*
Inform the item that there will be no distinction between its result
being FALSE or NULL.
@@ -1270,6 +1275,7 @@ public:
bool get_date_result(TIME *ltime,uint fuzzydate);
bool get_time(TIME *ltime);
bool is_null() { return field->is_null(); }
+ void update_null_value();
Item *get_tmp_table_item(THD *thd);
bool collect_item_field_processor(byte * arg);
bool find_item_in_field_list_processor(byte *arg);
diff --git a/sql/item_func.h b/sql/item_func.h
index 9d94bc85d2c..ca835177f18 100644
--- a/sql/item_func.h
+++ b/sql/item_func.h
@@ -157,7 +157,7 @@ public:
return (null_value=args[0]->get_time(ltime));
}
bool is_null() {
- (void) val_int(); /* Discard result. It sets null_value as side-effect. */
+ update_null_value();
return null_value;
}
void signal_divide_by_null();
@@ -241,7 +241,7 @@ public:
virtual double real_op()= 0;
virtual my_decimal *decimal_op(my_decimal *)= 0;
virtual String *str_op(String *)= 0;
- bool is_null() { (void) val_real(); return null_value; }
+ bool is_null() { update_null_value(); return null_value; }
};
/* function where type of result detected by first argument */
diff --git a/sql/item_subselect.h b/sql/item_subselect.h
index f1be99353cc..35ded79b75d 100644
--- a/sql/item_subselect.h
+++ b/sql/item_subselect.h
@@ -91,7 +91,7 @@ public:
enum Type type() const;
bool is_null()
{
- val_int();
+ update_null_value();
return null_value;
}
bool fix_fields(THD *thd, Item **ref);
diff --git a/sql/item_sum.cc b/sql/item_sum.cc
index c2219aafd03..3fd3535ae83 100644
--- a/sql/item_sum.cc
+++ b/sql/item_sum.cc
@@ -1050,7 +1050,7 @@ bool Item_sum_count::add()
count++;
else
{
- (void) args[0]->val_int();
+ args[0]->update_null_value();
if (!args[0]->null_value)
count++;
}
@@ -1957,7 +1957,7 @@ void Item_sum_count::reset_field()
nr=1;
else
{
- (void) args[0]->val_int();
+ args[0]->update_null_value();
if (!args[0]->null_value)
nr=1;
}
@@ -2067,7 +2067,7 @@ void Item_sum_count::update_field()
nr++;
else
{
- (void) args[0]->val_int();
+ args[0]->update_null_value();
if (!args[0]->null_value)
nr++;
}
@@ -2547,7 +2547,7 @@ bool Item_sum_count_distinct::setup(THD *thd)
return TRUE; // End of memory
if (item->const_item())
{
- (void) item->val_int();
+ item->update_null_value();
if (item->null_value)
always_null=1;
}
diff --git a/sql/item_sum.h b/sql/item_sum.h
index c11ef7e548a..ad05b3c9d12 100644
--- a/sql/item_sum.h
+++ b/sql/item_sum.h
@@ -618,7 +618,7 @@ public:
double val_real();
longlong val_int();
my_decimal *val_decimal(my_decimal *);
- bool is_null() { (void) val_int(); return null_value; }
+ bool is_null() { update_null_value(); return null_value; }
String *val_str(String*);
enum_field_types field_type() const
{
@@ -685,7 +685,7 @@ public:
{ /* can't be fix_fields()ed */ return (longlong) rint(val_real()); }
String *val_str(String*);
my_decimal *val_decimal(my_decimal *);
- bool is_null() { (void) val_int(); return null_value; }
+ bool is_null() { update_null_value(); return null_value; }
enum_field_types field_type() const
{
return hybrid_type == DECIMAL_RESULT ?
diff --git a/sql/sql_string.h b/sql/sql_string.h
index 09b8478adf8..2be2cca5427 100644
--- a/sql/sql_string.h
+++ b/sql/sql_string.h
@@ -363,3 +363,9 @@ public:
return (s->alloced && Ptr >= s->Ptr && Ptr < s->Ptr + s->str_length);
}
};
+
+static inline bool check_if_only_end_space(CHARSET_INFO *cs, char *str,
+ char *end)
+{
+ return str+ cs->cset->scan(cs, str, end, MY_SEQ_SPACES) == end;
+}