Commit 95f42e1d authored by unknown's avatar unknown
Browse files

Bug #5228 ORDER BY CAST(enumcol) sorts incorrectly under certain conditions

parent 7e7dfccc
Loading
Loading
Loading
Loading
+23 −0
Original line number Diff line number Diff line
@@ -155,3 +155,26 @@ NULL
select cast(NULL as BINARY);
cast(NULL as BINARY)
NULL
CREATE TABLE t1 (a enum ('aac','aab','aaa') not null);
INSERT INTO t1 VALUES ('aaa'),('aab'),('aac');
SELECT a, CAST(a AS CHAR) FROM t1 ORDER BY CAST(a AS UNSIGNED) ;
a	CAST(a AS CHAR)
aac	aac
aab	aab
aaa	aaa
SELECT a, CAST(a AS CHAR(3)) FROM t1 ORDER BY CAST(a AS CHAR(2)), a;
a	CAST(a AS CHAR(3))
aac	aac
aab	aab
aaa	aaa
SELECT a, CAST(a AS UNSIGNED) FROM t1 ORDER BY CAST(a AS CHAR) ;
a	CAST(a AS UNSIGNED)
aaa	3
aab	2
aac	1
SELECT a, CAST(a AS CHAR(2)) FROM t1 ORDER BY CAST(a AS CHAR(3)), a;
a	CAST(a AS CHAR(2))
aaa	aa
aab	aa
aac	aa
DROP TABLE t1;
+13 −0
Original line number Diff line number Diff line
@@ -95,3 +95,16 @@ select cast("2001-1-1" as datetime) = "2001-01-01 00:00:00";
select cast("1:2:3" as TIME) = "1:02:03";
select cast(NULL as DATE);
select cast(NULL as BINARY);

#
# Bug #5228 ORDER BY CAST(enumcol) sorts incorrectly under certain conditions
#
CREATE TABLE t1 (a enum ('aac','aab','aaa') not null);
INSERT INTO t1 VALUES ('aaa'),('aab'),('aac');
# these two should be in enum order
SELECT a, CAST(a AS CHAR) FROM t1 ORDER BY CAST(a AS UNSIGNED) ;
SELECT a, CAST(a AS CHAR(3)) FROM t1 ORDER BY CAST(a AS CHAR(2)), a;
# these two should be in alphabetic order
SELECT a, CAST(a AS UNSIGNED) FROM t1 ORDER BY CAST(a AS CHAR) ;
SELECT a, CAST(a AS CHAR(2)) FROM t1 ORDER BY CAST(a AS CHAR(3)), a;
DROP TABLE t1;
+2 −0
Original line number Diff line number Diff line
@@ -214,6 +214,7 @@ class Item_func_signed :public Item_int_func
{
public:
  Item_func_signed(Item *a) :Item_int_func(a) {}
  const char *func_name() const { return "cast_as_signed"; }
  double val()
  {
    double tmp= args[0]->val();
@@ -236,6 +237,7 @@ class Item_func_unsigned :public Item_func_signed
{
public:
  Item_func_unsigned(Item *a) :Item_func_signed(a) {}
  const char *func_name() const { return "cast_as_unsigned"; }
  void fix_length_and_dec()
  { max_length=args[0]->max_length; unsigned_flag=1; }
  void print(String *str);
+18 −0
Original line number Diff line number Diff line
@@ -2059,6 +2059,24 @@ bool Item_extract::eq(const Item *item, bool binary_cmp) const
}


bool Item_char_typecast::eq(const Item *item, bool binary_cmp) const
{
  if (this == item)
    return 1;
  if (item->type() != FUNC_ITEM ||
      func_name() != ((Item_func*)item)->func_name())
    return 0;

  Item_char_typecast *cast= (Item_char_typecast*)item;
  if (cast_length != cast->cast_length ||
      cast_cs     != cast->cast_cs)
    return 0;

  if (!args[0]->eq(cast->args[0], binary_cmp))
      return 0;
  return 1;
}

void Item_typecast::print(String *str)
{
  str->append("cast(", 5);
+5 −0
Original line number Diff line number Diff line
@@ -683,6 +683,8 @@ class Item_char_typecast :public Item_typecast
public:
  Item_char_typecast(Item *a, int length_arg, CHARSET_INFO *cs_arg)
    :Item_typecast(a), cast_length(length_arg), cast_cs(cs_arg) {}
  bool eq(const Item *item, bool binary_cmp) const;
  const char *func_name() const { return "cast_as_char"; }
  const char* cast_type() const { return "char"; };
  String *val_str(String *a);
  void fix_length_and_dec();
@@ -694,6 +696,7 @@ class Item_date_typecast :public Item_typecast_maybe_null
{
public:
  Item_date_typecast(Item *a) :Item_typecast_maybe_null(a) {}
  const char *func_name() const { return "cast_as_date"; }
  String *val_str(String *str);
  bool get_date(TIME *ltime, uint fuzzy_date);
  const char *cast_type() const { return "date"; }
@@ -709,6 +712,7 @@ class Item_time_typecast :public Item_typecast_maybe_null
{
public:
  Item_time_typecast(Item *a) :Item_typecast_maybe_null(a) {}
  const char *func_name() const { return "cast_as_time"; }
  String *val_str(String *str);
  bool get_time(TIME *ltime);
  const char *cast_type() const { return "time"; }
@@ -724,6 +728,7 @@ class Item_datetime_typecast :public Item_typecast_maybe_null
{
public:
  Item_datetime_typecast(Item *a) :Item_typecast_maybe_null(a) {}
  const char *func_name() const { return "cast_as_datetime"; }
  String *val_str(String *str);
  const char *cast_type() const { return "datetime"; }
  enum_field_types field_type() const { return MYSQL_TYPE_DATETIME; }