List:Internals« Previous MessageNext Message »
From:Jim Winstead Date:June 1 2005 12:51am
Subject:bk commit into 5.0 tree (jimw:1.1940)
View as plain text  
Below is the list of changes that have just been committed into a local
5.0 repository of jimw. When jimw does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html

ChangeSet
  1.1940 05/05/31 17:51:09 jimw@stripped +1 -0
  Merge mysql.com:/home/jimw/my/mysql-5.0-clean
  into  mysql.com:/home/jimw/my/mysql-5.0-6903

  sql/sql_show.cc
    1.223 05/05/31 17:51:04 jimw@stripped +0 -0
    Auto merged

# This is a BitKeeper patch.  What follows are the unified diffs for the
# set of deltas contained in the patch.  The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User:	jimw
# Host:	rama.(none)
# Root:	/home/jimw/my/mysql-5.0-6903/RESYNC

--- 1.222/sql/sql_show.cc	2005-03-04 10:41:44 -08:00
+++ 1.223/sql/sql_show.cc	2005-05-31 17:51:04 -07:00
@@ -41,6 +41,7 @@
 store_create_info(THD *thd, TABLE_LIST *table_list, String *packet);
 static int
 view_store_create_info(THD *thd, TABLE_LIST *table, String *packet);
+static bool schema_table_store_record(THD *thd, TABLE *table);
 
 
 /***************************************************************************
@@ -102,6 +103,7 @@
   {"Create routine","Functions,Procedures","To use CREATE FUNCTION/PROCEDURE"},
   {"Create temporary tables","Databases","To use CREATE TEMPORARY TABLE"},
   {"Create view", "Tables",  "To create new views"},
+  {"Create user", "Server Admin",  "To create new users"},
   {"Delete", "Tables",  "To delete existing rows"},
   {"Drop", "Databases,Tables", "To drop databases, tables, and views"},
   {"Execute", "Functions,Procedures", "To execute stored routines"},
@@ -394,7 +396,8 @@
   else
   {
     if (table_list->schema_table)
-      protocol->store(table_list->schema_table_name, system_charset_info);
+      protocol->store(table_list->schema_table->table_name,
+                      system_charset_info);
     else
       protocol->store(table->alias, system_charset_info);
     if (store_create_info(thd, table_list, &buffer))
@@ -703,6 +706,17 @@
     packet->append(' ');
     packet->append(dir_type);
     packet->append(" DIRECTORY='", 12);
+#ifdef __WIN__
+    /* Convert \ to / to be able to create table on unix */
+    char *winfilename= (char*) thd->memdup(filename, length);
+    char *pos, *end;
+    for (pos= winfilename, end= pos+length ; pos < end ; pos++)
+    {
+      if (*pos == '\\')
+        *pos = '/';
+    }
+    filename= winfilename;
+#endif
     packet->append(filename, length);
     packet->append('\'');
   }
@@ -744,7 +758,7 @@
   else
     packet->append("CREATE TABLE ", 13);
   if (table_list->schema_table)
-    alias= table_list->schema_table_name;
+    alias= table_list->schema_table->table_name;
   else
     alias= (lower_case_table_names == 2 ? table->alias :
             share->table_name);
@@ -966,7 +980,7 @@
       packet->append(buff, (uint) (end- buff));
     }
 
-    if (share->max_rows)
+    if (share->max_rows && !table_list->schema_table)
     {
       packet->append(" MAX_ROWS=", 10);
       end= longlong10_to_str(share->max_rows, buff, 10);
@@ -1325,6 +1339,45 @@
           pthread_mutex_unlock(&LOCK_active_mi);
           break;
         }
+        case SHOW_SLAVE_RETRIED_TRANS:
+        {
+          /*
+            TODO: in 5.1 with multimaster, have one such counter per line in SHOW
+            SLAVE STATUS, and have the sum over all lines here.
+          */
+	  pthread_mutex_lock(&LOCK_active_mi);
+          pthread_mutex_lock(&active_mi->rli.data_lock);
+	  end= int10_to_str(active_mi->rli.retried_trans, buff, 10);
+          pthread_mutex_unlock(&active_mi->rli.data_lock);
+	  pthread_mutex_unlock(&LOCK_active_mi);
+	  break;
+        }
+        case SHOW_SLAVE_SKIP_ERRORS:
+        {
+          MY_BITMAP *bitmap= (MY_BITMAP *)value;
+          if (!use_slave_mask || bitmap_is_clear_all(bitmap))
+          {
+            end= strmov(buff, "OFF");
+          }
+          else if (bitmap_is_set_all(bitmap))
+          {
+            end= strmov(buff, "ALL");
+          }
+          else
+          {
+            for (int i= 1; i < MAX_SLAVE_ERROR; i++)
+            {
+              if (bitmap_is_set(bitmap, i))
+              {
+                end= int10_to_str(i, (char*) end, 10);
+                *(char*) end++= ',';
+              }
+            }
+            if (end != buff)
+              end--;				// Remove last ','
+          }
+          break;
+        }
 #endif /* HAVE_REPLICATION */
         case SHOW_OPENTABLES:
           end= int10_to_str((long) cached_tables(), buff, 10);
@@ -1336,8 +1389,9 @@
           end= strend(pos);
           break;
         }
-        case SHOW_DOUBLE:
+        case SHOW_DOUBLE_STATUS:
         {
+          value= ((char *) status_var + (ulong) value);
           end= buff + sprintf(buff, "%f", *(double*) value);
           break;
         }
@@ -1531,7 +1585,8 @@
         table->field[0]->store(name_buffer, strlen(name_buffer),
                                system_charset_info);
         table->field[1]->store(pos, (uint32) (end - pos), system_charset_info);
-        table->file->write_row(table->record[0]);        
+        if (schema_table_store_record(thd, table))
+          DBUG_RETURN(TRUE);
       }
     }
   }
@@ -1579,6 +1634,8 @@
 
 /* INFORMATION_SCHEMA name */
 LEX_STRING information_schema_name= {(char*)"information_schema", 18};
+
+/* This is only used internally, but we need it here as a forward reference */
 extern ST_SCHEMA_TABLE schema_tables[];
 
 typedef struct st_index_field_values
@@ -1587,6 +1644,34 @@
 } INDEX_FIELD_VALUES;
 
 
+/*
+  Store record to I_S table, convert HEAP table
+  to MyISAM if necessary
+
+  SYNOPSIS
+    schema_table_store_record()
+    thd                   thread handler
+    table                 Information schema table to be updated
+
+  RETURN
+    0	                  success
+    1	                  error
+*/
+
+static bool schema_table_store_record(THD *thd, TABLE *table)
+{
+  int error;
+  if ((error= table->file->write_row(table->record[0])))
+  {
+    if (create_myisam_from_heap(thd, table, 
+                                table->pos_in_table_list->schema_table_param,
+                                error, 0))
+      return 1;
+  }
+  return 0;
+}
+
+
 void get_index_field_values(LEX *lex, INDEX_FIELD_VALUES *index_field_values)
 {
   const char *wild= lex->wild ? lex->wild->ptr() : NullS;
@@ -1644,8 +1729,8 @@
     CHARSET_INFO *cs= system_charset_info;
     ST_SCHEMA_TABLE *schema_table= table->schema_table;
     ST_FIELD_INFO *field_info= schema_table->fields_info;
-    const char *field_name1= field_info[schema_table->idx_field1].field_name;
-    const char *field_name2= field_info[schema_table->idx_field2].field_name;
+    const char *field_name1= schema_table->idx_field1 >= 0 ? field_info[schema_table->idx_field1].field_name : "";
+    const char *field_name2= schema_table->idx_field2 >= 0 ? field_info[schema_table->idx_field2].field_name : "";
     if (table->table != item_field->field->table ||
         (cs->coll->strnncollsp(cs, (uchar *) field_name1, strlen(field_name1),
                                (uchar *) item_field->field_name, 
@@ -1655,6 +1740,8 @@
                                strlen(item_field->field_name), 0)))
       return 0;
   }
+  else if (item->type() == Item::REF_ITEM)
+    return uses_only_table_name_fields(item->real_item(), table);
   if (item->type() == Item::SUBSELECT_ITEM &&
       !item->const_item())
     return 0;
@@ -1726,32 +1813,77 @@
 
 
 /*
-  Add 'information_schema' name to db_names list
+  Create db names list. Information schema name always is first in list
 
   SYNOPSIS
-    schema_db_add()
+    make_db_list()
     thd                   thread handler
     files                 list of db names
     wild                  wild string
+    idx_field_vals        idx_field_vals->db_name contains db name or
+                          wild string
     with_i_schema         returns 1 if we added 'IS' name to list
                           otherwise returns 0
+    is_wild_value         if value is 1 then idx_field_vals->db_name is
+                          wild string otherwise it's db name; 
 
   RETURN
     1	                  error
     0	                  success
 */
 
-int schema_db_add(THD *thd, List<char> *files,
-                  const char *wild, bool *with_i_schema)
+int make_db_list(THD *thd, List<char> *files,
+                 INDEX_FIELD_VALUES *idx_field_vals,
+                 bool *with_i_schema, bool is_wild_value)
 {
+  LEX *lex= thd->lex;
   *with_i_schema= 0;
-  if (!wild || !wild_compare(information_schema_name.str, wild, 0))
+  get_index_field_values(lex, idx_field_vals);
+  if (is_wild_value)
   {
-    *with_i_schema= 1;
-    if (files->push_back(thd->strdup(information_schema_name.str)))
-      return 1;
+    /*
+      This part of code is only for SHOW DATABASES command.
+      idx_field_vals->db_value can be 0 when we don't use
+      LIKE clause (see also get_index_field_values() function)
+    */
+    if (!idx_field_vals->db_value ||
+        !wild_case_compare(system_charset_info, 
+                           information_schema_name.str,
+                           idx_field_vals->db_value))
+    {
+      *with_i_schema= 1;
+      if (files->push_back(thd->strdup(information_schema_name.str)))
+        return 1;
+    }
+    return mysql_find_files(thd, files, NullS, mysql_data_home,
+                            idx_field_vals->db_value, 1);
   }
-  return 0;
+
+  /*
+    This part of code is for SHOW TABLES, SHOW TABLE STATUS commands.
+    idx_field_vals->db_value can't be 0 (see get_index_field_values()
+    function). lex->orig_sql_command can be not equal to SQLCOM_END
+    only in case of executing of SHOW commands.
+  */
+  if (lex->orig_sql_command != SQLCOM_END)
+  {
+    if (!my_strcasecmp(system_charset_info, information_schema_name.str,
+                       idx_field_vals->db_value))
+    {
+      *with_i_schema= 1;
+      return files->push_back(thd->strdup(information_schema_name.str));
+    }
+    return files->push_back(thd->strdup(idx_field_vals->db_value));
+  }
+
+  /*
+    Create list of existing databases. It is used in case
+    of select from information schema table
+  */
+  if (files->push_back(thd->strdup(information_schema_name.str)))
+    return 1;
+  *with_i_schema= 1;
+  return mysql_find_files(thd, files, NullS, mysql_data_home, NullS, 1);
 }
 
 
@@ -1829,14 +1961,9 @@
 
   if (schema_table_idx == SCH_TABLES)
     lock_type= TL_READ;
-  get_index_field_values(lex, &idx_field_vals);
-
-  /* information schema name always is first in list */
-  if (schema_db_add(thd, &bases, idx_field_vals.db_value, &with_i_schema))
-    goto err;
 
-  if (mysql_find_files(thd, &bases, NullS, mysql_data_home,
-		       idx_field_vals.db_value, 1))
+  if (make_db_list(thd, &bases, &idx_field_vals,
+                   &with_i_schema, 0))
     goto err;
 
   partial_cond= make_cond_for_info_schema(cond, tables);
@@ -1910,7 +2037,8 @@
                 }
               }
             }
-            table->file->write_row(table->record[0]);
+            if (schema_table_store_record(thd, table))
+              goto err;
           }
           else
           {
@@ -1947,13 +2075,14 @@
 }
 
 
-void store_schema_shemata(TABLE *table, const char *db_name,
-                          const char* cs_name)
+bool store_schema_shemata(THD* thd, TABLE *table, const char *db_name,
+                          CHARSET_INFO *cs)
 {
   restore_record(table, s->default_values);
   table->field[1]->store(db_name, strlen(db_name), system_charset_info);
-  table->field[2]->store(cs_name, strlen(cs_name), system_charset_info);
-  table->file->write_row(table->record[0]);
+  table->field[2]->store(cs->csname, strlen(cs->csname), system_charset_info);
+  table->field[3]->store(cs->name, strlen(cs->name), system_charset_info);
+  return schema_table_store_record(thd, table);
 }
 
 
@@ -1970,19 +2099,18 @@
   TABLE *table= tables->table;
   DBUG_ENTER("fill_schema_shemata");
 
-  get_index_field_values(thd->lex, &idx_field_vals);
-  /* information schema name always is first in list */
-  if (schema_db_add(thd, &files, idx_field_vals.db_value, &with_i_schema))
-    DBUG_RETURN(1);
-  if (mysql_find_files(thd, &files, NullS, mysql_data_home,
-                       idx_field_vals.db_value, 1))
+  if (make_db_list(thd, &files, &idx_field_vals,
+                   &with_i_schema, 1))
     DBUG_RETURN(1);
+
   List_iterator_fast<char> it(files);
   while ((file_name=it++))
   {
     if (with_i_schema)       // information schema name is always first in list
     {
-      store_schema_shemata(table, file_name, system_charset_info->csname);
+      if (store_schema_shemata(thd, table, file_name,
+                               system_charset_info))
+        DBUG_RETURN(1);
       with_i_schema= 0;
       continue;
     }
@@ -2005,8 +2133,9 @@
 	path[length-1]= FN_LIBCHAR;
       strmov(path+length, MY_DB_OPT_FILE);
       load_db_opt(thd, path, &create);
-      store_schema_shemata(table, file_name,
-                           create.default_table_charset->csname);
+      if (store_schema_shemata(thd, table, file_name, 
+                               create.default_table_charset))
+        DBUG_RETURN(1);
     }
   }
   DBUG_RETURN(0);
@@ -2191,8 +2320,7 @@
       }
     }
   }
-  table->file->write_row(table->record[0]);
-  DBUG_RETURN(0);
+  DBUG_RETURN(schema_table_store_record(thd, table));
 }
 
 
@@ -2238,8 +2366,38 @@
       char tmp[MAX_FIELD_WIDTH];
       char tmp1[MAX_FIELD_WIDTH];
       String type(tmp,sizeof(tmp), system_charset_info);
+      char *end= tmp;
       count++;
       restore_record(table, s->default_values);
+
+#ifndef NO_EMBEDDED_ACCESS_CHECKS
+      uint col_access;
+      check_access(thd,SELECT_ACL | EXTRA_ACL, base_name,
+                   &tables->grant.privilege, 0, 0);
+      col_access= get_column_grant(thd, &tables->grant, 
+                                   base_name, file_name,
+                                   field->field_name) & COL_ACLS;
+      if (lex->orig_sql_command != SQLCOM_SHOW_FIELDS  && 
+          !tables->schema_table && !col_access)
+        continue;
+      for (uint bitnr=0; col_access ; col_access>>=1,bitnr++)
+      {
+        if (col_access & 1)
+        {
+          *end++=',';
+          end=strmov(end,grant_types.type_names[bitnr]);
+        }
+      }
+      if (tables->schema_table)      // any user has 'select' privilege on all 
+                                     // I_S table columns
+        table->field[17]->store(grant_types.type_names[0],
+                                strlen(grant_types.type_names[0]), cs);
+      else
+        table->field[17]->store(tmp+1,end == tmp ? 0 : (uint) (end-tmp-1), cs);
+
+#else
+      *end= 0;
+#endif
       table->field[1]->store(base_name, strlen(base_name), cs);
       table->field[2]->store(file_name, strlen(file_name), cs);
       table->field[3]->store(field->field_name, strlen(field->field_name),
@@ -2283,17 +2441,20 @@
       table->field[6]->store((const char*) pos,
                              strlen((const char*) pos), cs);
       if (field->has_charset())
-        table->field[8]->store((longlong) field->representation_length()/
+      {
+        table->field[8]->store((longlong) field->field_length/
                                field->charset()->mbmaxlen);
-      else
-        table->field[8]->store((longlong) field->representation_length());
-      table->field[9]->store((longlong) field->representation_length());
+        table->field[8]->set_notnull();
+        table->field[9]->store((longlong) field->field_length);
+        table->field[9]->set_notnull();
+      }
 
       {
         uint dec =field->decimals();
         switch (field->type()) {
         case FIELD_TYPE_NEWDECIMAL:
-          table->field[10]->store((longlong) field->field_length);
+          table->field[10]->store((longlong)
+                                  ((Field_new_decimal*)field)->precision);
           table->field[10]->set_notnull();
           table->field[11]->store((longlong) field->decimals());
           table->field[11]->set_notnull();
@@ -2344,33 +2505,15 @@
                    (field->flags & MULTIPLE_KEY_FLAG) ? "MUL":"");
       table->field[15]->store((const char*) pos,
                               strlen((const char*) pos), cs);
-      char *end= tmp;
+      end= tmp;
       if (field->unireg_check == Field::NEXT_NUMBER)
         end=strmov(tmp,"auto_increment");
       table->field[16]->store(tmp, (uint) (end-tmp), cs);
 
       end=tmp;
-#ifndef NO_EMBEDDED_ACCESS_CHECKS
-      uint col_access;
-      check_access(thd,SELECT_ACL | EXTRA_ACL, base_name,
-                   &tables->grant.privilege, 0, 0);
-      col_access= get_column_grant(thd, &tables->grant, tables->db,
-                                   tables->table_name,
-                                   field->field_name) & COL_ACLS;
-      for (uint bitnr=0; col_access ; col_access>>=1,bitnr++)
-      {
-        if (col_access & 1)
-        {
-          *end++=',';
-          end=strmov(end,grant_types.type_names[bitnr]);
-        }
-      }
-#else
-      end=strmov(end,"");
-#endif
-      table->field[17]->store(tmp+1,end == tmp ? 0 : (uint) (end-tmp-1), cs);
       table->field[18]->store(field->comment.str, field->comment.length, cs);
-      table->file->write_row(table->record[0]);
+      if (schema_table_store_record(thd, table))
+        DBUG_RETURN(1);
     }
   }
   DBUG_RETURN(0);
@@ -2399,7 +2542,8 @@
 			     strlen(tmp_cs->comment ? tmp_cs->comment : ""),
                              scs);
       table->field[3]->store((longlong) tmp_cs->mbmaxlen);
-      table->file->write_row(table->record[0]);
+      if (schema_table_store_record(thd, table))
+        return 1;
     }
   }
   return 0;
@@ -2438,7 +2582,8 @@
         tmp_buff= (tmp_cl->state & MY_CS_COMPILED)? "Yes" : "";
 	table->field[4]->store(tmp_buff, strlen(tmp_buff), scs);
         table->field[5]->store((longlong) tmp_cl->strxfrm_multiply);
-	table->file->write_row(table->record[0]);
+        if (schema_table_store_record(thd, table))
+          return 1;
       }
     }
   }
@@ -2467,62 +2612,65 @@
       restore_record(table, s->default_values);
       table->field[0]->store(tmp_cl->name, strlen(tmp_cl->name), scs);
       table->field[1]->store(tmp_cl->csname , strlen(tmp_cl->csname), scs);
-      table->file->write_row(table->record[0]);
+      if (schema_table_store_record(thd, table))
+        return 1;
     }
   }
   return 0;
 }
 
 
-void store_schema_proc(THD *thd, TABLE *table,
-		       TABLE *proc_table,
-		       const char *wild)
+bool store_schema_proc(THD *thd, TABLE *table, TABLE *proc_table,
+                       const char *wild, bool full_access, const char *sp_user)
 {
   String tmp_string;
   TIME time;
   LEX *lex= thd->lex;
   CHARSET_INFO *cs= system_charset_info;
-  restore_record(table, s->default_values);
+  const char *sp_db, *sp_name, *definer;
+  sp_db= get_field(thd->mem_root, proc_table->field[0]);
+  sp_name= get_field(thd->mem_root, proc_table->field[1]);
+  definer= get_field(thd->mem_root, proc_table->field[11]);
+  if (!full_access)
+    full_access= !strcmp(sp_user, definer);
+  if (!full_access && check_some_routine_access(thd, sp_db, sp_name,
+			proc_table->field[2]->val_int() == TYPE_ENUM_PROCEDURE))
+    return 0;
+
   if (lex->orig_sql_command == SQLCOM_SHOW_STATUS_PROC &&
       proc_table->field[2]->val_int() == TYPE_ENUM_PROCEDURE ||
       lex->orig_sql_command == SQLCOM_SHOW_STATUS_FUNC &&
       proc_table->field[2]->val_int() == TYPE_ENUM_FUNCTION ||
       lex->orig_sql_command == SQLCOM_END)
   {
-    tmp_string.length(0);
-    get_field(thd->mem_root, proc_table->field[1], &tmp_string);
-    if (!wild || !wild[0] || !wild_compare(tmp_string.ptr(), wild, 0))
+    restore_record(table, s->default_values);
+    if (!wild || !wild[0] || !wild_compare(sp_name, wild, 0))
     {
-      table->field[3]->store(tmp_string.ptr(), tmp_string.length(), cs);
-      tmp_string.length(0);
+      table->field[3]->store(sp_name, strlen(sp_name), cs);
       get_field(thd->mem_root, proc_table->field[3], &tmp_string);
       table->field[0]->store(tmp_string.ptr(), tmp_string.length(), cs);
-      tmp_string.length(0);
-      get_field(thd->mem_root, proc_table->field[0], &tmp_string);
-      table->field[2]->store(tmp_string.ptr(), tmp_string.length(), cs);
-      tmp_string.length(0);
+      table->field[2]->store(sp_db, strlen(sp_db), cs);
       get_field(thd->mem_root, proc_table->field[2], &tmp_string);
       table->field[4]->store(tmp_string.ptr(), tmp_string.length(), cs);
       if (proc_table->field[2]->val_int() == TYPE_ENUM_FUNCTION)
       {
-        tmp_string.length(0);
         get_field(thd->mem_root, proc_table->field[9], &tmp_string);
         table->field[5]->store(tmp_string.ptr(), tmp_string.length(), cs);
         table->field[5]->set_notnull();
       }
+      if (full_access)
+      {
+        get_field(thd->mem_root, proc_table->field[10], &tmp_string);
+        table->field[7]->store(tmp_string.ptr(), tmp_string.length(), cs);
+      }
       table->field[6]->store("SQL", 3, cs);
-      tmp_string.length(0);
-      get_field(thd->mem_root, proc_table->field[10], &tmp_string);
-      table->field[7]->store(tmp_string.ptr(), tmp_string.length(), cs);
       table->field[10]->store("SQL", 3, cs);
-      tmp_string.length(0);
       get_field(thd->mem_root, proc_table->field[6], &tmp_string);
       table->field[11]->store(tmp_string.ptr(), tmp_string.length(), cs);
       if (proc_table->field[5]->val_int() == SP_CONTAINS_SQL)
       {
         table->field[12]->store("CONTAINS SQL", 12 , cs);
       }
-      tmp_string.length(0);
       get_field(thd->mem_root, proc_table->field[7], &tmp_string);
       table->field[14]->store(tmp_string.ptr(), tmp_string.length(), cs);
       bzero((char *)&time, sizeof(time));
@@ -2531,18 +2679,15 @@
       bzero((char *)&time, sizeof(time));
       ((Field_timestamp *) proc_table->field[13])->get_time(&time);
       table->field[16]->store_time(&time, MYSQL_TIMESTAMP_DATETIME);
-      tmp_string.length(0);
       get_field(thd->mem_root, proc_table->field[14], &tmp_string);
       table->field[17]->store(tmp_string.ptr(), tmp_string.length(), cs);
-      tmp_string.length(0);
       get_field(thd->mem_root, proc_table->field[15], &tmp_string);
       table->field[18]->store(tmp_string.ptr(), tmp_string.length(), cs);
-      tmp_string.length(0);
-      get_field(thd->mem_root, proc_table->field[11], &tmp_string);
-      table->field[19]->store(tmp_string.ptr(), tmp_string.length(), cs);
-      table->file->write_row(table->record[0]);
+      table->field[19]->store(definer, strlen(definer), cs);
+      return schema_table_store_record(thd, table);
     }
   }
+  return 0;
 }
 
 
@@ -2553,14 +2698,18 @@
   const char *wild= thd->lex->wild ? thd->lex->wild->ptr() : NullS;
   int res= 0;
   TABLE *table= tables->table, *old_open_tables= thd->open_tables;
+  bool full_access;
+  char definer[HOSTNAME_LENGTH+USERNAME_LENGTH+2];
   DBUG_ENTER("fill_schema_proc");
 
+  strxmov(definer, thd->priv_user, "@", thd->priv_host, NullS);
   bzero((char*) &proc_tables,sizeof(proc_tables));
   proc_tables.db= (char*) "mysql";
   proc_tables.db_length= 5;
   proc_tables.table_name= proc_tables.alias= (char*) "proc";
   proc_tables.table_name_length= 4;
   proc_tables.lock_type= TL_READ;
+  full_access= !check_table_access(thd, SELECT_ACL, &proc_tables, 1);
   if (!(proc_table= open_ltable(thd, &proc_tables, TL_READ)))
   {
     DBUG_RETURN(1);
@@ -2571,9 +2720,19 @@
     res= (res == HA_ERR_END_OF_FILE) ? 0 : 1;
     goto err;
   }
-  store_schema_proc(thd, table, proc_table, wild);
+  if (store_schema_proc(thd, table, proc_table, wild, full_access, definer))
+  {
+    res= 1;
+    goto err;
+  }
   while (!proc_table->file->index_next(proc_table->record[0]))
-    store_schema_proc(thd, table, proc_table, wild);
+  {
+    if (store_schema_proc(thd, table, proc_table, wild, full_access, definer))
+    {
+      res= 1;
+      goto err;
+    }
+  }
 
 err:
   proc_table->file->ha_index_end();
@@ -2663,7 +2822,8 @@
         else
           table->field[14]->store("", 0, cs);
         table->field[14]->set_notnull();
-        table->file->write_row(table->record[0]);
+        if (schema_table_store_record(thd, table))
+          DBUG_RETURN(1);
       }
     }
   }
@@ -2702,7 +2862,7 @@
         table->field[5]->store("YES", 3, cs);
       else
         table->field[5]->store("NO", 2, cs);
-      table->file->write_row(table->record[0]);
+      DBUG_RETURN(schema_table_store_record(thd, table));
     }
   }
   else
@@ -2716,9 +2876,9 @@
 }
 
 
-void store_constraints(TABLE *table, const char*db, const char *tname,
-                       const char *key_name, uint key_len,
-                       const char *con_type, uint con_len)
+bool store_constraints(THD *thd, TABLE *table, const char *db,
+                       const char *tname, const char *key_name,
+                       uint key_len, const char *con_type, uint con_len)
 {
   CHARSET_INFO *cs= system_charset_info;
   restore_record(table, s->default_values);
@@ -2727,7 +2887,7 @@
   table->field[3]->store(db, strlen(db), cs);
   table->field[4]->store(tname, strlen(tname), cs);
   table->field[5]->store(con_type, con_len, cs);
-  table->file->write_row(table->record[0]);
+  return schema_table_store_record(thd, table);
 }
 
 
@@ -2760,11 +2920,17 @@
         continue;
 
       if (i == primary_key && !strcmp(key_info->name, primary_key_name))
-        store_constraints(table, base_name, file_name, key_info->name,
-                          strlen(key_info->name), "PRIMARY KEY", 11);
+      {
+        if (store_constraints(thd, table, base_name, file_name, key_info->name,
+                              strlen(key_info->name), "PRIMARY KEY", 11))
+          DBUG_RETURN(1);
+      }
       else if (key_info->flags & HA_NOSAME)
-        store_constraints(table, base_name, file_name, key_info->name,
-                          strlen(key_info->name), "UNIQUE", 6);        
+      {
+        if (store_constraints(thd, table, base_name, file_name, key_info->name,
+                              strlen(key_info->name), "UNIQUE", 6))
+          DBUG_RETURN(1);
+      }
     }
 
     show_table->file->get_foreign_key_list(thd, &f_key_list);
@@ -2772,8 +2938,11 @@
     List_iterator_fast<FOREIGN_KEY_INFO> it(f_key_list);
     while ((f_key_info=it++))
     {
-      store_constraints(table, base_name, file_name, f_key_info->forein_id->str,
-                        strlen(f_key_info->forein_id->str), "FOREIGN KEY", 11);
+      if (store_constraints(thd, table, base_name, file_name, 
+                            f_key_info->forein_id->str,
+                            strlen(f_key_info->forein_id->str),
+                            "FOREIGN KEY", 11))
+        DBUG_RETURN(1);
     }
   }
   DBUG_RETURN(res);
@@ -2836,7 +3005,8 @@
                                  key_part->field->field_name, 
                                  strlen(key_part->field->field_name),
                                  (longlong) f_idx);
-          table->file->write_row(table->record[0]);
+          if (schema_table_store_record(thd, table))
+            DBUG_RETURN(1);
         }
       }
     }
@@ -2847,12 +3017,13 @@
     while ((f_key_info= it++))
     {
       LEX_STRING *f_info;
+      LEX_STRING *r_info;
       List_iterator_fast<LEX_STRING> it(f_key_info->foreign_fields),
         it1(f_key_info->referenced_fields);
       uint f_idx= 0;
       while ((f_info= it++))
       {
-        it1++;                                  // Ignore r_info
+        r_info= it1++;
         f_idx++;
         restore_record(table, s->default_values);
         store_key_column_usage(table, base_name, file_name,
@@ -2862,7 +3033,19 @@
                                (longlong) f_idx);
         table->field[8]->store((longlong) f_idx);
         table->field[8]->set_notnull();
-        table->file->write_row(table->record[0]);
+        table->field[9]->store(f_key_info->referenced_db->str,
+                               f_key_info->referenced_db->length,
+                               system_charset_info);
+        table->field[9]->set_notnull();
+        table->field[10]->store(f_key_info->referenced_table->str,
+                                f_key_info->referenced_table->length, 
+                                system_charset_info);
+        table->field[10]->set_notnull();
+        table->field[11]->store(r_info->str, r_info->length,
+                                system_charset_info);
+        table->field[11]->set_notnull();
+        if (schema_table_store_record(thd, table))
+          DBUG_RETURN(1);
       }
     }
   }
@@ -2887,7 +3070,8 @@
     table->field[1]->store(open_list->table, strlen(open_list->table), cs);
     table->field[2]->store((longlong) open_list->in_use);
     table->field[3]->store((longlong)  open_list->locked);
-    table->file->write_row(table->record[0]);
+    if (schema_table_store_record(thd, table))
+      DBUG_RETURN(1);
   }
   DBUG_RETURN(0);
 }
@@ -3028,6 +3212,7 @@
                                  TMP_TABLE_ALL_COLUMNS),
                                 HA_POS_ERROR, table_list->alias)))
     DBUG_RETURN(0);
+  table_list->schema_table_param= tmp_table_param;
   DBUG_RETURN(table);
 }
 
@@ -3353,12 +3538,11 @@
     TABLE_LIST *table_list= tab->table->pos_in_table_list;
     if (table_list->schema_table && thd->fill_derived_tables())
     {
-      TABLE_LIST *save_next_global= table_list->next_global;
       TABLE_LIST **query_tables_last= lex->query_tables_last;
       TABLE *old_derived_tables= thd->derived_tables;
       MYSQL_LOCK *sql_lock= thd->lock;
       lex->sql_command= SQLCOM_SHOW_FIELDS;
-
+      DBUG_ASSERT(!*query_tables_last);
       if (&lex->unit != lex->current_select->master_unit()) // is subselect
       {
         table_list->table->file->extra(HA_EXTRA_RESET_STATE);
@@ -3377,8 +3561,8 @@
       thd->lock= sql_lock;
       lex->sql_command= SQLCOM_SELECT;
       thd->derived_tables= old_derived_tables;
-      table_list->next_global= save_next_global;
       lex->query_tables_last= query_tables_last;
+      *query_tables_last= 0;
     }
   }
   thd->no_warnings_for_error= 0;
@@ -3391,6 +3575,7 @@
   {"CATALOG_NAME", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0},
   {"SCHEMA_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Database"},
   {"DEFAULT_CHARACTER_SET_NAME", 64, MYSQL_TYPE_STRING, 0, 0, 0},
+  {"DEFAULT_COLLATION_NAME", 64, MYSQL_TYPE_STRING, 0, 0, 0},
   {"SQL_PATH", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0},
   {0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
 };
@@ -3433,8 +3618,8 @@
   {"COLUMN_DEFAULT", NAME_LEN, MYSQL_TYPE_STRING, 0, 1, "Default"},
   {"IS_NULLABLE", 3, MYSQL_TYPE_STRING, 0, 0, "Null"},
   {"DATA_TYPE", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
-  {"CHARACTER_MAXIMUM_LENGTH", 21 , MYSQL_TYPE_LONG, 0, 0, 0},
-  {"CHARACTER_OCTET_LENGTH", 21 , MYSQL_TYPE_LONG, 0, 0, 0},
+  {"CHARACTER_MAXIMUM_LENGTH", 21 , MYSQL_TYPE_LONG, 0, 1, 0},
+  {"CHARACTER_OCTET_LENGTH", 21 , MYSQL_TYPE_LONG, 0, 1, 0},
   {"NUMERIC_PRECISION", 21 , MYSQL_TYPE_LONG, 0, 1, 0},
   {"NUMERIC_SCALE", 21 , MYSQL_TYPE_LONG, 0, 1, 0},
   {"CHARACTER_SET_NAME", 64, MYSQL_TYPE_STRING, 0, 1, 0},
@@ -3606,6 +3791,9 @@
   {"COLUMN_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
   {"ORDINAL_POSITION", 10 ,MYSQL_TYPE_LONG, 0, 0, 0},
   {"POSITION_IN_UNIQUE_CONSTRAINT", 10 ,MYSQL_TYPE_LONG, 0, 1, 0},
+  {"REFERENCED_TABLE_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 1, 0},
+  {"REFERENCED_TABLE_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 1, 0},
+  {"REFERENCED_COLUMN_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 1, 0},
   {0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
 };
 
Thread
bk commit into 5.0 tree (jimw:1.1940)Jim Winstead1 Jun