summaryrefslogtreecommitdiff
path: root/sql/field.cc
diff options
context:
space:
mode:
authorevgen@moonbone.local <>2006-06-13 19:09:24 +0400
committerevgen@moonbone.local <>2006-06-13 19:09:24 +0400
commit67de8c46a5ddbc13ef32a339cb8c3c3e5dcb77bd (patch)
treeff268d8624baae320972dc46dbe6577959f31c25 /sql/field.cc
parentde8a1b4f19bfaa362c8ff9725ba298f1954d0083 (diff)
downloadmariadb-git-67de8c46a5ddbc13ef32a339cb8c3c3e5dcb77bd.tar.gz
Fixed bug#16377: result of DATE/TIME functions were compared as strings which
can lead to a wrong result. All date/time functions has the STRING result type thus their results are compared as strings. The string date representation allows a user to skip some of leading zeros. This can lead to wrong comparison result if a date/time function result is compared to such a string constant. The idea behind this bug fix is to compare results of date/time functions and data/time constants as ints, because that date/time representation is more exact. To achieve this the agg_cmp_type() is changed to take in the account that a date/time field or an date/time item should be compared as ints. This bug fix is partially back ported from 5.0. The agg_cmp_type() function now accepts THD as one of parameters. In addition, it now checks if a date/time field/function is present in the list. If so, it tries to coerce all constants to INT to make date/time comparison return correct result. The field for the constant coercion is taken from the Item_field or constructed from the Item_func. In latter case the constructed field will be freed after conversion of all constant items. Otherwise the result is same as before - aggregated with help of the item_cmp_type() function. From the Item_func_between::fix_length_and_dec() function removed the part which was converting date/time constants to int if possible. Now this is done by the agg_cmp_type() function. The new function result_as_longlong() is added to the Item class. It indicates that the item is a date/time item and result of it can be compared as int. Such items are date/time fields/functions. Correct val_int() methods are implemented for classes Item_date_typecast, Item_func_makedate, Item_time_typecast, Item_datetime_typecast. All these classes are derived from Item_str_func and Item_str_func::val_int() converts its string value to int without regard to the date/time type of these items. Arg_comparator::set_compare_func() and Arg_comparator::set_cmp_func() functions are changed to substitute result type of an item with the INT_RESULT if the item is a date/time item and another item is a constant. This is done to get a correct result of comparisons like date_time_function() = string_constant.
Diffstat (limited to 'sql/field.cc')
-rw-r--r--sql/field.cc16
1 files changed, 11 insertions, 5 deletions
diff --git a/sql/field.cc b/sql/field.cc
index a64eaad7308..ec4d4b4e4f5 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -6841,7 +6841,11 @@ create_field::create_field(Field *old_field,Field *orig_field)
bool
Field::set_warning(const uint level, const uint code, int cuted_increment)
{
- THD *thd= table->in_use;
+ /*
+ If this field was created only for type conversion purposes it
+ will have table == NULL.
+ */
+ THD *thd= table ? table->in_use : current_thd;
if (thd->count_cuted_fields)
{
thd->cuted_fields+= cuted_increment;
@@ -6876,7 +6880,8 @@ Field::set_datetime_warning(const uint level, const uint code,
timestamp_type ts_type, int cuted_increment)
{
if (set_warning(level, code, cuted_increment))
- make_truncated_value_warning(table->in_use, str, str_length, ts_type);
+ make_truncated_value_warning(table ? table->in_use : current_thd,
+ str, str_length, ts_type);
}
@@ -6905,8 +6910,8 @@ Field::set_datetime_warning(const uint level, const uint code,
{
char str_nr[22];
char *str_end= longlong10_to_str(nr, str_nr, -10);
- make_truncated_value_warning(table->in_use, str_nr, str_end - str_nr,
- ts_type);
+ make_truncated_value_warning(table ? table->in_use : current_thd,
+ str_nr, str_end - str_nr, ts_type);
}
}
@@ -6935,7 +6940,8 @@ Field::set_datetime_warning(const uint level, const uint code,
/* DBL_DIG is enough to print '-[digits].E+###' */
char str_nr[DBL_DIG + 8];
uint str_len= my_sprintf(str_nr, (str_nr, "%g", nr));
- make_truncated_value_warning(table->in_use, str_nr, str_len, ts_type);
+ make_truncated_value_warning(table ? table->in_use : current_thd,
+ str_nr, str_len, ts_type);
}
}