Bug #71641 table_setup_actors::update_row_values function is unnecessary.
Submitted: 9 Feb 2014 23:49 Modified: 1 Oct 2014 13:34
Reporter: 徹 赤松 Email Updates:
Status: Not a Bug Impact on me:
None 
Category:MySQL Server: Performance Schema Severity:S5 (Performance)
Version:5.7.3, 5.7.4 OS:Linux
Assigned to: Marc ALFF CPU Architecture:Any
Tags: performance_schema, table_setup_actors.cc, update_row_values

[9 Feb 2014 23:49] 徹 赤松
Description:
There are table_setup_actors::update_row_values function in mysqld version 5.7.3 storage/perfschema/table_setup_actors.cc.

   239  int table_setup_actors::update_row_values(TABLE *table,
   240                                            const unsigned char *old_buf,
   241                                            unsigned char *new_buf,
   242                                            Field **fields)
   243  {
   244    Field *f;
   245
   246    for (; (f= *fields) ; fields++)
   247    {
   248      if (bitmap_is_set(table->write_set, f->field_index))
   249      {
   250        switch(f->field_index)
   251        {
   252        case 0: /* HOST */
   253        case 1: /* USER */
   254        case 2: /* ROLE */
   255          return HA_ERR_WRONG_COMMAND;
   256          break;
   257        default:
   258          DBUG_ASSERT(false);
   259        }
   260      }
   261    }
   262
   263    return 0;
   264  }

 All fields cannot update, so is this function unnecessary? 

 If update_row_values function in unnecessary, function fefinition in storage/perfschema/table_setup_actors.h is not necessary. 

    72    virtual int update_row_values(TABLE *table,
    73                                  const unsigned char *old_buf,
    74                                  unsigned char *new_buf,
    75                                  Field **fields);

I am pleased if a reply is got. 

How to repeat:
mysql> select * from performance_schema.setup_actors;
+------+------+------+
| HOST | USER | ROLE |
+------+------+------+
| %    | %    | %    |
+------+------+------+
1 row in set (0.00 sec)

mysql> update performance_schema.setup_actors set HOST='localhost' where USER='%';
ERROR 1683 (HY000): Invalid performance_schema usage.
mysql> update performance_schema.setup_actors set USER='root' where HOST='%';
ERROR 1683 (HY000): Invalid performance_schema usage.
[26 Jun 2014 13:36] MySQL Verification Team
Hello!

Thank you for the report.
IMHO table_setup_actors::update_row_values function is kept in for futuristic requirements.

int table_setup_actors::update_row_values(TABLE *table,
                                          const unsigned char *old_buf,
                                          unsigned char *new_buf,
                                          Field **fields)
{
  Field *f;

  for (; (f= *fields) ; fields++)
  {
    if (bitmap_is_set(table->write_set, f->field_index))
    {
      switch(f->field_index)
      {
      case 0: /* HOST */
      case 1: /* USER */
      case 2: /* ROLE */
        return HA_ERR_WRONG_COMMAND; <---- this is what it returns currently
        break;
      default:
        DBUG_ASSERT(false);
      }
    }
  }

  return 0;
} 

Looking at the below case, it seems only DELETE/INSERT's are allowed against setup_actors.

mysql>
mysql> select * from performance_schema.setup_actors;
+------+------+------+
| HOST | USER | ROLE |
+------+------+------+
| %    | %    | %    |
+------+------+------+
1 row in set (0.00 sec)

mysql> update  performance_schema.setup_actors set HOST='localhost';
ERROR 1683 (HY000): Invalid performance_schema usage.
mysql>
mysql> DELETE FROM performance_schema.setup_actors;
Query OK, 1 row affected (0.00 sec)

mysql> INSERT INTO performance_schema.setup_actors (HOST,USER,ROLE) VALUES('localhost','joe','%');
Query OK, 1 row affected (0.00 sec)

mysql> INSERT INTO performance_schema.setup_actors (HOST,USER,ROLE) VALUES('%','sam','%');
Query OK, 1 row affected (0.00 sec)

mysql> select * from performance_schema.setup_actors;
+-----------+------+------+
| HOST      | USER | ROLE |
+-----------+------+------+
| localhost | joe  | %    |
| %         | sam  | %    |
+-----------+------+------+
2 rows in set (0.00 sec)
[26 Jun 2014 13:37] MySQL Verification Team
Also, see the doc request for this Bug #71956
[1 Oct 2014 13:34] Marc ALFF
The method table_setup_actors::update_row_values() has indeed only one
possible outcome, which is return HA_ERR_WRONG_COMMAND.

This function *is* necessary, because ha_perfschema::update_row() need
to execute something (assumption is that m_table->update_row is not NULL),
and even when preventing UPDATE with more restrictive security permissions,
this method can still be executed when users are not supposed to update tables, for example when --skip-grants is used, so an implementation is required.

I agree that table_setup_actors::update_row_values() could be simplified to 1 line, but this is not a functional bug by itself.
It is hardly a performance bug either, since this is an error path already.
This bug is about a possible code cleanup that has otherwise no impact.

For GA releases (up to 5.6), this is not desirable to change.

For the current release (5.7), table_setup_actors::update_row_values() in the current form is reserved for future use, so changing the code structure is not desirable a this point.

Thank you for the report and your attention to details.
While this specific bug report is closed with no code change,
I would like to emphasis that bug reports of this nature are welcome.