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
3d01a3af
Commit
3d01a3af
authored
Dec 07, 2005
by
timour@mysql.com
Browse files
Options
Browse Files
Download
Plain Diff
Merge mysql.com:/home/timka/mysql/src/5.0-2486
into mysql.com:/home/timka/mysql/src/5.1-dbg
parents
548bacf4
ecb41e28
Changes
14
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 @
3d01a3af
...
...
@@ -5207,7 +5207,7 @@ void Item_trigger_field::setup_field(THD *thd, TABLE *table)
set field_idx properly.
*/
(
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
;
triggers
=
table
->
triggers
;
}
...
...
sql/item.h
View file @
3d01a3af
...
...
@@ -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
);
...
...
sql/mysql_priv.h
View file @
3d01a3af
...
...
@@ -820,18 +820,15 @@ find_field_in_tables(THD *thd, Item_ident *item,
bool
check_privileges
,
bool
register_tree_change
);
Field
*
find_field_in_table_ref
(
THD
*
thd
,
TABLE_LIST
*
table_list
,
const
char
*
name
,
const
char
*
item_name
,
const
char
*
table_name
,
const
char
*
db_name
,
uint
length
,
Item
**
ref
,
bool
check_grants_table
,
bool
check_grants_view
,
bool
allow_rowid
,
const
char
*
name
,
uint
length
,
const
char
*
item_name
,
const
char
*
db_name
,
const
char
*
table_name
,
Item
**
ref
,
bool
check_privileges
,
bool
allow_rowid
,
uint
*
cached_field_index_ptr
,
bool
register_tree_change
,
TABLE_LIST
**
actual_table
);
Field
*
find_field_in_table
(
THD
*
thd
,
TABLE
*
table
,
const
char
*
name
,
uint
length
,
bool
check_grants
,
bool
allow_rowid
,
uint
*
cached_field_index_ptr
,
Security_context
*
sctx
);
find_field_in_table
(
THD
*
thd
,
TABLE
*
table
,
const
char
*
name
,
uint
length
,
bool
allow_rowid
,
uint
*
cached_field_index_ptr
);
Field
*
find_field_in_table_sef
(
TABLE
*
table
,
const
char
*
name
);
...
...
@@ -950,8 +947,9 @@ create_field * new_create_field(THD *thd, char *field_name, enum_field_types typ
uint
uint_geom_type
);
void
store_position_for_column
(
const
char
*
name
);
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
,
TABLE_LIST
*
right_op
);
bool
push_new_name_resolution_context
(
THD
*
thd
,
TABLE_LIST
*
left_op
,
TABLE_LIST
*
right_op
);
void
add_join_on
(
TABLE_LIST
*
b
,
Item
*
expr
);
void
add_join_natural
(
TABLE_LIST
*
a
,
TABLE_LIST
*
b
,
List
<
String
>
*
using_fields
);
bool
add_proc_to_list
(
THD
*
thd
,
Item
*
item
);
...
...
sql/sql_acl.cc
View file @
3d01a3af
...
...
@@ -2760,8 +2760,9 @@ bool mysql_table_grant(THD *thd, TABLE_LIST *table_list,
uint
unused_field_idx
=
NO_CACHED_FIELD_INDEX
;
TABLE_LIST
*
dummy
;
Field
*
f
=
find_field_in_table_ref
(
thd
,
table_list
,
column
->
column
.
ptr
(),
column
->
column
.
length
(),
column
->
column
.
ptr
(),
NULL
,
NULL
,
column
->
column
.
length
(),
0
,
1
,
1
,
0
,
NULL
,
TRUE
,
FALSE
,
&
unused_field_idx
,
FALSE
,
&
dummy
);
if
(
f
==
(
Field
*
)
0
)
{
...
...
@@ -3616,11 +3617,28 @@ bool check_grant(THD *thd, ulong want_access, TABLE_LIST *tables,
}
/*
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
,
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_COLUMN
*
grant_column
;
ulong
want_access
=
grant
->
want_privilege
&
~
grant
->
privilege
;
...
...
@@ -3651,28 +3669,74 @@ bool check_grant_column(THD *thd, GRANT_INFO *grant,
rw_unlock
(
&
LOCK_grant
);
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:
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
];
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
);
/* View or derived information schema table. */
grant
=
&
(
table_ref
->
grant
);
db_name
=
table_ref
->
view_db
.
str
;
table_name
=
table_ref
->
view_name
.
str
;
}
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 @
3d01a3af
...
...
@@ -205,7 +205,9 @@ bool check_grant(THD *thd, ulong want_access, TABLE_LIST *tables,
uint
show_command
,
uint
number
,
bool
dont_print_error
);
bool
check_grant_column
(
THD
*
thd
,
GRANT_INFO
*
grant
,
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
,
const
char
*
db_name
,
const
char
*
table_name
,
Field_iterator
*
fields
);
...
...
sql/sql_base.cc
View file @
3d01a3af
...
...
@@ -3368,47 +3368,6 @@ static void update_field_dependencies(THD *thd, Field *field, TABLE *table)
}
#ifndef NO_EMBEDDED_ACCESS_CHECKS
/*
Check column rights in given security context
SYNOPSIS
check_grant_column_in_sctx()
thd thread handler
grant grant information structure
db db name
table table name
name column name
length column name length
check_grants need to check grants
sctx 0 or security context
RETURN
FALSE OK
TRUE access denied
*/
static
bool
check_grant_column_in_sctx
(
THD
*
thd
,
GRANT_INFO
*
grant
,
const
char
*
db
,
const
char
*
table
,
const
char
*
name
,
uint
length
,
bool
check_grants
,
Security_context
*
sctx
)
{
if
(
!
check_grants
)
return
FALSE
;
Security_context
*
save_security_ctx
=
thd
->
security_ctx
;
bool
res
;
if
(
sctx
)
{
thd
->
security_ctx
=
sctx
;
}
res
=
check_grant_column
(
thd
,
grant
,
db
,
table
,
name
,
length
);
thd
->
security_ctx
=
save_security_ctx
;
return
res
;
}
#endif
/*
Find a field by name in a view that uses merge algorithm.
...
...
@@ -3417,11 +3376,10 @@ static bool check_grant_column_in_sctx(THD *thd, GRANT_INFO *grant,
thd thread handler
table_list view to search for 'name'
name name of field
item_name name of item if it will be created (VIEW)
length length of name
item_name name of item if it will be created (VIEW)
ref expression substituted in VIEW should be passed
using this reference (return view_ref_found)
check_grants do check columns grants for view?
register_tree_change TRUE if ref is not stack variable and we
need register changes in item tree
...
...
@@ -3433,8 +3391,8 @@ static bool check_grant_column_in_sctx(THD *thd, GRANT_INFO *grant,
static
Field
*
find_field_in_view
(
THD
*
thd
,
TABLE_LIST
*
table_list
,
const
char
*
name
,
const
char
*
item_name
,
uint
length
,
Item
**
ref
,
bool
check_grants
,
const
char
*
name
,
uint
length
,
const
char
*
item_name
,
Item
**
ref
,
bool
register_tree_change
)
{
DBUG_ENTER
(
"find_field_in_view"
);
...
...
@@ -3451,24 +3409,13 @@ find_field_in_view(THD *thd, TABLE_LIST *table_list,
{
if
(
!
my_strcasecmp
(
system_charset_info
,
field_it
.
name
(),
name
))
{
if
(
table_list
->
schema_table_reformed
)
/*
Translation table items are always Item_fields and fixed already
('mysql_schema_table' function). So we can return ->field. It is
used only for 'show & where' commands.
*/
DBUG_RETURN
(((
Item_field
*
)
(
field_it
.
item
()))
->
field
);
#ifndef NO_EMBEDDED_ACCESS_CHECKS
if
(
check_grant_column_in_sctx
(
thd
,
&
table_list
->
grant
,
table_list
->
view_db
.
str
,
table_list
->
view_name
.
str
,
name
,
length
,
check_grants
,
table_list
->
security_ctx
))
DBUG_RETURN
(
WRONG_GRANT
);
#endif
// in PS use own arena or data will be freed after prepare
if
(
register_tree_change
)
arena
=
thd
->
activate_stmt_arena_if_needed
(
&
backup
);
/*
create_item() may, or may not create a new Item, depending on
the column reference. See create_view_field() for details.
*/
Item
*
item
=
field_it
.
create_item
(
thd
);
if
(
register_tree_change
&&
arena
)
thd
->
restore_active_arena
(
arena
,
&
backup
);
...
...
@@ -3510,7 +3457,6 @@ find_field_in_view(THD *thd, TABLE_LIST *table_list,
length [in] length of name
ref [in/out] if 'name' is resolved to a view field, ref is
set to point to the found view field
check_grants [in] do check columns grants?
register_tree_change [in] TRUE if ref is not stack variable and we
need register changes in item tree
actual_table [out] the original table reference where the field
...
...
@@ -3531,8 +3477,7 @@ find_field_in_view(THD *thd, TABLE_LIST *table_list,
static
Field
*
find_field_in_natural_join
(
THD
*
thd
,
TABLE_LIST
*
table_ref
,
const
char
*
name
,
uint
length
,
Item
**
ref
,
bool
check_grants
,
bool
register_tree_change
,
uint
length
,
Item
**
ref
,
bool
register_tree_change
,
TABLE_LIST
**
actual_table
)
{
List_iterator_fast
<
Natural_join_column
>
...
...
@@ -3557,23 +3502,16 @@ find_field_in_natural_join(THD *thd, TABLE_LIST *table_ref, const char *name,
break
;
}
#ifndef NO_EMBEDDED_ACCESS_CHECKS
if
(
check_grants
&&
nj_col
->
check_grants
(
thd
,
name
,
length
))
DBUG_RETURN
(
WRONG_GRANT
);
#endif
if
(
nj_col
->
view_field
)
{
Item
*
item
;
/*
The found field is a view field, we do as in find_field_in_view()
and return a pointer to pointer to the Item of that field.
*/
if
(
register_tree_change
)
arena
=
thd
->
activate_stmt_arena_if_needed
(
&
backup
);
/*
create_item() may, or may not create a new Item, depending on the
column reference. See create_view_field() for details.
*/
item
=
nj_col
->
create_item
(
thd
);
if
(
register_tree_change
&&
arena
)
thd
->
restore_active_arena
(
arena
,
&
backup
);
...
...
@@ -3619,7 +3557,6 @@ find_field_in_natural_join(THD *thd, TABLE_LIST *table_ref, const char *name,
table table where to search for the field
name name of field
length length of name
check_grants do check columns grants?
allow_rowid do allow finding of "_rowid" field?
cached_field_index_ptr cached position in field list (used to speedup
lookup for fields in prepared tables)
...
...
@@ -3631,9 +3568,7 @@ find_field_in_natural_join(THD *thd, TABLE_LIST *table_ref, const char *name,
Field
*
find_field_in_table
(
THD
*
thd
,
TABLE
*
table
,
const
char
*
name
,
uint
length
,
bool
check_grants
,
bool
allow_rowid
,
uint
*
cached_field_index_ptr
,
Security_context
*
sctx
)
bool
allow_rowid
,
uint
*
cached_field_index_ptr
)
{
Field
**
field_ptr
,
*
field
;
uint
cached_field_index
=
*
cached_field_index_ptr
;
...
...
@@ -3683,13 +3618,6 @@ find_field_in_table(THD *thd, TABLE *table, const char *name, uint length,
update_field_dependencies
(
thd
,
field
,
table
);
#ifndef NO_EMBEDDED_ACCESS_CHECKS
if
(
check_grant_column_in_sctx
(
thd
,
&
table
->
grant
,
table
->
s
->
db
.
str
,
table
->
s
->
table_name
.
str
,
name
,
length
,
check_grants
,
sctx
))
field
=
WRONG_GRANT
;
#endif
DBUG_RETURN
(
field
);
}
...
...
@@ -3702,14 +3630,13 @@ find_field_in_table(THD *thd, TABLE *table, const char *name, uint length,
thd [in] thread handler
table_list [in] table reference to search
name [in] name of field
length [in] field length of name
item_name [in] name of item if it will be created (VIEW)
table_name [in] optional table name that qualifies the field
db_name [in] optional database name that qualifies the
length [in] field length of name
table_name [in] optional table name that qualifies the field
ref [in/out] if 'name' is resolved to a view field, ref
is set to point to the found view field
check_grants_table [in] do check columns grants for table?
check_grants_view [in] do check columns grants for view?
check_privileges [in] check privileges
allow_rowid [in] do allow finding of "_rowid" field?
cached_field_index_ptr [in] cached position in field list (used to
speedup lookup for fields in prepared tables)
...
...
@@ -3739,11 +3666,11 @@ find_field_in_table(THD *thd, TABLE *table, const char *name, uint length,
Field
*
find_field_in_table_ref
(
THD
*
thd
,
TABLE_LIST
*
table_list
,
const
char
*
name
,
const
char
*
item_name
,
const
char
*
table
_name
,
const
char
*
db_name
,
uint
length
,
Item
**
ref
,
bool
check_
grants_table
,
bool
check_grants_view
,
bool
allow_rowid
,
uint
*
cached_field_index_ptr
,
const
char
*
name
,
uint
length
,
const
char
*
item
_name
,
const
char
*
db_name
,
const
char
*
table_name
,
Item
**
ref
,
bool
check_
privileges
,
bool
allow_rowid
,
uint
*
cached_field_index_ptr
,
bool
register_tree_change
,
TABLE_LIST
**
actual_table
)
{
Field
*
fld
;
...
...
@@ -3788,8 +3715,7 @@ find_field_in_table_ref(THD *thd, TABLE_LIST *table_list,
if
(
table_list
->
field_translation
)
{
/* 'table_list' is a view or an information schema table. */
if
((
fld
=
find_field_in_view
(
thd
,
table_list
,
name
,
item_name
,
length
,
ref
,
check_grants_view
,
if
((
fld
=
find_field_in_view
(
thd
,
table_list
,
name
,
length
,
item_name
,
ref
,
register_tree_change
)))
*
actual_table
=
table_list
;
}
...
...
@@ -3798,20 +3724,9 @@ find_field_in_table_ref(THD *thd, TABLE_LIST *table_list,
/* 'table_list' is a stored table. */
DBUG_ASSERT
(
table_list
->
table
);
if
((
fld
=
find_field_in_table
(
thd
,
table_list
->
table
,
name
,
length
,
check_grants_table
,
allow_rowid
,
cached_field_index_ptr
,
table_list
->
security_ctx
)))
allow_rowid
,
cached_field_index_ptr
)))
*
actual_table
=
table_list
;
#ifndef NO_EMBEDDED_ACCESS_CHECKS
/* check for views with temporary table algorithm */
if
(
check_grants_view
&&
table_list
->
view
&&
fld
&&
fld
!=
WRONG_GRANT
&&
check_grant_column
(
thd
,
&
table_list
->
grant
,
table_list
->
view_db
.
str
,
table_list
->
view_name
.
str
,
name
,
length
))
fld
=
WRONG_GRANT
;
#endif
}
else
{
...
...
@@ -3828,11 +3743,10 @@ find_field_in_table_ref(THD *thd, TABLE_LIST *table_list,
TABLE_LIST
*
table
;
while
((
table
=
it
++
))
{
if
((
fld
=
find_field_in_table_ref
(
thd
,
table
,
name
,
item_name
,
table_name
,
db_name
,
length
,
ref
,
check_grants_table
,
check_grants_view
,
allow_rowid
,
cached_field_index_ptr
,
if
((
fld
=
find_field_in_table_ref
(
thd
,
table
,
name
,
length
,
item_name
,
db_name
,
table_name
,
ref
,
check_privileges
,
allow_rowid
,
cached_field_index_ptr
,
register_tree_change
,
actual_table
)))
DBUG_RETURN
(
fld
);
}
...
...
@@ -3845,11 +3759,16 @@ find_field_in_table_ref(THD *thd, TABLE_LIST *table_list,
directly the top-most NATURAL/USING join.
*/
fld
=
find_field_in_natural_join
(
thd
,
table_list
,
name
,
length
,
ref
,
/* TIMOUR_TODO: check this with Sanja */
check_grants_table
||
check_grants_view
,
register_tree_change
,
actual_table
);
}
#ifndef NO_EMBEDDED_ACCESS_CHECKS
/* Check if there are sufficient access rights to the found field. */
if
(
fld
&&
check_privileges
&&
check_column_grant_in_table_ref
(
thd
,
*
actual_table
,
name
,
length
))
fld
=
WRONG_GRANT
;
#endif
DBUG_RETURN
(
fld
);
}
...
...
@@ -3967,21 +3886,11 @@ find_field_in_tables(THD *thd, Item_ident *item,
*/
if
(
table_ref
->
table
&&
!
table_ref
->
view
)
found
=
find_field_in_table
(
thd
,
table_ref
->
table
,
name
,
length
,
test
(
table_ref
->
table
->
grant
.
want_privilege
)
&&
check_privileges
,
1
,
&
(
item
->
cached_field_index
),
table_ref
->
security_ctx
);
TRUE
,
&
(
item
->
cached_field_index
));
else
found
=
find_field_in_table_ref
(
thd
,
table_ref
,
name
,
item
->
name
,
NULL
,
NULL
,
length
,
ref
,
(
table_ref
->
table
&&
test
(
table_ref
->
table
->
grant
.
want_privilege
)
&&
check_privileges
),
(
test
(
table_ref
->
grant
.
want_privilege
)
&&
check_privileges
),
1
,
&
(
item
->
cached_field_index
),
found
=
find_field_in_table_ref
(
thd
,
table_ref
,
name
,
length
,
item
->
name
,
NULL
,
NULL
,
ref
,
check_privileges
,
TRUE
,
&
(
item
->
cached_field_index
),
register_tree_change
,
&
actual_table
);
if
(
found
)
...
...
@@ -4021,17 +3930,9 @@ find_field_in_tables(THD *thd, Item_ident *item,
for
(;
cur_table
!=
last_table
;
cur_table
=
cur_table
->
next_name_resolution_table
)
{
Field
*
cur_field
=
find_field_in_table_ref
(
thd
,
cur_table
,
name
,
item
->
name
,
table_name
,
db
,
length
,
ref
,
(
cur_table
->
table
&&
test
(
cur_table
->
table
->
grant
.
want_privilege
)
&&
check_privileges
),
(
test
(
cur_table
->
grant
.
want_privilege
)
&&
check_privileges
),
allow_rowid
,
Field
*
cur_field
=
find_field_in_table_ref
(
thd
,
cur_table
,
name
,
length
,
item
->
name
,
db
,
table_name
,
ref
,
check_privileges
,
allow_rowid
,
&
(
item
->
cached_field_index
),
register_tree_change
,
&
actual_table
);
...
...
@@ -4439,7 +4340,7 @@ mark_common_columns(THD *thd, TABLE_LIST *table_ref_1, TABLE_LIST *table_ref_2,
{
bool
is_created_1
;
bool
found
=
FALSE
;
if
(
!
(
nj_col_1
=
it_1
.
get_or_create_column_ref
(
thd
,
&
is_created_1
)))
if
(
!
(
nj_col_1
=
it_1
.
get_or_create_column_ref
(
&
is_created_1
)))
goto
err
;
field_name_1
=
nj_col_1
->
name
();
...
...
@@ -4460,7 +4361,7 @@ mark_common_columns(THD *thd, TABLE_LIST *table_ref_1, TABLE_LIST *table_ref_2,
bool
is_created_2
;
Natural_join_column
*
cur_nj_col_2
;
const
char
*
cur_field_name_2
;
if
(
!
(
cur_nj_col_2
=
it_2
.
get_or_create_column_ref
(
thd
,
&
is_created_2
)))
if
(
!
(
cur_nj_col_2
=
it_2
.
get_or_create_column_ref
(
&
is_created_2
)))
goto
err
;
cur_field_name_2
=
cur_nj_col_2
->
name
();
...
...
@@ -4656,13 +4557,7 @@ store_natural_using_join_columns(THD *thd, TABLE_LIST *natural_using_join,
/* Append the columns of the first join operand. */
for
(
it_1
.
set
(
table_ref_1
);
!
it_1
.
end_of_fields
();
it_1
.
next
())
{
if
(
!
(
nj_col_1
=
it_1
.
get_or_create_column_ref
(
thd
,
&
is_created
)))
goto
err
;
/*
The following assert checks that mark_common_columns() was run and
we created the list table_ref_1->join_columns.
*/
DBUG_ASSERT
(
!
is_created
);
nj_col_1
=
it_1
.
get_natural_column_ref
();
if
(
nj_col_1
->
is_common
)
{
natural_using_join
->
join_columns
->
push_back
(
nj_col_1
);
...
...
@@ -4708,13 +4603,7 @@ store_natural_using_join_columns(THD *thd, TABLE_LIST *natural_using_join,
/* Append the non-equi-join columns of the second join operand. */
for
(
it_2
.
set
(
table_ref_2
);
!
it_2
.
end_of_fields
();
it_2
.
next
())
{
if
(
!
(
nj_col_2
=
it_2
.
get_or_create_column_ref
(
thd
,
&
is_created
)))
goto
err
;
/*
The following assert checks that mark_common_columns() was run and
we created the list table_ref_2->join_columns.
*/
DBUG_ASSERT
(
!
is_created
);
nj_col_2
=
it_2
.
get_natural_column_ref
();
if
(
!
nj_col_2
->
is_common
)
non_join_columns
->
push_back
(
nj_col_2
);
else
...
...
@@ -5449,8 +5338,7 @@ insert_fields(THD *thd, Name_resolution_context *context, const char *db_name,
because it was already created and stored with the natural join.
*/
Natural_join_column
*
nj_col
;
if
(
!
(
nj_col
=
field_iterator
.
get_or_create_column_ref
(
thd
,
&
is_created
)))
if
(
!
(
nj_col
=
field_iterator
.
get_or_create_column_ref
(
&
is_created
)))
DBUG_RETURN
(
TRUE
);
DBUG_ASSERT
(
nj_col
->
table_field
&&
!
is_created
);
field_table
=
nj_col
->
table_ref
->
table
;
...
...
sql/sql_insert.cc
View file @
3d01a3af
...
...
@@ -113,11 +113,7 @@ static int check_insert_fields(THD *thd, TABLE_LIST *table_list,
{
// Part field list
SELECT_LEX
*
select_lex
=
&
thd
->
lex
->
select_lex
;
Name_resolution_context
*
context
=
&
select_lex
->
context
;
TABLE_LIST
*
save_next_local
;
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
;
Name_resolution_context_state
ctx_state
;
int
res
;
if
(
fields
.
elements
!=
values
.
elements
)
...
...
@@ -130,14 +126,7 @@ static int check_insert_fields(THD *thd, TABLE_LIST *table_list,
select_lex
->
no_wrap_view_item
=
TRUE
;
/* Save the state of the current name resolution context. */
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
;
ctx_state
.
save_state
(
context
,
table_list
);
/*
Perform name resolution only in the first table - 'table_list',
...
...
@@ -152,13 +141,7 @@ static int check_insert_fields(THD *thd, TABLE_LIST *table_list,
res
=
setup_fields
(
thd
,
0
,
fields
,
2
,
0
,
0
);
/* Restore the current context. */
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
;
ctx_state
.
restore_state
(
context
,
table_list
);
thd
->
lex
->
select_lex
.
no_wrap_view_item
=
FALSE
;
if
(
res
)
...
...
@@ -293,13 +276,10 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
ulonglong
id
;
COPY_INFO
info
;
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_item
*
values
;
Name_resolution_context
*
context
;
Name_resolution_context_state
ctx_state
;
#ifndef EMBEDDED_LIBRARY
char
*
query
=
thd
->
query
;
#endif
...
...
@@ -380,13 +360,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
context
=
&
thd
->
lex
->
select_lex
.
context
;
/* Save the state of the current name resolution context. */
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
;
ctx_state
.
save_state
(
context
,
table_list
);
/*
Perform name resolution only in the first table - 'table_list',
...
...
@@ -410,16 +384,11 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
its
.
rewind
();
/* Restore the current context. */
table_list
->
next_local
=
save_next_local
;
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
;
ctx_state
.
restore_state
(
context
,
table_list
);
/*
Fill in the given fields and dump it to the table file
*/
info
.
records
=
info
.
deleted
=
info
.
copied
=
info
.
updated
=
0
;
info
.
ignore
=
ignore
;
info
.
handle_duplicates
=
duplic
;
...
...
@@ -827,11 +796,7 @@ bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list,
{
SELECT_LEX
*
select_lex
=
&
thd
->
lex
->
select_lex
;
Name_resolution_context
*
context
=
&
select_lex
->
context
;
TABLE_LIST
*
save_table_list
;
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
;
Name_resolution_context_state
ctx_state
;
bool
insert_into_view
=
(
table_list
->
view
!=
0
);
bool
res
=
0
;
DBUG_ENTER
(
"mysql_prepare_insert"
);
...
...
@@ -871,15 +836,7 @@ bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list,
DBUG_RETURN
(
TRUE
);
/* Save the state of the current name resolution context. */
save_table_list
=
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
;
ctx_state
.
save_state
(
context
,
table_list
);
/*
Perform name resolution only in the first table - 'table_list',
...
...
@@ -904,23 +861,17 @@ bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list,
*/
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() */
context
->
first_name_resolution_table
->
next_name_resolution_table
=
save_next_local
;
next_name_resolution_table
=
ctx_state
.
save_next_local
;
}
if
(
!
res
)
res
=
setup_fields
(
thd
,
0
,
update_values
,
1
,
0
,
0
);
}
/* Restore the current context. */
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
;
ctx_state
.
restore_state
(
context
,
table_list
);
if
(
res
)
DBUG_RETURN
(
res
);
...
...
@@ -2187,17 +2138,10 @@ select_insert::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
{
/* Save the state of the current name resolution context. */
Name_resolution_context
*
context
=
&
lex
->
select_lex
.
context
;
TABLE_LIST
*
save_table_list
;
TABLE_LIST
*
save_next_local
;
TABLE_LIST
*
save_first_name_resolution_table
;
TABLE_LIST
*
save_next_name_resolution_table
;
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
;
Name_resolution_context_state
ctx_state
;
/* Save the state of the current name resolution context. */
ctx_state
.
save_state
(
context
,
table_list
);
/* Perform name resolution only in the first table - 'table_list'. */
table_list
->
next_local
=
0
;
...
...
@@ -2213,20 +2157,15 @@ select_insert::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
*/
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() */
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
);
/* Restore the current context. */
table_list
->
next_local
=
save_next_local
;
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
;
ctx_state
.
restore_state
(
context
,
table_list
);
}
lex
->
current_select
=
lex_current_select_save
;
...
...
sql/sql_lex.cc
View file @
3d01a3af
...
...
@@ -1130,6 +1130,11 @@ void st_select_lex::init_query()
/*
Add the name resolution context of the current (sub)query to the
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
);
cond_count
=
with_wild
=
0
;
...
...
sql/sql_lex.h
View file @
3d01a3af
...
...
@@ -1024,9 +1024,9 @@ typedef struct st_lex
}
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
()
...
...
sql/sql_list.h
View file @
3d01a3af
...
...
@@ -266,10 +266,21 @@ class base_list_iterator
ls
.
elements
=
elm
;
}
public:
base_list_iterator
(
base_list
&
list_par
)
:
list
(
&
list_par
),
el
(
&
list_par
.
first
),
prev
(
0
),
current
(
0
)
base_list_iterator
()
:
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
)
{
prev
=
el
;
...
...
@@ -364,6 +375,8 @@ template <class T> class List_iterator :public base_list_iterator
{
public:
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
*
replace
(
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 @@ template <class T> class List_iterator_fast :public base_list_iterator
public:
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
void
rewind
(
void
)
{
base_list_iterator
::
rewind
();
}
void
sublist
(
List
<
T
>
&
list_arg
,
uint
el_arg
)
...
...
sql/sql_parse.cc
View file @
3d01a3af
...
...
@@ -6585,36 +6585,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
make_join_
on_context()
push_new_name_resoluti
on_context()
thd pointer to current thread
left_op left operand of the JOIN
right_op rigth operand of the JOIN
DESCRIPTION
Create a new name resolution context for a JOIN ... ON clause,
and set the first and last leaves of the list of table references
to be used for name resolution.
set the first and last leaves of the list of table references
to be used for name resolution, and push the newly created
context to the stack of contexts of the query.
RETURN
A new context
if all is OK
NULL -
if a memory allocation error occured
FALSE
if all is OK
TRUE
if a memory allocation error occured
*/
Name_resolution_context
*
make_join_on_context
(
THD
*
thd
,
TABLE_LIST
*
left_op
,
TABLE_LIST
*
right_op
)
bool
push_new_name_resolution_context
(
THD
*
thd
,
TABLE_LIST
*
left_op
,
TABLE_LIST
*
right_op
)
{
Name_resolution_context
*
on_context
;
if
(
!
(
on_context
=
new
(
thd
->
mem_root
)
Name_resolution_context
))
return
NULL
;
return
TRUE
;
on_context
->
init
();
on_context
->
first_name_resolution_table
=
left_op
->
first_leaf_for_name_resolution
();
on_context
->
last_name_resolution_table
=
right_op
->
last_leaf_for_name_resolution
();
return
on_context
;
return
thd
->
lex
->
push_context
(
on_context
)
;
}
...
...
sql/sql_yacc.yy
View file @
3d01a3af
...
...
@@ -5808,10 +5808,8 @@ join_table:
{
YYERROR_UNLESS($1 && ($$=$3));
/* Change the current name resolution context to a local context. */
Name_resolution_context *on_context;
if (!(on_context= make_join_on_context(YYTHD,$1,$3)))
if (push_new_name_resolution_context(YYTHD, $1, $3))
YYABORT;
Lex->push_context(on_context);
}
expr
{
...
...
@@ -5823,10 +5821,8 @@ join_table:
{
YYERROR_UNLESS($1 && ($$=$3));
/* Change the current name resolution context to a local context. */
Name_resolution_context *on_context;
if (!(on_context= make_join_on_context(YYTHD,$1,$3)))
if (push_new_name_resolution_context(YYTHD, $1, $3))
YYABORT;
Lex->push_context(on_context);
}
expr
{
...
...
@@ -5853,10 +5849,8 @@ join_table:
ON
{
/* Change the current name resolution context to a local context. */
Name_resolution_context *on_context;
if (!(on_context= make_join_on_context(YYTHD,$1,$5)))
if (push_new_name_resolution_context(YYTHD, $1, $5))
YYABORT;
Lex->push_context(on_context);
}
expr
{
...
...
@@ -5886,10 +5880,8 @@ join_table:
ON
{
/* Change the current name resolution context to a local context. */
Name_resolution_context *on_context;
if (!(on_context= make_join_on_context(YYTHD,$1,$5)))
if (push_new_name_resolution_context(YYTHD, $1, $5))
YYABORT;
Lex->push_context(on_context);
}
expr
{
...
...
@@ -5950,10 +5942,9 @@ table_factor:
ON
{
/* Change the current name resolution context to a local context. */
Name_resolution_context *on_context;
if (!(on_context= make_join_on_context(YYTHD,$3,$7)))
if (push_new_name_resolution_context(YYTHD, $3, $7))
YYABORT;
Lex->push_context(on_context);
}
expr '}'
{
...
...
sql/table.cc
View file @
3d01a3af
...
...
@@ -3080,60 +3080,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
.
str
;
table_name
=
table_ref
->
table
->
s
->
table_name
.
str
;
}
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
)
{
DBUG_ASSERT
(
table
->
field_translation
);
...
...
@@ -3176,8 +3122,9 @@ Item *create_view_field(THD *thd, TABLE_LIST *view, Item **field_ref,
if
(
view
->
schema_table_reformed
)
{
/*
In case of SHOW command (schema_table_reformed set) all items are
fixed
Translation table items are always Item_fields and already 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_RETURN
(
field
);
...
...
@@ -3209,21 +3156,14 @@ Item *create_view_field(THD *thd, TABLE_LIST *view, Item **field_ref,
void
Field_iterator_natural_join
::
set
(
TABLE_LIST
*
table_ref
)
{
DBUG_ASSERT
(
table_ref
->
join_columns
);
delete
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
)
++
;
column_ref_it
.
init
(
*
(
table_ref
->
join_columns
));
cur_column_ref
=
column_ref_it
++
;
}
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
||
cur_column_ref
->
table_ref
->
table
==
cur_column_ref
->
table_field
->
table
);
...
...
@@ -3350,7 +3290,6 @@ GRANT_INFO *Field_iterator_table_ref::grant()
SYNOPSIS
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,
FALSE if we return an already created colum
...
...
@@ -3363,7 +3302,7 @@ GRANT_INFO *Field_iterator_table_ref::grant()
*/
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
;
...
...
@@ -3397,6 +3336,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
*****************************************************************************/
...
...
sql/table.h
View file @
3d01a3af
...
...
@@ -432,9 +432,6 @@ class Natural_join_column: public Sql_alloc
const
char
*
table_name
();
const
char
*
db_name
();
GRANT_INFO
*
grant
();
#ifndef NO_EMBEDDED_ACCESS_CHECKS
bool
check_grants
(
THD
*
thd
,
const
char
*
name
,
uint
length
);
#endif
};
...
...
@@ -760,11 +757,11 @@ class Field_iterator_view: 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
;
public:
Field_iterator_natural_join
()
:
c
olumn_ref_it
(
NULL
),
c
ur_column_ref
(
NULL
)
{}
~
Field_iterator_natural_join
()
{
delete
column_ref_it
;
}
Field_iterator_natural_join
()
:
cur_column_ref
(
NULL
)
{}
~
Field_iterator_natural_join
()
{}
void
set
(
TABLE_LIST
*
table
);
void
next
();
bool
end_of_fields
()
{
return
!
cur_column_ref
;
}
...
...
@@ -811,7 +808,8 @@ class Field_iterator_table_ref: public Field_iterator
GRANT_INFO
*
grant
();
Item
*
create_item
(
THD
*
thd
)
{
return
field_it
->
create_item
(
thd
);
}
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