diff options
author | Tor Didriksen <tor.didriksen@oracle.com> | 2011-08-19 09:06:50 +0200 |
---|---|---|
committer | Tor Didriksen <tor.didriksen@oracle.com> | 2011-08-19 09:06:50 +0200 |
commit | af6f0876ade33ad67e4a3f458a88ec21649656e2 (patch) | |
tree | 73cea93f02979761076fafb51153522053e8bf3a /sql/item_cmpfunc.cc | |
parent | 0b78d5641248dc8c92a36713bfa9f4958b66648a (diff) | |
download | mariadb-git-af6f0876ade33ad67e4a3f458a88ec21649656e2.tar.gz |
Backport from trunk of:
Bug#12532830 - SIGFPE OR ASSERTION (PRECISION <= ((9 * 9) - 8*2)) && (DEC <= 30)
Diffstat (limited to 'sql/item_cmpfunc.cc')
-rw-r--r-- | sql/item_cmpfunc.cc | 46 |
1 files changed, 26 insertions, 20 deletions
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index e28221109d9..f30b6adcb93 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -2625,37 +2625,43 @@ Item_func_if::fix_fields(THD *thd, Item **ref) } -void -Item_func_if::fix_length_and_dec() +void Item_func_if::cache_type_info(Item *source) { - maybe_null=args[1]->maybe_null || args[2]->maybe_null; - decimals= max(args[1]->decimals, args[2]->decimals); - unsigned_flag=args[1]->unsigned_flag && args[2]->unsigned_flag; + collation.set(source->collation); + cached_field_type= source->field_type(); + cached_result_type= source->result_type(); + decimals= source->decimals; + max_length= source->max_length; + maybe_null= source->maybe_null; + unsigned_flag= source->unsigned_flag; +} - enum Item_result arg1_type=args[1]->result_type(); - enum Item_result arg2_type=args[2]->result_type(); - bool null1=args[1]->const_item() && args[1]->null_value; - bool null2=args[2]->const_item() && args[2]->null_value; - if (null1) +void +Item_func_if::fix_length_and_dec() +{ + // Let IF(cond, expr, NULL) and IF(cond, NULL, expr) inherit type from expr. + if (args[1]->type() == NULL_ITEM) { - cached_result_type= arg2_type; - collation.set(args[2]->collation); - cached_field_type= args[2]->field_type(); - max_length= args[2]->max_length; + cache_type_info(args[2]); + maybe_null= true; + // If both arguments are NULL, make resulting type BINARY(0). + if (args[2]->type() == NULL_ITEM) + cached_field_type= MYSQL_TYPE_STRING; return; } - - if (null2) + if (args[2]->type() == NULL_ITEM) { - cached_result_type= arg1_type; - collation.set(args[1]->collation); - cached_field_type= args[1]->field_type(); - max_length= args[1]->max_length; + cache_type_info(args[1]); + maybe_null= true; return; } agg_result_type(&cached_result_type, args + 1, 2); + maybe_null= args[1]->maybe_null || args[2]->maybe_null; + decimals= max(args[1]->decimals, args[2]->decimals); + unsigned_flag=args[1]->unsigned_flag && args[2]->unsigned_flag; + if (cached_result_type == STRING_RESULT) { if (agg_arg_charsets_for_string_result(collation, args + 1, 2)) |