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
a535342d
Commit
a535342d
authored
Apr 10, 2004
by
bell@sanja.is.com.ua
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
after review PS fixes
parent
e8137a13
Changes
13
Show whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
527 additions
and
317 deletions
+527
-317
sql/item_cmpfunc.cc
sql/item_cmpfunc.cc
+2
-3
sql/mysql_priv.h
sql/mysql_priv.h
+15
-1
sql/set_var.cc
sql/set_var.cc
+25
-1
sql/sql_acl.cc
sql/sql_acl.cc
+3
-3
sql/sql_acl.h
sql/sql_acl.h
+2
-2
sql/sql_delete.cc
sql/sql_delete.cc
+36
-12
sql/sql_insert.cc
sql/sql_insert.cc
+40
-12
sql/sql_lex.cc
sql/sql_lex.cc
+13
-7
sql/sql_parse.cc
sql/sql_parse.cc
+188
-98
sql/sql_prepare.cc
sql/sql_prepare.cc
+142
-152
sql/sql_show.cc
sql/sql_show.cc
+1
-1
sql/sql_update.cc
sql/sql_update.cc
+58
-24
sql/table.h
sql/table.h
+2
-1
No files found.
sql/item_cmpfunc.cc
View file @
a535342d
...
...
@@ -477,9 +477,8 @@ bool Item_in_optimizer::fix_left(THD *thd,
struct
st_table_list
*
tables
,
Item
**
ref
)
{
if
((
!
args
[
0
]
->
fixed
&&
args
[
0
]
->
fix_fields
(
thd
,
tables
,
args
)))
return
1
;
if
(
!
cache
&&
!
(
cache
=
Item_cache
::
get_cache
(
args
[
0
]
->
result_type
())))
if
(
!
args
[
0
]
->
fixed
&&
args
[
0
]
->
fix_fields
(
thd
,
tables
,
args
)
||
!
cache
&&
!
(
cache
=
Item_cache
::
get_cache
(
args
[
0
]
->
result_type
())))
return
1
;
cache
->
setup
(
args
[
0
]);
...
...
sql/mysql_priv.h
View file @
a535342d
...
...
@@ -348,12 +348,17 @@ void cleanup_items(Item *item);
class
THD
;
void
close_thread_tables
(
THD
*
thd
,
bool
locked
=
0
,
bool
skip_derived
=
0
);
int
check_one_table_access
(
THD
*
thd
,
ulong
privilege
,
TABLE_LIST
*
tables
,
bool
no_errors
);
TABLE_LIST
*
tables
);
bool
check_merge_table_access
(
THD
*
thd
,
char
*
db
,
TABLE_LIST
*
table_list
);
int
multi_update_precheck
(
THD
*
thd
,
TABLE_LIST
*
tables
);
int
multi_delete_precheck
(
THD
*
thd
,
TABLE_LIST
*
tables
,
uint
*
table_count
);
int
insert_select_precheck
(
THD
*
thd
,
TABLE_LIST
*
tables
);
int
update_precheck
(
THD
*
thd
,
TABLE_LIST
*
tables
);
int
delete_precheck
(
THD
*
thd
,
TABLE_LIST
*
tables
);
int
insert_precheck
(
THD
*
thd
,
TABLE_LIST
*
tables
,
bool
update
);
int
create_table_precheck
(
THD
*
thd
,
TABLE_LIST
*
tables
,
TABLE_LIST
*
create_table
);
#include "sql_class.h"
#include "opt_range.h"
...
...
@@ -532,6 +537,9 @@ bool mysql_rename_table(enum db_type base,
int
mysql_create_index
(
THD
*
thd
,
TABLE_LIST
*
table_list
,
List
<
Key
>
&
keys
);
int
mysql_drop_index
(
THD
*
thd
,
TABLE_LIST
*
table_list
,
List
<
Alter_drop
>
&
drop_list
);
int
mysql_prepare_update
(
THD
*
thd
,
TABLE_LIST
*
table_list
,
TABLE_LIST
*
update_table_list
,
Item
**
conds
,
uint
order_num
,
ORDER
*
order
);
int
mysql_update
(
THD
*
thd
,
TABLE_LIST
*
tables
,
List
<
Item
>
&
fields
,
List
<
Item
>
&
values
,
COND
*
conds
,
uint
order_num
,
ORDER
*
order
,
ha_rows
limit
,
...
...
@@ -541,9 +549,15 @@ int mysql_multi_update(THD *thd, TABLE_LIST *table_list,
COND
*
conds
,
ulong
options
,
enum
enum_duplicates
handle_duplicates
,
SELECT_LEX_UNIT
*
unit
,
SELECT_LEX
*
select_lex
);
int
mysql_prepare_insert
(
THD
*
thd
,
TABLE_LIST
*
table_list
,
TABLE_LIST
*
insert_table_list
,
TABLE
*
table
,
List
<
Item
>
&
fields
,
List_item
*
values
,
List
<
Item
>
&
update_fields
,
List
<
Item
>
&
update_values
,
enum_duplicates
duplic
);
int
mysql_insert
(
THD
*
thd
,
TABLE_LIST
*
table
,
List
<
Item
>
&
fields
,
List
<
List_item
>
&
values
,
List
<
Item
>
&
update_fields
,
List
<
Item
>
&
update_values
,
enum_duplicates
flag
);
int
mysql_prepare_delete
(
THD
*
thd
,
TABLE_LIST
*
table_list
,
Item
**
conds
);
int
mysql_delete
(
THD
*
thd
,
TABLE_LIST
*
table
,
COND
*
conds
,
SQL_LIST
*
order
,
ha_rows
rows
,
ulong
options
);
int
mysql_truncate
(
THD
*
thd
,
TABLE_LIST
*
table_list
,
bool
dont_send_ok
=
0
);
...
...
sql/set_var.cc
View file @
a535342d
...
...
@@ -2529,6 +2529,18 @@ int set_var::check(THD *thd)
}
/*
Check variable, but without assigning value (used by PS)
SYNOPSIS
set_var::light_check()
thd thread handler
RETURN VALUE
0 ok
1 ERROR, message sent (normally no variables was updated)
-1 ERROR, message not sent
*/
int
set_var
::
light_check
(
THD
*
thd
)
{
if
(
var
->
check_type
(
type
))
...
...
@@ -2538,7 +2550,7 @@ int set_var::light_check(THD *thd)
var
->
name
);
return
-
1
;
}
if
(
(
type
==
OPT_GLOBAL
&&
check_global_access
(
thd
,
SUPER_ACL
)
))
if
(
type
==
OPT_GLOBAL
&&
check_global_access
(
thd
,
SUPER_ACL
))
return
1
;
if
(
value
&&
(
value
->
fix_fields
(
thd
,
0
,
&
value
)
||
value
->
check_cols
(
1
)))
...
...
@@ -2574,6 +2586,18 @@ int set_var_user::check(THD *thd)
}
/*
Check variable, but without assigning value (used by PS)
SYNOPSIS
set_var_user::light_check()
thd thread handler
RETURN VALUE
0 ok
1 ERROR, message sent (normally no variables was updated)
-1 ERROR, message not sent
*/
int
set_var_user
::
light_check
(
THD
*
thd
)
{
/*
...
...
sql/sql_acl.cc
View file @
a535342d
...
...
@@ -1388,7 +1388,7 @@ static bool test_if_create_new_users(THD *thd)
thd
->
priv_user
,
tl
.
db
,
0
);
if
(
!
(
db_access
&
INSERT_ACL
))
{
if
(
check_grant
(
thd
,
INSERT_ACL
,
&
tl
,
0
,
1
))
if
(
check_grant
(
thd
,
INSERT_ACL
,
&
tl
,
0
,
UINT_MAX
,
1
))
create_new_users
=
0
;
}
}
...
...
@@ -2650,7 +2650,7 @@ void grant_reload(THD *thd)
****************************************************************************/
bool
check_grant
(
THD
*
thd
,
ulong
want_access
,
TABLE_LIST
*
tables
,
uint
show_table
,
bool
no_errors
)
uint
show_table
,
uint
number
,
bool
no_errors
)
{
TABLE_LIST
*
table
;
char
*
user
=
thd
->
priv_user
;
...
...
@@ -2660,7 +2660,7 @@ bool check_grant(THD *thd, ulong want_access, TABLE_LIST *tables,
return
0
;
// ok
rw_rdlock
(
&
LOCK_grant
);
for
(
table
=
tables
;
table
;
table
=
table
->
next
)
for
(
table
=
tables
;
table
&&
number
--
;
table
=
table
->
next
)
{
if
(
!
(
~
table
->
grant
.
privilege
&
want_access
)
||
table
->
derived
)
{
...
...
sql/sql_acl.h
View file @
a535342d
...
...
@@ -154,7 +154,7 @@ my_bool grant_init(THD *thd);
void
grant_free
(
void
);
void
grant_reload
(
THD
*
thd
);
bool
check_grant
(
THD
*
thd
,
ulong
want_access
,
TABLE_LIST
*
tables
,
uint
show_command
,
bool
dont_print_error
);
uint
show_command
,
uint
number
,
bool
dont_print_error
);
bool
check_grant_column
(
THD
*
thd
,
TABLE
*
table
,
const
char
*
name
,
uint
length
,
uint
show_command
=
0
);
bool
check_grant_all_columns
(
THD
*
thd
,
ulong
want_access
,
TABLE
*
table
);
...
...
@@ -168,6 +168,6 @@ int mysql_drop_user(THD *thd, List <LEX_USER> &list);
int
mysql_revoke_all
(
THD
*
thd
,
List
<
LEX_USER
>
&
list
);
#ifdef NO_EMBEDDED_ACCESS_CHECKS
#define check_grant(A,B,C,D,E) 0
#define check_grant(A,B,C,D,E
,F
) 0
#define check_grant_db(A,B) 0
#endif
sql/sql_delete.cc
View file @
a535342d
...
...
@@ -37,8 +37,6 @@ int mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, SQL_LIST *order,
bool
using_limit
=
limit
!=
HA_POS_ERROR
;
bool
transactional_table
,
log_delayed
,
safe_update
,
const_cond
;
ha_rows
deleted
;
TABLE_LIST
*
delete_table_list
=
(
TABLE_LIST
*
)
thd
->
lex
->
select_lex
.
table_list
.
first
;
DBUG_ENTER
(
"mysql_delete"
);
if
((
open_and_lock_tables
(
thd
,
table_list
)))
...
...
@@ -47,15 +45,9 @@ int mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, SQL_LIST *order,
table
->
file
->
info
(
HA_STATUS_VARIABLE
|
HA_STATUS_NO_LOCK
);
thd
->
proc_info
=
"init"
;
table
->
map
=
1
;
if
(
setup_conds
(
thd
,
delete_table_list
,
&
conds
)
||
setup_ftfuncs
(
&
thd
->
lex
->
select_lex
))
DBUG_RETURN
(
-
1
);
if
(
find_real_table_in_list
(
table_list
->
next
,
table_list
->
db
,
table_list
->
real_name
))
{
my_error
(
ER_UPDATE_TABLE_USED
,
MYF
(
0
),
table_list
->
real_name
);
DBUG_RETURN
(
-
1
);
}
if
((
error
=
mysql_prepare_delete
(
thd
,
table_list
,
&
conds
)))
DBUG_RETURN
(
error
);
const_cond
=
(
!
conds
||
conds
->
const_item
());
safe_update
=
test
(
thd
->
options
&
OPTION_SAFE_UPDATES
);
...
...
@@ -246,6 +238,38 @@ cleanup:
}
/*
Prepare items in DELETE statement
SYNOPSIS
mysql_prepare_delete()
thd - thread handler
table_list - global table list
conds - conditions
RETURN VALUE
0 - OK
1 - error (message is sent to user)
-1 - error (message is not sent to user)
*/
int
mysql_prepare_delete
(
THD
*
thd
,
TABLE_LIST
*
table_list
,
Item
**
conds
)
{
TABLE_LIST
*
delete_table_list
=
(
TABLE_LIST
*
)
thd
->
lex
->
select_lex
.
table_list
.
first
;
DBUG_ENTER
(
" mysql_prepare_delete"
);
if
(
setup_conds
(
thd
,
delete_table_list
,
conds
)
||
setup_ftfuncs
(
&
thd
->
lex
->
select_lex
))
DBUG_RETURN
(
-
1
);
if
(
find_real_table_in_list
(
table_list
->
next
,
table_list
->
db
,
table_list
->
real_name
))
{
my_error
(
ER_UPDATE_TABLE_USED
,
MYF
(
0
),
table_list
->
real_name
);
DBUG_RETURN
(
-
1
);
}
}
/***************************************************************************
Delete multiple tables from join
***************************************************************************/
...
...
sql/sql_insert.cc
View file @
a535342d
...
...
@@ -207,19 +207,10 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list,
goto
abort
;
}
if
(
check_insert_fields
(
thd
,
table
,
fields
,
*
values
,
1
)
||
setup_tables
(
insert_table_list
)
||
setup_fields
(
thd
,
0
,
insert_table_list
,
*
values
,
0
,
0
,
0
)
||
(
duplic
==
DUP_UPDATE
&&
(
setup_fields
(
thd
,
0
,
insert_table_list
,
update_fields
,
0
,
0
,
0
)
||
setup_fields
(
thd
,
0
,
insert_table_list
,
update_values
,
0
,
0
,
0
))))
if
(
mysql_prepare_insert
(
thd
,
table_list
,
insert_table_list
,
table
,
fields
,
values
,
update_fields
,
update_values
,
duplic
))
goto
abort
;
if
(
find_real_table_in_list
(
table_list
->
next
,
table_list
->
db
,
table_list
->
real_name
))
{
my_error
(
ER_UPDATE_TABLE_USED
,
MYF
(
0
),
table_list
->
real_name
);
goto
abort
;
}
value_count
=
values
->
elements
;
while
((
values
=
its
++
))
...
...
@@ -438,6 +429,43 @@ abort:
}
/*
Prepare items in INSERT statement
SYNOPSIS
mysql_prepare_update()
thd - thread handler
table_list - global table list
insert_table_list - local table list of INSERT SELECT_LEX
RETURN VALUE
0 - OK
-1 - error (message is not sent to user)
*/
int
mysql_prepare_insert
(
THD
*
thd
,
TABLE_LIST
*
table_list
,
TABLE_LIST
*
insert_table_list
,
TABLE
*
table
,
List
<
Item
>
&
fields
,
List_item
*
values
,
List
<
Item
>
&
update_fields
,
List
<
Item
>
&
update_values
,
enum_duplicates
duplic
)
{
DBUG_ENTER
(
"mysql_prepare_insert"
);
if
(
check_insert_fields
(
thd
,
table
,
fields
,
*
values
,
1
)
||
setup_tables
(
insert_table_list
)
||
setup_fields
(
thd
,
0
,
insert_table_list
,
*
values
,
0
,
0
,
0
)
||
(
duplic
==
DUP_UPDATE
&&
(
setup_fields
(
thd
,
0
,
insert_table_list
,
update_fields
,
0
,
0
,
0
)
||
setup_fields
(
thd
,
0
,
insert_table_list
,
update_values
,
0
,
0
,
0
))))
DBUG_RETURN
(
-
1
);
if
(
find_real_table_in_list
(
table_list
->
next
,
table_list
->
db
,
table_list
->
real_name
))
{
my_error
(
ER_UPDATE_TABLE_USED
,
MYF
(
0
),
table_list
->
real_name
);
DBUG_RETURN
(
-
1
);
}
DBUG_RETURN
(
0
);
}
/* Check if there is more uniq keys after field */
static
int
last_uniq_key
(
TABLE
*
table
,
uint
keynr
)
...
...
sql/sql_lex.cc
View file @
a535342d
...
...
@@ -1634,8 +1634,10 @@ void st_select_lex::print_limit(THD *thd, String *str)
}
}
/*
unlink first table from table lists
Unlink first table from global table list and first must outer select list
(lex->select_lex)
SYNOPSIS
unlink_first_table()
...
...
@@ -1652,9 +1654,13 @@ TABLE_LIST *st_lex::unlink_first_table(TABLE_LIST *tables,
{
*
global_first
=
tables
;
*
local_first
=
(
TABLE_LIST
*
)
select_lex
.
table_list
.
first
;
// exclude from global table list
/*
exclude from global table list
*/
tables
=
tables
->
next
;
// and from local list if it is not the same
/*
and from local list if it is not the same
*/
if
(
&
select_lex
!=
all_selects_list
)
select_lex
.
table_list
.
first
=
(
gptr
)(
*
local_first
)
->
next
;
else
...
...
@@ -1663,8 +1669,9 @@ TABLE_LIST *st_lex::unlink_first_table(TABLE_LIST *tables,
return
tables
;
}
/*
link unlinked first table back
Link table back that was unlinked with unlink_first_table()
SYNOPSIS
link_first_table_back()
...
...
@@ -1680,7 +1687,6 @@ TABLE_LIST *st_lex::link_first_table_back(TABLE_LIST *tables,
TABLE_LIST
*
local_first
)
{
global_first
->
next
=
tables
;
tables
=
global_first
;
if
(
&
select_lex
!=
all_selects_list
)
{
/*
...
...
@@ -1690,8 +1696,8 @@ TABLE_LIST *st_lex::link_first_table_back(TABLE_LIST *tables,
select_lex
.
table_list
.
first
=
(
gptr
)
local_first
;
}
else
select_lex
.
table_list
.
first
=
(
gptr
)
tables
;
return
tables
;
select_lex
.
table_list
.
first
=
(
gptr
)
global_first
;
return
global_first
;
}
/*
...
...
sql/sql_parse.cc
View file @
a535342d
...
...
@@ -1173,7 +1173,7 @@ int mysql_table_dump(THD* thd, char* db, char* tbl_name, int fd)
if
(
!
(
table
=
open_ltable
(
thd
,
table_list
,
TL_READ_NO_INSERT
)))
DBUG_RETURN
(
1
);
if
(
check_one_table_access
(
thd
,
SELECT_ACL
,
table_list
,
0
))
if
(
check_one_table_access
(
thd
,
SELECT_ACL
,
table_list
))
goto
err
;
thd
->
free_list
=
0
;
thd
->
query_length
=
(
uint
)
strlen
(
tbl_name
);
...
...
@@ -1530,7 +1530,8 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
if
(
check_access
(
thd
,
SELECT_ACL
,
table_list
.
db
,
&
table_list
.
grant
.
privilege
,
0
,
0
))
break
;
if
(
grant_option
&&
check_grant
(
thd
,
SELECT_ACL
,
&
table_list
,
2
,
0
))
if
(
grant_option
&&
check_grant
(
thd
,
SELECT_ACL
,
&
table_list
,
2
,
UINT_MAX
,
0
))
break
;
mysqld_list_fields
(
thd
,
&
table_list
,
fields
);
free_items
(
thd
->
free_list
);
...
...
@@ -2135,10 +2136,7 @@ mysql_execute_command(THD *thd)
if
(
grant_option
)
{
/* Check that the first table has CREATE privilege */
TABLE_LIST
*
tmp_table_list
=
tables
->
next
;
tables
->
next
=
0
;
bool
error
=
check_grant
(
thd
,
CREATE_ACL
,
tables
,
0
,
0
);
tables
->
next
=
tmp_table_list
;
bool
error
=
check_grant
(
thd
,
CREATE_ACL
,
tables
,
0
,
1
,
0
);
if
(
error
)
goto
error
;
}
...
...
@@ -2169,18 +2167,9 @@ mysql_execute_command(THD *thd)
tables
=
lex
->
unlink_first_table
(
tables
,
&
create_table
,
&
create_table_local
);
ulong
want_priv
=
((
lex
->
create_info
.
options
&
HA_LEX_CREATE_TMP_TABLE
)
?
CREATE_TMP_ACL
:
CREATE_ACL
);
lex
->
create_info
.
alias
=
create_table
->
alias
;
if
(
check_access
(
thd
,
want_priv
,
create_table
->
db
,
&
create_table
->
grant
.
privilege
,
0
,
0
)
||
check_merge_table_access
(
thd
,
create_table
->
db
,
(
TABLE_LIST
*
)
lex
->
create_info
.
merge_list
.
first
))
goto
create_error
;
/* purecov: inspected */
if
(
grant_option
&&
want_priv
!=
CREATE_TMP_ACL
&&
check_grant
(
thd
,
want_priv
,
create_table
,
0
,
0
))
goto
create_error
;
if
((
res
=
create_table_precheck
(
thd
,
tables
,
create_table
)))
goto
unsent_create_error
;
#ifndef HAVE_READLINK
lex
->
create_info
.
data_file_name
=
lex
->
create_info
.
index_file_name
=
0
;
#else
...
...
@@ -2272,7 +2261,7 @@ unsent_create_error:
break
;
}
case
SQLCOM_CREATE_INDEX
:
if
(
check_one_table_access
(
thd
,
INDEX_ACL
,
tables
,
0
))
if
(
check_one_table_access
(
thd
,
INDEX_ACL
,
tables
))
goto
error
;
/* purecov: inspected */
thd
->
slow_command
=
TRUE
;
if
(
end_active_trans
(
thd
))
...
...
@@ -2339,7 +2328,7 @@ unsent_create_error:
goto
error
;
/* purecov: inspected */
if
(
grant_option
)
{
if
(
check_grant
(
thd
,
ALTER_ACL
,
tables
,
0
,
0
))
if
(
check_grant
(
thd
,
ALTER_ACL
,
tables
,
0
,
UINT_MAX
,
0
))
goto
error
;
if
(
lex
->
name
&&
!
test_all_bits
(
priv
,
INSERT_ACL
|
CREATE_ACL
))
{
// Rename of table
...
...
@@ -2348,7 +2337,8 @@ unsent_create_error:
tmp_table
.
real_name
=
lex
->
name
;
tmp_table
.
db
=
select_lex
->
db
;
tmp_table
.
grant
.
privilege
=
priv
;
if
(
check_grant
(
thd
,
INSERT_ACL
|
CREATE_ACL
,
&
tmp_table
,
0
,
0
))
if
(
check_grant
(
thd
,
INSERT_ACL
|
CREATE_ACL
,
&
tmp_table
,
0
,
UINT_MAX
,
0
))
goto
error
;
}
}
...
...
@@ -2397,10 +2387,11 @@ unsent_create_error:
old_list
=
table
[
0
];
new_list
=
table
->
next
[
0
];
old_list
.
next
=
new_list
.
next
=
0
;
if
(
check_grant
(
thd
,
ALTER_ACL
,
&
old_list
,
0
,
0
)
||
if
(
check_grant
(
thd
,
ALTER_ACL
,
&
old_list
,
0
,
UINT_MAX
,
0
)
||
(
!
test_all_bits
(
table
->
next
->
grant
.
privilege
,
INSERT_ACL
|
CREATE_ACL
)
&&
check_grant
(
thd
,
INSERT_ACL
|
CREATE_ACL
,
&
new_list
,
0
,
0
)))
check_grant
(
thd
,
INSERT_ACL
|
CREATE_ACL
,
&
new_list
,
0
,
UINT_MAX
,
0
)))
goto
error
;
}
}
...
...
@@ -2535,15 +2526,8 @@ unsent_create_error:
break
;
}
case
SQLCOM_UPDATE
:
if
(
select_lex
->
item_list
.
elements
!=
lex
->
value_list
.
elements
)
{
send_error
(
thd
,
ER_WRONG_VALUE_COUNT
);
DBUG_VOID_RETURN
;
}
if
(
check_db_used
(
thd
,
tables
))
goto
error
;
if
(
check_one_table_access
(
thd
,
UPDATE_ACL
,
tables
,
0
))
goto
error
;
if
(
update_precheck
(
thd
,
tables
))
break
;
res
=
mysql_update
(
thd
,
tables
,
select_lex
->
item_list
,
lex
->
value_list
,
...
...
@@ -2570,17 +2554,9 @@ unsent_create_error:
case
SQLCOM_REPLACE
:
case
SQLCOM_INSERT
:
{
my_bool
update
=
(
lex
->
value_list
.
elements
?
UPDATE_ACL
:
0
);
ulong
privilege
=
(
lex
->
duplicates
==
DUP_REPLACE
?
INSERT_ACL
|
DELETE_ACL
:
INSERT_ACL
|
update
);
if
(
check_one_table_access
(
thd
,
privilege
,
tables
,
0
))
goto
error
;
if
(
select_lex
->
item_list
.
elements
!=
lex
->
value_list
.
elements
)
{
send_error
(
thd
,
ER_WRONG_VALUE_COUNT
);
DBUG_VOID_RETURN
;
}
my_bool
update
=
(
lex
->
value_list
.
elements
?
UPDATE_ACL
:
0
);
if
((
res
=
insert_precheck
(
thd
,
tables
,
update
)))
break
;
res
=
mysql_insert
(
thd
,
tables
,
lex
->
field_list
,
lex
->
many_values
,
select_lex
->
item_list
,
lex
->
value_list
,
(
update
?
DUP_UPDATE
:
lex
->
duplicates
));
...
...
@@ -2634,7 +2610,7 @@ unsent_create_error:
break
;
}
case
SQLCOM_TRUNCATE
:
if
(
check_one_table_access
(
thd
,
DELETE_ACL
,
tables
,
0
))
if
(
check_one_table_access
(
thd
,
DELETE_ACL
,
tables
))
goto
error
;
/*
Don't allow this within a transaction because we want to use
...
...
@@ -2649,10 +2625,8 @@ unsent_create_error:
break
;
case
SQLCOM_DELETE
:
{
if
(
check_one_table_access
(
thd
,
DELETE_ACL
,
tables
,
0
))
goto
error
;
// Set privilege for the WHERE clause
tables
->
grant
.
want_privilege
=
(
SELECT_ACL
&
~
tables
->
grant
.
privilege
);
if
((
res
=
delete_precheck
(
thd
,
tables
)))
break
;
res
=
mysql_delete
(
thd
,
tables
,
select_lex
->
where
,
&
select_lex
->
order_list
,
select_lex
->
select_limit
,
select_lex
->
options
);
...
...
@@ -2664,10 +2638,9 @@ unsent_create_error:
{
TABLE_LIST
*
aux_tables
=
(
TABLE_LIST
*
)
thd
->
lex
->
auxilliary_table_list
.
first
;
TABLE_LIST
*
delete_tables
=
(
TABLE_LIST
*
)
select_lex
->
table_list
.
first
;
TABLE_LIST
*
auxi
;
uint
table_count
=
0
;
TABLE_LIST
*
target_tbl
;
uint
table_count
;
multi_delete
*
result
;
if
((
res
=
multi_delete_precheck
(
thd
,
tables
,
&
table_count
)))
break
;
...
...
@@ -2685,9 +2658,11 @@ unsent_create_error:
if
((
res
=
open_and_lock_tables
(
thd
,
tables
)))
break
;
/* Fix tables-to-be-deleted-from list to point at opened tables */
for
(
auxi
=
(
TABLE_LIST
*
)
aux_tables
;
auxi
;
auxi
=
auxi
->
next
)
for
(
target_tbl
=
(
TABLE_LIST
*
)
aux_tables
;
target_tbl
;
target_tbl
=
target_tbl
->
next
)
{
auxi
->
table
=
auxi
->
table_list
->
table
;
target_tbl
->
table
=
target_tbl
->
table_list
->
table
;
/*
Multi-delete can't be constructed over-union => we always have
single SELECT on top and have to check underlaying SELECTs of it
...
...
@@ -2697,10 +2672,11 @@ unsent_create_error:
un
=
un
->
next_unit
())
{
if
(
un
->
first_select
()
->
linkage
!=
DERIVED_TABLE_TYPE
&&
un
->
check_updateable
(
auxi
->
table_list
->
db
,
auxi
->
table_list
->
real_name
))
un
->
check_updateable
(
target_tbl
->
table_list
->
db
,
target_tbl
->
table_list
->
real_name
))
{
my_error
(
ER_UPDATE_TABLE_USED
,
MYF
(
0
),
auxi
->
table_list
->
real_name
);
my_error
(
ER_UPDATE_TABLE_USED
,
MYF
(
0
),
target_tbl
->
table_list
->
real_name
);
res
=
-
1
;
break
;
}
...
...
@@ -2758,7 +2734,7 @@ unsent_create_error:
}
break
;
case
SQLCOM_DROP_INDEX
:
if
(
check_one_table_access
(
thd
,
INDEX_ACL
,
tables
,
0
))
if
(
check_one_table_access
(
thd
,
INDEX_ACL
,
tables
))
goto
error
;
/* purecov: inspected */
if
(
end_active_trans
(
thd
))
res
=
-
1
;
...
...
@@ -2873,7 +2849,7 @@ unsent_create_error:
if
(
check_access
(
thd
,
SELECT_ACL
|
EXTRA_ACL
,
db
,
&
tables
->
grant
.
privilege
,
0
,
0
))
goto
error
;
/* purecov: inspected */
if
(
grant_option
&&
check_grant
(
thd
,
SELECT_ACL
,
tables
,
2
,
0
))
if
(
grant_option
&&
check_grant
(
thd
,
SELECT_ACL
,
tables
,
2
,
UINT_MAX
,
0
))
goto
error
;
res
=
mysqld_show_fields
(
thd
,
tables
,
(
lex
->
wild
?
lex
->
wild
->
ptr
()
:
NullS
),
...
...
@@ -2893,7 +2869,7 @@ unsent_create_error:
if
(
check_access
(
thd
,
SELECT_ACL
|
EXTRA_ACL
,
db
,
&
tables
->
grant
.
privilege
,
0
,
0
))
goto
error
;
/* purecov: inspected */
if
(
grant_option
&&
check_grant
(
thd
,
SELECT_ACL
,
tables
,
2
,
0
))
if
(
grant_option
&&
check_grant
(
thd
,
SELECT_ACL
,
tables
,
2
,
UINT_MAX
,
0
))
goto
error
;
res
=
mysqld_show_keys
(
thd
,
tables
);
break
;
...
...
@@ -2921,7 +2897,7 @@ unsent_create_error:
send_error
(
thd
,
ER_NOT_ALLOWED_COMMAND
);
goto
error
;
}
if
(
check_one_table_access
(
thd
,
privilege
,
tables
,
0
))
if
(
check_one_table_access
(
thd
,
privilege
,
tables
))
goto
error
;
}
res
=
mysql_load
(
thd
,
lex
->
exchange
,
tables
,
lex
->
field_list
,
...
...
@@ -3189,7 +3165,7 @@ unsent_create_error:
if
(
grant_option
&&
check_grant
(
thd
,
(
lex
->
grant
|
lex
->
grant_tot_col
|
GRANT_ACL
),
tables
,
0
,
0
))
tables
,
0
,
UINT_MAX
,
0
))
goto
error
;
if
(
!
(
res
=
mysql_table_grant
(
thd
,
tables
,
lex
->
users_list
,
lex
->
columns
,
lex
->
grant
,
...
...
@@ -3406,32 +3382,26 @@ error:
thd Thread handler
privilege requested privelage
tables table list of command
no_errors Don't send error to client
RETURN
0 - OK
1 - access denied, error is sent to client
*/
int
check_one_table_access
(
THD
*
thd
,
ulong
privilege
,
TABLE_LIST
*
tables
,
bool
no_errors
)
TABLE_LIST
*
tables
)
{
if
(
check_access
(
thd
,
privilege
,
tables
->
db
,
&
tables
->
grant
.
privilege
,
0
,
0
))
return
1
;
// Show only 1 table for check_grant
TABLE_LIST
*
subselects_tables
=
tables
->
next
;
tables
->
next
=
0
;
if
(
grant_option
&&
check_grant
(
thd
,
privilege
,
tables
,
0
,
0
))
{
tables
->
next
=
subselects_tables
;
if
(
grant_option
&&
check_grant
(
thd
,
privilege
,
tables
,
0
,
1
,
0
))
return
1
;
}
// check rights on tables of subselect (if exists)
if
(
subselects_tables
)
TABLE_LIST
*
subselects_tables
;
if
((
subselects_tables
=
tables
->
next
))
{
tables
->
next
=
subselects_tables
;
if
((
check_table_access
(
thd
,
SELECT_ACL
,
subselects_tables
,
0
)))
return
1
;
}
...
...
@@ -3610,7 +3580,7 @@ check_table_access(THD *thd, ulong want_access,TABLE_LIST *tables,
}
if
(
grant_option
)
return
check_grant
(
thd
,
want_access
&
~
EXTRA_ACL
,
org_tables
,
test
(
want_access
&
EXTRA_ACL
),
no_errors
);
test
(
want_access
&
EXTRA_ACL
),
UINT_MAX
,
no_errors
);
return
FALSE
;
}
...
...
@@ -4961,7 +4931,7 @@ int mysql_drop_index(THD *thd, TABLE_LIST *table_list, List<Alter_drop> &drop)
thd - thread handler
tables - global table list
RETURN
RETURN
VALUE
0 - OK
1 - error (message is sent to user)
-1 - error (message is not sent to user)
...
...
@@ -4986,27 +4956,30 @@ int multi_update_precheck(THD *thd, TABLE_LIST *tables)
*/
for
(
table
=
update_list
;
table
;
table
=
table
->
next
)
{
TABLE_LIST
*
save
=
table
->
next
;
table
->
next
=
0
;
if
((
check_access
(
thd
,
UPDATE_ACL
,
table
->
db
,
&
table
->
grant
.
privilege
,
0
,
1
)
||
grant_option
&&
check_grant
(
thd
,
UPDATE_ACL
,
table
,
0
,
1
))
&&
grant_option
&&
check_grant
(
thd
,
UPDATE_ACL
,
table
,
0
,
1
,
1
))
&&
(
check_access
(
thd
,
SELECT_ACL
,
table
->
db
,
&
table
->
grant
.
privilege
,
0
,
0
)
||
grant_option
&&
check_grant
(
thd
,
SELECT_ACL
,
table
,
0
,
0
)))
grant_option
&&
check_grant
(
thd
,
SELECT_ACL
,
table
,
0
,
1
,
0
)))
DBUG_RETURN
(
1
);
table
->
next
=
save
;
/*
We assign following flag only to copy of table, because it will
be checked only if query contains subqueries i.e. only if copy exists
*/
if
(
table
->
table_list
)
table
->
table_list
->
checked
=
1
;
table
->
table_list
->
table_in_update_from_clause
=
1
;
}
// tables of subqueries
/*
Is there tables of subqueries?
*/
if
(
&
lex
->
select_lex
!=
lex
->
all_selects_list
)
{
for
(
table
=
tables
;
table
;
table
=
table
->
next
)
{
if
(
table
->
checked
)
if
(
table
->
table_in_update_from_clause
)
{
table
->
checked
=
0
;
/*
If we check table by local TABLE_LIST copy then we should copy
grants to global table list, because it will be used for table
...
...
@@ -5017,13 +4990,10 @@ int multi_update_precheck(THD *thd, TABLE_LIST *tables)
}
else
{
TABLE_LIST
*
save
=
table
->
next
;
table
->
next
=
0
;
if
(
check_access
(
thd
,
SELECT_ACL
,
table
->
db
,
&
table
->
grant
.
privilege
,
0
,
0
)
||
grant_option
&&
check_grant
(
thd
,
SELECT_ACL
,
table
,
0
,
0
))
grant_option
&&
check_grant
(
thd
,
SELECT_ACL
,
table
,
0
,
1
,
0
))
DBUG_RETURN
(
1
);
table
->
next
=
save
;
}
}
}
...
...
@@ -5050,7 +5020,7 @@ int multi_update_precheck(THD *thd, TABLE_LIST *tables)
tables - global table list
table_count - pointer to table counter
RETURN
RETURN
VALUE
0 - OK
1 - error (message is sent to user)
-1 - error (message is not sent to user)
...
...
@@ -5062,7 +5032,9 @@ int multi_delete_precheck(THD *thd, TABLE_LIST *tables, uint *table_count)
TABLE_LIST
*
aux_tables
=
(
TABLE_LIST
*
)
thd
->
lex
->
auxilliary_table_list
.
first
;
TABLE_LIST
*
delete_tables
=
(
TABLE_LIST
*
)
select_lex
->
table_list
.
first
;
TABLE_LIST
*
auxi
;
TABLE_LIST
*
target_tbl
;
*
table_count
=
0
;
/* sql_yacc guarantees that tables and aux_tables are not zero */
DBUG_ASSERT
(
aux_tables
!=
0
);
...
...
@@ -5075,29 +5047,32 @@ int multi_delete_precheck(THD *thd, TABLE_LIST *tables, uint *table_count)
my_error
(
ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE
,
MYF
(
0
));
DBUG_RETURN
(
-
1
);
}
for
(
auxi
=
aux_tables
;
auxi
;
auxi
=
auxi
->
next
)
for
(
target_tbl
=
aux_tables
;
target_tbl
;
target_tbl
=
target_tbl
->
next
)
{
(
*
table_count
)
++
;
/* All tables in aux_tables must be found in FROM PART */
TABLE_LIST
*
walk
;
for
(
walk
=
delete_tables
;
walk
;
walk
=
walk
->
next
)
{
if
(
!
my_strcasecmp
(
table_alias_charset
,
auxi
->
alias
,
walk
->
alias
)
&&
!
strcmp
(
walk
->
db
,
auxi
->
db
))
if
(
!
my_strcasecmp
(
table_alias_charset
,
target_tbl
->
alias
,
walk
->
alias
)
&&
!
strcmp
(
walk
->
db
,
target_tbl
->
db
))
break
;
}
if
(
!
walk
)
{
my_error
(
ER_UNKNOWN_TABLE
,
MYF
(
0
),
auxi
->
real_name
,
"MULTI DELETE"
);
my_error
(
ER_UNKNOWN_TABLE
,
MYF
(
0
),
target_tbl
->
real_name
,
"MULTI DELETE"
);
DBUG_RETURN
(
-
1
);
}
if
(
walk
->
derived
)
{
my_error
(
ER_NON_UPDATABLE_TABLE
,
MYF
(
0
),
auxi
->
real_name
,
"DELETE"
);
my_error
(
ER_NON_UPDATABLE_TABLE
,
MYF
(
0
),
target_tbl
->
real_name
,
"DELETE"
);
DBUG_RETURN
(
-
1
);
}
walk
->
lock_type
=
auxi
->
lock_type
;
auxi
->
table_list
=
walk
;
// Remember corresponding table
walk
->
lock_type
=
target_tbl
->
lock_type
;
target_tbl
->
table_list
=
walk
;
// Remember corresponding table
}
DBUG_RETURN
(
0
);
}
...
...
@@ -5111,7 +5086,7 @@ int multi_delete_precheck(THD *thd, TABLE_LIST *tables, uint *table_count)
thd - thread handler
tables - global table list
RETURN
RETURN
VALUE
0 - OK
1 - error (message is sent to user)
-1 - error (message is not sent to user)
...
...
@@ -5125,7 +5100,122 @@ int insert_select_precheck(THD *thd, TABLE_LIST *tables)
*/
ulong
privilege
=
(
thd
->
lex
->
duplicates
==
DUP_REPLACE
?
INSERT_ACL
|
DELETE_ACL
:
INSERT_ACL
);
if
(
check_one_table_access
(
thd
,
privilege
,
tables
,
0
))
DBUG_RETURN
(
check_one_table_access
(
thd
,
privilege
,
tables
)
?
1
:
0
);
}
/*
simple UPDATE query pre-check
SYNOPSIS
update_precheck()
thd - thread handler
tables - global table list
RETURN VALUE
0 - OK
1 - error (message is sent to user)
-1 - error (message is not sent to user)
*/
int
update_precheck
(
THD
*
thd
,
TABLE_LIST
*
tables
)
{
DBUG_ENTER
(
"update_precheck"
);
if
(
thd
->
lex
->
select_lex
.
item_list
.
elements
!=
thd
->
lex
->
value_list
.
elements
)
{
my_error
(
ER_WRONG_VALUE_COUNT
,
MYF
(
0
));
DBUG_RETURN
(
-
1
);
}
DBUG_RETURN
((
check_db_used
(
thd
,
tables
)
||
check_one_table_access
(
thd
,
UPDATE_ACL
,
tables
))
?
1
:
0
);
}
/*
simple DELETE query pre-check
SYNOPSIS
delete_precheck()
thd - thread handler
tables - global table list
RETURN VALUE
0 - OK
1 - error (message is sent to user)
-1 - error (message is not sent to user)
*/
int
delete_precheck
(
THD
*
thd
,
TABLE_LIST
*
tables
)
{
DBUG_ENTER
(
"delete_precheck"
);
if
(
check_one_table_access
(
thd
,
DELETE_ACL
,
tables
))
DBUG_RETURN
(
1
);
// Set privilege for the WHERE clause
tables
->
grant
.
want_privilege
=
(
SELECT_ACL
&
~
tables
->
grant
.
privilege
);
DBUG_RETURN
(
0
);
}
/*
simple INSERT query pre-check
SYNOPSIS
insert_precheck()
thd - thread handler
tables - global table list
RETURN VALUE
0 - OK
1 - error (message is sent to user)
-1 - error (message is not sent to user)
*/
int
insert_precheck
(
THD
*
thd
,
TABLE_LIST
*
tables
,
bool
update
)
{
LEX
*
lex
=
thd
->
lex
;
DBUG_ENTER
(
"insert_precheck"
);
ulong
privilege
=
(
lex
->
duplicates
==
DUP_REPLACE
?
INSERT_ACL
|
DELETE_ACL
:
INSERT_ACL
|
update
);
if
(
check_one_table_access
(
thd
,
privilege
,
tables
))
DBUG_RETURN
(
1
);
if
(
lex
->
select_lex
.
item_list
.
elements
!=
lex
->
value_list
.
elements
)
{
my_error
(
ER_WRONG_VALUE_COUNT
,
MYF
(
0
));
DBUG_RETURN
(
-
1
);
}
DBUG_RETURN
(
0
);
}
/*
CREATE TABLE query pre-check
SYNOPSIS
create_table_precheck()
thd - thread handler
tables - global table list
create_table - table which will be created
RETURN VALUE
0 - OK
1 - error (message is sent to user)
-1 - error (message is not sent to user)
*/
int
create_table_precheck
(
THD
*
thd
,
TABLE_LIST
*
tables
,
TABLE_LIST
*
create_table
)
{
LEX
*
lex
=
thd
->
lex
;
DBUG_ENTER
(
"create_table_precheck"
);
ulong
want_priv
=
((
lex
->
create_info
.
options
&
HA_LEX_CREATE_TMP_TABLE
)
?
CREATE_TMP_ACL
:
CREATE_ACL
);
lex
->
create_info
.
alias
=
create_table
->
alias
;
if
(
check_access
(
thd
,
want_priv
,
create_table
->
db
,
&
create_table
->
grant
.
privilege
,
0
,
0
)
||
check_merge_table_access
(
thd
,
create_table
->
db
,
(
TABLE_LIST
*
)
lex
->
create_info
.
merge_list
.
first
))
DBUG_RETURN
(
1
);
DBUG_RETURN
((
grant_option
&&
want_priv
!=
CREATE_TMP_ACL
&&
check_grant
(
thd
,
want_priv
,
create_table
,
0
,
UINT_MAX
,
0
))
?
1
:
0
)
}
sql/sql_prepare.cc
View file @
a535342d
...
...
@@ -631,19 +631,21 @@ static bool emb_insert_params_withlog(Prepared_statement *stmt)
#endif
/*!EMBEDDED_LIBRARY*/
/*
Validate the following information for INSERT statement:
- field existence
- fields count
Validate INSERT statement:
SYNOPSIS
mysql_test_insert_fields()
mysql_test_insert()
stmt prepared statemen handler
tables list of tables queries
RETURN VALUE
0 ok
1 error, sent to the client
-1 error, not sent to client
*/
static
int
mysql_test_insert_fields
(
Prepared_statement
*
stmt
,
static
int
mysql_test_insert
(
Prepared_statement
*
stmt
,
TABLE_LIST
*
table_list
,
List
<
Item
>
&
fields
,
List
<
List_item
>
&
values_list
,
...
...
@@ -653,20 +655,16 @@ static int mysql_test_insert_fields(Prepared_statement *stmt,
{
THD
*
thd
=
stmt
->
thd
;
LEX
*
lex
=
stmt
->
lex
;
TABLE
*
table
;
List_iterator_fast
<
List_item
>
its
(
values_list
);
List_item
*
values
;
int
res
=
-
1
;
TABLE_LIST
*
insert_table_list
=
(
TABLE_LIST
*
)
lex
->
select_lex
.
table_list
.
first
;
my_bool
update
=
(
lex
->
value_list
.
elements
?
UPDATE_ACL
:
0
);
DBUG_ENTER
(
"mysql_test_insert_fields"
);
#ifndef NO_EMBEDDED_ACCESS_CHECKS
ulong
privilege
=
(
lex
->
duplicates
==
DUP_REPLACE
?
INSERT_ACL
|
DELETE_ACL
:
INSERT_ACL
);
if
(
check_one_table_access
(
thd
,
privilege
,
table_list
,
0
))
DBUG_RETURN
(
1
);
#endif
if
((
res
=
insert_precheck
(
thd
,
table_list
,
update
)))
DBUG_RETURN
(
res
);
/*
open temporary memory pool for temporary data allocated by derived
...
...
@@ -679,26 +677,15 @@ static int mysql_test_insert_fields(Prepared_statement *stmt,
DBUG_RETURN
(
-
1
);
}
table
=
table_list
->
table
;
if
((
values
=
its
++
))
{
uint
value_count
;
ulong
counter
=
0
;
if
(
check_insert_fields
(
thd
,
table
,
fields
,
*
values
,
1
)
||
setup_tables
(
insert_table_list
)
||
setup_fields
(
thd
,
0
,
insert_table_list
,
*
values
,
0
,
0
,
0
)
||
(
duplic
==
DUP_UPDATE
&&
(
setup_fields
(
thd
,
0
,
insert_table_list
,
update_fields
,
0
,
0
,
0
)
||
setup_fields
(
thd
,
0
,
insert_table_list
,
update_values
,
0
,
0
,
0
))))
if
((
res
=
mysql_prepare_insert
(
thd
,
table_list
,
insert_table_list
,
table_list
->
table
,
fields
,
values
,
update_fields
,
update_values
,
duplic
)))
goto
error
;
if
(
find_real_table_in_list
(
table_list
->
next
,
table_list
->
db
,
table_list
->
real_name
))
{
my_error
(
ER_UPDATE_TABLE_USED
,
MYF
(
0
),
table_list
->
real_name
);
goto
error
;
}
value_count
=
values
->
elements
;
its
.
rewind
();
...
...
@@ -717,50 +704,38 @@ static int mysql_test_insert_fields(Prepared_statement *stmt,
goto
error
;
}
}
lex
->
unit
.
cleanup
();
thd
->
free_temporary_memory_pool_for_ps_preparing
();
DBUG_RETURN
(
0
);
res
=
0
;
error:
lex
->
unit
.
cleanup
();
thd
->
free_temporary_memory_pool_for_ps_preparing
();
DBUG_RETURN
(
-
1
);
DBUG_RETURN
(
res
);
}
/*
Validate the following information:
UPDATE - set and where clause
DELETE - where clause
Validate UPDATE statement
SYNOPSIS
mysql_test_upd_fields()
mysql_test_delete()
stmt prepared statemen handler
tables list of tables queries
RETURN VALUE
0 success
1 error, sent to client
-1 error, not sent to client
*/
static
int
mysql_test_upd_fields
(
Prepared_statement
*
stmt
,
TABLE_LIST
*
table_list
,
List
<
Item
>
&
fields
,
List
<
Item
>
&
values
,
COND
*
conds
,
ulong
privelege
)
static
int
mysql_test_update
(
Prepared_statement
*
stmt
,
TABLE_LIST
*
table_list
)
{
int
res
;
THD
*
thd
=
stmt
->
thd
;
SELECT_LEX
*
select_lex
=
&
stmt
->
lex
->
select_lex
;
TABLE_LIST
*
upd_table_list
=
(
TABLE_LIST
*
)
select_lex
->
table_list
.
first
;
List
<
Item
>
all_fields
;
uint
order_num
=
select_lex
->
order_list
.
elements
;
ORDER
*
order
=
(
ORDER
*
)
select_lex
->
order_list
.
first
;
DBUG_ENTER
(
"mysql_test_upd_fields"
);
#ifndef NO_EMBEDDED_ACCESS_CHECKS
if
(
check_one_table_access
(
thd
,
privelege
,
table_list
,
0
))
DBUG_RETURN
(
1
);
// Set privilege for the WHERE clause
table_list
->
grant
.
want_privilege
=
(
SELECT_ACL
&
~
table_list
->
grant
.
privilege
);
#endif
SELECT_LEX
*
select
=
&
stmt
->
lex
->
select_lex
;
DBUG_ENTER
(
"mysql_test_update"
);
if
((
res
=
update_precheck
(
thd
,
table_list
)))
DBUG_RETURN
(
res
);
/*
open temporary memory pool for temporary data allocated by derived
...
...
@@ -769,57 +744,97 @@ static int mysql_test_upd_fields(Prepared_statement *stmt,
thd
->
allocate_temporary_memory_pool_for_ps_preparing
();
if
(
open_and_lock_tables
(
thd
,
table_list
))
goto
err
;
if
(
setup_tables
(
upd_table_list
)
||
setup_conds
(
thd
,
upd_table_list
,
&
conds
)
||
thd
->
lex
->
select_lex
.
setup_ref_array
(
thd
,
order_num
)
||
setup_fields
(
thd
,
0
,
upd_table_list
,
fields
,
1
,
0
,
0
)
||
setup_order
(
thd
,
thd
->
lex
->
select_lex
.
ref_pointer_array
,
upd_table_list
,
all_fields
,
all_fields
,
order
)
||
thd
->
net
.
report_error
)
res
=
-
1
;
else
{
stmt
->
lex
->
unit
.
cleanup
();
goto
err
;
TABLE_LIST
*
update_table_list
=
(
TABLE_LIST
*
)
select
->
table_list
.
first
;
if
(
!
(
res
=
mysql_prepare_update
(
thd
,
table_list
,
update_table_list
,
&
select
->
where
,
select
->
order_list
.
elements
,
(
ORDER
*
)
select
->
order_list
.
first
)))
{
if
(
setup_fields
(
thd
,
0
,
update_table_list
,
select
->
item_list
,
1
,
0
,
0
)
||
setup_fields
(
thd
,
0
,
update_table_list
,
stmt
->
lex
->
value_list
,
0
,
0
,
0
))
res
=
-
1
;
}
stmt
->
lex
->
unit
.
cleanup
();
}
thd
->
free_temporary_memory_pool_for_ps_preparing
();
/* TODO: here we should send types of placeholders to the client. */
DBUG_RETURN
(
0
);
err:
DBUG_RETURN
(
res
);
}
/*
Validate DELETE statement
SYNOPSIS
mysql_test_delete()
stmt prepared statemen handler
tables list of tables queries
RETURN VALUE
0 success
1 error, sent to client
-1 error, not sent to client
*/
static
int
mysql_test_delete
(
Prepared_statement
*
stmt
,
TABLE_LIST
*
table_list
)
{
int
res
;
THD
*
thd
=
stmt
->
thd
;
LEX
*
lex
=
stmt
->
lex
;
DBUG_ENTER
(
"mysql_test_delete"
);
if
((
res
=
delete_precheck
(
thd
,
table_list
)))
DBUG_RETURN
(
res
);
/*
open temporary memory pool for temporary data allocated by derived
tables & preparation procedure
*/
thd
->
allocate_temporary_memory_pool_for_ps_preparing
();
if
(
open_and_lock_tables
(
thd
,
table_list
))
res
=
-
1
;
else
{
res
=
mysql_prepare_delete
(
thd
,
table_list
,
&
lex
->
select_lex
.
where
);
lex
->
unit
.
cleanup
();
}
thd
->
free_temporary_memory_pool_for_ps_preparing
();
DBUG_RETURN
(
-
1
);
/* TODO: here we should send types of placeholders to the client. */
DBUG_RETURN
(
res
);
}
/*
Validate the following information:
SELECT - column list
- where clause
- order clause
- having clause
- group by clause
- if no column spec i.e. '*', then setup all fields
Validate SELECT statement.
In case of success, if this query is not EXPLAIN, send column list info
back to client.
SYNOPSIS
mysql_test_select_fields()
mysql_test_select()
stmt prepared statemen handler
tables list of tables queries
RETURN VALUE
0 success
1 error, sent to client
-1 error, not sent to client
*/
static
int
mysql_test_select_fields
(
Prepared_statement
*
stmt
,
TABLE_LIST
*
tables
,
List
<
Item
>
&
fields
)
static
int
mysql_test_select
(
Prepared_statement
*
stmt
,
TABLE_LIST
*
tables
)
{
THD
*
thd
=
stmt
->
thd
;
LEX
*
lex
=
stmt
->
lex
;
SELECT_LEX_UNIT
*
unit
=
&
lex
->
unit
;
DBUG_ENTER
(
"mysql_test_select_fields"
);
DBUG_ENTER
(
"mysql_test_select"
);
#ifndef NO_EMBEDDED_ACCESS_CHECKS
ulong
privilege
=
lex
->
exchange
?
SELECT_ACL
|
FILE_ACL
:
SELECT_ACL
;
...
...
@@ -852,14 +867,15 @@ static int mysql_test_select_fields(Prepared_statement *stmt,
{
thd
->
used_tables
=
0
;
// Updated by setup_fields
// JOIN::prepare calls
if
(
unit
->
prepare
(
thd
,
0
,
0
))
{
send_error
(
thd
);
goto
err_prep
;
}
if
(
send_prep_stmt
(
stmt
,
fields
.
elements
)
||
thd
->
protocol_simple
.
send_fields
(
&
fields
,
0
)
if
(
send_prep_stmt
(
stmt
,
lex
->
select_lex
.
item_list
.
elements
)
||
thd
->
protocol_simple
.
send_fields
(
&
lex
->
select_lex
.
item_list
,
0
)
#ifndef EMBEDDED_LIBRARY
||
net_flush
(
&
thd
->
net
)
#endif
...
...
@@ -964,11 +980,8 @@ static int mysql_test_set_fields(Prepared_statement *stmt,
goto
error
;
}
}
stmt
->
lex
->
unit
.
cleanup
();
thd
->
free_temporary_memory_pool_for_ps_preparing
();
DBUG_RETURN
(
0
);
error:
stmt
->
lex
->
unit
.
cleanup
();
thd
->
free_temporary_memory_pool_for_ps_preparing
();
DBUG_RETURN
(
res
);
}
...
...
@@ -982,7 +995,7 @@ error:
stmt - prepared table handler
tables - global list of tables
RETURN
RETURN
VALUE
0 success
1 error, sent to client
-1 error, not sent to client
...
...
@@ -1004,6 +1017,7 @@ static int select_like_statement_test(Prepared_statement *stmt,
thd
->
used_tables
=
0
;
// Updated by setup_fields
// JOIN::prepare calls
if
(
lex
->
unit
.
prepare
(
thd
,
0
,
0
))
{
res
=
thd
->
net
.
report_error
?
-
1
:
1
;
...
...
@@ -1036,36 +1050,22 @@ static int mysql_test_create_table(Prepared_statement *stmt,
LEX
*
lex
=
stmt
->
lex
;
int
res
=
0
;
ulong
want_priv
=
((
lex
->
create_info
.
options
&
HA_LEX_CREATE_TMP_TABLE
)
?
CREATE_TMP_ACL
:
CREATE_ACL
);
if
(
check_one_table_access
(
thd
,
want_priv
,
tables
,
0
)
||
check_merge_table_access
(
thd
,
tables
->
db
,
(
TABLE_LIST
*
)
lex
->
create_info
.
merge_list
.
first
))
DBUG_RETURN
(
1
);
/* Skip first table, which is the table we are creating */
TABLE_LIST
*
create_table
,
*
create_table_local
;
tables
=
lex
->
unlink_first_table
(
tables
,
&
create_table
,
&
create_table_local
);
if
(
grant_option
&&
want_priv
!=
CREATE_TMP_ACL
&&
check_grant
(
thd
,
want_priv
,
create_table
,
0
,
0
))
{
res
=
1
;
goto
end
;
}
if
(
tables
)
if
(
!
(
res
=
create_table_precheck
(
thd
,
tables
,
create_table
))
&&
lex
->
select_lex
.
item_list
.
elements
)
res
=
select_like_statement_test
(
stmt
,
tables
);
end:
// put tables back for PS rexecuting
/* put tables back for PS rexecuting */
tables
=
lex
->
link_first_table_back
(
tables
,
create_table
,
create_table_local
);
DBUG_RETURN
(
res
);
}
/*
Validate and prepare for execution multy update statement
...
...
@@ -1110,7 +1110,7 @@ static int mysql_test_multidelete(Prepared_statement *stmt,
if
(
add_item_to_list
(
stmt
->
thd
,
new
Item_null
()))
return
-
1
;
uint
fake_counter
=
0
;
uint
fake_counter
;
if
((
res
=
multi_delete_precheck
(
stmt
->
thd
,
tables
,
&
fake_counter
)))
return
res
;
return
select_like_statement_test
(
stmt
,
tables
);
...
...
@@ -1161,78 +1161,68 @@ static int mysql_test_insert_select(Prepared_statement *stmt,
*/
static
int
send_prepare_results
(
Prepared_statement
*
stmt
)
{
DBUG_ENTER
(
"send_prepare_results"
);
THD
*
thd
=
stmt
->
thd
;
LEX
*
lex
=
stmt
->
lex
;
SELECT_LEX
*
select_lex
=
&
lex
->
select_lex
;
TABLE_LIST
*
tables
=
(
TABLE_LIST
*
)
select_lex
->
table_list
.
first
;
enum
enum_sql_command
sql_command
=
lex
->
sql_command
;
int
res
;
int
res
=
0
;
DBUG_ENTER
(
"send_prepare_results"
);
DBUG_PRINT
(
"enter"
,(
"command: %d, param_count: %ld"
,
sql_command
,
stmt
->
param_count
));
if
(
&
lex
->
select_lex
!=
lex
->
all_selects_list
&&
if
(
select_lex
!=
lex
->
all_selects_list
&&
lex
->
unit
.
create_total_list
(
thd
,
lex
,
&
tables
))
DBUG_RETURN
(
1
);
switch
(
sql_command
)
{
case
SQLCOM_REPLACE
:
case
SQLCOM_INSERT
:
if
((
res
=
mysql_test_insert_fields
(
stmt
,
tables
,
lex
->
field_list
,
res
=
mysql_test_insert
(
stmt
,
tables
,
lex
->
field_list
,
lex
->
many_values
,
select_lex
->
item_list
,
lex
->
value_list
,
(
lex
->
value_list
.
elements
?
DUP_UPDATE
:
lex
->
duplicates
))))
goto
error
;
DUP_UPDATE
:
lex
->
duplicates
));
break
;
case
SQLCOM_UPDATE
:
/* XXX: fallthrough */
res
=
mysql_test_update
(
stmt
,
tables
);
break
;
case
SQLCOM_DELETE
:
if
((
res
=
mysql_test_upd_fields
(
stmt
,
tables
,
select_lex
->
item_list
,
lex
->
value_list
,
select_lex
->
where
,
((
sql_command
==
SQLCOM_DELETE
)
?
DELETE_ACL
:
UPDATE_ACL
))))
goto
error
;
res
=
mysql_test_delete
(
stmt
,
tables
);
break
;
case
SQLCOM_SELECT
:
if
((
res
=
mysql_test_select
_fields
(
stmt
,
tables
,
select_lex
->
item_list
)))
if
((
res
=
mysql_test_select
(
stmt
,
tables
)))
goto
error
;
/* Statement and field info has already been sent */
DBUG_RETURN
(
0
);
case
SQLCOM_CREATE_TABLE
:
if
((
res
=
mysql_test_create_table
(
stmt
,
tables
)))
goto
error
;
res
=
mysql_test_create_table
(
stmt
,
tables
);
break
;
case
SQLCOM_DO
:
if
((
res
=
mysql_test_do_fields
(
stmt
,
tables
,
lex
->
insert_list
)))
goto
error
;
res
=
mysql_test_do_fields
(
stmt
,
tables
,
lex
->
insert_list
);
break
;
case
SQLCOM_SET_OPTION
:
if
((
res
=
mysql_test_set_fields
(
stmt
,
tables
,
&
lex
->
var_list
)))
goto
error
;
res
=
mysql_test_set_fields
(
stmt
,
tables
,
&
lex
->
var_list
);
break
;
case
SQLCOM_DELETE_MULTI
:
if
((
res
=
mysql_test_multidelete
(
stmt
,
tables
)))
goto
error
;
res
=
mysql_test_multidelete
(
stmt
,
tables
);
break
;
case
SQLCOM_UPDATE_MULTI
:
if
((
res
=
mysql_test_multiupdate
(
stmt
,
tables
)))
goto
error
;
res
=
mysql_test_multiupdate
(
stmt
,
tables
);
break
;
case
SQLCOM_INSERT_SELECT
:
if
((
res
=
mysql_test_insert_select
(
stmt
,
tables
)))
goto
error
;
res
=
mysql_test_insert_select
(
stmt
,
tables
);
break
;
case
SQLCOM_SHOW_DATABASES
:
...
...
@@ -1263,8 +1253,8 @@ static int send_prepare_results(Prepared_statement *stmt)
my_error
(
ER_UNSUPPORTED_PS
,
MYF
(
0
));
goto
error
;
}
if
(
res
==
0
)
DBUG_RETURN
(
send_prep_stmt
(
stmt
,
0
));
error:
if
(
res
<
0
)
send_error
(
thd
,
thd
->
killed
?
ER_SERVER_SHUTDOWN
:
0
);
...
...
sql/sql_show.cc
View file @
a535342d
...
...
@@ -436,7 +436,7 @@ mysql_find_files(THD *thd,List<char> *files, const char *db,const char *path,
table_list
.
db
=
(
char
*
)
db
;
table_list
.
real_name
=
file
->
name
;
table_list
.
grant
.
privilege
=
col_access
;
if
(
check_grant
(
thd
,
TABLE_ACLS
,
&
table_list
,
1
,
1
))
if
(
check_grant
(
thd
,
TABLE_ACLS
,
&
table_list
,
1
,
UINT_MAX
,
1
))
continue
;
}
#endif
...
...
sql/sql_update.cc
View file @
a535342d
...
...
@@ -70,8 +70,6 @@ int mysql_update(THD *thd,
READ_RECORD
info
;
TABLE_LIST
*
update_table_list
=
((
TABLE_LIST
*
)
thd
->
lex
->
select_lex
.
table_list
.
first
);
TABLE_LIST
tables
;
List
<
Item
>
all_fields
;
DBUG_ENTER
(
"mysql_update"
);
LINT_INIT
(
used_index
);
...
...
@@ -86,30 +84,13 @@ int mysql_update(THD *thd,
/* Calculate "table->used_keys" based on the WHERE */
table
->
used_keys
=
table
->
keys_in_use
;
table
->
quick_keys
.
clear_all
();
#ifndef NO_EMBEDDED_ACCESS_CHECKS
want_privilege
=
table
->
grant
.
want_privilege
;
table
->
grant
.
want_privilege
=
(
SELECT_ACL
&
~
table
->
grant
.
privilege
);
want_privilege
=
table
->
grant
.
want_privilege
;
#endif
bzero
((
char
*
)
&
tables
,
sizeof
(
tables
));
// For ORDER BY
tables
.
table
=
table
;
tables
.
alias
=
table_list
->
alias
;
if
(
setup_tables
(
update_table_list
)
||
setup_conds
(
thd
,
update_table_list
,
&
conds
)
||
thd
->
lex
->
select_lex
.
setup_ref_array
(
thd
,
order_num
)
||
setup_order
(
thd
,
thd
->
lex
->
select_lex
.
ref_pointer_array
,
update_table_list
,
all_fields
,
all_fields
,
order
)
||
setup_ftfuncs
(
&
thd
->
lex
->
select_lex
))
DBUG_RETURN
(
-
1
);
/* purecov: inspected */
/* Check that we are not using table that we are updating in a sub select */
if
(
find_real_table_in_list
(
table_list
->
next
,
table_list
->
db
,
table_list
->
real_name
))
{
my_error
(
ER_UPDATE_TABLE_USED
,
MYF
(
0
),
table_list
->
real_name
);
DBUG_RETURN
(
-
1
);
}
if
((
error
=
mysql_prepare_update
(
thd
,
table_list
,
update_table_list
,
&
conds
,
order_num
,
order
)))
DBUG_RETURN
(
error
);
old_used_keys
=
table
->
used_keys
;
// Keys used in WHERE
/*
...
...
@@ -406,6 +387,59 @@ err:
DBUG_RETURN
(
-
1
);
}
/*
Prepare items in UPDATE statement
SYNOPSIS
mysql_prepare_update()
thd - thread handler
table_list - global table list
update_table_list - local table list of UPDATE SELECT_LEX
conds - conditions
order_num - number of ORDER BY list entries
order - ORDER BY clause list
RETURN VALUE
0 - OK
1 - error (message is sent to user)
-1 - error (message is not sent to user)
*/
int
mysql_prepare_update
(
THD
*
thd
,
TABLE_LIST
*
table_list
,
TABLE_LIST
*
update_table_list
,
Item
**
conds
,
uint
order_num
,
ORDER
*
order
)
{
TABLE
*
table
=
table_list
->
table
;
TABLE_LIST
tables
;
List
<
Item
>
all_fields
;
DBUG_ENTER
(
"mysql_prepare_update"
);
#ifndef NO_EMBEDDED_ACCESS_CHECKS
table
->
grant
.
want_privilege
=
(
SELECT_ACL
&
~
table
->
grant
.
privilege
);
#endif
bzero
((
char
*
)
&
tables
,
sizeof
(
tables
));
// For ORDER BY
tables
.
table
=
table
;
tables
.
alias
=
table_list
->
alias
;
if
(
setup_tables
(
update_table_list
)
||
setup_conds
(
thd
,
update_table_list
,
conds
)
||
thd
->
lex
->
select_lex
.
setup_ref_array
(
thd
,
order_num
)
||
setup_order
(
thd
,
thd
->
lex
->
select_lex
.
ref_pointer_array
,
update_table_list
,
all_fields
,
all_fields
,
order
)
||
setup_ftfuncs
(
&
thd
->
lex
->
select_lex
))
DBUG_RETURN
(
-
1
);
/* Check that we are not using table that we are updating in a sub select */
if
(
find_real_table_in_list
(
table_list
->
next
,
table_list
->
db
,
table_list
->
real_name
))
{
my_error
(
ER_UPDATE_TABLE_USED
,
MYF
(
0
),
table_list
->
real_name
);
DBUG_RETURN
(
-
1
);
}
DBUG_RETURN
(
0
);
}
/***************************************************************************
Update multiple tables from join
...
...
sql/table.h
View file @
a535342d
...
...
@@ -194,7 +194,8 @@ typedef struct st_table_list
bool
force_index
;
/* Prefer index over table scan */
bool
ignore_leaves
;
/* Preload only non-leaf nodes */
bool
cacheable_table
;
/* stop PS caching */
bool
checked
;
/* used in multi-upd privelege check */
/* used in multi-upd privelege check */
bool
table_in_update_from_clause
;
}
TABLE_LIST
;
typedef
struct
st_changed_table_list
...
...
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