Commit 4c6692b7 authored by Sergey Vojtovich's avatar Sergey Vojtovich

Merge 5.1-bugteam -> 5.1-bugteam (local).

parents a1d1f1eb d325957f
......@@ -2025,7 +2025,6 @@ TABLE_SCHEMA = 'test' and TABLE_NAME='tm1';
TABLE_CATALOG TABLE_SCHEMA TABLE_NAME TABLE_TYPE ENGINE VERSION ROW_FORMAT TABLE_ROWS AVG_ROW_LENGTH DATA_LENGTH MAX_DATA_LENGTH INDEX_LENGTH DATA_FREE AUTO_INCREMENT CREATE_TIME UPDATE_TIME CHECK_TIME TABLE_COLLATION CHECKSUM CREATE_OPTIONS TABLE_COMMENT
NULL test tm1 BASE TABLE NULL NULL NULL # # # # # # # # # # NULL # # Unable to open underlying table which is differently defined or of non-MyISAM ty
DROP TABLE tm1;
End of 5.1 tests
CREATE TABLE t1(C1 INT, C2 INT, KEY C1(C1), KEY C2(C2)) ENGINE=MYISAM;
CREATE TABLE t2(C1 INT, C2 INT, KEY C1(C1), KEY C2(C2)) ENGINE=MYISAM;
CREATE TABLE t3(C1 INT, C2 INT, KEY C1(C1), KEY C2(C2)) ENGINE=MYISAM;
......@@ -2060,4 +2059,48 @@ SELECT CARDINALITY FROM INFORMATION_SCHEMA.STATISTICS WHERE TABLE_SCHEMA='test'
CARDINALITY
5
DROP TABLE t1, m1;
#
# Bug #40675 MySQL 5.1 crash with index merge algorithm and Merge tables
#
# create MYISAM table t1 and insert values into it
CREATE TABLE t1(a INT);
INSERT INTO t1 VALUES(1);
# create MYISAM table t2 and insert values into it
CREATE TABLE t2(a INT, b INT, dummy CHAR(16) DEFAULT '', KEY(a), KEY(b));
INSERT INTO t2(a,b) VALUES
(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),
(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),
(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),
(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),
(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),
(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),
(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),
(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),
(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),
(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),
(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),
(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),
(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),
(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),
(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),
(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),
(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),
(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),
(1,2);
# Create the merge table t3
CREATE TABLE t3(a INT, b INT, dummy CHAR(16) DEFAULT '', KEY(a), KEY(b))
ENGINE=MERGE UNION=(t2) INSERT_METHOD=FIRST;
# Lock tables t1 and t3 for write
LOCK TABLES t1 WRITE, t3 WRITE;
# Insert values into the merge table t3
INSERT INTO t3(a,b) VALUES(1,2);
# select from the join of t2 and t3 (The merge table)
SELECT t3.a FROM t1,t3 WHERE t3.b=2 AND t3.a=1;
a
1
1
# Unlock the tables
UNLOCK TABLES;
# drop the created tables
DROP TABLE t1, t2, t3;
End of 5.1 tests
......@@ -1418,8 +1418,6 @@ TABLE_SCHEMA = 'test' and TABLE_NAME='tm1';
DROP TABLE tm1;
--echo End of 5.1 tests
#
# Bug#36006 - Optimizer does table scan for select count(*)
#
......@@ -1448,4 +1446,54 @@ SELECT CARDINALITY FROM INFORMATION_SCHEMA.STATISTICS WHERE TABLE_SCHEMA='test'
SELECT CARDINALITY FROM INFORMATION_SCHEMA.STATISTICS WHERE TABLE_SCHEMA='test' AND TABLE_NAME='m1';
DROP TABLE t1, m1;
--echo #
--echo # Bug #40675 MySQL 5.1 crash with index merge algorithm and Merge tables
--echo #
--echo # create MYISAM table t1 and insert values into it
CREATE TABLE t1(a INT);
INSERT INTO t1 VALUES(1);
--echo # create MYISAM table t2 and insert values into it
CREATE TABLE t2(a INT, b INT, dummy CHAR(16) DEFAULT '', KEY(a), KEY(b));
INSERT INTO t2(a,b) VALUES
(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),
(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),
(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),
(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),
(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),
(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),
(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),
(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),
(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),
(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),
(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),
(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),
(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),
(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),
(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),
(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),
(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),
(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),
(1,2);
--echo # Create the merge table t3
CREATE TABLE t3(a INT, b INT, dummy CHAR(16) DEFAULT '', KEY(a), KEY(b))
ENGINE=MERGE UNION=(t2) INSERT_METHOD=FIRST;
--echo # Lock tables t1 and t3 for write
LOCK TABLES t1 WRITE, t3 WRITE;
--echo # Insert values into the merge table t3
INSERT INTO t3(a,b) VALUES(1,2);
--echo # select from the join of t2 and t3 (The merge table)
SELECT t3.a FROM t1,t3 WHERE t3.b=2 AND t3.a=1;
--echo # Unlock the tables
UNLOCK TABLES;
--echo # drop the created tables
DROP TABLE t1, t2, t3;
--echo End of 5.1 tests
......@@ -116,7 +116,7 @@ static handler *myisammrg_create_handler(handlerton *hton,
*/
ha_myisammrg::ha_myisammrg(handlerton *hton, TABLE_SHARE *table_arg)
:handler(hton, table_arg), file(0)
:handler(hton, table_arg), file(0), is_cloned(0)
{}
......@@ -413,7 +413,28 @@ int ha_myisammrg::open(const char *name, int mode __attribute__((unused)),
/* retrieve children table list. */
my_errno= 0;
if (!(file= myrg_parent_open(name, myisammrg_parent_open_callback, this)))
if (is_cloned)
{
/*
Open and attaches the MyISAM tables,that are under the MERGE table
parent, on the MyISAM storage engine interface directly within the
MERGE engine. The new MyISAM table instances, as well as the MERGE
clone itself, are not visible in the table cache. This is not a
problem because all locking is handled by the original MERGE table
from which this is cloned of.
*/
if (!(file= myrg_open(table->s->normalized_path.str, table->db_stat,
HA_OPEN_IGNORE_IF_LOCKED)))
{
DBUG_PRINT("error", ("my_errno %d", my_errno));
DBUG_RETURN(my_errno ? my_errno : -1);
}
file->children_attached= TRUE;
info(HA_STATUS_NO_LOCK | HA_STATUS_VARIABLE | HA_STATUS_CONST);
}
else if (!(file= myrg_parent_open(name, myisammrg_parent_open_callback, this)))
{
DBUG_PRINT("error", ("my_errno %d", my_errno));
DBUG_RETURN(my_errno ? my_errno : -1);
......@@ -422,6 +443,55 @@ int ha_myisammrg::open(const char *name, int mode __attribute__((unused)),
DBUG_RETURN(0);
}
/**
Returns a cloned instance of the current handler.
@return A cloned handler instance.
*/
handler *ha_myisammrg::clone(MEM_ROOT *mem_root)
{
MYRG_TABLE *u_table,*newu_table;
ha_myisammrg *new_handler=
(ha_myisammrg*) get_new_handler(table->s, mem_root, table->s->db_type());
if (!new_handler)
return NULL;
/* Inform ha_myisammrg::open() that it is a cloned handler */
new_handler->is_cloned= TRUE;
/*
Allocate handler->ref here because otherwise ha_open will allocate it
on this->table->mem_root and we will not be able to reclaim that memory
when the clone handler object is destroyed.
*/
if (!(new_handler->ref= (uchar*) alloc_root(mem_root, ALIGN_SIZE(ref_length)*2)))
{
delete new_handler;
return NULL;
}
if (new_handler->ha_open(table, table->s->normalized_path.str, table->db_stat,
HA_OPEN_IGNORE_IF_LOCKED))
{
delete new_handler;
return NULL;
}
/*
Iterate through the original child tables and
copy the state into the cloned child tables.
We need to do this because all the child tables
can be involved in delete.
*/
newu_table= new_handler->file->open_tables;
for (u_table= file->open_tables; u_table < file->end_table; u_table++)
{
newu_table->table->state= u_table->table->state;
newu_table++;
}
return new_handler;
}
/**
@brief Attach children to a MERGE table.
......@@ -613,9 +683,10 @@ int ha_myisammrg::close(void)
DBUG_ENTER("ha_myisammrg::close");
/*
Children must not be attached here. Unless the MERGE table has no
children. In this case children_attached is always true.
children or the handler instance has been cloned. In these cases
children_attached is always true.
*/
DBUG_ASSERT(!this->file->children_attached || !this->file->tables);
DBUG_ASSERT(!this->file->children_attached || !this->file->tables || this->is_cloned);
rc= myrg_close(file);
file= 0;
DBUG_RETURN(rc);
......
......@@ -25,6 +25,7 @@
class ha_myisammrg: public handler
{
MYRG_INFO *file;
my_bool is_cloned; /* This instance has been cloned */
public:
TABLE_LIST *next_child_attach; /* next child to attach */
......@@ -60,6 +61,7 @@ class ha_myisammrg: public handler
int open(const char *name, int mode, uint test_if_locked);
int attach_children(void);
int detach_children(void);
virtual handler *clone(MEM_ROOT *mem_root);
int close(void);
int write_row(uchar * buf);
int update_row(const uchar * old_data, uchar * new_data);
......
......@@ -33,7 +33,6 @@
myrg_attach_children(). Please duplicate changes in these
functions or make common sub-functions.
*/
/* purecov: begin deadcode */ /* not used in MySQL server */
MYRG_INFO *myrg_open(const char *name, int mode, int handle_locking)
{
......@@ -198,7 +197,6 @@ err:
my_errno=save_errno;
DBUG_RETURN (NULL);
}
/* purecov: end */
/**
......
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