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