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
6d6b617a
Commit
6d6b617a
authored
Dec 06, 2005
by
timour@mysql.com
Browse files
Options
Browse Files
Download
Plain Diff
Merge mysql.com:/home/timka/mysql/src/5.0-virgin
into mysql.com:/home/timka/mysql/src/5.0-2486
parents
c6fc5d35
687b66b8
Changes
14
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
294 additions
and
375 deletions
+294
-375
sql/item.cc
sql/item.cc
+1
-1
sql/item.h
sql/item.h
+42
-0
sql/mysql_priv.h
sql/mysql_priv.h
+9
-11
sql/sql_acl.cc
sql/sql_acl.cc
+84
-20
sql/sql_acl.h
sql/sql_acl.h
+3
-1
sql/sql_base.cc
sql/sql_base.cc
+47
-159
sql/sql_insert.cc
sql/sql_insert.cc
+18
-79
sql/sql_lex.cc
sql/sql_lex.cc
+5
-0
sql/sql_lex.h
sql/sql_lex.h
+2
-2
sql/sql_list.h
sql/sql_list.h
+17
-2
sql/sql_parse.cc
sql/sql_parse.cc
+13
-10
sql/sql_yacc.yy
sql/sql_yacc.yy
+6
-15
sql/table.cc
sql/table.cc
+42
-68
sql/table.h
sql/table.h
+5
-7
No files found.
sql/item.cc
View file @
6d6b617a
...
@@ -5165,7 +5165,7 @@ void Item_trigger_field::setup_field(THD *thd, TABLE *table)
...
@@ -5165,7 +5165,7 @@ void Item_trigger_field::setup_field(THD *thd, TABLE *table)
set field_idx properly.
set field_idx properly.
*/
*/
(
void
)
find_field_in_table
(
thd
,
table
,
field_name
,
(
uint
)
strlen
(
field_name
),
(
void
)
find_field_in_table
(
thd
,
table
,
field_name
,
(
uint
)
strlen
(
field_name
),
0
,
0
,
&
field_idx
,
0
);
0
,
&
field_idx
);
thd
->
set_query_id
=
save_set_query_id
;
thd
->
set_query_id
=
save_set_query_id
;
triggers
=
table
->
triggers
;
triggers
=
table
->
triggers
;
}
}
...
...
sql/item.h
View file @
6d6b617a
...
@@ -326,6 +326,48 @@ struct Name_resolution_context: Sql_alloc
...
@@ -326,6 +326,48 @@ struct Name_resolution_context: Sql_alloc
};
};
/*
Store and restore the current state of a name resolution context.
*/
class
Name_resolution_context_state
{
private:
TABLE_LIST
*
save_table_list
;
TABLE_LIST
*
save_first_name_resolution_table
;
TABLE_LIST
*
save_next_name_resolution_table
;
bool
save_resolve_in_select_list
;
public:
TABLE_LIST
*
save_next_local
;
public:
/* Save the state of a name resolution context. */
void
save_state
(
Name_resolution_context
*
context
,
TABLE_LIST
*
table_list
)
{
save_table_list
=
context
->
table_list
;
save_first_name_resolution_table
=
context
->
first_name_resolution_table
;
save_next_name_resolution_table
=
(
context
->
first_name_resolution_table
)
?
context
->
first_name_resolution_table
->
next_name_resolution_table
:
NULL
;
save_resolve_in_select_list
=
context
->
resolve_in_select_list
;
save_next_local
=
table_list
->
next_local
;
}
/* Restore a name resolution context from saved state. */
void
restore_state
(
Name_resolution_context
*
context
,
TABLE_LIST
*
table_list
)
{
table_list
->
next_local
=
save_next_local
;
context
->
table_list
=
save_table_list
;
context
->
first_name_resolution_table
=
save_first_name_resolution_table
;
if
(
context
->
first_name_resolution_table
)
context
->
first_name_resolution_table
->
next_name_resolution_table
=
save_next_name_resolution_table
;
context
->
resolve_in_select_list
=
save_resolve_in_select_list
;
}
};
/*************************************************************************/
/*************************************************************************/
typedef
bool
(
Item
::*
Item_processor
)(
byte
*
arg
);
typedef
bool
(
Item
::*
Item_processor
)(
byte
*
arg
);
...
...
sql/mysql_priv.h
View file @
6d6b617a
...
@@ -791,18 +791,15 @@ find_field_in_tables(THD *thd, Item_ident *item,
...
@@ -791,18 +791,15 @@ find_field_in_tables(THD *thd, Item_ident *item,
bool
check_privileges
,
bool
register_tree_change
);
bool
check_privileges
,
bool
register_tree_change
);
Field
*
Field
*
find_field_in_table_ref
(
THD
*
thd
,
TABLE_LIST
*
table_list
,
find_field_in_table_ref
(
THD
*
thd
,
TABLE_LIST
*
table_list
,
const
char
*
name
,
const
char
*
item_name
,
const
char
*
name
,
uint
length
,
const
char
*
table_name
,
const
char
*
db_name
,
const
char
*
item_name
,
const
char
*
db_name
,
uint
length
,
Item
**
ref
,
const
char
*
table_name
,
Item
**
ref
,
bool
check_grants_table
,
bool
check_grants_view
,
bool
check_privileges
,
bool
allow_rowid
,
bool
allow_rowid
,
uint
*
cached_field_index_ptr
,
uint
*
cached_field_index_ptr
,
bool
register_tree_change
,
TABLE_LIST
**
actual_table
);
bool
register_tree_change
,
TABLE_LIST
**
actual_table
);
Field
*
Field
*
find_field_in_table
(
THD
*
thd
,
TABLE
*
table
,
const
char
*
name
,
find_field_in_table
(
THD
*
thd
,
TABLE
*
table
,
const
char
*
name
,
uint
length
,
uint
length
,
bool
check_grants
,
bool
allow_rowid
,
bool
allow_rowid
,
uint
*
cached_field_index_ptr
);
uint
*
cached_field_index_ptr
,
Security_context
*
sctx
);
#ifdef HAVE_OPENSSL
#ifdef HAVE_OPENSSL
#include <openssl/des.h>
#include <openssl/des.h>
...
@@ -918,8 +915,9 @@ create_field * new_create_field(THD *thd, char *field_name, enum_field_types typ
...
@@ -918,8 +915,9 @@ create_field * new_create_field(THD *thd, char *field_name, enum_field_types typ
uint
uint_geom_type
);
uint
uint_geom_type
);
void
store_position_for_column
(
const
char
*
name
);
void
store_position_for_column
(
const
char
*
name
);
bool
add_to_list
(
THD
*
thd
,
SQL_LIST
&
list
,
Item
*
group
,
bool
asc
);
bool
add_to_list
(
THD
*
thd
,
SQL_LIST
&
list
,
Item
*
group
,
bool
asc
);
Name_resolution_context
*
make_join_on_context
(
THD
*
thd
,
TABLE_LIST
*
left_op
,
bool
push_new_name_resolution_context
(
THD
*
thd
,
TABLE_LIST
*
right_op
);
TABLE_LIST
*
left_op
,
TABLE_LIST
*
right_op
);
void
add_join_on
(
TABLE_LIST
*
b
,
Item
*
expr
);
void
add_join_on
(
TABLE_LIST
*
b
,
Item
*
expr
);
void
add_join_natural
(
TABLE_LIST
*
a
,
TABLE_LIST
*
b
,
List
<
String
>
*
using_fields
);
void
add_join_natural
(
TABLE_LIST
*
a
,
TABLE_LIST
*
b
,
List
<
String
>
*
using_fields
);
bool
add_proc_to_list
(
THD
*
thd
,
Item
*
item
);
bool
add_proc_to_list
(
THD
*
thd
,
Item
*
item
);
...
...
sql/sql_acl.cc
View file @
6d6b617a
...
@@ -2761,8 +2761,9 @@ bool mysql_table_grant(THD *thd, TABLE_LIST *table_list,
...
@@ -2761,8 +2761,9 @@ bool mysql_table_grant(THD *thd, TABLE_LIST *table_list,
uint
unused_field_idx
=
NO_CACHED_FIELD_INDEX
;
uint
unused_field_idx
=
NO_CACHED_FIELD_INDEX
;
TABLE_LIST
*
dummy
;
TABLE_LIST
*
dummy
;
Field
*
f
=
find_field_in_table_ref
(
thd
,
table_list
,
column
->
column
.
ptr
(),
Field
*
f
=
find_field_in_table_ref
(
thd
,
table_list
,
column
->
column
.
ptr
(),
column
->
column
.
length
(),
column
->
column
.
ptr
(),
NULL
,
NULL
,
column
->
column
.
ptr
(),
NULL
,
NULL
,
column
->
column
.
length
(),
0
,
1
,
1
,
0
,
NULL
,
TRUE
,
FALSE
,
&
unused_field_idx
,
FALSE
,
&
dummy
);
&
unused_field_idx
,
FALSE
,
&
dummy
);
if
(
f
==
(
Field
*
)
0
)
if
(
f
==
(
Field
*
)
0
)
{
{
...
@@ -3616,11 +3617,28 @@ err:
...
@@ -3616,11 +3617,28 @@ err:
}
}
/*
Check column rights in given security context
SYNOPSIS
check_grant_column()
thd thread handler
grant grant information structure
db_name db name
table_name table name
name column name
length column name length
sctx security context
RETURN
FALSE OK
TRUE access denied
*/
bool
check_grant_column
(
THD
*
thd
,
GRANT_INFO
*
grant
,
bool
check_grant_column
(
THD
*
thd
,
GRANT_INFO
*
grant
,
const
char
*
db_name
,
const
char
*
table_name
,
const
char
*
db_name
,
const
char
*
table_name
,
const
char
*
name
,
uint
length
,
uint
show_tables
)
const
char
*
name
,
uint
length
,
Security_context
*
sctx
)
{
{
Security_context
*
sctx
=
thd
->
security_ctx
;
GRANT_TABLE
*
grant_table
;
GRANT_TABLE
*
grant_table
;
GRANT_COLUMN
*
grant_column
;
GRANT_COLUMN
*
grant_column
;
ulong
want_access
=
grant
->
want_privilege
&
~
grant
->
privilege
;
ulong
want_access
=
grant
->
want_privilege
&
~
grant
->
privilege
;
...
@@ -3651,28 +3669,74 @@ bool check_grant_column(THD *thd, GRANT_INFO *grant,
...
@@ -3651,28 +3669,74 @@ bool check_grant_column(THD *thd, GRANT_INFO *grant,
rw_unlock
(
&
LOCK_grant
);
rw_unlock
(
&
LOCK_grant
);
DBUG_RETURN
(
0
);
DBUG_RETURN
(
0
);
}
}
#ifdef NOT_USED
if
(
show_tables
&&
(
grant_column
||
grant
->
privilege
&
COL_ACLS
))
{
rw_unlock
(
&
LOCK_grant
);
/* purecov: deadcode */
DBUG_RETURN
(
0
);
/* purecov: deadcode */
}
#endif
err:
err:
rw_unlock
(
&
LOCK_grant
);
rw_unlock
(
&
LOCK_grant
);
if
(
!
show_tables
)
char
command
[
128
];
get_privilege_desc
(
command
,
sizeof
(
command
),
want_access
);
my_error
(
ER_COLUMNACCESS_DENIED_ERROR
,
MYF
(
0
),
command
,
sctx
->
priv_user
,
sctx
->
host_or_ip
,
name
,
table_name
);
DBUG_RETURN
(
1
);
}
/*
Check the access right to a column depending on the type of table.
SYNOPSIS
check_column_grant_in_table_ref()
thd thread handler
table_ref table reference where to check the field
name name of field to check
length length of name
DESCRIPTION
Check the access rights to a column depending on the type of table
reference where the column is checked. The function provides a
generic interface to check column access rights that hides the
heterogeneity of the column representation - whether it is a view
or a stored table colum.
RETURN
FALSE OK
TRUE access denied
*/
bool
check_column_grant_in_table_ref
(
THD
*
thd
,
TABLE_LIST
*
table_ref
,
const
char
*
name
,
uint
length
)
{
GRANT_INFO
*
grant
;
const
char
*
db_name
;
const
char
*
table_name
;
Security_context
*
sctx
=
test
(
table_ref
->
security_ctx
)
?
table_ref
->
security_ctx
:
thd
->
security_ctx
;
if
(
table_ref
->
view
||
table_ref
->
field_translation
)
{
{
char
command
[
128
];
/* View or derived information schema table. */
get_privilege_desc
(
command
,
sizeof
(
command
),
want_access
);
grant
=
&
(
table_ref
->
grant
);
my_error
(
ER_COLUMNACCESS_DENIED_ERROR
,
MYF
(
0
),
db_name
=
table_ref
->
view_db
.
str
;
command
,
table_name
=
table_ref
->
view_name
.
str
;
sctx
->
priv_user
,
sctx
->
host_or_ip
,
name
,
table_name
);
}
}
DBUG_RETURN
(
1
);
else
{
/* Normal or temporary table. */
TABLE
*
table
=
table_ref
->
table
;
grant
=
&
(
table
->
grant
);
db_name
=
table
->
s
->
db
;
table_name
=
table
->
s
->
table_name
;
}
if
(
grant
->
want_privilege
)
return
check_grant_column
(
thd
,
grant
,
db_name
,
table_name
,
name
,
length
,
sctx
);
else
return
FALSE
;
}
}
...
...
sql/sql_acl.h
View file @
6d6b617a
...
@@ -204,7 +204,9 @@ bool check_grant(THD *thd, ulong want_access, TABLE_LIST *tables,
...
@@ -204,7 +204,9 @@ bool check_grant(THD *thd, ulong want_access, TABLE_LIST *tables,
uint
show_command
,
uint
number
,
bool
dont_print_error
);
uint
show_command
,
uint
number
,
bool
dont_print_error
);
bool
check_grant_column
(
THD
*
thd
,
GRANT_INFO
*
grant
,
bool
check_grant_column
(
THD
*
thd
,
GRANT_INFO
*
grant
,
const
char
*
db_name
,
const
char
*
table_name
,
const
char
*
db_name
,
const
char
*
table_name
,
const
char
*
name
,
uint
length
,
uint
show_command
=
0
);
const
char
*
name
,
uint
length
,
Security_context
*
sctx
);
bool
check_column_grant_in_table_ref
(
THD
*
thd
,
TABLE_LIST
*
table_ref
,
const
char
*
name
,
uint
length
);
bool
check_grant_all_columns
(
THD
*
thd
,
ulong
want_access
,
GRANT_INFO
*
grant
,
bool
check_grant_all_columns
(
THD
*
thd
,
ulong
want_access
,
GRANT_INFO
*
grant
,
const
char
*
db_name
,
const
char
*
table_name
,
const
char
*
db_name
,
const
char
*
table_name
,
Field_iterator
*
fields
);
Field_iterator
*
fields
);
...
...
sql/sql_base.cc
View file @
6d6b617a
This diff is collapsed.
Click to expand it.
sql/sql_insert.cc
View file @
6d6b617a
...
@@ -108,11 +108,7 @@ static int check_insert_fields(THD *thd, TABLE_LIST *table_list,
...
@@ -108,11 +108,7 @@ static int check_insert_fields(THD *thd, TABLE_LIST *table_list,
{
// Part field list
{
// Part field list
SELECT_LEX
*
select_lex
=
&
thd
->
lex
->
select_lex
;
SELECT_LEX
*
select_lex
=
&
thd
->
lex
->
select_lex
;
Name_resolution_context
*
context
=
&
select_lex
->
context
;
Name_resolution_context
*
context
=
&
select_lex
->
context
;
TABLE_LIST
*
save_next_local
;
Name_resolution_context_state
ctx_state
;
TABLE_LIST
*
save_table_list
;
TABLE_LIST
*
save_first_name_resolution_table
;
TABLE_LIST
*
save_next_name_resolution_table
;
bool
save_resolve_in_select_list
;
int
res
;
int
res
;
if
(
fields
.
elements
!=
values
.
elements
)
if
(
fields
.
elements
!=
values
.
elements
)
...
@@ -125,14 +121,7 @@ static int check_insert_fields(THD *thd, TABLE_LIST *table_list,
...
@@ -125,14 +121,7 @@ static int check_insert_fields(THD *thd, TABLE_LIST *table_list,
select_lex
->
no_wrap_view_item
=
TRUE
;
select_lex
->
no_wrap_view_item
=
TRUE
;
/* Save the state of the current name resolution context. */
/* Save the state of the current name resolution context. */
save_table_list
=
context
->
table_list
;
ctx_state
.
save_state
(
context
,
table_list
);
save_first_name_resolution_table
=
context
->
first_name_resolution_table
;
save_next_name_resolution_table
=
(
context
->
first_name_resolution_table
)
?
context
->
first_name_resolution_table
->
next_name_resolution_table
:
NULL
;
save_resolve_in_select_list
=
context
->
resolve_in_select_list
;
save_next_local
=
table_list
->
next_local
;
/*
/*
Perform name resolution only in the first table - 'table_list',
Perform name resolution only in the first table - 'table_list',
...
@@ -143,13 +132,7 @@ static int check_insert_fields(THD *thd, TABLE_LIST *table_list,
...
@@ -143,13 +132,7 @@ static int check_insert_fields(THD *thd, TABLE_LIST *table_list,
res
=
setup_fields
(
thd
,
0
,
fields
,
1
,
0
,
0
);
res
=
setup_fields
(
thd
,
0
,
fields
,
1
,
0
,
0
);
/* Restore the current context. */
/* Restore the current context. */
table_list
->
next_local
=
save_next_local
;
ctx_state
.
restore_state
(
context
,
table_list
);
context
->
table_list
=
save_table_list
;
context
->
first_name_resolution_table
=
save_first_name_resolution_table
;
if
(
context
->
first_name_resolution_table
)
context
->
first_name_resolution_table
->
next_name_resolution_table
=
save_next_name_resolution_table
;
context
->
resolve_in_select_list
=
save_resolve_in_select_list
;
thd
->
lex
->
select_lex
.
no_wrap_view_item
=
FALSE
;
thd
->
lex
->
select_lex
.
no_wrap_view_item
=
FALSE
;
if
(
res
)
if
(
res
)
...
@@ -280,13 +263,10 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
...
@@ -280,13 +263,10 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
ulonglong
id
;
ulonglong
id
;
COPY_INFO
info
;
COPY_INFO
info
;
TABLE
*
table
=
0
;
TABLE
*
table
=
0
;
TABLE_LIST
*
save_table_list
;
TABLE_LIST
*
save_next_local
;
TABLE_LIST
*
save_first_name_resolution_table
;
TABLE_LIST
*
save_next_name_resolution_table
;
List_iterator_fast
<
List_item
>
its
(
values_list
);
List_iterator_fast
<
List_item
>
its
(
values_list
);
List_item
*
values
;
List_item
*
values
;
Name_resolution_context
*
context
;
Name_resolution_context
*
context
;
Name_resolution_context_state
ctx_state
;
#ifndef EMBEDDED_LIBRARY
#ifndef EMBEDDED_LIBRARY
char
*
query
=
thd
->
query
;
char
*
query
=
thd
->
query
;
#endif
#endif
...
@@ -367,13 +347,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
...
@@ -367,13 +347,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
context
=
&
thd
->
lex
->
select_lex
.
context
;
context
=
&
thd
->
lex
->
select_lex
.
context
;
/* Save the state of the current name resolution context. */
/* Save the state of the current name resolution context. */
save_table_list
=
context
->
table_list
;
ctx_state
.
save_state
(
context
,
table_list
);
save_first_name_resolution_table
=
context
->
first_name_resolution_table
;
save_next_name_resolution_table
=
(
context
->
first_name_resolution_table
)
?
context
->
first_name_resolution_table
->
next_name_resolution_table
:
NULL
;
save_next_local
=
table_list
->
next_local
;
/*
/*
Perform name resolution only in the first table - 'table_list',
Perform name resolution only in the first table - 'table_list',
...
@@ -397,16 +371,11 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
...
@@ -397,16 +371,11 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
its
.
rewind
();
its
.
rewind
();
/* Restore the current context. */
/* Restore the current context. */
table_list
->
next_local
=
save_next_local
;
ctx_state
.
restore_state
(
context
,
table_list
);
context
->
first_name_resolution_table
=
save_first_name_resolution_table
;
if
(
context
->
first_name_resolution_table
)
context
->
first_name_resolution_table
->
next_name_resolution_table
=
save_next_name_resolution_table
;
/*
/*
Fill in the given fields and dump it to the table file
Fill in the given fields and dump it to the table file
*/
*/
info
.
records
=
info
.
deleted
=
info
.
copied
=
info
.
updated
=
0
;
info
.
records
=
info
.
deleted
=
info
.
copied
=
info
.
updated
=
0
;
info
.
ignore
=
ignore
;
info
.
ignore
=
ignore
;
info
.
handle_duplicates
=
duplic
;
info
.
handle_duplicates
=
duplic
;
...
@@ -814,11 +783,7 @@ bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list,
...
@@ -814,11 +783,7 @@ bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list,
{
{
SELECT_LEX
*
select_lex
=
&
thd
->
lex
->
select_lex
;
SELECT_LEX
*
select_lex
=
&
thd
->
lex
->
select_lex
;
Name_resolution_context
*
context
=
&
select_lex
->
context
;
Name_resolution_context
*
context
=
&
select_lex
->
context
;
TABLE_LIST
*
save_table_list
;
Name_resolution_context_state
ctx_state
;
TABLE_LIST
*
save_next_local
;
TABLE_LIST
*
save_first_name_resolution_table
;
TABLE_LIST
*
save_next_name_resolution_table
;
bool
save_resolve_in_select_list
;
bool
insert_into_view
=
(
table_list
->
view
!=
0
);
bool
insert_into_view
=
(
table_list
->
view
!=
0
);
bool
res
=
0
;
bool
res
=
0
;
DBUG_ENTER
(
"mysql_prepare_insert"
);
DBUG_ENTER
(
"mysql_prepare_insert"
);
...
@@ -858,15 +823,7 @@ bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list,
...
@@ -858,15 +823,7 @@ bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list,
DBUG_RETURN
(
TRUE
);
DBUG_RETURN
(
TRUE
);
/* Save the state of the current name resolution context. */
/* Save the state of the current name resolution context. */
save_table_list
=
context
->
table_list
;
ctx_state
.
save_state
(
context
,
table_list
);
/* Here first_name_resolution_table points to the first select table. */
save_first_name_resolution_table
=
context
->
first_name_resolution_table
;
save_next_name_resolution_table
=
(
context
->
first_name_resolution_table
)
?
context
->
first_name_resolution_table
->
next_name_resolution_table
:
NULL
;
save_resolve_in_select_list
=
context
->
resolve_in_select_list
;
save_next_local
=
table_list
->
next_local
;
/*
/*
Perform name resolution only in the first table - 'table_list',
Perform name resolution only in the first table - 'table_list',
...
@@ -891,23 +848,17 @@ bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list,
...
@@ -891,23 +848,17 @@ bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list,
*/
*/
if
(
select_lex
->
group_list
.
elements
==
0
)
if
(
select_lex
->
group_list
.
elements
==
0
)
{
{
context
->
table_list
->
next_local
=
save_next_local
;
context
->
table_list
->
next_local
=
ctx_state
.
save_next_local
;
/* first_name_resolution_table was set by resolve_in_table_list_only() */
/* first_name_resolution_table was set by resolve_in_table_list_only() */
context
->
first_name_resolution_table
->
context
->
first_name_resolution_table
->
next_name_resolution_table
=
save_next_local
;
next_name_resolution_table
=
ctx_state
.
save_next_local
;
}
}
if
(
!
res
)
if
(
!
res
)
res
=
setup_fields
(
thd
,
0
,
update_values
,
1
,
0
,
0
);
res
=
setup_fields
(
thd
,
0
,
update_values
,
1
,
0
,
0
);
}
}
/* Restore the current context. */
/* Restore the current context. */
table_list
->
next_local
=
save_next_local
;
ctx_state
.
restore_state
(
context
,
table_list
);
context
->
table_list
=
save_table_list
;
context
->
first_name_resolution_table
=
save_first_name_resolution_table
;
if
(
context
->
first_name_resolution_table
)
context
->
first_name_resolution_table
->
next_name_resolution_table
=
save_next_name_resolution_table
;
context
->
resolve_in_select_list
=
save_resolve_in_select_list
;
if
(
res
)
if
(
res
)
DBUG_RETURN
(
res
);
DBUG_RETURN
(
res
);
...
@@ -2176,17 +2127,10 @@ select_insert::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
...
@@ -2176,17 +2127,10 @@ select_insert::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
{
{
/* Save the state of the current name resolution context. */
/* Save the state of the current name resolution context. */
Name_resolution_context
*
context
=
&
lex
->
select_lex
.
context
;
Name_resolution_context
*
context
=
&
lex
->
select_lex
.
context
;
TABLE_LIST
*
save_table_list
;
Name_resolution_context_state
ctx_state
;
TABLE_LIST
*
save_next_local
;
TABLE_LIST
*
save_first_name_resolution_table
;
/* Save the state of the current name resolution context. */
TABLE_LIST
*
save_next_name_resolution_table
;
ctx_state
.
save_state
(
context
,
table_list
);
save_table_list
=
context
->
table_list
;
save_first_name_resolution_table
=
context
->
first_name_resolution_table
;
save_next_name_resolution_table
=
(
context
->
first_name_resolution_table
)
?
context
->
first_name_resolution_table
->
next_name_resolution_table
:
NULL
;
save_next_local
=
table_list
->
next_local
;
/* Perform name resolution only in the first table - 'table_list'. */
/* Perform name resolution only in the first table - 'table_list'. */
table_list
->
next_local
=
0
;
table_list
->
next_local
=
0
;
...
@@ -2202,20 +2146,15 @@ select_insert::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
...
@@ -2202,20 +2146,15 @@ select_insert::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
*/
*/
if
(
lex
->
select_lex
.
group_list
.
elements
==
0
)
if
(
lex
->
select_lex
.
group_list
.
elements
==
0
)
{
{
context
->
table_list
->
next_local
=
save_next_local
;
context
->
table_list
->
next_local
=
ctx_state
.
save_next_local
;
/* first_name_resolution_table was set by resolve_in_table_list_only() */
/* first_name_resolution_table was set by resolve_in_table_list_only() */
context
->
first_name_resolution_table
->
context
->
first_name_resolution_table
->
next_name_resolution_table
=
save_next_local
;
next_name_resolution_table
=
ctx_state
.
save_next_local
;
}
}
res
=
res
||
setup_fields
(
thd
,
0
,
*
info
.
update_values
,
1
,
0
,
0
);
res
=
res
||
setup_fields
(
thd
,
0
,
*
info
.
update_values
,
1
,
0
,
0
);
/* Restore the current context. */
/* Restore the current context. */
table_list
->
next_local
=
save_next_local
;
ctx_state
.
restore_state
(
context
,
table_list
);
context
->
first_name_resolution_table
=
save_first_name_resolution_table
;
if
(
context
->
first_name_resolution_table
)
context
->
first_name_resolution_table
->
next_name_resolution_table
=
save_next_name_resolution_table
;
}
}
lex
->
current_select
=
lex_current_select_save
;
lex
->
current_select
=
lex_current_select_save
;
...
...
sql/sql_lex.cc
View file @
6d6b617a
...
@@ -1127,6 +1127,11 @@ void st_select_lex::init_query()
...
@@ -1127,6 +1127,11 @@ void st_select_lex::init_query()
/*
/*
Add the name resolution context of the current (sub)query to the
Add the name resolution context of the current (sub)query to the
stack of contexts for the whole query.
stack of contexts for the whole query.
TODO:
push_context may return an error if there is no memory for a new
element in the stack, however this method has no return value,
thus push_context should be moved to a place where query
initialization is checked for failure.
*/
*/
parent_lex
->
push_context
(
&
context
);
parent_lex
->
push_context
(
&
context
);
cond_count
=
with_wild
=
0
;
cond_count
=
with_wild
=
0
;
...
...
sql/sql_lex.h
View file @
6d6b617a
...
@@ -1006,9 +1006,9 @@ typedef struct st_lex
...
@@ -1006,9 +1006,9 @@ typedef struct st_lex
}
}
void
cleanup_after_one_table_open
();
void
cleanup_after_one_table_open
();
void
push_context
(
Name_resolution_context
*
context
)
bool
push_context
(
Name_resolution_context
*
context
)
{
{
context_stack
.
push_front
(
context
);
return
context_stack
.
push_front
(
context
);
}
}
void
pop_context
()
void
pop_context
()
...
...
sql/sql_list.h
View file @
6d6b617a
...
@@ -266,10 +266,21 @@ protected:
...
@@ -266,10 +266,21 @@ protected:
ls
.
elements
=
elm
;
ls
.
elements
=
elm
;
}
}
public:
public:
base_list_iterator
(
base_list
&
list_par
)
base_list_iterator
()
:
list
(
&
list_par
),
el
(
&
list_par
.
first
),
prev
(
0
),
current
(
0
)
:
list
(
0
),
el
(
0
),
prev
(
0
),
current
(
0
)
{}
{}
base_list_iterator
(
base_list
&
list_par
)
{
init
(
list_par
);
}
inline
void
init
(
base_list
&
list_par
)
{
list
=
&
list_par
;
el
=
&
list_par
.
first
;
prev
=
0
;
current
=
0
;
}
inline
void
*
next
(
void
)
inline
void
*
next
(
void
)
{
{
prev
=
el
;
prev
=
el
;
...
@@ -364,6 +375,8 @@ template <class T> class List_iterator :public base_list_iterator
...
@@ -364,6 +375,8 @@ template <class T> class List_iterator :public base_list_iterator
{
{
public:
public:
List_iterator
(
List
<
T
>
&
a
)
:
base_list_iterator
(
a
)
{}
List_iterator
(
List
<
T
>
&
a
)
:
base_list_iterator
(
a
)
{}
List_iterator
()
:
base_list_iterator
()
{}
inline
void
init
(
List
<
T
>
&
a
)
{
base_list_iterator
::
init
(
a
);
}
inline
T
*
operator
++
(
int
)
{
return
(
T
*
)
base_list_iterator
::
next
();
}
inline
T
*
operator
++
(
int
)
{
return
(
T
*
)
base_list_iterator
::
next
();
}
inline
T
*
replace
(
T
*
a
)
{
return
(
T
*
)
base_list_iterator
::
replace
(
a
);
}
inline
T
*
replace
(
T
*
a
)
{
return
(
T
*
)
base_list_iterator
::
replace
(
a
);
}
inline
T
*
replace
(
List
<
T
>
&
a
)
{
return
(
T
*
)
base_list_iterator
::
replace
(
a
);
}
inline
T
*
replace
(
List
<
T
>
&
a
)
{
return
(
T
*
)
base_list_iterator
::
replace
(
a
);
}
...
@@ -385,6 +398,8 @@ protected:
...
@@ -385,6 +398,8 @@ protected:
public:
public:
inline
List_iterator_fast
(
List
<
T
>
&
a
)
:
base_list_iterator
(
a
)
{}
inline
List_iterator_fast
(
List
<
T
>
&
a
)
:
base_list_iterator
(
a
)
{}
inline
List_iterator_fast
()
:
base_list_iterator
()
{}
inline
void
init
(
List
<
T
>
&
a
)
{
base_list_iterator
::
init
(
a
);
}
inline
T
*
operator
++
(
int
)
{
return
(
T
*
)
base_list_iterator
::
next_fast
();
}
inline
T
*
operator
++
(
int
)
{
return
(
T
*
)
base_list_iterator
::
next_fast
();
}
inline
void
rewind
(
void
)
{
base_list_iterator
::
rewind
();
}
inline
void
rewind
(
void
)
{
base_list_iterator
::
rewind
();
}
void
sublist
(
List
<
T
>
&
list_arg
,
uint
el_arg
)
void
sublist
(
List
<
T
>
&
list_arg
,
uint
el_arg
)
...
...
sql/sql_parse.cc
View file @
6d6b617a
...
@@ -6583,36 +6583,39 @@ void st_select_lex::set_lock_for_tables(thr_lock_type lock_type)
...
@@ -6583,36 +6583,39 @@ void st_select_lex::set_lock_for_tables(thr_lock_type lock_type)
/*
/*
Create a new name resolution context for a JOIN ... ON clause.
Push a new name resolution context for a JOIN ... ON clause to the
context stack of a query block.
SYNOPSIS
SYNOPSIS
make_join_
on_context()
push_new_name_resoluti
on_context()
thd pointer to current thread
thd pointer to current thread
left_op left operand of the JOIN
left_op left operand of the JOIN
right_op rigth operand of the JOIN
right_op rigth operand of the JOIN
DESCRIPTION
DESCRIPTION
Create a new name resolution context for a JOIN ... ON clause,
Create a new name resolution context for a JOIN ... ON clause,
and set the first and last leaves of the list of table references
set the first and last leaves of the list of table references
to be used for name resolution.
to be used for name resolution, and push the newly created
context to the stack of contexts of the query.
RETURN
RETURN
A new context
if all is OK
FALSE
if all is OK
NULL -
if a memory allocation error occured
TRUE
if a memory allocation error occured
*/
*/
Name_resolution_context
*
bool
make_join_on_context
(
THD
*
thd
,
TABLE_LIST
*
left_op
,
TABLE_LIST
*
right_op
)
push_new_name_resolution_context
(
THD
*
thd
,
TABLE_LIST
*
left_op
,
TABLE_LIST
*
right_op
)
{
{
Name_resolution_context
*
on_context
;
Name_resolution_context
*
on_context
;
if
(
!
(
on_context
=
new
(
thd
->
mem_root
)
Name_resolution_context
))
if
(
!
(
on_context
=
new
(
thd
->
mem_root
)
Name_resolution_context
))
return
NULL
;
return
TRUE
;
on_context
->
init
();
on_context
->
init
();
on_context
->
first_name_resolution_table
=
on_context
->
first_name_resolution_table
=
left_op
->
first_leaf_for_name_resolution
();
left_op
->
first_leaf_for_name_resolution
();
on_context
->
last_name_resolution_table
=
on_context
->
last_name_resolution_table
=
right_op
->
last_leaf_for_name_resolution
();
right_op
->
last_leaf_for_name_resolution
();
return
on_context
;
return
thd
->
lex
->
push_context
(
on_context
)
;
}
}
...
...
sql/sql_yacc.yy
View file @
6d6b617a
...
@@ -5185,10 +5185,8 @@ join_table:
...
@@ -5185,10 +5185,8 @@ join_table:
{
{
YYERROR_UNLESS($1 && ($$=$3));
YYERROR_UNLESS($1 && ($$=$3));
/* Change the current name resolution context to a local context. */
/* Change the current name resolution context to a local context. */
Name_resolution_context *on_context;
if (push_new_name_resolution_context(YYTHD, $1, $3))
if (!(on_context= make_join_on_context(YYTHD,$1,$3)))
YYABORT;
YYABORT;
Lex->push_context(on_context);
}
}
expr
expr
{
{
...
@@ -5200,10 +5198,8 @@ join_table:
...
@@ -5200,10 +5198,8 @@ join_table:
{
{
YYERROR_UNLESS($1 && ($$=$3));
YYERROR_UNLESS($1 && ($$=$3));
/* Change the current name resolution context to a local context. */
/* Change the current name resolution context to a local context. */
Name_resolution_context *on_context;
if (push_new_name_resolution_context(YYTHD, $1, $3))
if (!(on_context= make_join_on_context(YYTHD,$1,$3)))
YYABORT;
YYABORT;
Lex->push_context(on_context);
}
}
expr
expr
{
{
...
@@ -5230,10 +5226,8 @@ join_table:
...
@@ -5230,10 +5226,8 @@ join_table:
ON
ON
{
{
/* Change the current name resolution context to a local context. */
/* Change the current name resolution context to a local context. */
Name_resolution_context *on_context;
if (push_new_name_resolution_context(YYTHD, $1, $5))
if (!(on_context= make_join_on_context(YYTHD,$1,$5)))
YYABORT;
YYABORT;
Lex->push_context(on_context);
}
}
expr
expr
{
{
...
@@ -5263,10 +5257,8 @@ join_table:
...
@@ -5263,10 +5257,8 @@ join_table:
ON
ON
{
{
/* Change the current name resolution context to a local context. */
/* Change the current name resolution context to a local context. */
Name_resolution_context *on_context;
if (push_new_name_resolution_context(YYTHD, $1, $5))
if (!(on_context= make_join_on_context(YYTHD,$1,$5)))
YYABORT;
YYABORT;
Lex->push_context(on_context);
}
}
expr
expr
{
{
...
@@ -5327,10 +5319,9 @@ table_factor:
...
@@ -5327,10 +5319,9 @@ table_factor:
ON
ON
{
{
/* Change the current name resolution context to a local context. */
/* Change the current name resolution context to a local context. */
Name_resolution_context *on_context;
if (push_new_name_resolution_context(YYTHD, $3, $7))
if (!(on_context= make_join_on_context(YYTHD,$3,$7)))
YYABORT;
YYABORT;
Lex->push_context(on_context);
}
}
expr '}'
expr '}'
{
{
...
...
sql/table.cc
View file @
6d6b617a
...
@@ -2606,60 +2606,6 @@ GRANT_INFO *Natural_join_column::grant()
...
@@ -2606,60 +2606,6 @@ GRANT_INFO *Natural_join_column::grant()
}
}
#ifndef NO_EMBEDDED_ACCESS_CHECKS
/*
Check the access rights for the current join column.
columns.
SYNOPSIS
Natural_join_column::check_grants()
DESCRIPTION
Check the access rights to a column from a natural join in a generic
way that hides the heterogeneity of the column representation - whether
it is a view or a stored table colum.
RETURN
FALSE The column can be accessed
TRUE There are no access rights to all equivalent columns
*/
bool
Natural_join_column
::
check_grants
(
THD
*
thd
,
const
char
*
name
,
uint
length
)
{
GRANT_INFO
*
grant
;
const
char
*
db_name
;
const
char
*
table_name
;
Security_context
*
save_security_ctx
=
thd
->
security_ctx
;
Security_context
*
new_sctx
=
table_ref
->
security_ctx
;
bool
res
;
if
(
view_field
)
{
DBUG_ASSERT
(
table_field
==
NULL
);
grant
=
&
(
table_ref
->
grant
);
db_name
=
table_ref
->
view_db
.
str
;
table_name
=
table_ref
->
view_name
.
str
;
}
else
{
DBUG_ASSERT
(
table_field
&&
view_field
==
NULL
);
grant
=
&
(
table_ref
->
table
->
grant
);
db_name
=
table_ref
->
table
->
s
->
db
;
table_name
=
table_ref
->
table
->
s
->
table_name
;
}
if
(
new_sctx
)
thd
->
security_ctx
=
new_sctx
;
res
=
check_grant_column
(
thd
,
grant
,
db_name
,
table_name
,
name
,
length
);
thd
->
security_ctx
=
save_security_ctx
;
return
res
;
}
#endif
void
Field_iterator_view
::
set
(
TABLE_LIST
*
table
)
void
Field_iterator_view
::
set
(
TABLE_LIST
*
table
)
{
{
DBUG_ASSERT
(
table
->
field_translation
);
DBUG_ASSERT
(
table
->
field_translation
);
...
@@ -2702,8 +2648,9 @@ Item *create_view_field(THD *thd, TABLE_LIST *view, Item **field_ref,
...
@@ -2702,8 +2648,9 @@ Item *create_view_field(THD *thd, TABLE_LIST *view, Item **field_ref,
if
(
view
->
schema_table_reformed
)
if
(
view
->
schema_table_reformed
)
{
{
/*
/*
In case of SHOW command (schema_table_reformed set) all items are
Translation table items are always Item_fields and already fixed
fixed
('mysql_schema_table' function). So we can return directly the
field. This case happens only for 'show & where' commands.
*/
*/
DBUG_ASSERT
(
field
&&
field
->
fixed
);
DBUG_ASSERT
(
field
&&
field
->
fixed
);
DBUG_RETURN
(
field
);
DBUG_RETURN
(
field
);
...
@@ -2735,21 +2682,14 @@ Item *create_view_field(THD *thd, TABLE_LIST *view, Item **field_ref,
...
@@ -2735,21 +2682,14 @@ Item *create_view_field(THD *thd, TABLE_LIST *view, Item **field_ref,
void
Field_iterator_natural_join
::
set
(
TABLE_LIST
*
table_ref
)
void
Field_iterator_natural_join
::
set
(
TABLE_LIST
*
table_ref
)
{
{
DBUG_ASSERT
(
table_ref
->
join_columns
);
DBUG_ASSERT
(
table_ref
->
join_columns
);
delete
column_ref_it
;
column_ref_it
.
init
(
*
(
table_ref
->
join_columns
));
cur_column_ref
=
column_ref_it
++
;
/*
TODO: try not to allocate new iterator every time. If we have to,
then check for out of memory condition.
*/
column_ref_it
=
new
List_iterator_fast
<
Natural_join_column
>
(
*
(
table_ref
->
join_columns
));
cur_column_ref
=
(
*
column_ref_it
)
++
;
}
}
void
Field_iterator_natural_join
::
next
()
void
Field_iterator_natural_join
::
next
()
{
{
cur_column_ref
=
(
*
column_ref_it
)
++
;
cur_column_ref
=
column_ref_it
++
;
DBUG_ASSERT
(
!
cur_column_ref
||
!
cur_column_ref
->
table_field
||
DBUG_ASSERT
(
!
cur_column_ref
||
!
cur_column_ref
->
table_field
||
cur_column_ref
->
table_ref
->
table
==
cur_column_ref
->
table_ref
->
table
==
cur_column_ref
->
table_field
->
table
);
cur_column_ref
->
table_field
->
table
);
...
@@ -2876,7 +2816,6 @@ GRANT_INFO *Field_iterator_table_ref::grant()
...
@@ -2876,7 +2816,6 @@ GRANT_INFO *Field_iterator_table_ref::grant()
SYNOPSIS
SYNOPSIS
Field_iterator_table_ref::get_or_create_column_ref()
Field_iterator_table_ref::get_or_create_column_ref()
thd [in] pointer to current thread
is_created [out] set to TRUE if the column was created,
is_created [out] set to TRUE if the column was created,
FALSE if we return an already created colum
FALSE if we return an already created colum
...
@@ -2889,7 +2828,7 @@ GRANT_INFO *Field_iterator_table_ref::grant()
...
@@ -2889,7 +2828,7 @@ GRANT_INFO *Field_iterator_table_ref::grant()
*/
*/
Natural_join_column
*
Natural_join_column
*
Field_iterator_table_ref
::
get_or_create_column_ref
(
THD
*
thd
,
bool
*
is_created
)
Field_iterator_table_ref
::
get_or_create_column_ref
(
bool
*
is_created
)
{
{
Natural_join_column
*
nj_col
;
Natural_join_column
*
nj_col
;
...
@@ -2923,6 +2862,41 @@ Field_iterator_table_ref::get_or_create_column_ref(THD *thd, bool *is_created)
...
@@ -2923,6 +2862,41 @@ Field_iterator_table_ref::get_or_create_column_ref(THD *thd, bool *is_created)
}
}
/*
Return an existing reference to a column of a natural/using join.
SYNOPSIS
Field_iterator_table_ref::get_natural_column_ref()
DESCRIPTION
The method should be called in contexts where it is expected that
all natural join columns are already created, and that the column
being retrieved is a Natural_join_column.
RETURN
# Pointer to a column of a natural join (or its operand)
NULL No memory to allocate the column
*/
Natural_join_column
*
Field_iterator_table_ref
::
get_natural_column_ref
()
{
Natural_join_column
*
nj_col
;
DBUG_ASSERT
(
field_it
==
&
natural_join_it
);
/*
The field belongs to a NATURAL join, therefore the column reference was
already created via one of the two constructor calls above. In this case
we just return the already created column reference.
*/
nj_col
=
natural_join_it
.
column_ref
();
DBUG_ASSERT
(
nj_col
&&
(
!
nj_col
->
table_field
||
nj_col
->
table_ref
->
table
==
nj_col
->
table_field
->
table
));
return
nj_col
;
}
/*****************************************************************************
/*****************************************************************************
** Instansiate templates
** Instansiate templates
*****************************************************************************/
*****************************************************************************/
...
...
sql/table.h
View file @
6d6b617a
...
@@ -407,9 +407,6 @@ public:
...
@@ -407,9 +407,6 @@ public:
const
char
*
table_name
();
const
char
*
table_name
();
const
char
*
db_name
();
const
char
*
db_name
();
GRANT_INFO
*
grant
();
GRANT_INFO
*
grant
();
#ifndef NO_EMBEDDED_ACCESS_CHECKS
bool
check_grants
(
THD
*
thd
,
const
char
*
name
,
uint
length
);
#endif
};
};
...
@@ -734,11 +731,11 @@ public:
...
@@ -734,11 +731,11 @@ public:
class
Field_iterator_natural_join
:
public
Field_iterator
class
Field_iterator_natural_join
:
public
Field_iterator
{
{
List_iterator_fast
<
Natural_join_column
>
*
column_ref_it
;
List_iterator_fast
<
Natural_join_column
>
column_ref_it
;
Natural_join_column
*
cur_column_ref
;
Natural_join_column
*
cur_column_ref
;
public:
public:
Field_iterator_natural_join
()
:
c
olumn_ref_it
(
NULL
),
c
ur_column_ref
(
NULL
)
{}
Field_iterator_natural_join
()
:
cur_column_ref
(
NULL
)
{}
~
Field_iterator_natural_join
()
{
delete
column_ref_it
;
}
~
Field_iterator_natural_join
()
{}
void
set
(
TABLE_LIST
*
table
);
void
set
(
TABLE_LIST
*
table
);
void
next
();
void
next
();
bool
end_of_fields
()
{
return
!
cur_column_ref
;
}
bool
end_of_fields
()
{
return
!
cur_column_ref
;
}
...
@@ -785,7 +782,8 @@ public:
...
@@ -785,7 +782,8 @@ public:
GRANT_INFO
*
grant
();
GRANT_INFO
*
grant
();
Item
*
create_item
(
THD
*
thd
)
{
return
field_it
->
create_item
(
thd
);
}
Item
*
create_item
(
THD
*
thd
)
{
return
field_it
->
create_item
(
thd
);
}
Field
*
field
()
{
return
field_it
->
field
();
}
Field
*
field
()
{
return
field_it
->
field
();
}
Natural_join_column
*
get_or_create_column_ref
(
THD
*
thd
,
bool
*
is_created
);
Natural_join_column
*
get_or_create_column_ref
(
bool
*
is_created
);
Natural_join_column
*
get_natural_column_ref
();
};
};
...
...
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