Commit 21989e7d authored by unknown's avatar unknown
Browse files

item_func.h:

  Fixed bug #9939: a wrong conversion of arguments
  for functions COALESCE and IFNULL.
  The str_op virtual method was added into Item_func_numhybrid.
item_func.cc:
  Fixed bug #9939: a wrong conversion of arguments
  for functions COALESCE and IFNULL.
  The str_op virtual method was added into Item_func_numhybrid.
item_cmpfunc.h, item_cmpfunc.cc:
  Fixed bug #9939: a wrong conversion of arguments
  for functions COALESCE and IFNULL.
  Item_func_coalesce and Item_func_ifnull now
  inherit from a modified Item_func_numhybrid.
case.test, case.result:
  Added test cases for bug #9939.


mysql-test/r/case.result:
  Added test cases for bug #9939.
mysql-test/t/case.test:
  Added test cases for bug #9939.
sql/item_cmpfunc.cc:
  Fixed bug #9939: a wrong conversion of arguments
  for functions COALESCE and IFNULL.
  Item_func_coalesce and Item_func_ifnull now
  inherit from a modified Item_func_numhybrid.
sql/item_cmpfunc.h:
  Fixed bug #9939: a wrong conversion of arguments
  for functions COALESCE and IFNULL.
  Item_func_coalesce and Item_func_ifnull now
  inherit from a modified Item_func_numhybrid.
sql/item_func.cc:
  Fixed bug #9939: a wrong conversion of arguments
  for functions COALESCE and IFNULL.
  The str_op virtual method was added into Item_func_numhybrid.
sql/item_func.h:
  Fixed bug #9939: a wrong conversion of arguments
  for functions COALESCE and IFNULL.
  he str_op virtual method was added into Item_func_numhybrid.
BitKeeper/etc/logging_ok:
  Logging to logging@openlogging.org accepted
parent 190aafb4
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -87,6 +87,7 @@ hf@deer.mysql.r18.ru
hf@genie.(none)
holyfoot@mysql.com
igor@hundin.mysql.fi
igor@igor-inspiron.creware.com
igor@linux.local
igor@rurik.mysql.com
ingo@mysql.com
+17 −0
Original line number Diff line number Diff line
@@ -160,3 +160,20 @@ t1 CREATE TABLE `t1` (
  `COALESCE('a' COLLATE latin1_bin,'b')` varchar(1) character set latin1 collate latin1_bin NOT NULL default ''
) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE t1;
CREATE TABLE t1 (EMPNUM INT);
INSERT INTO t1 VALUES (0), (2);
CREATE TABLE t2 (EMPNUM DECIMAL (4, 2));
INSERT INTO t2 VALUES (0.0), (9.0);
SELECT COALESCE(t2.EMPNUM,t1.EMPNUM) AS CEMPNUM,
t1.EMPNUM AS EMPMUM1, t2.EMPNUM AS EMPNUM2
FROM t1 LEFT JOIN t2 ON t1.EMPNUM=t2.EMPNUM;
CEMPNUM	EMPMUM1	EMPNUM2
0.00	0	0.00
2.00	2	NULL
SELECT IFNULL(t2.EMPNUM,t1.EMPNUM) AS CEMPNUM,
t1.EMPNUM AS EMPMUM1, t2.EMPNUM AS EMPNUM2
FROM t1 LEFT JOIN t2 ON t1.EMPNUM=t2.EMPNUM;
CEMPNUM	EMPMUM1	EMPNUM2
0.00	0	0.00
2.00	2	NULL
DROP TABLE t1,t2;
+19 −0
Original line number Diff line number Diff line
@@ -110,3 +110,22 @@ explain extended SELECT
 COALESCE('a' COLLATE latin1_bin,'b');
SHOW CREATE TABLE t1;
DROP TABLE t1;

#
# Tests for bug #9939: conversion of the arguments for COALESCE and IFNULL
#

CREATE TABLE t1 (EMPNUM INT);
INSERT INTO t1 VALUES (0), (2);
CREATE TABLE t2 (EMPNUM DECIMAL (4, 2));
INSERT INTO t2 VALUES (0.0), (9.0);

SELECT COALESCE(t2.EMPNUM,t1.EMPNUM) AS CEMPNUM,
               t1.EMPNUM AS EMPMUM1, t2.EMPNUM AS EMPNUM2
  FROM t1 LEFT JOIN t2 ON t1.EMPNUM=t2.EMPNUM;

SELECT IFNULL(t2.EMPNUM,t1.EMPNUM) AS CEMPNUM,
               t1.EMPNUM AS EMPMUM1, t2.EMPNUM AS EMPNUM2
  FROM t1 LEFT JOIN t2 ON t1.EMPNUM=t2.EMPNUM;

DROP TABLE t1,t2;
+12 −12
Original line number Diff line number Diff line
@@ -1114,8 +1114,8 @@ Item_func_ifnull::fix_length_and_dec()
  max_length= (max(args[0]->max_length - args[0]->decimals,
                   args[1]->max_length - args[1]->decimals) +
               decimals);
  agg_result_type(&cached_result_type, args, 2);
  switch (cached_result_type) {
  agg_result_type(&hybrid_type, args, 2);
  switch (hybrid_type) {
  case STRING_RESULT:
    agg_arg_charsets(collation, args, arg_count, MY_COLL_CMP_CONV);
    break;
@@ -1153,7 +1153,7 @@ Field *Item_func_ifnull::tmp_table_field(TABLE *table)
}

double
Item_func_ifnull::val_real()
Item_func_ifnull::real_op()
{
  DBUG_ASSERT(fixed == 1);
  double value= args[0]->val_real();
@@ -1169,7 +1169,7 @@ Item_func_ifnull::val_real()
}

longlong
Item_func_ifnull::val_int()
Item_func_ifnull::int_op()
{
  DBUG_ASSERT(fixed == 1);
  longlong value=args[0]->val_int();
@@ -1185,7 +1185,7 @@ Item_func_ifnull::val_int()
}


my_decimal *Item_func_ifnull::val_decimal(my_decimal *decimal_value)
my_decimal *Item_func_ifnull::decimal_op(my_decimal *decimal_value)
{
  DBUG_ASSERT(fixed == 1);
  my_decimal *value= args[0]->val_decimal(decimal_value);
@@ -1202,7 +1202,7 @@ my_decimal *Item_func_ifnull::val_decimal(my_decimal *decimal_value)


String *
Item_func_ifnull::val_str(String *str)
Item_func_ifnull::str_op(String *str)
{
  DBUG_ASSERT(fixed == 1);
  String *res  =args[0]->val_str(str);
@@ -1676,7 +1676,7 @@ void Item_func_case::print(String *str)
  Coalesce - return first not NULL argument.
*/

String *Item_func_coalesce::val_str(String *str)
String *Item_func_coalesce::str_op(String *str)
{
  DBUG_ASSERT(fixed == 1);
  null_value=0;
@@ -1690,7 +1690,7 @@ String *Item_func_coalesce::val_str(String *str)
  return 0;
}

longlong Item_func_coalesce::val_int()
longlong Item_func_coalesce::int_op()
{
  DBUG_ASSERT(fixed == 1);
  null_value=0;
@@ -1704,7 +1704,7 @@ longlong Item_func_coalesce::val_int()
  return 0;
}

double Item_func_coalesce::val_real()
double Item_func_coalesce::real_op()
{
  DBUG_ASSERT(fixed == 1);
  null_value=0;
@@ -1719,7 +1719,7 @@ double Item_func_coalesce::val_real()
}


my_decimal *Item_func_coalesce::val_decimal(my_decimal *decimal_value)
my_decimal *Item_func_coalesce::decimal_op(my_decimal *decimal_value)
{
  DBUG_ASSERT(fixed == 1);
  null_value= 0;
@@ -1736,8 +1736,8 @@ my_decimal *Item_func_coalesce::val_decimal(my_decimal *decimal_value)

void Item_func_coalesce::fix_length_and_dec()
{
  agg_result_type(&cached_result_type, args, arg_count);
  switch (cached_result_type) {
  agg_result_type(&hybrid_type, args, arg_count);
  switch (hybrid_type) {
  case STRING_RESULT:
    count_only_length();
    decimals= NOT_FIXED_DEC;
+13 −17
Original line number Diff line number Diff line
@@ -453,23 +453,19 @@ class Item_func_interval :public Item_int_func
};


class Item_func_coalesce :public Item_func
class Item_func_coalesce :public Item_func_numhybrid
{
protected:
  enum Item_result cached_result_type;
  Item_func_coalesce(Item *a, Item *b)
    :Item_func(a, b), cached_result_type(INT_RESULT)
  {}
  Item_func_coalesce(Item *a, Item *b) :Item_func_numhybrid(a, b) {}
public:
  Item_func_coalesce(List<Item> &list)
    :Item_func(list),cached_result_type(INT_RESULT)
  {}
  double val_real();
  longlong val_int();
  String *val_str(String *);
  my_decimal *val_decimal(my_decimal *);
  Item_func_coalesce(List<Item> &list) :Item_func_numhybrid(list) {}
  double real_op();
  longlong int_op();
  String *str_op(String *);
  my_decimal *decimal_op(my_decimal *);
  void fix_length_and_dec();
  enum Item_result result_type () const { return cached_result_type; }
  void find_num_type() {}
  enum Item_result result_type () const { return hybrid_type; }
  const char *func_name() const { return "coalesce"; }
  table_map not_null_tables() const { return 0; }
};
@@ -482,10 +478,10 @@ class Item_func_ifnull :public Item_func_coalesce
  bool field_type_defined;
public:
  Item_func_ifnull(Item *a, Item *b) :Item_func_coalesce(a,b) {}
  double val_real();
  longlong val_int();
  String *val_str(String *str);
  my_decimal *val_decimal(my_decimal *);
  double real_op();
  longlong int_op();
  String *str_op(String *str);
  my_decimal *decimal_op(my_decimal *);
  enum_field_types field_type() const;
  void fix_length_and_dec();
  const char *func_name() const { return "ifnull"; }
Loading