Bug #49021 Function st_mysql_sys_var::update should be able to return error code
Submitted: 24 Nov 2009 3:56 Modified: 6 Jan 2011 15:47
Reporter: Yuan WANG Email Updates:
Status: Verified Impact on me:
None 
Category:MySQL Server: Storage Engine API Severity:S4 (Feature request)
Version:5.1 OS:Any
Assigned to: CPU Architecture:Any

[24 Nov 2009 3:56] Yuan WANG
Description:
Currently st_mysql_sys_var::update returns void. However the server should not assume that update a variable will always succeed, so this function should return error code.

We are developing a storage engine, which use a system variable to submit commands to the engine. For example, if user said:

set ntse_command = "set test.TestTable.splitFactor = 70"

My engine will set the split factor of the btree index of table TestTable to 70. However this could fail. For example probably we can not acquired the table lock. 

So we hope that st_mysql_sys_var::update can return error code instead of void. 

How to repeat:
This is a feature request and can not be repeated
[24 Nov 2009 18:04] Davi Arnaut
I guess you are talking about sys_var_pluginvar::update. In 5.1, this function has a return type of bool (true for error) and a storage engine can set a specific error by calling handler::print_error and implementing the associated methods.
[24 Nov 2009 19:58] Sergei Golubchik
no, he's talking about mysql/plugin.h:

/*
  SYNOPSIS
    (*mysql_var_update_func)()
      thd               thread handle
      var               dynamic variable being altered
      var_ptr           pointer to dynamic variable
      save              pointer to temporary storage
   RETURN
     NONE
   
   This function should use the validated value stored in the temporary store
   and persist it in the provided pointer to the dynamic variable.
   For example, strings may require memory to be allocated.
*/
typedef void (*mysql_var_update_func)(MYSQL_THD thd,
                                      struct st_mysql_sys_var *var,
                                      void *var_ptr, const void *save);
[24 Nov 2009 20:00] Sergei Golubchik
The idea was that if check() signals a success update() is expected to succeed, it should not fail.

But I understand that it's difficult to achieve in all cases.

Still, you could try to move more checks into, eh, check() function. In particular, you can take a table lock there.
[25 Nov 2009 3:53] Yuan WANG
Will update() be called in all cases if check() succeeds? If I acquire table lock in check(), I definitely need a good place to release the lock in all cases.
[25 Nov 2009 8:26] Sergei Golubchik
No, and that's the problem. if more than one variable is assigned to in the same SET statement then update will be called only if all variables' checks will succeed. That is if one will do

  SET ntse_command = "set test.TestTable.splitFactor = 70", ft_boolean_syntax="foobar";

then your check() will succeed, ft_boolean_syntax's check() will fail and your update() won't be called.

But if you start a transaction from within your check() (and call trans_register_ha accordingly) you will be asked to commit or rollback it at the end, and in autocommit mode this will be the end of the statement. And you will be able to release your table lock.

So, the only case when you will *not* be able to release your table lock at once is - autocommit disabled or START TRANSACTION was issued, and one does SET for many variables at once, and a variable *after* yours in the list fails the check.

I personally think it's ok to not release table lock in this case - releasing locks in the middle of transaction breaks 2pl and users are used to the fact that locks taken in a transaction are only released at commit/rollback.