Commit ef15a335 authored by Konstantin Osipov's avatar Konstantin Osipov

Backport of:

----------------------------------------------------------
revno: 2630.4.38
committer: Konstantin Osipov <konstantin@mysql.com>
branch nick: mysql-6.0-4144
timestamp: Wed 2008-06-25 22:07:06 +0400
message:
  WL#4144 - Lock MERGE engine children.
  Committing a version of the patch merged with WL#3726
  on behalf of Ingo.

  Step #1: Move locking from parent to children.

  MERGE children are now left in the query list of tables
  after inserted there in open_tables(). So they are locked
  by lock_tables() as all other tables are.

  The MERGE parent does not store locks any more. It appears
  in a MYSQL_LOCK with zero lock data. This is kind of a "dummy"
  lock.

  All other lock handling is also done directly on the children.
  To protect against parent or child modifications during LOCK
  TABLES, the children are detached after every statement and
  attached before every statement, even under LOCK TABLES.

  The children table list is removed from the query list of tables
  on every detach and on close of the parent.

  Step #2: Move MERGE specific functionality from SQL layer
  into table handler.

  Functionality moved from SQL layer (mainly sql_base.cc)
  to the table handler (ha_myisammrg.cc).

  Unnecessary code is removed from the SQL layer.

  Step #3: Moved all MERGE specific members from TABLE
  to ha_myisammrg.

  Moved members from TABLE to ha_myisammrg.
  Renamed some mebers.
  Fixed comments.

  Step #4: Valgrind and coverage testing

  Valgrind did not uncover new problems.
  Added purecov comments.

  Added a new test for DATA/INDEX DIRECTORY options.
  Changed handling of ::reset() for non-attached children.
  Fixed the merge-big test.

  Step #5: Fixed crashes detected during review
  Changed detection when to attach/detach.
  Added new tests.

Backport also the fix for Bug#44040 "MySQL allows creating a 
MERGE table upon VIEWs but crashes when using it"
parent f744a841
...@@ -191,10 +191,11 @@ enum ha_extra_function { ...@@ -191,10 +191,11 @@ enum ha_extra_function {
/* Inform handler that we will do a rename */ /* Inform handler that we will do a rename */
HA_EXTRA_PREPARE_FOR_RENAME, HA_EXTRA_PREPARE_FOR_RENAME,
/* /*
Orders MERGE handler to attach or detach its child tables. Used at Special actions for MERGE tables.
begin and end of a statement.
*/ */
HA_EXTRA_ADD_CHILDREN_LIST,
HA_EXTRA_ATTACH_CHILDREN, HA_EXTRA_ATTACH_CHILDREN,
HA_EXTRA_IS_ATTACHED_CHILDREN,
HA_EXTRA_DETACH_CHILDREN HA_EXTRA_DETACH_CHILDREN
}; };
......
...@@ -578,23 +578,23 @@ select max(b) from t1 where a = 2; ...@@ -578,23 +578,23 @@ select max(b) from t1 where a = 2;
max(b) max(b)
1 1
drop table t3,t1,t2; drop table t3,t1,t2;
create table t1 (a int not null); CREATE TABLE t1 (c1 INT NOT NULL);
create table t2 (a int not null); CREATE TABLE t2 (c1 INT NOT NULL);
insert into t1 values (1); INSERT INTO t1 VALUES (1);
insert into t2 values (2); INSERT INTO t2 VALUES (2);
create temporary table t3 (a int not null) ENGINE=MERGE UNION=(t1,t2); CREATE TEMPORARY TABLE t3 (c1 INT NOT NULL) ENGINE=MRG_MYISAM UNION=(t1,t2);
select * from t3; SELECT * FROM t3;
ERROR HY000: Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist ERROR HY000: Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist
create temporary table t4 (a int not null); CREATE TEMPORARY TABLE t4 (c1 INT NOT NULL);
create temporary table t5 (a int not null); CREATE TEMPORARY TABLE t5 (c1 INT NOT NULL);
insert into t4 values (1); INSERT INTO t4 VALUES (4);
insert into t5 values (2); INSERT INTO t5 VALUES (5);
create temporary table t6 (a int not null) ENGINE=MERGE UNION=(t4,t5); CREATE TEMPORARY TABLE t6 (c1 INT NOT NULL) ENGINE=MRG_MYISAM UNION=(t4,t5);
select * from t6; SELECT * FROM t6;
a c1
1 4
2 5
drop table t6, t3, t1, t2, t4, t5; DROP TABLE t6, t3, t1, t2, t4, t5;
create temporary table t1 (a int not null); create temporary table t1 (a int not null);
create temporary table t2 (a int not null); create temporary table t2 (a int not null);
insert into t1 values (1); insert into t1 values (1);
...@@ -1258,7 +1258,7 @@ c1 ...@@ -1258,7 +1258,7 @@ c1
LOCK TABLES t1 WRITE, t2 WRITE, t3 WRITE; LOCK TABLES t1 WRITE, t2 WRITE, t3 WRITE;
ALTER TABLE t2 RENAME TO t5; ALTER TABLE t2 RENAME TO t5;
SELECT * FROM t3 ORDER BY c1; SELECT * FROM t3 ORDER BY c1;
ERROR HY000: Table 't3' was not locked with LOCK TABLES ERROR HY000: Table 't2' was not locked with LOCK TABLES
ALTER TABLE t5 RENAME TO t2; ALTER TABLE t5 RENAME TO t2;
ERROR HY000: Table 't5' was not locked with LOCK TABLES ERROR HY000: Table 't5' was not locked with LOCK TABLES
UNLOCK TABLES; UNLOCK TABLES;
...@@ -1330,9 +1330,9 @@ LOCK TABLES t1 WRITE, t2 WRITE; ...@@ -1330,9 +1330,9 @@ LOCK TABLES t1 WRITE, t2 WRITE;
INSERT INTO t1 VALUES (1); INSERT INTO t1 VALUES (1);
DROP TABLE t1; DROP TABLE t1;
SELECT * FROM t2; SELECT * FROM t2;
ERROR HY000: Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist ERROR HY000: Table 't1' was not locked with LOCK TABLES
SELECT * FROM t1; SELECT * FROM t1;
ERROR 42S02: Table 'test.t1' doesn't exist ERROR HY000: Table 't1' was not locked with LOCK TABLES
UNLOCK TABLES; UNLOCK TABLES;
DROP TABLE t2; DROP TABLE t2;
# #
...@@ -2256,3 +2256,250 @@ deallocate prepare stmt; ...@@ -2256,3 +2256,250 @@ deallocate prepare stmt;
# #
drop table t_parent; drop table t_parent;
set @@global.table_definition_cache=@save_table_definition_cache; set @@global.table_definition_cache=@save_table_definition_cache;
DROP DATABASE IF EXISTS mysql_test1;
CREATE DATABASE mysql_test1;
CREATE TABLE t1 ... DATA DIRECTORY=... INDEX DIRECTORY=...
CREATE TABLE mysql_test1.t2 ... DATA DIRECTORY=... INDEX DIRECTORY=...
CREATE TABLE m1 (c1 INT) ENGINE=MRG_MYISAM UNION=(t1,mysql_test1.t2)
INSERT_METHOD=LAST;
INSERT INTO t1 VALUES (1);
INSERT INTO mysql_test1.t2 VALUES (2);
SELECT * FROM m1;
c1
1
2
DROP TABLE t1, mysql_test1.t2, m1;
DROP DATABASE mysql_test1;
CREATE TABLE t1 (c1 INT);
CREATE TABLE t2 (c1 INT);
INSERT INTO t1 (c1) VALUES (1);
CREATE TABLE tm1 (c1 INT) ENGINE=MRG_MYISAM UNION=(t1,t2) INSERT_METHOD=FIRST;
CREATE TABLE t3 (c1 INT);
INSERT INTO t3 (c1) VALUES (1);
CREATE FUNCTION f1() RETURNS INT RETURN (SELECT MAX(c1) FROM t3);
CREATE VIEW v1 AS SELECT foo.c1 c1, f1() c2, bar.c1 c3, f1() c4
FROM tm1 foo, tm1 bar, t3;
SELECT * FROM v1;
c1 c2 c3 c4
1 1 1 1
DROP FUNCTION f1;
DROP VIEW v1;
DROP TABLE tm1, t1, t2, t3;
CREATE TEMPORARY TABLE t1 (c1 INT);
CREATE TEMPORARY TABLE t2 (c1 INT);
CREATE TEMPORARY TABLE tm1 (c1 INT) ENGINE=MRG_MYISAM UNION=(t1,t2)
INSERT_METHOD=FIRST;
CREATE FUNCTION f1() RETURNS INT RETURN (SELECT MAX(c1) FROM tm1);
INSERT INTO tm1 (c1) VALUES (1);
SELECT f1() FROM (SELECT 1) AS c1;
f1()
1
DROP FUNCTION f1;
DROP TABLE tm1, t1, t2;
CREATE FUNCTION f1() RETURNS INT
BEGIN
CREATE TEMPORARY TABLE t1 (c1 INT);
CREATE TEMPORARY TABLE t2 (c1 INT);
CREATE TEMPORARY TABLE tm1 (c1 INT) ENGINE=MRG_MYISAM UNION=(t1,t2);
INSERT INTO t1 (c1) VALUES (1);
RETURN (SELECT MAX(c1) FROM tm1);
END|
SELECT f1() FROM (SELECT 1 UNION SELECT 1) c1;
f1()
1
DROP FUNCTION f1;
DROP TABLE tm1, t1, t2;
CREATE TEMPORARY TABLE t1 (c1 INT);
INSERT INTO t1 (c1) VALUES (1);
CREATE TEMPORARY TABLE tm1 (c1 INT) ENGINE=MRG_MYISAM UNION=(t1);
CREATE FUNCTION f1() RETURNS INT
BEGIN
CREATE TEMPORARY TABLE t2 (c1 INT);
ALTER TEMPORARY TABLE tm1 UNION=(t1,t2);
INSERT INTO t2 (c1) VALUES (2);
RETURN (SELECT MAX(c1) FROM tm1);
END|
ERROR 0A000: ALTER VIEW is not allowed in stored procedures
DROP TABLE tm1, t1;
CREATE TABLE t1 (c1 INT) ENGINE=MyISAM;
CREATE TABLE tm1 (c1 INT) ENGINE=MRG_MYISAM UNION=(t1) INSERT_METHOD=LAST;
INSERT INTO tm1 VALUES (1);
SELECT * FROM tm1;
c1
1
DROP TABLE tm1, t1;
CREATE FUNCTION f1() RETURNS INT
BEGIN
INSERT INTO tm1 VALUES (1);
RETURN (SELECT MAX(c1) FROM tm1);
END|
CREATE TABLE t1 (c1 INT) ENGINE=MyISAM;
CREATE TABLE tm1 (c1 INT) ENGINE=MRG_MYISAM UNION=(t1) INSERT_METHOD=LAST;
SELECT f1();
f1()
1
DROP FUNCTION f1;
DROP TABLE tm1, t1;
CREATE TABLE t1 (c1 INT) ENGINE=MyISAM;
CREATE TABLE tm1 (c1 INT) ENGINE=MRG_MYISAM UNION=(t1) INSERT_METHOD=LAST;
LOCK TABLE tm1 WRITE;
INSERT INTO tm1 VALUES (1);
SELECT * FROM tm1;
c1
1
UNLOCK TABLES;
DROP TABLE tm1, t1;
CREATE FUNCTION f1() RETURNS INT
BEGIN
INSERT INTO tm1 VALUES (1);
RETURN (SELECT MAX(c1) FROM tm1);
END|
CREATE TABLE t1 (c1 INT) ENGINE=MyISAM;
CREATE TABLE tm1 (c1 INT) ENGINE=MRG_MYISAM UNION=(t1) INSERT_METHOD=LAST;
LOCK TABLE tm1 WRITE;
SELECT f1();
f1()
1
UNLOCK TABLES;
DROP FUNCTION f1;
DROP TABLE tm1, t1;
CREATE TABLE t1 (c1 INT) ENGINE=MyISAM;
CREATE TABLE t2 (c1 INT) ENGINE=MyISAM;
CREATE TABLE tm1 (c1 INT) ENGINE=MRG_MYISAM UNION=(t1) INSERT_METHOD=LAST;
CREATE TRIGGER t2_ai AFTER INSERT ON t2
FOR EACH ROW INSERT INTO tm1 VALUES(11);
LOCK TABLE t2 WRITE;
INSERT INTO t2 VALUES (2);
SELECT * FROM tm1;
c1
11
SELECT * FROM t2;
c1
2
UNLOCK TABLES;
DROP TRIGGER t2_ai;
DROP TABLE tm1, t1, t2;
CREATE TEMPORARY TABLE t1 (c1 INT) ENGINE=MyISAM;
CREATE TEMPORARY TABLE tm1 (c1 INT) ENGINE=MRG_MYISAM UNION=(t1)
INSERT_METHOD=LAST;
INSERT INTO tm1 VALUES (1);
SELECT * FROM tm1;
c1
1
DROP TABLE tm1, t1;
CREATE FUNCTION f1() RETURNS INT
BEGIN
INSERT INTO tm1 VALUES (1);
RETURN (SELECT MAX(c1) FROM tm1);
END|
CREATE TEMPORARY TABLE t1 (c1 INT) ENGINE=MyISAM;
CREATE TEMPORARY TABLE tm1 (c1 INT) ENGINE=MRG_MYISAM UNION=(t1)
INSERT_METHOD=LAST;
SELECT f1();
f1()
1
DROP FUNCTION f1;
DROP TABLE tm1, t1;
CREATE TEMPORARY TABLE t1 (c1 INT) ENGINE=MyISAM;
CREATE TEMPORARY TABLE tm1 (c1 INT) ENGINE=MRG_MYISAM UNION=(t1)
INSERT_METHOD=LAST;
CREATE TABLE t9 (c1 INT) ENGINE=MyISAM;
LOCK TABLE t9 WRITE;
INSERT INTO tm1 VALUES (1);
SELECT * FROM tm1;
c1
1
UNLOCK TABLES;
DROP TABLE tm1, t1, t9;
CREATE FUNCTION f1() RETURNS INT
BEGIN
INSERT INTO tm1 VALUES (1);
RETURN (SELECT MAX(c1) FROM tm1);
END|
CREATE TEMPORARY TABLE t1 (c1 INT) ENGINE=MyISAM;
CREATE TEMPORARY TABLE tm1 (c1 INT) ENGINE=MRG_MYISAM UNION=(t1)
INSERT_METHOD=LAST;
CREATE TABLE t9 (c1 INT) ENGINE=MyISAM;
LOCK TABLE t9 WRITE;
SELECT f1();
f1()
1
UNLOCK TABLES;
DROP FUNCTION f1;
DROP TABLE tm1, t1, t9;
CREATE TEMPORARY TABLE t1 (c1 INT) ENGINE=MyISAM;
CREATE TEMPORARY TABLE tm1 (c1 INT) ENGINE=MRG_MYISAM UNION=(t1)
INSERT_METHOD=LAST;
CREATE TABLE t2 (c1 INT) ENGINE=MyISAM;
CREATE TRIGGER t2_ai AFTER INSERT ON t2
FOR EACH ROW INSERT INTO tm1 VALUES(11);
LOCK TABLE t2 WRITE;
INSERT INTO t2 VALUES (2);
SELECT * FROM tm1;
c1
11
SELECT * FROM t2;
c1
2
UNLOCK TABLES;
DROP TRIGGER t2_ai;
DROP TABLE tm1, t1, t2;
#
# Don't select MERGE child when trying to get prelocked table.
#
CREATE TABLE t1 (c1 INT) ENGINE=MyISAM;
CREATE TABLE tm1 (c1 INT) ENGINE=MRG_MYISAM UNION=(t1)
INSERT_METHOD=LAST;
CREATE TRIGGER tm1_ai AFTER INSERT ON tm1
FOR EACH ROW INSERT INTO t1 VALUES(11);
LOCK TABLE tm1 WRITE, t1 WRITE;
INSERT INTO tm1 VALUES (1);
SELECT * FROM tm1;
c1
1
11
UNLOCK TABLES;
LOCK TABLE t1 WRITE, tm1 WRITE;
INSERT INTO tm1 VALUES (1);
SELECT * FROM tm1;
c1
1
11
1
11
UNLOCK TABLES;
DROP TRIGGER tm1_ai;
DROP TABLE tm1, t1;
CREATE TABLE t1 (c1 INT) ENGINE=MyISAM;
CREATE TABLE t2 (c1 INT) ENGINE=MyISAM;
CREATE TABLE t3 (c1 INT) ENGINE=MyISAM;
CREATE TABLE t4 (c1 INT) ENGINE=MyISAM;
CREATE TABLE t5 (c1 INT) ENGINE=MyISAM;
CREATE TABLE tm1 (c1 INT) ENGINE=MRG_MYISAM UNION=(t1,t2,t3,t4,t5)
INSERT_METHOD=LAST;
CREATE TRIGGER t2_au AFTER UPDATE ON t2
FOR EACH ROW INSERT INTO t3 VALUES(33);
CREATE FUNCTION f1() RETURNS INT
RETURN (SELECT MAX(c1) FROM t4);
LOCK TABLE tm1 WRITE, t1 WRITE, t2 WRITE, t3 WRITE, t4 WRITE, t5 WRITE;
INSERT INTO t1 VALUES(1);
INSERT INTO t2 VALUES(2);
INSERT INTO t3 VALUES(3);
INSERT INTO t4 VALUES(4);
INSERT INTO t5 VALUES(5);
UPDATE t2, tm1 SET t2.c1=f1();
FLUSH TABLES;
FLUSH TABLES;
UNLOCK TABLES;
SELECT * FROM tm1;
c1
1
4
3
33
4
5
DROP TRIGGER t2_au;
DROP FUNCTION f1;
DROP TABLE tm1, t1, t2, t3, t4, t5;
End of 6.0 tests
...@@ -15,4 +15,3 @@ partition_innodb_builtin : Bug#32430 2009-09-25 mattiasj Waiting for push of Inn ...@@ -15,4 +15,3 @@ partition_innodb_builtin : Bug#32430 2009-09-25 mattiasj Waiting for push of Inn
partition_innodb_plugin : Bug#32430 2009-09-25 mattiasj Waiting for push of Innodb changes partition_innodb_plugin : Bug#32430 2009-09-25 mattiasj Waiting for push of Innodb changes
innodb-autoinc : Bug#48482 2009-11-02 svoj innodb-autoinc.test fails with results difference innodb-autoinc : Bug#48482 2009-11-02 svoj innodb-autoinc.test fails with results difference
rpl_killed_ddl : Bug#45520: rpl_killed_ddl fails sporadically in pb2 rpl_killed_ddl : Bug#45520: rpl_killed_ddl fails sporadically in pb2
merge : WL#4144
...@@ -51,7 +51,7 @@ connection default; ...@@ -51,7 +51,7 @@ connection default;
#--sleep 8 #--sleep 8
#SELECT ID,STATE,INFO FROM INFORMATION_SCHEMA.PROCESSLIST; #SELECT ID,STATE,INFO FROM INFORMATION_SCHEMA.PROCESSLIST;
let $wait_condition= SELECT 1 FROM INFORMATION_SCHEMA.PROCESSLIST let $wait_condition= SELECT 1 FROM INFORMATION_SCHEMA.PROCESSLIST
WHERE ID = $con1_id AND STATE = 'Locked'; WHERE ID = $con1_id AND STATE = 'Table lock';
--source include/wait_condition.inc --source include/wait_condition.inc
#SELECT NOW(); #SELECT NOW();
--echo # Kick INSERT out of thr_multi_lock(). --echo # Kick INSERT out of thr_multi_lock().
...@@ -61,7 +61,7 @@ FLUSH TABLES; ...@@ -61,7 +61,7 @@ FLUSH TABLES;
#--sleep 8 #--sleep 8
#SELECT ID,STATE,INFO FROM INFORMATION_SCHEMA.PROCESSLIST; #SELECT ID,STATE,INFO FROM INFORMATION_SCHEMA.PROCESSLIST;
let $wait_condition= SELECT 1 FROM INFORMATION_SCHEMA.PROCESSLIST let $wait_condition= SELECT 1 FROM INFORMATION_SCHEMA.PROCESSLIST
WHERE ID = $con1_id AND STATE = 'Waiting for table'; WHERE ID = $con1_id AND STATE = 'Table lock';
--source include/wait_condition.inc --source include/wait_condition.inc
#SELECT NOW(); #SELECT NOW();
--echo # Unlock and close table and wait for con1 to close too. --echo # Unlock and close table and wait for con1 to close too.
......
This diff is collapsed.
...@@ -631,6 +631,7 @@ thr_lock(THR_LOCK_DATA *data, THR_LOCK_OWNER *owner, ...@@ -631,6 +631,7 @@ thr_lock(THR_LOCK_DATA *data, THR_LOCK_OWNER *owner,
{ {
if (lock->write.data->type == TL_WRITE_ONLY) if (lock->write.data->type == TL_WRITE_ONLY)
{ {
/* purecov: begin tested */
/* Allow lock owner to bypass TL_WRITE_ONLY. */ /* Allow lock owner to bypass TL_WRITE_ONLY. */
if (!thr_lock_owner_equal(data->owner, lock->write.data->owner)) if (!thr_lock_owner_equal(data->owner, lock->write.data->owner))
{ {
...@@ -639,6 +640,7 @@ thr_lock(THR_LOCK_DATA *data, THR_LOCK_OWNER *owner, ...@@ -639,6 +640,7 @@ thr_lock(THR_LOCK_DATA *data, THR_LOCK_OWNER *owner,
result= THR_LOCK_ABORTED; /* Can't wait for this one */ result= THR_LOCK_ABORTED; /* Can't wait for this one */
goto end; goto end;
} }
/* purecov: end */
} }
/* /*
......
...@@ -5265,34 +5265,35 @@ void ha_partition::get_dynamic_partition_info(PARTITION_INFO *stat_info, ...@@ -5265,34 +5265,35 @@ void ha_partition::get_dynamic_partition_info(PARTITION_INFO *stat_info,
} }
/* /**
General function to prepare handler for certain behavior General function to prepare handler for certain behavior.
SYNOPSIS @param[in] operation operation to execute
extra()
operation Operation type for extra call operation Operation type for extra call
RETURN VALUE @return status
>0 Error code @retval 0 success
0 Success @retval >0 error code
@detail
DESCRIPTION
extra() is called whenever the server wishes to send a hint to extra() is called whenever the server wishes to send a hint to
the storage engine. The MyISAM engine implements the most hints. the storage engine. The MyISAM engine implements the most hints.
We divide the parameters into the following categories: We divide the parameters into the following categories:
1) Parameters used by most handlers 1) Operations used by most handlers
2) Parameters used by some non-MyISAM handlers 2) Operations used by some non-MyISAM handlers
3) Parameters used only by MyISAM 3) Operations used only by MyISAM
4) Parameters only used by temporary tables for query processing 4) Operations only used by temporary tables for query processing
5) Parameters only used by MyISAM internally 5) Operations only used by MyISAM internally
6) Parameters not used at all 6) Operations not used at all
7) Parameters only used by federated tables for query processing 7) Operations only used by federated tables for query processing
8) Parameters only used by NDB 8) Operations only used by NDB
9) Operations only used by MERGE
The partition handler need to handle category 1), 2) and 3). The partition handler need to handle category 1), 2) and 3).
1) Parameters used by most handlers 1) Operations used by most handlers
----------------------------------- -----------------------------------
HA_EXTRA_RESET: HA_EXTRA_RESET:
This option is used by most handlers and it resets the handler state This option is used by most handlers and it resets the handler state
...@@ -5331,7 +5332,7 @@ void ha_partition::get_dynamic_partition_info(PARTITION_INFO *stat_info, ...@@ -5331,7 +5332,7 @@ void ha_partition::get_dynamic_partition_info(PARTITION_INFO *stat_info,
ensure disk based tables are flushed at end of query execution. ensure disk based tables are flushed at end of query execution.
Currently is never used. Currently is never used.
2) Parameters used by some non-MyISAM handlers 2) Operations used by some non-MyISAM handlers
---------------------------------------------- ----------------------------------------------
HA_EXTRA_KEYREAD_PRESERVE_FIELDS: HA_EXTRA_KEYREAD_PRESERVE_FIELDS:
This is a strictly InnoDB feature that is more or less undocumented. This is a strictly InnoDB feature that is more or less undocumented.
...@@ -5350,7 +5351,7 @@ void ha_partition::get_dynamic_partition_info(PARTITION_INFO *stat_info, ...@@ -5350,7 +5351,7 @@ void ha_partition::get_dynamic_partition_info(PARTITION_INFO *stat_info,
SQL constructs. SQL constructs.
Not used by MyISAM. Not used by MyISAM.
3) Parameters used only by MyISAM 3) Operations used only by MyISAM
--------------------------------- ---------------------------------
HA_EXTRA_NORMAL: HA_EXTRA_NORMAL:
Only used in MyISAM to reset quick mode, not implemented by any other Only used in MyISAM to reset quick mode, not implemented by any other
...@@ -5481,7 +5482,7 @@ void ha_partition::get_dynamic_partition_info(PARTITION_INFO *stat_info, ...@@ -5481,7 +5482,7 @@ void ha_partition::get_dynamic_partition_info(PARTITION_INFO *stat_info,
Only used by MyISAM, called when altering table, closing tables to Only used by MyISAM, called when altering table, closing tables to
enforce a reopen of the table files. enforce a reopen of the table files.
4) Parameters only used by temporary tables for query processing 4) Operations only used by temporary tables for query processing
---------------------------------------------------------------- ----------------------------------------------------------------
HA_EXTRA_RESET_STATE: HA_EXTRA_RESET_STATE:
Same as reset() except that buffers are not released. If there is Same as reset() except that buffers are not released. If there is
...@@ -5512,7 +5513,7 @@ void ha_partition::get_dynamic_partition_info(PARTITION_INFO *stat_info, ...@@ -5512,7 +5513,7 @@ void ha_partition::get_dynamic_partition_info(PARTITION_INFO *stat_info,
tables used in query processing. tables used in query processing.
Not handled by partition handler. Not handled by partition handler.
5) Parameters only used by MyISAM internally 5) Operations only used by MyISAM internally
-------------------------------------------- --------------------------------------------
HA_EXTRA_REINIT_CACHE: HA_EXTRA_REINIT_CACHE:
This call reinitializes the READ CACHE described above if there is one This call reinitializes the READ CACHE described above if there is one
...@@ -5547,19 +5548,19 @@ void ha_partition::get_dynamic_partition_info(PARTITION_INFO *stat_info, ...@@ -5547,19 +5548,19 @@ void ha_partition::get_dynamic_partition_info(PARTITION_INFO *stat_info,
HA_EXTRA_CHANGE_KEY_TO_UNIQUE: HA_EXTRA_CHANGE_KEY_TO_UNIQUE:
Only used by MyISAM, never called. Only used by MyISAM, never called.
6) Parameters not used at all 6) Operations not used at all
----------------------------- -----------------------------
HA_EXTRA_KEY_CACHE: HA_EXTRA_KEY_CACHE:
HA_EXTRA_NO_KEY_CACHE: HA_EXTRA_NO_KEY_CACHE:
This parameters are no longer used and could be removed. This parameters are no longer used and could be removed.
7) Parameters only used by federated tables for query processing 7) Operations only used by federated tables for query processing
---------------------------------------------------------------- ----------------------------------------------------------------
HA_EXTRA_INSERT_WITH_UPDATE: HA_EXTRA_INSERT_WITH_UPDATE:
Inform handler that an "INSERT...ON DUPLICATE KEY UPDATE" will be Inform handler that an "INSERT...ON DUPLICATE KEY UPDATE" will be
executed. This condition is unset by HA_EXTRA_NO_IGNORE_DUP_KEY. executed. This condition is unset by HA_EXTRA_NO_IGNORE_DUP_KEY.
8) Parameters only used by NDB 8) Operations only used by NDB
------------------------------ ------------------------------
HA_EXTRA_DELETE_CANNOT_BATCH: HA_EXTRA_DELETE_CANNOT_BATCH:
HA_EXTRA_UPDATE_CANNOT_BATCH: HA_EXTRA_UPDATE_CANNOT_BATCH:
...@@ -5567,6 +5568,14 @@ void ha_partition::get_dynamic_partition_info(PARTITION_INFO *stat_info, ...@@ -5567,6 +5568,14 @@ void ha_partition::get_dynamic_partition_info(PARTITION_INFO *stat_info,
and should perform them immediately. This may be needed when table has and should perform them immediately. This may be needed when table has
AFTER DELETE/UPDATE triggers which access to subject table. AFTER DELETE/UPDATE triggers which access to subject table.
These flags are reset by the handler::extra(HA_EXTRA_RESET) call. These flags are reset by the handler::extra(HA_EXTRA_RESET) call.
9) Operations only used by MERGE
------------------------------
HA_EXTRA_ADD_CHILDREN_LIST:
HA_EXTRA_ATTACH_CHILDREN:
HA_EXTRA_IS_ATTACHED_CHILDREN:
HA_EXTRA_DETACH_CHILDREN:
Special actions for MERGE tables. Ignore.
*/ */
int ha_partition::extra(enum ha_extra_function operation) int ha_partition::extra(enum ha_extra_function operation)
...@@ -5659,12 +5668,21 @@ int ha_partition::extra(enum ha_extra_function operation) ...@@ -5659,12 +5668,21 @@ int ha_partition::extra(enum ha_extra_function operation)
/* Category 7), used by federated handlers */ /* Category 7), used by federated handlers */
case HA_EXTRA_INSERT_WITH_UPDATE: case HA_EXTRA_INSERT_WITH_UPDATE:
DBUG_RETURN(loop_extra(operation)); DBUG_RETURN(loop_extra(operation));
/* Category 8) Parameters only used by NDB */ /* Category 8) Operations only used by NDB */
case HA_EXTRA_DELETE_CANNOT_BATCH: case HA_EXTRA_DELETE_CANNOT_BATCH:
case HA_EXTRA_UPDATE_CANNOT_BATCH: case HA_EXTRA_UPDATE_CANNOT_BATCH:
{ {
/* Currently only NDB use the *_CANNOT_BATCH */ /* Currently only NDB use the *_CANNOT_BATCH */
break; break;
}
/* Category 9) Operations only used by MERGE */
case HA_EXTRA_ADD_CHILDREN_LIST:
case HA_EXTRA_ATTACH_CHILDREN:
case HA_EXTRA_IS_ATTACHED_CHILDREN:
case HA_EXTRA_DETACH_CHILDREN:
{
/* Special actions for MERGE tables. Ignore. */
break;
} }
/* /*
http://dev.mysql.com/doc/refman/5.1/en/partitioning-limitations.html http://dev.mysql.com/doc/refman/5.1/en/partitioning-limitations.html
......
...@@ -1228,9 +1228,6 @@ bool tdc_open_view(THD *thd, TABLE_LIST *table_list, const char *alias, ...@@ -1228,9 +1228,6 @@ bool tdc_open_view(THD *thd, TABLE_LIST *table_list, const char *alias,
TABLE *find_locked_table(TABLE *list, const char *db, const char *table_name); TABLE *find_locked_table(TABLE *list, const char *db, const char *table_name);
TABLE *find_write_locked_table(TABLE *list, const char *db, TABLE *find_write_locked_table(TABLE *list, const char *db,
const char *table_name); const char *table_name);
void detach_merge_children(TABLE *table, bool clear_refs);
bool fix_merge_after_open(TABLE_LIST *old_child_list, TABLE_LIST **old_last,
TABLE_LIST *new_child_list, TABLE_LIST **new_last);
thr_lock_type read_lock_type_for_table(THD *thd, TABLE *table); thr_lock_type read_lock_type_for_table(THD *thd, TABLE *table);
void execute_init_command(THD *thd, sys_var_str *init_command_var, void execute_init_command(THD *thd, sys_var_str *init_command_var,
rw_lock_t *var_mutex); rw_lock_t *var_mutex);
......
This diff is collapsed.
...@@ -4396,7 +4396,8 @@ static int prepare_for_restore(THD* thd, TABLE_LIST* table, ...@@ -4396,7 +4396,8 @@ static int prepare_for_restore(THD* thd, TABLE_LIST* table,
"Failed to open partially restored table")); "Failed to open partially restored table"));
} }
/* A MERGE table must not come here. */ /* A MERGE table must not come here. */
DBUG_ASSERT(!table->table || !table->table->child_l); DBUG_ASSERT(!table->table ||
table->table->file->ht->db_type != DB_TYPE_MRG_MYISAM);
DBUG_RETURN(0); DBUG_RETURN(0);
} }
...@@ -4463,7 +4464,7 @@ static int prepare_for_repair(THD *thd, TABLE_LIST *table_list, ...@@ -4463,7 +4464,7 @@ static int prepare_for_repair(THD *thd, TABLE_LIST *table_list,
} }
/* A MERGE table must not come here. */ /* A MERGE table must not come here. */
DBUG_ASSERT(!table->child_l); DBUG_ASSERT(table->file->ht->db_type != DB_TYPE_MRG_MYISAM);
/* /*
REPAIR TABLE ... USE_FRM for temporary tables makes little sense. REPAIR TABLE ... USE_FRM for temporary tables makes little sense.
...@@ -7270,7 +7271,8 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, ...@@ -7270,7 +7271,8 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
} }
else else
{ {
if (wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN)) if (!table->s->tmp_table &&
wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN))
goto err_new_table_cleanup; goto err_new_table_cleanup;
thd_proc_info(thd, "manage keys"); thd_proc_info(thd, "manage keys");
alter_table_manage_keys(table, table->file->indexes_are_disabled(), alter_table_manage_keys(table, table->file->indexes_are_disabled(),
......
...@@ -4555,24 +4555,6 @@ void TABLE::mark_columns_needed_for_insert() ...@@ -4555,24 +4555,6 @@ void TABLE::mark_columns_needed_for_insert()
} }
/**
@brief Check if this is part of a MERGE table with attached children.
@return status
@retval TRUE children are attached
@retval FALSE no MERGE part or children not attached
@detail
A MERGE table consists of a parent TABLE and zero or more child
TABLEs. Each of these TABLEs is called a part of a MERGE table.
*/
bool TABLE::is_children_attached(void)
{
return((child_l && children_attached) ||
(parent && parent->children_attached));
}
/* /*
Cleanup this table for re-execution. Cleanup this table for re-execution.
......
...@@ -635,11 +635,6 @@ struct TABLE ...@@ -635,11 +635,6 @@ struct TABLE
public: public:
/* For the below MERGE related members see top comment in ha_myisammrg.cc */
TABLE *parent; /* Set in MERGE child. Ptr to parent */
TABLE_LIST *child_l; /* Set in MERGE parent. List of children */
TABLE_LIST **child_last_l; /* Set in MERGE parent. End of list */
THD *in_use; /* Which thread uses this */ THD *in_use; /* Which thread uses this */
Field **field; /* Pointer to fields */ Field **field; /* Pointer to fields */
...@@ -809,8 +804,6 @@ struct TABLE ...@@ -809,8 +804,6 @@ struct TABLE
my_bool insert_or_update; /* Can be used by the handler */ my_bool insert_or_update; /* Can be used by the handler */
my_bool alias_name_used; /* true if table_name is alias */ my_bool alias_name_used; /* true if table_name is alias */
my_bool get_fields_in_item_tree; /* Signal to fix_field */ my_bool get_fields_in_item_tree; /* Signal to fix_field */
/* If MERGE children attached to parent. See top comment in ha_myisammrg.cc */
my_bool children_attached;
REGINFO reginfo; /* field connections */ REGINFO reginfo; /* field connections */
MEM_ROOT mem_root; MEM_ROOT mem_root;
...@@ -861,7 +854,6 @@ struct TABLE ...@@ -861,7 +854,6 @@ struct TABLE
*/ */
inline bool needs_reopen() inline bool needs_reopen()
{ return s->version != refresh_version; } { return s->version != refresh_version; }
bool is_children_attached(void);
}; };
......
This diff is collapsed.
...@@ -28,6 +28,9 @@ class ha_myisammrg: public handler ...@@ -28,6 +28,9 @@ class ha_myisammrg: public handler
my_bool is_cloned; /* This instance has been cloned */ my_bool is_cloned; /* This instance has been cloned */
public: public:
MEM_ROOT children_mem_root; /* mem root for children list */
TABLE_LIST *children_l; /* children list */
TABLE_LIST **children_last_l; /* children list end */
TABLE_LIST *next_child_attach; /* next child to attach */ TABLE_LIST *next_child_attach; /* next child to attach */
uint test_if_locked; /* flags from ::open() */ uint test_if_locked; /* flags from ::open() */
bool need_compat_check; /* if need compatibility check */ bool need_compat_check; /* if need compatibility check */
...@@ -60,6 +63,7 @@ class ha_myisammrg: public handler ...@@ -60,6 +63,7 @@ class ha_myisammrg: public handler
{ return ulonglong2double(stats.data_file_length) / IO_SIZE + file->tables; } { return ulonglong2double(stats.data_file_length) / IO_SIZE + file->tables; }
int open(const char *name, int mode, uint test_if_locked); int open(const char *name, int mode, uint test_if_locked);
int add_children_list(void);
int attach_children(void); int attach_children(void);
int detach_children(void); int detach_children(void);
virtual handler *clone(MEM_ROOT *mem_root); virtual handler *clone(MEM_ROOT *mem_root);
......
...@@ -75,12 +75,17 @@ int myrg_reset(MYRG_INFO *info) ...@@ -75,12 +75,17 @@ int myrg_reset(MYRG_INFO *info)
MYRG_TABLE *file; MYRG_TABLE *file;
DBUG_ENTER("myrg_reset"); DBUG_ENTER("myrg_reset");
if (!info->children_attached)
DBUG_RETURN(1);
info->cache_in_use=0; info->cache_in_use=0;
info->current_table=0; info->current_table=0;
info->last_used_table= info->open_tables; info->last_used_table= info->open_tables;
/*
This is normally called with detached children.
Return OK as this is the normal case.
*/
if (!info->children_attached)
DBUG_RETURN(0);
for (file=info->open_tables ; file != info->end_table ; file++) for (file=info->open_tables ; file != info->end_table ; file++)
{ {
int error; int error;
......
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