summaryrefslogtreecommitdiff
path: root/sql/item.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/item.cc')
-rw-r--r--sql/item.cc116
1 files changed, 75 insertions, 41 deletions
diff --git a/sql/item.cc b/sql/item.cc
index 6c74f509915..002621acb5a 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -329,7 +329,7 @@ int Item::save_time_in_field(Field *field)
if (get_time(&ltime))
return set_field_to_null_with_conversions(field, 0);
field->set_notnull();
- return field->store_time(&ltime, MYSQL_TIMESTAMP_TIME);
+ return field->store_time_dec(&ltime, decimals);
}
@@ -339,7 +339,7 @@ int Item::save_date_in_field(Field *field)
if (get_date(&ltime, TIME_FUZZY_DATE))
return set_field_to_null_with_conversions(field, 0);
field->set_notnull();
- return field->store_time(&ltime, MYSQL_TIMESTAMP_DATETIME);
+ return field->store_time_dec(&ltime, decimals);
}
@@ -984,27 +984,59 @@ bool Item::get_date(MYSQL_TIME *ltime,uint fuzzydate)
{
if (field_type() == MYSQL_TYPE_TIME)
fuzzydate|= TIME_TIME_ONLY;
- if (result_type() != INT_RESULT || fuzzydate & TIME_TIME_ONLY)
+
+ Item_result res_type= result_type();
+
+ enum_field_types f_type= MYSQL_TYPE_SET; // a.k.a. use fuzzydate flags
+
+ switch (res_type) {
+ case INT_RESULT:
+ {
+ longlong value= val_int();
+ if (field_type() == MYSQL_TYPE_YEAR)
+ {
+ f_type= MYSQL_TYPE_YEAR;
+ if (value < 70)
+ value+= 2000;
+ else if (value <= 1900)
+ value+= 1900;
+ }
+ if (null_value || int_to_datetime_with_warn(value, ltime, fuzzydate,
+ f_type, field_name_or_null()))
+ goto err;
+ break;
+ }
+ case REAL_RESULT:
+ {
+ double value= val_real();
+ if (null_value || double_to_datetime_with_warn(value, ltime, fuzzydate,
+ f_type, field_name_or_null()))
+ goto err;
+ break;
+ }
+ case DECIMAL_RESULT:
+ {
+ my_decimal value, *res;
+ if (!(res= val_decimal(&value)) ||
+ decimal_to_datetime_with_warn(res, ltime, fuzzydate,
+ f_type, field_name_or_null()))
+ goto err;
+ break;
+ }
+ case STRING_RESULT:
{
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)
+ str_to_datetime_with_warn(res->ptr(), res->length(),
+ ltime, fuzzydate) <= MYSQL_TIMESTAMP_ERROR)
goto err;
+ break;
}
- else
- {
- longlong value= val_int();
- int was_cut;
- if (number_to_datetime(value, ltime, fuzzydate, &was_cut) == LL(-1))
- {
- Lazy_string_num str(value);
- make_truncated_value_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
- &str, MYSQL_TIMESTAMP_NONE, NullS);
- goto err;
- }
+ default:
+ DBUG_ASSERT(0);
}
+
return 0;
err:
@@ -1012,17 +1044,27 @@ err:
return 1;
}
-/**
- Get time of first argument.
-
- As a extra convenience the time structure is reset on error!
-*/
-
bool Item::get_time(MYSQL_TIME *ltime)
{
return get_date(ltime, TIME_TIME_ONLY | TIME_FUZZY_DATE);
}
+bool Item::get_seconds(ulonglong *sec, ulong *sec_part)
+{
+ if (result_type() == INT_RESULT)
+ { // optimize for an important special case
+ longlong val= val_int();
+ bool neg= val < 0 && !unsigned_flag;
+ *sec= neg ? -val : val;
+ *sec_part= 0;
+ return neg;
+ }
+ my_decimal tmp, *dec= val_decimal(&tmp);
+ if (!dec)
+ return 0;
+ return my_decimal2seconds(dec, sec, sec_part);
+}
+
CHARSET_INFO *Item::default_charset()
{
return current_thd->variables.collation_connection;
@@ -2951,7 +2993,7 @@ int Item_param::save_in_field(Field *field, bool no_conversions)
case DECIMAL_VALUE:
return field->store_decimal(&decimal_value);
case TIME_VALUE:
- field->store_time(&value.time, value.time.time_type);
+ field->store_time_dec(&value.time, decimals);
return 0;
case STRING_VALUE:
case LONG_DATA_VALUE:
@@ -5247,7 +5289,7 @@ void Item_datetime::set(longlong packed)
int Item_datetime::save_in_field(Field *field, bool no_conversions)
{
field->set_notnull();
- return field->store_time(&ltime, ltime.time_type);
+ return field->store_time_dec(&ltime, decimals);
}
longlong Item_datetime::val_int()
@@ -7194,30 +7236,22 @@ longlong Item_cache_int::val_int()
bool Item_cache_int::get_date(MYSQL_TIME *ltime, uint fuzzydate)
{
+ Lazy_string_num str(value);
+
if (!value_cached && !cache_value())
- goto err;
+ {
+ bzero((char*) ltime,sizeof(*ltime));
+ return 1;
+ }
if (cmp_type() == TIME_RESULT)
{
unpack_time(value, ltime);
ltime->time_type= mysql_type_to_time_type(field_type());
+ return 0;
}
- else
- {
- int was_cut;
- if (number_to_datetime(value, ltime, fuzzydate, &was_cut) == -1LL)
- {
- Lazy_string_num str(value);
- make_truncated_value_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
- &str, MYSQL_TIMESTAMP_NONE, NullS);
- goto err;
- }
- }
- return 0;
-err:
- bzero((char*) ltime,sizeof(*ltime));
- return 1;
+ return Item::get_date(ltime, fuzzydate);
}
int Item_cache_int::save_in_field(Field *field, bool no_conversions)
@@ -7232,7 +7266,7 @@ int Item_cache_int::save_in_field(Field *field, bool no_conversions)
MYSQL_TIME ltime;
unpack_time(value, &ltime);
ltime.time_type= mysql_type_to_time_type(field_type());
- error= field->store_time(&ltime, ltime.time_type);
+ error= field->store_time_dec(&ltime, decimals);
}
else
error= field->store(value, unsigned_flag);