MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
sql_view.cc
1 /* Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved.
2 
3  This program is free software; you can redistribute it and/or modify
4  it under the terms of the GNU General Public License as published by
5  the Free Software Foundation; version 2 of the License.
6 
7  This program is distributed in the hope that it will be useful,
8  but WITHOUT ANY WARRANTY; without even the implied warranty of
9  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  GNU General Public License for more details.
11 
12  You should have received a copy of the GNU General Public License
13  along with this program; if not, write to the Free Software Foundation,
14  51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */
15 
16 #define MYSQL_LEX 1
17 #include "my_global.h" /* NO_EMBEDDED_ACCESS_CHECKS */
18 #include "sql_priv.h"
19 #include "unireg.h"
20 #include "sql_view.h"
21 #include "sql_base.h" // find_table_in_global_list, lock_table_names
22 #include "sql_parse.h" // sql_parse
23 #include "sql_cache.h" // query_cache_*
24 #include "lock.h" // MYSQL_OPEN_SKIP_TEMPORARY
25 #include "sql_show.h" // append_identifier
26 #include "sql_table.h" // build_table_filename
27 #include "sql_db.h" // mysql_opt_change_db, mysql_change_db
28 #include "sql_acl.h" // *_ACL, check_grant
29 #include "sql_select.h"
30 #include "parse_file.h"
31 #include "sp.h"
32 #include "sp_head.h"
33 #include "sp_cache.h"
34 #include "datadict.h" // dd_frm_type()
35 #include "opt_trace.h" // opt_trace_disable_etc
36 
37 #define MD5_BUFF_LENGTH 33
38 
39 const LEX_STRING view_type= { C_STRING_WITH_LEN("VIEW") };
40 
41 static int mysql_register_view(THD *thd, TABLE_LIST *view,
42  enum_view_create_mode mode);
43 
44 /*
45  Make a unique name for an anonymous view column
46  SYNOPSIS
47  target reference to the item for which a new name has to be made
48  item_list list of items within which we should check uniqueness of
49  the created name
50  last_element the last element of the list above
51 
52  NOTE
53  Unique names are generated by adding 'My_exp_' to the old name of the
54  column. In case the name that was created this way already exists, we
55  add a numeric postfix to its end (i.e. "1") and increase the number
56  until the name becomes unique. If the generated name is longer than
57  NAME_LEN, it is truncated.
58 */
59 
60 static void make_unique_view_field_name(Item *target,
61  List<Item> &item_list,
62  Item *last_element)
63 {
64  const char *name= (target->orig_name.is_set() ?
65  target->orig_name.ptr() : target->item_name.ptr());
66  size_t name_len;
67  uint attempt;
68  char buff[NAME_LEN+1];
69  List_iterator_fast<Item> itc(item_list);
70 
71  for (attempt= 0;; attempt++)
72  {
73  Item *check;
74  bool ok= TRUE;
75 
76  if (attempt)
77  name_len= my_snprintf(buff, NAME_LEN, "My_exp_%d_%s", attempt, name);
78  else
79  name_len= my_snprintf(buff, NAME_LEN, "My_exp_%s", name);
80 
81  do
82  {
83  check= itc++;
84  if (check != target && check->item_name.eq(buff))
85  {
86  ok= FALSE;
87  break;
88  }
89  } while (check != last_element);
90  if (ok)
91  break;
92  itc.rewind();
93  }
94 
95  target->orig_name= target->item_name;
96  target->item_name.copy(buff, name_len);
97 }
98 
99 
100 /*
101  Check if items with same names are present in list and possibly
102  generate unique names for them.
103 
104  SYNOPSIS
105  item_list list of Items which should be checked for duplicates
106  gen_unique_view_name flag: generate unique name or return with error when
107  duplicate names are found.
108 
109  DESCRIPTION
110  This function is used on view creation and preparation of derived tables.
111  It checks item_list for items with duplicate names. If it founds two
112  items with same name and conversion to unique names isn't allowed, or
113  names for both items are set by user - function fails.
114  Otherwise it generates unique name for one item with autogenerated name
115  using make_unique_view_field_name()
116 
117  RETURN VALUE
118  FALSE no duplicate names found, or they are converted to unique ones
119  TRUE duplicate names are found and they can't be converted or conversion
120  isn't allowed
121 */
122 
123 bool check_duplicate_names(List<Item> &item_list, bool gen_unique_view_name)
124 {
125  Item *item;
126  List_iterator_fast<Item> it(item_list);
127  List_iterator_fast<Item> itc(item_list);
128  DBUG_ENTER("check_duplicate_names");
129 
130  while ((item= it++))
131  {
132  Item *check;
133  /* treat underlying fields like set by user names */
134  if (item->real_item()->type() == Item::FIELD_ITEM)
135  item->item_name.set_autogenerated(false);
136  itc.rewind();
137  while ((check= itc++) && check != item)
138  {
139  if (item->item_name.eq(check->item_name))
140  {
141  if (!gen_unique_view_name)
142  goto err;
143  if (item->item_name.is_autogenerated())
144  make_unique_view_field_name(item, item_list, item);
145  else if (check->item_name.is_autogenerated())
146  make_unique_view_field_name(check, item_list, item);
147  else
148  goto err;
149  }
150  }
151  }
152  DBUG_RETURN(FALSE);
153 
154 err:
155  my_error(ER_DUP_FIELDNAME, MYF(0), item->item_name.ptr());
156  DBUG_RETURN(TRUE);
157 }
158 
159 
167 static void make_valid_column_names(List<Item> &item_list)
168 {
169  Item *item;
170  uint name_len;
171  List_iterator_fast<Item> it(item_list);
172  char buff[NAME_LEN];
173  DBUG_ENTER("make_valid_column_names");
174 
175  for (uint column_no= 1; (item= it++); column_no++)
176  {
177  if (!item->item_name.is_autogenerated() ||
178  !check_column_name(item->item_name.ptr()))
179  continue;
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);
183  }
184 
185  DBUG_VOID_RETURN;
186 }
187 
188 
189 /*
190  Fill defined view parts
191 
192  SYNOPSIS
193  fill_defined_view_parts()
194  thd current thread.
195  view view to operate on
196 
197  DESCRIPTION
198  This function will initialize the parts of the view
199  definition that are not specified in ALTER VIEW
200  to their values from CREATE VIEW.
201  The view must be opened to get its definition.
202  We use a copy of the view when opening because we want
203  to preserve the original view instance.
204 
205  RETURN VALUE
206  TRUE can't open table
207  FALSE success
208 */
209 static bool
210 fill_defined_view_parts (THD *thd, TABLE_LIST *view)
211 {
212  const char *key;
213  uint key_length;
214  LEX *lex= thd->lex;
215  TABLE_LIST decoy;
216 
217  memcpy (&decoy, view, sizeof (TABLE_LIST));
218 
219  key_length= get_table_def_key(view, &key);
220 
221  if (tdc_open_view(thd, &decoy, decoy.alias, key, key_length,
222  OPEN_VIEW_NO_PARSE))
223  return TRUE;
224 
225  if (!lex->definer)
226  {
227  view->definer.host= decoy.definer.host;
228  view->definer.user= decoy.definer.user;
229  lex->definer= &view->definer;
230  }
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;
236 
237  return FALSE;
238 }
239 
240 #ifndef NO_EMBEDDED_ACCESS_CHECKS
241 
254 bool create_view_precheck(THD *thd, TABLE_LIST *tables, TABLE_LIST *view,
255  enum_view_create_mode mode)
256 {
257  LEX *lex= thd->lex;
258  /* first table in list is target VIEW name => cut off it */
259  TABLE_LIST *tbl;
260  SELECT_LEX *select_lex= &lex->select_lex;
261  SELECT_LEX *sl;
262  bool res= TRUE;
263  DBUG_ENTER("create_view_precheck");
264 
265  /*
266  Privilege check for view creation:
267  - user has CREATE VIEW privilege on view table
268  - user has DROP privilege in case of ALTER VIEW or CREATE OR REPLACE
269  VIEW
270  - user has some (SELECT/UPDATE/INSERT/DELETE) privileges on columns of
271  underlying tables used on top of SELECT list (because it can be
272  (theoretically) updated, so it is enough to have UPDATE privilege on
273  them, for example)
274  - user has SELECT privilege on columns used in expressions of VIEW select
275  - for columns of underly tables used on top of SELECT list also will be
276  checked that we have not more privileges on correspondent column of view
277  table (i.e. user will not get some privileges by view creation)
278  */
279  if ((check_access(thd, CREATE_VIEW_ACL, view->db,
280  &view->grant.privilege,
281  &view->grant.m_internal,
282  0, 0) ||
283  check_grant(thd, CREATE_VIEW_ACL, view, FALSE, 1, FALSE)) ||
284  (mode != VIEW_CREATE_NEW &&
285  (check_access(thd, DROP_ACL, view->db,
286  &view->grant.privilege,
287  &view->grant.m_internal,
288  0, 0) ||
289  check_grant(thd, DROP_ACL, view, FALSE, 1, FALSE))))
290  goto err;
291 
292  for (sl= select_lex; sl; sl= sl->next_select())
293  {
294  for (tbl= sl->get_table_list(); tbl; tbl= tbl->next_local)
295  {
296  /*
297  Ensure that we have some privileges on this table, more strict check
298  will be done on column level after preparation,
299  */
300  if (check_some_access(thd, VIEW_ANY_ACL, tbl))
301  {
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);
305  goto err;
306  }
307  /*
308  Mark this table as a table which will be checked after the prepare
309  phase
310  */
311  tbl->table_in_first_from_clause= 1;
312 
313  /*
314  We need to check only SELECT_ACL for all normal fields, fields for
315  which we need "any" (SELECT/UPDATE/INSERT/DELETE) privilege will be
316  checked later
317  */
318  tbl->grant.want_privilege= SELECT_ACL;
319  /*
320  Make sure that all rights are loaded to the TABLE::grant field.
321 
322  tbl->table_name will be correct name of table because VIEWs are
323  not opened yet.
324  */
325  fill_effective_table_privileges(thd, &tbl->grant, tbl->db,
326  tbl->table_name);
327  }
328  }
329 
330  if (&lex->select_lex != lex->all_selects_list)
331  {
332  /* check tables of subqueries */
333  for (tbl= tables; tbl; tbl= tbl->next_global)
334  {
335  if (!tbl->table_in_first_from_clause)
336  {
337  if (check_access(thd, SELECT_ACL, tbl->db,
338  &tbl->grant.privilege,
339  &tbl->grant.m_internal,
340  0, 0) ||
341  check_grant(thd, SELECT_ACL, tbl, FALSE, 1, FALSE))
342  goto err;
343  }
344  }
345  }
346  /*
347  Mark fields for special privilege check ("any" privilege)
348  */
349  for (sl= select_lex; sl; sl= sl->next_select())
350  {
351  List_iterator_fast<Item> it(sl->item_list);
352  Item *item;
353  while ((item= it++))
354  {
355  Item_field *field;
356  if ((field= item->field_for_view_update()))
357  {
358  /*
359  any_privileges may be reset later by the Item_field::set_field
360  method in case of a system temporary table.
361  */
362  field->any_privileges= 1;
363  }
364  }
365  }
366 
367  res= FALSE;
368 
369 err:
370  DBUG_RETURN(res || thd->is_error());
371 }
372 
373 #else
374 
375 bool create_view_precheck(THD *thd, TABLE_LIST *tables, TABLE_LIST *view,
376  enum_view_create_mode mode)
377 {
378  return FALSE;
379 }
380 
381 #endif
382 
383 
397 bool mysql_create_view(THD *thd, TABLE_LIST *views,
398  enum_view_create_mode mode)
399 {
400  LEX *lex= thd->lex;
401  bool link_to_local;
402  /* first table in list is target VIEW name => cut off it */
403  TABLE_LIST *view= lex->unlink_first_table(&link_to_local);
404  TABLE_LIST *tables= lex->query_tables;
405  TABLE_LIST *tbl;
406  SELECT_LEX *select_lex= &lex->select_lex;
407 #ifndef NO_EMBEDDED_ACCESS_CHECKS
408  SELECT_LEX *sl;
409 #endif
410  SELECT_LEX_UNIT *unit= &lex->unit;
411  bool res= FALSE;
412  DBUG_ENTER("mysql_create_view");
413 
414  /* This is ensured in the parser. */
415  DBUG_ASSERT(!lex->proc_analyse && !lex->result &&
416  !lex->param_list.elements);
417 
418  /*
419  We can't allow taking exclusive meta-data locks of unlocked view under
420  LOCK TABLES since this might lead to deadlock. Since at the moment we
421  can't really lock view with LOCK TABLES we simply prohibit creation/
422  alteration of views under LOCK TABLES.
423  */
424 
425  if (thd->locked_tables_mode)
426  {
427  my_error(ER_LOCK_OR_ACTIVE_TRANSACTION, MYF(0));
428  res= TRUE;
429  goto err;
430  }
431 
432  if ((res= create_view_precheck(thd, tables, view, mode)))
433  goto err;
434 
435  lex->link_first_table_back(view, link_to_local);
436  view->open_type= OT_BASE_ONLY;
437 
438  /*
439  No pre-opening of temporary tables is possible since must
440  wait until TABLE_LIST::open_type is set. So we have to open
441  them here instead.
442  */
443  if (open_temporary_tables(thd, lex->query_tables))
444  {
445  view= lex->unlink_first_table(&link_to_local);
446  res= true;
447  goto err;
448  }
449 
450  /* Not required to lock any tables. */
451  if (open_normal_and_derived_tables(thd, lex->query_tables, 0))
452  {
453  view= lex->unlink_first_table(&link_to_local);
454  res= TRUE;
455  goto err;
456  }
457 
458  view= lex->unlink_first_table(&link_to_local);
459 
460  /*
461  Checking the existence of the database in which the view is to be created
462  */
463  if (check_db_dir_existence(view->db))
464  {
465  my_error(ER_BAD_DB_ERROR, MYF(0), view->db);
466  res= TRUE;
467  goto err;
468  }
469 
470  if (mode == VIEW_ALTER && fill_defined_view_parts(thd, view))
471  {
472  res= TRUE;
473  goto err;
474  }
475 
476  sp_cache_invalidate();
477 
478  if (!lex->definer)
479  {
480  /*
481  DEFINER-clause is missing; we have to create default definer in
482  persistent arena to be PS/SP friendly.
483  If this is an ALTER VIEW then the current user should be set as
484  the definer.
485  */
486  Prepared_stmt_arena_holder ps_arena_holder(thd);
487 
488  lex->definer= create_default_definer(thd);
489 
490  if (!lex->definer)
491  goto err;
492  }
493 
494 #ifndef NO_EMBEDDED_ACCESS_CHECKS
495  /*
496  check definer of view:
497  - same as current user
498  - current user has SUPER_ACL
499  */
500  if (lex->definer &&
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))
505  {
506  if (!(thd->security_ctx->master_access & SUPER_ACL))
507  {
508  my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), "SUPER");
509  res= TRUE;
510  goto err;
511  }
512  else
513  {
514  if (!is_acl_user(lex->definer->host.str,
515  lex->definer->user.str))
516  {
517  push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE,
518  ER_NO_SUCH_USER,
519  ER(ER_NO_SUCH_USER),
520  lex->definer->user.str,
521  lex->definer->host.str);
522  }
523  }
524  }
525 #endif
526  /*
527  check that tables are not temporary and this VIEW do not used in query
528  (it is possible with ALTERing VIEW).
529  open_and_lock_tables can change the value of tables,
530  e.g. it may happen if before the function call tables was equal to 0.
531  */
532  for (tbl= lex->query_tables; tbl; tbl= tbl->next_global)
533  {
534  /* is this table view and the same view which we creates now? */
535  if (tbl->view &&
536  strcmp(tbl->view_db.str, view->db) == 0 &&
537  strcmp(tbl->view_name.str, view->table_name) == 0)
538  {
539  my_error(ER_NO_SUCH_TABLE, MYF(0), tbl->view_db.str, tbl->view_name.str);
540  res= TRUE;
541  goto err;
542  }
543 
544  /*
545  tbl->table can be NULL when tbl is a placeholder for a view
546  that is indirectly referenced via a stored function from the
547  view being created. We don't check these indirectly
548  referenced views in CREATE VIEW so they don't have table
549  object.
550  */
551  if (tbl->table)
552  {
553  /* is this table temporary and is not view? */
554  if (tbl->table->s->tmp_table != NO_TMP_TABLE && !tbl->view &&
555  !tbl->schema_table)
556  {
557  my_error(ER_VIEW_SELECT_TMPTABLE, MYF(0), tbl->alias);
558  res= TRUE;
559  goto err;
560  }
561  /*
562  Copy the privileges of the underlying VIEWs which were filled by
563  fill_effective_table_privileges
564  (they were not copied at derived tables processing)
565  */
566  tbl->table->grant.privilege= tbl->grant.privilege;
567  }
568  }
569 
570  /* prepare select to resolve all fields */
571  lex->context_analysis_only|= CONTEXT_ANALYSIS_ONLY_VIEW;
572  if (unit->prepare(thd, 0, 0))
573  {
574  /*
575  some errors from prepare are reported to user, if is not then
576  it will be checked after err: label
577  */
578  res= TRUE;
579  goto err;
580  }
581 
582  /* view list (list of view fields names) */
583  if (lex->view_list.elements)
584  {
585  List_iterator_fast<Item> it(select_lex->item_list);
586  List_iterator_fast<LEX_STRING> nm(lex->view_list);
587  Item *item;
588  LEX_STRING *name;
589 
590  if (lex->view_list.elements != select_lex->item_list.elements)
591  {
592  my_message(ER_VIEW_WRONG_LIST, ER(ER_VIEW_WRONG_LIST), MYF(0));
593  res= TRUE;
594  goto err;
595  }
596  while ((item= it++, name= nm++))
597  {
598  item->item_name.copy(name->str, (uint) name->length,
599  system_charset_info, false);
600  }
601  }
602 
603  /* Check if the auto generated column names are conforming. */
604  make_valid_column_names(select_lex->item_list);
605 
606  if (check_duplicate_names(select_lex->item_list, 1))
607  {
608  res= TRUE;
609  goto err;
610  }
611 
612  /*
613  Make sure the view doesn't have so many columns that we hit the
614  64k header limit if the view is materialized as a MyISAM table.
615  */
616  if (select_lex->item_list.elements > MAX_FIELDS)
617  {
618  my_error(ER_TOO_MANY_FIELDS, MYF(0));
619  res= TRUE;
620  goto err;
621  }
622 
623 #ifndef NO_EMBEDDED_ACCESS_CHECKS
624  /*
625  Compare/check grants on view with grants of underlying tables
626  */
627 
628  fill_effective_table_privileges(thd, &view->grant, view->db,
629  view->table_name);
630 
631  /*
632  Make sure that the current user does not have more column-level privileges
633  on the newly created view than he/she does on the underlying
634  tables. E.g. it must not be so that the user has UPDATE privileges on a
635  view column of he/she doesn't have it on the underlying table's
636  corresponding column. In that case, return an error for CREATE VIEW.
637  */
638  {
639  Item *report_item= NULL;
640  /*
641  This will hold the intersection of the priviliges on all columns in the
642  view.
643  */
644  uint final_priv= VIEW_ANY_ACL;
645 
646  for (sl= select_lex; sl; sl= sl->next_select())
647  {
648  DBUG_ASSERT(view->db); /* Must be set in the parser */
649  List_iterator_fast<Item> it(sl->item_list);
650  Item *item;
651  while ((item= it++))
652  {
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()) &
656  VIEW_ANY_ACL);
657 
658  if (fld && !fld->field->table->s->tmp_table)
659  {
660 
661  final_priv&= fld->have_privileges;
662 
663  if (~fld->have_privileges & priv)
664  report_item= item;
665  }
666  }
667  }
668 
669  if (!final_priv && report_item)
670  {
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(),
674  view->table_name);
675  res= TRUE;
676  goto err;
677  }
678  }
679 #endif
680 
681  res= mysql_register_view(thd, view, mode);
682 
683  /*
684  View TABLE_SHARE must be removed from the table definition cache in order to
685  make ALTER VIEW work properly. Otherwise, we would not be able to detect
686  meta-data changes after ALTER VIEW.
687  */
688 
689  if (!res)
690  tdc_remove_table(thd, TDC_RT_REMOVE_ALL, view->db, view->table_name, false);
691 
692  if (mysql_bin_log.is_open())
693  {
694  String buff;
695  const LEX_STRING command[3]=
696  {{ C_STRING_WITH_LEN("CREATE ") },
697  { C_STRING_WITH_LEN("ALTER ") },
698  { C_STRING_WITH_LEN("CREATE OR REPLACE ") }};
699 
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 "));
704  /* Test if user supplied a db (ie: we did not use thd->db) */
705  if (views->db && views->db[0] &&
706  (thd->db == NULL || strcmp(views->db, thd->db)))
707  {
708  append_identifier(thd, &buff, views->db,
709  views->db_length);
710  buff.append('.');
711  }
712  append_identifier(thd, &buff, views->table_name,
713  views->table_name_length);
714  if (lex->view_list.elements)
715  {
716  List_iterator_fast<LEX_STRING> names(lex->view_list);
717  LEX_STRING *name;
718  int i;
719 
720  for (i= 0; (name= names++); i++)
721  {
722  buff.append(i ? ", " : "(");
723  append_identifier(thd, &buff, name->str, name->length);
724  }
725  buff.append(')');
726  }
727  buff.append(STRING_WITH_LEN(" AS "));
728  buff.append(views->source.str, views->source.length);
729 
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))
734  res= TRUE;
735  }
736 
737  if (mode != VIEW_CREATE_NEW)
738  query_cache_invalidate3(thd, view, 0);
739  if (res)
740  goto err;
741 
742  my_ok(thd);
743  lex->link_first_table_back(view, link_to_local);
744  DBUG_RETURN(0);
745 
746 err:
747  THD_STAGE_INFO(thd, stage_end);
748  lex->link_first_table_back(view, link_to_local);
749  unit->cleanup();
750  DBUG_RETURN(res || thd->is_error());
751 }
752 
753 
754 /* number of required parameters for making view */
755 static const int required_view_parameters= 14;
756 
757 /*
758  table of VIEW .frm field descriptors
759 
760  Note that one should NOT change the order for this, as it's used by
761  parse()
762 */
763 static File_option view_parameters[]=
764 {{{ C_STRING_WITH_LEN("query")},
765  my_offsetof(TABLE_LIST, select_stmt),
766  FILE_OPTIONS_ESTRING},
767  {{ C_STRING_WITH_LEN("md5")},
768  my_offsetof(TABLE_LIST, md5),
769  FILE_OPTIONS_STRING},
770  {{ C_STRING_WITH_LEN("updatable")},
771  my_offsetof(TABLE_LIST, updatable_view),
772  FILE_OPTIONS_ULONGLONG},
773  {{ C_STRING_WITH_LEN("algorithm")},
774  my_offsetof(TABLE_LIST, algorithm),
775  FILE_OPTIONS_ULONGLONG},
776  {{ C_STRING_WITH_LEN("definer_user")},
777  my_offsetof(TABLE_LIST, definer.user),
778  FILE_OPTIONS_STRING},
779  {{ C_STRING_WITH_LEN("definer_host")},
780  my_offsetof(TABLE_LIST, definer.host),
781  FILE_OPTIONS_STRING},
782  {{ C_STRING_WITH_LEN("suid")},
783  my_offsetof(TABLE_LIST, view_suid),
784  FILE_OPTIONS_ULONGLONG},
785  {{ C_STRING_WITH_LEN("with_check_option")},
786  my_offsetof(TABLE_LIST, with_check),
787  FILE_OPTIONS_ULONGLONG},
788  {{ C_STRING_WITH_LEN("timestamp")},
789  my_offsetof(TABLE_LIST, timestamp),
790  FILE_OPTIONS_TIMESTAMP},
791  {{ C_STRING_WITH_LEN("create-version")},
792  my_offsetof(TABLE_LIST, file_version),
793  FILE_OPTIONS_ULONGLONG},
794  {{ C_STRING_WITH_LEN("source")},
795  my_offsetof(TABLE_LIST, source),
796  FILE_OPTIONS_ESTRING},
797  {{(char*) STRING_WITH_LEN("client_cs_name")},
798  my_offsetof(TABLE_LIST, view_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")},
804  my_offsetof(TABLE_LIST, view_body_utf8),
805  FILE_OPTIONS_ESTRING},
806  {{NullS, 0}, 0,
807  FILE_OPTIONS_STRING}
808 };
809 
810 static LEX_STRING view_file_type[]= {{(char*) STRING_WITH_LEN("VIEW") }};
811 
812 
813 /*
814  Register VIEW (write .frm & process .frm's history backups)
815 
816  SYNOPSIS
817  mysql_register_view()
818  thd - thread handler
819  view - view description
820  mode - VIEW_CREATE_NEW, VIEW_ALTER, VIEW_CREATE_OR_REPLACE
821 
822  RETURN
823  0 OK
824  -1 Error
825  1 Error and error message given
826 */
827 
828 static int mysql_register_view(THD *thd, TABLE_LIST *view,
829  enum_view_create_mode mode)
830 {
831  LEX *lex= thd->lex;
832 
833  /*
834  View definition query -- a SELECT statement that fully defines view. It
835  is generated from the Item-tree built from the original (specified by
836  the user) query. The idea is that generated query should eliminates all
837  ambiguities and fix view structure at CREATE-time (once for all).
838  Item::print() virtual operation is used to generate view definition
839  query.
840 
841  INFORMATION_SCHEMA query (IS query) -- a SQL statement describing a
842  view that is shown in INFORMATION_SCHEMA. Basically, it is 'view
843  definition query' with text literals converted to UTF8 and without
844  character set introducers.
845 
846  For example:
847  Let's suppose we have:
848  CREATE TABLE t1(a INT, b INT);
849  User specified query:
850  CREATE VIEW v1(x, y) AS SELECT * FROM t1;
851  Generated query:
852  SELECT a AS x, b AS y FROM t1;
853  IS query:
854  SELECT a AS x, b AS y FROM t1;
855 
856  View definition query is stored in the client character set.
857  */
858  char view_query_buff[4096];
859  String view_query(view_query_buff,
860  sizeof (view_query_buff),
861  thd->charset());
862 
863  char is_query_buff[4096];
864  String is_query(is_query_buff,
865  sizeof (is_query_buff),
866  system_charset_info);
867 
868  char md5[MD5_BUFF_LENGTH];
869  bool can_be_merged;
870  char dir_buff[FN_REFLEN + 1], path_buff[FN_REFLEN + 1];
871  LEX_STRING dir, file, path;
872  int error= 0;
873  bool was_truncated;
874  DBUG_ENTER("mysql_register_view");
875 
876  /* Generate view definition and IS queries. */
877  view_query.length(0);
878  is_query.length(0);
879  {
880  sql_mode_t sql_mode= thd->variables.sql_mode & MODE_ANSI_QUOTES;
881  thd->variables.sql_mode&= ~MODE_ANSI_QUOTES;
882 
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));
886 
887  thd->variables.sql_mode|= sql_mode;
888  }
889  DBUG_PRINT("info",
890  ("View: %*.s", (int) view_query.length(), view_query.ptr()));
891 
892  /* fill structure */
893  view->source= thd->lex->create_view_select;
894 
895  if (!thd->make_lex_string(&view->select_stmt, view_query.ptr(),
896  view_query.length(), false))
897  {
898  my_error(ER_OUT_OF_RESOURCES, MYF(0));
899  error= -1;
900  goto err;
901  }
902 
903  view->file_version= 1;
904  view->calc_md5(md5);
905  if (!(view->md5.str= (char*) thd->memdup(md5, 32)))
906  {
907  my_error(ER_OUT_OF_RESOURCES, MYF(0));
908  error= -1;
909  goto err;
910  }
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())
915  {
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;
919  }
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)))
927  {
928  /* TODO: change here when we will support UNIONs */
929  for (TABLE_LIST *tbl= lex->select_lex.table_list.first;
930  tbl;
931  tbl= tbl->next_local)
932  {
933  if ((tbl->view && !tbl->updatable_view) || tbl->schema_table)
934  {
935  view->updatable_view= 0;
936  break;
937  }
938  for (TABLE_LIST *up= tbl; up; up= up->embedding)
939  {
940  if (up->outer_join)
941  {
942  view->updatable_view= 0;
943  goto loop_out;
944  }
945  }
946  }
947  }
948 loop_out:
949  /* print file name */
950  dir.length= build_table_filename(dir_buff, sizeof(dir_buff) - 1,
951  view->db, "", "", 0);
952  dir.str= dir_buff;
953 
954  path.length= build_table_filename(path_buff, sizeof(path_buff) - 1,
955  view->db, view->table_name, reg_ext,
956  0, &was_truncated);
957  // Check if we hit FN_REFLEN bytes in path length
958  if (was_truncated)
959  {
960  my_error(ER_IDENT_CAUSES_TOO_LONG_PATH, MYF(0), sizeof(path_buff)-1,
961  path_buff);
962  error= -1;
963  goto err;
964  }
965  path.str= path_buff;
966 
967  file.str= path.str + dir.length;
968  file.length= path.length - dir.length;
969 
970  /* init timestamp */
971  if (!view->timestamp.str)
972  view->timestamp.str= view->timestamp_buffer;
973 
974  /* check old .frm */
975  {
976  char path_buff[FN_REFLEN];
977  LEX_STRING path;
978  File_parser *parser;
979 
980  path.str= path_buff;
981  fn_format(path_buff, file.str, dir.str, "", MY_UNPACK_FILENAME);
982  path.length= strlen(path_buff);
983 
984  if (!access(path.str, F_OK))
985  {
986  if (mode == VIEW_CREATE_NEW)
987  {
988  my_error(ER_TABLE_EXISTS_ERROR, MYF(0), view->alias);
989  error= -1;
990  goto err;
991  }
992 
993  if (!(parser= sql_parse_prepare(&path, thd->mem_root, 0)))
994  {
995  error= 1;
996  goto err;
997  }
998 
999  if (!parser->ok() || !is_equal(&view_type, parser->type()))
1000  {
1001  my_error(ER_WRONG_OBJECT, MYF(0), view->db, view->table_name, "VIEW");
1002  error= -1;
1003  goto err;
1004  }
1005 
1006  /*
1007  TODO: read dependence list, too, to process cascade/restrict
1008  TODO: special cascade/restrict procedure for alter?
1009  */
1010  }
1011  else
1012  {
1013  if (mode == VIEW_ALTER)
1014  {
1015  my_error(ER_NO_SUCH_TABLE, MYF(0), view->db, view->alias);
1016  error= -1;
1017  goto err;
1018  }
1019  }
1020  }
1021 
1022  /* Initialize view creation context from the environment. */
1023 
1024  view->view_creation_ctx= View_creation_ctx::create(thd);
1025 
1026  /*
1027  Set LEX_STRING attributes in view-structure for parser to create
1028  frm-file.
1029  */
1030 
1031  lex_string_set(&view->view_client_cs_name,
1032  view->view_creation_ctx->get_client_cs()->csname);
1033 
1034  lex_string_set(&view->view_connection_cl_name,
1035  view->view_creation_ctx->get_connection_cl()->name);
1036 
1037  if (!thd->make_lex_string(&view->view_body_utf8, is_query.ptr(),
1038  is_query.length(), false))
1039  {
1040  my_error(ER_OUT_OF_RESOURCES, MYF(0));
1041  error= -1;
1042  goto err;
1043  }
1044 
1045  /*
1046  Check that table of main select do not used in subqueries.
1047 
1048  This test can catch only very simple cases of such non-updateable views,
1049  all other will be detected before updating commands execution.
1050  (it is more optimisation then real check)
1051 
1052  NOTE: this skip cases of using table via VIEWs, joined VIEWs, VIEWs with
1053  UNION
1054  */
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))
1061  {
1062  view->updatable_view= 0;
1063  }
1064 
1065  if (view->with_check != VIEW_CHECK_NONE &&
1066  !view->updatable_view)
1067  {
1068  my_error(ER_VIEW_NONUPD_CHECK, MYF(0), view->db, view->table_name);
1069  error= -1;
1070  goto err;
1071  }
1072 
1073  if (sql_create_definition_file(&dir, &file, view_file_type,
1074  (uchar*)view, view_parameters))
1075  {
1076  error= thd->is_error() ? -1 : 1;
1077  goto err;
1078  }
1079  DBUG_RETURN(0);
1080 err:
1081  view->select_stmt.str= NULL;
1082  view->select_stmt.length= 0;
1083  view->md5.str= NULL;
1084  view->md5.length= 0;
1085  DBUG_RETURN(error);
1086 }
1087 
1088 
1100 static void repoint_contexts_of_join_nests(List<TABLE_LIST> join_list,
1101  SELECT_LEX *removed_select,
1102  SELECT_LEX *parent_select)
1103 {
1104  List_iterator_fast<TABLE_LIST> ti(join_list);
1105  TABLE_LIST *tbl;
1106  while ((tbl= ti++))
1107  {
1108  DBUG_ASSERT(tbl->select_lex == removed_select);
1109  tbl->select_lex= parent_select;
1110  if (tbl->context_of_embedding &&
1111  tbl->context_of_embedding->select_lex == removed_select)
1112  tbl->context_of_embedding->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);
1116  }
1117 }
1118 
1119 
1131 bool mysql_make_view(THD *thd, TABLE_SHARE *share, TABLE_LIST *table,
1132  bool open_view_no_parse)
1133 {
1134  SELECT_LEX *end, *view_select= NULL;
1135  LEX *old_lex, *lex;
1136  Query_arena *arena, backup;
1137  TABLE_LIST *top_view= table->top_table();
1138  bool parse_status= true;
1139  bool result= true, view_is_mergeable;
1140  TABLE_LIST *UNINIT_VAR(view_main_select_tables);
1141 
1142  DBUG_ENTER("mysql_make_view");
1143  DBUG_PRINT("info", ("table: 0x%lx (%s)", (ulong) table, table->table_name));
1144 
1145  if (table->required_type == FRMTYPE_TABLE)
1146  {
1147  my_error(ER_WRONG_OBJECT, MYF(0), share->db.str, share->table_name.str,
1148  "BASE TABLE");
1149  DBUG_RETURN(true);
1150  }
1151 
1152  if (table->view)
1153  {
1154  /*
1155  It's an execution of a PS/SP and the view has already been unfolded
1156  into a list of used tables. Now we only need to update the information
1157  about granted privileges in the view tables with the actual data
1158  stored in MySQL privilege system. We don't need to restore the
1159  required privileges (by calling register_want_access) because they has
1160  not changed since PREPARE or the previous execution: the only case
1161  when this information is changed is execution of UPDATE on a view, but
1162  the original want_access is restored in its end.
1163 
1164  Optimizer trace: because tables have been unfolded already, they are
1165  in lex->query_tables of the statement using the view. So privileges on
1166  them are checked as done for explicitely listed tables, in constructor
1167  of Opt_trace_start. Security context change is checked in
1168  prepare_security() below.
1169  */
1170  if (!table->prelocking_placeholder && table->prepare_security(thd))
1171  {
1172  DBUG_RETURN(true);
1173  }
1174  DBUG_PRINT("info",
1175  ("VIEW %s.%s is already processed on previous PS/SP execution",
1176  table->view_db.str, table->view_name.str));
1177  DBUG_RETURN(false);
1178  }
1179 
1180  if (table->index_hints && table->index_hints->elements)
1181  {
1182  my_error(ER_KEY_DOES_NOT_EXITS, MYF(0),
1183  table->index_hints->head()->key_name.str, table->table_name);
1184  DBUG_RETURN(true);
1185  }
1186 
1187  /* check loop via view definition */
1188  for (TABLE_LIST *precedent= table->referencing_view;
1189  precedent;
1190  precedent= precedent->referencing_view)
1191  {
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)
1198  {
1199  my_error(ER_VIEW_RECURSIVE, MYF(0),
1200  top_view->view_db.str, top_view->view_name.str);
1201  DBUG_RETURN(true);
1202  }
1203  }
1204 
1205  /*
1206  For now we assume that tables will not be changed during PS life (it
1207  will be TRUE as far as we make new table cache).
1208  */
1209  old_lex= thd->lex;
1210  arena= thd->stmt_arena;
1211  if (arena->is_conventional())
1212  arena= 0;
1213  else
1214  thd->set_n_backup_active_arena(arena, &backup);
1215 
1216  /* init timestamp */
1217  if (!table->timestamp.str)
1218  table->timestamp.str= table->timestamp_buffer;
1219  /* prepare default values for old format */
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;
1223 
1224  Opt_trace_object trace_wrapper(&thd->opt_trace);
1225  Opt_trace_object trace_view(&thd->opt_trace, "view");
1226  // When reading I_S.VIEWS, table->alias may be NULL
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);
1230 
1231  /*
1232  TODO: when VIEWs will be stored in cache, table mem_root should
1233  be used here
1234  */
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)))
1239  goto end;
1240 
1241  /*
1242  check old format view .frm
1243  */
1244  if (!table->definer.user.str)
1245  {
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);
1252  get_default_definer(thd, &table->definer);
1253  }
1254 
1255  /*
1256  Initialize view definition context by character set names loaded from
1257  the view definition file. Use UTF8 character set if view definition
1258  file is of old version and does not contain the character set names.
1259  */
1260  table->view_creation_ctx= View_creation_ctx::create(thd, table);
1261 
1262  if (open_view_no_parse)
1263  {
1264  if (arena)
1265  thd->restore_active_arena(arena, &backup);
1266  DBUG_RETURN(false);
1267  }
1268 
1269  /*
1270  Save VIEW parameters, which will be wiped out by derived table
1271  processing
1272  */
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;
1277  /*
1278  We don't invalidate a prepared statement when a view changes,
1279  or when someone creates a temporary table.
1280  Instead, the view is inlined into the body of the statement
1281  upon the first execution. Below, make sure that on
1282  re-execution of a prepared statement we don't prefer
1283  a temporary table to the view, if the view name was shadowed
1284  with a temporary table with the same name.
1285  This assignment ensures that on re-execution open_table() will
1286  not try to call find_temporary_table() for this TABLE_LIST,
1287  but will invoke open_table_from_share(), which will
1288  eventually call this function.
1289  */
1290  table->open_type= OT_BASE_ONLY;
1291 
1292  /*TODO: md5 test here and warning if it is differ */
1293 
1294 
1295  /*
1296  TODO: TABLE mem root should be used here when VIEW will be stored in
1297  TABLE cache
1298 
1299  now Lex placed in statement memory
1300  */
1301  table->view= lex= thd->lex= (LEX*) new(thd->mem_root) st_lex_local;
1302  if (!table->view)
1303  {
1304  result= true;
1305  goto end;
1306  }
1307 
1308  {
1309  char old_db_buf[NAME_LEN+1];
1310  LEX_STRING old_db= { old_db_buf, sizeof(old_db_buf) };
1311  bool dbchanged;
1312  Parser_state parser_state;
1313  if (parser_state.init(thd, table->select_stmt.str,
1314  table->select_stmt.length))
1315  goto err;
1316 
1317  /*
1318  Use view db name as thread default database, in order to ensure
1319  that the view is parsed and prepared correctly.
1320  */
1321  if ((result= mysql_opt_change_db(thd, &table->view_db, &old_db, 1,
1322  &dbchanged)))
1323  goto end;
1324 
1325  lex_start(thd);
1326  view_select= &lex->select_lex;
1327  view_select->select_number= ++thd->select_number;
1328 
1329  trace_view.add("select#", view_select->select_number);
1330 
1331  sql_mode_t saved_mode= thd->variables.sql_mode;
1332  /* switch off modes which can prevent normal parsing of VIEW
1333  - MODE_REAL_AS_FLOAT affect only CREATE TABLE parsing
1334  + MODE_PIPES_AS_CONCAT affect expression parsing
1335  + MODE_ANSI_QUOTES affect expression parsing
1336  + MODE_IGNORE_SPACE affect expression parsing
1337  - MODE_NOT_USED not used :)
1338  * MODE_ONLY_FULL_GROUP_BY affect execution
1339  * MODE_NO_UNSIGNED_SUBTRACTION affect execution
1340  - MODE_NO_DIR_IN_CREATE affect table creation only
1341  - MODE_POSTGRESQL compounded from other modes
1342  - MODE_ORACLE compounded from other modes
1343  - MODE_MSSQL compounded from other modes
1344  - MODE_DB2 compounded from other modes
1345  - MODE_MAXDB affect only CREATE TABLE parsing
1346  - MODE_NO_KEY_OPTIONS affect only SHOW
1347  - MODE_NO_TABLE_OPTIONS affect only SHOW
1348  - MODE_NO_FIELD_OPTIONS affect only SHOW
1349  - MODE_MYSQL323 affect only SHOW
1350  - MODE_MYSQL40 affect only SHOW
1351  - MODE_ANSI compounded from other modes
1352  (+ transaction mode)
1353  ? MODE_NO_AUTO_VALUE_ON_ZERO affect UPDATEs
1354  + MODE_NO_BACKSLASH_ESCAPES affect expression parsing
1355  */
1356  thd->variables.sql_mode&= ~(MODE_PIPES_AS_CONCAT | MODE_ANSI_QUOTES |
1357  MODE_IGNORE_SPACE | MODE_NO_BACKSLASH_ESCAPES);
1358 
1359  /* Parse the query. */
1360 
1361  parse_status= parse_sql(thd, & parser_state, table->view_creation_ctx);
1362 
1363  /* Restore environment. */
1364 
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;
1368 
1369  thd->variables.sql_mode= saved_mode;
1370 
1371  if (dbchanged && mysql_change_db(thd, &old_db, TRUE))
1372  goto err;
1373  }
1374  if (!parse_status)
1375  {
1376  TABLE_LIST *view_tables= lex->query_tables;
1377  TABLE_LIST *view_tables_tail= 0;
1378  TABLE_LIST *tbl;
1379  Security_context *security_ctx;
1380 
1381  /*
1382  Check rights to run commands (EXPLAIN SELECT & SHOW CREATE) which show
1383  underlying tables.
1384  Skip this step if we are opening view for prelocking only.
1385  */
1386  if (!table->prelocking_placeholder)
1387  {
1388  // If executing prepared statement: see "Optimizer trace" note above.
1389  opt_trace_disable_if_no_view_access(thd, table, view_tables);
1390 
1391  if (old_lex->describe && is_explainable_query(old_lex->sql_command))
1392  {
1393  /*
1394  The user we run EXPLAIN as (either the connected user who issued
1395  the EXPLAIN statement, or the definer of a SUID stored routine
1396  which contains the EXPLAIN) should have both SHOW_VIEW_ACL and
1397  SELECT_ACL on the view being opened as well as on all underlying
1398  views since EXPLAIN will disclose their structure. This user also
1399  should have SELECT_ACL on all underlying tables of the view since
1400  this EXPLAIN will disclose information about the number of rows in
1401  it.
1402 
1403  To perform this privilege check we create auxiliary TABLE_LIST
1404  object for the view in order a) to avoid trashing "table->grant"
1405  member for original table list element, which contents can be
1406  important at later stage for column-level privilege checking
1407  b) get TABLE_LIST object with "security_ctx" member set to 0,
1408  i.e. forcing check_table_access() to use active user's security
1409  context.
1410 
1411  There is no need for creating similar copies of table list elements
1412  for underlying tables since they are just have been constructed and
1413  thus have TABLE_LIST::security_ctx == 0 and fresh TABLE_LIST::grant
1414  member.
1415 
1416  Finally at this point making sure we have SHOW_VIEW_ACL on the views
1417  will suffice as we implicitly require SELECT_ACL anyway.
1418  */
1419 
1420  TABLE_LIST view_no_suid;
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;
1424 
1425  DBUG_ASSERT(view_tables == NULL || view_tables->security_ctx == NULL);
1426 
1427  if (check_table_access(thd, SELECT_ACL, view_tables,
1428  FALSE, UINT_MAX, TRUE) ||
1429  check_table_access(thd, SHOW_VIEW_ACL, &view_no_suid,
1430  FALSE, UINT_MAX, TRUE))
1431  {
1432  my_message(ER_VIEW_NO_EXPLAIN, ER(ER_VIEW_NO_EXPLAIN), MYF(0));
1433  goto err;
1434  }
1435  }
1436  else if ((old_lex->sql_command == SQLCOM_SHOW_CREATE) &&
1437  !table->belong_to_view)
1438  {
1439  if (check_table_access(thd, SHOW_VIEW_ACL, table, FALSE, UINT_MAX, FALSE))
1440  goto err;
1441  }
1442  }
1443 
1444  if (!(table->view_tables=
1445  (List<TABLE_LIST>*) new(thd->mem_root) List<TABLE_LIST>))
1446  goto err;
1447  /*
1448  mark to avoid temporary table using and put view reference and find
1449  last view table
1450  */
1451  for (tbl= view_tables;
1452  tbl;
1453  tbl= (view_tables_tail= tbl)->next_global)
1454  {
1455  tbl->open_type= OT_BASE_ONLY;
1456  tbl->belong_to_view= top_view;
1457  tbl->referencing_view= table;
1458  tbl->prelocking_placeholder= table->prelocking_placeholder;
1459  /*
1460  First we fill want_privilege with SELECT_ACL (this is needed for the
1461  tables which belongs to view subqueries and temporary table views,
1462  then for the merged view underlying tables we will set wanted
1463  privileges of top_view
1464  */
1465  tbl->grant.want_privilege= SELECT_ACL;
1466  /*
1467  After unfolding the view we lose the list of tables referenced in it
1468  (we will have only a list of underlying tables in case of MERGE
1469  algorithm, which does not include the tables referenced from
1470  subqueries used in view definition).
1471  Let's build a list of all tables referenced in the view.
1472  */
1473  table->view_tables->push_back(tbl);
1474  }
1475 
1476  /*
1477  Put tables of VIEW after VIEW TABLE_LIST
1478 
1479  NOTE: It is important for UPDATE/INSERT/DELETE checks to have this
1480  tables just after VIEW instead of tail of list, to be able check that
1481  table is unique. Also we store old next table for the same purpose.
1482  */
1483  if (view_tables)
1484  {
1485  if (table->next_global)
1486  {
1487  view_tables_tail->next_global= table->next_global;
1488  table->next_global->prev_global= &view_tables_tail->next_global;
1489  }
1490  else
1491  {
1492  old_lex->query_tables_last= &view_tables_tail->next_global;
1493  }
1494  view_tables->prev_global= &table->next_global;
1495  table->next_global= view_tables;
1496  }
1497 
1498  /*
1499  If the view's body needs row-based binlogging (e.g. the VIEW is created
1500  from SELECT UUID()), the top statement also needs it.
1501  */
1502  old_lex->set_stmt_unsafe_flags(lex->get_stmt_unsafe_flags());
1503 
1504  view_is_mergeable= (table->algorithm != VIEW_ALGORITHM_TMPTABLE &&
1505  lex->can_be_merged());
1506 
1507  if (view_is_mergeable)
1508  {
1509  /*
1510  Currently 'view_main_select_tables' differs from 'view_tables'
1511  only then view has CONVERT_TZ() function in its select list.
1512  This may change in future, for example if we enable merging of
1513  views with subqueries in select list.
1514  */
1515  view_main_select_tables= lex->select_lex.table_list.first;
1516 
1517  /*
1518  Let us set proper lock type for tables of the view's main
1519  select since we may want to perform update or insert on
1520  view. This won't work for view containing union. But this is
1521  ok since we don't allow insert and update on such views
1522  anyway.
1523  */
1524  for (tbl= view_main_select_tables; tbl; tbl= tbl->next_local)
1525  {
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);
1529  }
1530  /*
1531  If the view is mergeable, we might want to
1532  INSERT/UPDATE/DELETE into tables of this view. Preserve the
1533  original sql command and 'duplicates' of the outer lex.
1534  This is used later in set_trg_event_type_for_command.
1535  */
1536  lex->sql_command= old_lex->sql_command;
1537  lex->duplicates= old_lex->duplicates;
1538  }
1539  /*
1540  This method has a dependency on the proper lock type being set,
1541  so in case of views should be called here.
1542  */
1543  lex->set_trg_event_type_for_tables();
1544 
1545  /*
1546  If we are opening this view as part of implicit LOCK TABLES, then
1547  this view serves as simple placeholder and we should not continue
1548  further processing.
1549  */
1550  if (table->prelocking_placeholder)
1551  goto ok2;
1552 
1553  old_lex->derived_tables|= (DERIVED_VIEW | lex->derived_tables);
1554 
1555  /* move SQL_NO_CACHE & Co to whole query */
1556  old_lex->safe_to_cache_query= (old_lex->safe_to_cache_query &&
1557  lex->safe_to_cache_query);
1558  /* move SQL_CACHE to whole query */
1559  if (view_select->options & OPTION_TO_QUERY_CACHE)
1560  old_lex->select_lex.options|= OPTION_TO_QUERY_CACHE;
1561 
1562  if (table->view_suid)
1563  {
1564  /*
1565  For suid views prepare a security context for checking underlying
1566  objects of the view.
1567  */
1568  if (!(table->view_sctx= (Security_context *)
1569  thd->stmt_arena->calloc(sizeof(Security_context))))
1570  goto err;
1571  security_ctx= table->view_sctx;
1572  }
1573  else
1574  {
1575  /*
1576  For non-suid views inherit security context from view's table list.
1577  This allows properly handle situation when non-suid view is used
1578  from within suid view.
1579  */
1580  security_ctx= table->security_ctx;
1581  }
1582 
1583  /* Assign the context to the tables referenced in the view */
1584  if (view_tables)
1585  {
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;
1590  }
1591 
1592  /* assign security context to SELECT name resolution contexts of view */
1593  for(SELECT_LEX *sl= lex->all_selects_list;
1594  sl;
1595  sl= sl->next_select_in_list())
1596  sl->context.security_ctx= security_ctx;
1597 
1598  /*
1599  Setup an error processor to hide error messages issued by stored
1600  routines referenced in the view
1601  */
1602  for (SELECT_LEX *sl= lex->all_selects_list;
1603  sl;
1604  sl= sl->next_select_in_list())
1605  {
1606  sl->context.error_processor= &view_error_processor;
1607  sl->context.error_processor_data= (void *)table;
1608  }
1609 
1610  /*
1611  check MERGE algorithm ability
1612  - algorithm is not explicit TEMPORARY TABLE
1613  - VIEW SELECT allow merging
1614  - VIEW used in subquery or command support MERGE algorithm
1615  */
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())
1620  {
1621  /* lex should contain at least one table */
1622  DBUG_ASSERT(view_main_select_tables != 0);
1623 
1624  List_iterator_fast<TABLE_LIST> ti(view_select->top_join_list);
1625 
1626  table->effective_algorithm= VIEW_ALGORITHM_MERGE;
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;
1633 
1634  /* Fill correct wanted privileges. */
1635  for (tbl= view_main_select_tables; tbl; tbl= tbl->next_local)
1636  tbl->grant.want_privilege= top_view->grant.orig_want_privilege;
1637 
1638  /* prepare view context */
1639  lex->select_lex.context.resolve_in_table_list_only(view_main_select_tables);
1640  lex->select_lex.context.outer_context= 0;
1641 
1642  /*
1643  Correct all name resolution contexts which point to the view's
1644  select_lex.
1645  */
1646  lex->select_lex.context.select_lex= table->select_lex;
1647  repoint_contexts_of_join_nests(view_select->top_join_list,
1648  view_select,
1649  table->select_lex);
1650 
1651  lex->select_lex.select_n_having_items+=
1652  table->select_lex->select_n_having_items;
1653 
1654  /*
1655  Tables of the main select of the view should be marked as belonging
1656  to the same select as original view (again we can use LEX::select_lex
1657  for this purprose because we don't support MERGE algorithm for views
1658  with unions).
1659  */
1660  for (tbl= lex->select_lex.get_table_list(); tbl; tbl= tbl->next_local)
1661  tbl->select_lex= table->select_lex;
1662 
1663  {
1664  if (view_main_select_tables->next_local)
1665  {
1666  table->multitable_view= TRUE;
1667  if (table->belong_to_view)
1668  table->belong_to_view->multitable_view= TRUE;
1669  }
1670  /* make nested join structure for view tables */
1671  NESTED_JOIN *nested_join;
1672  if (!(nested_join= table->nested_join=
1673  (NESTED_JOIN *) thd->calloc(sizeof(NESTED_JOIN))))
1674  goto err;
1675  nested_join->join_list= view_select->top_join_list;
1676 
1677  /* re-nest tables of VIEW */
1678  ti.rewind();
1679  while ((tbl= ti++))
1680  {
1681  tbl->join_list= &nested_join->join_list;
1682  tbl->embedding= table;
1683  }
1684  }
1685 
1686  /* Store WHERE clause for post-processing in setup_underlying */
1687  table->where= view_select->where;
1688  /*
1689  Add subqueries units to SELECT into which we merging current view.
1690  unit(->next)* chain starts with subqueries that are used by this
1691  view and continues with subqueries that are used by other views.
1692  We must not add any subquery twice (otherwise we'll form a loop),
1693  to do this we remember in end_unit the first subquery that has
1694  been already added.
1695 
1696  NOTE: we do not support UNION here, so we take only one select
1697  */
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();
1701  unit;
1702  unit= next_unit)
1703  {
1704  if (unit == end_unit)
1705  break;
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; // fix include_down initialisation
1710  }
1711 
1712  /*
1713  We can safely ignore the VIEW's ORDER BY if we merge into union
1714  branch, as order is not important there.
1715  */
1716  if (!table->select_lex->master_unit()->is_union())
1717  table->select_lex->order_list.push_back(&lex->select_lex.order_list);
1718  /*
1719  This SELECT_LEX will be linked in global SELECT_LEX list
1720  to make it processed by mysql_handle_derived(),
1721  but it will not be included to SELECT_LEX tree, because it
1722  will not be executed
1723  */
1724  goto ok;
1725  }
1726 
1727  table->effective_algorithm= VIEW_ALGORITHM_TMPTABLE;
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;
1734 
1735  /* SELECT tree link */
1736  lex->unit.include_down(table->select_lex);
1737  lex->unit.slave= view_select; // fix include_down initialisation
1738 
1739  table->derived= &lex->unit;
1740  }
1741  else
1742  goto err;
1743 
1744 ok:
1745  /* global SELECT list linking */
1746  end= view_select; // primary SELECT_LEX is always last
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();
1753 
1754 ok2:
1755  DBUG_ASSERT(lex == thd->lex);
1756  thd->lex= old_lex; // Needed for prepare_security
1757  result= !table->prelocking_placeholder && table->prepare_security(thd);
1758 
1759  lex_end(lex);
1760 end:
1761  if (arena)
1762  thd->restore_active_arena(arena, &backup);
1763  thd->lex= old_lex;
1764  DBUG_RETURN(result);
1765 
1766 err:
1767  DBUG_ASSERT(thd->lex == table->view);
1768  lex_end(thd->lex);
1769  delete table->view;
1770  table->view= 0; // now it is not VIEW placeholder
1771  result= 1;
1772  goto end;
1773 }
1774 
1775 
1776 /*
1777  drop view
1778 
1779  SYNOPSIS
1780  mysql_drop_view()
1781  thd - thread handler
1782  views - views to delete
1783  drop_mode - cascade/check
1784 
1785  RETURN VALUE
1786  FALSE OK
1787  TRUE Error
1788 */
1789 
1790 bool mysql_drop_view(THD *thd, TABLE_LIST *views, enum_drop_mode drop_mode)
1791 {
1792  char path[FN_REFLEN + 1];
1793  TABLE_LIST *view;
1794  String non_existant_views;
1795  char *wrong_object_db= NULL, *wrong_object_name= NULL;
1796  bool error= FALSE;
1797  enum legacy_db_type not_used;
1798  bool some_views_deleted= FALSE;
1799  bool something_wrong= FALSE;
1800  DBUG_ENTER("mysql_drop_view");
1801 
1802  /*
1803  We can't allow dropping of unlocked view under LOCK TABLES since this
1804  might lead to deadlock. But since we can't really lock view with LOCK
1805  TABLES we have to simply prohibit dropping of views.
1806  */
1807 
1808  if (thd->locked_tables_mode)
1809  {
1810  my_error(ER_LOCK_OR_ACTIVE_TRANSACTION, MYF(0));
1811  DBUG_RETURN(TRUE);
1812  }
1813 
1814  if (lock_table_names(thd, views, 0, thd->variables.lock_wait_timeout, 0))
1815  DBUG_RETURN(TRUE);
1816 
1817  for (view= views; view; view= view->next_local)
1818  {
1819  frm_type_enum type= FRMTYPE_ERROR;
1820  build_table_filename(path, sizeof(path) - 1,
1821  view->db, view->table_name, reg_ext, 0);
1822 
1823  if (access(path, F_OK) ||
1824  FRMTYPE_VIEW != (type= dd_frm_type(thd, path, &not_used)))
1825  {
1826  if (thd->lex->drop_if_exists)
1827  {
1828  String tbl_name;
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),
1834  tbl_name.c_ptr());
1835  continue;
1836  }
1837  if (type == FRMTYPE_TABLE)
1838  {
1839  if (!wrong_object_name)
1840  {
1841  wrong_object_db= view->db;
1842  wrong_object_name= view->table_name;
1843  }
1844  }
1845  else
1846  {
1847  if (non_existant_views.length())
1848  non_existant_views.append(',');
1849 
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));
1853  }
1854  continue;
1855  }
1856  thd->add_to_binlog_accessed_dbs(view->db);
1857  if (mysql_file_delete(key_file_frm, path, MYF(MY_WME)))
1858  error= TRUE;
1859 
1860  some_views_deleted= TRUE;
1861 
1862  /*
1863  For a view, there is a TABLE_SHARE object, but its
1864  ref_count never goes above 1. Remove it from the table
1865  definition cache, in case the view was cached.
1866  */
1867  tdc_remove_table(thd, TDC_RT_REMOVE_ALL, view->db, view->table_name,
1868  FALSE);
1869  query_cache_invalidate3(thd, view, 0);
1870  sp_cache_invalidate();
1871  }
1872 
1873  if (wrong_object_name)
1874  {
1875  my_error(ER_WRONG_OBJECT, MYF(0), wrong_object_db, wrong_object_name,
1876  "VIEW");
1877  }
1878  if (non_existant_views.length())
1879  {
1880  my_error(ER_BAD_TABLE_ERROR, MYF(0), non_existant_views.c_ptr());
1881  }
1882 
1883  something_wrong= error || wrong_object_name || non_existant_views.length();
1884  if (some_views_deleted || !something_wrong)
1885  {
1886  /* if something goes wrong, bin-log with possible error code,
1887  otherwise bin-log with error code cleared.
1888  */
1889  if (write_bin_log(thd, !something_wrong, thd->query(), thd->query_length()))
1890  something_wrong= 1;
1891  }
1892 
1893  if (something_wrong)
1894  {
1895  DBUG_RETURN(TRUE);
1896  }
1897  my_ok(thd);
1898  DBUG_RETURN(FALSE);
1899 }
1900 
1901 
1902 /*
1903  check of key (primary or unique) presence in updatable view
1904 
1905  SYNOPSIS
1906  check_key_in_view()
1907  thd thread handler
1908  view view for check with opened table
1909 
1910  DESCRIPTION
1911  If it is VIEW and query have LIMIT clause then check that underlying
1912  table of view contain one of following:
1913  1) primary key of underlying table
1914  2) unique key underlying table with fields for which NULL value is
1915  impossible
1916  3) all fields of underlying table
1917 
1918  RETURN
1919  FALSE OK
1920  TRUE view do not contain key or all fields
1921 */
1922 
1923 bool check_key_in_view(THD *thd, TABLE_LIST *view)
1924 {
1925  TABLE *table;
1926  Field_translator *trans, *end_of_trans;
1927  KEY *key_info, *key_info_end;
1928  DBUG_ENTER("check_key_in_view");
1929 
1930  /*
1931  we do not support updatable UNIONs in VIEW, so we can check just limit of
1932  LEX::select_lex
1933  */
1934  if ((!view->view && !view->belong_to_view) ||
1935  thd->lex->sql_command == SQLCOM_INSERT ||
1936  thd->lex->select_lex.select_limit == 0)
1937  DBUG_RETURN(FALSE); /* it is normal table or query without LIMIT */
1938  table= view->table;
1939  view= view->top_table();
1940  trans= view->field_translation;
1941  key_info_end= (key_info= table->key_info)+ table->s->keys;
1942 
1943  end_of_trans= view->field_translation_end;
1944  DBUG_ASSERT(table != 0 && view->field_translation != 0);
1945 
1946  {
1947  /*
1948  We should be sure that all fields are ready to get keys from them, but
1949  this operation should not have influence on Field::query_id, to avoid
1950  marking as used fields which are not used
1951  */
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));
1955  for (Field_translator *fld= trans; fld < end_of_trans; fld++)
1956  {
1957  if (!fld->item->fixed && fld->item->fix_fields(thd, &fld->item))
1958  {
1959  thd->mark_used_columns= save_mark_used_columns;
1960  DBUG_RETURN(TRUE);
1961  }
1962  }
1963  thd->mark_used_columns= save_mark_used_columns;
1964  DBUG_PRINT("info", ("thd->mark_used_columns: %d", thd->mark_used_columns));
1965  }
1966  /* Loop over all keys to see if a unique-not-null key is used */
1967  for (;key_info != key_info_end ; key_info++)
1968  {
1969  if ((key_info->flags & (HA_NOSAME | HA_NULL_PART_KEY)) == HA_NOSAME)
1970  {
1971  KEY_PART_INFO *key_part= key_info->key_part;
1972  KEY_PART_INFO *key_part_end= key_part + key_info->user_defined_key_parts;
1973 
1974  /* check that all key parts are used */
1975  for (;;)
1976  {
1977  Field_translator *k;
1978  for (k= trans; k < end_of_trans; k++)
1979  {
1980  Item_field *field;
1981  if ((field= k->item->field_for_view_update()) &&
1982  field->field == key_part->field)
1983  break;
1984  }
1985  if (k == end_of_trans)
1986  break; // Key is not possible
1987  if (++key_part == key_part_end)
1988  DBUG_RETURN(FALSE); // Found usable key
1989  }
1990  }
1991  }
1992 
1993  DBUG_PRINT("info", ("checking if all fields of table are used"));
1994  /* check all fields presence */
1995  {
1996  Field **field_ptr;
1997  Field_translator *fld;
1998  for (field_ptr= table->field; *field_ptr; field_ptr++)
1999  {
2000  for (fld= trans; fld < end_of_trans; fld++)
2001  {
2002  Item_field *field;
2003  if ((field= fld->item->field_for_view_update()) &&
2004  field->field == *field_ptr)
2005  break;
2006  }
2007  if (fld == end_of_trans) // If field didn't exists
2008  {
2009  /*
2010  Keys or all fields of underlying tables are not found => we have
2011  to check variable updatable_views_with_limit to decide should we
2012  issue an error or just a warning
2013  */
2014  if (thd->variables.updatable_views_with_limit)
2015  {
2016  /* update allowed, but issue warning */
2017  push_warning(thd, Sql_condition::WARN_LEVEL_NOTE,
2018  ER_WARN_VIEW_WITHOUT_KEY, ER(ER_WARN_VIEW_WITHOUT_KEY));
2019  DBUG_RETURN(FALSE);
2020  }
2021  /* prohibit update */
2022  DBUG_RETURN(TRUE);
2023  }
2024  }
2025  }
2026  DBUG_RETURN(FALSE);
2027 }
2028 
2029 
2030 /*
2031  insert fields from VIEW (MERGE algorithm) into given list
2032 
2033  SYNOPSIS
2034  insert_view_fields()
2035  thd thread handler
2036  list list for insertion
2037  view view for processing
2038 
2039  RETURN
2040  FALSE OK
2041  TRUE error (is not sent to cliet)
2042 */
2043 
2044 bool insert_view_fields(THD *thd, List<Item> *list, TABLE_LIST *view)
2045 {
2046  Field_translator *trans_end;
2047  Field_translator *trans;
2048  DBUG_ENTER("insert_view_fields");
2049 
2050  if (!(trans= view->field_translation))
2051  DBUG_RETURN(FALSE);
2052  trans_end= view->field_translation_end;
2053 
2054  for (Field_translator *entry= trans; entry < trans_end; entry++)
2055  {
2056  Item_field *fld;
2057  if ((fld= entry->item->field_for_view_update()))
2058  list->push_back(fld);
2059  else
2060  {
2061  my_error(ER_NON_INSERTABLE_TABLE, MYF(0), view->alias, "INSERT");
2062  DBUG_RETURN(TRUE);
2063  }
2064  }
2065  DBUG_RETURN(FALSE);
2066 }
2067 
2068 /*
2069  checking view md5 check suum
2070 
2071  SINOPSYS
2072  view_checksum()
2073  thd threar handler
2074  view view for check
2075 
2076  RETUIRN
2077  HA_ADMIN_OK OK
2078  HA_ADMIN_NOT_IMPLEMENTED it is not VIEW
2079  HA_ADMIN_WRONG_CHECKSUM check sum is wrong
2080 */
2081 
2082 int view_checksum(THD *thd, TABLE_LIST *view)
2083 {
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 :
2090  HA_ADMIN_OK);
2091 }
2092 
2093 /*
2094  rename view
2095 
2096  Synopsis:
2097  renames a view
2098 
2099  Parameters:
2100  thd thread handler
2101  new_db new name of database
2102  new_name new name of view
2103  view view
2104 
2105  Return values:
2106  FALSE Ok
2107  TRUE Error
2108 */
2109 bool
2110 mysql_rename_view(THD *thd,
2111  const char *new_db,
2112  const char *new_name,
2113  TABLE_LIST *view)
2114 {
2115  LEX_STRING pathstr;
2116  File_parser *parser;
2117  char path_buff[FN_REFLEN + 1];
2118  bool error= TRUE;
2119  bool was_truncated;
2120  DBUG_ENTER("mysql_rename_view");
2121 
2122  pathstr.str= (char *) path_buff;
2123  pathstr.length= build_table_filename(path_buff, sizeof(path_buff) - 1,
2124  view->db, view->table_name,
2125  reg_ext, 0);
2126 
2127  if ((parser= sql_parse_prepare(&pathstr, thd->mem_root, 1)) &&
2128  is_equal(&view_type, parser->type()))
2129  {
2130  TABLE_LIST view_def;
2131  char dir_buff[FN_REFLEN + 1];
2132  LEX_STRING dir, file;
2133 
2134  /*
2135  To be PS-friendly we should either to restore state of
2136  TABLE_LIST object pointed by 'view' after using it for
2137  view definition parsing or use temporary 'view_def'
2138  object for it.
2139  */
2140  memset(&view_def, 0, sizeof(view_def));
2141  view_def.timestamp.str= view_def.timestamp_buffer;
2142  view_def.view_suid= TRUE;
2143 
2144  /* get view definition and source */
2145  if (parser->parse((uchar*)&view_def, thd->mem_root, view_parameters,
2146  array_elements(view_parameters)-1,
2147  &file_parser_dummy_hook))
2148  goto err;
2149 
2150  dir.str= dir_buff;
2151  dir.length= build_table_filename(dir_buff, sizeof(dir_buff) - 1,
2152  new_db, "", "", 0);
2153 
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,
2157  &was_truncated);
2158  // Check if we hit FN_REFLEN characters in path length
2159  if (was_truncated)
2160  {
2161  my_error(ER_IDENT_CAUSES_TOO_LONG_PATH, MYF(0), sizeof(path_buff)-1,
2162  path_buff);
2163  goto err;
2164  }
2165  file.str= pathstr.str + dir.length;
2166  file.length= pathstr.length - dir.length;
2167 
2168  /* rename view and it's backups */
2169  if (rename_in_schema_file(thd, view->db, view->table_name, new_db, new_name))
2170  goto err;
2171 
2172  if (sql_create_definition_file(&dir, &file, view_file_type,
2173  (uchar*)&view_def, view_parameters))
2174  {
2175  /* restore renamed view in case of error */
2176  rename_in_schema_file(thd, new_db, new_name, view->db, view->table_name);
2177  goto err;
2178  }
2179  } else
2180  DBUG_RETURN(1);
2181 
2182  /* remove cache entries */
2183  query_cache_invalidate3(thd, view, 0);
2184  sp_cache_invalidate();
2185  error= FALSE;
2186 
2187 err:
2188  DBUG_RETURN(error);
2189 }