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
4ea4d24d
Commit
4ea4d24d
authored
Jan 31, 2005
by
unknown
Browse files
Options
Browse Files
Download
Plain Diff
Bug#7011
Merge from 4.0 sql/sql_select.cc: Auto merged
parents
b6c6cde8
b8ab81f1
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
196 additions
and
20 deletions
+196
-20
mysql-test/r/rpl_multi_update2.result
mysql-test/r/rpl_multi_update2.result
+42
-0
mysql-test/t/rpl_multi_update2-slave.opt
mysql-test/t/rpl_multi_update2-slave.opt
+1
-0
mysql-test/t/rpl_multi_update2.test
mysql-test/t/rpl_multi_update2.test
+33
-0
sql/mysql_priv.h
sql/mysql_priv.h
+4
-0
sql/sql_parse.cc
sql/sql_parse.cc
+81
-0
sql/sql_update.cc
sql/sql_update.cc
+35
-20
No files found.
mysql-test/r/rpl_multi_update2.result
0 → 100644
View file @
4ea4d24d
slave stop;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
reset master;
reset slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
slave start;
CREATE TABLE t1 (
a int unsigned not null auto_increment primary key,
b int unsigned
) TYPE=MyISAM;
CREATE TABLE t2 (
a int unsigned not null auto_increment primary key,
b int unsigned
) TYPE=MyISAM;
INSERT INTO t1 VALUES (NULL, 0);
INSERT INTO t1 SELECT NULL, 0 FROM t1;
INSERT INTO t2 VALUES (NULL, 0), (NULL,1);
SELECT * FROM t1 ORDER BY a;
a b
1 0
2 0
SELECT * FROM t2 ORDER BY a;
a b
1 0
2 1
UPDATE t1, t2 SET t1.b = (t2.b+4) WHERE t1.a = t2.a;
SELECT * FROM t1 ORDER BY a;
a b
1 4
2 5
SELECT * FROM t2 ORDER BY a;
a b
1 0
2 1
SELECT * FROM t1 ORDER BY a;
a b
1 4
2 5
SELECT * FROM t2 ORDER BY a;
a b
1 0
2 1
mysql-test/t/rpl_multi_update2-slave.opt
0 → 100644
View file @
4ea4d24d
--replicate-ignore-table=nothing.sensible
mysql-test/t/rpl_multi_update2.test
0 → 100644
View file @
4ea4d24d
# Let's verify that multi-update is not always skipped by slave if
# some replicate-* rules exist.
# (BUG#7011)
source
include
/
master
-
slave
.
inc
;
CREATE
TABLE
t1
(
a
int
unsigned
not
null
auto_increment
primary
key
,
b
int
unsigned
)
TYPE
=
MyISAM
;
CREATE
TABLE
t2
(
a
int
unsigned
not
null
auto_increment
primary
key
,
b
int
unsigned
)
TYPE
=
MyISAM
;
INSERT
INTO
t1
VALUES
(
NULL
,
0
);
INSERT
INTO
t1
SELECT
NULL
,
0
FROM
t1
;
INSERT
INTO
t2
VALUES
(
NULL
,
0
),
(
NULL
,
1
);
SELECT
*
FROM
t1
ORDER
BY
a
;
SELECT
*
FROM
t2
ORDER
BY
a
;
UPDATE
t1
,
t2
SET
t1
.
b
=
(
t2
.
b
+
4
)
WHERE
t1
.
a
=
t2
.
a
;
SELECT
*
FROM
t1
ORDER
BY
a
;
SELECT
*
FROM
t2
ORDER
BY
a
;
save_master_pos
;
connection
slave
;
sync_with_master
;
SELECT
*
FROM
t1
ORDER
BY
a
;
SELECT
*
FROM
t2
ORDER
BY
a
;
sql/mysql_priv.h
View file @
4ea4d24d
...
...
@@ -564,6 +564,10 @@ int mysql_multi_update(THD *thd, TABLE_LIST *table_list,
COND
*
conds
,
ulong
options
,
enum
enum_duplicates
handle_duplicates
,
bool
ignore
,
SELECT_LEX_UNIT
*
unit
,
SELECT_LEX
*
select_lex
);
int
mysql_multi_update_lock
(
THD
*
thd
,
TABLE_LIST
*
table_list
,
List
<
Item
>
*
fields
,
SELECT_LEX
*
select_lex
);
int
mysql_prepare_insert
(
THD
*
thd
,
TABLE_LIST
*
table_list
,
TABLE_LIST
*
insert_table_list
,
TABLE
*
table
,
List
<
Item
>
&
fields
,
List_item
*
values
,
...
...
sql/sql_parse.cc
View file @
4ea4d24d
...
...
@@ -52,6 +52,8 @@ static int check_for_max_user_connections(THD *thd, USER_CONN *uc);
#endif
static
void
decrease_user_connections
(
USER_CONN
*
uc
);
static
bool
check_db_used
(
THD
*
thd
,
TABLE_LIST
*
tables
);
static
bool
check_multi_update_lock
(
THD
*
thd
,
TABLE_LIST
*
tables
,
List
<
Item
>
*
fields
,
SELECT_LEX
*
select_lex
);
static
void
remove_escape
(
char
*
name
);
static
void
refresh_status
(
void
);
static
bool
append_file_to_dir
(
THD
*
thd
,
const
char
**
filename_ptr
,
...
...
@@ -1883,6 +1885,8 @@ mysql_execute_command(THD *thd)
{
int
res
=
0
;
LEX
*
lex
=
thd
->
lex
;
bool
slave_fake_lock
=
0
;
MYSQL_LOCK
*
fake_prev_lock
=
0
;
SELECT_LEX
*
select_lex
=
&
lex
->
select_lex
;
TABLE_LIST
*
tables
=
(
TABLE_LIST
*
)
select_lex
->
table_list
.
first
;
SELECT_LEX_UNIT
*
unit
=
&
lex
->
unit
;
...
...
@@ -1900,6 +1904,23 @@ mysql_execute_command(THD *thd)
#ifdef HAVE_REPLICATION
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
given and the table list says the query should not be replicated
...
...
@@ -3582,6 +3603,14 @@ purposes internal to the MySQL server", MYF(0));
send_error
(
thd
,
thd
->
killed
?
ER_SERVER_SHUTDOWN
:
0
);
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
;
}
...
...
@@ -5012,6 +5041,58 @@ bool check_simple_select()
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
)
{
...
...
sql/sql_update.cc
View file @
4ea4d24d
...
...
@@ -464,30 +464,23 @@ static table_map get_table_map(List<Item> *items)
}
/*
Setup multi-update handling and call SELECT to do the join
Prepare tables for multi-update
Analyse which tables need specific privileges and perform locking
as required
*/
int
mysql_multi_update
(
THD
*
thd
,
TABLE_LIST
*
table_list
,
List
<
Item
>
*
fields
,
List
<
Item
>
*
values
,
COND
*
conds
,
ulong
options
,
enum
enum_duplicates
handle_duplicates
,
bool
ignore
,
SELECT_LEX_UNIT
*
unit
,
SELECT_LEX
*
select_lex
)
int
mysql_multi_update_lock
(
THD
*
thd
,
TABLE_LIST
*
table_list
,
List
<
Item
>
*
fields
,
SELECT_LEX
*
select_lex
)
{
int
res
;
multi_update
*
result
;
TABLE_LIST
*
tl
;
TABLE_LIST
*
update_list
=
(
TABLE_LIST
*
)
thd
->
lex
->
select_lex
.
table_list
.
first
;
List
<
Item
>
total_list
;
const
bool
using_lock_tables
=
thd
->
locked_tables
!=
0
;
bool
initialized_dervied
=
0
;
DBUG_ENTER
(
"mysql_multi_update"
);
select_lex
->
select_limit
=
HA_POS_ERROR
;
DBUG_ENTER
(
"mysql_multi_update_lock"
);
/*
The following loop is here to to ensure that we only lock tables
...
...
@@ -593,7 +586,7 @@ int mysql_multi_update(THD *thd,
(
grant_option
&&
check_grant
(
thd
,
wants
,
tl
,
0
,
0
,
0
)))
{
tl
->
next
=
save
;
DBUG_RETURN
(
0
);
DBUG_RETURN
(
1
);
}
tl
->
next
=
save
;
}
...
...
@@ -616,11 +609,7 @@ int mysql_multi_update(THD *thd,
/* Relock the tables with the correct modes */
res
=
lock_tables
(
thd
,
table_list
,
table_count
);
if
(
using_lock_tables
)
{
if
(
res
)
DBUG_RETURN
(
res
);
break
;
// Don't have to do setup_field()
}
/*
We must setup fields again as the file may have been reopened
...
...
@@ -651,6 +640,32 @@ int mysql_multi_update(THD *thd,
*/
close_thread_tables
(
thd
);
}
DBUG_RETURN
(
res
);
}
/*
Setup multi-update handling and call SELECT to do the join
*/
int
mysql_multi_update
(
THD
*
thd
,
TABLE_LIST
*
table_list
,
List
<
Item
>
*
fields
,
List
<
Item
>
*
values
,
COND
*
conds
,
ulong
options
,
enum
enum_duplicates
handle_duplicates
,
bool
ignore
,
SELECT_LEX_UNIT
*
unit
,
SELECT_LEX
*
select_lex
)
{
int
res
;
TABLE_LIST
*
tl
;
TABLE_LIST
*
update_list
=
(
TABLE_LIST
*
)
thd
->
lex
->
select_lex
.
table_list
.
first
;
List
<
Item
>
total_list
;
multi_update
*
result
;
DBUG_ENTER
(
"mysql_multi_update"
);
if
((
res
=
mysql_multi_update_lock
(
thd
,
table_list
,
fields
,
select_lex
)))
DBUG_RETURN
(
res
);
/* Setup timestamp handling */
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