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
97a1418d
Commit
97a1418d
authored
Sep 16, 2004
by
bell@sanja.is.com.ua
Browse files
Options
Browse Files
Download
Plain Diff
Merge sanja.is.com.ua:/home/bell/mysql/bk/mysql-4.1
into sanja.is.com.ua:/home/bell/mysql/bk/work-update-4.1
parents
f6dba131
0badc913
Changes
6
Show 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 @
97a1418d
...
@@ -455,3 +455,10 @@ create table t3 (a int, primary key (a));
...
@@ -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);
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
ERROR 42S02: Unknown table 't3' in MULTI DELETE
drop table t1, t2, t3;
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 @
97a1418d
...
@@ -417,3 +417,14 @@ create table t3 (a int, primary key (a));
...
@@ -417,3 +417,14 @@ create table t3 (a int, primary key (a));
--
error
1109
--
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
);
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
;
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 @
97a1418d
...
@@ -1550,6 +1550,7 @@ bool st_select_lex::setup_ref_array(THD *thd, uint order_group_num)
...
@@ -1550,6 +1550,7 @@ bool st_select_lex::setup_ref_array(THD *thd, uint order_group_num)
1 - found
1 - found
0 - OK (table did not found)
0 - OK (table did not found)
*/
*/
bool
st_select_lex_unit
::
check_updateable
(
char
*
db
,
char
*
table
)
bool
st_select_lex_unit
::
check_updateable
(
char
*
db
,
char
*
table
)
{
{
for
(
SELECT_LEX
*
sl
=
first_select
();
sl
;
sl
=
sl
->
next_select
())
for
(
SELECT_LEX
*
sl
=
first_select
();
sl
;
sl
=
sl
->
next_select
())
...
@@ -1561,7 +1562,7 @@ bool st_select_lex_unit::check_updateable(char *db, char *table)
...
@@ -1561,7 +1562,7 @@ bool st_select_lex_unit::check_updateable(char *db, char *table)
/*
/*
Find db.table which will be updated in this select and
Find db.table which will be updated in this select and
underlay
ed
ones (except derived tables)
underlay
ing
ones (except derived tables)
SYNOPSIS
SYNOPSIS
st_select_lex::check_updateable()
st_select_lex::check_updateable()
...
@@ -1572,11 +1573,30 @@ bool st_select_lex_unit::check_updateable(char *db, char *table)
...
@@ -1572,11 +1573,30 @@ bool st_select_lex_unit::check_updateable(char *db, char *table)
1 - found
1 - found
0 - OK (table did not found)
0 - OK (table did not found)
*/
*/
bool
st_select_lex
::
check_updateable
(
char
*
db
,
char
*
table
)
bool
st_select_lex
::
check_updateable
(
char
*
db
,
char
*
table
)
{
{
if
(
find_real_table_in_list
(
get_table_list
(),
db
,
table
))
if
(
find_real_table_in_list
(
get_table_list
(),
db
,
table
))
return
1
;
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
();
for
(
SELECT_LEX_UNIT
*
un
=
first_inner_unit
();
un
;
un
;
un
=
un
->
next_unit
())
un
=
un
->
next_unit
())
...
...
sql/sql_lex.h
View file @
97a1418d
...
@@ -517,6 +517,7 @@ public:
...
@@ -517,6 +517,7 @@ public:
}
}
bool
setup_ref_array
(
THD
*
thd
,
uint
order_group_num
);
bool
setup_ref_array
(
THD
*
thd
,
uint
order_group_num
);
bool
check_updateable
(
char
*
db
,
char
*
table
);
bool
check_updateable
(
char
*
db
,
char
*
table
);
bool
check_updateable_in_subqueries
(
char
*
db
,
char
*
table
);
void
print
(
THD
*
thd
,
String
*
str
);
void
print
(
THD
*
thd
,
String
*
str
);
static
void
print_order
(
String
*
str
,
ORDER
*
order
);
static
void
print_order
(
String
*
str
,
ORDER
*
order
);
void
print_limit
(
THD
*
thd
,
String
*
str
);
void
print_limit
(
THD
*
thd
,
String
*
str
);
...
...
sql/sql_parse.cc
View file @
97a1418d
...
@@ -2796,26 +2796,21 @@ unsent_create_error:
...
@@ -2796,26 +2796,21 @@ unsent_create_error:
target_tbl
;
target_tbl
;
target_tbl
=
target_tbl
->
next
)
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
Multi-delete can't be constructed over-union => we always have
single SELECT on top and have to check underlaying SELECTs of it
single SELECT on top and have to check underlaying SELECTs of it
*/
*/
for
(
SELECT_LEX_UNIT
*
un
=
lex
->
select_lex
.
first_inner_unit
();
if
(
lex
->
select_lex
.
check_updateable_in_subqueries
(
orig
->
db
,
un
;
orig
->
real_name
))
un
=
un
->
next_unit
())
{
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
),
my_error
(
ER_UPDATE_TABLE_USED
,
MYF
(
0
),
target_tbl
->
table_list
->
real_name
);
orig
->
real_name
);
res
=
-
1
;
res
=
-
1
;
break
;
break
;
}
}
}
}
}
if
(
!
thd
->
is_fatal_error
&&
(
result
=
new
multi_delete
(
thd
,
aux_tables
,
if
(
!
thd
->
is_fatal_error
&&
(
result
=
new
multi_delete
(
thd
,
aux_tables
,
table_count
)))
table_count
)))
...
...
sql/sql_update.cc
View file @
97a1418d
...
@@ -490,9 +490,8 @@ int mysql_multi_update(THD *thd,
...
@@ -490,9 +490,8 @@ int mysql_multi_update(THD *thd,
table
->
grant
.
want_privilege
=
(
UPDATE_ACL
&
~
table
->
grant
.
privilege
);
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
;
uint
tablenr
=
0
;
for
(
TABLE_LIST
*
table_list
=
update_list
;
for
(
TABLE_LIST
*
table_list
=
update_list
;
table_list
;
table_list
;
...
@@ -501,11 +500,12 @@ int mysql_multi_update(THD *thd,
...
@@ -501,11 +500,12 @@ int mysql_multi_update(THD *thd,
table_list
->
table
->
map
=
(
table_map
)
1
<<
tablenr
;
table_list
->
table
->
map
=
(
table_map
)
1
<<
tablenr
;
}
}
}
}
if
(
setup_fields
(
thd
,
0
,
update_list
,
*
fields
,
1
,
0
,
0
))
if
(
setup_fields
(
thd
,
0
,
update_list
,
*
fields
,
1
,
0
,
0
))
DBUG_RETURN
(
-
1
);
DBUG_RETURN
(
-
1
);
if
(
thd
->
lex
->
derived_tables
)
/* Find tables used in items */
{
{
// Find tables used in items
List_iterator_fast
<
Item
>
it
(
*
fields
);
List_iterator_fast
<
Item
>
it
(
*
fields
);
Item
*
item
;
Item
*
item
;
while
((
item
=
it
++
))
while
((
item
=
it
++
))
...
@@ -528,6 +528,22 @@ int mysql_multi_update(THD *thd,
...
@@ -528,6 +528,22 @@ int mysql_multi_update(THD *thd,
table
->
timestamp_field
->
query_id
==
thd
->
query_id
)
table
->
timestamp_field
->
query_id
==
thd
->
query_id
)
table
->
timestamp_on_update_now
=
0
;
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
)
if
(
tl
->
derived
)
derived_tables
|=
table
->
map
;
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