mirror of
https://github.com/MariaDB/server.git
synced 2025-07-05 12:42:17 +03:00
Merge.
This commit is contained in:
@ -2040,4 +2040,31 @@ DROP TABLE t4;
|
|||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
DROP TABLE t2;
|
DROP TABLE t2;
|
||||||
DROP TABLE t3;
|
DROP TABLE t3;
|
||||||
|
CREATE TABLE t1 (a INT, b INT, KEY (a)) ENGINE = INNODB;
|
||||||
|
CREATE TABLE t2 (a INT KEY, b INT, KEY (b)) ENGINE = INNODB;
|
||||||
|
CREATE TABLE t3 (a INT, b INT KEY, KEY (a)) ENGINE = INNODB;
|
||||||
|
CREATE TABLE t4 (a INT KEY, b INT, KEY (b)) ENGINE = INNODB;
|
||||||
|
INSERT INTO t1 VALUES (1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6);
|
||||||
|
INSERT INTO t2 VALUES (1, 1), (2, 2), (3, 3), (4, 4), (5, 5);
|
||||||
|
INSERT INTO t3 VALUES (1, 101), (2, 102), (3, 103), (4, 104), (5, 105), (6, 106);
|
||||||
|
INSERT INTO t4 VALUES (1, 1), (2, 2), (3, 3), (4, 4), (5, 5);
|
||||||
|
UPDATE t1, t2 SET t1.a = t1.a + 100, t2.b = t1.a + 10
|
||||||
|
WHERE t1.a BETWEEN 2 AND 4 AND t2.a = t1.b;
|
||||||
|
SELECT * FROM t2;
|
||||||
|
a b
|
||||||
|
1 1
|
||||||
|
2 12
|
||||||
|
3 13
|
||||||
|
4 14
|
||||||
|
5 5
|
||||||
|
UPDATE t3, t4 SET t3.a = t3.a + 100, t4.b = t3.a + 10
|
||||||
|
WHERE t3.a BETWEEN 2 AND 4 AND t4.a = t3.b - 100;
|
||||||
|
SELECT * FROM t4;
|
||||||
|
a b
|
||||||
|
1 1
|
||||||
|
2 12
|
||||||
|
3 13
|
||||||
|
4 14
|
||||||
|
5 5
|
||||||
|
DROP TABLE t1, t2, t3, t4;
|
||||||
End of 5.1 tests
|
End of 5.1 tests
|
||||||
|
@ -39,8 +39,8 @@ a b
|
|||||||
SELECT * FROM t2;
|
SELECT * FROM t2;
|
||||||
c d
|
c d
|
||||||
1 2
|
1 2
|
||||||
2 16
|
2 8
|
||||||
3 54
|
3 18
|
||||||
**** On Slave ****
|
**** On Slave ****
|
||||||
START SLAVE UNTIL MASTER_LOG_FILE='master-bin.000001', MASTER_LOG_POS=762;
|
START SLAVE UNTIL MASTER_LOG_FILE='master-bin.000001', MASTER_LOG_POS=762;
|
||||||
SHOW SLAVE STATUS;
|
SHOW SLAVE STATUS;
|
||||||
@ -50,7 +50,7 @@ Master_User root
|
|||||||
Master_Port MASTER_PORT
|
Master_Port MASTER_PORT
|
||||||
Connect_Retry 1
|
Connect_Retry 1
|
||||||
Master_Log_File master-bin.000001
|
Master_Log_File master-bin.000001
|
||||||
Read_Master_Log_Pos 1133
|
Read_Master_Log_Pos 1115
|
||||||
Relay_Log_File #
|
Relay_Log_File #
|
||||||
Relay_Log_Pos #
|
Relay_Log_Pos #
|
||||||
Relay_Master_Log_File master-bin.000001
|
Relay_Master_Log_File master-bin.000001
|
||||||
|
@ -332,4 +332,31 @@ DROP TABLE t1;
|
|||||||
DROP TABLE t2;
|
DROP TABLE t2;
|
||||||
DROP TABLE t3;
|
DROP TABLE t3;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug#43580: Issue with Innodb on multi-table update
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 (a INT, b INT, KEY (a)) ENGINE = INNODB;
|
||||||
|
CREATE TABLE t2 (a INT KEY, b INT, KEY (b)) ENGINE = INNODB;
|
||||||
|
|
||||||
|
CREATE TABLE t3 (a INT, b INT KEY, KEY (a)) ENGINE = INNODB;
|
||||||
|
CREATE TABLE t4 (a INT KEY, b INT, KEY (b)) ENGINE = INNODB;
|
||||||
|
|
||||||
|
INSERT INTO t1 VALUES (1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6);
|
||||||
|
INSERT INTO t2 VALUES (1, 1), (2, 2), (3, 3), (4, 4), (5, 5);
|
||||||
|
|
||||||
|
INSERT INTO t3 VALUES (1, 101), (2, 102), (3, 103), (4, 104), (5, 105), (6, 106);
|
||||||
|
INSERT INTO t4 VALUES (1, 1), (2, 2), (3, 3), (4, 4), (5, 5);
|
||||||
|
|
||||||
|
UPDATE t1, t2 SET t1.a = t1.a + 100, t2.b = t1.a + 10
|
||||||
|
WHERE t1.a BETWEEN 2 AND 4 AND t2.a = t1.b;
|
||||||
|
--sorted_result
|
||||||
|
SELECT * FROM t2;
|
||||||
|
|
||||||
|
UPDATE t3, t4 SET t3.a = t3.a + 100, t4.b = t3.a + 10
|
||||||
|
WHERE t3.a BETWEEN 2 AND 4 AND t4.a = t3.b - 100;
|
||||||
|
--sorted_result
|
||||||
|
SELECT * FROM t4;
|
||||||
|
|
||||||
|
DROP TABLE t1, t2, t3, t4;
|
||||||
|
|
||||||
--echo End of 5.1 tests
|
--echo End of 5.1 tests
|
||||||
|
@ -5585,6 +5585,13 @@ static void update_field_dependencies(THD *thd, Field *field, TABLE *table)
|
|||||||
other_bitmap= table->read_set;
|
other_bitmap= table->read_set;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
The test-and-set mechanism in the bitmap is not reliable during
|
||||||
|
multi-UPDATE statements under MARK_COLUMNS_READ mode
|
||||||
|
(thd->mark_used_columns == MARK_COLUMNS_READ), as this bitmap contains
|
||||||
|
only those columns that are used in the SET clause. I.e they are being
|
||||||
|
set here. See multi_update::prepare()
|
||||||
|
*/
|
||||||
if (bitmap_fast_test_and_set(current_bitmap, field->field_index))
|
if (bitmap_fast_test_and_set(current_bitmap, field->field_index))
|
||||||
{
|
{
|
||||||
if (thd->mark_used_columns == MARK_COLUMNS_WRITE)
|
if (thd->mark_used_columns == MARK_COLUMNS_WRITE)
|
||||||
|
@ -1031,7 +1031,6 @@ reopen_tables:
|
|||||||
DBUG_RETURN(TRUE);
|
DBUG_RETURN(TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
table->mark_columns_needed_for_update();
|
|
||||||
DBUG_PRINT("info",("setting table `%s` for update", tl->alias));
|
DBUG_PRINT("info",("setting table `%s` for update", tl->alias));
|
||||||
/*
|
/*
|
||||||
If table will be updated we should not downgrade lock for it and
|
If table will be updated we should not downgrade lock for it and
|
||||||
@ -1274,12 +1273,40 @@ int multi_update::prepare(List<Item> ¬_used_values,
|
|||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
We gather the set of columns read during evaluation of SET expression in
|
||||||
|
TABLE::tmp_set by pointing TABLE::read_set to it and then restore it after
|
||||||
|
setup_fields().
|
||||||
|
*/
|
||||||
|
for (table_ref= leaves; table_ref; table_ref= table_ref->next_leaf)
|
||||||
|
{
|
||||||
|
TABLE *table= table_ref->table;
|
||||||
|
if (tables_to_update & table->map)
|
||||||
|
{
|
||||||
|
DBUG_ASSERT(table->read_set == &table->def_read_set);
|
||||||
|
table->read_set= &table->tmp_set;
|
||||||
|
bitmap_clear_all(table->read_set);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
We have to check values after setup_tables to get covering_keys right in
|
We have to check values after setup_tables to get covering_keys right in
|
||||||
reference tables
|
reference tables
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (setup_fields(thd, 0, *values, MARK_COLUMNS_READ, 0, 0))
|
int error= setup_fields(thd, 0, *values, MARK_COLUMNS_READ, 0, 0);
|
||||||
|
|
||||||
|
for (table_ref= leaves; table_ref; table_ref= table_ref->next_leaf)
|
||||||
|
{
|
||||||
|
TABLE *table= table_ref->table;
|
||||||
|
if (tables_to_update & table->map)
|
||||||
|
{
|
||||||
|
table->read_set= &table->def_read_set;
|
||||||
|
bitmap_union(table->read_set, &table->tmp_set);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (error)
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1375,6 +1402,8 @@ int multi_update::prepare(List<Item> ¬_used_values,
|
|||||||
a row in this table will never be read twice. This is true under
|
a row in this table will never be read twice. This is true under
|
||||||
the following conditions:
|
the following conditions:
|
||||||
|
|
||||||
|
- No column is both written to and read in SET expressions.
|
||||||
|
|
||||||
- We are doing a table scan and the data is in a separate file (MyISAM) or
|
- We are doing a table scan and the data is in a separate file (MyISAM) or
|
||||||
if we don't update a clustered key.
|
if we don't update a clustered key.
|
||||||
|
|
||||||
@ -1389,6 +1418,9 @@ int multi_update::prepare(List<Item> ¬_used_values,
|
|||||||
WARNING
|
WARNING
|
||||||
This code is a bit dependent of how make_join_readinfo() works.
|
This code is a bit dependent of how make_join_readinfo() works.
|
||||||
|
|
||||||
|
The field table->tmp_set is used for keeping track of which fields are
|
||||||
|
read during evaluation of the SET expression. See multi_update::prepare.
|
||||||
|
|
||||||
RETURN
|
RETURN
|
||||||
0 Not safe to update
|
0 Not safe to update
|
||||||
1 Safe to update
|
1 Safe to update
|
||||||
@ -1409,6 +1441,8 @@ static bool safe_update_on_fly(THD *thd, JOIN_TAB *join_tab,
|
|||||||
case JT_REF_OR_NULL:
|
case JT_REF_OR_NULL:
|
||||||
return !is_key_used(table, join_tab->ref.key, table->write_set);
|
return !is_key_used(table, join_tab->ref.key, table->write_set);
|
||||||
case JT_ALL:
|
case JT_ALL:
|
||||||
|
if (bitmap_is_overlapping(&table->tmp_set, table->write_set))
|
||||||
|
return FALSE;
|
||||||
/* If range search on index */
|
/* If range search on index */
|
||||||
if (join_tab->quick)
|
if (join_tab->quick)
|
||||||
return !join_tab->quick->is_keys_used(table->write_set);
|
return !join_tab->quick->is_keys_used(table->write_set);
|
||||||
@ -1464,17 +1498,18 @@ multi_update::initialize_tables(JOIN *join)
|
|||||||
ORDER group;
|
ORDER group;
|
||||||
TMP_TABLE_PARAM *tmp_param;
|
TMP_TABLE_PARAM *tmp_param;
|
||||||
|
|
||||||
table->mark_columns_needed_for_update();
|
|
||||||
if (ignore)
|
if (ignore)
|
||||||
table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
|
table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
|
||||||
if (table == main_table) // First table in join
|
if (table == main_table) // First table in join
|
||||||
{
|
{
|
||||||
if (safe_update_on_fly(thd, join->join_tab, table_ref, all_tables))
|
if (safe_update_on_fly(thd, join->join_tab, table_ref, all_tables))
|
||||||
{
|
{
|
||||||
table_to_update= main_table; // Update table on the fly
|
table->mark_columns_needed_for_update();
|
||||||
|
table_to_update= table; // Update table on the fly
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
table->mark_columns_needed_for_update();
|
||||||
table->prepare_for_position();
|
table->prepare_for_position();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Reference in New Issue
Block a user