Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
M
MariaDB
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nexedi
MariaDB
Commits
5811a137
Commit
5811a137
authored
May 13, 2009
by
Martin Hansson
Browse files
Options
Browse Files
Download
Plain Diff
Merge.
parents
bd596287
391364fa
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
104 additions
and
8 deletions
+104
-8
mysql-test/r/innodb_mysql.result
mysql-test/r/innodb_mysql.result
+27
-0
mysql-test/suite/rpl/r/rpl_slave_skip.result
mysql-test/suite/rpl/r/rpl_slave_skip.result
+3
-3
mysql-test/t/innodb_mysql.test
mysql-test/t/innodb_mysql.test
+27
-0
sql/sql_base.cc
sql/sql_base.cc
+7
-0
sql/sql_update.cc
sql/sql_update.cc
+40
-5
No files found.
mysql-test/r/innodb_mysql.result
View file @
5811a137
...
@@ -2040,4 +2040,31 @@ DROP TABLE t4;
...
@@ -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
mysql-test/suite/rpl/r/rpl_slave_skip.result
View file @
5811a137
...
@@ -39,8 +39,8 @@ a b
...
@@ -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
...
@@ -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 11
33
Read_Master_Log_Pos 11
15
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
...
...
mysql-test/t/innodb_mysql.test
View file @
5811a137
...
@@ -332,4 +332,31 @@ DROP TABLE t1;
...
@@ -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
sql/sql_base.cc
View file @
5811a137
...
@@ -5585,6 +5585,13 @@ static void update_field_dependencies(THD *thd, Field *field, TABLE *table)
...
@@ -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
)
...
...
sql/sql_update.cc
View file @
5811a137
...
@@ -1031,7 +1031,6 @@ int mysql_multi_update_prepare(THD *thd)
...
@@ -1031,7 +1031,6 @@ int mysql_multi_update_prepare(THD *thd)
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,13 +1273,41 @@ int multi_update::prepare(List<Item> ¬_used_values,
...
@@ -1274,13 +1273,41 @@ 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
);
DBUG_RETURN
(
1
);
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
);
/*
/*
Save tables beeing updated in update_tables
Save tables beeing updated in update_tables
...
@@ -1375,6 +1402,8 @@ int multi_update::prepare(List<Item> ¬_used_values,
...
@@ -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,
...
@@ -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,
...
@@ -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)
...
@@ -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
();
/*
/*
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment