summaryrefslogtreecommitdiff
path: root/sql/item.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/item.cc')
-rw-r--r--sql/item.cc88
1 files changed, 54 insertions, 34 deletions
diff --git a/sql/item.cc b/sql/item.cc
index 28729e9936f..a5dfa0db6b6 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -270,7 +270,7 @@ my_decimal *Item::val_decimal_from_string(my_decimal *decimal_value)
my_decimal *Item::val_decimal_from_date(my_decimal *decimal_value)
{
DBUG_ASSERT(fixed == 1);
- TIME ltime;
+ MYSQL_TIME ltime;
if (get_date(&ltime, TIME_FUZZY_DATE))
{
my_decimal_set_zero(decimal_value);
@@ -283,7 +283,7 @@ my_decimal *Item::val_decimal_from_date(my_decimal *decimal_value)
my_decimal *Item::val_decimal_from_time(my_decimal *decimal_value)
{
DBUG_ASSERT(fixed == 1);
- TIME ltime;
+ MYSQL_TIME ltime;
if (get_time(&ltime))
{
my_decimal_set_zero(decimal_value);
@@ -318,7 +318,7 @@ longlong Item::val_int_from_decimal()
int Item::save_time_in_field(Field *field)
{
- TIME ltime;
+ MYSQL_TIME ltime;
if (get_time(&ltime))
return set_field_to_null(field);
field->set_notnull();
@@ -328,7 +328,7 @@ int Item::save_time_in_field(Field *field)
int Item::save_date_in_field(Field *field)
{
- TIME ltime;
+ MYSQL_TIME ltime;
if (get_date(&ltime, TIME_FUZZY_DATE))
return set_field_to_null(field);
field->set_notnull();
@@ -836,22 +836,40 @@ bool Item_string::eq(const Item *item, bool binary_cmp) const
/*
- Get the value of the function as a TIME structure.
+ Get the value of the function as a MYSQL_TIME structure.
As a extra convenience the time structure is reset on error!
*/
-bool Item::get_date(TIME *ltime,uint fuzzydate)
+bool Item::get_date(MYSQL_TIME *ltime,uint fuzzydate)
{
- char buff[40];
- String tmp(buff,sizeof(buff), &my_charset_bin),*res;
- if (!(res=val_str(&tmp)) ||
- str_to_datetime_with_warn(res->ptr(), res->length(),
- ltime, fuzzydate) <= MYSQL_TIMESTAMP_ERROR)
+ if (result_type() == STRING_RESULT)
{
- bzero((char*) ltime,sizeof(*ltime));
- return 1;
+ char buff[40];
+ String tmp(buff,sizeof(buff), &my_charset_bin),*res;
+ if (!(res=val_str(&tmp)) ||
+ str_to_datetime_with_warn(res->ptr(), res->length(),
+ ltime, fuzzydate) <= MYSQL_TIMESTAMP_ERROR)
+ goto err;
+ }
+ else
+ {
+ longlong value= val_int();
+ int was_cut;
+ if (number_to_datetime(value, ltime, fuzzydate, &was_cut) == LL(-1))
+ {
+ char buff[22], *end;
+ end= longlong10_to_str(value, buff, -10);
+ make_truncated_value_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+ buff, (int) (end-buff), MYSQL_TIMESTAMP_NONE,
+ NullS);
+ goto err;
+ }
}
return 0;
+
+err:
+ bzero((char*) ltime,sizeof(*ltime));
+ return 1;
}
/*
@@ -859,7 +877,7 @@ bool Item::get_date(TIME *ltime,uint fuzzydate)
As a extra convenience the time structure is reset on error!
*/
-bool Item::get_time(TIME *ltime)
+bool Item::get_time(MYSQL_TIME *ltime)
{
char buff[40];
String tmp(buff,sizeof(buff),&my_charset_bin),*res;
@@ -1011,6 +1029,7 @@ Item_splocal::Item_splocal(const LEX_STRING &sp_var_name,
maybe_null= TRUE;
m_type= sp_map_item_type(sp_var_type);
+ m_field_type= sp_var_type;
m_result_type= sp_map_result_type(sp_var_type);
}
@@ -1837,7 +1856,7 @@ String *Item_field::str_result(String *str)
return result_field->val_str(str,&str_value);
}
-bool Item_field::get_date(TIME *ltime,uint fuzzydate)
+bool Item_field::get_date(MYSQL_TIME *ltime,uint fuzzydate)
{
if ((null_value=field->is_null()) || field->get_date(ltime,fuzzydate))
{
@@ -1847,7 +1866,7 @@ bool Item_field::get_date(TIME *ltime,uint fuzzydate)
return 0;
}
-bool Item_field::get_date_result(TIME *ltime,uint fuzzydate)
+bool Item_field::get_date_result(MYSQL_TIME *ltime,uint fuzzydate)
{
if ((null_value=result_field->is_null()) ||
result_field->get_date(ltime,fuzzydate))
@@ -1858,7 +1877,7 @@ bool Item_field::get_date_result(TIME *ltime,uint fuzzydate)
return 0;
}
-bool Item_field::get_time(TIME *ltime)
+bool Item_field::get_time(MYSQL_TIME *ltime)
{
if ((null_value=field->is_null()) || field->get_time(ltime))
{
@@ -2294,6 +2313,7 @@ default_set_param_func(Item_param *param,
Item_param::Item_param(unsigned pos_in_query_arg) :
+ strict_type(FALSE),
state(NO_VALUE),
item_result_type(STRING_RESULT),
/* Don't pretend to be a literal unless value for this item is set. */
@@ -2385,7 +2405,7 @@ void Item_param::set_decimal(const char *str, ulong length)
/*
- Set parameter value from TIME value.
+ Set parameter value from MYSQL_TIME value.
SYNOPSIS
set_time()
@@ -2399,7 +2419,7 @@ void Item_param::set_decimal(const char *str, ulong length)
the fact that even wrong value sent over binary protocol fits into
MAX_DATE_STRING_REP_LENGTH buffer.
*/
-void Item_param::set_time(TIME *tm, timestamp_type time_type,
+void Item_param::set_time(MYSQL_TIME *tm, timestamp_type time_type,
uint32 max_length_arg)
{
DBUG_ENTER("Item_param::set_time");
@@ -2414,7 +2434,8 @@ void Item_param::set_time(TIME *tm, timestamp_type time_type,
{
char buff[MAX_DATE_STRING_REP_LENGTH];
uint length= my_TIME_to_str(&value.time, buff);
- make_truncated_value_warning(current_thd, buff, length, time_type, 0);
+ make_truncated_value_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+ buff, length, time_type, 0);
set_zero_time(&value.time, MYSQL_TIMESTAMP_ERROR);
}
@@ -2487,16 +2508,16 @@ bool Item_param::set_from_user_var(THD *thd, const user_var_entry *entry)
if (entry && entry->value)
{
item_result_type= entry->type;
- switch (entry->type) {
+ if (strict_type && required_result_type != item_result_type)
+ DBUG_RETURN(1);
+ switch (item_result_type) {
case REAL_RESULT:
set_double(*(double*)entry->value);
item_type= Item::REAL_ITEM;
- item_result_type= REAL_RESULT;
break;
case INT_RESULT:
set_int(*(longlong*)entry->value, MY_INT64_NUM_DECIMAL_DIGITS);
item_type= Item::INT_ITEM;
- item_result_type= INT_RESULT;
break;
case STRING_RESULT:
{
@@ -2518,7 +2539,6 @@ bool Item_param::set_from_user_var(THD *thd, const user_var_entry *entry)
charset of connection, so we have to set it later.
*/
item_type= Item::STRING_ITEM;
- item_result_type= STRING_RESULT;
if (set_str((const char *)entry->value, entry->length))
DBUG_RETURN(1);
@@ -2532,6 +2552,7 @@ bool Item_param::set_from_user_var(THD *thd, const user_var_entry *entry)
decimals= ent_value->frac;
max_length= my_decimal_precision_to_length(ent_value->precision(),
decimals, unsigned_flag);
+ item_type= Item::DECIMAL_ITEM;
break;
}
default:
@@ -2615,7 +2636,7 @@ int Item_param::save_in_field(Field *field, bool no_conversions)
}
-bool Item_param::get_time(TIME *res)
+bool Item_param::get_time(MYSQL_TIME *res)
{
if (state == TIME_VALUE)
{
@@ -2630,7 +2651,7 @@ bool Item_param::get_time(TIME *res)
}
-bool Item_param::get_date(TIME *res, uint fuzzydate)
+bool Item_param::get_date(MYSQL_TIME *res, uint fuzzydate)
{
if (state == TIME_VALUE)
{
@@ -3056,7 +3077,7 @@ String* Item_ref_null_helper::val_str(String* s)
}
-bool Item_ref_null_helper::get_date(TIME *ltime, uint fuzzydate)
+bool Item_ref_null_helper::get_date(MYSQL_TIME *ltime, uint fuzzydate)
{
return (owner->was_null|= null_value= (*ref)->get_date(ltime, fuzzydate));
}
@@ -3502,7 +3523,8 @@ Item_field::fix_outer_field(THD *thd, Field **from_field, Item **reference)
prev_subselect_item->const_item_cache= 0;
set_field(*from_field);
if (!last_checked_context->select_lex->having_fix_field &&
- select->group_list.elements)
+ select->group_list.elements &&
+ (place == SELECT_LIST || place == IN_HAVING))
{
Item_outer_ref *rf;
/*
@@ -4621,7 +4643,6 @@ inline uint char_val(char X)
Item_hex_string::Item_hex_string(const char *str, uint str_length)
{
- name=(char*) str-2; // Lex makes this start with 0x
max_length=(str_length+1)/2;
char *ptr=(char*) sql_alloc(max_length+1);
if (!ptr)
@@ -4732,7 +4753,6 @@ Item_bin_string::Item_bin_string(const char *str, uint str_length)
uchar bits= 0;
uint power= 1;
- name= (char*) str - 2;
max_length= (str_length + 7) >> 3;
char *ptr= (char*) sql_alloc(max_length + 1);
if (!ptr)
@@ -4852,7 +4872,7 @@ bool Item::send(Protocol *protocol, String *buffer)
case MYSQL_TYPE_DATE:
case MYSQL_TYPE_TIMESTAMP:
{
- TIME tm;
+ MYSQL_TIME tm;
get_date(&tm, TIME_FUZZY_DATE);
if (!null_value)
{
@@ -4865,7 +4885,7 @@ bool Item::send(Protocol *protocol, String *buffer)
}
case MYSQL_TYPE_TIME:
{
- TIME tm;
+ MYSQL_TIME tm;
get_time(&tm);
if (!null_value)
result= protocol->store_time(&tm);
@@ -5437,7 +5457,7 @@ bool Item_ref::is_null()
}
-bool Item_ref::get_date(TIME *ltime,uint fuzzydate)
+bool Item_ref::get_date(MYSQL_TIME *ltime,uint fuzzydate)
{
return (null_value=(*ref)->get_date_result(ltime,fuzzydate));
}
@@ -5536,7 +5556,7 @@ bool Item_direct_ref::is_null()
}
-bool Item_direct_ref::get_date(TIME *ltime,uint fuzzydate)
+bool Item_direct_ref::get_date(MYSQL_TIME *ltime,uint fuzzydate)
{
return (null_value=(*ref)->get_date(ltime,fuzzydate));
}