List:Commits« Previous MessageNext Message »
From:Marc Alff Date:May 7 2010 10:08am
Subject:bzr commit into mysql-next-mr branch (marc.alff:3141) WL#4674
View as plain text  
#At file:///Users/malff/BZR_TREE/mysql-next-mr-wl4674/ based on revid:marc.alff@stripped

 3141 Marc Alff	2010-05-07
      WL#4674 PERFORMANCE_SCHEMA SETUP ACTORS
      
      Port in progress

    added:
      storage/perfschema/pfs_setup_actor.cc
      storage/perfschema/pfs_setup_actor.h
    modified:
      include/mysql/psi/psi.h
      include/mysql/psi/psi_abi_v1.h.pp
      libmysqld/lib_sql.cc
      sql/event_scheduler.cc
      sql/ha_ndbcluster_binlog.cc
      sql/log.cc
      sql/sql_class.cc
      sql/sql_class.h
      sql/sql_connect.cc
      sql/sql_insert.cc
      sql/sql_parse.cc
      sql/sql_prepare.cc
      sql/sql_repl.cc
      sql/sql_show.cc
      storage/perfschema/CMakeLists.txt
      storage/perfschema/Makefile.am
      storage/perfschema/pfs.cc
      storage/perfschema/pfs_instr.cc
      storage/perfschema/pfs_instr.h
      storage/perfschema/pfs_lock.h
      storage/perfschema/pfs_server.h
      storage/perfschema/unittest/stub_pfs_global.h
=== modified file 'include/mysql/psi/psi.h'
--- a/include/mysql/psi/psi.h	2010-01-26 23:42:54 +0000
+++ b/include/mysql/psi/psi.h	2010-05-07 10:08:23 +0000
@@ -600,6 +600,20 @@ typedef void (*set_thread_id_v1_t)(struc
 */
 typedef struct PSI_thread* (*get_thread_v1_t)(void);
 
+typedef void (*set_thread_user_v1_t)(const char *user, int user_len);
+
+typedef void (*set_thread_host_v1_t)(const char *host, int host_len);
+
+typedef void (*set_thread_db_v1_t)(const char* db, int db_len);
+
+typedef void (*set_thread_command_v1_t)(int command);
+
+typedef void (*set_thread_start_time_v1_t)(time_t start_time);
+
+typedef void (*set_thread_state_v1_t)(const char* state);
+
+typedef void (*set_thread_info_v1_t)(const char* info, int info_len);
+
 /**
   Attach a thread instrumentation to the running thread.
   In case of thread pools, this method should be called when
@@ -889,6 +903,20 @@ struct PSI_v1
   set_thread_id_v1_t set_thread_id;
   /** @sa get_thread_v1_t. */
   get_thread_v1_t get_thread;
+  /** @sa set_thread_user_v1_t. */
+  set_thread_user_v1_t set_thread_user;
+  /** @sa set_thread_host_v1_t. */
+  set_thread_host_v1_t set_thread_host;
+  /** @sa set_thread_db_v1_t. */
+  set_thread_db_v1_t set_thread_db;
+  /** @sa set_thread_command_v1_t. */
+  set_thread_command_v1_t set_thread_command;
+  /** @sa set_thread_start_time_v1_t. */
+  set_thread_start_time_v1_t set_thread_start_time;
+  /** @sa set_thread_state_v1_t. */
+  set_thread_state_v1_t set_thread_state;
+  /** @sa set_thread_info_v1_t. */
+  set_thread_info_v1_t set_thread_info;
   /** @sa set_thread_v1_t. */
   set_thread_v1_t set_thread;
   /** @sa delete_current_thread_v1_t. */

=== modified file 'include/mysql/psi/psi_abi_v1.h.pp'
--- a/include/mysql/psi/psi_abi_v1.h.pp	2010-01-26 23:42:54 +0000
+++ b/include/mysql/psi/psi_abi_v1.h.pp	2010-05-07 10:08:23 +0000
@@ -125,6 +125,13 @@ typedef struct PSI_thread* (*new_thread_
 typedef void (*set_thread_id_v1_t)(struct PSI_thread *thread,
                                    unsigned long id);
 typedef struct PSI_thread* (*get_thread_v1_t)(void);
+typedef void (*set_thread_user_v1_t)(const char *user, int user_len);
+typedef void (*set_thread_host_v1_t)(const char *host, int host_len);
+typedef void (*set_thread_db_v1_t)(const char* db, int db_len);
+typedef void (*set_thread_command_v1_t)(int command);
+typedef void (*set_thread_start_time_v1_t)(time_t start_time);
+typedef void (*set_thread_state_v1_t)(const char* state);
+typedef void (*set_thread_info_v1_t)(const char* info, int info_len);
 typedef void (*set_thread_v1_t)(struct PSI_thread *thread);
 typedef void (*delete_current_thread_v1_t)(void);
 typedef void (*delete_thread_v1_t)(struct PSI_thread *thread);
@@ -203,6 +210,13 @@ struct PSI_v1
   new_thread_v1_t new_thread;
   set_thread_id_v1_t set_thread_id;
   get_thread_v1_t get_thread;
+  set_thread_user_v1_t set_thread_user;
+  set_thread_host_v1_t set_thread_host;
+  set_thread_db_v1_t set_thread_db;
+  set_thread_command_v1_t set_thread_command;
+  set_thread_start_time_v1_t set_thread_start_time;
+  set_thread_state_v1_t set_thread_state;
+  set_thread_info_v1_t set_thread_info;
   set_thread_v1_t set_thread;
   delete_current_thread_v1_t delete_current_thread;
   delete_thread_v1_t delete_thread;

=== modified file 'libmysqld/lib_sql.cc'
--- a/libmysqld/lib_sql.cc	2010-04-13 15:04:45 +0000
+++ b/libmysqld/lib_sql.cc	2010-05-07 10:08:23 +0000
@@ -633,7 +633,7 @@ void *create_embedded_thd(int client_fla
   if (thd->variables.max_join_size == HA_POS_ERROR)
     thd->variables.option_bits |= OPTION_BIG_SELECTS;
   thd->proc_info=0;				// Remove 'login'
-  thd->command=COM_SLEEP;
+  thd->set_command(COM_SLEEP);
   thd->version=refresh_version;
   thd->set_time();
   thd->init_for_queries();

=== modified file 'sql/event_scheduler.cc'
--- a/sql/event_scheduler.cc	2010-04-20 08:51:50 +0000
+++ b/sql/event_scheduler.cc	2010-05-07 10:08:23 +0000
@@ -398,7 +398,7 @@ Event_scheduler::start()
   }
   pre_init_event_thread(new_thd);
   new_thd->system_thread= SYSTEM_THREAD_EVENT_SCHEDULER;
-  new_thd->command= COM_DAEMON;
+  new_thd->set_command(COM_DAEMON);
 
   /*
     We should run the event scheduler thread under the super-user privileges.

=== modified file 'sql/ha_ndbcluster_binlog.cc'
--- a/sql/ha_ndbcluster_binlog.cc	2010-03-31 14:05:33 +0000
+++ b/sql/ha_ndbcluster_binlog.cc	2010-05-07 10:08:23 +0000
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000-2003 MySQL AB, 2008-2009 Sun Microsystems, Inc
+/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -3674,7 +3674,7 @@ pthread_handler_t ndb_binlog_thread_func
   }
 
   thd->init_for_queries();
-  thd->command= COM_DAEMON;
+  thd->set_command(COM_DAEMON);
   thd->system_thread= SYSTEM_THREAD_NDBCLUSTER_BINLOG;
   thd->version= refresh_version;
   thd->main_security_ctx.host_or_ip= "";

=== modified file 'sql/log.cc'
--- a/sql/log.cc	2010-04-20 11:58:28 +0000
+++ b/sql/log.cc	2010-05-07 10:08:23 +0000
@@ -1,4 +1,4 @@
-/* Copyright 2000-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc.
+/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -1133,8 +1133,8 @@ bool LOGGER::slow_log_print(THD *thd, co
     if (!query)
     {
       is_command= TRUE;
-      query= command_name[thd->command].str;
-      query_length= command_name[thd->command].length;
+      query= command_name[thd->get_command()].str;
+      query_length= command_name[thd->get_command()].length;
     }
 
     for (current_handler= slow_log_handler_list; *current_handler ;)

=== modified file 'sql/sql_class.cc'
--- a/sql/sql_class.cc	2010-04-26 09:06:35 +0000
+++ b/sql/sql_class.cc	2010-05-07 10:08:23 +0000
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc.
+/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -276,6 +276,10 @@ const char *set_thd_proc_info(THD *thd, 
   thd->profiling.status_change(info, calling_function, calling_file, calling_line);
 #endif
   thd->proc_info= info;
+#ifdef HAVE_PSI_INTERFACE
+  if (PSI_server)
+    PSI_server->set_thread_state(info);
+#endif
   return old_info;
 }
 
@@ -556,7 +560,7 @@ THD::THD()
   where= THD::DEFAULT_WHERE;
   server_id = ::server_id;
   slave_net = 0;
-  command=COM_CONNECT;
+  set_command(COM_CONNECT);
   *scramble= '\0';
 
   /* Call to init() below requires fully initialized Open_tables_state. */
@@ -3295,6 +3299,16 @@ void THD::set_statement(Statement *stmt)
 }
 
 
+void THD::set_command(enum enum_server_command command)
+{
+  m_command= command;
+#ifdef HAVE_PSI_INTERFACE
+  if (PSI_server)
+    PSI_server->set_thread_command(m_command);
+#endif
+}
+
+
 /** Assign a new value to thd->query.  */
 
 void THD::set_query(char *query_arg, uint32 query_length_arg)
@@ -3302,6 +3316,11 @@ void THD::set_query(char *query_arg, uin
   mysql_mutex_lock(&LOCK_thd_data);
   set_query_inner(query_arg, query_length_arg);
   mysql_mutex_unlock(&LOCK_thd_data);
+
+#ifdef HAVE_PSI_INTERFACE
+  if (PSI_server)
+    PSI_server->set_thread_info(query_arg, query_length_arg);
+#endif
 }
 
 /** Assign a new value to thd->query and thd->query_id.  */

=== modified file 'sql/sql_class.h'
--- a/sql/sql_class.h	2010-04-26 09:06:35 +0000
+++ b/sql/sql_class.h	2010-05-07 10:08:23 +0000
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc.
+/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -1648,11 +1648,15 @@ public:
   uint dbug_sentry; // watch out for memory corruption
 #endif
   struct st_my_thread_var *mysys_var;
-  /*
-    Type of current query: COM_STMT_PREPARE, COM_QUERY, etc. Set from
-    first byte of the packet in do_command()
+
+private:
+  /**
+    Type of current query: COM_STMT_PREPARE, COM_QUERY, etc.
+    Set from first byte of the packet in do_command()
   */
-  enum enum_server_command command;
+  enum enum_server_command m_command;
+
+public:
   uint32     server_id;
   uint32     file_id;			// for LOAD DATA INFILE
   /* remote (peer) port */
@@ -2296,12 +2300,28 @@ public:
     }
     else
       start_utime= utime_after_lock= my_micro_time_and_time(&start_time);
+
+#ifdef HAVE_PSI_INTERFACE
+    if (PSI_server)
+      PSI_server->set_thread_start_time(start_time);
+#endif
   }
-  inline void	set_current_time()    { start_time= my_time(MY_WME); }
-  inline void	set_time(time_t t)
+  inline void set_current_time()
+  {
+    start_time= my_time(MY_WME);
+#ifdef HAVE_PSI_INTERFACE
+    if (PSI_server)
+      PSI_server->set_thread_start_time(start_time);
+#endif
+  }
+  inline void set_time(time_t t)
   {
     start_time= user_time= t;
     start_utime= utime_after_lock= my_micro_time();
+#ifdef HAVE_PSI_INTERFACE
+    if (PSI_server)
+      PSI_server->set_thread_start_time(start_time);
+#endif
   }
   void set_time_after_lock()  { utime_after_lock= my_micro_time(); }
   ulonglong current_utime()  { return my_micro_time(); }
@@ -2569,6 +2589,7 @@ public:
   */
   bool set_db(const char *new_db, size_t new_db_len)
   {
+    bool result;
     /* Do not reallocate memory if current chunk is big enough. */
     if (db && new_db && db_length >= new_db_len)
       memcpy(db, new_db, new_db_len+1);
@@ -2581,7 +2602,12 @@ public:
         db= NULL;
     }
     db_length= db ? new_db_len : 0;
-    return new_db && !db;
+    result= new_db && !db;
+#ifdef HAVE_PSI_INTERFACE
+    if (result && PSI_server)
+      PSI_server->set_thread_db(new_db, new_db_len);
+#endif
+    return result;
   }
 
   /**
@@ -2599,6 +2625,10 @@ public:
   {
     db= new_db;
     db_length= new_db_len;
+#ifdef HAVE_PSI_INTERFACE
+    if (PSI_server)
+      PSI_server->set_thread_db(new_db, new_db_len);
+#endif
   }
   /*
     Copy the current database to the argument. Use the current arena to
@@ -2733,6 +2763,11 @@ public:
   /** Overloaded to guard query/query_length fields */
   virtual void set_statement(Statement *stmt);
 
+  void set_command(enum enum_server_command command);
+
+  inline enum enum_server_command get_command() const
+  { return m_command; }
+
   /**
     Assign a new value to thd->query and thd->query_id.
     Protected with LOCK_thd_data mutex.

=== modified file 'sql/sql_connect.cc'
--- a/sql/sql_connect.cc	2010-04-13 15:04:45 +0000
+++ b/sql/sql_connect.cc	2010-05-07 10:08:23 +0000
@@ -1,4 +1,4 @@
-/* Copyright (C) 2007 MySQL AB, 2008-2009 Sun Microsystems, Inc
+/* Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -15,7 +15,7 @@
 
 
 /*
-  Functions to autenticate and handle reqests for a connection
+  Functions to authenticate and handle requests for a connection
 */
 
 #include "my_global.h"
@@ -496,6 +496,15 @@ check_user(THD *thd, enum enum_server_co
       }
       my_ok(thd);
       thd->password= test(passwd_len);          // remember for error messages 
+#ifdef HAVE_PSI_INTERFACE
+      if (PSI_server)
+      {
+        PSI_server->set_thread_host(thd->main_security_ctx.host_or_ip,
+                                    strlen(thd->main_security_ctx.host_or_ip));
+        PSI_server->set_thread_user(thd->main_security_ctx.user,
+                                    strlen(thd->main_security_ctx.user));
+      }
+#endif
       /* Ready to handle queries */
       DBUG_RETURN(0);
     }
@@ -1078,7 +1087,7 @@ static void prepare_new_connection_state
   */
   thd->version= refresh_version;
   thd->proc_info= 0;
-  thd->command= COM_SLEEP;
+  thd->set_command(COM_SLEEP);
   thd->set_time();
   thd->init_for_queries();
 

=== modified file 'sql/sql_insert.cc'
--- a/sql/sql_insert.cc	2010-04-07 12:02:19 +0000
+++ b/sql/sql_insert.cc	2010-05-07 10:08:23 +0000
@@ -1816,7 +1816,7 @@ public:
     thd.security_ctx->host=(char*) my_localhost;
     thd.current_tablenr=0;
     thd.version=refresh_version;
-    thd.command=COM_DELAYED_INSERT;
+    thd.set_command(COM_DELAYED_INSERT);
     thd.lex->current_select= 0; 		// for my_message_sql
     thd.lex->sql_command= SQLCOM_INSERT;        // For innodb::store_lock()
     /*

=== modified file 'sql/sql_parse.cc'
--- a/sql/sql_parse.cc	2010-04-26 09:06:35 +0000
+++ b/sql/sql_parse.cc	2010-05-07 10:08:23 +0000
@@ -882,7 +882,7 @@ bool dispatch_command(enum enum_server_c
                       thd->security_ctx->priv_user,
                       (char *) thd->security_ctx->host_or_ip);
   
-  thd->command=command;
+  thd->set_command(command);
   /*
     Commands which always take a long time are logged into
     the slow log only if opt_log_slow_admin_statements is set.
@@ -1457,7 +1457,7 @@ bool dispatch_command(enum enum_server_c
 
   thd_proc_info(thd, "cleaning up");
   thd->set_query(NULL, 0);
-  thd->command=COM_SLEEP;
+  thd->set_command(COM_SLEEP);
   dec_thread_running();
   thd_proc_info(thd, 0);
   thd->packet.shrink(thd->variables.net_buffer_length);	// Reclaim some memory
@@ -6880,7 +6880,7 @@ uint kill_one_thread(THD *thd, ulong id,
   I_List_iterator<THD> it(threads);
   while ((tmp=it++))
   {
-    if (tmp->command == COM_DAEMON)
+    if (tmp->get_command() == COM_DAEMON)
       continue;
     if (tmp->thread_id == id)
     {

=== modified file 'sql/sql_prepare.cc'
--- a/sql/sql_prepare.cc	2010-04-07 11:58:40 +0000
+++ b/sql/sql_prepare.cc	2010-05-07 10:08:23 +0000
@@ -1,4 +1,4 @@
-/* Copyright (C) 1995-2002 MySQL AB, 2008-2009 Sun Microsystems, Inc
+/* Copyright (c) 1995, 2010, Oracle and/or its affiliates. All rights reserved.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -2700,7 +2700,7 @@ void mysqld_stmt_reset(THD *thd, char *p
 
   stmt->state= Query_arena::PREPARED;
 
-  general_log_print(thd, thd->command, NullS);
+  general_log_print(thd, thd->get_command(), NullS);
 
   my_ok(thd);
 
@@ -2733,7 +2733,7 @@ void mysqld_stmt_close(THD *thd, char *p
   */
   DBUG_ASSERT(! stmt->is_in_use());
   stmt->deallocate();
-  general_log_print(thd, thd->command, NullS);
+  general_log_print(thd, thd->get_command(), NullS);
 
   DBUG_VOID_RETURN;
 }
@@ -2837,7 +2837,7 @@ void mysql_stmt_get_longdata(THD *thd, c
     sprintf(stmt->last_error, ER(ER_OUTOFMEMORY), 0);
   }
 
-  general_log_print(thd, thd->command, NullS);
+  general_log_print(thd, thd->get_command(), NullS);
 
   DBUG_VOID_RETURN;
 }

=== modified file 'sql/sql_repl.cc'
--- a/sql/sql_repl.cc	2010-04-01 19:34:09 +0000
+++ b/sql/sql_repl.cc	2010-05-07 10:08:23 +0000
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000-2006 MySQL AB & Sasha, 2008-2009 Sun Microsystems, Inc
+/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -1308,7 +1308,7 @@ void kill_zombie_dump_threads(uint32 sla
 
   while ((tmp=it++))
   {
-    if (tmp->command == COM_BINLOG_DUMP &&
+    if (tmp->get_command() == COM_BINLOG_DUMP &&
        tmp->server_id == slave_server_id)
     {
       mysql_mutex_lock(&tmp->LOCK_thd_data);    // Lock from delete

=== modified file 'sql/sql_show.cc'
--- a/sql/sql_show.cc	2010-04-21 07:35:37 +0000
+++ b/sql/sql_show.cc	2010-05-07 10:08:23 +0000
@@ -1714,7 +1714,7 @@ static const char *thread_state_info(THD
   {
     if (tmp->net.reading_or_writing == 2)
       return "Writing to net";
-    else if (tmp->command == COM_SLEEP)
+    else if (tmp->get_command() == COM_SLEEP)
       return "";
     else
       return "Reading from net";
@@ -1788,7 +1788,7 @@ void mysqld_list_processes(THD *thd,cons
                                       tmp_sctx->host ? tmp_sctx->host : "");
         if ((thd_info->db=tmp->db))             // Safe test
           thd_info->db=thd->strdup(thd_info->db);
-        thd_info->command=(int) tmp->command;
+        thd_info->command=(int) tmp->get_command();
         if ((mysys_var= tmp->mysys_var))
           mysql_mutex_lock(&mysys_var->mutex);
         thd_info->proc_info= (char*) (tmp->killed == THD::KILL_CONNECTION? "Killed" : 0);
@@ -1898,8 +1898,8 @@ int fill_schema_processlist(THD* thd, TA
       if ((val= (char *) (tmp->killed == THD::KILL_CONNECTION? "Killed" : 0)))
         table->field[4]->store(val, strlen(val), cs);
       else
-        table->field[4]->store(command_name[tmp->command].str,
-                               command_name[tmp->command].length, cs);
+        table->field[4]->store(command_name[tmp->get_command()].str,
+                               command_name[tmp->get_command()].length, cs);
       /* MYSQL_TIME */
       table->field[5]->store((longlong)(tmp->start_time ?
                                       now - tmp->start_time : 0), FALSE);

=== modified file 'storage/perfschema/CMakeLists.txt'
--- a/storage/perfschema/CMakeLists.txt	2010-04-19 12:26:29 +0000
+++ b/storage/perfschema/CMakeLists.txt	2010-05-07 10:08:23 +0000
@@ -33,6 +33,7 @@ SET(PERFSCHEMA_SOURCES ha_perfschema.h
   pfs_lock.h
   pfs_atomic.h
   pfs_server.h
+  pfs_setup_actor.h
   pfs_stat.h
   pfs_engine_table.h
   pfs_timer.h
@@ -56,6 +57,7 @@ SET(PERFSCHEMA_SOURCES ha_perfschema.h
   pfs_instr.cc
   pfs_instr_class.cc
   pfs_server.cc
+  pfs_setup_actor.cc
   pfs_engine_table.cc
   pfs_timer.cc
   table_all_instr.cc

=== modified file 'storage/perfschema/Makefile.am'
--- a/storage/perfschema/Makefile.am	2010-04-19 12:26:29 +0000
+++ b/storage/perfschema/Makefile.am	2010-05-07 10:08:23 +0000
@@ -44,7 +44,8 @@ noinst_HEADERS = ha_perfschema.h pfs_eng
 		table_events_waits_summary.h pfs_stat.h \
 		table_all_instr.h \
 		table_file_instances.h table_file_summary.h \
-		table_setup_objects.h pfs_lock.h pfs_atomic.h
+		table_setup_objects.h pfs_lock.h pfs_atomic.h \
+		pfs_setup_actor.h
 
 PSE_SOURCES = ha_perfschema.cc pfs_engine_table.cc pfs.cc pfs_server.cc \
 		pfs_global.cc pfs_instr_class.cc pfs_instr.cc \
@@ -57,7 +58,8 @@ PSE_SOURCES = ha_perfschema.cc pfs_engin
 		table_events_waits_summary.cc \
 		table_all_instr.cc \
 		table_file_instances.cc table_file_summary.cc \
-		table_setup_objects.cc pfs_atomic.cc pfs_check.cc
+		table_setup_objects.cc pfs_atomic.cc pfs_check.cc \
+		pfs_setup_actor.cc
 
 EXTRA_LIBRARIES = libperfschema.a
 noinst_LIBRARIES = @plugin_perfschema_static_target@

=== modified file 'storage/perfschema/pfs.cc'
--- a/storage/perfschema/pfs.cc	2010-04-19 12:26:29 +0000
+++ b/storage/perfschema/pfs.cc	2010-05-07 10:08:23 +0000
@@ -26,6 +26,7 @@
 #include "pfs_column_values.h"
 #include "pfs_timer.h"
 #include "pfs_events_waits.h"
+#include "pfs_setup_actor.h"
 
 /* Pending WL#4895 PERFORMANCE_SCHEMA Instrumenting Table IO */
 #undef HAVE_TABLE_WAIT
@@ -1065,6 +1066,134 @@ get_thread_v1(void)
   return reinterpret_cast<PSI_thread*> (pfs);
 }
 
+static void set_thread_user_v1(const char *user, int user_len)
+{
+  PFS_thread *pfs= my_pthread_getspecific_ptr(PFS_thread*, THR_PFS);
+
+  DBUG_ASSERT((user != NULL) || (user_len == 0));
+  DBUG_ASSERT(user_len >= 0);
+  DBUG_ASSERT((uint) user_len <= sizeof(pfs->m_username));
+
+  if (unlikely(pfs == NULL))
+    return;
+
+  pfs->m_lock.allocated_to_dirty();
+  if (user_len > 0)
+    memcpy(pfs->m_username, user, user_len);
+  pfs->m_username_length= user_len;
+
+  bool enabled= false;
+
+  if ((pfs->m_username_length > 0) && (pfs->m_hostname_length > 0))
+  {
+    /*
+      TODO: performance improvement.
+      Once performance_schema.USERS is exposed,
+      we can use PFS_user::m_enabled instead of looking up
+      SETUP_ACTORS every time.
+    */
+    lookup_setup_actor(pfs,
+                       pfs->m_username, pfs->m_username_length,
+                       pfs->m_hostname, pfs->m_hostname_length,
+                       &enabled);
+  }
+
+  pfs->m_enabled= enabled;
+
+  pfs->m_lock.dirty_to_allocated();
+}
+
+static void set_thread_host_v1(const char *host, int host_len)
+{
+  PFS_thread *pfs= my_pthread_getspecific_ptr(PFS_thread*, THR_PFS);
+
+  DBUG_ASSERT((host != NULL) || (host_len == 0));
+  DBUG_ASSERT(host_len >= 0);
+  DBUG_ASSERT((uint) host_len <= sizeof(pfs->m_hostname));
+
+  if (likely(pfs != NULL))
+  {
+    pfs->m_lock.allocated_to_dirty();
+    if (host_len > 0)
+      memcpy(pfs->m_hostname, host, host_len);
+    pfs->m_hostname_length= host_len;
+    pfs->m_lock.dirty_to_allocated();
+  }
+}
+
+static void set_thread_db_v1(const char* db, int db_len)
+{
+  PFS_thread *pfs= my_pthread_getspecific_ptr(PFS_thread*, THR_PFS);
+
+  DBUG_ASSERT((db != NULL) || (db_len == 0));
+  DBUG_ASSERT(db_len >= 0);
+  DBUG_ASSERT((uint) db_len <= sizeof(pfs->m_dbname));
+
+  if (likely(pfs != NULL))
+  {
+    pfs->m_lock.allocated_to_dirty();
+    if (db_len > 0)
+      memcpy(pfs->m_dbname, db, db_len);
+    pfs->m_dbname_length= db_len;
+    pfs->m_lock.dirty_to_allocated();
+  }
+}
+
+static void set_thread_command_v1(int command)
+{
+  PFS_thread *pfs= my_pthread_getspecific_ptr(PFS_thread*, THR_PFS);
+
+  DBUG_ASSERT(command >= 0);
+  DBUG_ASSERT(command <= (int) COM_END);
+
+  if (likely(pfs != NULL))
+  {
+    pfs->m_lock.allocated_to_dirty();
+    pfs->m_command= command;
+    pfs->m_lock.dirty_to_allocated();
+  }
+}
+
+static void set_thread_start_time_v1(time_t start_time)
+{
+  PFS_thread *pfs= my_pthread_getspecific_ptr(PFS_thread*, THR_PFS);
+
+  if (likely(pfs != NULL))
+  {
+    pfs->m_lock.allocated_to_dirty();
+    pfs->m_start_time= start_time;
+    pfs->m_lock.dirty_to_allocated();
+  }
+}
+
+static void set_thread_state_v1(const char* state)
+{
+  PFS_thread *pfs= my_pthread_getspecific_ptr(PFS_thread*, THR_PFS);
+
+  if (likely(pfs != NULL))
+  {
+    int state_len= state ? strlen(state) : 0;
+
+    pfs->m_lock.allocated_to_dirty();
+    pfs->m_processlist_state_ptr= state;
+    pfs->m_processlist_state_length= state_len;
+    pfs->m_lock.dirty_to_allocated();
+  }
+}
+
+static void set_thread_info_v1(const char* info, int info_len)
+{
+  PFS_thread *pfs= my_pthread_getspecific_ptr(PFS_thread*, THR_PFS);
+
+  if (likely(pfs != NULL))
+  {
+    pfs->m_lock.allocated_to_dirty();
+    pfs->m_processlist_info_ptr= info;
+    pfs->m_processlist_info_length= info_len;
+    pfs->m_lock.dirty_to_allocated();
+  }
+}
+
 static void set_thread_v1(PSI_thread* thread)
 {
   PFS_thread *pfs= reinterpret_cast<PFS_thread*> (thread);
@@ -2012,6 +2141,13 @@ PSI_v1 PFS_v1=
   new_thread_v1,
   set_thread_id_v1,
   get_thread_v1,
+  set_thread_user_v1,
+  set_thread_host_v1,
+  set_thread_db_v1,
+  set_thread_command_v1,
+  set_thread_start_time_v1,
+  set_thread_state_v1,
+  set_thread_info_v1,
   set_thread_v1,
   delete_current_thread_v1,
   delete_thread_v1,

=== modified file 'storage/perfschema/pfs_instr.cc'
--- a/storage/perfschema/pfs_instr.cc	2010-04-13 09:49:50 +0000
+++ b/storage/perfschema/pfs_instr.cc	2010-05-07 10:08:23 +0000
@@ -23,6 +23,7 @@
 #include "my_global.h"
 #include "sql_priv.h"
 #include "my_sys.h"
+#include "pfs.h"
 #include "pfs_stat.h"
 #include "pfs_instr.h"
 #include "pfs_global.h"
@@ -687,6 +688,12 @@ void destroy_cond(PFS_cond *pfs)
   pfs->m_lock.allocated_to_free();
 }
 
+PFS_thread* PFS_thread::get_current_thread()
+{
+  PFS_thread *pfs= my_pthread_getspecific_ptr(PFS_thread*, THR_PFS);
+  return pfs;
+}
+
 /**
   Create instrumentation for a thread instance.
   @param klass                        the thread class
@@ -730,6 +737,16 @@ PFS_thread* create_thread(PFS_thread_cla
             reset_single_stat_link(stat);
           pfs->m_filename_hash_pins= NULL;
           pfs->m_table_share_hash_pins= NULL;
+          pfs->m_setup_actor_hash_pins= NULL;
+
+          pfs->m_username_length= 0;
+          pfs->m_hostname_length= 0;
+          pfs->m_dbname_length= 0;
+          pfs->m_command= 0; /* FIXME: revise this */
+          pfs->m_start_time= 0;
+          pfs->m_processlist_state_length= 0;
+          pfs->m_processlist_info_length= 0;
+
           pfs->m_lock.dirty_to_allocated();
           return pfs;
         }

=== modified file 'storage/perfschema/pfs_instr.h'
--- a/storage/perfschema/pfs_instr.h	2010-04-19 12:26:29 +0000
+++ b/storage/perfschema/pfs_instr.h	2010-05-07 10:08:23 +0000
@@ -181,12 +181,16 @@ private:
 /** Instrumented thread implementation. @see PSI_thread. */
 struct PFS_thread
 {
+  static PFS_thread* get_current_thread(void);
+
   /** Internal lock. */
   pfs_lock m_lock;
   /** Pins for filename_hash. */
   LF_PINS *m_filename_hash_pins;
   /** Pins for table_share_hash. */
   LF_PINS *m_table_share_hash_pins;
+  /** Pins for setup_actor_hash. */
+  LF_PINS *m_setup_actor_hash_pins;
   /** Event ID counter */
   ulonglong m_event_id;
   /** Thread instrumentation flag. */
@@ -225,6 +229,19 @@ struct PFS_thread
     PERFORMANCE_SCHEMA.EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME.
   */
   PFS_single_stat_chain *m_instr_class_wait_stats;
+
+  char m_username[USERNAME_LENGTH];
+  uint m_username_length;
+  char m_hostname[HOSTNAME_LENGTH];
+  uint m_hostname_length;
+  char m_dbname[NAME_LEN];
+  uint m_dbname_length;
+  int m_command;
+  time_t m_start_time;
+  const char *m_processlist_state_ptr;
+  uint m_processlist_state_length;
+  const char *m_processlist_info_ptr;
+  uint m_processlist_info_length;
 };
 
 PFS_thread *sanitize_thread(PFS_thread *unsafe);

=== modified file 'storage/perfschema/pfs_lock.h'
--- a/storage/perfschema/pfs_lock.h	2010-04-19 12:26:29 +0000
+++ b/storage/perfschema/pfs_lock.h	2010-05-07 10:08:23 +0000
@@ -108,6 +108,17 @@ struct pfs_lock
   }
 
   /**
+    Execute an allocated to dirty transition.
+    This transition should be executed by the writer that owns the record,
+    before the record is modified.
+  */
+  void allocated_to_dirty(void)
+  {
+    DBUG_ASSERT(m_state == PFS_LOCK_ALLOCATED);
+    PFS_atomic::store_32(&m_state, PFS_LOCK_DIRTY);
+  }
+
+  /**
     Execute a dirty to allocated transition.
     This transition should be executed by the writer that owns the record,
     after the record is in a state ready to be read.

=== modified file 'storage/perfschema/pfs_server.h'
--- a/storage/perfschema/pfs_server.h	2010-04-19 12:26:29 +0000
+++ b/storage/perfschema/pfs_server.h	2010-05-07 10:08:23 +0000
@@ -66,6 +66,9 @@
 #ifndef PFS_WAITS_HISTORY_LONG_SIZE
   #define PFS_WAITS_HISTORY_LONG_SIZE 10000
 #endif
+#ifndef PFS_MAX_SETUP_ACTOR
+  #define PFS_MAX_SETUP_ACTOR 100
+#endif
 
 struct PFS_global_param
 {
@@ -85,6 +88,7 @@ struct PFS_global_param
   ulong m_file_handle_sizing;
   ulong m_events_waits_history_sizing;
   ulong m_events_waits_history_long_sizing;
+  ulong m_setup_actor_sizing;
 };
 
 extern PFS_global_param pfs_param;

=== added file 'storage/perfschema/pfs_setup_actor.cc'
--- a/storage/perfschema/pfs_setup_actor.cc	1970-01-01 00:00:00 +0000
+++ b/storage/perfschema/pfs_setup_actor.cc	2010-05-07 10:08:23 +0000
@@ -0,0 +1,325 @@
+/* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; version 2 of the License.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
+
+/**
+  @file storage/perfschema/pfs_setup_actor.cc
+  Performance schema setup actor (implementation).
+*/
+
+#include "my_global.h"
+#include "my_sys.h"
+#include "my_base.h"
+#include "pfs.h"
+#include "pfs_stat.h"
+#include "pfs_instr.h"
+#include "pfs_setup_actor.h"
+#include "pfs_global.h"
+
+/**
+  @addtogroup Performance_schema_buffers
+  @{
+*/
+
+ulong setup_actor_max;
+
+PFS_setup_actor *setup_actor_array= NULL;
+
+static LF_HASH setup_actor_hash;
+static bool setup_actor_hash_inited= false;
+
+/**
+  Initialize the setup actor buffers.
+  @param param                        sizing parameters
+  @return 0 on success
+*/
+int init_setup_actor(const PFS_global_param *param)
+{
+  setup_actor_max= param->m_setup_actor_sizing;
+
+  setup_actor_array= NULL;
+
+  if (setup_actor_max > 0)
+  {
+    setup_actor_array= PFS_MALLOC_ARRAY(setup_actor_max, PFS_setup_actor,
+                                         MYF(MY_ZEROFILL));
+    if (unlikely(setup_actor_array == NULL))
+      return 1;
+  }
+
+  return 0;
+}
+
+/** Cleanup all the setup actor buffers. */
+void cleanup_setup_actor(void)
+{
+  pfs_free(setup_actor_array);
+  setup_actor_array= NULL;
+  setup_actor_max= 0;
+}
+
+static uchar *setup_actor_hash_get_key(const uchar *entry, size_t *length,
+                                       my_bool)
+{
+  const PFS_setup_actor * const *typed_entry;
+  const PFS_setup_actor *setup_actor;
+  const void *result;
+  typed_entry= reinterpret_cast<const PFS_setup_actor* const *> (entry);
+  DBUG_ASSERT(typed_entry != NULL);
+  setup_actor= *typed_entry;
+  DBUG_ASSERT(setup_actor != NULL);
+  *length= setup_actor->m_key.m_key_length;
+  result= setup_actor->m_key.m_hash_key;
+  return const_cast<uchar*> (reinterpret_cast<const uchar*> (result));
+}
+
+/**
+  Initialize the setup actor hash.
+  @return 0 on success
+*/
+int init_setup_actor_hash(void)
+{
+  if (! setup_actor_hash_inited)
+  {
+    lf_hash_init(&setup_actor_hash, sizeof(PFS_setup_actor*), LF_HASH_UNIQUE,
+                 0, 0, setup_actor_hash_get_key, &my_charset_bin);
+    setup_actor_hash_inited= true;
+  }
+  return 0;
+}
+
+/** Cleanup the setup actor hash. */
+void cleanup_setup_actor_hash(void)
+{
+  if (setup_actor_hash_inited)
+  {
+    lf_hash_destroy(&setup_actor_hash);
+    setup_actor_hash_inited= false;
+  }
+}
+
+static LF_PINS* get_setup_actor_hash_pins(PFS_thread *thread)
+{
+  if (! setup_actor_hash_inited)
+    return NULL;
+  if (unlikely(thread->m_setup_actor_hash_pins == NULL))
+    thread->m_setup_actor_hash_pins= lf_hash_get_pins(&setup_actor_hash);
+  return thread->m_setup_actor_hash_pins;
+}
+
+static void set_setup_actor_key(PFS_setup_actor_key *key,
+                                const char *user, uint user_length,
+                                const char *host, uint host_length,
+                                const char *role, uint role_length)
+{
+  DBUG_ASSERT(user_length <= USERNAME_LENGTH);
+  DBUG_ASSERT(host_length <= HOSTNAME_LENGTH);
+
+  char *ptr= &key->m_hash_key[0];
+  memcpy(ptr, user, user_length);
+  ptr+= user_length;
+  ptr[0]= 0;
+  ptr++;
+  memcpy(ptr, host, host_length);
+  ptr+= host_length;
+  ptr[0]= 0;
+  ptr++;
+  memcpy(ptr, role, role_length);
+  ptr+= role_length;
+  ptr[0]= 0;
+  ptr++;
+  key->m_key_length= ptr - &key->m_hash_key[0];
+}
+
+int insert_setup_actor(const String *user, const String *host, const String *role)
+{
+  if (setup_actor_max == 0)
+    return HA_ERR_RECORD_FILE_FULL;
+
+  PFS_thread *thread= PFS_thread::get_current_thread();
+  if (unlikely(thread == NULL))
+    return HA_ERR_OUT_OF_MEM;
+
+  LF_PINS *pins= get_setup_actor_hash_pins(thread);
+  if (unlikely(pins == NULL))
+    return HA_ERR_OUT_OF_MEM;
+
+  /* user is not constant, just using it for noise on insert */
+  uint i= randomized_index(user, setup_actor_max);
+
+  /*
+    Pass 1: [random, setup_actor_max - 1]
+    Pass 2: [0, setup_actor_max - 1]
+  */
+  int pass;
+  for (pass= 1; pass <= 2; i=0, pass++)
+  {
+    PFS_setup_actor *pfs= setup_actor_array + i;
+    PFS_setup_actor *pfs_last= setup_actor_array + setup_actor_max;
+    for ( ; pfs < pfs_last; pfs++)
+    {
+      if (pfs->m_lock.is_free())
+      {
+        if (pfs->m_lock.free_to_dirty())
+        {
+          set_setup_actor_key(&pfs->m_key,
+                              user->ptr(), user->length(),
+                              host->ptr(), host->length(),
+                              role->ptr(), role->length());
+          pfs->m_username= &pfs->m_key.m_hash_key[0];
+          pfs->m_username_length= user->length();
+          pfs->m_hostname= pfs->m_username + pfs->m_username_length + 1;
+          pfs->m_hostname_length= host->length();
+          pfs->m_rolename= pfs->m_hostname + pfs->m_hostname_length + 1;
+          pfs->m_rolename_length= role->length();
+
+          int res;
+          res= lf_hash_insert(&setup_actor_hash, pins, &pfs);
+          if (likely(res == 0))
+          {
+            pfs->m_lock.dirty_to_allocated();
+            return 0;
+          }
+
+          pfs->m_lock.dirty_to_free();
+          if (res > 0)
+            return HA_ERR_FOUND_DUPP_KEY;
+          return HA_ERR_OUT_OF_MEM;
+        }
+      }
+    }
+  }
+
+  return HA_ERR_RECORD_FILE_FULL;
+}
+
+int delete_setup_actor(const String *user, const String *host, const String *role)
+{
+  PFS_thread *thread= PFS_thread::get_current_thread();
+  if (unlikely(thread == NULL))
+    return HA_ERR_OUT_OF_MEM;
+
+  LF_PINS* pins= get_setup_actor_hash_pins(thread);
+  if (unlikely(pins == NULL))
+    return HA_ERR_OUT_OF_MEM;
+
+  PFS_setup_actor_key key;
+  set_setup_actor_key(&key,
+                      user->ptr(), user->length(),
+                      host->ptr(), host->length(),
+                      role->ptr(), role->length());
+
+  PFS_setup_actor **entry;
+  entry= reinterpret_cast<PFS_setup_actor**>
+    (lf_hash_search(&setup_actor_hash, pins, key.m_hash_key, key.m_key_length));
+
+  if (entry && (entry != MY_ERRPTR))
+  {
+    PFS_setup_actor *pfs= *entry;
+    lf_hash_delete(&setup_actor_hash, pins, key.m_hash_key, key.m_key_length);
+    pfs->m_lock.allocated_to_free();
+  }
+
+  return 0;
+}
+
+int reset_setup_actor()
+{
+  PFS_thread *thread= PFS_thread::get_current_thread();
+  if (unlikely(thread == NULL))
+    return HA_ERR_OUT_OF_MEM;
+
+  LF_PINS* pins= get_setup_actor_hash_pins(thread);
+  if (unlikely(pins == NULL))
+    return HA_ERR_OUT_OF_MEM;
+
+  PFS_setup_actor *pfs= setup_actor_array;
+  PFS_setup_actor *pfs_last= setup_actor_array + setup_actor_max;
+
+  for ( ; pfs < pfs_last; pfs++)
+  {
+    if (pfs->m_lock.is_populated())
+    {
+      lf_hash_delete(&setup_actor_hash, pins,
+                     pfs->m_key.m_hash_key, pfs->m_key.m_key_length);
+      pfs->m_lock.allocated_to_free();
+    }
+  }
+
+  return 0;
+}
+
+long setup_actor_count()
+{
+  return setup_actor_hash.count;
+}
+
+/*
+  - '%' should be replaced by NULL in table SETUP_ACTOR
+  - add an ENABLED column to include/exclude patterns, more flexible
+  - the principle is similar to SETUP_OBJECTS
+*/
+void lookup_setup_actor(PFS_thread *thread,
+                        const char *user, uint user_length,
+                        const char *host, uint host_length,
+                        bool *enabled)
+{
+#ifdef PORTME
+  PFS_setup_actor_key key;
+  PFS_setup_actor **entry;
+  int i;
+
+  LF_PINS* pins= get_setup_actor_hash_pins(thread);
+  if (unlikely(pins == NULL))
+  {
+    *enabled= false;
+    return;
+  }
+
+  for (i= 1; i<=4; i++)
+  {
+    /*
+      WL#988 Roles is not implemented, so we do not have a role name.
+      Looking up "%" in SETUP_ACTORS.ROLE.
+    */
+    switch(i)
+    {
+    case 1:
+      set_setup_actor_key(&key, user, user_length, host, host_length, "%", 1);
+      break;
+    case 2:
+      set_setup_actor_key(&key, user, user_length, "%", 1, "%", 1);
+      break;
+    case 3:
+      set_setup_actor_key(&key, "%", 1, host, host_length, "%", 1);
+      break;
+    case 4:
+      set_setup_actor_key(&key, "%", 1, "%", 1, "%", 1);
+      break;
+    }
+    entry= reinterpret_cast<PFS_setup_actor**>
+      (lf_hash_search(&setup_actor_hash, pins, key.m_hash_key, key.m_key_length));
+
+    if (entry && (entry != MY_ERRPTR))
+    {
+      *enabled= true;
+      return;
+    }
+  }
+#endif
+  *enabled= false;
+  return;
+}
+
+/** @} */

=== added file 'storage/perfschema/pfs_setup_actor.h'
--- a/storage/perfschema/pfs_setup_actor.h	1970-01-01 00:00:00 +0000
+++ b/storage/perfschema/pfs_setup_actor.h	2010-05-07 10:08:23 +0000
@@ -0,0 +1,87 @@
+/* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; version 2 of the License.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
+
+#ifndef PFS_SETUP_ACTOR_H
+#define PFS_SETUP_ACTOR_H
+
+/**
+  @file storage/perfschema/pfs_setup_actor.h
+  Performance schema setup actors (declarations).
+*/
+
+#include "sql_string.h"
+#include "pfs_lock.h"
+#include "lf.h"
+
+struct PFS_global_param;
+
+/* WL#988 Roles Not implemented yet */
+#define ROLENAME_LENGTH 64
+
+/**
+  @addtogroup Performance_schema_buffers
+  @{
+*/
+
+struct PFS_setup_actor_key
+{
+  /**
+    Hash search key.
+    This has to be a string for LF_HASH,
+    the format is "<username><0x00><hostname><0x00><rolename><0x00>"
+  */
+  char m_hash_key[USERNAME_LENGTH + 1 + HOSTNAME_LENGTH + 1 + ROLENAME_LENGTH + 1];
+  uint m_key_length;
+};
+
+struct PFS_setup_actor
+{
+  /** Internal lock. */
+  pfs_lock m_lock;
+  PFS_setup_actor_key m_key;
+  const char *m_username;
+  uint m_username_length;
+  const char *m_hostname;
+  uint m_hostname_length;
+  const char *m_rolename;
+  uint m_rolename_length;
+};
+
+int init_setup_actor(const PFS_global_param *param);
+void cleanup_setup_actor(void);
+int init_setup_actor_hash(void);
+void cleanup_setup_actor_hash(void);
+
+int insert_setup_actor(const String *user, const String *host, const String *role);
+int delete_setup_actor(const String *user, const String *host, const String *role);
+int reset_setup_actor(void);
+long setup_actor_count(void);
+
+void lookup_setup_actor(PFS_thread *thread,
+                        const char *user, uint user_length,
+                        const char *host, uint host_length,
+                        bool *enabled);
+
+/* For iterators and show status. */
+
+extern ulong setup_actor_max;
+
+/* Exposing the data directly, for iterators. */
+
+extern PFS_setup_actor *setup_actor_array;
+
+/** @} */
+#endif
+

=== modified file 'storage/perfschema/unittest/stub_pfs_global.h'
--- a/storage/perfschema/unittest/stub_pfs_global.h	2010-01-12 01:47:27 +0000
+++ b/storage/perfschema/unittest/stub_pfs_global.h	2010-05-07 10:08:23 +0000
@@ -1,4 +1,4 @@
-/* Copyright (C) 2008-2009 Sun Microsystems, Inc
+/* Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -39,3 +39,7 @@ void pfs_free(void *)
 {
 }
 
+void pfs_print_error(const char *format, ...)
+{
+}
+


Attachment: [text/bzr-bundle] bzr/marc.alff@oracle.com-20100507100823-chmdl83td4z5dxai.bundle
Thread
bzr commit into mysql-next-mr branch (marc.alff:3141) WL#4674Marc Alff7 May