Commit 6101fd25 authored by unknown's avatar unknown
Browse files

Fixed bug #19579: at range analysis optimizer did not take into

account predicates that become sargable after reading const tables.
In some cases this resulted in choosing non-optimal execution plans.
Now info of such potentially saragable predicates is saved in
an array and after reading const tables we check whether this
predicates has become saragable.



mysql-test/r/select.result:
  Added a test case for bug #19579.
mysql-test/t/select.test:
  Added a test case for bug #19579.
sql/item_cmpfunc.cc:
  Fixed bug #19579: at range analysis optimizer did not take into 
  account predicates that become sargable after reading const tables.
  Added a counter of between predicates.
sql/sql_base.cc:
  Fixed bug #19579: at range analysis optimizer did not take into 
  account predicates that become sargable after reading const tables.
  Added a counter of between predicates.
sql/sql_lex.cc:
  Fixed bug #19579: at range analysis optimizer did not take into 
  account predicates that become sargable after reading const tables.
  Added a counter of between predicates.
sql/sql_lex.h:
  Fixed bug #19579: at range analysis optimizer did not take into 
  account predicates that become sargable after reading const tables.
  Added a counter of between predicates.
sql/sql_select.cc:
  Fixed bug #19579: at range analysis optimizer did not take into 
  account predicates that become sargable after reading const tables.
  Now info of such potentially saragable predicates is saved in
  an array and after reading const tables we check whether this
  predicates has become saragable.
parent 40197cd3
Loading
Loading
Loading
Loading
+49 −0
Original line number Diff line number Diff line
@@ -3552,3 +3552,52 @@ id select_type table type possible_keys key key_len ref rows Extra
1	SIMPLE	t1	range	PRIMARY	PRIMARY	12	NULL	2	Using where
1	SIMPLE	t2	ref	PRIMARY	PRIMARY	18	test.t1.fk	1	Using where
DROP TABLE t1,t2;
CREATE TABLE t1(id int PRIMARY KEY, b int, e int);
CREATE TABLE t2(i int, a int, INDEX si(i), INDEX ai(a));
CREATE TABLE t3(a int PRIMARY KEY, c char(4), INDEX ci(c));
INSERT INTO t1 VALUES 
(1,10,19), (2,20,22), (4,41,42), (9,93,95), (7, 77,79),
(6,63,67), (5,55,58), (3,38,39), (8,81,89);
INSERT INTO t2 VALUES
(21,210), (41,410), (82,820), (83,830), (84,840),
(65,650), (51,510), (37,370), (94,940), (76,760),
(22,220), (33,330), (40,400), (95,950), (38,380),
(67,670), (88,880), (57,570), (96,960), (97,970);
INSERT INTO t3 VALUES
(210,'bb'), (950,'ii'), (400,'ab'), (500,'ee'), (220,'gg'),
(440,'gg'), (310,'eg'), (380,'ee'), (840,'bb'), (830,'ff'),
(230,'aa'), (960,'ii'), (410,'aa'), (510,'ee'), (290,'bb'),
(450,'gg'), (320,'dd'), (390,'hh'), (850,'jj'), (860,'ff');
EXPLAIN
SELECT t3.a FROM t1,t2 FORCE INDEX (si),t3
WHERE t1.id = 8 AND t2.i BETWEEN t1.b AND t1.e AND 
t3.a=t2.a AND t3.c IN ('bb','ee');
id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
1	SIMPLE	t1	const	PRIMARY	PRIMARY	4	const	1	
1	SIMPLE	t2	range	si	si	5	NULL	4	Using where
1	SIMPLE	t3	eq_ref	PRIMARY,ci	PRIMARY	4	test.t2.a	1	Using where
EXPLAIN
SELECT t3.a FROM t1,t2,t3
WHERE t1.id = 8 AND t2.i BETWEEN t1.b AND t1.e AND
t3.a=t2.a AND t3.c IN ('bb','ee') ;
id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
1	SIMPLE	t1	const	PRIMARY	PRIMARY	4	const	1	
1	SIMPLE	t2	range	si,ai	si	5	NULL	4	Using where
1	SIMPLE	t3	eq_ref	PRIMARY,ci	PRIMARY	4	test.t2.a	1	Using where
EXPLAIN 
SELECT t3.a FROM t1,t2 FORCE INDEX (si),t3
WHERE t1.id = 8 AND (t2.i=t1.b OR t2.i=t1.e) AND t3.a=t2.a AND
t3.c IN ('bb','ee');
id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
1	SIMPLE	t1	const	PRIMARY	PRIMARY	4	const	1	
1	SIMPLE	t2	range	si	si	5	NULL	2	Using where
1	SIMPLE	t3	eq_ref	PRIMARY,ci	PRIMARY	4	test.t2.a	1	Using where
EXPLAIN 
SELECT t3.a FROM t1,t2,t3
WHERE t1.id = 8 AND (t2.i=t1.b OR t2.i=t1.e) AND t3.a=t2.a AND
t3.c IN ('bb','ee');
id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
1	SIMPLE	t1	const	PRIMARY	PRIMARY	4	const	1	
1	SIMPLE	t2	range	si,ai	si	5	NULL	2	Using where
1	SIMPLE	t3	eq_ref	PRIMARY,ci	PRIMARY	4	test.t2.a	1	Using where
DROP TABLE t1,t2,t3;
+45 −0
Original line number Diff line number Diff line
@@ -3007,6 +3007,8 @@ c7 int, c8 int, c9 int, fulltext key (`c1`));
select distinct match (`c1`) against ('z') , c2, c3, c4,c5, c6,c7, c8 
  from t1 where c9=1 order by c2, c2;
drop table t1;

#
# Bug #22735: no equality propagation for BETWEEN and IN with STRING arguments
#

@@ -3033,3 +3035,46 @@ EXPLAIN SELECT t2.*
    WHERE t2.fk IN ('a','b') AND t2.pk=t1.fk;

DROP TABLE t1,t2;

#
# Bug #19579: predicates that become sargable after reading const tables
#             are not taken into account by optimizer
#

CREATE TABLE t1(id int PRIMARY KEY, b int, e int);
CREATE TABLE t2(i int, a int, INDEX si(i), INDEX ai(a));
CREATE TABLE t3(a int PRIMARY KEY, c char(4), INDEX ci(c));

INSERT INTO t1 VALUES 
  (1,10,19), (2,20,22), (4,41,42), (9,93,95), (7, 77,79),
  (6,63,67), (5,55,58), (3,38,39), (8,81,89);
INSERT INTO t2 VALUES
  (21,210), (41,410), (82,820), (83,830), (84,840),
  (65,650), (51,510), (37,370), (94,940), (76,760),
  (22,220), (33,330), (40,400), (95,950), (38,380),
  (67,670), (88,880), (57,570), (96,960), (97,970);
INSERT INTO t3 VALUES
  (210,'bb'), (950,'ii'), (400,'ab'), (500,'ee'), (220,'gg'),
  (440,'gg'), (310,'eg'), (380,'ee'), (840,'bb'), (830,'ff'),
  (230,'aa'), (960,'ii'), (410,'aa'), (510,'ee'), (290,'bb'),
  (450,'gg'), (320,'dd'), (390,'hh'), (850,'jj'), (860,'ff');

EXPLAIN
SELECT t3.a FROM t1,t2 FORCE INDEX (si),t3
  WHERE t1.id = 8 AND t2.i BETWEEN t1.b AND t1.e AND 
        t3.a=t2.a AND t3.c IN ('bb','ee');
EXPLAIN
SELECT t3.a FROM t1,t2,t3
  WHERE t1.id = 8 AND t2.i BETWEEN t1.b AND t1.e AND
        t3.a=t2.a AND t3.c IN ('bb','ee') ;

EXPLAIN 
SELECT t3.a FROM t1,t2 FORCE INDEX (si),t3
  WHERE t1.id = 8 AND (t2.i=t1.b OR t2.i=t1.e) AND t3.a=t2.a AND
        t3.c IN ('bb','ee');
EXPLAIN 
SELECT t3.a FROM t1,t2,t3
  WHERE t1.id = 8 AND (t2.i=t1.b OR t2.i=t1.e) AND t3.a=t2.a AND
        t3.c IN ('bb','ee');

DROP TABLE t1,t2,t3;
+2 −0
Original line number Diff line number Diff line
@@ -1078,6 +1078,8 @@ bool Item_func_between::fix_fields(THD *thd, Item **ref)
  if (Item_func_opt_neg::fix_fields(thd, ref))
    return 1;

  thd->lex->current_select->between_count++;

  /* not_null_tables_cache == union(T1(e),T1(e1),T1(e2)) */
  if (pred_level && !negated)
    return 0;
+1 −0
Original line number Diff line number Diff line
@@ -4906,6 +4906,7 @@ int setup_conds(THD *thd, TABLE_LIST *tables, TABLE_LIST *leaves,

  thd->set_query_id=1;
  select_lex->cond_count= 0;
  select_lex->between_count= 0;

  for (table= tables; table; table= table->next_local)
  {
+1 −1
Original line number Diff line number Diff line
@@ -1138,7 +1138,7 @@ void st_select_lex::init_query()
    initialization is checked for failure.
  */
  parent_lex->push_context(&context);
  cond_count= with_wild= 0;
  cond_count= between_count= with_wild= 0;
  conds_processed_with_permanent_arena= 0;
  ref_pointer_array= 0;
  select_n_having_items= 0;
Loading