From 95f42e1da29deb3fb2843c5066ea8692e7bdca08 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 7 Sep 2004 15:42:19 +0500 Subject: [PATCH] Bug #5228 ORDER BY CAST(enumcol) sorts incorrectly under certain conditions --- mysql-test/r/cast.result | 23 +++++++++++++++++++++++ mysql-test/t/cast.test | 13 +++++++++++++ sql/item_func.h | 2 ++ sql/item_timefunc.cc | 18 ++++++++++++++++++ sql/item_timefunc.h | 5 +++++ 5 files changed, 61 insertions(+) diff --git a/mysql-test/r/cast.result b/mysql-test/r/cast.result index 6564a3e392b..ccf75f68e88 100644 --- a/mysql-test/r/cast.result +++ b/mysql-test/r/cast.result @@ -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; diff --git a/mysql-test/t/cast.test b/mysql-test/t/cast.test index e2deb792d47..e5681dedbac 100644 --- a/mysql-test/t/cast.test +++ b/mysql-test/t/cast.test @@ -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; diff --git a/sql/item_func.h b/sql/item_func.h index d45f7244e55..836ed27ee46 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -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); diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index 5d9a6dd9490..8f09fe82c1b 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -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); diff --git a/sql/item_timefunc.h b/sql/item_timefunc.h index 2254fc830c9..df0b05d6d42 100644 --- a/sql/item_timefunc.h +++ b/sql/item_timefunc.h @@ -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; }