Commit 8ea9b8c0 authored by Alexander Barkov's avatar Alexander Barkov

MDEV-8722 The patch for MDEV-8688 disabled equal field propagation for...

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).
parent a3c24ee7
...@@ -495,5 +495,21 @@ DROP TABLE t1; ...@@ -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 # 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 # End of 10.1 tests
# #
...@@ -393,6 +393,16 @@ let type=DATE; ...@@ -393,6 +393,16 @@ let type=DATE;
let defval='0000-00-00'; let defval='0000-00-00';
--source include/type_temporal_zero_default.inc --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 #
--echo # End of 10.1 tests --echo # End of 10.1 tests
--echo # --echo #
...@@ -8619,7 +8619,7 @@ void resolve_const_item(THD *thd, Item **ref, Item *comp_item) ...@@ -8619,7 +8619,7 @@ void resolve_const_item(THD *thd, Item **ref, Item *comp_item)
return; // Can't be better return; // Can't be better
Item *new_item= NULL; 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 char *name=item->name; // Alloced by sql_alloc
MEM_ROOT *mem_root= thd->mem_root; MEM_ROOT *mem_root= thd->mem_root;
......
...@@ -165,7 +165,7 @@ static int agg_cmp_type(Item_result *type, Item **items, uint nitems) ...@@ -165,7 +165,7 @@ static int agg_cmp_type(Item_result *type, Item **items, uint nitems)
type[0]= items[0]->cmp_type(); type[0]= items[0]->cmp_type();
for (i= 1 ; i < nitems ; i++) 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 When aggregating types of two row expressions we have to check
that they have the same cardinality and that each component 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) ...@@ -231,26 +231,25 @@ static uint collect_cmp_types(Item **items, uint nitems, bool skip_nulls= FALSE)
{ {
uint i; uint i;
uint found_types; uint found_types;
Item_result left_result= items[0]->cmp_type(); Item_result left_cmp_type= items[0]->cmp_type();
DBUG_ASSERT(nitems > 1); DBUG_ASSERT(nitems > 1);
found_types= 0; found_types= 0;
for (i= 1; i < nitems ; i++) for (i= 1; i < nitems ; i++)
{ {
if (skip_nulls && items[i]->type() == Item::NULL_ITEM) if (skip_nulls && items[i]->type() == Item::NULL_ITEM)
continue; // Skip NULL constant items continue; // Skip NULL constant items
if ((left_result == ROW_RESULT || if ((left_cmp_type == ROW_RESULT ||
items[i]->cmp_type() == ROW_RESULT) && items[i]->cmp_type() == ROW_RESULT) &&
cmp_row_type(items[0], items[i])) cmp_row_type(items[0], items[i]))
return 0; return 0;
found_types|= 1U << (uint)item_cmp_type(left_result, found_types|= 1U << (uint) item_cmp_type(left_cmp_type, items[i]);
items[i]->cmp_type());
} }
/* /*
Even if all right-hand items are NULLs and we are skipping them all, we need 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. at least one type bit in the found_type bitmask.
*/ */
if (skip_nulls && !found_types) if (skip_nulls && !found_types)
found_types= 1U << (uint)left_result; found_types= 1U << (uint) left_cmp_type;
return found_types; return found_types;
} }
...@@ -500,8 +499,7 @@ bool Item_func::setup_args_and_comparator(THD *thd, Arg_comparator *cmp) ...@@ -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)) agg_arg_charsets_for_comparison(cmp->cmp_collation, args, 2))
return true; return true;
args[0]->cmp_context= args[1]->cmp_context= args[0]->cmp_context= args[1]->cmp_context= item_cmp_type(args[0], args[1]);
item_cmp_type(args[0]->result_type(), args[1]->result_type());
// Convert constants when compared to int/year field // Convert constants when compared to int/year field
DBUG_ASSERT(functype() != LIKE_FUNC); DBUG_ASSERT(functype() != LIKE_FUNC);
...@@ -2781,7 +2779,7 @@ Item_func_nullif::is_null() ...@@ -2781,7 +2779,7 @@ Item_func_nullif::is_null()
Item_func_case::Item_func_case(THD *thd, List<Item> &list, Item_func_case::Item_func_case(THD *thd, List<Item> &list,
Item *first_expr_arg, Item *else_expr_arg): Item *first_expr_arg, Item *else_expr_arg):
Item_func_hybrid_field_type(thd), first_expr_num(-1), else_expr_num(-1), 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; ncases= list.elements;
if (first_expr_arg) if (first_expr_arg)
...@@ -2840,7 +2838,7 @@ Item *Item_func_case::find_item(String *str) ...@@ -2840,7 +2838,7 @@ Item *Item_func_case::find_item(String *str)
{ {
if (args[i]->real_item()->type() == NULL_ITEM) if (args[i]->real_item()->type() == NULL_ITEM)
continue; 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_type != ROW_RESULT);
DBUG_ASSERT(cmp_items[(uint)cmp_type]); DBUG_ASSERT(cmp_items[(uint)cmp_type]);
if (!(value_added_map & (1U << (uint)cmp_type))) if (!(value_added_map & (1U << (uint)cmp_type)))
...@@ -3070,7 +3068,7 @@ void Item_func_case::fix_length_and_dec() ...@@ -3070,7 +3068,7 @@ void Item_func_case::fix_length_and_dec()
{ {
uint i; uint i;
agg[0]= args[first_expr_num]; 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 As the first expression and WHEN expressions
...@@ -3146,8 +3144,7 @@ void Item_func_case::fix_length_and_dec() ...@@ -3146,8 +3144,7 @@ void Item_func_case::fix_length_and_dec()
require rebuilding cmp_items. require rebuilding cmp_items.
*/ */
for (i= 0; i < ncases; i+= 2) for (i= 0; i < ncases; i+= 2)
args[i]->cmp_context= item_cmp_type(left_result_type, args[i]->cmp_context= item_cmp_type(left_cmp_type, args[i]);
args[i]->result_type());
} }
} }
...@@ -3977,7 +3974,7 @@ void Item_func_in::fix_length_and_dec() ...@@ -3977,7 +3974,7 @@ void Item_func_in::fix_length_and_dec()
uint found_types= 0; uint found_types= 0;
uint type_cnt= 0, i; uint type_cnt= 0, i;
m_compare_type= STRING_RESULT; 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))) if (!(found_types= collect_cmp_types(args, arg_count, true)))
return; return;
...@@ -4143,7 +4140,7 @@ void Item_func_in::fix_length_and_dec() ...@@ -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++) 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; max_length= 1;
} }
...@@ -4209,7 +4206,7 @@ longlong Item_func_in::val_int() ...@@ -4209,7 +4206,7 @@ longlong Item_func_in::val_int()
have_null= TRUE; have_null= TRUE;
continue; 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]; in_item= cmp_items[(uint)cmp_type];
DBUG_ASSERT(in_item); DBUG_ASSERT(in_item);
if (!(value_added_map & (1U << (uint)cmp_type))) if (!(value_added_map & (1U << (uint)cmp_type)))
......
...@@ -29,6 +29,14 @@ ...@@ -29,6 +29,14 @@
#include "pcre.h" /* pcre header file */ #include "pcre.h" /* pcre header file */
extern Item_result item_cmp_type(Item_result a,Item_result b); 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 Item_bool_func2;
class Arg_comparator; class Arg_comparator;
...@@ -51,8 +59,7 @@ class Arg_comparator: public Sql_alloc ...@@ -51,8 +59,7 @@ class Arg_comparator: public Sql_alloc
int set_compare_func(Item_func_or_sum *owner, Item_result type); int set_compare_func(Item_func_or_sum *owner, Item_result type);
inline int set_compare_func(Item_func_or_sum *owner_arg) inline int set_compare_func(Item_func_or_sum *owner_arg)
{ {
return set_compare_func(owner_arg, item_cmp_type((*a)->result_type(), return set_compare_func(owner_arg, item_cmp_type(*a, *b));
(*b)->result_type()));
} }
bool agg_arg_charsets_for_comparison(); bool agg_arg_charsets_for_comparison();
...@@ -75,16 +82,14 @@ public: ...@@ -75,16 +82,14 @@ public:
Item **a1, Item **a2, bool set_null_arg) Item **a1, Item **a2, bool set_null_arg)
{ {
set_null= set_null_arg; set_null= set_null_arg;
return set_cmp_func(owner_arg, a1, a2, return set_cmp_func(owner_arg, a1, a2, item_cmp_type(*a1, *a2));
item_cmp_type((*a1)->cmp_type(),
(*a2)->cmp_type()));
} }
int set_cmp_func_and_arg_cmp_context(Item_func_or_sum *owner_arg, int set_cmp_func_and_arg_cmp_context(Item_func_or_sum *owner_arg,
Item **a1, Item **a2, Item **a1, Item **a2,
bool set_null_arg) bool set_null_arg)
{ {
set_null= 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); int rc= set_cmp_func(owner_arg, a1, a2, type);
if (!rc) if (!rc)
(*a1)->cmp_context= (*a2)->cmp_context= type; (*a1)->cmp_context= (*a2)->cmp_context= type;
...@@ -397,7 +402,7 @@ public: ...@@ -397,7 +402,7 @@ public:
if (set_cmp_func()) if (set_cmp_func())
return true; return true;
tmp_arg[0]->cmp_context= tmp_arg[1]->cmp_context= 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; return false;
} }
CHARSET_INFO *compare_collation() const CHARSET_INFO *compare_collation() const
...@@ -1313,7 +1318,7 @@ public: ...@@ -1313,7 +1318,7 @@ public:
class Item_func_case :public Item_func_hybrid_field_type class Item_func_case :public Item_func_hybrid_field_type
{ {
int first_expr_num, else_expr_num; int first_expr_num, else_expr_num;
enum Item_result left_result_type; enum Item_result left_cmp_type;
String tmp_value; String tmp_value;
uint ncases; uint ncases;
Item_result cmp_type; Item_result cmp_type;
...@@ -1373,7 +1378,7 @@ public: ...@@ -1373,7 +1378,7 @@ public:
and can be used safely as comparisons for key conditions and can be used safely as comparisons for key conditions
*/ */
bool arg_types_compatible; 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 */ cmp_item *cmp_items[6]; /* One cmp_item for each result type */
Item_func_in(THD *thd, List<Item> &list): Item_func_in(THD *thd, List<Item> &list):
......
...@@ -15471,7 +15471,7 @@ static bool ...@@ -15471,7 +15471,7 @@ static bool
test_if_equality_guarantees_uniqueness(Item *l, Item *r) test_if_equality_guarantees_uniqueness(Item *l, Item *r)
{ {
return (r->const_item() || !(r->used_tables() & ~OUTER_REF_TABLE_BIT)) && 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->cmp_type() != STRING_RESULT ||
l->collation.collation == r->collation.collation); l->collation.collation == r->collation.collation);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment