Commit a50bf2f0 authored by unknown's avatar unknown
Browse files

- stackoverflow check added for view of view processing

- fixed bug in join view processing
- postreview fixes (BUG#9398 & BUG#8703)


sql/sql_base.cc:
  used original TABLE object to get correct name of table and db
sql/sql_view.cc:
  fixed bug of assigning select_lex for join view
sql/table.cc:
  comment fixed
  stack overflow check added
  new method for underlying base table finding
sql/table.h:
  comment fixed
  new method for underlying base table finding
parent 8af8c530
Loading
Loading
Loading
Loading
+24 −21
Original line number Diff line number Diff line
@@ -724,31 +724,34 @@ TABLE_LIST *find_table_in_list(TABLE_LIST *table,
TABLE_LIST* unique_table(TABLE_LIST *table, TABLE_LIST *table_list)
{
  TABLE_LIST *res;
  const char *d_name= table->db, *t_name= table->table_name;
  char d_name_buff[MAX_ALIAS_NAME], t_name_buff[MAX_ALIAS_NAME];
  const char *d_name, *t_name;
  DBUG_ENTER("unique_table");
  DBUG_PRINT("enter", ("table alias: %s", table->alias));

  /*
    If this function called for query which update table (INSERT/UPDATE/...)
    then we have in table->table pointer to TABLE object which we are
    updating even if it is VIEW so we need TABLE_LIST of this TABLE object
    to get right names (even if lower_case_table_names used).

    If this function called for CREATE command that we have not opened table
    (table->table equal to 0) and right names is in current TABLE_LIST
    object.
  */
  if (table->table)
  {
    /* temporary table is always unique */
    if (table->table && table->table->s->tmp_table != NO_TMP_TABLE)
      DBUG_RETURN(0);
  if (table->view)
  {
    /* it is view and table opened */
    if (lower_case_table_names)
    {
      strmov(t_name_buff, table->table->alias);
      my_casedn_str(files_charset_info, t_name_buff);
      t_name= t_name_buff;
      strmov(d_name_buff, table->table->s->db);
      my_casedn_str(files_charset_info, d_name_buff);
      d_name= d_name_buff;
    }
    else
    {
      d_name= table->table->s->db;
      t_name= table->table->alias;
    }
    table= table->find_underlying_table(table->table);
    /*
      as far as we have table->table we have to find real TABLE_LIST of
      it in underlying tables
    */
    DBUG_ASSERT(table);
  }
  d_name= table->db;
  t_name= table->table_name;

  DBUG_PRINT("info", ("real table: %s.%s", d_name, t_name));
  for(;;)
+4 −4
Original line number Diff line number Diff line
@@ -755,17 +755,17 @@ mysql_make_view(File_parser *parser, TABLE_LIST *table)

      table->ancestor= view_tables;

      /* next table should include SELECT_LEX under this table SELECT_LEX */
      table->ancestor->select_lex= table->select_lex;

      /*
        Process upper level tables of view. As far as we do noy suport union
        here we can go through local tables of view most upper SELECT
      */
      for(tbl= (TABLE_LIST*)view_select->table_list.first;
      for(tbl= view_tables;
          tbl;
          tbl= tbl->next_local)
      {
        /* next table should include SELECT_LEX under this table SELECT_LEX */
        tbl->select_lex= table->select_lex;

        /*
          move lock type (TODO: should we issue error in case of TMPTABLE
          algorithm and non-read locking)?
+32 −1
Original line number Diff line number Diff line
@@ -1716,7 +1716,7 @@ void st_table_list::restore_want_privilege()
    check_opt_type  - WHITH CHECK OPTION type (VIEW_CHECK_NONE,
                      VIEW_CHECK_LOCAL, VIEW_CHECK_CASCADED)
  NOTES
    ancestor is list of tables and views used by view
    ancestor is list of tables and views used by view (underlying tables/views)

  DESCRIPTION
    It is:
@@ -1750,6 +1750,9 @@ bool st_table_list::setup_ancestor(THD *thd, Item **conds,
  bool res= FALSE;
  DBUG_ENTER("st_table_list::setup_ancestor");

  if (check_stack_overrun(thd, (char *)&res))
    return TRUE;

  for (tbl= ancestor; tbl; tbl= tbl->next_local)
  {
    if (tbl->ancestor &&
@@ -1986,6 +1989,34 @@ bool st_table_list::setup_ancestor(THD *thd, Item **conds,
}


/*
  Find underlying base tables (TABLE_LIST) which represent given
  table_to_find (TABLE)

  SYNOPSIS
    st_table_list::find_underlying_table()
    table_to_find table to find

  RETURN
    0  table is not found
    found table reference
*/

st_table_list *st_table_list::find_underlying_table(TABLE *table_to_find)
{
  /* is this real table and table which we are looking for? */
  if (table == table_to_find && ancestor == 0)
    return this;

  for (TABLE_LIST *tbl= ancestor; tbl; tbl= tbl->next_local)
  {
    TABLE_LIST *result;
    if ((result= tbl->find_underlying_table(table_to_find)))
      return result;
  }
  return 0;
}

/*
  cleunup items belonged to view fields translation table

+2 −1
Original line number Diff line number Diff line
@@ -376,7 +376,7 @@ typedef struct st_table_list
  st_select_lex	*select_lex;
  st_lex	*view;			/* link on VIEW lex for merging */
  Field_translator *field_translation;	/* array of VIEW fields */
  /* ancestor of this table (VIEW merge algorithm) */
  /* list of ancestor(s) of this table (underlying table(s)/view(s) */
  st_table_list	*ancestor;
  /* most upper view this table belongs to */
  st_table_list	*belong_to_view;
@@ -448,6 +448,7 @@ typedef struct st_table_list
  void restore_want_privilege();
  bool check_single_table(st_table_list **table, table_map map);
  bool set_insert_values(MEM_ROOT *mem_root);
  st_table_list *find_underlying_table(TABLE *table);
} TABLE_LIST;

class Item;