diff options
author | unknown <bell@sanja.is.com.ua> | 2004-11-11 21:18:10 +0200 |
---|---|---|
committer | unknown <bell@sanja.is.com.ua> | 2004-11-11 21:18:10 +0200 |
commit | 3bc1fcd409eb08474884a556fef193d707117212 (patch) | |
tree | b838d2bae358ea54b828bff0e3dfb8a0faf1bc8e /sql/table.cc | |
parent | e5fd013fdf6c8664daa0bbdcaf0d22bf44e90d62 (diff) | |
parent | 5b82bc6644fb766c7a04b49d60e70c474450ce28 (diff) | |
download | mariadb-git-3bc1fcd409eb08474884a556fef193d707117212.tar.gz |
merge
sql/item_cmpfunc.h:
Auto merged
sql/item_subselect.cc:
Auto merged
sql/mysql_priv.h:
Auto merged
sql/opt_sum.cc:
Auto merged
sql/sp.cc:
Auto merged
sql/sql_class.h:
Auto merged
sql/sql_delete.cc:
Auto merged
sql/sql_help.cc:
Auto merged
sql/sql_lex.cc:
Auto merged
sql/sql_lex.h:
Auto merged
sql/sql_load.cc:
Auto merged
sql/sql_prepare.cc:
Auto merged
sql/sql_select.cc:
Auto merged
sql/sql_view.h:
Auto merged
sql/sql_yacc.yy:
Auto merged
Diffstat (limited to 'sql/table.cc')
-rw-r--r-- | sql/table.cc | 244 |
1 files changed, 213 insertions, 31 deletions
diff --git a/sql/table.cc b/sql/table.cc index 0e8045abacf..74e35e0f2d7 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -1517,10 +1517,65 @@ void st_table_list::calc_md5(char *buffer) void st_table_list::set_ancestor() { - if (ancestor->ancestor) - ancestor->set_ancestor(); - table= ancestor->table; - ancestor->table->grant= grant; + /* process all tables of view */ + for (TABLE_LIST *tbl= ancestor; tbl; tbl= tbl->next_local) + { + if (tbl->ancestor) + ancestor->set_ancestor(); + tbl->table->grant= grant; + } + /* if view contain only one table, substitute TABLE of it */ + if (!ancestor->next_local) + table= ancestor->table; +} + + +/* + Save old want_privilege and clear want_privilege + + SYNOPSIS + save_and_clear_want_privilege() +*/ + +void st_table_list::save_and_clear_want_privilege() +{ + for (TABLE_LIST *tbl= ancestor; tbl; tbl= tbl->next_local) + { + if (tbl->table) + { + privilege_backup= tbl->table->grant.want_privilege; + tbl->table->grant.want_privilege= 0; + } + else + { + DBUG_ASSERT(tbl->view && tbl->ancestor && + tbl->ancestor->next_local); + tbl->save_and_clear_want_privilege(); + } + } +} + + +/* + restore want_privilege saved by save_and_clear_want_privilege + + SYNOPSIS + restore_want_privilege() +*/ + +void st_table_list::restore_want_privilege() +{ + for (TABLE_LIST *tbl= ancestor; tbl; tbl= tbl->next_local) + { + if (tbl->table) + tbl->table->grant.want_privilege= privilege_backup; + else + { + DBUG_ASSERT(tbl->view && tbl->ancestor && + tbl->ancestor->next_local); + tbl->restore_want_privilege(); + } + } } @@ -1550,10 +1605,11 @@ void st_table_list::set_ancestor() bool st_table_list::setup_ancestor(THD *thd, Item **conds, uint8 check_opt_type) { - Item **transl; + Field_translator *transl; SELECT_LEX *select= &view->select_lex; SELECT_LEX *current_select_save= thd->lex->current_select; Item *item; + TABLE_LIST *tbl; List_iterator_fast<Item> it(select->item_list); uint i= 0; bool save_set_query_id= thd->set_query_id; @@ -1561,38 +1617,57 @@ bool st_table_list::setup_ancestor(THD *thd, Item **conds, bool save_allow_sum_func= thd->allow_sum_func; DBUG_ENTER("st_table_list::setup_ancestor"); - if (ancestor->ancestor && - ancestor->setup_ancestor(thd, conds, - (check_opt_type == VIEW_CHECK_CASCADED ? - VIEW_CHECK_CASCADED : - VIEW_CHECK_NONE))) - DBUG_RETURN(1); + for (tbl= ancestor; tbl; tbl= tbl->next_local) + { + if (tbl->ancestor && + tbl->setup_ancestor(thd, conds, + (check_opt_type == VIEW_CHECK_CASCADED ? + VIEW_CHECK_CASCADED : + VIEW_CHECK_NONE))) + DBUG_RETURN(1); + } if (field_translation) { /* prevent look up in SELECTs tree */ thd->lex->current_select= &thd->lex->select_lex; + thd->lex->select_lex.no_wrap_view_item= 1; thd->set_query_id= 1; /* this view was prepared already on previous PS/SP execution */ - Item **end= field_translation + select->item_list.elements; - for (Item **item= field_translation; item < end; item++) + Field_translator *end= field_translation + select->item_list.elements; + /* real rights will be checked in VIEW field */ + save_and_clear_want_privilege(); + /* aggregate function are allowed */ + thd->allow_sum_func= 1; + for (transl= field_translation; transl < end; transl++) { - /* TODO: fix for several tables in VIEW */ - uint want_privilege= ancestor->table->grant.want_privilege; - /* real rights will be checked in VIEW field */ - ancestor->table->grant.want_privilege= 0; - /* aggregate function are allowed */ - thd->allow_sum_func= 1; - if (!(*item)->fixed && (*item)->fix_fields(thd, ancestor, item)) + if (!transl->item->fixed && + transl->item->fix_fields(thd, ancestor, &transl->item)) goto err; - ancestor->table->grant.want_privilege= want_privilege; + } + for (tbl= ancestor; tbl; tbl= tbl->next_local) + { + if (tbl->on_expr && !tbl->on_expr->fixed && + tbl->on_expr->fix_fields(thd, ancestor, &tbl->on_expr)) + goto err; + } + if (where && !where->fixed && where->fix_fields(thd, ancestor, &where)) + goto err; + restore_want_privilege(); + + /* WHERE/ON resolved => we can rename fields */ + for (transl= field_translation; transl < end; transl++) + { + transl->item->rename((char *)transl->name); } goto ok; } /* view fields translation table */ if (!(transl= - (Item**)(thd->current_arena->alloc(select->item_list.elements * sizeof(Item*))))) + (Field_translator*)(thd->current_arena-> + alloc(select->item_list.elements * + sizeof(Field_translator))))) { DBUG_RETURN(1); } @@ -1608,22 +1683,29 @@ bool st_table_list::setup_ancestor(THD *thd, Item **conds, used fields correctly. */ thd->set_query_id= 1; + /* real rights will be checked in VIEW field */ + save_and_clear_want_privilege(); + /* aggregate function are allowed */ + thd->allow_sum_func= 1; while ((item= it++)) { - /* TODO: fix for several tables in VIEW */ - uint want_privilege= ancestor->table->grant.want_privilege; - /* real rights will be checked in VIEW field */ - ancestor->table->grant.want_privilege= 0; - /* aggregate function are allowed */ - thd->allow_sum_func= 1; + /* save original name of view column */ + char *name= item->name; if (!item->fixed && item->fix_fields(thd, ancestor, &item)) goto err; - ancestor->table->grant.want_privilege= want_privilege; - transl[i++]= item; + /* set new item get in fix fields and original column name */ + transl[i].name= name; + transl[i++].item= item; } field_translation= transl; /* TODO: sort this list? Use hash for big number of fields */ + for (tbl= ancestor; tbl; tbl= tbl->next_local) + { + if (tbl->on_expr && !tbl->on_expr->fixed && + tbl->on_expr->fix_fields(thd, ancestor, &tbl->on_expr)) + goto err; + } if (where || (check_opt_type == VIEW_CHECK_CASCADED && ancestor->check_option)) @@ -1696,6 +1778,8 @@ bool st_table_list::setup_ancestor(THD *thd, Item **conds, if (arena) thd->restore_backup_item_arena(arena, &backup); } + restore_want_privilege(); + /* fix_fields do not need tables, because new are only AND operation and we just need recollect statistics @@ -1704,6 +1788,15 @@ bool st_table_list::setup_ancestor(THD *thd, Item **conds, check_option->fix_fields(thd, 0, &check_option)) goto err; + /* WHERE/ON resolved => we can rename fields */ + { + Field_translator *end= field_translation + select->item_list.elements; + for (transl= field_translation; transl < end; transl++) + { + transl->item->rename((char *)transl->name); + } + } + /* full text function moving to current select */ if (view->select_lex.ftfunc_list->elements) { @@ -1788,6 +1881,95 @@ int st_table_list::view_check_option(THD *thd, bool ignore_failure) } +/* + Find table in underlaying tables by mask and check that only this + table sbelong to given mask + + SYNOPSIS + st_table_list::check_single_table() + table reference on variable where to store found table + (should be 0 on call, to find table, or point to table for + unique test) + map bit mask of tables + + RETURN + 0 table not found or found only one + 1 found several tables +*/ + +bool st_table_list::check_single_table(st_table_list **table, table_map map) +{ + for (TABLE_LIST *tbl= ancestor; tbl; tbl= tbl->next_local) + { + if (tbl->table) + { + if (tbl->table->map & map) + { + if (*table) + return 1; + else + *table= tbl; + } + } + else + if (tbl->check_single_table(table, map)) + return 1; + } +} + + +/* + Set insert_values buffer + + SYNOPSIS + set_insert_values() + mem_root memory pool for allocating + + RETURN + FALSE - OK + TRUE - out of memory +*/ + +bool st_table_list::set_insert_values(MEM_ROOT *mem_root) +{ + if (table) + { + if (!table->insert_values && + !(table->insert_values= (byte *)alloc_root(mem_root, + table->rec_buff_length))) + return TRUE; + } + else + { + DBUG_ASSERT(view && ancestor && ancestor->next_local); + for (TABLE_LIST *tbl= ancestor; tbl; tbl= tbl->next_local) + if (tbl->set_insert_values(mem_root)) + return TRUE; + } + return FALSE; +} + + +/* + clear insert_values reference + + SYNOPSIS + clear_insert_values() +*/ + +void st_table_list::clear_insert_values() +{ + if (table) + table->insert_values= 0; + else + { + DBUG_ASSERT(view && ancestor && ancestor->next_local); + for (TABLE_LIST *tbl= ancestor; tbl; tbl= tbl->next_local) + tbl->clear_insert_values(); + } +} + + void Field_iterator_view::set(TABLE_LIST *table) { ptr= table->field_translation; @@ -1809,7 +1991,7 @@ Item *Field_iterator_table::item(THD *thd) const char *Field_iterator_view::name() { - return (*ptr)->name; + return ptr->name; } |