Commit 209cfe77 authored by unknown's avatar unknown

Fixed unlikely bug in the range optimzer when using many IN() queries on...

Fixed unlikely bug in the range optimzer when using many IN() queries on different key parts. (Bug #4157)


mysql-test/r/range.result:
  Test of range optimizer bug
mysql-test/t/range.test:
  Test of range optimizer bug
sql/opt_range.cc:
  Fixed unlikely bug in the range optimzer when using many IN() queries on
  different key parts. (Bug #4157)
parent eefb240b
...@@ -314,3 +314,24 @@ a b ...@@ -314,3 +314,24 @@ a b
15 1 15 1
47 1 47 1
DROP TABLE t1; DROP TABLE t1;
CREATE TABLE t1 (
id int( 11 ) unsigned NOT NULL AUTO_INCREMENT ,
line int( 5 ) unsigned NOT NULL default '0',
columnid int( 3 ) unsigned NOT NULL default '0',
owner int( 3 ) unsigned NOT NULL default '0',
ordinal int( 3 ) unsigned NOT NULL default '0',
showid smallint( 6 ) unsigned NOT NULL default '1',
tableid int( 1 ) unsigned NOT NULL default '1',
content int( 5 ) unsigned NOT NULL default '188',
PRIMARY KEY ( owner, id ) ,
KEY menu( owner, showid, columnid ) ,
KEY `COLUMN` ( owner, columnid, line ) ,
KEY `LINES` ( owner, tableid, content, id ) ,
KEY recount( owner, line )
) ENGINE = MYISAM;
INSERT into t1 (owner,id,columnid,line) values (11,15,15,1),(11,13,13,5);
SELECT id, columnid, tableid, content, showid, line, ordinal FROM t1 WHERE owner=11 AND ((columnid IN ( 15, 13, 14 ) AND line IN ( 1, 2, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 31 )) OR (columnid IN ( 13, 14 ) AND line IN ( 15 ))) LIMIT 0 , 30;
id columnid tableid content showid line ordinal
13 13 1 188 1 5 0
15 15 1 188 1 1 0
drop table t1;
...@@ -264,3 +264,28 @@ WHERE ...@@ -264,3 +264,28 @@ WHERE
(a BETWEEN 19 AND 47) (a BETWEEN 19 AND 47)
); );
DROP TABLE t1; DROP TABLE t1;
#
# Test of problem with IN on many different keyparts. (Bug #4157)
#
CREATE TABLE t1 (
id int( 11 ) unsigned NOT NULL AUTO_INCREMENT ,
line int( 5 ) unsigned NOT NULL default '0',
columnid int( 3 ) unsigned NOT NULL default '0',
owner int( 3 ) unsigned NOT NULL default '0',
ordinal int( 3 ) unsigned NOT NULL default '0',
showid smallint( 6 ) unsigned NOT NULL default '1',
tableid int( 1 ) unsigned NOT NULL default '1',
content int( 5 ) unsigned NOT NULL default '188',
PRIMARY KEY ( owner, id ) ,
KEY menu( owner, showid, columnid ) ,
KEY `COLUMN` ( owner, columnid, line ) ,
KEY `LINES` ( owner, tableid, content, id ) ,
KEY recount( owner, line )
) ENGINE = MYISAM;
INSERT into t1 (owner,id,columnid,line) values (11,15,15,1),(11,13,13,5);
SELECT id, columnid, tableid, content, showid, line, ordinal FROM t1 WHERE owner=11 AND ((columnid IN ( 15, 13, 14 ) AND line IN ( 1, 2, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 31 )) OR (columnid IN ( 13, 14 ) AND line IN ( 15 ))) LIMIT 0 , 30;
drop table t1;
...@@ -1539,7 +1539,7 @@ key_or(SEL_ARG *key1,SEL_ARG *key2) ...@@ -1539,7 +1539,7 @@ key_or(SEL_ARG *key1,SEL_ARG *key2)
{ {
swap(SEL_ARG *,key1,key2); swap(SEL_ARG *,key1,key2);
} }
else if (!(key1=key1->clone_tree())) if (key1->use_count > 0 || !(key1=key1->clone_tree()))
return 0; // OOM return 0; // OOM
} }
...@@ -1608,10 +1608,10 @@ key_or(SEL_ARG *key1,SEL_ARG *key2) ...@@ -1608,10 +1608,10 @@ key_or(SEL_ARG *key1,SEL_ARG *key2)
SEL_ARG *next=key2->next; // Keys are not overlapping SEL_ARG *next=key2->next; // Keys are not overlapping
if (key2_shared) if (key2_shared)
{ {
SEL_ARG *tmp= new SEL_ARG(*key2); // Must make copy SEL_ARG *cpy= new SEL_ARG(*key2); // Must make copy
if (!tmp) if (!cpy)
return 0; // OOM return 0; // OOM
key1=key1->insert(tmp); key1=key1->insert(cpy);
key2->increment_use_count(key1->use_count+1); key2->increment_use_count(key1->use_count+1);
} }
else else
...@@ -1847,8 +1847,17 @@ SEL_ARG::find_range(SEL_ARG *key) ...@@ -1847,8 +1847,17 @@ SEL_ARG::find_range(SEL_ARG *key)
/* /*
** Remove a element from the tree Remove a element from the tree
** This also frees all sub trees that is used by the element
SYNOPSIS
tree_delete()
key Key that is to be deleted from tree (this)
NOTE
This also frees all sub trees that is used by the element
RETURN
root of new tree (with key deleted)
*/ */
SEL_ARG * SEL_ARG *
...@@ -1856,7 +1865,10 @@ SEL_ARG::tree_delete(SEL_ARG *key) ...@@ -1856,7 +1865,10 @@ SEL_ARG::tree_delete(SEL_ARG *key)
{ {
enum leaf_color remove_color; enum leaf_color remove_color;
SEL_ARG *root,*nod,**par,*fix_par; SEL_ARG *root,*nod,**par,*fix_par;
root=this; this->parent= 0; DBUG_ENTER("tree_delete");
root=this;
this->parent= 0;
/* Unlink from list */ /* Unlink from list */
if (key->prev) if (key->prev)
...@@ -1903,7 +1915,7 @@ SEL_ARG::tree_delete(SEL_ARG *key) ...@@ -1903,7 +1915,7 @@ SEL_ARG::tree_delete(SEL_ARG *key)
} }
if (root == &null_element) if (root == &null_element)
return 0; // Maybe root later DBUG_RETURN(0); // Maybe root later
if (remove_color == BLACK) if (remove_color == BLACK)
root=rb_delete_fixup(root,nod,fix_par); root=rb_delete_fixup(root,nod,fix_par);
test_rb_tree(root,root->parent); test_rb_tree(root,root->parent);
...@@ -1911,7 +1923,7 @@ SEL_ARG::tree_delete(SEL_ARG *key) ...@@ -1911,7 +1923,7 @@ SEL_ARG::tree_delete(SEL_ARG *key)
root->use_count=this->use_count; // Fix root counters root->use_count=this->use_count; // Fix root counters
root->elements=this->elements-1; root->elements=this->elements-1;
root->maybe_flag=this->maybe_flag; root->maybe_flag=this->maybe_flag;
return root; DBUG_RETURN(root);
} }
......
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