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
20b60510
Commit
20b60510
authored
Jul 15, 2004
by
marko@hundin.mysql.fi
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
InnoDB: limit the recursion depth for ON (UPDATE|DELETE) CASCADE
(Bug #4446)
parent
0614f8c7
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
91 additions
and
13 deletions
+91
-13
innobase/row/row0ins.c
innobase/row/row0ins.c
+65
-13
mysql-test/r/innodb.result
mysql-test/r/innodb.result
+12
-0
mysql-test/t/innodb.test
mysql-test/t/innodb.test
+14
-0
No files found.
innobase/row/row0ins.c
View file @
20b60510
...
...
@@ -370,6 +370,32 @@ row_ins_cascade_ancestor_updates_table(
return
(
FALSE
);
}
/*************************************************************************
Returns the number of ancestor UPDATE or DELETE nodes of a
cascaded update/delete node. */
static
ulint
row_ins_cascade_n_ancestors
(
/*========================*/
/* out: number of ancestors */
que_node_t
*
node
)
/* in: node in a query graph */
{
que_node_t
*
parent
;
ulint
n_ancestors
=
0
;
parent
=
que_node_get_parent
(
node
);
while
(
que_node_get_type
(
parent
)
==
QUE_NODE_UPDATE
)
{
n_ancestors
++
;
parent
=
que_node_get_parent
(
parent
);
ut_a
(
parent
);
}
return
(
n_ancestors
);
}
/**********************************************************************
Calculates the update vector node->cascade->update for a child table in
a cascaded update. */
...
...
@@ -615,6 +641,34 @@ row_ins_foreign_report_add_err(
mutex_exit
(
&
dict_foreign_err_mutex
);
}
/*************************************************************************
Invalidate the query cache for the given table. */
static
void
row_ins_invalidate_query_cache
(
/*===========================*/
que_thr_t
*
thr
,
/* in: query thread whose run_node
is an update node */
const
char
*
name
)
/* in: table name prefixed with
database name and a '/' character */
{
char
*
buf
;
char
*
ptr
;
ulint
len
=
strlen
(
name
)
+
1
;
buf
=
mem_strdupl
(
name
,
len
);
ptr
=
strchr
(
buf
,
'/'
);
ut_a
(
ptr
);
*
ptr
=
'\0'
;
/* We call a function in ha_innodb.cc */
#ifndef UNIV_HOTBACKUP
innobase_invalidate_query_cache
(
thr_get_trx
(
thr
),
buf
,
len
);
#endif
mem_free
(
buf
);
}
/*************************************************************************
Perform referential actions or checks when a parent row is deleted or updated
and the constraint had an ON DELETE or ON UPDATE condition which was not
...
...
@@ -650,26 +704,14 @@ row_ins_foreign_check_on_constraint(
ulint
n_to_update
;
ulint
err
;
ulint
i
;
char
*
ptr
;
char
table_name_buf
[
1000
];
ut_a
(
thr
&&
foreign
&&
pcur
&&
mtr
);
/* Since we are going to delete or update a row, we have to invalidate
the MySQL query cache for table */
ut_a
(
ut_strlen
(
table
->
name
)
<
998
);
strcpy
(
table_name_buf
,
table
->
name
);
row_ins_invalidate_query_cache
(
thr
,
table
->
name
);
ptr
=
strchr
(
table_name_buf
,
'/'
);
ut_a
(
ptr
);
*
ptr
=
'\0'
;
/* We call a function in ha_innodb.cc */
#ifndef UNIV_HOTBACKUP
innobase_invalidate_query_cache
(
thr_get_trx
(
thr
),
table_name_buf
,
ut_strlen
(
table
->
name
)
+
1
);
#endif
node
=
thr
->
run_node
;
if
(
node
->
is_delete
&&
0
==
(
foreign
->
type
&
...
...
@@ -756,6 +798,16 @@ row_ins_foreign_check_on_constraint(
goto
nonstandard_exit_func
;
}
if
(
row_ins_cascade_n_ancestors
(
cascade
)
>=
15
)
{
err
=
DB_ROW_IS_REFERENCED
;
row_ins_foreign_report_err
(
(
char
*
)
"Trying a too deep cascaded delete or update
\n
"
,
thr
,
foreign
,
btr_pcur_get_rec
(
pcur
),
entry
);
goto
nonstandard_exit_func
;
}
index
=
btr_pcur_get_btr_cur
(
pcur
)
->
index
;
ut_a
(
index
==
foreign
->
foreign_index
);
...
...
mysql-test/r/innodb.result
View file @
20b60510
...
...
@@ -1259,3 +1259,15 @@ Cannot delete or update a parent row: a foreign key constraint fails
update t3 set t3.id=7 where t1.id =1 and t2.id = t1.id and t3.id = t2.id;
Unknown table 't1' in where clause
drop table t3,t2,t1;
create table t1(
id int primary key,
pid int,
index(pid),
foreign key(pid) references t1(id) on delete cascade) type=innodb;
insert into t1 values(0,0),(1,0),(2,1),(3,2),(4,3),(5,4),(6,5),(7,6),
(8,7),(9,8),(10,9),(11,10),(12,11),(13,12),(14,13),(15,14);
delete from t1 where id=0;
Cannot delete or update a parent row: a foreign key constraint fails
delete from t1 where id=15;
delete from t1 where id=0;
drop table t1;
mysql-test/t/innodb.test
View file @
20b60510
...
...
@@ -896,3 +896,17 @@ update t1,t2,t3 set t3.id=5, t2.id=6, t1.id=7 where t1.id =1 and t2.id = t1.id
--
error
1109
update
t3
set
t3
.
id
=
7
where
t1
.
id
=
1
and
t2
.
id
=
t1
.
id
and
t3
.
id
=
t2
.
id
;
drop
table
t3
,
t2
,
t1
;
create
table
t1
(
id
int
primary
key
,
pid
int
,
index
(
pid
),
foreign
key
(
pid
)
references
t1
(
id
)
on
delete
cascade
)
type
=
innodb
;
insert
into
t1
values
(
0
,
0
),(
1
,
0
),(
2
,
1
),(
3
,
2
),(
4
,
3
),(
5
,
4
),(
6
,
5
),(
7
,
6
),
(
8
,
7
),(
9
,
8
),(
10
,
9
),(
11
,
10
),(
12
,
11
),(
13
,
12
),(
14
,
13
),(
15
,
14
);
--
error
1217
delete
from
t1
where
id
=
0
;
delete
from
t1
where
id
=
15
;
delete
from
t1
where
id
=
0
;
drop
table
t1
;
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