List:Commits« Previous MessageNext Message »
From:Stewart Smith Date:June 5 2006 3:42pm
Subject:bk commit into 5.1 tree (stewart:1.2188)
View as plain text  
Below is the list of changes that have just been committed into a local
5.1 repository of stewart. When stewart 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.2188 06/06/06 01:42:20 stewart@stripped +1 -0
  Merge mysql.com:/home/stewart/Documents/MySQL/5.1/new
  into  mysql.com:/home/stewart/Documents/MySQL/5.1/bug19544

  sql/sql_show.cc
    1.338 06/06/06 01:42:12 stewart@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:	stewart
# Host:	willster.(none)
# Root:	/home/stewart/Documents/MySQL/5.1/bug19544/RESYNC

--- 1.337/sql/sql_show.cc	2006-05-25 17:35:14 +10:00
+++ 1.338/sql/sql_show.cc	2006-06-06 01:42:12 +10:00
@@ -47,7 +47,7 @@
                               KEY *key_info);
 
 /***************************************************************************
-** List all table types supported 
+** List all table types supported
 ***************************************************************************/
 
 static my_bool show_handlerton(THD *thd, st_plugin_int *plugin,
@@ -55,25 +55,26 @@
 {
   handlerton *default_type= (handlerton *) arg;
   Protocol *protocol= thd->protocol;
-  handlerton *hton= (handlerton *) plugin->plugin->info;
+  handlerton *hton= (handlerton *)plugin->data;
 
   if (!(hton->flags & HTON_HIDDEN))
   {
     protocol->prepare_for_resend();
-    protocol->store(hton->name, system_charset_info);
+    protocol->store(plugin->name.str, plugin->name.length,
+                    system_charset_info);
     const char *option_name= show_comp_option_name[(int) hton->state];
 
     if (hton->state == SHOW_OPTION_YES && default_type == hton)
       option_name= "DEFAULT";
     protocol->store(option_name, system_charset_info);
-    protocol->store(hton->comment, system_charset_info);
+    protocol->store(plugin->plugin->descr, system_charset_info);
     protocol->store(hton->commit ? "YES" : "NO", system_charset_info);
     protocol->store(hton->prepare ? "YES" : "NO", system_charset_info);
     protocol->store(hton->savepoint_set ? "YES" : "NO", system_charset_info);
-    
+
     return protocol->write() ? 1 : 0;
   }
-  return 0;  
+  return 0;
 }
 
 bool mysqld_show_storage_engines(THD *thd)
@@ -93,7 +94,7 @@
                             Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
     DBUG_RETURN(TRUE);
 
-  if (plugin_foreach(thd, show_handlerton, 
+  if (plugin_foreach(thd, show_handlerton,
                      MYSQL_STORAGE_ENGINE_PLUGIN, thd->variables.table_type))
     DBUG_RETURN(TRUE);
 
@@ -740,6 +741,7 @@
       field_list.push_back(new Item_field(field));
   }
   restore_record(table, s->default_values);              // Get empty record
+  table->use_all_columns();
   if (thd->protocol->send_fields(&field_list, Protocol::SEND_DEFAULTS |
                                               Protocol::SEND_EOF))
     DBUG_VOID_RETURN;
@@ -953,9 +955,9 @@
   RETURN
     0       OK
  */
-int
-store_create_info(THD *thd, TABLE_LIST *table_list, String *packet,
-                  HA_CREATE_INFO *create_info_arg)
+
+int store_create_info(THD *thd, TABLE_LIST *table_list, String *packet,
+                      HA_CREATE_INFO *create_info_arg)
 {
   List<Item> field_list;
   char tmp[MAX_FIELD_WIDTH], *for_str, buff[128], *end, uname[NAME_LEN*3+1];
@@ -977,6 +979,7 @@
   bool limited_mysql_mode= (thd->variables.sql_mode & (MODE_NO_FIELD_OPTIONS |
                                                        MODE_MYSQL323 |
                                                        MODE_MYSQL40)) != 0;
+  my_bitmap_map *old_map;
   DBUG_ENTER("store_create_info");
   DBUG_PRINT("enter",("table: %s", table->s->table_name.str));
 
@@ -999,6 +1002,12 @@
   }
   append_identifier(thd, packet, alias, strlen(alias));
   packet->append(STRING_WITH_LEN(" (\n"));
+  /*
+    We need this to get default values from the table
+    We have to restore the read_set if we are called from insert in case
+    of row based replication.
+  */
+  old_map= tmp_use_all_columns(table, table->read_set);
 
   for (ptr=table->field ; (field= *ptr); ptr++)
   {
@@ -1153,10 +1162,11 @@
            table->field[key_part->fieldnr-1]->key_length() &&
            !(key_info->flags & HA_FULLTEXT)))
       {
+        char *end;
         buff[0] = '(';
-        char* end=int10_to_str((long) key_part->length /
-			       key_part->field->charset()->mbmaxlen,
-			       buff + 1,10);
+        end= int10_to_str((long) key_part->length /
+                          key_part->field->charset()->mbmaxlen,
+                          buff + 1,10);
         *end++ = ')';
         packet->append(buff,(uint) (end-buff));
       }
@@ -1325,13 +1335,14 @@
         (!table->part_info->is_auto_partitioned) &&
         ((part_syntax= generate_partition_syntax(table->part_info,
                                                   &part_syntax_len,
-                                                  FALSE,FALSE))))
+                                                  FALSE))))
     {
        packet->append(part_syntax, part_syntax_len);
        my_free(part_syntax, MYF(0));
     }
   }
 #endif
+  tmp_restore_column_map(table->read_set, old_map);
   DBUG_RETURN(0);
 }
 
@@ -2375,7 +2386,6 @@
   TABLE *table= tables->table;
   SELECT_LEX *select_lex= &lex->select_lex;
   SELECT_LEX *old_all_select_lex= lex->all_selects_list;
-  TABLE_LIST **save_query_tables_last= lex->query_tables_last;
   enum_sql_command save_sql_command= lex->sql_command;
   SELECT_LEX *lsel= tables->schema_select_lex;
   ST_SCHEMA_TABLE *schema_table= tables->schema_table;
@@ -2394,6 +2404,7 @@
   enum legacy_db_type not_used;
   Open_tables_state open_tables_state_backup;
   bool save_view_prepare_mode= lex->view_prepare_mode;
+  Query_tables_list query_tables_list_backup;
   lex->view_prepare_mode= TRUE;
   DBUG_ENTER("get_all_tables");
 
@@ -2406,6 +2417,8 @@
   */
   lex->sql_command= SQLCOM_SHOW_FIELDS;
 
+  lex->reset_n_backup_query_tables_list(&query_tables_list_backup);
+
   /*
     We should not introduce deadlocks even if we already have some
     tables open and locked, since we won't lock tables which we will
@@ -2446,8 +2459,7 @@
                                              show_table_list->db),
                                             show_table_list->alias));
     thd->temporary_tables= 0;
-    close_thread_tables(thd);
-    show_table_list->table= 0;
+    close_tables_for_reopen(thd, &show_table_list);
     goto err;
   }
 
@@ -2539,8 +2551,8 @@
           {
             int res;
             /*
-              Set the parent lex of 'sel' because it is needed by sel.init_query()
-              which is called inside make_table_list.
+              Set the parent lex of 'sel' because it is needed by
+              sel.init_query() which is called inside make_table_list.
             */
             sel.parent_lex= lex;
             if (make_table_list(thd, &sel, base_name, file_name))
@@ -2558,9 +2570,10 @@
               in this case.
             */
             res= schema_table->process_table(thd, show_table_list, table,
-                                            res, base_name,
-                                            show_table_list->alias);
-            close_thread_tables(thd);
+                                             res, base_name,
+                                             show_table_list->alias);
+            close_tables_for_reopen(thd, &show_table_list);
+            DBUG_ASSERT(!lex->query_tables_own_last);
             if (res)
               goto err;
           }
@@ -2577,11 +2590,10 @@
   error= 0;
 err:
   thd->restore_backup_open_tables_state(&open_tables_state_backup);
+  lex->restore_backup_query_tables_list(&query_tables_list_backup);
   lex->derived_tables= derived_tables;
   lex->all_selects_list= old_all_select_lex;
-  lex->query_tables_last= save_query_tables_last;
   lex->view_prepare_mode= save_view_prepare_mode;
-  *save_query_tables_last= 0;
   lex->sql_command= save_sql_command;
   DBUG_RETURN(error);
 }
@@ -2735,50 +2747,55 @@
     case ROW_TYPE_COMPACT:
       tmp_buff= "Compact";
       break;
+    case ROW_TYPE_PAGES:
+      tmp_buff= "Paged";
+      break;
     }
     table->field[6]->store(tmp_buff, strlen(tmp_buff), cs);
     if (!tables->schema_table)
     {
-      table->field[7]->store((longlong) file->records, TRUE);
+      table->field[7]->store((longlong) file->stats.records, TRUE);
       table->field[7]->set_notnull();
     }
-    table->field[8]->store((longlong) file->mean_rec_length, TRUE);
-    table->field[9]->store((longlong) file->data_file_length, TRUE);
-    if (file->max_data_file_length)
+    table->field[8]->store((longlong) file->stats.mean_rec_length, TRUE);
+    table->field[9]->store((longlong) file->stats.data_file_length, TRUE);
+    if (file->stats.max_data_file_length)
     {
-      table->field[10]->store((longlong) file->max_data_file_length, TRUE);
+      table->field[10]->store((longlong) file->stats.max_data_file_length,
+                              TRUE);
     }
-    table->field[11]->store((longlong) file->index_file_length, TRUE);
-    table->field[12]->store((longlong) file->delete_length, TRUE);
+    table->field[11]->store((longlong) file->stats.index_file_length, TRUE);
+    table->field[12]->store((longlong) file->stats.delete_length, TRUE);
     if (show_table->found_next_number_field)
     {
-      table->field[13]->store((longlong) file->auto_increment_value, TRUE);
+      table->field[13]->store((longlong) file->stats.auto_increment_value,
+                              TRUE);
       table->field[13]->set_notnull();
     }
-    if (file->create_time)
+    if (file->stats.create_time)
     {
       thd->variables.time_zone->gmt_sec_to_TIME(&time,
-                                                file->create_time);
+                                                file->stats.create_time);
       table->field[14]->store_time(&time, MYSQL_TIMESTAMP_DATETIME);
       table->field[14]->set_notnull();
     }
-    if (file->update_time)
+    if (file->stats.update_time)
     {
       thd->variables.time_zone->gmt_sec_to_TIME(&time,
-                                                file->update_time);
+                                                file->stats.update_time);
       table->field[15]->store_time(&time, MYSQL_TIMESTAMP_DATETIME);
       table->field[15]->set_notnull();
     }
-    if (file->check_time)
+    if (file->stats.check_time)
     {
-      thd->variables.time_zone->gmt_sec_to_TIME(&time, file->check_time);
+      thd->variables.time_zone->gmt_sec_to_TIME(&time, file->stats.check_time);
       table->field[16]->store_time(&time, MYSQL_TIMESTAMP_DATETIME);
       table->field[16]->set_notnull();
     }
     tmp_buff= (share->table_charset ?
                share->table_charset->name : "default");
     table->field[17]->store(tmp_buff, strlen(tmp_buff), cs);
-    if (file->table_flags() & (ulong) HA_HAS_CHECKSUM)
+    if (file->ha_table_flags() & (ulong) HA_HAS_CHECKSUM)
     {
       table->field[18]->store((longlong) file->checksum(), TRUE);
       table->field[18]->set_notnull();
@@ -2875,6 +2892,7 @@
   restore_record(show_table, s->default_values);
   base_name_length= strlen(base_name);
   file_name_length= strlen(file_name);
+  show_table->use_all_columns();               // Required for default
 
   for (ptr=show_table->field; (field= *ptr) ; ptr++)
   {
@@ -3091,7 +3109,7 @@
                                    void *ptable)
 {
   TABLE *table= (TABLE *) ptable;
-  handlerton *hton= (handlerton *) plugin->plugin->info;
+  handlerton *hton= (handlerton *)plugin->data;
   const char *wild= thd->lex->wild ? thd->lex->wild->ptr() : NullS;
   CHARSET_INFO *scs= system_charset_info;
   DBUG_ENTER("iter_schema_engines");
@@ -3099,21 +3117,26 @@
   if (!(hton->flags & HTON_HIDDEN))
   {
     if (!(wild && wild[0] &&
-          wild_case_compare(scs, hton->name,wild)))
+          wild_case_compare(scs, plugin->name.str,wild)))
     {
-      const char *tmp;
+      LEX_STRING state[2]= {{(char*) STRING_WITH_LEN("ENABLED")},
+                            {(char*) STRING_WITH_LEN("DISABLED")}};
+      LEX_STRING yesno[2]= {{(char*) STRING_WITH_LEN("NO")},
+                            {(char*) STRING_WITH_LEN("YES")}};
+      LEX_STRING *tmp;
       restore_record(table, s->default_values);
 
-      table->field[0]->store(hton->name, strlen(hton->name), scs);
-      tmp= hton->state ? "DISABLED" : "ENABLED";
-      table->field[1]->store( tmp, strlen(tmp), scs);
-      table->field[2]->store(hton->comment, strlen(hton->comment), scs);
-      tmp= hton->commit ? "YES" : "NO";
-      table->field[3]->store( tmp, strlen(tmp), scs);
-      tmp= hton->prepare ? "YES" : "NO";
-      table->field[4]->store( tmp, strlen(tmp), scs);
-      tmp= hton->savepoint_set ? "YES" : "NO";
-      table->field[5]->store( tmp, strlen(tmp), scs);
+      table->field[0]->store(plugin->name.str, plugin->name.length, scs);
+      tmp= &state[test(hton->state)];
+      table->field[1]->store(tmp->str, tmp->length, scs);
+      table->field[2]->store(plugin->plugin->descr,
+                             strlen(plugin->plugin->descr), scs);
+      tmp= &yesno[test(hton->commit)];
+      table->field[3]->store(tmp->str, tmp->length, scs);
+      tmp= &yesno[test(hton->prepare)];
+      table->field[4]->store(tmp->str, tmp->length, scs);
+      tmp= &yesno[test(hton->savepoint_set)];
+      table->field[5]->store(tmp->str, tmp->length, scs);
 
       if (schema_table_store_record(thd, table))
         DBUG_RETURN(1);
@@ -3125,7 +3148,7 @@
 
 int fill_schema_engines(THD *thd, TABLE_LIST *tables, COND *cond)
 {
-  return plugin_foreach(thd, iter_schema_engines, 
+  return plugin_foreach(thd, iter_schema_engines,
                         MYSQL_STORAGE_ENGINE_PLUGIN, tables->table);
 }
 
@@ -3140,7 +3163,7 @@
   {
     CHARSET_INFO **cl;
     CHARSET_INFO *tmp_cs= cs[0];
-    if (!tmp_cs || !(tmp_cs->state & MY_CS_AVAILABLE) || 
+    if (!tmp_cs || !(tmp_cs->state & MY_CS_AVAILABLE) ||
          (tmp_cs->state & MY_CS_HIDDEN) ||
         !(tmp_cs->state & MY_CS_PRIMARY))
       continue;
@@ -3382,7 +3405,7 @@
         KEY *key=show_table->key_info+i;
         if (key->rec_per_key[j])
         {
-          ha_rows records=(show_table->file->records /
+          ha_rows records=(show_table->file->stats.records /
                            key->rec_per_key[j]);
           table->field[9]->store((longlong) records, TRUE);
           table->field[9]->set_notnull();
@@ -3427,11 +3450,33 @@
 
   if (tables->view)
   {
+    Security_context *sctx= thd->security_ctx;
+    ulong grant= SHOW_VIEW_ACL;
+#ifndef NO_EMBEDDED_ACCESS_CHECKS
+    char *save_table_name= tables->table_name;
+    if (!my_strcasecmp(system_charset_info, tables->definer.user.str,
+                       sctx->priv_user) &&
+        !my_strcasecmp(system_charset_info, tables->definer.host.str,
+                       sctx->priv_host))
+      grant= SHOW_VIEW_ACL;
+    else
+    {
+      tables->table_name= tables->view_name.str;
+      if (check_access(thd, SHOW_VIEW_ACL , base_name,
+                       &tables->grant.privilege, 0, 1,
+                       test(tables->schema_table)))
+        grant= get_table_grant(thd, tables);
+      else
+        grant= tables->grant.privilege;
+    }
+    tables->table_name= save_table_name;
+#endif
+
     restore_record(table, s->default_values);
     table->field[1]->store(tables->view_db.str, tables->view_db.length, cs);
-    table->field[2]->store(tables->view_name.str, tables->view_name.length,
-                           cs);
-    table->field[3]->store(tables->query.str, tables->query.length, cs);
+    table->field[2]->store(tables->view_name.str, tables->view_name.length, cs);
+    if (grant & SHOW_VIEW_ACL)
+      table->field[3]->store(tables->query.str, tables->query.length, cs);
 
     if (tables->with_check != VIEW_CHECK_NONE)
     {
@@ -3787,7 +3832,7 @@
     table->field[20]->store_time(&time, MYSQL_TIMESTAMP_DATETIME);
     table->field[20]->set_notnull();
   }
-  if (file->table_flags() & (ulong) HA_HAS_CHECKSUM)
+  if (file->ha_table_flags() & (ulong) HA_HAS_CHECKSUM)
   {
     table->field[21]->store((longlong) stat_info.check_sum, TRUE);
     table->field[21]->set_notnull();
@@ -3889,24 +3934,28 @@
     {
       table->field[9]->store(part_info->part_func_string,
                              part_info->part_func_len, cs);
-      table->field[9]->set_notnull();
     }
     else if (part_info->list_of_part_fields)
     {
       collect_partition_expr(part_info->part_field_list, &tmp_str);
       table->field[9]->store(tmp_str.ptr(), tmp_str.length(), cs);
-      table->field[9]->set_notnull();
     }
+    table->field[9]->set_notnull();
 
     if (part_info->is_sub_partitioned())
     {
       /* Subpartition method */
+      tmp_res.length(0);
+      if (part_info->linear_hash_ind)
+        tmp_res.append(partition_keywords[PKW_LINEAR].str,
+                       partition_keywords[PKW_LINEAR].length);
       if (part_info->list_of_subpart_fields)
-        table->field[8]->store(partition_keywords[PKW_KEY].str,
-                               partition_keywords[PKW_KEY].length, cs);
+        tmp_res.append(partition_keywords[PKW_KEY].str,
+                       partition_keywords[PKW_KEY].length);
       else
-        table->field[8]->store(partition_keywords[PKW_HASH].str,
-                               partition_keywords[PKW_HASH].length, cs);
+        tmp_res.append(partition_keywords[PKW_HASH].str, 
+                       partition_keywords[PKW_HASH].length);
+      table->field[8]->store(tmp_res.ptr(), tmp_res.length(), cs);
       table->field[8]->set_notnull();
 
       /* Subpartition expression */
@@ -3914,14 +3963,13 @@
       {
         table->field[10]->store(part_info->subpart_func_string,
                                 part_info->subpart_func_len, cs);
-        table->field[10]->set_notnull();
       }
       else if (part_info->list_of_subpart_fields)
       {
         collect_partition_expr(part_info->subpart_field_list, &tmp_str);
         table->field[10]->store(tmp_str.ptr(), tmp_str.length(), cs);
-        table->field[10]->set_notnull();
       }
+      table->field[10]->set_notnull();
     }
 
     while ((part_elem= part_it++))
@@ -4056,8 +4104,24 @@
 
 extern LEX_STRING interval_type_to_name[];
 
+
+/*
+  Loads an event from mysql.event and copies it's data to a row of
+  I_S.EVENTS
+
+  Synopsis
+    copy_event_to_schema_table()
+      thd         Thread
+      sch_table   The schema table (information_schema.event)
+      event_table The event table to use for loading (mysql.event).
+
+  Returns
+    0  OK
+    1  Error
+*/
+
 static int
-fill_events_copy_to_schema_table(THD *thd, TABLE *sch_table, TABLE *event_table)
+copy_event_to_schema_table(THD *thd, TABLE *sch_table, TABLE *event_table)
 {
   const char *wild= thd->lex->wild ? thd->lex->wild->ptr() : NullS;
   CHARSET_INFO *scs= system_charset_info;
@@ -4075,9 +4139,19 @@
 
   if (!(!wild || !wild[0] || !wild_compare(et.name.str, wild, 0)))
     DBUG_RETURN(0);
-  
+
+  /*
+    Skip events in schemas one does not have access to. The check is
+    optimized. It's guaranteed in case of SHOW EVENTS that the user
+    has access.
+  */
+  if (thd->lex->orig_sql_command != SQLCOM_SHOW_EVENTS &&
+      check_access(thd, EVENT_ACL, et.dbname.str, 0, 0, 1,
+                   is_schema_db(et.dbname.str)))
+    DBUG_RETURN(0);
+
   /* ->field[0] is EVENT_CATALOG and is by default NULL */
-  
+
   sch_table->field[1]->store(et.dbname.str, et.dbname.length, scs);
   sch_table->field[2]->store(et.name.str, et.name.length, scs);
   sch_table->field[3]->store(et.definer.str, et.definer.length, scs);
@@ -4089,19 +4163,18 @@
     ulong sql_mode_len=0;
     sql_mode_str=
            sys_var_thd_sql_mode::symbolic_mode_representation(thd, et.sql_mode,
-                                                              &sql_mode_len);  
+                                                              &sql_mode_len);
     sch_table->field[9]->store((const char*)sql_mode_str, sql_mode_len, scs);
   }
-  
+
   if (et.expression)
   {
     String show_str;
     /* type */
     sch_table->field[5]->store(STRING_WITH_LEN("RECURRING"), scs);
 
-    if (Events::reconstruct_interval_expression(&show_str,
-                                                          et.interval,
-                                                          et.expression))
+    if (Events::reconstruct_interval_expression(&show_str, et.interval,
+                                                et.expression))
       DBUG_RETURN(1);
 
     sch_table->field[7]->set_notnull();
@@ -4111,7 +4184,7 @@
     sch_table->field[8]->set_notnull();
     sch_table->field[8]->store(ival->str, ival->length, scs);
 
-    //starts & ends    
+    /* starts & ends */
     sch_table->field[10]->set_notnull();
     sch_table->field[10]->store_time(&et.starts, MYSQL_TIMESTAMP_DATETIME);
 
@@ -4130,13 +4203,13 @@
     sch_table->field[6]->store_time(&et.execute_at, MYSQL_TIMESTAMP_DATETIME);
   }
 
-  //status
+  /* status */
   if (et.status == Event_timed::ENABLED)
     sch_table->field[12]->store(STRING_WITH_LEN("ENABLED"), scs);
   else
     sch_table->field[12]->store(STRING_WITH_LEN("DISABLED"), scs);
 
-  //on_completion
+  /* on_completion */
   if (et.on_completion == Event_timed::ON_COMPLETION_DROP)
     sch_table->field[13]->store(STRING_WITH_LEN("NOT PRESERVE"), scs);
   else
@@ -4166,98 +4239,179 @@
 }
 
 
-int fill_schema_events(THD *thd, TABLE_LIST *tables, COND *cond)
+/*
+  Performs an index scan of event_table (mysql.event) and fills schema_table.
+
+  Synopsis
+    events_table_index_read_for_db()
+      thd          Thread
+      schema_table The I_S.EVENTS table
+      event_table  The event table to use for loading (mysql.event)
+
+  Returns
+    0  OK
+    1  Error
+*/
+
+static
+int events_table_index_read_for_db(THD *thd, TABLE *schema_table,
+                                TABLE *event_table)
 {
-  TABLE *table= tables->table;
-  CHARSET_INFO *scs= system_charset_info;
-  TABLE *event_table= NULL;
-  Open_tables_state backup;
   int ret=0;
-  bool verbose= false;
-  char definer[HOSTNAME_LENGTH+USERNAME_LENGTH+2];
-  bool use_prefix_scanning= true;
-  uint key_len= 0;
+  CHARSET_INFO *scs= system_charset_info;
+  KEY *key_info;
+  uint key_len;
   byte *key_buf= NULL;
   LINT_INIT(key_buf);
 
-  DBUG_ENTER("fill_schema_events");
-
-  strxmov(definer, thd->security_ctx->priv_user,"@",thd->security_ctx->priv_host,
-          NullS);
+  DBUG_ENTER("schema_events_do_index_scan");
 
-  DBUG_PRINT("info",("db=%s current_user=%s", thd->lex->select_lex.db, definer));
-
-  thd->reset_n_backup_open_tables_state(&backup);
+  DBUG_PRINT("info", ("Using prefix scanning on PK"));
+  event_table->file->ha_index_init(0, 1);
+  event_table->field[Events::FIELD_DB]->
+        store(thd->lex->select_lex.db, strlen(thd->lex->select_lex.db), scs);
+  key_info= event_table->key_info;
+  key_len= key_info->key_part[0].store_length;
 
-  if ((ret= Events::open_event_table(thd, TL_READ, &event_table)))
+  if (!(key_buf= (byte *)alloc_root(thd->mem_root, key_len)))
   {
-    sql_print_error("Table mysql.event is damaged.");
     ret= 1;
-    goto err;
-  }
-  
-  event_table->file->ha_index_init(0, 1);
-
-  /* see others' events only if you have PROCESS_ACL !! */
-  verbose= ((thd->lex->verbose ||
-             thd->lex->orig_sql_command != SQLCOM_SHOW_EVENTS) &&
-            (thd->security_ctx->master_access & PROCESS_ACL));
-
-  if (verbose && thd->security_ctx->user)
-  {    
-    ret= event_table->file->index_first(event_table->record[0]);
-    use_prefix_scanning= false;
+    /* don't send error, it would be done by sql_alloc_error_handler() */
   }
   else
   {
-    event_table->field[Events::FIELD_DEFINER]->
-                                         store(definer, strlen(definer), scs);
-    key_len= event_table->key_info->key_part[0].store_length;
+    key_copy(key_buf, event_table->record[0], key_info, key_len);
+    if (!(ret= event_table->file->index_read(event_table->record[0], key_buf,
+                                             key_len, HA_READ_PREFIX)))
+    {
+      DBUG_PRINT("info",("Found rows. Let's retrieve them. ret=%d", ret));
+      do
+      {
+        ret= copy_event_to_schema_table(thd, schema_table, event_table);
+        if (ret == 0)
+          ret= event_table->file->index_next_same(event_table->record[0],
+                                                  key_buf, key_len); 
+      } while (ret == 0);
+    }
+    DBUG_PRINT("info", ("Scan finished. ret=%d", ret));
+  }
+  event_table->file->ha_index_end(); 
+  /*  ret is guaranteed to be != 0 */
+  if (ret == HA_ERR_END_OF_FILE || ret == HA_ERR_KEY_NOT_FOUND)
+    DBUG_RETURN(0);
+  DBUG_RETURN(1);
+}
 
-    if (thd->lex->select_lex.db)
-    {
-      event_table->field[Events::FIELD_DB]->
-            store(thd->lex->select_lex.db, strlen(thd->lex->select_lex.db), scs);
-      key_len+= event_table->key_info->key_part[1].store_length;
-    }
-    if (!(key_buf= (byte *)alloc_root(thd->mem_root, key_len)))
-    {
-      ret= 1;
-      goto err;
-    }
-    
-    key_copy(key_buf, event_table->record[0], event_table->key_info, key_len);
-    ret= event_table->file->index_read(event_table->record[0], key_buf, key_len,
-                                       HA_READ_PREFIX);
-  }
 
-  if (ret)
+/*
+  Performs a table scan of event_table (mysql.event) and fills schema_table.
+
+  Synopsis
+    events_table_scan_all()
+      thd          Thread
+      schema_table The I_S.EVENTS in memory table
+      event_table  The event table to use for loading.
+
+  Returns
+    0  OK
+    1  Error
+*/
+
+static
+int events_table_scan_all(THD *thd, TABLE *schema_table,
+                                TABLE *event_table)
+{
+  int ret;
+  READ_RECORD read_record_info;
+
+  DBUG_ENTER("schema_events_do_table_scan");
+  init_read_record(&read_record_info, thd, event_table, NULL, 1, 0);
+
+  /*
+    rr_sequential, in read_record(), returns 137==HA_ERR_END_OF_FILE,
+    but rr_handle_error returns -1 for that reason. Thus, read_record()
+    returns -1 eventually.
+  */
+  do
   {
-    ret= (ret == HA_ERR_END_OF_FILE || ret == HA_ERR_KEY_NOT_FOUND) ? 0 : 1;
-    goto err;
+    ret= read_record_info.read_record(&read_record_info);
+    if (ret == 0)
+      ret= copy_event_to_schema_table(thd, schema_table, event_table);
   }
+  while (ret == 0);
 
-  while (!ret)
-  {
-    if ((ret= fill_events_copy_to_schema_table(thd, table, event_table)))
-      goto err;
+  DBUG_PRINT("info", ("Scan finished. ret=%d", ret));
+  end_read_record(&read_record_info);
 
-    if (use_prefix_scanning)
-      ret= event_table->file->
-                       index_next_same(event_table->record[0], key_buf, key_len);                                  
-    else
-      ret= event_table->file->index_next(event_table->record[0]);
+  /*  ret is guaranteed to be != 0 */
+  DBUG_RETURN(ret == -1? 0:1);
+}
+
+
+/*
+  Fills I_S.EVENTS with data loaded from mysql.event. Also used by
+  SHOW EVENTS
+
+  Synopsis
+    fill_schema_events()
+      thd     Thread
+      tables  The schema table
+      cond    Unused
+
+  Returns
+    0  OK
+    1  Error
+*/
+
+int fill_schema_events(THD *thd, TABLE_LIST *tables, COND * /* cond */)
+{
+  TABLE *schema_table= tables->table;
+  TABLE *event_table= NULL;
+  Open_tables_state backup;
+  int ret= 0;
+
+  DBUG_ENTER("fill_schema_events");
+  /*
+    If it's SHOW EVENTS then thd->lex->select_lex.db is guaranteed not to
+    be NULL. Let's do an assert anyway.
+  */
+  if (thd->lex->orig_sql_command == SQLCOM_SHOW_EVENTS)
+  {
+    DBUG_ASSERT(thd->lex->select_lex.db);
+    if (check_access(thd, EVENT_ACL, thd->lex->select_lex.db, 0, 0, 0,
+                     is_schema_db(thd->lex->select_lex.db)))
+      DBUG_RETURN(1);
   }
-  // ret is guaranteed to be != 0
-  ret= (ret != HA_ERR_END_OF_FILE);
-err:
-  if (event_table)
+
+  DBUG_PRINT("info",("db=%s", thd->lex->select_lex.db?
+              thd->lex->select_lex.db:"(null)"));
+
+  thd->reset_n_backup_open_tables_state(&backup);
+  if (Events::open_event_table(thd, TL_READ, &event_table))
   {
-    event_table->file->ha_index_end();
-    close_thread_tables(thd);
+    sql_print_error("Table mysql.event is damaged.");
+    thd->restore_backup_open_tables_state(&backup);
+    DBUG_RETURN(1);
   }
 
+  /*
+    1. SELECT I_S => use table scan. I_S.EVENTS does not guarantee order
+                     thus we won't order it. OTOH, SHOW EVENTS will be
+                     ordered.
+    2. SHOW EVENTS => PRIMARY KEY with prefix scanning on (db)
+       Reasoning: Events are per schema, therefore a scan over an index
+                  will save use from doing a table scan and comparing
+                  every single row's `db` with the schema which we show.
+  */
+  if (thd->lex->orig_sql_command == SQLCOM_SHOW_EVENTS)
+    ret= events_table_index_read_for_db(thd, schema_table, event_table);
+  else
+    ret= events_table_scan_all(thd, schema_table, event_table);
+
+  close_thread_tables(thd);
   thd->restore_backup_open_tables_state(&backup);
+
+  DBUG_PRINT("info", ("Return code=%d", ret));
   DBUG_RETURN(ret);
 }
 
@@ -4480,7 +4634,7 @@
     field_count++;
   }
   TMP_TABLE_PARAM *tmp_table_param =
-    (TMP_TABLE_PARAM*) (thd->calloc(sizeof(TMP_TABLE_PARAM)));
+    (TMP_TABLE_PARAM*) (thd->alloc(sizeof(TMP_TABLE_PARAM)));
   tmp_table_param->init();
   tmp_table_param->table_charset= cs;
   tmp_table_param->field_count= field_count;
@@ -4852,7 +5006,7 @@
         filesort_free_buffers(table_list->table);
       }
       else
-        table_list->table->file->records= 0;
+        table_list->table->file->stats.records= 0;
 
       if (table_list->schema_table->fill_table(thd, table_list,
                                                tab->select_cond))
@@ -4875,7 +5029,7 @@
 {
   struct run_hton_fill_schema_files_args *args=
     (run_hton_fill_schema_files_args *) arg;
-  handlerton *hton= (handlerton *) plugin->plugin->info;
+  handlerton *hton= (handlerton *)plugin->data;
   if(hton->fill_files_table)
     hton->fill_files_table(thd, args->tables, args->cond);
   return false;
@@ -5219,7 +5373,7 @@
   {"PARTITION_ORDINAL_POSITION", 21 , MYSQL_TYPE_LONG, 0, 1, 0},
   {"SUBPARTITION_ORDINAL_POSITION", 21 , MYSQL_TYPE_LONG, 0, 1, 0},
   {"PARTITION_METHOD", 12, MYSQL_TYPE_STRING, 0, 1, 0},
-  {"SUBPARTITION_METHOD", 5, MYSQL_TYPE_STRING, 0, 1, 0},
+  {"SUBPARTITION_METHOD", 12, MYSQL_TYPE_STRING, 0, 1, 0},
   {"PARTITION_EXPRESSION", 65535, MYSQL_TYPE_STRING, 0, 1, 0},
   {"SUBPARTITION_EXPRESSION", 65535, MYSQL_TYPE_STRING, 0, 1, 0},
   {"PARTITION_DESCRIPTION", 65535, MYSQL_TYPE_STRING, 0, 1, 0},
Thread
bk commit into 5.1 tree (stewart:1.2188)Stewart Smith5 Jun