The world's most popular open source database
#include "mysql_priv.h"#include "sql_select.h"#include "parse_file.h"#include "sp.h"#include "sp_head.h"#include "sp_cache.h"Include dependency graph for sql_view.cc:

Go to the source code of this file.
Defines | |
| #define | MYSQL_LEX 1 |
| #define | MD5_BUFF_LENGTH 33 |
Functions | |
| static int | mysql_register_view (THD *thd, TABLE_LIST *view, enum_view_create_mode mode) |
| static void | make_unique_view_field_name (Item *target, List< Item > &item_list, Item *last_element) |
| bool | check_duplicate_names (List< Item > &item_list, bool gen_unique_view_name) |
| static bool | fill_defined_view_parts (THD *thd, TABLE_LIST *view) |
| bool | mysql_create_view (THD *thd, enum_view_create_mode mode) |
| bool | mysql_make_view (THD *thd, File_parser *parser, TABLE_LIST *table, uint flags) |
| bool | mysql_drop_view (THD *thd, TABLE_LIST *views, enum_drop_mode drop_mode) |
| frm_type_enum | mysql_frm_type (THD *thd, char *path, enum legacy_db_type *dbt) |
| bool | check_key_in_view (THD *thd, TABLE_LIST *view) |
| bool | insert_view_fields (THD *thd, List< Item > *list, TABLE_LIST *view) |
| int | view_checksum (THD *thd, TABLE_LIST *view) |
| bool | mysql_rename_view (THD *thd, const char *new_name, TABLE_LIST *view) |
Variables | |
| const LEX_STRING | view_type = { C_STRING_WITH_LEN("VIEW") } |
| const char * | updatable_views_with_limit_names [] = { "NO", "YES", NullS } |
| TYPELIB | updatable_views_with_limit_typelib |
| static const int | revision_number_position = 8 |
| static const int | required_view_parameters = 10 |
| static const int | num_view_backups = 3 |
| static File_option | view_parameters [] |
| static LEX_STRING | view_file_type [] = {{(char*) STRING_WITH_LEN("VIEW") }} |
| #define MD5_BUFF_LENGTH 33 |
Definition at line 26 of file sql_view.cc.
Referenced by mysql_register_view(), and view_checksum().
| #define MYSQL_LEX 1 |
Definition at line 18 of file sql_view.cc.
Definition at line 122 of file sql_view.cc.
References check(), DBUG_ENTER, DBUG_RETURN, ER_DUP_FIELDNAME, err, FALSE, Item::FIELD_ITEM, Item::is_autogenerated_name, make_unique_view_field_name(), my_error(), my_strcasecmp, MYF, Item::name, Item::real_item(), List_iterator_fast< T >::rewind(), system_charset_info, TRUE, and Item::type().
Referenced by mysql_derived_prepare().
00123 { 00124 Item *item; 00125 List_iterator_fast<Item> it(item_list); 00126 List_iterator_fast<Item> itc(item_list); 00127 DBUG_ENTER("check_duplicate_names"); 00128 00129 while ((item= it++)) 00130 { 00131 Item *check; 00132 /* treat underlying fields like set by user names */ 00133 if (item->real_item()->type() == Item::FIELD_ITEM) 00134 item->is_autogenerated_name= FALSE; 00135 itc.rewind(); 00136 while ((check= itc++) && check != item) 00137 { 00138 if (my_strcasecmp(system_charset_info, item->name, check->name) == 0) 00139 { 00140 if (!gen_unique_view_name) 00141 goto err; 00142 if (item->is_autogenerated_name) 00143 make_unique_view_field_name(item, item_list, item); 00144 else if (check->is_autogenerated_name) 00145 make_unique_view_field_name(check, item_list, item); 00146 else 00147 goto err; 00148 } 00149 } 00150 } 00151 DBUG_RETURN(FALSE); 00152 00153 err: 00154 my_error(ER_DUP_FIELDNAME, MYF(0), item->name); 00155 DBUG_RETURN(TRUE); 00156 }
Here is the call graph for this function:

Here is the caller graph for this function:

| bool check_key_in_view | ( | THD * | thd, | |
| TABLE_LIST * | view | |||
| ) |
Definition at line 1460 of file sql_view.cc.
References st_table_list::belong_to_view, DBUG_ASSERT, DBUG_ENTER, DBUG_PRINT, DBUG_RETURN, FALSE, Item_field::field, st_table_list::field_translation, st_table_list::field_translation_end, Item_field::filed_for_view_update(), Item_field::fix_fields(), Item::fixed, st_key::flags, HA_NOSAME, HA_NULL_PART_KEY, st_table::key_info, st_key::key_part, st_key::key_parts, st_table_share::keys, MARK_COLUMNS_NONE, st_table::s, SQLCOM_INSERT, st_table_list::table, st_table_list::top_table(), TRUE, and st_table_list::view.
Referenced by check_insert_fields(), mysql_load(), mysql_multi_delete_prepare(), and mysql_prepare_delete().
01461 { 01462 TABLE *table; 01463 Field_translator *trans, *end_of_trans; 01464 KEY *key_info, *key_info_end; 01465 uint i; 01466 DBUG_ENTER("check_key_in_view"); 01467 01468 /* 01469 we do not support updatable UNIONs in VIEW, so we can check just limit of 01470 LEX::select_lex 01471 */ 01472 if ((!view->view && !view->belong_to_view) || 01473 thd->lex->sql_command == SQLCOM_INSERT || 01474 thd->lex->select_lex.select_limit == 0) 01475 DBUG_RETURN(FALSE); /* it is normal table or query without LIMIT */ 01476 table= view->table; 01477 view= view->top_table(); 01478 trans= view->field_translation; 01479 key_info_end= (key_info= table->key_info)+ table->s->keys; 01480 01481 end_of_trans= view->field_translation_end; 01482 DBUG_ASSERT(table != 0 && view->field_translation != 0); 01483 01484 { 01485 /* 01486 We should be sure that all fields are ready to get keys from them, but 01487 this operation should not have influence on Field::query_id, to avoid 01488 marking as used fields which are not used 01489 */ 01490 enum_mark_columns save_mark_used_columns= thd->mark_used_columns; 01491 thd->mark_used_columns= MARK_COLUMNS_NONE; 01492 DBUG_PRINT("info", ("thd->mark_used_columns: %d", thd->mark_used_columns)); 01493 for (Field_translator *fld= trans; fld < end_of_trans; fld++) 01494 { 01495 if (!fld->item->fixed && fld->item->fix_fields(thd, &fld->item)) 01496 { 01497 thd->mark_used_columns= save_mark_used_columns; 01498 return TRUE; 01499 } 01500 } 01501 thd->mark_used_columns= save_mark_used_columns; 01502 DBUG_PRINT("info", ("thd->mark_used_columns: %d", thd->mark_used_columns)); 01503 } 01504 /* Loop over all keys to see if a unique-not-null key is used */ 01505 for (;key_info != key_info_end ; key_info++) 01506 { 01507 if ((key_info->flags & (HA_NOSAME | HA_NULL_PART_KEY)) == HA_NOSAME) 01508 { 01509 KEY_PART_INFO *key_part= key_info->key_part; 01510 KEY_PART_INFO *key_part_end= key_part + key_info->key_parts; 01511 01512 /* check that all key parts are used */ 01513 for (;;) 01514 { 01515 Field_translator *k; 01516 for (k= trans; k < end_of_trans; k++) 01517 { 01518 Item_field *field; 01519 if ((field= k->item->filed_for_view_update()) && 01520 field->field == key_part->field) 01521 break; 01522 } 01523 if (k == end_of_trans) 01524 break; // Key is not possible 01525 if (++key_part == key_part_end) 01526 DBUG_RETURN(FALSE); // Found usable key 01527 } 01528 } 01529 } 01530 01531 DBUG_PRINT("info", ("checking if all fields of table are used")); 01532 /* check all fields presence */ 01533 { 01534 Field **field_ptr; 01535 Field_translator *fld; 01536 for (field_ptr= table->field; *field_ptr; field_ptr++) 01537 { 01538 for (fld= trans; fld < end_of_trans; fld++) 01539 { 01540 Item_field *field; 01541 if ((field= fld->item->filed_for_view_update()) && 01542 field->field == *field_ptr) 01543 break; 01544 } 01545 if (fld == end_of_trans) // If field didn't exists 01546 { 01547 /* 01548 Keys or all fields of underlying tables are not found => we have 01549 to check variable updatable_views_with_limit to decide should we 01550 issue an error or just a warning 01551 */ 01552 if (thd->variables.updatable_views_with_limit) 01553 { 01554 /* update allowed, but issue warning */ 01555 push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE, 01556 ER_WARN_VIEW_WITHOUT_KEY, ER(ER_WARN_VIEW_WITHOUT_KEY)); 01557 DBUG_RETURN(FALSE); 01558 } 01559 /* prohibit update */ 01560 DBUG_RETURN(TRUE); 01561 } 01562 } 01563 } 01564 DBUG_RETURN(FALSE); 01565 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static bool fill_defined_view_parts | ( | THD * | thd, | |
| TABLE_LIST * | view | |||
| ) | [static] |
Definition at line 179 of file sql_view.cc.
References st_table_list::algorithm, st_table_list::definer, FALSE, st_lex_user::host, memcpy, open_table(), OPEN_VIEW_NO_PARSE, TRUE, st_lex_user::user, st_table_list::view, VIEW_ALGORITHM_UNDEFINED, st_table_list::view_suid, VIEW_SUID_DEFAULT, VIEW_SUID_DEFINER, and VIEW_SUID_INVOKER.
Referenced by mysql_create_view().
00180 { 00181 LEX *lex= thd->lex; 00182 bool not_used; 00183 TABLE_LIST decoy; 00184 00185 memcpy (&decoy, view, sizeof (TABLE_LIST)); 00186 if (!open_table(thd, &decoy, thd->mem_root, ¬_used, OPEN_VIEW_NO_PARSE) && 00187 !decoy.view) 00188 { 00189 /* It's a table */ 00190 return TRUE; 00191 } 00192 00193 if (!lex->definer) 00194 { 00195 view->definer.host= decoy.definer.host; 00196 view->definer.user= decoy.definer.user; 00197 lex->definer= &view->definer; 00198 } 00199 if (lex->create_view_algorithm == VIEW_ALGORITHM_UNDEFINED) 00200 lex->create_view_algorithm= decoy.algorithm; 00201 if (lex->create_view_suid == VIEW_SUID_DEFAULT) 00202 lex->create_view_suid= decoy.view_suid ? 00203 VIEW_SUID_DEFINER : VIEW_SUID_INVOKER; 00204 00205 return FALSE; 00206 }
Here is the call graph for this function:

Here is the caller graph for this function:

| bool insert_view_fields | ( | THD * | thd, | |
| List< Item > * | list, | |||
| TABLE_LIST * | view | |||
| ) |
Definition at line 1582 of file sql_view.cc.
References st_table_list::alias, DBUG_ENTER, DBUG_RETURN, ER_NON_UPDATABLE_TABLE, FALSE, st_table_list::field_translation, st_table_list::field_translation_end, Item::filed_for_view_update(), Field_translator::item, list(), my_error(), MYF, and TRUE.
Referenced by mysql_prepare_insert_check_table().
01583 { 01584 Field_translator *trans_end; 01585 Field_translator *trans; 01586 DBUG_ENTER("insert_view_fields"); 01587 01588 if (!(trans= view->field_translation)) 01589 DBUG_RETURN(FALSE); 01590 trans_end= view->field_translation_end; 01591 01592 for (Field_translator *entry= trans; entry < trans_end; entry++) 01593 { 01594 Item_field *fld; 01595 if ((fld= entry->item->filed_for_view_update())) 01596 list->push_back(fld); 01597 else 01598 { 01599 my_error(ER_NON_UPDATABLE_TABLE, MYF(0), view->alias, "INSERT"); 01600 DBUG_RETURN(TRUE); 01601 } 01602 } 01603 DBUG_RETURN(FALSE); 01604 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static void make_unique_view_field_name | ( | Item * | target, | |
| List< Item > & | item_list, | |||
| Item * | last_element | |||
| ) | [static] |
Definition at line 58 of file sql_view.cc.
References check(), FALSE, my_snprintf(), my_strcasecmp, Item::name, name, NAME_LEN, ok(), Item::orig_name, List_iterator_fast< T >::rewind(), Item::set_name(), system_charset_info, and TRUE.
Referenced by check_duplicate_names().
00061 { 00062 char *name= (target->orig_name ? 00063 target->orig_name : 00064 target->name); 00065 uint name_len, attempt; 00066 char buff[NAME_LEN+1]; 00067 List_iterator_fast<Item> itc(item_list); 00068 00069 for (attempt= 0;; attempt++) 00070 { 00071 Item *check; 00072 bool ok= TRUE; 00073 00074 if (attempt) 00075 name_len= my_snprintf(buff, NAME_LEN, "My_exp_%d_%s", attempt, name); 00076 else 00077 name_len= my_snprintf(buff, NAME_LEN, "My_exp_%s", name); 00078 00079 do 00080 { 00081 check= itc++; 00082 if (check != target && 00083 my_strcasecmp(system_charset_info, buff, check->name) == 0) 00084 { 00085 ok= FALSE; 00086 break; 00087 } 00088 } while (check != last_element); 00089 if (ok) 00090 break; 00091 itc.rewind(); 00092 } 00093 00094 target->orig_name= target->name; 00095 target->set_name(buff, name_len, system_charset_info); 00096 }
Here is the call graph for this function:

Here is the caller graph for this function:

| bool mysql_create_view | ( | THD * | thd, | |
| enum_view_create_mode | mode | |||
| ) |
Definition at line 222 of file sql_view.cc.
References check_access(), check_grant(), check_some_access(), create_default_definer(), CREATE_VIEW_ACL, st_table_list::db, DBUG_ENTER, DROP_ACL, ER, ER_NO_SUCH_USER, ER_SPECIFIC_ACCESS_DENIED_ERROR, ER_TABLEACCESS_DENIED_ERROR, ER_VIEW_SELECT_CLAUSE, ER_VIEW_SELECT_DERIVED, ER_VIEW_SELECT_VARIABLE, err, FALSE, fill_defined_view_parts(), fill_effective_table_privileges(), st_table_list::grant, grant_option, is_acl_user(), my_error(), my_message(), my_strcasecmp, MYF, st_table_list::next_global, st_table_list::next_local, st_grant_info::privilege, push_warning_printf(), st_table_list::schema_table, SELECT_ACL, sp_cache_invalidate(), strcmp(), SUPER_ACL, system_charset_info, st_table_list::table_in_first_from_clause, st_table_list::table_name, test, TRUE, VIEW_ANY_ACL, st_grant_info::want_privilege, and MYSQL_ERROR::WARN_LEVEL_NOTE.
Referenced by mysql_execute_command().
00224 { 00225 LEX *lex= thd->lex; 00226 bool link_to_local; 00227 /* first table in list is target VIEW name => cut off it */ 00228 TABLE_LIST *view= lex->unlink_first_table(&link_to_local); 00229 TABLE_LIST *tables= lex->query_tables; 00230 TABLE_LIST *tbl; 00231 SELECT_LEX *select_lex= &lex->select_lex; 00232 #ifndef NO_EMBEDDED_ACCESS_CHECKS 00233 SELECT_LEX *sl; 00234 #endif 00235 SELECT_LEX_UNIT *unit= &lex->unit; 00236 bool res= FALSE; 00237 DBUG_ENTER("mysql_create_view"); 00238 00239 if (lex->proc_list.first || 00240 lex->result) 00241 { 00242 my_error(ER_VIEW_SELECT_CLAUSE, MYF(0), (lex->result ? 00243 "INTO" : 00244 "PROCEDURE")); 00245 res= TRUE; 00246 goto err; 00247 } 00248 if (lex->derived_tables || 00249 lex->variables_used || lex->param_list.elements) 00250 { 00251 int err= (lex->derived_tables ? 00252 ER_VIEW_SELECT_DERIVED : 00253 ER_VIEW_SELECT_VARIABLE); 00254 my_message(err, ER(err), MYF(0)); 00255 res= TRUE; 00256 goto err; 00257 } 00258 00259 if (mode != VIEW_CREATE_NEW) 00260 { 00261 if (mode == VIEW_ALTER && 00262 fill_defined_view_parts(thd, view)) 00263 { 00264 res= TRUE; 00265 goto err; 00266 } 00267 sp_cache_invalidate(); 00268 } 00269 00270 if (!lex->definer) 00271 { 00272 /* 00273 DEFINER-clause is missing; we have to create default definer in 00274 persistent arena to be PS/SP friendly. 00275 */ 00276 00277 Query_arena original_arena; 00278 Query_arena *ps_arena = thd->activate_stmt_arena_if_needed(&original_arena); 00279 00280 if (!(lex->definer= create_default_definer(thd))) 00281 res= TRUE; 00282 00283 if (ps_arena) 00284 thd->restore_active_arena(ps_arena, &original_arena); 00285 00286 if (res) 00287 goto err; 00288 } 00289 00290 #ifndef NO_EMBEDDED_ACCESS_CHECKS 00291 /* 00292 check definer of view: 00293 - same as current user 00294 - current user has SUPER_ACL 00295 */ 00296 if (strcmp(lex->definer->user.str, 00297 thd->security_ctx->priv_user) != 0 || 00298 my_strcasecmp(system_charset_info, 00299 lex->definer->host.str, 00300 thd->security_ctx->priv_host) != 0) 00301 { 00302 if (!(thd->security_ctx->master_access & SUPER_ACL)) 00303 { 00304 my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), "SUPER"); 00305 res= TRUE; 00306 goto err; 00307 } 00308 else 00309 { 00310 if (!is_acl_user(lex->definer->host.str, 00311 lex->definer->user.str)) 00312 { 00313 push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE, 00314 ER_NO_SUCH_USER, 00315 ER(ER_NO_SUCH_USER), 00316 lex->definer->user.str, 00317 lex->definer->host.str); 00318 } 00319 } 00320 } 00321 /* 00322 Privilege check for view creation: 00323 - user has CREATE VIEW privilege on view table 00324 - user has DROP privilege in case of ALTER VIEW or CREATE OR REPLACE 00325 VIEW 00326 - user has some (SELECT/UPDATE/INSERT/DELETE) privileges on columns of 00327 underlying tables used on top of SELECT list (because it can be 00328 (theoretically) updated, so it is enough to have UPDATE privilege on 00329 them, for example) 00330 - user has SELECT privilege on columns used in expressions of VIEW select 00331 - for columns of underly tables used on top of SELECT list also will be 00332 checked that we have not more privileges on correspondent column of view 00333 table (i.e. user will not get some privileges by view creation) 00334 */ 00335 if ((check_access(thd, CREATE_VIEW_ACL, view->db, &view->grant.privilege, 00336 0, 0, is_schema_db(view->db)) || 00337 grant_option && check_grant(thd, CREATE_VIEW_ACL, view, 0, 1, 0)) || 00338 (mode != VIEW_CREATE_NEW && 00339 (check_access(thd, DROP_ACL, view->db, &view->grant.privilege, 00340 0, 0, is_schema_db(view->db)) || 00341 grant_option && check_grant(thd, DROP_ACL, view, 0, 1, 0)))) 00342 { 00343 res= TRUE; 00344 goto err; 00345 } 00346 for (sl= select_lex; sl; sl= sl->next_select()) 00347 { 00348 for (tbl= sl->get_table_list(); tbl; tbl= tbl->next_local) 00349 { 00350 /* 00351 Ensure that we have some privileges on this table, more strict check 00352 will be done on column level after preparation, 00353 */ 00354 if (check_some_access(thd, VIEW_ANY_ACL, tbl)) 00355 { 00356 my_error(ER_TABLEACCESS_DENIED_ERROR, MYF(0), 00357 "ANY", thd->security_ctx->priv_user, 00358 thd->security_ctx->priv_host, tbl->table_name); 00359 res= TRUE; 00360 goto err; 00361 } 00362 /* 00363 Mark this table as a table which will be checked after the prepare 00364 phase 00365 */ 00366 tbl->table_in_first_from_clause= 1; 00367 00368 /* 00369 We need to check only SELECT_ACL for all normal fields, fields for 00370 which we need "any" (SELECT/UPDATE/INSERT/DELETE) privilege will be 00371 checked later 00372 */ 00373 tbl->grant.want_privilege= SELECT_ACL; 00374 /* 00375 Make sure that all rights are loaded to the TABLE::grant field. 00376 00377 tbl->table_name will be correct name of table because VIEWs are 00378 not opened yet. 00379 */ 00380 fill_effective_table_privileges(thd, &tbl->grant, tbl->db, 00381 tbl->table_name); 00382 } 00383 } 00384 00385 if (&lex->select_lex != lex->all_selects_list) 00386 { 00387 /* check tables of subqueries */ 00388 for (tbl= tables; tbl; tbl= tbl->next_global) 00389 { 00390 if (!tbl->table_in_first_from_clause) 00391 { 00392 if (check_access(thd, SELECT_ACL, tbl->db, 00393 &tbl->grant.privilege, 0, 0, test(tbl->schema_table)) || 00394 grant_option && check_grant(thd, SELECT_ACL, tbl, 0, 1, 0)) 00395 { 00396 res= TRUE; 00397 goto err; 00398 } 00399 } 00400 } 00401 } 00402 /* 00403 Mark fields for special privilege check ("any" privilege) 00404 */ 00405 for (sl= select_lex; sl; sl= sl->next_select()) 00406 { 00407 List_iterator_fast<Item> it(sl->item_list); 00408 Item *item; 00409 while ((item= it++)) 00410 { 00411 Item_field *field; 00412 if ((field= item->filed_for_view_update())) 00413 field->any_privileges= 1; 00414 } 00415 } 00416 #endif 00417 00418 if (open_and_lock_tables(thd, tables)) 00419 { 00420 res= TRUE; 00421 goto err; 00422 } 00423 00424 /* 00425 check that tables are not temporary and this VIEW do not used in query 00426 (it is possible with ALTERing VIEW). 00427 open_and_lock_tables can change the value of tables, 00428 e.g. it may happen if before the function call tables was equal to 0. 00429 */ 00430 for (tbl= lex->query_tables; tbl; tbl= tbl->next_global) 00431 { 00432 /* is this table view and the same view which we creates now? */ 00433 if (tbl->view && 00434 strcmp(tbl->view_db.str, view->db) == 0 && 00435 strcmp(tbl->view_name.str, view->table_name) == 0) 00436 { 00437 my_error(ER_NO_SUCH_TABLE, MYF(0), tbl->view_db.str, tbl->view_name.str); 00438 res= TRUE; 00439 goto err; 00440 } 00441 00442 /* 00443 tbl->table can be NULL when tbl is a placeholder for a view 00444 that is indirectly referenced via a stored function from the 00445 view being created. We don't check these indirectly 00446 referenced views in CREATE VIEW so they don't have table 00447 object. 00448 */ 00449 if (tbl->table) 00450 { 00451 /* is this table temporary and is not view? */ 00452 if (tbl->table->s->tmp_table != NO_TMP_TABLE && !tbl->view && 00453 !tbl->schema_table) 00454 { 00455 my_error(ER_VIEW_SELECT_TMPTABLE, MYF(0), tbl->alias); 00456 res= TRUE; 00457 goto err; 00458 } 00459 /* 00460 Copy the privileges of the underlying VIEWs which were filled by 00461 fill_effective_table_privileges 00462 (they were not copied at derived tables processing) 00463 */ 00464 tbl->table->grant.privilege= tbl->grant.privilege; 00465 } 00466 } 00467 00468 /* prepare select to resolve all fields */ 00469 lex->view_prepare_mode= 1; 00470 if (unit->prepare(thd, 0, 0)) 00471 { 00472 /* 00473 some errors from prepare are reported to user, if is not then 00474 it will be checked after err: label 00475 */ 00476 res= TRUE; 00477 goto err; 00478 } 00479 00480 /* view list (list of view fields names) */ 00481 if (lex->view_list.elements) 00482 { 00483 List_iterator_fast<Item> it(select_lex->item_list); 00484 List_iterator_fast<LEX_STRING> nm(lex->view_list); 00485 Item *item; 00486 LEX_STRING *name; 00487 00488 if (lex->view_list.elements != select_lex->item_list.elements) 00489 { 00490 my_message(ER_VIEW_WRONG_LIST, ER(ER_VIEW_WRONG_LIST), MYF(0)); 00491 res= TRUE; 00492 goto err; 00493 } 00494 while ((item= it++, name= nm++)) 00495 { 00496 item->set_name(name->str, name->length, system_charset_info); 00497 item->is_autogenerated_name= FALSE; 00498 } 00499 } 00500 00501 if (check_duplicate_names(select_lex->item_list, 1)) 00502 { 00503 res= TRUE; 00504 goto err; 00505 } 00506 00507 #ifndef NO_EMBEDDED_ACCESS_CHECKS 00508 /* 00509 Compare/check grants on view with grants of underlying tables 00510 */ 00511 for (sl= select_lex; sl; sl= sl->next_select()) 00512 { 00513 DBUG_ASSERT(view->db); /* Must be set in the parser */ 00514 List_iterator_fast<Item> it(sl->item_list); 00515 Item *item; 00516 fill_effective_table_privileges(thd, &view->grant, view->db, 00517 view->table_name); 00518 while ((item= it++)) 00519 { 00520 Item_field *fld; 00521 uint priv= (get_column_grant(thd, &view->grant, view->db, 00522 view->table_name, item->name) & 00523 VIEW_ANY_ACL); 00524 if ((fld= item->filed_for_view_update())) 00525 { 00526 /* 00527 Do we have more privileges on view field then underlying table field? 00528 */ 00529 if (!fld->field->table->s->tmp_table && (~fld->have_privileges & priv)) 00530 { 00531 /* VIEW column has more privileges */ 00532 my_error(ER_COLUMNACCESS_DENIED_ERROR, MYF(0), 00533 "create view", thd->security_ctx->priv_user, 00534 thd->security_ctx->priv_host, item->name, 00535 view->table_name); 00536 res= TRUE; 00537 goto err; 00538 } 00539 } 00540 } 00541 } 00542 #endif 00543 00544 if (wait_if_global_read_lock(thd, 0, 0)) 00545 { 00546 res= TRUE; 00547 goto err; 00548 } 00549 VOID(pthread_mutex_lock(&LOCK_open)); 00550 res= mysql_register_view(thd, view, mode); 00551 VOID(pthread_mutex_unlock(&LOCK_open)); 00552 if (view->revision != 1) 00553 query_cache_invalidate3(thd, view, 0); 00554 start_waiting_global_read_lock(thd); 00555 if (res) 00556 goto err; 00557 00558 send_ok(thd); 00559 lex->link_first_table_back(view, link_to_local); 00560 DBUG_RETURN(0); 00561 00562 err: 00563 thd->proc_info= "end"; 00564 lex->link_first_table_back(view, link_to_local); 00565 unit->cleanup(); 00566 DBUG_RETURN(res || thd->net.report_error); 00567 }
Here is the call graph for this function:

Here is the caller graph for this function:

| bool mysql_drop_view | ( | THD * | thd, | |
| TABLE_LIST * | views, | |||
| enum_drop_mode | drop_mode | |||
| ) |
Definition at line 1303 of file sql_view.cc.
References access, String::append(), build_table_filename(), String::c_ptr(), st_table_list::db, DBUG_ASSERT, DBUG_ENTER, DBUG_RETURN, ER, ER_BAD_TABLE_ERROR, ER_WRONG_OBJECT, error, F_OK, FALSE, FN_REFLEN, FRMTYPE_ERROR, FRMTYPE_TABLE, FRMTYPE_VIEW, get_cached_table_share(), String::length(), LOCK_open, my_delete(), my_error(), my_snprintf(), MY_WME, MYF, mysql_frm_type(), name, st_table_list::next_local, NULL, path, pthread_mutex_lock, pthread_mutex_unlock, push_warning_printf(), reg_ext, release_table_share(), RELEASE_WAIT_FOR_DROP, send_ok(), sp_cache_invalidate(), system_charset_info, st_table_list::table_name, TRUE, VOID, and MYSQL_ERROR::WARN_LEVEL_NOTE.
Referenced by mysql_execute_command().
01304 { 01305 char path[FN_REFLEN]; 01306 TABLE_LIST *view; 01307 frm_type_enum type; 01308 String non_existant_views; 01309 char *wrong_object_db= NULL, *wrong_object_name= NULL; 01310 bool error= FALSE; 01311 enum legacy_db_type not_used; 01312 DBUG_ENTER("mysql_drop_view"); 01313 01314 for (view= views; view; view= view->next_local) 01315 { 01316 TABLE_SHARE *share; 01317 frm_type_enum type= FRMTYPE_ERROR; 01318 build_table_filename(path, sizeof(path), 01319 view->db, view->table_name, reg_ext, 0); 01320 VOID(pthread_mutex_lock(&LOCK_open)); 01321 01322 if (access(path, F_OK) || 01323 FRMTYPE_VIEW != (type= mysql_frm_type(thd, path, ¬_used))) 01324 { 01325 char name[FN_REFLEN]; 01326 my_snprintf(name, sizeof(name), "%s.%s", view->db, view->table_name); 01327 if (thd->lex->drop_if_exists) 01328 { 01329 push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE, 01330

