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
99838052
Commit
99838052
authored
Oct 10, 2005
by
lars@mysql.com
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
BUG#12618: Removing fake locking
parent
e8f291f5
Changes
4
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
151 additions
and
85 deletions
+151
-85
mysql-test/r/rpl_multi_update3.result
mysql-test/r/rpl_multi_update3.result
+72
-0
mysql-test/t/rpl_multi_update3.test
mysql-test/t/rpl_multi_update3.test
+59
-0
sql/sql_parse.cc
sql/sql_parse.cc
+20
-82
sql/sql_update.cc
sql/sql_update.cc
+0
-3
No files found.
mysql-test/r/rpl_multi_update3.result
View file @
99838052
...
@@ -122,3 +122,75 @@ SELECT * FROM t1;
...
@@ -122,3 +122,75 @@ SELECT * FROM t1;
i j x y z
i j x y z
1 2 23 24 71
1 2 23 24 71
DROP TABLE t1, t2, t3;
DROP TABLE t1, t2, t3;
DROP TABLE IF EXISTS t1;
Warnings:
Note 1051 Unknown table 't1'
DROP TABLE IF EXISTS t2;
Warnings:
Note 1051 Unknown table 't2'
CREATE TABLE t1 (
idp int(11) NOT NULL default '0',
idpro int(11) default NULL,
price decimal(19,4) default NULL,
PRIMARY KEY (idp)
);
CREATE TABLE t2 (
idpro int(11) NOT NULL default '0',
price decimal(19,4) default NULL,
nbprice int(11) default NULL,
PRIMARY KEY (idpro)
);
INSERT INTO t1 VALUES
(1,1,'3.0000'),
(2,2,'1.0000'),
(3,1,'1.0000'),
(4,1,'4.0000'),
(5,3,'2.0000'),
(6,2,'4.0000');
INSERT INTO t2 VALUES
(1,'0.0000',0),
(2,'0.0000',0),
(3,'0.0000',0);
update
t2
join
( select idpro, min(price) as min_price, count(*) as nbr_price
from t1
where idpro>0 and price>0
group by idpro
) as table_price
on t2.idpro = table_price.idpro
set t2.price = table_price.min_price,
t2.nbprice = table_price.nbr_price;
select "-- MASTER AFTER JOIN --" as "";
-- MASTER AFTER JOIN --
select * from t1;
idp idpro price
1 1 3.0000
2 2 1.0000
3 1 1.0000
4 1 4.0000
5 3 2.0000
6 2 4.0000
select * from t2;
idpro price nbprice
1 1.0000 3
2 1.0000 2
3 2.0000 1
select "-- SLAVE AFTER JOIN --" as "";
-- SLAVE AFTER JOIN --
select * from t1;
idp idpro price
1 1 3.0000
2 2 1.0000
3 1 1.0000
4 1 4.0000
5 3 2.0000
6 2 4.0000
select * from t2;
idpro price nbprice
1 1.0000 3
2 1.0000 2
3 2.0000 1
mysql-test/t/rpl_multi_update3.test
View file @
99838052
...
@@ -158,4 +158,63 @@ SELECT * FROM t1;
...
@@ -158,4 +158,63 @@ SELECT * FROM t1;
connection
master
;
connection
master
;
DROP
TABLE
t1
,
t2
,
t3
;
DROP
TABLE
t1
,
t2
,
t3
;
##############################################################################
#
# BUG#12618
#
# TEST: Replication of a statement containing a join in a multi-update.
DROP
TABLE
IF
EXISTS
t1
;
DROP
TABLE
IF
EXISTS
t2
;
CREATE
TABLE
t1
(
idp
int
(
11
)
NOT
NULL
default
'0'
,
idpro
int
(
11
)
default
NULL
,
price
decimal
(
19
,
4
)
default
NULL
,
PRIMARY
KEY
(
idp
)
);
CREATE
TABLE
t2
(
idpro
int
(
11
)
NOT
NULL
default
'0'
,
price
decimal
(
19
,
4
)
default
NULL
,
nbprice
int
(
11
)
default
NULL
,
PRIMARY
KEY
(
idpro
)
);
INSERT
INTO
t1
VALUES
(
1
,
1
,
'3.0000'
),
(
2
,
2
,
'1.0000'
),
(
3
,
1
,
'1.0000'
),
(
4
,
1
,
'4.0000'
),
(
5
,
3
,
'2.0000'
),
(
6
,
2
,
'4.0000'
);
INSERT
INTO
t2
VALUES
(
1
,
'0.0000'
,
0
),
(
2
,
'0.0000'
,
0
),
(
3
,
'0.0000'
,
0
);
# This update sets t2 to the minimal prices for each product
update
t2
join
(
select
idpro
,
min
(
price
)
as
min_price
,
count
(
*
)
as
nbr_price
from
t1
where
idpro
>
0
and
price
>
0
group
by
idpro
)
as
table_price
on
t2
.
idpro
=
table_price
.
idpro
set
t2
.
price
=
table_price
.
min_price
,
t2
.
nbprice
=
table_price
.
nbr_price
;
select
"-- MASTER AFTER JOIN --"
as
""
;
select
*
from
t1
;
select
*
from
t2
;
sync_slave_with_master
;
select
"-- SLAVE AFTER JOIN --"
as
""
;
select
*
from
t1
;
select
*
from
t2
;
# End of 4.1 tests
# End of 4.1 tests
sql/sql_parse.cc
View file @
99838052
...
@@ -1941,8 +1941,6 @@ mysql_execute_command(THD *thd)
...
@@ -1941,8 +1941,6 @@ mysql_execute_command(THD *thd)
{
{
int
res
=
0
;
int
res
=
0
;
LEX
*
lex
=
thd
->
lex
;
LEX
*
lex
=
thd
->
lex
;
bool
slave_fake_lock
=
0
;
MYSQL_LOCK
*
fake_prev_lock
=
0
;
SELECT_LEX
*
select_lex
=
&
lex
->
select_lex
;
SELECT_LEX
*
select_lex
=
&
lex
->
select_lex
;
TABLE_LIST
*
tables
=
(
TABLE_LIST
*
)
select_lex
->
table_list
.
first
;
TABLE_LIST
*
tables
=
(
TABLE_LIST
*
)
select_lex
->
table_list
.
first
;
SELECT_LEX_UNIT
*
unit
=
&
lex
->
unit
;
SELECT_LEX_UNIT
*
unit
=
&
lex
->
unit
;
...
@@ -1971,35 +1969,21 @@ mysql_execute_command(THD *thd)
...
@@ -1971,35 +1969,21 @@ mysql_execute_command(THD *thd)
#ifdef HAVE_REPLICATION
#ifdef HAVE_REPLICATION
if
(
thd
->
slave_thread
)
if
(
thd
->
slave_thread
)
{
{
if
(
lex
->
sql_command
==
SQLCOM_UPDATE_MULTI
)
{
DBUG_PRINT
(
"info"
,(
"need faked locked tables"
));
if
(
check_multi_update_lock
(
thd
,
tables
,
&
select_lex
->
item_list
,
select_lex
))
goto
error
;
/* Fix for replication, the tables are opened and locked,
now we pretend that we have performed a LOCK TABLES action */
fake_prev_lock
=
thd
->
locked_tables
;
if
(
thd
->
lock
)
thd
->
locked_tables
=
thd
->
lock
;
thd
->
lock
=
0
;
slave_fake_lock
=
1
;
}
/*
/*
Skip if we are in the slave thread, some table rules have been
Check if statment should be skipped because of slave filtering
given and the table list says the query should not be replicated.
rules
Exceptions are:
Exceptions are:
- UPDATE MULTI: For this statement, we want to check the filtering
rules later in the code
- SET: we always execute it (Not that many SET commands exists in
- SET: we always execute it (Not that many SET commands exists in
the binary log anyway -- only 4.1 masters write SET statements,
the binary log anyway -- only 4.1 masters write SET statements,
in 5.0 there are no SET statements in the binary log)
in 5.0 there are no SET statements in the binary log)
- DROP TEMPORARY TABLE IF EXISTS: we always execute it (otherwise we
- DROP TEMPORARY TABLE IF EXISTS: we always execute it (otherwise we
have stale files on slave caused by exclusion of one tmp table).
have stale files on slave caused by exclusion of one tmp table).
*/
*/
if
(
!
(
lex
->
sql_command
==
SQLCOM_SET_OPTION
)
&&
if
(
!
(
lex
->
sql_command
==
SQLCOM_UPDATE_MULTI
)
&&
!
(
lex
->
sql_command
==
SQLCOM_SET_OPTION
)
&&
!
(
lex
->
sql_command
==
SQLCOM_DROP_TABLE
&&
!
(
lex
->
sql_command
==
SQLCOM_DROP_TABLE
&&
lex
->
drop_temporary
&&
lex
->
drop_if_exists
)
&&
lex
->
drop_temporary
&&
lex
->
drop_if_exists
)
&&
all_tables_not_ok
(
thd
,
tables
))
all_tables_not_ok
(
thd
,
tables
))
...
@@ -2852,6 +2836,20 @@ mysql_execute_command(THD *thd)
...
@@ -2852,6 +2836,20 @@ mysql_execute_command(THD *thd)
{
{
if
((
res
=
multi_update_precheck
(
thd
,
tables
)))
if
((
res
=
multi_update_precheck
(
thd
,
tables
)))
break
;
break
;
if
((
res
=
mysql_multi_update_lock
(
thd
,
tables
,
&
select_lex
->
item_list
,
select_lex
)))
break
;
/* Check slave filtering rules */
if
(
thd
->
slave_thread
)
if
(
all_tables_not_ok
(
thd
,
tables
))
{
/* we warn the slave SQL thread */
my_error
(
ER_SLAVE_IGNORED_TABLE
,
MYF
(
0
));
break
;
}
res
=
mysql_multi_update
(
thd
,
tables
,
res
=
mysql_multi_update
(
thd
,
tables
,
&
select_lex
->
item_list
,
&
select_lex
->
item_list
,
&
lex
->
value_list
,
&
lex
->
value_list
,
...
@@ -3764,14 +3762,6 @@ purposes internal to the MySQL server", MYF(0));
...
@@ -3764,14 +3762,6 @@ purposes internal to the MySQL server", MYF(0));
send_error
(
thd
,
thd
->
killed
?
ER_SERVER_SHUTDOWN
:
0
);
send_error
(
thd
,
thd
->
killed
?
ER_SERVER_SHUTDOWN
:
0
);
error:
error:
if
(
unlikely
(
slave_fake_lock
))
{
DBUG_PRINT
(
"info"
,(
"undoing faked lock"
));
thd
->
lock
=
thd
->
locked_tables
;
thd
->
locked_tables
=
fake_prev_lock
;
if
(
thd
->
lock
==
thd
->
locked_tables
)
thd
->
lock
=
0
;
}
DBUG_VOID_RETURN
;
DBUG_VOID_RETURN
;
}
}
...
@@ -5303,58 +5293,6 @@ bool check_simple_select()
...
@@ -5303,58 +5293,6 @@ bool check_simple_select()
return
0
;
return
0
;
}
}
/*
Setup locking for multi-table updates. Used by the replication slave.
Replication slave SQL thread examines (all_tables_not_ok()) the
locking state of referenced tables to determine if the query has to
be executed or ignored. Since in multi-table update, the
'default' lock is read-only, this lock is corrected early enough by
calling this function, before the slave decides to execute/ignore.
SYNOPSIS
check_multi_update_lock()
thd Current thread
tables List of user-supplied tables
fields List of fields requiring update
RETURN VALUES
0 ok
1 error
*/
static
bool
check_multi_update_lock
(
THD
*
thd
,
TABLE_LIST
*
tables
,
List
<
Item
>
*
fields
,
SELECT_LEX
*
select_lex
)
{
bool
res
=
1
;
TABLE_LIST
*
table
;
DBUG_ENTER
(
"check_multi_update_lock"
);
if
(
check_db_used
(
thd
,
tables
))
goto
error
;
/*
Ensure that we have UPDATE or SELECT privilege for each table
The exact privilege is checked in mysql_multi_update()
*/
for
(
table
=
tables
;
table
;
table
=
table
->
next
)
{
TABLE_LIST
*
save
=
table
->
next
;
table
->
next
=
0
;
if
((
check_access
(
thd
,
UPDATE_ACL
,
table
->
db
,
&
table
->
grant
.
privilege
,
0
,
1
)
||
(
grant_option
&&
check_grant
(
thd
,
UPDATE_ACL
,
table
,
0
,
1
,
1
)))
&&
check_one_table_access
(
thd
,
SELECT_ACL
,
table
))
goto
error
;
table
->
next
=
save
;
}
if
(
mysql_multi_update_lock
(
thd
,
tables
,
fields
,
select_lex
))
goto
error
;
res
=
0
;
error:
DBUG_RETURN
(
res
);
}
Comp_creator
*
comp_eq_creator
(
bool
invert
)
Comp_creator
*
comp_eq_creator
(
bool
invert
)
{
{
...
...
sql/sql_update.cc
View file @
99838052
...
@@ -672,9 +672,6 @@ int mysql_multi_update(THD *thd,
...
@@ -672,9 +672,6 @@ int mysql_multi_update(THD *thd,
multi_update
*
result
;
multi_update
*
result
;
DBUG_ENTER
(
"mysql_multi_update"
);
DBUG_ENTER
(
"mysql_multi_update"
);
if
((
res
=
mysql_multi_update_lock
(
thd
,
table_list
,
fields
,
select_lex
)))
DBUG_RETURN
(
res
);
/* Setup timestamp handling */
/* Setup timestamp handling */
for
(
tl
=
update_list
;
tl
;
tl
=
tl
->
next
)
for
(
tl
=
update_list
;
tl
;
tl
=
tl
->
next
)
{
{
...
...
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