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
0badc913
Commit
0badc913
authored
Sep 08, 2004
by
bell@sanja.is.com.ua
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
check that table used in multi-update is unique added (BUG#5455)
parent
dab89186
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
70 additions
and
20 deletions
+70
-20
mysql-test/r/multi_update.result
mysql-test/r/multi_update.result
+7
-0
mysql-test/t/multi_update.test
mysql-test/t/multi_update.test
+11
-0
sql/sql_lex.cc
sql/sql_lex.cc
+21
-1
sql/sql_lex.h
sql/sql_lex.h
+1
-0
sql/sql_parse.cc
sql/sql_parse.cc
+9
-14
sql/sql_update.cc
sql/sql_update.cc
+21
-5
No files found.
mysql-test/r/multi_update.result
View file @
0badc913
...
...
@@ -455,3 +455,10 @@ create table t3 (a int, primary key (a));
delete t1,t3 from t1,t2 where t1.a=t2.a and t2.a=(select t3.a from t3 where t1.a=t3.a);
ERROR 42S02: Unknown table 't3' in MULTI DELETE
drop table t1, t2, t3;
create table t1 (col1 int);
create table t2 (col1 int);
update t1,t2 set t1.col1 = (select max(col1) from t1) where t1.col1 = t2.col1;
ERROR HY000: You can't specify target table 't1' for update in FROM clause
delete t1 from t1,t2 where t1.col1 < (select max(col1) from t1) and t1.col1 = t2.col1;
ERROR HY000: You can't specify target table 't1' for update in FROM clause
drop table t1,t2;
mysql-test/t/multi_update.test
View file @
0badc913
...
...
@@ -417,3 +417,14 @@ create table t3 (a int, primary key (a));
--
error
1109
delete
t1
,
t3
from
t1
,
t2
where
t1
.
a
=
t2
.
a
and
t2
.
a
=
(
select
t3
.
a
from
t3
where
t1
.
a
=
t3
.
a
);
drop
table
t1
,
t2
,
t3
;
#
# multi* unique updating table check
#
create
table
t1
(
col1
int
);
create
table
t2
(
col1
int
);
--
error
1093
update
t1
,
t2
set
t1
.
col1
=
(
select
max
(
col1
)
from
t1
)
where
t1
.
col1
=
t2
.
col1
;
--
error
1093
delete
t1
from
t1
,
t2
where
t1
.
col1
<
(
select
max
(
col1
)
from
t1
)
and
t1
.
col1
=
t2
.
col1
;
drop
table
t1
,
t2
;
sql/sql_lex.cc
View file @
0badc913
...
...
@@ -1548,6 +1548,7 @@ bool st_select_lex::setup_ref_array(THD *thd, uint order_group_num)
1 - found
0 - OK (table did not found)
*/
bool
st_select_lex_unit
::
check_updateable
(
char
*
db
,
char
*
table
)
{
for
(
SELECT_LEX
*
sl
=
first_select
();
sl
;
sl
=
sl
->
next_select
())
...
...
@@ -1559,7 +1560,7 @@ bool st_select_lex_unit::check_updateable(char *db, char *table)
/*
Find db.table which will be updated in this select and
underlay
ed
ones (except derived tables)
underlay
ing
ones (except derived tables)
SYNOPSIS
st_select_lex::check_updateable()
...
...
@@ -1570,11 +1571,30 @@ bool st_select_lex_unit::check_updateable(char *db, char *table)
1 - found
0 - OK (table did not found)
*/
bool
st_select_lex
::
check_updateable
(
char
*
db
,
char
*
table
)
{
if
(
find_real_table_in_list
(
get_table_list
(),
db
,
table
))
return
1
;
return
check_updateable_in_subqueries
(
db
,
table
);
}
/*
Find db.table which will be updated in underlaying subqueries
SYNOPSIS
st_select_lex::check_updateable_in_subqueries()
db - data base name
table - real table name
RETURN
1 - found
0 - OK (table did not found)
*/
bool
st_select_lex
::
check_updateable_in_subqueries
(
char
*
db
,
char
*
table
)
{
for
(
SELECT_LEX_UNIT
*
un
=
first_inner_unit
();
un
;
un
=
un
->
next_unit
())
...
...
sql/sql_lex.h
View file @
0badc913
...
...
@@ -517,6 +517,7 @@ class st_select_lex: public st_select_lex_node
}
bool
setup_ref_array
(
THD
*
thd
,
uint
order_group_num
);
bool
check_updateable
(
char
*
db
,
char
*
table
);
bool
check_updateable_in_subqueries
(
char
*
db
,
char
*
table
);
void
print
(
THD
*
thd
,
String
*
str
);
static
void
print_order
(
String
*
str
,
ORDER
*
order
);
void
print_limit
(
THD
*
thd
,
String
*
str
);
...
...
sql/sql_parse.cc
View file @
0badc913
...
...
@@ -2796,24 +2796,19 @@ mysql_execute_command(THD *thd)
target_tbl
;
target_tbl
=
target_tbl
->
next
)
{
target_tbl
->
table
=
target_tbl
->
table_list
->
table
;
/*
TABLE_LIST
*
orig
=
target_tbl
->
table_list
;
target_tbl
->
table
=
orig
->
table
;
/*
Multi-delete can't be constructed over-union => we always have
single SELECT on top and have to check underlaying SELECTs of it
*/
for
(
SELECT_LEX_UNIT
*
un
=
lex
->
select_lex
.
first_inner_unit
();
un
;
un
=
un
->
next_unit
())
if
(
lex
->
select_lex
.
check_updateable_in_subqueries
(
orig
->
db
,
orig
->
real_name
))
{
if
(
un
->
first_select
()
->
linkage
!=
DERIVED_TABLE_TYPE
&&
un
->
check_updateable
(
target_tbl
->
table_list
->
db
,
target_tbl
->
table_list
->
real_name
))
{
my_error
(
ER_UPDATE_TABLE_USED
,
MYF
(
0
),
target_tbl
->
table_list
->
real_name
);
res
=
-
1
;
break
;
}
my_error
(
ER_UPDATE_TABLE_USED
,
MYF
(
0
),
orig
->
real_name
);
res
=
-
1
;
break
;
}
}
...
...
sql/sql_update.cc
View file @
0badc913
...
...
@@ -490,9 +490,8 @@ int mysql_multi_update(THD *thd,
table
->
grant
.
want_privilege
=
(
UPDATE_ACL
&
~
table
->
grant
.
privilege
);
}
if
(
thd
->
lex
->
derived_tables
)
/* Assign table map values to check updatability of derived tables */
{
// Assign table map values to check updatability of derived tables
uint
tablenr
=
0
;
for
(
TABLE_LIST
*
table_list
=
update_list
;
table_list
;
...
...
@@ -501,11 +500,12 @@ int mysql_multi_update(THD *thd,
table_list
->
table
->
map
=
(
table_map
)
1
<<
tablenr
;
}
}
if
(
setup_fields
(
thd
,
0
,
update_list
,
*
fields
,
1
,
0
,
0
))
DBUG_RETURN
(
-
1
);
if
(
thd
->
lex
->
derived_tables
)
/* Find tables used in items */
{
// Find tables used in items
List_iterator_fast
<
Item
>
it
(
*
fields
);
Item
*
item
;
while
((
item
=
it
++
))
...
...
@@ -527,7 +527,23 @@ int mysql_multi_update(THD *thd,
if
(
table
->
timestamp_field
&&
table
->
timestamp_field
->
query_id
==
thd
->
query_id
)
table
->
timestamp_on_update_now
=
0
;
/* if table will be updated then check that it is unique */
if
(
table
->
map
&
item_tables
)
{
/*
Multi-update can't be constructed over-union => we always have
single SELECT on top and have to check underlaying SELECTs of it
*/
if
(
select_lex
->
check_updateable_in_subqueries
(
tl
->
db
,
tl
->
real_name
))
{
my_error
(
ER_UPDATE_TABLE_USED
,
MYF
(
0
),
tl
->
real_name
);
DBUG_RETURN
(
-
1
);
}
}
if
(
tl
->
derived
)
derived_tables
|=
table
->
map
;
}
...
...
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