Bug #53696 Performance schema engine violates the PSEA API by calling my_error()

Submitted: 17 May 2010 11:07 Modified: 30 Dec 2010 18:54
Reporter: Konstantin Osipov (OCA) Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Server: Performance Schema Severity:S3 (Non-critical)
Version:5.6.99 OS:Any
Assigned to: Marc ALFF CPU Architecture:Any

[17 May 2010 11:07] Konstantin Osipov
Description:
The storage engine must not inject errors into the connection diagnostics stack unless so is requested by calling ha_print_error(). Performance schema, however, does it in a number of cases.
This leads to ugliness of special cases for performance schema.

How to repeat:
Inspect the code:
kostja@ibbur:~/work/trunk-runtime/storage/perfschema$ grep 'my_error' *
ha_perfschema.cc:    my_error(ER_WRONG_PERFSCHEMA_USAGE, MYF(0));
ha_perfschema.cc:    my_error(ER_WRONG_PERFSCHEMA_USAGE, MYF(0));
ha_perfschema.cc:  my_error(ER_WRONG_PERFSCHEMA_USAGE, MYF(0));
ha_perfschema.cc:  my_error(ER_WRONG_PERFSCHEMA_USAGE, MYF(0));
Binary file libperfschema.a matches
Binary file libperfschema_embedded.a matches
pfs_engine_table.cc:    my_error(ER_WRONG_NATIVE_TABLE_STRUCTURE, MYF(0),
pfs_engine_table.cc:    my_error(ER_WRONG_NATIVE_TABLE_STRUCTURE, MYF(0),
pfs_engine_table.cc:  my_error(ER_WRONG_PERFSCHEMA_USAGE, MYF(0));
table_setup_consumers.cc:        my_error(ER_WRONG_PERFSCHEMA_USAGE, MYF(0));
table_setup_instruments.cc:        my_error(ER_WRONG_PERFSCHEMA_USAGE, MYF(0));
table_setup_objects.cc:        my_error(ER_WRONG_PERFSCHEMA_USAGE, MYF(0));
table_setup_timers.cc:        my_error(ER_WRONG_PERFSCHEMA_USAGE, MYF(0));

Suggested fix:
Do not call my_error(), return a return code and inject the error
in ha_print_error() only.
[25 May 2010 9:04] Sveta Smirnova
Thank you for the report.

Verified as described.

Really ha_federated, myisam, innobase and ibmdb2i have such calls too.
[25 May 2010 9:15] Marc ALFF
Add csv and myisammrg to the list:

csv/ha_tina.cc:      my_error(ER_CHECK_NOT_IMPLEMENTED, MYF(0), "nullable columns");
federated/ha_federated.cc:  my_error(error_num, MYF(0), buf);
federated/ha_federated.cc:  my_error(error_num, MYF(0), error_buffer);
federated/ha_federated.cc:  my_error(retval, MYF(0), error_buffer);
federated/ha_federated.cc:    my_error(error_code, MYF(0), error_buffer);
federated/ha_federated.cc:    my_error(error_code, MYF(0), ER(error_code));
federated/ha_federated.cc:    my_error(ER_CONNECT_TO_FOREIGN_DATA_SOURCE, MYF(0), remote_error_buf);
federated/ha_federated.cc:    my_error(ER_FOREIGN_DATA_SOURCE_DOESNT_EXIST, MYF(0), sql_query.ptr());
ibmdb2i/db2i_charsetSupport.cc:    my_error(ER_OUTOFMEMORY, MYF(0), sizeof(IconvMap));
ibmdb2i/ha_ibmdb2i.cc:    my_error(ER_BLOB_USED_AS_KEY, MYF(0), "*unknown*");
innobase/handler/ha_innodb.cc:		my_error(ER_QUERY_INTERRUPTED, MYF(0));
innobase/handler/ha_innodb.cc:		my_error(ER_TOO_BIG_ROWSIZE, MYF(0),
innobase/handler/ha_innodb.cc:			my_error(EE_OUT_OF_FILERESOURCES,
innobase/handler/ha_innodb.cc:	my_error(ER_CHECK_NOT_IMPLEMENTED, MYF(0), "this functionality");
innobase/handler/ha_innodb.cc:			my_error(ER_WRONG_COLUMN_NAME, MYF(0),
innobase/handler/ha_innodb.cc:		my_error(ER_TABLE_EXISTS_ERROR, MYF(0), buf);
innobase/handler/ha_innodb.cc:		my_error(ER_TABLE_EXISTS_ERROR, MYF(0), to);
innobase/handler/ha_innodb.cc:		my_error(ER_QUERY_INTERRUPTED, MYF(0));
innobase/handler/ha_innodb.cc:				my_error(ER_BINLOG_STMT_MODE_AND_ROW_ENGINE, MYF(0),
innobase/handler/ha_innodb.cc:			my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0),
innobase/handler/handler0alter.cc:				my_error(HA_ERR_TABLE_EXIST, MYF(0),
innobase/handler/handler0alter.cc:				my_error(HA_ERR_TABLE_EXIST, MYF(0), tmp_name);
innobase/handler/handler0alter.cc:		my_error(HA_ERR_TO_BIG_ROW, MYF(0));
innobase/handler/handler0alter.cc:		my_error(ER_PRIMARY_CANT_HAVE_NULL, MYF(0));
innobase/handler/handler0alter.cc:			my_error(ER_REQUIRES_PRIMARY_KEY, MYF(0));
myisam/mi_info.c:  my_error(errcode, MYF(ME_NOREFRESH), file_name);
myisam/myisampack.c:    my_error(EE_OUTOFMEMORY,MYF(ME_BELL),sizeof(uint)*length*2);
myisammrg/ha_myisammrg.cc:    my_error(ER_ADMIN_WRONG_MRG_TABLE, MYF(0), parent_l->alias);
[25 May 2010 9:26] Marc ALFF
Based on the existing calls to my_error() that originates from other storage engines, I fail to see that a "special case" exists in the performance schema.

There is no functional bug either, the product behaves as expected.

Closing as not a bug.
[25 May 2010 16:02] Konstantin Osipov
Guys, (and girls) can you please read the code?

Innobase and MyISAM do not push the error from, say, delete_all_rows(), performance schema does. In fact, both these engines push error in rare special cases.

CSV and others are written by copy-paste programming and do not qualify as good examples.
[25 May 2010 16:07] Konstantin Osipov
So, please let me refine this:
The server assumes that no error comes from the engine in cursor calls:
 - delete_all_rows() (see the sql_truncate.cc code to verify)
 - rnd_first, rnd_next(), index_first(), index_next() (see records.cc code, that calls rr_print_error() explicitly after an error, and thus assumes there is no error on the stack to verify).
There may be others. The case in point is delete_all_rows(), which currently demands a special case in the fix for Bug#42643 (please see the latest patch attached to the bug report).
[25 May 2010 17:12] Sveta Smirnova
Konstantin,

thank you for the update. Set back to "Verified"
[25 May 2010 20:19] Konstantin Osipov
I don't see how errors can be ignored. The effect is that error may appear twice on the stack (i.e. the error list may contain duplicates).
[14 Jul 2010 1:06] Marc ALFF
Analysis:

Just found out today that there is a handler::get_error_message() method,
which can be used to customize error messages from a storage engine.

The fix should investigate how to use:
- return HA_ERR_XXX from the performance schema code,
  preferably for existing HA_ERR error codes.
- ha_perfschema::get_error_message()
[1 Dec 2010 12:07] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/125646

3158 Marc Alff	2010-12-01
      Bug#53696 Performance schema engine violates the PSEA API by calling my_error()
      
      This is a code cleanup.
      
      The implementation of a storage engine (subclasses of handler) is not supposed
      to call my_error() directly inside the engine implementation, 
      but only return error codes, and report errors later at the demand
      of the sql layer only (if needed), using handler::print_error().
      
      This fix removes misplaced calls to my_error(),
      and provide an implementation of print_error() instead.
      
      Given that the sql layer implementation of create table, ha_create_table(),
      does not use print_error() but returns ER_CANT_CREATE_TABLE directly,
      the return code for create table statements using the performance schema
      has changed to ER_CANT_CREATE_TABLE.
      
      Adjusted the test suite accordingly.
[1 Dec 2010 17:38] Christopher Powers
Patch approved.
[1 Dec 2010 18:51] Marc ALFF
Pushed into:
- mysql-5.5-bugteam
- mysql-trunk-bugfixing
[5 Dec 2010 12:43] Bugs System
Pushed into mysql-trunk 5.6.1 (revid:alexander.nozdrin@oracle.com-20101205122447-6x94l4fmslpbttxj) (version source revid:alexander.nozdrin@oracle.com-20101205122447-6x94l4fmslpbttxj) (merge vers: 5.6.1) (pib:23)
[11 Dec 2010 17:07] Paul DuBois
Code cleanup. No changelog entry needed.
[17 Dec 2010 12:52] Bugs System
Pushed into mysql-5.5 5.5.9 (revid:georgi.kodinov@oracle.com-20101217124733-p1ivu6higouawv8l) (version source revid:marc.alff@oracle.com-20101201180757-db5woxysu9kenfau) (merge vers: 5.5.8) (pib:24)

Portions of this website are copyright © 2001, 2002 The PHP Group

Page generated in 0.046 sec. using MySQL 8.4.7-u6-cloud

Timestamp references displayed by the system are UTC.
Content reproduced on this site is the property of the respective copyright holders.
It is not reviewed in advance by Oracle and does not necessarily represent the opinion of Oracle or any other party.