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
b53b448d
Commit
b53b448d
authored
Jun 05, 2007
by
lars/lthalmann@dl145h.mysql.com
Browse files
Options
Browse Files
Download
Plain Diff
Merge mysql.com:/nfsdisk1/lars/bkroot/mysql-5.0-rpl
into mysql.com:/nfsdisk1/lars/MERGE/mysql-5.0-merge
parents
d9fcc304
c762ec3a
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
229 additions
and
20 deletions
+229
-20
mysql-test/r/innodb.result
mysql-test/r/innodb.result
+39
-6
mysql-test/r/multi_update.result
mysql-test/r/multi_update.result
+34
-0
mysql-test/t/innodb.test
mysql-test/t/innodb.test
+39
-0
mysql-test/t/multi_update.test
mysql-test/t/multi_update.test
+41
-0
sql/sql_update.cc
sql/sql_update.cc
+76
-14
No files found.
mysql-test/r/innodb.result
View file @
b53b448d
...
...
@@ -1086,6 +1086,39 @@ n d
1 30
2 20
drop table t1,t2;
CREATE TABLE `t1` (
`a`
int(11) NOT NULL auto_increment,
`b`
int(11) default NULL,
PRIMARY KEY (`a`)
)
ENGINE=MyISAM DEFAULT CHARSET=latin1 ;
CREATE TABLE `t2` (
`a`
int(11) NOT NULL auto_increment,
`b`
int(11) default NULL,
PRIMARY KEY (`a`)
)
ENGINE=INNODB DEFAULT CHARSET=latin1 ;
insert into t1 values (1,1),(2,2);
insert into t2 values (1,1),(4,4);
reset master;
UPDATE t2,t1 SET t2.a=t1.a+2;
ERROR 23000: Duplicate entry '3' for key 1
select * from t2 /* must be (3,1), (4,4) */;
a b
1 1
4 4
show master status /* there must no UPDATE in binlog */;
File Position Binlog_Do_DB Binlog_Ignore_DB
master-bin.000001 98
delete from t1;
delete from t2;
insert into t1 values (1,2),(3,4),(4,4);
insert into t2 values (1,2),(3,4),(4,4);
reset master;
UPDATE t2,t1 SET t2.a=t2.b where t2.a=t1.a;
ERROR 23000: Duplicate entry '4' for key 1
show master status /* there must be no UPDATE query event */;
File Position Binlog_Do_DB Binlog_Ignore_DB
master-bin.000001 98
drop table t1, t2;
create table t1 (a int, b int) engine=innodb;
insert into t1 values(20,null);
select t2.b, ifnull(t2.b,"this is null") from t1 as t2 left join t1 as t3 on
...
...
@@ -1642,14 +1675,14 @@ t2 CREATE TABLE `t2` (
drop table t2, t1;
show status like "binlog_cache_use";
Variable_name Value
Binlog_cache_use 15
5
Binlog_cache_use 15
8
show status like "binlog_cache_disk_use";
Variable_name Value
Binlog_cache_disk_use 0
create table t1 (a int) engine=innodb;
show status like "binlog_cache_use";
Variable_name Value
Binlog_cache_use 15
6
Binlog_cache_use 15
9
show status like "binlog_cache_disk_use";
Variable_name Value
Binlog_cache_disk_use 1
...
...
@@ -1658,7 +1691,7 @@ delete from t1;
commit;
show status like "binlog_cache_use";
Variable_name Value
Binlog_cache_use 1
57
Binlog_cache_use 1
60
show status like "binlog_cache_disk_use";
Variable_name Value
Binlog_cache_disk_use 1
...
...
@@ -1782,13 +1815,13 @@ Variable_name Value
Innodb_page_size 16384
show status like "Innodb_rows_deleted";
Variable_name Value
Innodb_rows_deleted 207
0
Innodb_rows_deleted 207
2
show status like "Innodb_rows_inserted";
Variable_name Value
Innodb_rows_inserted 317
27
Innodb_rows_inserted 317
32
show status like "Innodb_rows_updated";
Variable_name Value
Innodb_rows_updated 2953
0
Innodb_rows_updated 2953
2
show status like "Innodb_row_lock_waits";
Variable_name Value
Innodb_row_lock_waits 0
...
...
mysql-test/r/multi_update.result
View file @
b53b448d
...
...
@@ -524,3 +524,37 @@ a
30
drop view v1;
drop table t1, t2;
CREATE TABLE `t1` (
`a` int(11) NOT NULL auto_increment,
`b` int(11) default NULL,
PRIMARY KEY (`a`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 ;
CREATE TABLE `t2` (
`a` int(11) NOT NULL auto_increment,
`b` int(11) default NULL,
PRIMARY KEY (`a`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 ;
insert into t1 values (1,1),(2,2);
insert into t2 values (1,1),(4,4);
reset master;
UPDATE t2,t1 SET t2.a=t1.a+2;
ERROR 23000: Duplicate entry '3' for key 1
select * from t2 /* must be (3,1), (4,4) */;
a b
3 1
4 4
show master status /* there must be the UPDATE query event */;
File Position Binlog_Do_DB Binlog_Ignore_DB
master-bin.000001 189
delete from t1;
delete from t2;
insert into t1 values (1,2),(3,4),(4,4);
insert into t2 values (1,2),(3,4),(4,4);
reset master;
UPDATE t2,t1 SET t2.a=t2.b where t2.a=t1.a;
ERROR 23000: Duplicate entry '4' for key 1
show master status /* there must be the UPDATE query event */;
File Position Binlog_Do_DB Binlog_Ignore_DB
master-bin.000001 204
drop table t1, t2;
end of tests
mysql-test/t/innodb.test
View file @
b53b448d
...
...
@@ -753,6 +753,45 @@ select * from t1;
select
*
from
t2
;
drop
table
t1
,
t2
;
#
# Bug#27716 multi-update did partially and has not binlogged
#
CREATE
TABLE
`t1`
(
`a`
int
(
11
)
NOT
NULL
auto_increment
,
`b`
int
(
11
)
default
NULL
,
PRIMARY
KEY
(
`a`
)
)
ENGINE
=
MyISAM
DEFAULT
CHARSET
=
latin1
;
CREATE
TABLE
`t2`
(
`a`
int
(
11
)
NOT
NULL
auto_increment
,
`b`
int
(
11
)
default
NULL
,
PRIMARY
KEY
(
`a`
)
)
ENGINE
=
INNODB
DEFAULT
CHARSET
=
latin1
;
# A. testing multi_update::send_eof() execution branch
insert
into
t1
values
(
1
,
1
),(
2
,
2
);
insert
into
t2
values
(
1
,
1
),(
4
,
4
);
reset
master
;
--
error
ER_DUP_ENTRY
UPDATE
t2
,
t1
SET
t2
.
a
=
t1
.
a
+
2
;
# check
select
*
from
t2
/* must be (3,1), (4,4) */
;
show
master
status
/* there must no UPDATE in binlog */
;
# B. testing multi_update::send_error() execution branch
delete
from
t1
;
delete
from
t2
;
insert
into
t1
values
(
1
,
2
),(
3
,
4
),(
4
,
4
);
insert
into
t2
values
(
1
,
2
),(
3
,
4
),(
4
,
4
);
reset
master
;
--
error
ER_DUP_ENTRY
UPDATE
t2
,
t1
SET
t2
.
a
=
t2
.
b
where
t2
.
a
=
t1
.
a
;
show
master
status
/* there must be no UPDATE query event */
;
# cleanup bug#27716
drop
table
t1
,
t2
;
#
# Testing of IFNULL
#
...
...
mysql-test/t/multi_update.test
View file @
b53b448d
...
...
@@ -534,3 +534,44 @@ select * from t1;
select
*
from
t2
;
drop
view
v1
;
drop
table
t1
,
t2
;
#
# Bug#27716 multi-update did partially and has not binlogged
#
CREATE
TABLE
`t1`
(
`a`
int
(
11
)
NOT
NULL
auto_increment
,
`b`
int
(
11
)
default
NULL
,
PRIMARY
KEY
(
`a`
)
)
ENGINE
=
MyISAM
DEFAULT
CHARSET
=
latin1
;
CREATE
TABLE
`t2`
(
`a`
int
(
11
)
NOT
NULL
auto_increment
,
`b`
int
(
11
)
default
NULL
,
PRIMARY
KEY
(
`a`
)
)
ENGINE
=
MyISAM
DEFAULT
CHARSET
=
latin1
;
# A. testing multi_update::send_eof() execution branch
insert
into
t1
values
(
1
,
1
),(
2
,
2
);
insert
into
t2
values
(
1
,
1
),(
4
,
4
);
reset
master
;
--
error
ER_DUP_ENTRY
UPDATE
t2
,
t1
SET
t2
.
a
=
t1
.
a
+
2
;
# check
select
*
from
t2
/* must be (3,1), (4,4) */
;
show
master
status
/* there must be the UPDATE query event */
;
# B. testing multi_update::send_error() execution branch
delete
from
t1
;
delete
from
t2
;
insert
into
t1
values
(
1
,
2
),(
3
,
4
),(
4
,
4
);
insert
into
t2
values
(
1
,
2
),(
3
,
4
),(
4
,
4
);
reset
master
;
--
error
ER_DUP_ENTRY
UPDATE
t2
,
t1
SET
t2
.
a
=
t2
.
b
where
t2
.
a
=
t1
.
a
;
show
master
status
/* there must be the UPDATE query event */
;
# cleanup bug#27716
drop
table
t1
,
t2
;
--
echo
end
of
tests
sql/sql_update.cc
View file @
b53b448d
...
...
@@ -946,6 +946,7 @@ bool mysql_multi_update(THD *thd,
SELECT_LEX_UNIT
*
unit
,
SELECT_LEX
*
select_lex
)
{
multi_update
*
result
;
bool
res
;
DBUG_ENTER
(
"mysql_multi_update"
);
if
(
!
(
result
=
new
multi_update
(
table_list
,
...
...
@@ -960,7 +961,7 @@ bool mysql_multi_update(THD *thd,
MODE_STRICT_ALL_TABLES
));
List
<
Item
>
total_list
;
(
void
)
mysql_select
(
thd
,
&
select_lex
->
ref_pointer_array
,
res
=
mysql_select
(
thd
,
&
select_lex
->
ref_pointer_array
,
table_list
,
select_lex
->
with_wild
,
total_list
,
conds
,
0
,
(
ORDER
*
)
NULL
,
(
ORDER
*
)
NULL
,
(
Item
*
)
NULL
,
...
...
@@ -968,6 +969,15 @@ bool mysql_multi_update(THD *thd,
options
|
SELECT_NO_JOIN_CACHE
|
SELECT_NO_UNLOCK
|
OPTION_SETUP_TABLES_DONE
,
result
,
unit
,
select_lex
);
DBUG_PRINT
(
"info"
,(
"res: %d report_error: %d"
,
res
,
thd
->
net
.
report_error
));
res
|=
thd
->
net
.
report_error
;
if
(
unlikely
(
res
))
{
/* If we had a another error reported earlier then this will be ignored */
result
->
send_error
(
ER_UNKNOWN_ERROR
,
ER
(
ER_UNKNOWN_ERROR
));
result
->
abort
();
}
delete
result
;
thd
->
abort_on_warning
=
0
;
DBUG_RETURN
(
FALSE
);
...
...
@@ -1321,8 +1331,9 @@ multi_update::~multi_update()
if
(
copy_field
)
delete
[]
copy_field
;
thd
->
count_cuted_fields
=
CHECK_FIELD_IGNORE
;
// Restore this setting
if
(
!
trans_safe
)
if
(
!
trans_safe
)
// todo: remove since redundant
thd
->
no_trans_update
.
all
=
TRUE
;
DBUG_ASSERT
(
trans_safe
||
thd
->
no_trans_update
.
all
);
}
...
...
@@ -1408,8 +1419,15 @@ bool multi_update::send_data(List<Item> ¬_used_values)
}
else
{
if
(
!
table
->
file
->
has_transactions
())
/* non-transactional or transactional table got modified */
/* either multi_update class' flag is raised in its branch */
if
(
table
->
file
->
has_transactions
())
transactional_tables
=
1
;
else
{
trans_safe
=
0
;
thd
->
no_trans_update
.
stmt
=
TRUE
;
}
if
(
table
->
triggers
&&
table
->
triggers
->
process_triggers
(
thd
,
TRG_EVENT_UPDATE
,
TRG_ACTION_AFTER
,
TRUE
))
...
...
@@ -1466,8 +1484,8 @@ void multi_update::send_error(uint errcode,const char *err)
my_error
(
errcode
,
MYF
(
0
),
err
);
/* If nothing updated return */
if
(
!
updated
)
return
;
if
(
updated
==
0
)
/* the counter might be reset in send_eof */
return
;
/* and then the query has been binlogged */
/* Something already updated so we have to invalidate cache */
query_cache_invalidate3
(
thd
,
update_tables
,
1
);
...
...
@@ -1478,11 +1496,43 @@ void multi_update::send_error(uint errcode,const char *err)
*/
if
(
trans_safe
)
ha_rollback_stmt
(
thd
);
else
if
(
do_update
&&
table_count
>
1
)
{
/* Add warning here */
VOID
(
do_updates
(
0
));
DBUG_ASSERT
(
transactional_tables
);
(
void
)
ha_autocommit_or_rollback
(
thd
,
1
);
}
else
{
DBUG_ASSERT
(
thd
->
no_trans_update
.
stmt
);
if
(
do_update
&&
table_count
>
1
)
{
/* Add warning here */
/*
todo/fixme: do_update() is never called with the arg 1.
should it change the signature to become argless?
*/
VOID
(
do_updates
(
0
));
}
}
if
(
thd
->
no_trans_update
.
stmt
)
{
/*
The query has to binlog because there's a modified non-transactional table
either from the query's list or via a stored routine: bug#13270,23333
*/
if
(
mysql_bin_log
.
is_open
())
{
Query_log_event
qinfo
(
thd
,
thd
->
query
,
thd
->
query_length
,
transactional_tables
,
FALSE
);
mysql_bin_log
.
write
(
&
qinfo
);
}
if
(
!
trans_safe
)
thd
->
no_trans_update
.
all
=
TRUE
;
}
DBUG_ASSERT
(
trans_safe
||
!
updated
||
thd
->
no_trans_update
.
stmt
);
if
(
transactional_tables
)
{
(
void
)
ha_autocommit_or_rollback
(
thd
,
1
);
}
}
...
...
@@ -1610,9 +1660,12 @@ int multi_update::do_updates(bool from_send_error)
if
(
updated
!=
org_updated
)
{
if
(
table
->
file
->
has_transactions
())
transactional_tables
=
1
;
transactional_tables
=
1
;
else
trans_safe
=
0
;
// Can't do safe rollback
{
trans_safe
=
0
;
// Can't do safe rollback
thd
->
no_trans_update
.
stmt
=
TRUE
;
}
}
(
void
)
table
->
file
->
ha_rnd_end
();
(
void
)
tmp_table
->
file
->
ha_rnd_end
();
...
...
@@ -1642,7 +1695,10 @@ int multi_update::do_updates(bool from_send_error)
if
(
table
->
file
->
has_transactions
())
transactional_tables
=
1
;
else
{
trans_safe
=
0
;
thd
->
no_trans_update
.
stmt
=
TRUE
;
}
}
DBUG_RETURN
(
1
);
}
...
...
@@ -1671,20 +1727,26 @@ bool multi_update::send_eof()
Write the SQL statement to the binlog if we updated
rows and we succeeded or if we updated some non
transactional tables.
The query has to binlog because there's a modified non-transactional table
either from the query's list or via a stored routine: bug#13270,23333
*/
if
((
local_error
==
0
)
||
(
updated
&&
!
trans_safe
))
DBUG_ASSERT
(
trans_safe
||
!
updated
||
thd
->
no_trans_update
.
stmt
);
if
(
local_error
==
0
||
thd
->
no_trans_update
.
stmt
)
{
if
(
mysql_bin_log
.
is_open
())
{
if
(
local_error
==
0
)
thd
->
clear_error
();
else
updated
=
0
;
/* if there's an error binlog it here not in ::send_error */
Query_log_event
qinfo
(
thd
,
thd
->
query
,
thd
->
query_length
,
transactional_tables
,
FALSE
);
if
(
mysql_bin_log
.
write
(
&
qinfo
)
&&
trans_safe
)
local_error
=
1
;
// Rollback update
}
if
(
!
trans
actional_tables
)
if
(
!
trans
_safe
)
thd
->
no_trans_update
.
all
=
TRUE
;
}
...
...
@@ -1696,7 +1758,7 @@ bool multi_update::send_eof()
if
(
local_error
>
0
)
// if the above log write did not fail ...
{
/* Safety: If we haven't got an error before (
should not happen
) */
/* Safety: If we haven't got an error before (
can happen in do_updates
) */
my_message
(
ER_UNKNOWN_ERROR
,
"An error occured in multi-table update"
,
MYF
(
0
));
return
TRUE
;
...
...
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