summaryrefslogtreecommitdiff
path: root/sql/sql_base.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/sql_base.cc')
-rw-r--r--sql/sql_base.cc177
1 files changed, 94 insertions, 83 deletions
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index d8bbb686ba2..7cc0c4fecf1 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -2439,21 +2439,19 @@ find_field_in_table(THD *thd, TABLE_LIST *table_list,
table_list->alias, name, item_name, (ulong) ref));
if (table_list->field_translation)
{
- uint num;
- if (table_list->schema_table_reformed)
+ Field_iterator_view field_it;
+ field_it.set(table_list);
+ DBUG_ASSERT(table_list->schema_table_reformed ||
+ (ref != 0 && table_list->view != 0));
+ for (; !field_it.end_of_fields(); field_it.next())
{
- num= thd->lex->current_select->item_list.elements;
- }
- else
- {
- DBUG_ASSERT(ref != 0 && table_list->view != 0);
- num= table_list->view->select_lex.item_list.elements;
- }
- Field_translator *trans= table_list->field_translation;
- for (uint i= 0; i < num; i ++)
- {
- if (!my_strcasecmp(system_charset_info, trans[i].name, name))
+ if (!my_strcasecmp(system_charset_info, field_it.name(), name))
{
+ Item *item= field_it.create_item(thd);
+ if (!item)
+ {
+ DBUG_RETURN(0);
+ }
if (table_list->schema_table_reformed)
{
/*
@@ -2462,7 +2460,7 @@ find_field_in_table(THD *thd, TABLE_LIST *table_list,
So we can return ->field. It is used only for
'show & where' commands.
*/
- DBUG_RETURN(((Item_field*) (trans[i].item))->field);
+ DBUG_RETURN(((Item_field*) (field_it.item()))->field);
}
#ifndef NO_EMBEDDED_ACCESS_CHECKS
if (check_grants_view &&
@@ -2472,26 +2470,10 @@ find_field_in_table(THD *thd, TABLE_LIST *table_list,
name, length))
DBUG_RETURN(WRONG_GRANT);
#endif
- if (thd->lex->current_select->no_wrap_view_item)
- {
- if (register_tree_change)
- thd->change_item_tree(ref, trans[i].item);
- else
- *ref= trans[i].item;
- }
+ if (register_tree_change)
+ thd->change_item_tree(ref, item);
else
- {
- Item_ref *item_ref= new Item_ref(&trans[i].item,
- table_list->view_name.str,
- item_name);
- /* as far as Item_ref have defined reference it do not need tables */
- if (register_tree_change && item_ref)
- thd->change_item_tree(ref, item_ref);
- else if (item_ref)
- *ref= item_ref;
- if (!(*ref)->fixed)
- (*ref)->fix_fields(thd, 0, ref);
- }
+ *ref= item;
DBUG_RETURN((Field*) view_ref_found);
}
}
@@ -3066,7 +3048,8 @@ int setup_wild(THD *thd, TABLE_LIST *tables, List<Item> &fields,
*/
it.replace(new Item_int("Not_used", (longlong) 1, 21));
}
- else if (insert_fields(thd,tables,((Item_field*) item)->db_name,
+ else if (insert_fields(thd, ((Item_field*) item)->context,
+ ((Item_field*) item)->db_name,
((Item_field*) item)->table_name, &it,
any_privileges))
{
@@ -3102,7 +3085,7 @@ int setup_wild(THD *thd, TABLE_LIST *tables, List<Item> &fields,
** Check that all given fields exists and fill struct with current data
****************************************************************************/
-bool setup_fields(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables,
+bool setup_fields(THD *thd, Item **ref_pointer_array,
List<Item> &fields, bool set_query_id,
List<Item> *sum_func_list, bool allow_sum_func)
{
@@ -3131,7 +3114,7 @@ bool setup_fields(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables,
Item **ref= ref_pointer_array;
while ((item= it++))
{
- if (!item->fixed && item->fix_fields(thd, tables, it.ref()) ||
+ if (!item->fixed && item->fix_fields(thd, it.ref()) ||
(item= *(it.ref()))->check_cols(1))
{
DBUG_RETURN(TRUE); /* purecov: inspected */
@@ -3181,6 +3164,7 @@ TABLE_LIST **make_leaves_list(TABLE_LIST **list, TABLE_LIST *tables)
SYNOPSIS
setup_tables()
thd Thread handler
+ context name resolution contest to setup table list there
tables Table list
conds Condition of current SELECT (can be changed by VIEW)
leaves List of join table leaves list
@@ -3200,11 +3184,15 @@ TABLE_LIST **make_leaves_list(TABLE_LIST **list, TABLE_LIST *tables)
TRUE error
*/
-bool setup_tables(THD *thd, TABLE_LIST *tables, Item **conds,
+bool setup_tables(THD *thd, Name_resolution_context *context,
+ TABLE_LIST *tables, Item **conds,
TABLE_LIST **leaves, bool select_insert)
{
uint tablenr= 0;
DBUG_ENTER("setup_tables");
+
+ context->table_list= tables;
+
/*
this is used for INSERT ... SELECT.
For select we setup tables except first (and its underlying tables)
@@ -3259,10 +3247,21 @@ bool setup_tables(THD *thd, TABLE_LIST *tables, Item **conds,
table_list;
table_list= table_list->next_local)
{
- if (table_list->ancestor &&
- table_list->setup_ancestor(thd, conds,
- table_list->effective_with_check))
- DBUG_RETURN(1);
+ if (table_list->ancestor)
+ {
+ DBUG_ASSERT(table_list->view);
+ Query_arena *arena= thd->current_arena, backup;
+ bool res;
+ if (arena->is_conventional())
+ arena= 0; // For easier test
+ else
+ thd->set_n_backup_item_arena(arena, &backup);
+ res= table_list->setup_ancestor(thd);
+ if (arena)
+ thd->restore_backup_item_arena(arena, &backup);
+ if (res)
+ DBUG_RETURN(1);
+ }
}
DBUG_RETURN(0);
}
@@ -3314,7 +3313,7 @@ bool get_key_map_from_key_list(key_map *map, TABLE *table,
SYNOPSIS
insert_fields()
thd Thread handler
- tables List of tables
+ context Context for name resolution
db_name Database name in case of 'database_name.table_name.*'
table_name Table name in case of 'table_name.*'
it Pointer to '*'
@@ -3328,7 +3327,7 @@ bool get_key_map_from_key_list(key_map *map, TABLE *table,
*/
bool
-insert_fields(THD *thd, TABLE_LIST *tables, const char *db_name,
+insert_fields(THD *thd, Name_resolution_context *context, const char *db_name,
const char *table_name, List_iterator<Item> *it,
bool any_privileges)
{
@@ -3352,7 +3351,9 @@ insert_fields(THD *thd, TABLE_LIST *tables, const char *db_name,
}
found= 0;
- for (; tables; tables= tables->next_local)
+ for (TABLE_LIST *tables= context->table_list;
+ tables;
+ tables= tables->next_local)
{
Field_iterator *iterator;
TABLE_LIST *natural_join_table;
@@ -3361,7 +3362,6 @@ insert_fields(THD *thd, TABLE_LIST *tables, const char *db_name,
TABLE_LIST *last;
TABLE_LIST *embedding;
TABLE *table= tables->table;
- bool alias_used= 0;
if (!table_name || (!my_strcasecmp(table_alias_charset, table_name,
tables->alias) &&
@@ -3395,16 +3395,6 @@ insert_fields(THD *thd, TABLE_LIST *tables, const char *db_name,
}
}
#endif
- if (table)
- thd->used_tables|= table->map;
- else
- {
- view_iter.set(tables);
- for (; !view_iter.end_of_fields(); view_iter.next())
- {
- thd->used_tables|= view_iter.item(thd)->used_tables();
- }
- }
natural_join_table= 0;
last= embedded= tables;
@@ -3435,8 +3425,6 @@ insert_fields(THD *thd, TABLE_LIST *tables, const char *db_name,
{
iterator= &view_iter;
view= 1;
- alias_used= my_strcasecmp(table_alias_charset,
- tables->table_name, tables->alias);
}
else
{
@@ -3445,6 +3433,10 @@ insert_fields(THD *thd, TABLE_LIST *tables, const char *db_name,
}
iterator->set(tables);
+ /* for view used tables will be collected in following loop */
+ if (table)
+ thd->used_tables|= table->map;
+
for (; !iterator->end_of_fields(); iterator->next())
{
Item *not_used_item;
@@ -3457,16 +3449,10 @@ insert_fields(THD *thd, TABLE_LIST *tables, const char *db_name,
strlen(field_name), &not_used_item, 0, 0, 0,
&not_used_field_index, TRUE))
{
- Item *item= iterator->item(thd);
- if (view && !thd->lex->current_select->no_wrap_view_item)
- {
- /*
- as far as we have view, then item point to view_iter, so we
- can use it directly for this view specific operation
- */
- item= new Item_ref(view_iter.item_ptr(), tables->view_name.str,
- field_name);
- }
+ Item *item= iterator->create_item(thd);
+ if (!item)
+ goto err;
+ thd->used_tables|= item->used_tables();
if (!found++)
(void) it->replace(item); // Replace '*'
else
@@ -3537,9 +3523,7 @@ insert_fields(THD *thd, TABLE_LIST *tables, const char *db_name,
my_message(ER_NO_TABLES_USED, ER(ER_NO_TABLES_USED), MYF(0));
else
my_error(ER_BAD_TABLE_ERROR, MYF(0), table_name);
-#ifndef NO_EMBEDDED_ACCESS_CHECKS
err:
-#endif
DBUG_RETURN(1);
}
@@ -3550,16 +3534,25 @@ err:
SYNOPSIS
setup_conds()
thd thread handler
- tables list of tables for name resolving
leaves list of leaves of join table tree
*/
-int setup_conds(THD *thd, TABLE_LIST *tables, TABLE_LIST *leaves, COND **conds)
+int setup_conds(THD *thd, TABLE_LIST *tables, TABLE_LIST *leaves,
+ COND **conds)
{
SELECT_LEX *select_lex= thd->lex->current_select;
Query_arena *arena= thd->current_arena, backup;
- bool save_wrapper= thd->lex->current_select->no_wrap_view_item;
TABLE_LIST *table= NULL; // For HP compilers
+ /*
+ it_is_update set to TRUE when tables of primary SELECT_LEX (SELECT_LEX
+ which belong to LEX, i.e. most up SELECT) will be updated by
+ INSERT/UPDATE/LOAD
+ NOTE: using this condition helps to prevent call of prepare_check_option()
+ from subquery of VIEW, because tables of subquery belongs to VIEW
+ (see condition before prepare_check_option() call)
+ */
+ bool it_is_update= (select_lex == &thd->lex->select_lex) &&
+ thd->lex->which_check_option_applicable();
DBUG_ENTER("setup_conds");
if (select_lex->conds_processed_with_permanent_arena ||
@@ -3568,12 +3561,17 @@ int setup_conds(THD *thd, TABLE_LIST *tables, TABLE_LIST *leaves, COND **conds)
thd->set_query_id=1;
- thd->lex->current_select->no_wrap_view_item= 0;
+ for (table= tables; table; table= table->next_local)
+ {
+ if (table->prepare_where(thd, conds, FALSE))
+ goto err_no_arena;
+ }
+
select_lex->cond_count= 0;
if (*conds)
{
thd->where="where clause";
- if (!(*conds)->fixed && (*conds)->fix_fields(thd, tables, conds) ||
+ if (!(*conds)->fixed && (*conds)->fix_fields(thd, conds) ||
(*conds)->check_cols(1))
goto err_no_arena;
}
@@ -3591,11 +3589,12 @@ int setup_conds(THD *thd, TABLE_LIST *tables, TABLE_LIST *leaves, COND **conds)
/* Make a join an a expression */
thd->where="on clause";
if (!embedded->on_expr->fixed &&
- embedded->on_expr->fix_fields(thd, tables, &embedded->on_expr) ||
+ embedded->on_expr->fix_fields(thd, &embedded->on_expr) ||
embedded->on_expr->check_cols(1))
goto err_no_arena;
select_lex->cond_count++;
}
+
if (embedded->natural_join)
{
/* Make a join of all fields wich have the same name */
@@ -3675,7 +3674,8 @@ int setup_conds(THD *thd, TABLE_LIST *tables, TABLE_LIST *leaves, COND **conds)
{
if (t2_field != view_ref_found)
{
- if (!(item_t2= new Item_field(thd, t2_field)))
+ if (!(item_t2= new Item_field(thd, &select_lex->context,
+ t2_field)))
goto err;
/* Mark field used for table cache */
t2_field->query_id= thd->query_id;
@@ -3687,7 +3687,7 @@ int setup_conds(THD *thd, TABLE_LIST *tables, TABLE_LIST *leaves, COND **conds)
t1_field->query_id= thd->query_id;
t1->used_keys.intersect(t1_field->part_of_key);
}
- Item_func_eq *tmp= new Item_func_eq(iterator->item(thd),
+ Item_func_eq *tmp= new Item_func_eq(iterator->create_item(thd),
item_t2);
if (!tmp)
goto err;
@@ -3703,7 +3703,7 @@ int setup_conds(THD *thd, TABLE_LIST *tables, TABLE_LIST *leaves, COND **conds)
{
COND *on_expr= cond_and;
if (!on_expr->fixed)
- on_expr->fix_fields(thd, 0, &on_expr);
+ on_expr->fix_fields(thd, &on_expr);
if (!embedded->outer_join) // Not left join
{
*conds= and_conds(*conds, cond_and);
@@ -3712,7 +3712,7 @@ int setup_conds(THD *thd, TABLE_LIST *tables, TABLE_LIST *leaves, COND **conds)
thd->restore_backup_item_arena(arena, &backup);
if (*conds && !(*conds)->fixed)
{
- if ((*conds)->fix_fields(thd, tables, conds))
+ if ((*conds)->fix_fields(thd, conds))
goto err_no_arena;
}
}
@@ -3724,8 +3724,7 @@ int setup_conds(THD *thd, TABLE_LIST *tables, TABLE_LIST *leaves, COND **conds)
thd->restore_backup_item_arena(arena, &backup);
if (embedded->on_expr && !embedded->on_expr->fixed)
{
- if (embedded->on_expr->fix_fields(thd, tables,
- &embedded->on_expr))
+ if (embedded->on_expr->fix_fields(thd, &embedded->on_expr))
goto err_no_arena;
}
}
@@ -3737,6 +3736,20 @@ int setup_conds(THD *thd, TABLE_LIST *tables, TABLE_LIST *leaves, COND **conds)
}
while (embedding &&
embedding->nested_join->join_list.head() == embedded);
+
+ /* process CHECK OPTION */
+ if (it_is_update)
+ {
+ TABLE_LIST *view= table->belong_to_view;
+ if (!view)
+ view= table;
+ if (view->effective_with_check)
+ {
+ if (view->prepare_check_option(thd))
+ goto err_no_arena;
+ thd->change_item_tree(&table->check_option, view->check_option);
+ }
+ }
}
if (!thd->current_arena->is_conventional())
@@ -3750,14 +3763,12 @@ int setup_conds(THD *thd, TABLE_LIST *tables, TABLE_LIST *leaves, COND **conds)
select_lex->where= *conds;
select_lex->conds_processed_with_permanent_arena= 1;
}
- thd->lex->current_select->no_wrap_view_item= save_wrapper;
DBUG_RETURN(test(thd->net.report_error));
err:
if (arena)
thd->restore_backup_item_arena(arena, &backup);
err_no_arena:
- thd->lex->current_select->no_wrap_view_item= save_wrapper;
DBUG_RETURN(1);
}