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
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
mariadb
Commits
ba10c9cc
Commit
ba10c9cc
authored
Mar 30, 2009
by
Kristofer Pettersson
Browse files
Options
Browse Files
Download
Plain Diff
Automerge
parents
98698756
a20bc967
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
324 additions
and
10 deletions
+324
-10
mysql-test/r/innodb_mysql.result
mysql-test/r/innodb_mysql.result
+145
-0
mysql-test/t/innodb_mysql.test
mysql-test/t/innodb_mysql.test
+147
-0
sql/sql_delete.cc
sql/sql_delete.cc
+32
-10
No files found.
mysql-test/r/innodb_mysql.result
View file @
ba10c9cc
...
...
@@ -1876,4 +1876,149 @@ id
TRUNCATE TABLE t2;
DROP TABLE t2;
DROP TABLE t1;
#
# Bug#40127 Multiple table DELETE IGNORE hangs on foreign key constraint violation on 5.0
#
CREATE TABLE t1 (
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
PRIMARY KEY (id)
) ENGINE=InnoDB;
CREATE TABLE t2 (
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
aid INT UNSIGNED NOT NULL,
PRIMARY KEY (id),
FOREIGN KEY (aid) REFERENCES t1 (id)
) ENGINE=InnoDB;
CREATE TABLE t3 (
bid INT UNSIGNED NOT NULL,
FOREIGN KEY (bid) REFERENCES t2 (id)
) ENGINE=InnoDB;
CREATE TABLE t4 (
a INT
) ENGINE=InnoDB;
CREATE TABLE t5 (
a INT
) ENGINE=InnoDB;
INSERT INTO t1 (id) VALUES (1);
INSERT INTO t2 (id, aid) VALUES (1, 1),(2,1),(3,1),(4,1);
INSERT INTO t3 (bid) VALUES (1);
INSERT INTO t4 VALUES (1),(2),(3),(4),(5);
INSERT INTO t5 VALUES (1);
DELETE t5 FROM t4 LEFT JOIN t5 ON t4.a= t5.a;
DELETE t2, t1 FROM t2 INNER JOIN t1 ON (t2.aid = t1.id) WHERE t2.id = 1;
ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t3`, CONSTRAINT `t3_ibfk_1` FOREIGN KEY (`bid`) REFERENCES `t2` (`id`))
DELETE t2, t1 FROM t2 INNER JOIN t1 ON (t2.aid = t1.id) WHERE t2.id = 1;
ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t3`, CONSTRAINT `t3_ibfk_1` FOREIGN KEY (`bid`) REFERENCES `t2` (`id`))
DELETE IGNORE t2, t1 FROM t2 INNER JOIN t1 ON (t2.aid = t1.id) WHERE t2.id = 1;
DROP TABLE t3;
DROP TABLE t2;
DROP TABLE t1;
DROP TABLES t4,t5;
# Bug#40127 Multiple table DELETE IGNORE hangs on foreign key constraint violation on 5.0
# Testing for any side effects of IGNORE on AFTER DELETE triggers used with
# transactional tables.
#
CREATE TABLE t1 (i INT NOT NULL PRIMARY KEY) ENGINE=InnoDB;
CREATE TABLE t2 (a VARCHAR(100)) ENGINE=InnoDB;
CREATE TABLE t3 (i INT NOT NULL PRIMARY KEY) ENGINE=InnoDB;
CREATE TABLE t4 (i INT NOT NULL PRIMARY KEY, t1i INT,
FOREIGN KEY (t1i) REFERENCES t1(i))
ENGINE=InnoDB;
CREATE TRIGGER trg AFTER DELETE ON t1 FOR EACH ROW
BEGIN
SET @b:='EXECUTED TRIGGER';
INSERT INTO t2 VALUES (@b);
SET @a:= error_happens_here;
END||
SET @b:="";
SET @a:="";
INSERT INTO t1 VALUES (1),(2),(3),(4);
INSERT INTO t3 SELECT * FROM t1;
** An error in a trigger causes rollback of the statement.
DELETE t1 FROM t3 LEFT JOIN t1 ON t1.i=t3.i;
ERROR 42S22: Unknown column 'error_happens_here' in 'field list'
SELECT @a,@b;
@a @b
EXECUTED TRIGGER
SELECT * FROM t2;
a
SELECT * FROM t1 LEFT JOIN t3 ON t1.i=t3.i;
i i
1 1
2 2
3 3
4 4
** Same happens with the IGNORE option
DELETE IGNORE t1 FROM t3 LEFT JOIN t1 ON t1.i=t3.i;
ERROR 42S22: Unknown column 'error_happens_here' in 'field list'
SELECT * FROM t2;
a
SELECT * FROM t1 LEFT JOIN t3 ON t1.i=t3.i;
i i
1 1
2 2
3 3
4 4
**
** The following is an attempt to demonstrate
** error handling inside a row iteration.
**
DROP TRIGGER trg;
TRUNCATE TABLE t1;
TRUNCATE TABLE t2;
TRUNCATE TABLE t3;
INSERT INTO t1 VALUES (1),(2),(3),(4);
INSERT INTO t3 VALUES (1),(2),(3),(4);
INSERT INTO t4 VALUES (3,3),(4,4);
CREATE TRIGGER trg AFTER DELETE ON t1 FOR EACH ROW
BEGIN
SET @b:= CONCAT('EXECUTED TRIGGER FOR ROW ',CAST(OLD.i AS CHAR));
INSERT INTO t2 VALUES (@b);
END||
** DELETE is prevented by foreign key constrains but errors are silenced.
** The AFTER trigger isn't fired.
DELETE IGNORE t1 FROM t3 LEFT JOIN t1 ON t1.i=t3.i;
** Tables are modified by best effort:
SELECT * FROM t1 LEFT JOIN t3 ON t1.i=t3.i;
i i
3 3
4 4
** The AFTER trigger was only executed on successful rows:
SELECT * FROM t2;
a
EXECUTED TRIGGER FOR ROW 1
EXECUTED TRIGGER FOR ROW 2
DROP TRIGGER trg;
**
** Induce an error midway through an AFTER-trigger
**
TRUNCATE TABLE t4;
TRUNCATE TABLE t1;
TRUNCATE TABLE t3;
INSERT INTO t1 VALUES (1),(2),(3),(4);
INSERT INTO t3 VALUES (1),(2),(3),(4);
CREATE TRIGGER trg AFTER DELETE ON t1 FOR EACH ROW
BEGIN
SET @a:= @a+1;
IF @a > 2 THEN
INSERT INTO t4 VALUES (5,5);
END IF;
END||
SET @a:=0;
** Errors in the trigger causes the statement to abort.
DELETE IGNORE t1 FROM t3 LEFT JOIN t1 ON t1.i=t3.i;
ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`t4`, CONSTRAINT `t4_ibfk_1` FOREIGN KEY (`t1i`) REFERENCES `t1` (`i`))
SELECT * FROM t1 LEFT JOIN t3 ON t1.i=t3.i;
i i
1 1
2 2
3 3
4 4
SELECT * FROM t4;
i t1i
DROP TRIGGER trg;
DROP TABLE t4;
DROP TABLE t1;
DROP TABLE t2;
DROP TABLE t3;
End of 5.1 tests
mysql-test/t/innodb_mysql.test
View file @
ba10c9cc
...
...
@@ -185,4 +185,151 @@ TRUNCATE TABLE t2;
DROP
TABLE
t2
;
DROP
TABLE
t1
;
--
echo
#
--
echo
# Bug#40127 Multiple table DELETE IGNORE hangs on foreign key constraint violation on 5.0
--
echo
#
CREATE
TABLE
t1
(
id
INT
UNSIGNED
NOT
NULL
AUTO_INCREMENT
,
PRIMARY
KEY
(
id
)
)
ENGINE
=
InnoDB
;
CREATE
TABLE
t2
(
id
INT
UNSIGNED
NOT
NULL
AUTO_INCREMENT
,
aid
INT
UNSIGNED
NOT
NULL
,
PRIMARY
KEY
(
id
),
FOREIGN
KEY
(
aid
)
REFERENCES
t1
(
id
)
)
ENGINE
=
InnoDB
;
CREATE
TABLE
t3
(
bid
INT
UNSIGNED
NOT
NULL
,
FOREIGN
KEY
(
bid
)
REFERENCES
t2
(
id
)
)
ENGINE
=
InnoDB
;
CREATE
TABLE
t4
(
a
INT
)
ENGINE
=
InnoDB
;
CREATE
TABLE
t5
(
a
INT
)
ENGINE
=
InnoDB
;
INSERT
INTO
t1
(
id
)
VALUES
(
1
);
INSERT
INTO
t2
(
id
,
aid
)
VALUES
(
1
,
1
),(
2
,
1
),(
3
,
1
),(
4
,
1
);
INSERT
INTO
t3
(
bid
)
VALUES
(
1
);
INSERT
INTO
t4
VALUES
(
1
),(
2
),(
3
),(
4
),(
5
);
INSERT
INTO
t5
VALUES
(
1
);
DELETE
t5
FROM
t4
LEFT
JOIN
t5
ON
t4
.
a
=
t5
.
a
;
--
error
ER_ROW_IS_REFERENCED_2
DELETE
t2
,
t1
FROM
t2
INNER
JOIN
t1
ON
(
t2
.
aid
=
t1
.
id
)
WHERE
t2
.
id
=
1
;
--
error
ER_ROW_IS_REFERENCED_2
DELETE
t2
,
t1
FROM
t2
INNER
JOIN
t1
ON
(
t2
.
aid
=
t1
.
id
)
WHERE
t2
.
id
=
1
;
DELETE
IGNORE
t2
,
t1
FROM
t2
INNER
JOIN
t1
ON
(
t2
.
aid
=
t1
.
id
)
WHERE
t2
.
id
=
1
;
DROP
TABLE
t3
;
DROP
TABLE
t2
;
DROP
TABLE
t1
;
DROP
TABLES
t4
,
t5
;
--
echo
# Bug#40127 Multiple table DELETE IGNORE hangs on foreign key constraint violation on 5.0
--
echo
# Testing for any side effects of IGNORE on AFTER DELETE triggers used with
--
echo
# transactional tables.
--
echo
#
CREATE
TABLE
t1
(
i
INT
NOT
NULL
PRIMARY
KEY
)
ENGINE
=
InnoDB
;
CREATE
TABLE
t2
(
a
VARCHAR
(
100
))
ENGINE
=
InnoDB
;
CREATE
TABLE
t3
(
i
INT
NOT
NULL
PRIMARY
KEY
)
ENGINE
=
InnoDB
;
CREATE
TABLE
t4
(
i
INT
NOT
NULL
PRIMARY
KEY
,
t1i
INT
,
FOREIGN
KEY
(
t1i
)
REFERENCES
t1
(
i
))
ENGINE
=
InnoDB
;
delimiter
||
;
CREATE
TRIGGER
trg
AFTER
DELETE
ON
t1
FOR
EACH
ROW
BEGIN
SET
@
b
:=
'EXECUTED TRIGGER'
;
INSERT
INTO
t2
VALUES
(
@
b
);
SET
@
a
:=
error_happens_here
;
END
||
delimiter
;
||
SET
@
b
:=
""
;
SET
@
a
:=
""
;
INSERT
INTO
t1
VALUES
(
1
),(
2
),(
3
),(
4
);
INSERT
INTO
t3
SELECT
*
FROM
t1
;
--
echo
**
An
error
in
a
trigger
causes
rollback
of
the
statement
.
--
error
ER_BAD_FIELD_ERROR
DELETE
t1
FROM
t3
LEFT
JOIN
t1
ON
t1
.
i
=
t3
.
i
;
SELECT
@
a
,
@
b
;
SELECT
*
FROM
t2
;
SELECT
*
FROM
t1
LEFT
JOIN
t3
ON
t1
.
i
=
t3
.
i
;
--
echo
**
Same
happens
with
the
IGNORE
option
--
error
ER_BAD_FIELD_ERROR
DELETE
IGNORE
t1
FROM
t3
LEFT
JOIN
t1
ON
t1
.
i
=
t3
.
i
;
SELECT
*
FROM
t2
;
SELECT
*
FROM
t1
LEFT
JOIN
t3
ON
t1
.
i
=
t3
.
i
;
--
echo
**
--
echo
**
The
following
is
an
attempt
to
demonstrate
--
echo
**
error
handling
inside
a
row
iteration
.
--
echo
**
DROP
TRIGGER
trg
;
TRUNCATE
TABLE
t1
;
TRUNCATE
TABLE
t2
;
TRUNCATE
TABLE
t3
;
INSERT
INTO
t1
VALUES
(
1
),(
2
),(
3
),(
4
);
INSERT
INTO
t3
VALUES
(
1
),(
2
),(
3
),(
4
);
INSERT
INTO
t4
VALUES
(
3
,
3
),(
4
,
4
);
delimiter
||
;
CREATE
TRIGGER
trg
AFTER
DELETE
ON
t1
FOR
EACH
ROW
BEGIN
SET
@
b
:=
CONCAT
(
'EXECUTED TRIGGER FOR ROW '
,
CAST
(
OLD
.
i
AS
CHAR
));
INSERT
INTO
t2
VALUES
(
@
b
);
END
||
delimiter
;
||
--
echo
**
DELETE
is
prevented
by
foreign
key
constrains
but
errors
are
silenced
.
--
echo
**
The
AFTER
trigger
isn
'
t
fired
.
DELETE
IGNORE
t1
FROM
t3
LEFT
JOIN
t1
ON
t1
.
i
=
t3
.
i
;
--
echo
**
Tables
are
modified
by
best
effort
:
SELECT
*
FROM
t1
LEFT
JOIN
t3
ON
t1
.
i
=
t3
.
i
;
--
echo
**
The
AFTER
trigger
was
only
executed
on
successful
rows
:
SELECT
*
FROM
t2
;
DROP
TRIGGER
trg
;
--
echo
**
--
echo
**
Induce
an
error
midway
through
an
AFTER
-
trigger
--
echo
**
TRUNCATE
TABLE
t4
;
TRUNCATE
TABLE
t1
;
TRUNCATE
TABLE
t3
;
INSERT
INTO
t1
VALUES
(
1
),(
2
),(
3
),(
4
);
INSERT
INTO
t3
VALUES
(
1
),(
2
),(
3
),(
4
);
delimiter
||
;
CREATE
TRIGGER
trg
AFTER
DELETE
ON
t1
FOR
EACH
ROW
BEGIN
SET
@
a
:=
@
a
+
1
;
IF
@
a
>
2
THEN
INSERT
INTO
t4
VALUES
(
5
,
5
);
END
IF
;
END
||
delimiter
;
||
SET
@
a
:=
0
;
--
echo
**
Errors
in
the
trigger
causes
the
statement
to
abort
.
--
error
ER_NO_REFERENCED_ROW_2
DELETE
IGNORE
t1
FROM
t3
LEFT
JOIN
t1
ON
t1
.
i
=
t3
.
i
;
SELECT
*
FROM
t1
LEFT
JOIN
t3
ON
t1
.
i
=
t3
.
i
;
SELECT
*
FROM
t4
;
DROP
TRIGGER
trg
;
DROP
TABLE
t4
;
DROP
TABLE
t1
;
DROP
TABLE
t2
;
DROP
TABLE
t3
;
--
echo
End
of
5.1
tests
sql/sql_delete.cc
View file @
ba10c9cc
...
...
@@ -709,6 +709,8 @@ bool multi_delete::send_data(List<Item> &values)
TABLE_LIST
*
del_table
;
DBUG_ENTER
(
"multi_delete::send_data"
);
bool
ignore
=
thd
->
lex
->
current_select
->
no_error
;
for
(
del_table
=
delete_tables
;
del_table
;
del_table
=
del_table
->
next_local
,
secure_counter
++
)
...
...
@@ -741,8 +743,12 @@ bool multi_delete::send_data(List<Item> &values)
TRG_ACTION_AFTER
,
FALSE
))
DBUG_RETURN
(
1
);
}
else
else
if
(
!
ignore
)
{
/*
If the IGNORE option is used errors caused by ha_delete_row don't
have to stop the iteration.
*/
table
->
file
->
print_error
(
error
,
MYF
(
0
));
DBUG_RETURN
(
1
);
}
...
...
@@ -834,6 +840,11 @@ int multi_delete::do_deletes()
{
int
local_error
=
0
,
counter
=
0
,
tmp_error
;
bool
will_batch
;
/*
If the IGNORE option is used all non fatal errors will be translated
to warnings and we should not break the row-by-row iteration
*/
bool
ignore
=
thd
->
lex
->
current_select
->
no_error
;
DBUG_ENTER
(
"do_deletes"
);
DBUG_ASSERT
(
do_delete
);
...
...
@@ -872,18 +883,29 @@ int multi_delete::do_deletes()
local_error
=
1
;
break
;
}
if
((
local_error
=
table
->
file
->
ha_delete_row
(
table
->
record
[
0
])))
local_error
=
table
->
file
->
ha_delete_row
(
table
->
record
[
0
]);
if
(
local_error
&&
!
ignore
)
{
table
->
file
->
print_error
(
local_error
,
MYF
(
0
));
break
;
table
->
file
->
print_error
(
local_error
,
MYF
(
0
));
break
;
}
deleted
++
;
if
(
table
->
triggers
&&
table
->
triggers
->
process_triggers
(
thd
,
TRG_EVENT_DELETE
,
TRG_ACTION_AFTER
,
FALSE
))
/*
Increase the reported number of deleted rows only if no error occurred
during ha_delete_row.
Also, don't execute the AFTER trigger if the row operation failed.
*/
if
(
!
local_error
)
{
local_error
=
1
;
break
;
deleted
++
;
if
(
table
->
triggers
&&
table
->
triggers
->
process_triggers
(
thd
,
TRG_EVENT_DELETE
,
TRG_ACTION_AFTER
,
FALSE
))
{
local_error
=
1
;
break
;
}
}
}
if
(
will_batch
&&
(
tmp_error
=
table
->
file
->
end_bulk_delete
()))
...
...
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