diff --git a/mysql-test/suite/tianmu/r/issue1352.result b/mysql-test/suite/tianmu/r/issue1352.result new file mode 100644 index 000000000..ceeba31c8 --- /dev/null +++ b/mysql-test/suite/tianmu/r/issue1352.result @@ -0,0 +1,25 @@ +DROP DATABASE IF EXISTS issue1352_test; +CREATE DATABASE issue1352_test; +USE issue1352_test; +CREATE TABLE test (dt TIMESTAMP) engine=tianmu; +insert test values(now()); +EXPLAIN SELECT dt FROM test WHERE dt >= date_sub(now(), INTERVAL 30 DAY) AND dt < now(); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE test NULL ALL NULL NULL NULL NULL 1 100.00 Using where with pushed condition ((`issue1352_test`.`test`.`dt` >= ((now() - interval 30 day))) and (`issue1352_test`.`test`.`dt` < (now())))(t0) Pckrows: 1, susp. 0 (0 empty 1 full). Conditions: 1 +EXPLAIN SELECT dt FROM test WHERE dt < date_sub(now(), INTERVAL 30 DAY) AND dt < now(); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE test NULL ALL NULL NULL NULL NULL 1 100.00 Using where with pushed condition ((`issue1352_test`.`test`.`dt` < ((now() - interval 30 day))) and (`issue1352_test`.`test`.`dt` < (now())))(t0) Pckrows: 1, susp. 0 (1 empty 0 full). Conditions: 1 +EXPLAIN SELECT dt FROM test WHERE dt >= date_sub(now(), INTERVAL 30 DAY) AND dt >= now(); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE test NULL ALL NULL NULL NULL NULL 1 100.00 Using where with pushed condition ((`issue1352_test`.`test`.`dt` >= ((now() - interval 30 day))) and (`issue1352_test`.`test`.`dt` >= (now())))(t0) Pckrows: 1, susp. 0 (1 empty 0 full). Conditions: 1 +EXPLAIN SELECT count(dt) FROM test WHERE dt >= date_sub(now(), INTERVAL 30 DAY) AND dt >= now() group by dt; +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE test NULL ALL NULL NULL NULL NULL 1 100.00 Using where with pushed condition ((`issue1352_test`.`test`.`dt` >= ((now() - interval 30 day))) and (`issue1352_test`.`test`.`dt` >= (now())))(t0) Pckrows: 1, susp. 0 (1 empty 0 full). Conditions: 1; Using temporary; Using filesort +EXPLAIN SELECT count(dt) FROM test WHERE dt >= date_sub(now(), INTERVAL 30 DAY) AND dt >= now() group by dt; +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE test NULL ALL NULL NULL NULL NULL 1 100.00 Using where with pushed condition ((`issue1352_test`.`test`.`dt` >= ((now() - interval 30 day))) and (`issue1352_test`.`test`.`dt` >= (now())))(t0) Pckrows: 1, susp. 0 (1 empty 0 full). Conditions: 1; Using temporary; Using filesort +EXPLAIN SELECT dt FROM test WHERE dt >= date_add(now(), INTERVAL 30 DAY) AND dt < now(); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE test NULL ALL NULL NULL NULL NULL 1 100.00 Using where with pushed condition ((`issue1352_test`.`test`.`dt` >= ((now() + interval 30 day))) and (`issue1352_test`.`test`.`dt` < (now()))) +DROP TABLE test; +DROP DATABASE issue1352_test; diff --git a/mysql-test/suite/tianmu/t/issue1352.test b/mysql-test/suite/tianmu/t/issue1352.test new file mode 100644 index 000000000..c9cab52d9 --- /dev/null +++ b/mysql-test/suite/tianmu/t/issue1352.test @@ -0,0 +1,36 @@ +--source include/have_tianmu.inc + +--disable_warnings + +DROP DATABASE IF EXISTS issue1352_test; +CREATE DATABASE issue1352_test; + +USE issue1352_test; + +## DDL + +CREATE TABLE test (dt TIMESTAMP) engine=tianmu; + +### insert data + +insert test values(now()); + +## explain + +EXPLAIN SELECT dt FROM test WHERE dt >= date_sub(now(), INTERVAL 30 DAY) AND dt < now(); + +EXPLAIN SELECT dt FROM test WHERE dt < date_sub(now(), INTERVAL 30 DAY) AND dt < now(); + +EXPLAIN SELECT dt FROM test WHERE dt >= date_sub(now(), INTERVAL 30 DAY) AND dt >= now(); + +EXPLAIN SELECT count(dt) FROM test WHERE dt >= date_sub(now(), INTERVAL 30 DAY) AND dt >= now() group by dt; + +EXPLAIN SELECT count(dt) FROM test WHERE dt >= date_sub(now(), INTERVAL 30 DAY) AND dt >= now() group by dt; + +EXPLAIN SELECT dt FROM test WHERE dt >= date_add(now(), INTERVAL 30 DAY) AND dt < now(); + +## clean test table + +DROP TABLE test; + +DROP DATABASE issue1352_test; diff --git a/storage/tianmu/core/mysql_expression.cpp b/storage/tianmu/core/mysql_expression.cpp index f0ee1327f..0f2e4ef98 100644 --- a/storage/tianmu/core/mysql_expression.cpp +++ b/storage/tianmu/core/mysql_expression.cpp @@ -579,8 +579,11 @@ bool operator==(Item const &, Item const &); namespace { bool generic_item_same(Item const &left, Item const &right) { - return ((&left == &right) || - ((left.type() == right.type()) && (left.result_type() == right.result_type()) && + if (&left == &right) { + return true; + } + + return (((left.type() == right.type()) && (left.result_type() == right.result_type()) && (left.cast_to_int_type() == right.cast_to_int_type()) && (left.string_field_type() == right.string_field_type()) && (left.field_type() == right.field_type()) && (left.const_during_execution() == right.const_during_execution()) && (left == right))); @@ -601,8 +604,8 @@ bool operator==(Item const &left, Item const &right) { } break; case (Item::COND_ITEM): case (Item::FUNC_ITEM): { - Item_func const *l = static_cast(&left); - Item_func const *r = static_cast(&right); + Item_func const *l = down_cast(&left); + Item_func const *r = down_cast(&right); same = !std::strcmp(l->func_name(), r->func_name()); same = same && (l->arg_count == r->arg_count); same = same && l->functype() == r->functype(); @@ -611,8 +614,8 @@ bool operator==(Item const &left, Item const &right) { same = same && l->item_name.eq_safe(r->item_name); if (l->functype() == Item_func::GUSERVAR_FUNC) { if (same) { - Item_func_get_user_var const *ll = static_cast(&left); - Item_func_get_user_var const *rr = static_cast(&right); + Item_func_get_user_var const *ll = down_cast(&left); + Item_func_get_user_var const *rr = down_cast(&right); same = !std::strcmp(ll->name.ptr(), rr->name.ptr()); } } else { @@ -628,13 +631,13 @@ bool operator==(Item const &left, Item const &right) { same = same && ((l->int_type == r->int_type) && (l->date_sub_interval == r->date_sub_interval)); if (l->functype() == Item_func::IN_FUNC) { - const Item_func_in *l = static_cast(&left); - const Item_func_in *r = static_cast(&right); + const Item_func_in *l = down_cast(&left); + const Item_func_in *r = down_cast(&right); same = same && l->negated == r->negated; } if (same && (l->functype() == Item_func::COND_AND_FUNC || l->functype() == Item_func::COND_OR_FUNC)) { - Item_cond *l = const_cast(static_cast(&left)); - Item_cond *r = const_cast(static_cast(&right)); + Item_cond *l = const_cast(down_cast(&left)); + Item_cond *r = const_cast(down_cast(&right)); List_iterator li(*l->argument_list()); List_iterator ri(*r->argument_list()); Item *il, *ir; @@ -649,13 +652,13 @@ bool operator==(Item const &left, Item const &right) { } } break; case static_cast(Item_tianmufield::enumTIANMUFiledItem::TIANMUFIELD_ITEM): { - Item_tianmufield const *l = static_cast(&left); - Item_tianmufield const *r = static_cast(&right); + Item_tianmufield const *l = down_cast(&left); + Item_tianmufield const *r = down_cast(&right); same = (*l == *r); } break; case (Item::REF_ITEM): { - Item_ref const *l = static_cast(&left); - Item_ref const *r = static_cast(&right); + Item_ref const *l = down_cast(&left); + Item_ref const *r = down_cast(&right); same = (!(l->ref || r->ref)) || (l->ref && r->ref && ((!(*(l->ref) || *(r->ref))) || (*(l->ref) && *(r->ref) && (*(*(l->ref)) == *(*(r->ref)))))); @@ -665,6 +668,7 @@ bool operator==(Item const &left, Item const &right) { case (Item::DECIMAL_ITEM): case (Item::REAL_ITEM): case (Item::VARBIN_ITEM): + case (Item::CACHE_ITEM): case (Item::INT_ITEM): { same = left.eq(&right, true); } break;