summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/r/derived_cond_pushdown.result30
-rw-r--r--mysql-test/r/func_time.result17
-rw-r--r--mysql-test/t/derived_cond_pushdown.test28
-rw-r--r--mysql-test/t/func_time.test8
-rw-r--r--sql/item_timefunc.cc20
-rw-r--r--sql/item_timefunc.h25
6 files changed, 104 insertions, 24 deletions
diff --git a/mysql-test/r/derived_cond_pushdown.result b/mysql-test/r/derived_cond_pushdown.result
index ac16dac73de..1010ed6eccb 100644
--- a/mysql-test/r/derived_cond_pushdown.result
+++ b/mysql-test/r/derived_cond_pushdown.result
@@ -10551,4 +10551,34 @@ EXPLAIN
}
DROP TABLE t1;
DROP VIEW v1;
+#
+# MDEV-21388 Wrong result of DAYNAME()=xxx in combination with condition_pushdown_for_derived=on
+#
+CREATE TABLE t1 (a INT, b DATE, c INT);
+INSERT INTO t1 VALUES
+(1,'2001-01-21',345),
+(6,'2001-01-20',315),
+(6,'2001-01-20',214);
+CREATE TABLE t2 (a INT, b INT);
+INSERT INTO t2 VALUES (2,19), (7,20);
+CREATE VIEW v1 AS SELECT a, b, max(c) AS max_c FROM t1
+GROUP BY a,b HAVING max_c < 707;
+SELECT *, dayname(v1.b) FROM v1,t2 WHERE (v1.max_c>214) AND (t2.a>v1.a);
+a b max_c a b dayname(v1.b)
+1 2001-01-21 345 2 19 Sunday
+1 2001-01-21 345 7 20 Sunday
+6 2001-01-20 315 7 20 Saturday
+SET optimizer_switch='condition_pushdown_for_derived=off';
+SELECT *, dayname(v1.b) FROM v1,t2 WHERE (v1.max_c>214) AND (t2.a>v1.a) AND dayname(v1.b)='Sunday';
+a b max_c a b dayname(v1.b)
+1 2001-01-21 345 2 19 Sunday
+1 2001-01-21 345 7 20 Sunday
+SET optimizer_switch='condition_pushdown_for_derived=on';
+SELECT *, dayname(v1.b) FROM v1,t2 WHERE (v1.max_c>214) AND (t2.a>v1.a) AND dayname(v1.b)='Sunday';
+a b max_c a b dayname(v1.b)
+1 2001-01-21 345 2 19 Sunday
+1 2001-01-21 345 7 20 Sunday
+DROP VIEW v1;
+DROP TABLE t1, t2;
+SET optimizer_switch=DEFAULT;
# End of 10.2 tests
diff --git a/mysql-test/r/func_time.result b/mysql-test/r/func_time.result
index b0c69a5334f..a82cf3c19c2 100644
--- a/mysql-test/r/func_time.result
+++ b/mysql-test/r/func_time.result
@@ -159,7 +159,9 @@ date_format('1999-12-31','%x-%v') date_format('2000-01-01','%x-%v')
1999-52 1999-52
select dayname("1962-03-03"),dayname("1962-03-03")+0;
dayname("1962-03-03") dayname("1962-03-03")+0
-Saturday 5
+Saturday 0
+Warnings:
+Warning 1292 Truncated incorrect DOUBLE value: 'Saturday'
select monthname("1972-03-04"),monthname("1972-03-04")+0;
monthname("1972-03-04") monthname("1972-03-04")+0
March 0
@@ -3508,5 +3510,18 @@ v3 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VI
DROP VIEW v1,v2,v3;
DROP TABLE t1,t2;
#
+# MDEV-21388 Wrong result of DAYNAME()=xxx in combination with condition_pushdown_for_derived=on
+#
+SELECT DAYNAME('2019-01-05')+0;
+DAYNAME('2019-01-05')+0
+0
+Warnings:
+Warning 1292 Truncated incorrect DOUBLE value: 'Saturday'
+SELECT CAST(DAYNAME('2019-01-05') AS SIGNED);
+CAST(DAYNAME('2019-01-05') AS SIGNED)
+0
+Warnings:
+Warning 1292 Truncated incorrect INTEGER value: 'Saturday'
+#
# End of 10.2 tests
#
diff --git a/mysql-test/t/derived_cond_pushdown.test b/mysql-test/t/derived_cond_pushdown.test
index c9c8fb21ac7..ec15791ddbd 100644
--- a/mysql-test/t/derived_cond_pushdown.test
+++ b/mysql-test/t/derived_cond_pushdown.test
@@ -2140,4 +2140,32 @@ SELECT * FROM (SELECT 1 FROM v1 UNION (SELECT 1 FROM v1 WHERE @a := uuid())) dt;
DROP TABLE t1;
DROP VIEW v1;
+--echo #
+--echo # MDEV-21388 Wrong result of DAYNAME()=xxx in combination with condition_pushdown_for_derived=on
+--echo #
+
+CREATE TABLE t1 (a INT, b DATE, c INT);
+INSERT INTO t1 VALUES
+ (1,'2001-01-21',345),
+ (6,'2001-01-20',315),
+ (6,'2001-01-20',214);
+
+CREATE TABLE t2 (a INT, b INT);
+INSERT INTO t2 VALUES (2,19), (7,20);
+CREATE VIEW v1 AS SELECT a, b, max(c) AS max_c FROM t1
+ GROUP BY a,b HAVING max_c < 707;
+
+SELECT *, dayname(v1.b) FROM v1,t2 WHERE (v1.max_c>214) AND (t2.a>v1.a);
+
+SET optimizer_switch='condition_pushdown_for_derived=off';
+SELECT *, dayname(v1.b) FROM v1,t2 WHERE (v1.max_c>214) AND (t2.a>v1.a) AND dayname(v1.b)='Sunday';
+
+SET optimizer_switch='condition_pushdown_for_derived=on';
+SELECT *, dayname(v1.b) FROM v1,t2 WHERE (v1.max_c>214) AND (t2.a>v1.a) AND dayname(v1.b)='Sunday';
+
+DROP VIEW v1;
+DROP TABLE t1, t2;
+
+SET optimizer_switch=DEFAULT;
+
--echo # End of 10.2 tests
diff --git a/mysql-test/t/func_time.test b/mysql-test/t/func_time.test
index 6c5b1cab95f..22729b4300b 100644
--- a/mysql-test/t/func_time.test
+++ b/mysql-test/t/func_time.test
@@ -1970,5 +1970,13 @@ DROP VIEW v1,v2,v3;
DROP TABLE t1,t2;
--echo #
+--echo # MDEV-21388 Wrong result of DAYNAME()=xxx in combination with condition_pushdown_for_derived=on
+--echo #
+
+SELECT DAYNAME('2019-01-05')+0;
+SELECT CAST(DAYNAME('2019-01-05') AS SIGNED);
+
+
+--echo #
--echo # End of 10.2 tests
--echo #
diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc
index 394552f219e..b7455f36d1b 100644
--- a/sql/item_timefunc.cc
+++ b/sql/item_timefunc.cc
@@ -1090,17 +1090,21 @@ longlong Item_func_yearweek::val_int()
}
-longlong Item_func_weekday::val_int()
+static uint weekday_from_item(Item *item, bool *null_value, bool week_starts_on_sunday)
{
- DBUG_ASSERT(fixed == 1);
MYSQL_TIME ltime;
-
- if (get_arg0_date(&ltime, TIME_NO_ZERO_DATE | TIME_NO_ZERO_IN_DATE))
+ if ((*null_value= item->get_date_with_conversion(&ltime, TIME_NO_ZERO_DATE |
+ TIME_NO_ZERO_IN_DATE)))
return 0;
+ return calc_weekday(calc_daynr(ltime.year, ltime.month, ltime.day), week_starts_on_sunday) +
+ MY_TEST(week_starts_on_sunday);
+}
- return (longlong) calc_weekday(calc_daynr(ltime.year, ltime.month,
- ltime.day),
- odbc_type) + MY_TEST(odbc_type);
+
+longlong Item_func_weekday::val_int()
+{
+ DBUG_ASSERT(fixed == 1);
+ return (longlong) weekday_from_item(args[0], &null_value, odbc_type);
}
bool Item_func_dayname::fix_length_and_dec()
@@ -1119,7 +1123,7 @@ bool Item_func_dayname::fix_length_and_dec()
String* Item_func_dayname::val_str(String* str)
{
DBUG_ASSERT(fixed == 1);
- uint weekday=(uint) val_int(); // Always Item_func_weekday()
+ uint weekday= weekday_from_item(args[0], &null_value, false);
const char *day_name;
uint err;
diff --git a/sql/item_timefunc.h b/sql/item_timefunc.h
index e37438947dd..c89b6921796 100644
--- a/sql/item_timefunc.h
+++ b/sql/item_timefunc.h
@@ -410,26 +410,17 @@ public:
};
-class Item_func_weekday :public Item_func
+class Item_func_weekday :public Item_int_func
{
bool odbc_type;
public:
Item_func_weekday(THD *thd, Item *a, bool type_arg):
- Item_func(thd, a), odbc_type(type_arg) { collation.set_numeric(); }
+ Item_int_func(thd, a), odbc_type(type_arg) { }
longlong val_int();
- double val_real() { DBUG_ASSERT(fixed == 1); return (double) val_int(); }
- String *val_str(String *str)
- {
- DBUG_ASSERT(fixed == 1);
- str->set(val_int(), &my_charset_bin);
- return null_value ? 0 : str;
- }
const char *func_name() const
{
return (odbc_type ? "dayofweek" : "weekday");
}
- enum Item_result result_type () const { return INT_RESULT; }
- enum_field_types field_type() const { return MYSQL_TYPE_LONGLONG; }
bool fix_length_and_dec()
{
decimals= 0;
@@ -447,21 +438,25 @@ public:
{ return get_item_copy<Item_func_weekday>(thd, mem_root, this); }
};
-class Item_func_dayname :public Item_func_weekday
+class Item_func_dayname :public Item_str_func
{
MY_LOCALE *locale;
public:
- Item_func_dayname(THD *thd, Item *a): Item_func_weekday(thd, a, 0) {}
+ Item_func_dayname(THD *thd, Item *a): Item_str_func(thd, a) {}
const char *func_name() const { return "dayname"; }
String *val_str(String *str);
- enum Item_result result_type () const { return STRING_RESULT; }
- enum_field_types field_type() const { return MYSQL_TYPE_VARCHAR; }
bool fix_length_and_dec();
bool check_partition_func_processor(void *int_arg) {return TRUE;}
bool check_vcol_func_processor(void *arg)
{
return mark_unsupported_function(func_name(), "()", arg, VCOL_SESSION_FUNC);
}
+ bool check_valid_arguments_processor(void *int_arg)
+ {
+ return !has_date_args();
+ }
+ Item *get_copy(THD *thd, MEM_ROOT *mem_root)
+ { return get_item_copy<Item_func_dayname>(thd, mem_root, this); }
};