17 #include "my_global.h"
22 #include "sql_parse.h"
23 #include "sql_cache.h"
26 #include "sql_table.h"
30 #include "parse_file.h"
37 #define MD5_BUFF_LENGTH 33
39 const LEX_STRING view_type= { C_STRING_WITH_LEN(
"VIEW") };
42 enum_view_create_mode
mode);
60 static void make_unique_view_field_name(
Item *target,
64 const char *
name= (target->orig_name.
is_set() ?
65 target->orig_name.
ptr() : target->item_name.
ptr());
68 char buff[NAME_LEN+1];
71 for (attempt= 0;; attempt++)
77 name_len= my_snprintf(buff, NAME_LEN,
"My_exp_%d_%s", attempt, name);
79 name_len= my_snprintf(buff, NAME_LEN,
"My_exp_%s", name);
84 if (check != target && check->item_name.
eq(buff))
89 }
while (check != last_element);
95 target->orig_name= target->item_name;
96 target->item_name.
copy(buff, name_len);
123 bool check_duplicate_names(
List<Item> &item_list,
bool gen_unique_view_name)
128 DBUG_ENTER(
"check_duplicate_names");
134 if (item->real_item()->type() == Item::FIELD_ITEM)
137 while ((check= itc++) && check != item)
139 if (item->item_name.
eq(check->item_name))
141 if (!gen_unique_view_name)
144 make_unique_view_field_name(item, item_list, item);
146 make_unique_view_field_name(check, item_list, item);
155 my_error(ER_DUP_FIELDNAME, MYF(0), item->item_name.
ptr());
167 static void make_valid_column_names(
List<Item> &item_list)
173 DBUG_ENTER(
"make_valid_column_names");
175 for (uint column_no= 1; (item= it++); column_no++)
178 !check_column_name(item->item_name.
ptr()))
180 name_len= my_snprintf(buff, NAME_LEN,
"Name_exp_%u", column_no);
181 item->orig_name= item->item_name;
182 item->item_name.
copy(buff, name_len);
227 view->definer.host= decoy.definer.host;
228 view->definer.user= decoy.definer.user;
229 lex->definer= &view->definer;
231 if (lex->create_view_algorithm == VIEW_ALGORITHM_UNDEFINED)
232 lex->create_view_algorithm= (uint8) decoy.
algorithm;
233 if (lex->create_view_suid == VIEW_SUID_DEFAULT)
234 lex->create_view_suid= decoy.view_suid ?
235 VIEW_SUID_DEFINER : VIEW_SUID_INVOKER;
240 #ifndef NO_EMBEDDED_ACCESS_CHECKS
255 enum_view_create_mode
mode)
260 SELECT_LEX *select_lex= &lex->select_lex;
263 DBUG_ENTER(
"create_view_precheck");
283 check_grant(thd, CREATE_VIEW_ACL, view, FALSE, 1, FALSE)) ||
284 (mode != VIEW_CREATE_NEW &&
289 check_grant(thd, DROP_ACL, view, FALSE, 1, FALSE))))
292 for (sl= select_lex; sl; sl= sl->next_select())
294 for (tbl= sl->get_table_list(); tbl; tbl= tbl->next_local)
302 my_error(ER_TABLEACCESS_DENIED_ERROR, MYF(0),
303 "ANY", thd->security_ctx->priv_user,
304 thd->security_ctx->priv_host, tbl->table_name);
311 tbl->table_in_first_from_clause= 1;
325 fill_effective_table_privileges(thd, &tbl->grant, tbl->db,
330 if (&lex->select_lex != lex->all_selects_list)
333 for (tbl= tables; tbl; tbl= tbl->next_global)
335 if (!tbl->table_in_first_from_clause)
341 check_grant(thd, SELECT_ACL, tbl, FALSE, 1, FALSE))
349 for (sl= select_lex; sl; sl= sl->next_select())
356 if ((field= item->field_for_view_update()))
362 field->any_privileges= 1;
370 DBUG_RETURN(res || thd->is_error());
376 enum_view_create_mode mode)
397 bool mysql_create_view(THD *thd,
TABLE_LIST *views,
398 enum_view_create_mode mode)
403 TABLE_LIST *view= lex->unlink_first_table(&link_to_local);
406 SELECT_LEX *select_lex= &lex->select_lex;
407 #ifndef NO_EMBEDDED_ACCESS_CHECKS
410 SELECT_LEX_UNIT *unit= &lex->unit;
412 DBUG_ENTER(
"mysql_create_view");
415 DBUG_ASSERT(!lex->proc_analyse && !lex->result &&
416 !lex->param_list.elements);
425 if (thd->locked_tables_mode)
427 my_error(ER_LOCK_OR_ACTIVE_TRANSACTION, MYF(0));
432 if ((res= create_view_precheck(thd, tables, view, mode)))
435 lex->link_first_table_back(view, link_to_local);
445 view= lex->unlink_first_table(&link_to_local);
453 view= lex->unlink_first_table(&link_to_local);
458 view= lex->unlink_first_table(&link_to_local);
463 if (check_db_dir_existence(view->db))
465 my_error(ER_BAD_DB_ERROR, MYF(0), view->db);
470 if (mode == VIEW_ALTER && fill_defined_view_parts(thd, view))
476 sp_cache_invalidate();
486 Prepared_stmt_arena_holder ps_arena_holder(thd);
494 #ifndef NO_EMBEDDED_ACCESS_CHECKS
501 (strcmp(lex->definer->user.str, thd->security_ctx->priv_user) != 0 ||
502 my_strcasecmp(system_charset_info,
503 lex->definer->host.str,
504 thd->security_ctx->priv_host) != 0))
506 if (!(thd->security_ctx->master_access & SUPER_ACL))
508 my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0),
"SUPER");
514 if (!is_acl_user(lex->definer->host.str,
515 lex->definer->user.str))
517 push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE,
520 lex->definer->user.str,
521 lex->definer->host.str);
532 for (tbl= lex->query_tables; tbl; tbl= tbl->next_global)
536 strcmp(tbl->view_db.str, view->db) == 0 &&
537 strcmp(tbl->view_name.str, view->table_name) == 0)
539 my_error(ER_NO_SUCH_TABLE, MYF(0), tbl->view_db.str, tbl->view_name.str);
554 if (tbl->table->s->tmp_table != NO_TMP_TABLE && !tbl->view &&
557 my_error(ER_VIEW_SELECT_TMPTABLE, MYF(0), tbl->alias);
571 lex->context_analysis_only|= CONTEXT_ANALYSIS_ONLY_VIEW;
572 if (unit->prepare(thd, 0, 0))
583 if (lex->view_list.elements)
590 if (lex->view_list.elements != select_lex->item_list.elements)
592 my_message(ER_VIEW_WRONG_LIST, ER(ER_VIEW_WRONG_LIST), MYF(0));
596 while ((item= it++, name= nm++))
598 item->item_name.
copy(name->str, (uint) name->length,
599 system_charset_info,
false);
604 make_valid_column_names(select_lex->item_list);
606 if (check_duplicate_names(select_lex->item_list, 1))
616 if (select_lex->item_list.elements > MAX_FIELDS)
618 my_error(ER_TOO_MANY_FIELDS, MYF(0));
623 #ifndef NO_EMBEDDED_ACCESS_CHECKS
628 fill_effective_table_privileges(thd, &view->grant, view->db,
639 Item *report_item= NULL;
644 uint final_priv= VIEW_ANY_ACL;
646 for (sl= select_lex; sl; sl= sl->next_select())
648 DBUG_ASSERT(view->db);
653 Item_field *fld= item->field_for_view_update();
654 uint priv= (get_column_grant(thd, &view->grant, view->db,
655 view->table_name, item->item_name.
ptr()) &
658 if (fld && !fld->field->table->s->tmp_table)
661 final_priv&= fld->have_privileges;
663 if (~fld->have_privileges & priv)
669 if (!final_priv && report_item)
671 my_error(ER_COLUMNACCESS_DENIED_ERROR, MYF(0),
672 "create view", thd->security_ctx->priv_user,
673 thd->security_ctx->priv_host, report_item->item_name.
ptr(),
681 res= mysql_register_view(thd, view, mode);
690 tdc_remove_table(thd, TDC_RT_REMOVE_ALL, view->db, view->table_name,
false);
692 if (mysql_bin_log.is_open())
696 {{ C_STRING_WITH_LEN(
"CREATE ") },
697 { C_STRING_WITH_LEN(
"ALTER ") },
698 { C_STRING_WITH_LEN(
"CREATE OR REPLACE ") }};
700 buff.append(command[thd->lex->create_view_mode].str,
701 command[thd->lex->create_view_mode].length);
702 view_store_options(thd, views, &buff);
703 buff.append(STRING_WITH_LEN(
"VIEW "));
705 if (views->db && views->db[0] &&
706 (thd->db == NULL || strcmp(views->db, thd->db)))
708 append_identifier(thd, &buff, views->db,
712 append_identifier(thd, &buff, views->table_name,
713 views->table_name_length);
714 if (lex->view_list.elements)
720 for (i= 0; (name= names++); i++)
722 buff.append(i ?
", " :
"(");
723 append_identifier(thd, &buff, name->str, name->length);
727 buff.append(STRING_WITH_LEN(
" AS "));
728 buff.append(views->source.str, views->source.length);
730 int errcode= query_error_code(thd, TRUE);
731 thd->add_to_binlog_accessed_dbs(views->db);
732 if (thd->binlog_query(THD::STMT_QUERY_TYPE,
733 buff.ptr(), buff.length(), FALSE, FALSE, FALSE, errcode))
737 if (mode != VIEW_CREATE_NEW)
738 query_cache_invalidate3(thd, view, 0);
743 lex->link_first_table_back(view, link_to_local);
747 THD_STAGE_INFO(thd, stage_end);
748 lex->link_first_table_back(view, link_to_local);
750 DBUG_RETURN(res || thd->is_error());
755 static const int required_view_parameters= 14;
764 {{{ C_STRING_WITH_LEN(
"query")},
766 FILE_OPTIONS_ESTRING},
767 {{ C_STRING_WITH_LEN(
"md5")},
769 FILE_OPTIONS_STRING},
770 {{ C_STRING_WITH_LEN(
"updatable")},
772 FILE_OPTIONS_ULONGLONG},
773 {{ C_STRING_WITH_LEN(
"algorithm")},
775 FILE_OPTIONS_ULONGLONG},
776 {{ C_STRING_WITH_LEN(
"definer_user")},
778 FILE_OPTIONS_STRING},
779 {{ C_STRING_WITH_LEN(
"definer_host")},
781 FILE_OPTIONS_STRING},
782 {{ C_STRING_WITH_LEN(
"suid")},
784 FILE_OPTIONS_ULONGLONG},
785 {{ C_STRING_WITH_LEN(
"with_check_option")},
787 FILE_OPTIONS_ULONGLONG},
788 {{ C_STRING_WITH_LEN(
"timestamp")},
790 FILE_OPTIONS_TIMESTAMP},
791 {{ C_STRING_WITH_LEN(
"create-version")},
793 FILE_OPTIONS_ULONGLONG},
794 {{ C_STRING_WITH_LEN(
"source")},
796 FILE_OPTIONS_ESTRING},
797 {{(
char*) STRING_WITH_LEN(
"client_cs_name")},
799 FILE_OPTIONS_STRING},
800 {{(
char*) STRING_WITH_LEN(
"connection_cl_name")},
801 my_offsetof(
TABLE_LIST, view_connection_cl_name),
802 FILE_OPTIONS_STRING},
803 {{(
char*) STRING_WITH_LEN(
"view_body_utf8")},
805 FILE_OPTIONS_ESTRING},
810 static LEX_STRING view_file_type[]= {{(
char*) STRING_WITH_LEN(
"VIEW") }};
828 static int mysql_register_view(THD *thd,
TABLE_LIST *view,
829 enum_view_create_mode mode)
858 char view_query_buff[4096];
859 String view_query(view_query_buff,
860 sizeof (view_query_buff),
863 char is_query_buff[4096];
864 String is_query(is_query_buff,
865 sizeof (is_query_buff),
866 system_charset_info);
868 char md5[MD5_BUFF_LENGTH];
870 char dir_buff[FN_REFLEN + 1], path_buff[FN_REFLEN + 1];
874 DBUG_ENTER(
"mysql_register_view");
877 view_query.length(0);
880 sql_mode_t sql_mode= thd->variables.sql_mode & MODE_ANSI_QUOTES;
881 thd->variables.sql_mode&= ~MODE_ANSI_QUOTES;
883 lex->unit.print(&view_query, QT_ORDINARY);
884 lex->unit.print(&is_query,
885 enum_query_type(QT_TO_SYSTEM_CHARSET | QT_WITHOUT_INTRODUCERS));
887 thd->variables.sql_mode|= sql_mode;
890 (
"View: %*.s", (
int) view_query.length(), view_query.ptr()));
893 view->source= thd->lex->create_view_select;
895 if (!thd->make_lex_string(&view->select_stmt, view_query.ptr(),
896 view_query.length(),
false))
898 my_error(ER_OUT_OF_RESOURCES, MYF(0));
903 view->file_version= 1;
905 if (!(view->md5.str= (
char*) thd->memdup(md5, 32)))
907 my_error(ER_OUT_OF_RESOURCES, MYF(0));
911 view->md5.length= 32;
912 can_be_merged= lex->can_be_merged();
913 if (lex->create_view_algorithm == VIEW_ALGORITHM_MERGE &&
914 !lex->can_be_merged())
916 push_warning(thd, Sql_condition::WARN_LEVEL_WARN, ER_WARN_VIEW_MERGE,
917 ER(ER_WARN_VIEW_MERGE));
918 lex->create_view_algorithm= VIEW_ALGORITHM_UNDEFINED;
920 view->
algorithm= lex->create_view_algorithm;
921 view->definer.user= lex->definer->user;
922 view->definer.host= lex->definer->host;
923 view->view_suid= lex->create_view_suid;
924 view->with_check= lex->create_view_check;
925 if ((view->updatable_view= (can_be_merged &&
926 view->
algorithm != VIEW_ALGORITHM_TMPTABLE)))
929 for (
TABLE_LIST *tbl= lex->select_lex.table_list.first;
931 tbl= tbl->next_local)
933 if ((tbl->view && !tbl->updatable_view) || tbl->schema_table)
935 view->updatable_view= 0;
938 for (
TABLE_LIST *up= tbl; up; up= up->embedding)
942 view->updatable_view= 0;
950 dir.length= build_table_filename(dir_buff,
sizeof(dir_buff) - 1,
951 view->db,
"",
"", 0);
954 path.length= build_table_filename(path_buff,
sizeof(path_buff) - 1,
955 view->db, view->table_name, reg_ext,
960 my_error(ER_IDENT_CAUSES_TOO_LONG_PATH, MYF(0),
sizeof(path_buff)-1,
967 file.str= path.str + dir.length;
968 file.length= path.length - dir.length;
971 if (!view->timestamp.str)
972 view->timestamp.str= view->timestamp_buffer;
976 char path_buff[FN_REFLEN];
981 fn_format(path_buff, file.str, dir.str,
"", MY_UNPACK_FILENAME);
982 path.length= strlen(path_buff);
984 if (!access(path.str, F_OK))
986 if (mode == VIEW_CREATE_NEW)
988 my_error(ER_TABLE_EXISTS_ERROR, MYF(0), view->alias);
999 if (!parser->ok() || !is_equal(&view_type, parser->type()))
1001 my_error(ER_WRONG_OBJECT, MYF(0), view->db, view->table_name,
"VIEW");
1013 if (mode == VIEW_ALTER)
1015 my_error(ER_NO_SUCH_TABLE, MYF(0), view->db, view->alias);
1024 view->view_creation_ctx= View_creation_ctx::create(thd);
1031 lex_string_set(&view->view_client_cs_name,
1032 view->view_creation_ctx->get_client_cs()->csname);
1034 lex_string_set(&view->view_connection_cl_name,
1035 view->view_creation_ctx->get_connection_cl()->name);
1037 if (!thd->make_lex_string(&view->view_body_utf8, is_query.ptr(),
1038 is_query.length(),
false))
1040 my_error(ER_OUT_OF_RESOURCES, MYF(0));
1055 if (view->updatable_view &&
1056 !lex->select_lex.master_unit()->is_union() &&
1057 !(lex->select_lex.table_list.first)->next_local &&
1058 find_table_in_global_list(lex->query_tables->next_global,
1059 lex->query_tables->db,
1060 lex->query_tables->table_name))
1062 view->updatable_view= 0;
1065 if (view->with_check != VIEW_CHECK_NONE &&
1066 !view->updatable_view)
1068 my_error(ER_VIEW_NONUPD_CHECK, MYF(0), view->db, view->table_name);
1074 (uchar*)view, view_parameters))
1076 error= thd->is_error() ? -1 : 1;
1081 view->select_stmt.str= NULL;
1082 view->select_stmt.length= 0;
1083 view->md5.str= NULL;
1084 view->md5.length= 0;
1101 SELECT_LEX *removed_select,
1102 SELECT_LEX *parent_select)
1108 DBUG_ASSERT(tbl->select_lex == removed_select);
1109 tbl->select_lex= parent_select;
1113 if (tbl->nested_join)
1114 repoint_contexts_of_join_nests(tbl->nested_join->join_list,
1115 removed_select, parent_select);
1132 bool open_view_no_parse)
1134 SELECT_LEX *end, *view_select= NULL;
1136 Query_arena *arena, backup;
1138 bool parse_status=
true;
1139 bool result=
true, view_is_mergeable;
1140 TABLE_LIST *UNINIT_VAR(view_main_select_tables);
1142 DBUG_ENTER(
"mysql_make_view");
1143 DBUG_PRINT(
"info", (
"table: 0x%lx (%s)", (ulong) table, table->table_name));
1145 if (table->required_type == FRMTYPE_TABLE)
1147 my_error(ER_WRONG_OBJECT, MYF(0), share->db.str, share->table_name.str,
1170 if (!table->prelocking_placeholder && table->prepare_security(thd))
1175 (
"VIEW %s.%s is already processed on previous PS/SP execution",
1176 table->view_db.str, table->view_name.str));
1180 if (table->index_hints && table->index_hints->elements)
1182 my_error(ER_KEY_DOES_NOT_EXITS, MYF(0),
1183 table->index_hints->head()->key_name.str, table->table_name);
1188 for (
TABLE_LIST *precedent= table->referencing_view;
1190 precedent= precedent->referencing_view)
1192 if (precedent->view_name.length == table->table_name_length &&
1193 precedent->view_db.length == table->db_length &&
1194 my_strcasecmp(system_charset_info,
1195 precedent->view_name.str, table->table_name) == 0 &&
1196 my_strcasecmp(system_charset_info,
1197 precedent->view_db.str, table->db) == 0)
1199 my_error(ER_VIEW_RECURSIVE, MYF(0),
1200 top_view->view_db.str, top_view->view_name.str);
1210 arena= thd->stmt_arena;
1211 if (arena->is_conventional())
1214 thd->set_n_backup_active_arena(arena, &backup);
1217 if (!table->timestamp.str)
1218 table->timestamp.str= table->timestamp_buffer;
1220 table->view_suid= TRUE;
1221 table->definer.user.str= table->definer.host.str= 0;
1222 table->definer.user.length= table->definer.host.length= 0;
1227 trace_view.add_utf8(
"database", table->db, table->db_length).
1228 add_utf8(
"view", table->alias ? table->alias : table->table_name).
1229 add(
"in_select#", old_lex->select_lex.select_number);
1235 DBUG_ASSERT(share->
view_def != NULL);
1236 if ((result= share->
view_def->
parse((uchar*)table, thd->mem_root,
1237 view_parameters, required_view_parameters,
1238 &file_parser_dummy_hook)))
1244 if (!table->definer.user.str)
1246 DBUG_ASSERT(!table->definer.host.str &&
1247 !table->definer.user.length &&
1248 !table->definer.host.length);
1249 push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
1250 ER_VIEW_FRM_NO_USER, ER(ER_VIEW_FRM_NO_USER),
1251 table->db, table->table_name);
1260 table->view_creation_ctx= View_creation_ctx::create(thd, table);
1262 if (open_view_no_parse)
1265 thd->restore_active_arena(arena, &backup);
1273 table->view_db.str= table->db;
1274 table->view_db.length= table->db_length;
1275 table->view_name.str= table->table_name;
1276 table->view_name.length= table->table_name_length;
1301 table->view= lex= thd->lex= (LEX*)
new(thd->mem_root) st_lex_local;
1309 char old_db_buf[NAME_LEN+1];
1310 LEX_STRING old_db= { old_db_buf,
sizeof(old_db_buf) };
1312 Parser_state parser_state;
1313 if (parser_state.init(thd, table->select_stmt.str,
1314 table->select_stmt.length))
1321 if ((result= mysql_opt_change_db(thd, &table->view_db, &old_db, 1,
1326 view_select= &lex->select_lex;
1327 view_select->select_number= ++thd->select_number;
1329 trace_view.add(
"select#", view_select->select_number);
1331 sql_mode_t saved_mode= thd->variables.sql_mode;
1356 thd->variables.sql_mode&= ~(MODE_PIPES_AS_CONCAT | MODE_ANSI_QUOTES |
1357 MODE_IGNORE_SPACE | MODE_NO_BACKSLASH_ESCAPES);
1361 parse_status=
parse_sql(thd, & parser_state, table->view_creation_ctx);
1365 if ((old_lex->sql_command == SQLCOM_SHOW_FIELDS) ||
1366 (old_lex->sql_command == SQLCOM_SHOW_CREATE))
1367 lex->sql_command= old_lex->sql_command;
1369 thd->variables.sql_mode= saved_mode;
1371 if (dbchanged && mysql_change_db(thd, &old_db, TRUE))
1379 Security_context *security_ctx;
1386 if (!table->prelocking_placeholder)
1389 opt_trace_disable_if_no_view_access(thd, table, view_tables);
1391 if (old_lex->describe && is_explainable_query(old_lex->sql_command))
1421 memset(static_cast<void *>(&view_no_suid), 0,
sizeof(
TABLE_LIST));
1422 view_no_suid.db= table->db;
1423 view_no_suid.table_name= table->table_name;
1425 DBUG_ASSERT(view_tables == NULL || view_tables->security_ctx == NULL);
1428 FALSE, UINT_MAX, TRUE) ||
1430 FALSE, UINT_MAX, TRUE))
1432 my_message(ER_VIEW_NO_EXPLAIN, ER(ER_VIEW_NO_EXPLAIN), MYF(0));
1436 else if ((old_lex->sql_command == SQLCOM_SHOW_CREATE) &&
1437 !table->belong_to_view)
1444 if (!(table->view_tables=
1451 for (tbl= view_tables;
1453 tbl= (view_tables_tail= tbl)->next_global)
1456 tbl->belong_to_view= top_view;
1457 tbl->referencing_view=
table;
1458 tbl->prelocking_placeholder= table->prelocking_placeholder;
1473 table->view_tables->push_back(tbl);
1485 if (table->next_global)
1487 view_tables_tail->next_global= table->next_global;
1488 table->next_global->prev_global= &view_tables_tail->next_global;
1492 old_lex->query_tables_last= &view_tables_tail->next_global;
1494 view_tables->prev_global= &table->next_global;
1495 table->next_global= view_tables;
1502 old_lex->set_stmt_unsafe_flags(lex->get_stmt_unsafe_flags());
1504 view_is_mergeable= (table->
algorithm != VIEW_ALGORITHM_TMPTABLE &&
1505 lex->can_be_merged());
1507 if (view_is_mergeable)
1515 view_main_select_tables= lex->select_lex.table_list.first;
1524 for (tbl= view_main_select_tables; tbl; tbl= tbl->next_local)
1526 tbl->lock_type= table->lock_type;
1527 tbl->mdl_request.
set_type((tbl->lock_type >= TL_WRITE_ALLOW_WRITE) ?
1528 MDL_SHARED_WRITE : MDL_SHARED_READ);
1536 lex->sql_command= old_lex->sql_command;
1537 lex->duplicates= old_lex->duplicates;
1543 lex->set_trg_event_type_for_tables();
1550 if (table->prelocking_placeholder)
1553 old_lex->derived_tables|= (DERIVED_VIEW | lex->derived_tables);
1556 old_lex->safe_to_cache_query= (old_lex->safe_to_cache_query &&
1557 lex->safe_to_cache_query);
1559 if (view_select->options & OPTION_TO_QUERY_CACHE)
1560 old_lex->select_lex.options|= OPTION_TO_QUERY_CACHE;
1562 if (table->view_suid)
1568 if (!(table->view_sctx= (Security_context *)
1569 thd->stmt_arena->calloc(
sizeof(Security_context))))
1571 security_ctx= table->view_sctx;
1580 security_ctx= table->security_ctx;
1586 DBUG_ASSERT(view_tables_tail);
1587 for (tbl= view_tables; tbl != view_tables_tail->next_global;
1588 tbl= tbl->next_global)
1589 tbl->security_ctx= security_ctx;
1593 for(SELECT_LEX *sl= lex->all_selects_list;
1595 sl= sl->next_select_in_list())
1596 sl->context.security_ctx= security_ctx;
1602 for (SELECT_LEX *sl= lex->all_selects_list;
1604 sl= sl->next_select_in_list())
1606 sl->context.error_processor= &view_error_processor;
1607 sl->context.error_processor_data= (
void *)table;
1616 if (view_is_mergeable &&
1617 (table->select_lex->master_unit() != &old_lex->unit ||
1618 old_lex->can_use_merged()) &&
1619 !old_lex->can_not_use_merged())
1622 DBUG_ASSERT(view_main_select_tables != 0);
1627 DBUG_PRINT(
"info", (
"algorithm: MERGE"));
1628 trace_view.add(
"merged",
true);
1629 table->updatable= (table->updatable_view != 0);
1630 table->effective_with_check=
1631 old_lex->get_effective_with_check(table);
1632 table->merge_underlying_list= view_main_select_tables;
1635 for (tbl= view_main_select_tables; tbl; tbl= tbl->next_local)
1639 lex->select_lex.context.resolve_in_table_list_only(view_main_select_tables);
1640 lex->select_lex.context.outer_context= 0;
1646 lex->select_lex.context.select_lex= table->select_lex;
1647 repoint_contexts_of_join_nests(view_select->top_join_list,
1651 lex->select_lex.select_n_having_items+=
1652 table->select_lex->select_n_having_items;
1660 for (tbl= lex->select_lex.get_table_list(); tbl; tbl= tbl->next_local)
1661 tbl->select_lex= table->select_lex;
1664 if (view_main_select_tables->next_local)
1666 table->multitable_view= TRUE;
1667 if (table->belong_to_view)
1668 table->belong_to_view->multitable_view= TRUE;
1672 if (!(nested_join= table->nested_join=
1675 nested_join->join_list= view_select->top_join_list;
1681 tbl->join_list= &nested_join->join_list;
1682 tbl->embedding=
table;
1687 table->where= view_select->where;
1698 SELECT_LEX_NODE *end_unit= table->select_lex->slave;
1699 SELECT_LEX_UNIT *next_unit;
1700 for (SELECT_LEX_UNIT *unit= lex->select_lex.first_inner_unit();
1704 if (unit == end_unit)
1706 SELECT_LEX_NODE *save_slave= unit->slave;
1707 next_unit= unit->next_unit();
1708 unit->include_down(table->select_lex);
1709 unit->slave= save_slave;
1716 if (!table->select_lex->master_unit()->is_union())
1717 table->select_lex->order_list.push_back(&lex->select_lex.order_list);
1728 DBUG_PRINT(
"info", (
"algorithm: TEMPORARY TABLE"));
1729 trace_view.add(
"materialized",
true);
1730 view_select->linkage= DERIVED_TABLE_TYPE;
1731 table->updatable= 0;
1732 table->effective_with_check= VIEW_CHECK_NONE;
1733 old_lex->subqueries= TRUE;
1736 lex->unit.include_down(table->select_lex);
1737 lex->unit.slave= view_select;
1747 end->link_next= old_lex->all_selects_list;
1748 old_lex->all_selects_list->link_prev= &end->link_next;
1749 old_lex->all_selects_list= lex->all_selects_list;
1750 lex->all_selects_list->link_prev=
1751 (st_select_lex_node**)&old_lex->all_selects_list;
1752 table->derived_key_list.empty();
1755 DBUG_ASSERT(lex == thd->lex);
1757 result= !table->prelocking_placeholder && table->prepare_security(thd);
1762 thd->restore_active_arena(arena, &backup);
1764 DBUG_RETURN(result);
1767 DBUG_ASSERT(thd->lex == table->view);
1790 bool mysql_drop_view(THD *thd,
TABLE_LIST *views, enum_drop_mode drop_mode)
1792 char path[FN_REFLEN + 1];
1794 String non_existant_views;
1795 char *wrong_object_db= NULL, *wrong_object_name= NULL;
1797 enum legacy_db_type not_used;
1798 bool some_views_deleted= FALSE;
1799 bool something_wrong= FALSE;
1800 DBUG_ENTER(
"mysql_drop_view");
1808 if (thd->locked_tables_mode)
1810 my_error(ER_LOCK_OR_ACTIVE_TRANSACTION, MYF(0));
1817 for (view= views; view; view= view->next_local)
1819 frm_type_enum
type= FRMTYPE_ERROR;
1820 build_table_filename(path,
sizeof(path) - 1,
1821 view->db, view->table_name, reg_ext, 0);
1823 if (access(path, F_OK) ||
1824 FRMTYPE_VIEW != (type= dd_frm_type(thd, path, ¬_used)))
1826 if (thd->lex->drop_if_exists)
1829 tbl_name.append(
String(view->db,system_charset_info));
1830 tbl_name.append(
'.');
1831 tbl_name.append(
String(view->table_name,system_charset_info));
1832 push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE,
1833 ER_BAD_TABLE_ERROR, ER(ER_BAD_TABLE_ERROR),
1837 if (type == FRMTYPE_TABLE)
1839 if (!wrong_object_name)
1841 wrong_object_db= view->db;
1842 wrong_object_name= view->table_name;
1847 if (non_existant_views.length())
1848 non_existant_views.append(
',');
1850 non_existant_views.append(
String(view->db,system_charset_info));
1851 non_existant_views.append(
'.');
1852 non_existant_views.append(
String(view->table_name,system_charset_info));
1856 thd->add_to_binlog_accessed_dbs(view->db);
1860 some_views_deleted= TRUE;
1869 query_cache_invalidate3(thd, view, 0);
1870 sp_cache_invalidate();
1873 if (wrong_object_name)
1875 my_error(ER_WRONG_OBJECT, MYF(0), wrong_object_db, wrong_object_name,
1878 if (non_existant_views.length())
1880 my_error(ER_BAD_TABLE_ERROR, MYF(0), non_existant_views.c_ptr());
1883 something_wrong= error || wrong_object_name || non_existant_views.length();
1884 if (some_views_deleted || !something_wrong)
1889 if (write_bin_log(thd, !something_wrong, thd->query(), thd->query_length()))
1893 if (something_wrong)
1923 bool check_key_in_view(THD *thd,
TABLE_LIST *view)
1927 KEY *key_info, *key_info_end;
1928 DBUG_ENTER(
"check_key_in_view");
1934 if ((!view->view && !view->belong_to_view) ||
1935 thd->lex->sql_command == SQLCOM_INSERT ||
1936 thd->lex->select_lex.select_limit == 0)
1939 view= view->top_table();
1940 trans= view->field_translation;
1941 key_info_end= (key_info= table->key_info)+ table->s->keys;
1943 end_of_trans= view->field_translation_end;
1944 DBUG_ASSERT(table != 0 && view->field_translation != 0);
1952 enum_mark_columns save_mark_used_columns= thd->mark_used_columns;
1953 thd->mark_used_columns= MARK_COLUMNS_NONE;
1954 DBUG_PRINT(
"info", (
"thd->mark_used_columns: %d", thd->mark_used_columns));
1957 if (!fld->item->fixed && fld->item->
fix_fields(thd, &fld->item))
1959 thd->mark_used_columns= save_mark_used_columns;
1963 thd->mark_used_columns= save_mark_used_columns;
1964 DBUG_PRINT(
"info", (
"thd->mark_used_columns: %d", thd->mark_used_columns));
1967 for (;key_info != key_info_end ; key_info++)
1969 if ((key_info->
flags & (HA_NOSAME | HA_NULL_PART_KEY)) == HA_NOSAME)
1978 for (k= trans; k < end_of_trans; k++)
1981 if ((field= k->item->field_for_view_update()) &&
1982 field->field == key_part->field)
1985 if (k == end_of_trans)
1987 if (++key_part == key_part_end)
1993 DBUG_PRINT(
"info", (
"checking if all fields of table are used"));
1998 for (field_ptr= table->field; *field_ptr; field_ptr++)
2000 for (fld= trans; fld < end_of_trans; fld++)
2003 if ((field= fld->item->field_for_view_update()) &&
2004 field->field == *field_ptr)
2007 if (fld == end_of_trans)
2014 if (thd->variables.updatable_views_with_limit)
2017 push_warning(thd, Sql_condition::WARN_LEVEL_NOTE,
2018 ER_WARN_VIEW_WITHOUT_KEY, ER(ER_WARN_VIEW_WITHOUT_KEY));
2048 DBUG_ENTER(
"insert_view_fields");
2050 if (!(trans= view->field_translation))
2052 trans_end= view->field_translation_end;
2057 if ((fld=
entry->item->field_for_view_update()))
2058 list->push_back(fld);
2061 my_error(ER_NON_INSERTABLE_TABLE, MYF(0), view->alias,
"INSERT");
2082 int view_checksum(THD *thd,
TABLE_LIST *view)
2084 char md5[MD5_BUFF_LENGTH];
2085 if (!view->view || view->md5.length != 32)
2086 return HA_ADMIN_NOT_IMPLEMENTED;
2087 view->calc_md5(md5);
2088 return (strncmp(md5, view->md5.str, 32) ?
2089 HA_ADMIN_WRONG_CHECKSUM :
2110 mysql_rename_view(THD *thd,
2112 const char *new_name,
2117 char path_buff[FN_REFLEN + 1];
2120 DBUG_ENTER(
"mysql_rename_view");
2122 pathstr.str= (
char *) path_buff;
2123 pathstr.length= build_table_filename(path_buff,
sizeof(path_buff) - 1,
2124 view->db, view->table_name,
2128 is_equal(&view_type, parser->type()))
2131 char dir_buff[FN_REFLEN + 1];
2140 memset(&view_def, 0,
sizeof(view_def));
2141 view_def.timestamp.str= view_def.timestamp_buffer;
2142 view_def.view_suid= TRUE;
2145 if (parser->
parse((uchar*)&view_def, thd->mem_root, view_parameters,
2146 array_elements(view_parameters)-1,
2147 &file_parser_dummy_hook))
2151 dir.length= build_table_filename(dir_buff,
sizeof(dir_buff) - 1,
2154 pathstr.str= path_buff;
2155 pathstr.length= build_table_filename(path_buff,
sizeof(path_buff) - 1,
2156 new_db, new_name, reg_ext, 0,
2161 my_error(ER_IDENT_CAUSES_TOO_LONG_PATH, MYF(0),
sizeof(path_buff)-1,
2165 file.str= pathstr.str + dir.length;
2166 file.length= pathstr.length - dir.length;
2173 (uchar*)&view_def, view_parameters))
2183 query_cache_invalidate3(thd, view, 0);
2184 sp_cache_invalidate();