summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Barkov <bar@mariadb.org>2015-09-01 19:24:58 +0400
committerAlexander Barkov <bar@mariadb.org>2015-09-01 19:24:58 +0400
commit8ea9b8c0b168b3e5aad08886477d8726531abcd5 (patch)
tree3897e54df42462d6d5376bee3505a9b06f6e6a89
parenta3c24ee7393ef08559b2a559909b42a400bfe692 (diff)
downloadmariadb-git-8ea9b8c0b168b3e5aad08886477d8726531abcd5.tar.gz
MDEV-8722 The patch for MDEV-8688 disabled equal field propagation for temporal column and BETWEEN and IN
Item::cmp_context was inconsistently used in combination with cmp_type() and result_type() in different places of the code. Fixed to use cmp_type() in all places where cmp_context is involved, to avoid unexpected results for temporal data types (which have result_type()==STRING_RESULT and cmp_type==TIME_RESULT).
-rw-r--r--mysql-test/r/type_date.result16
-rw-r--r--mysql-test/t/type_date.test10
-rw-r--r--sql/item.cc2
-rw-r--r--sql/item_cmpfunc.cc29
-rw-r--r--sql/item_cmpfunc.h23
-rw-r--r--sql/sql_select.cc2
6 files changed, 55 insertions, 27 deletions
diff --git a/mysql-test/r/type_date.result b/mysql-test/r/type_date.result
index 48bb3224e80..90d66ba6d98 100644
--- a/mysql-test/r/type_date.result
+++ b/mysql-test/r/type_date.result
@@ -495,5 +495,21 @@ DROP TABLE t1;
# End of MDEV-8373 Zero date can be inserted in strict no-zero mode through CREATE TABLE AS SELECT timestamp_field
#
#
+# MDEV-8722 The patch for MDEV-8688 disabled equal field propagation for temporal column and BETWEEN and IN
+#
+CREATE TABLE t1 (a DATE);
+INSERT INTO t1 VALUES ('2001-01-01'),('2001-01-02');
+EXPLAIN EXTENDED SELECT * FROM t1 WHERE a='2001-01-01' AND a BETWEEN '2001-01-01' AND '2001-01-02';
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
+Warnings:
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` = '2001-01-01')
+EXPLAIN EXTENDED SELECT * FROM t1 WHERE a='2001-01-01' AND a IN ('2001-01-01','2001-01-02');
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
+Warnings:
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` = '2001-01-01')
+DROP TABLE t1;
+#
# End of 10.1 tests
#
diff --git a/mysql-test/t/type_date.test b/mysql-test/t/type_date.test
index 53627c637fc..c89b1168427 100644
--- a/mysql-test/t/type_date.test
+++ b/mysql-test/t/type_date.test
@@ -394,5 +394,15 @@ let defval='0000-00-00';
--source include/type_temporal_zero_default.inc
--echo #
+--echo # MDEV-8722 The patch for MDEV-8688 disabled equal field propagation for temporal column and BETWEEN and IN
+--echo #
+CREATE TABLE t1 (a DATE);
+INSERT INTO t1 VALUES ('2001-01-01'),('2001-01-02');
+EXPLAIN EXTENDED SELECT * FROM t1 WHERE a='2001-01-01' AND a BETWEEN '2001-01-01' AND '2001-01-02';
+EXPLAIN EXTENDED SELECT * FROM t1 WHERE a='2001-01-01' AND a IN ('2001-01-01','2001-01-02');
+DROP TABLE t1;
+
+
+--echo #
--echo # End of 10.1 tests
--echo #
diff --git a/sql/item.cc b/sql/item.cc
index 769ca9d2a49..cf646f591de 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -8619,7 +8619,7 @@ void resolve_const_item(THD *thd, Item **ref, Item *comp_item)
return; // Can't be better
Item *new_item= NULL;
- Item_result res_type=item_cmp_type(comp_item->cmp_type(), item->cmp_type());
+ Item_result res_type= item_cmp_type(comp_item, item);
char *name=item->name; // Alloced by sql_alloc
MEM_ROOT *mem_root= thd->mem_root;
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index ca7dcc03ef1..ae1e003e871 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -165,7 +165,7 @@ static int agg_cmp_type(Item_result *type, Item **items, uint nitems)
type[0]= items[0]->cmp_type();
for (i= 1 ; i < nitems ; i++)
{
- type[0]= item_cmp_type(type[0], items[i]->cmp_type());
+ type[0]= item_cmp_type(type[0], items[i]);
/*
When aggregating types of two row expressions we have to check
that they have the same cardinality and that each component
@@ -231,26 +231,25 @@ static uint collect_cmp_types(Item **items, uint nitems, bool skip_nulls= FALSE)
{
uint i;
uint found_types;
- Item_result left_result= items[0]->cmp_type();
+ Item_result left_cmp_type= items[0]->cmp_type();
DBUG_ASSERT(nitems > 1);
found_types= 0;
for (i= 1; i < nitems ; i++)
{
if (skip_nulls && items[i]->type() == Item::NULL_ITEM)
continue; // Skip NULL constant items
- if ((left_result == ROW_RESULT ||
+ if ((left_cmp_type == ROW_RESULT ||
items[i]->cmp_type() == ROW_RESULT) &&
cmp_row_type(items[0], items[i]))
return 0;
- found_types|= 1U << (uint)item_cmp_type(left_result,
- items[i]->cmp_type());
+ found_types|= 1U << (uint) item_cmp_type(left_cmp_type, items[i]);
}
/*
Even if all right-hand items are NULLs and we are skipping them all, we need
at least one type bit in the found_type bitmask.
*/
if (skip_nulls && !found_types)
- found_types= 1U << (uint)left_result;
+ found_types= 1U << (uint) left_cmp_type;
return found_types;
}
@@ -500,8 +499,7 @@ bool Item_func::setup_args_and_comparator(THD *thd, Arg_comparator *cmp)
agg_arg_charsets_for_comparison(cmp->cmp_collation, args, 2))
return true;
- args[0]->cmp_context= args[1]->cmp_context=
- item_cmp_type(args[0]->result_type(), args[1]->result_type());
+ args[0]->cmp_context= args[1]->cmp_context= item_cmp_type(args[0], args[1]);
// Convert constants when compared to int/year field
DBUG_ASSERT(functype() != LIKE_FUNC);
@@ -2781,7 +2779,7 @@ Item_func_nullif::is_null()
Item_func_case::Item_func_case(THD *thd, List<Item> &list,
Item *first_expr_arg, Item *else_expr_arg):
Item_func_hybrid_field_type(thd), first_expr_num(-1), else_expr_num(-1),
- left_result_type(INT_RESULT), case_item(0)
+ left_cmp_type(INT_RESULT), case_item(0)
{
ncases= list.elements;
if (first_expr_arg)
@@ -2840,7 +2838,7 @@ Item *Item_func_case::find_item(String *str)
{
if (args[i]->real_item()->type() == NULL_ITEM)
continue;
- cmp_type= item_cmp_type(left_result_type, args[i]->cmp_type());
+ cmp_type= item_cmp_type(left_cmp_type, args[i]);
DBUG_ASSERT(cmp_type != ROW_RESULT);
DBUG_ASSERT(cmp_items[(uint)cmp_type]);
if (!(value_added_map & (1U << (uint)cmp_type)))
@@ -3070,7 +3068,7 @@ void Item_func_case::fix_length_and_dec()
{
uint i;
agg[0]= args[first_expr_num];
- left_result_type= agg[0]->cmp_type();
+ left_cmp_type= agg[0]->cmp_type();
/*
As the first expression and WHEN expressions
@@ -3146,8 +3144,7 @@ void Item_func_case::fix_length_and_dec()
require rebuilding cmp_items.
*/
for (i= 0; i < ncases; i+= 2)
- args[i]->cmp_context= item_cmp_type(left_result_type,
- args[i]->result_type());
+ args[i]->cmp_context= item_cmp_type(left_cmp_type, args[i]);
}
}
@@ -3977,7 +3974,7 @@ void Item_func_in::fix_length_and_dec()
uint found_types= 0;
uint type_cnt= 0, i;
m_compare_type= STRING_RESULT;
- left_result_type= args[0]->cmp_type();
+ left_cmp_type= args[0]->cmp_type();
if (!(found_types= collect_cmp_types(args, arg_count, true)))
return;
@@ -4143,7 +4140,7 @@ void Item_func_in::fix_length_and_dec()
*/
for (arg= args + 1, arg_end= args + arg_count; arg != arg_end ; arg++)
{
- arg[0]->cmp_context= item_cmp_type(left_result_type, arg[0]->result_type());
+ arg[0]->cmp_context= item_cmp_type(left_cmp_type, arg[0]);
}
max_length= 1;
}
@@ -4209,7 +4206,7 @@ longlong Item_func_in::val_int()
have_null= TRUE;
continue;
}
- Item_result cmp_type= item_cmp_type(left_result_type, args[i]->cmp_type());
+ Item_result cmp_type= item_cmp_type(left_cmp_type, args[i]);
in_item= cmp_items[(uint)cmp_type];
DBUG_ASSERT(in_item);
if (!(value_added_map & (1U << (uint)cmp_type)))
diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h
index 2d986b39c39..b20a741c6b4 100644
--- a/sql/item_cmpfunc.h
+++ b/sql/item_cmpfunc.h
@@ -29,6 +29,14 @@
#include "pcre.h" /* pcre header file */
extern Item_result item_cmp_type(Item_result a,Item_result b);
+inline Item_result item_cmp_type(const Item *a, const Item *b)
+{
+ return item_cmp_type(a->cmp_type(), b->cmp_type());
+}
+inline Item_result item_cmp_type(Item_result a, const Item *b)
+{
+ return item_cmp_type(a, b->cmp_type());
+}
class Item_bool_func2;
class Arg_comparator;
@@ -51,8 +59,7 @@ class Arg_comparator: public Sql_alloc
int set_compare_func(Item_func_or_sum *owner, Item_result type);
inline int set_compare_func(Item_func_or_sum *owner_arg)
{
- return set_compare_func(owner_arg, item_cmp_type((*a)->result_type(),
- (*b)->result_type()));
+ return set_compare_func(owner_arg, item_cmp_type(*a, *b));
}
bool agg_arg_charsets_for_comparison();
@@ -75,16 +82,14 @@ public:
Item **a1, Item **a2, bool set_null_arg)
{
set_null= set_null_arg;
- return set_cmp_func(owner_arg, a1, a2,
- item_cmp_type((*a1)->cmp_type(),
- (*a2)->cmp_type()));
+ return set_cmp_func(owner_arg, a1, a2, item_cmp_type(*a1, *a2));
}
int set_cmp_func_and_arg_cmp_context(Item_func_or_sum *owner_arg,
Item **a1, Item **a2,
bool set_null_arg)
{
set_null= set_null_arg;
- Item_result type= item_cmp_type((*a1)->cmp_type(), (*a2)->cmp_type());
+ Item_result type= item_cmp_type(*a1, *a2);
int rc= set_cmp_func(owner_arg, a1, a2, type);
if (!rc)
(*a1)->cmp_context= (*a2)->cmp_context= type;
@@ -397,7 +402,7 @@ public:
if (set_cmp_func())
return true;
tmp_arg[0]->cmp_context= tmp_arg[1]->cmp_context=
- item_cmp_type(tmp_arg[0]->result_type(), tmp_arg[1]->result_type());
+ item_cmp_type(tmp_arg[0], tmp_arg[1]);
return false;
}
CHARSET_INFO *compare_collation() const
@@ -1313,7 +1318,7 @@ public:
class Item_func_case :public Item_func_hybrid_field_type
{
int first_expr_num, else_expr_num;
- enum Item_result left_result_type;
+ enum Item_result left_cmp_type;
String tmp_value;
uint ncases;
Item_result cmp_type;
@@ -1373,7 +1378,7 @@ public:
and can be used safely as comparisons for key conditions
*/
bool arg_types_compatible;
- Item_result left_result_type;
+ Item_result left_cmp_type;
cmp_item *cmp_items[6]; /* One cmp_item for each result type */
Item_func_in(THD *thd, List<Item> &list):
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 8d60be54914..3e60120aaf6 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -15471,7 +15471,7 @@ static bool
test_if_equality_guarantees_uniqueness(Item *l, Item *r)
{
return (r->const_item() || !(r->used_tables() & ~OUTER_REF_TABLE_BIT)) &&
- item_cmp_type(l->cmp_type(), r->cmp_type()) == l->cmp_type() &&
+ item_cmp_type(l, r) == l->cmp_type() &&
(l->cmp_type() != STRING_RESULT ||
l->collation.collation == r->collation.collation);
}