[MDEV-8644] Using a UDF in a virtual column causes a crash when stopping the server Created: 2015-08-18  Updated: 2015-12-08  Resolved: 2015-12-08

Status: Closed
Project: MariaDB Server
Component/s: Virtual Columns
Affects Version/s: 5.5, 10.0, 10.1
Fix Version/s: 5.5.47, 10.0.23, 10.1.10

Type: Bug Priority: Major
Reporter: Olivier Bertrand Assignee: Sergei Golubchik
Resolution: Fixed Votes: 0
Labels: UDF, Virtual

Attachments: File noconst.c     File udf_crash.log    

 Description   

Because MariaDB does not accept a constant virtual column (other DBMS's do) I was obliged to write the noconst UDF as:

/***********************************************************************/
/*  Returns its argument saying it is not a constant.                  */
/***********************************************************************/
my_bool noconst_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
{
	if (args->arg_count != 1 || args->arg_type[0] != STRING_RESULT) {
		strcpy(message, "noconst unique argument must be a string");
		return true;
	} // endif arg
 
	initid->const_item = false;    // The trick!
	return false;
} // end of noconst_init
 
char *noconst(UDF_INIT *initid, UDF_ARGS *args, char *result,
	unsigned long *res_length, char *, char *)
{
	return args->args[0];
} // end of noconst

Now, creating the table t1, inserting one line to it and displaying it does work:

MariaDB [test]> create table t1 (
    -> n int key not null auto_increment,
    -> msg char(20) as (noconst('Hello World')) virtual);
Query OK, 0 rows affected (0.06 sec)
 
MariaDB [test]> insert into t1() values();
Query OK, 1 row affected (0.01 sec)
 
MariaDB [test]> select * from t1;
+---+-------------+
| n | msg         |
+---+-------------+
| 1 | Hello World |
+---+-------------+
1 row in set (0.00 sec)

However, later on when stopping the server a crash occurs in the function:

void udf_handler::cleanup()
{
  if (!not_original)
  {
    if (initialized)
    {
      if (u_d->func_deinit != NULL)
      {
        Udf_func_deinit deinit= u_d->func_deinit;
        (*deinit)(&initid);
      }
      free_udf(u_d);
      initialized= FALSE;
    }
    if (buffers)				// Because of bug in ecc
      delete [] buffers;
    buffers= 0;
  }
}

See the attach udf_crash.log.
The same kind of crash occurs with different other UDF's.



 Comments   
Comment by Elena Stepanova [ 2015-08-18 ]

That's a surprise it works at all, documentation says UDFs are not allowed for virtual columns.

bertrandop,
Could you please attach the whole c file with your UDF function? It will be faster than me creating missing parts.

Comment by Olivier Bertrand [ 2015-08-18 ]

Done.

Comment by Elena Stepanova [ 2015-09-16 ]

Stack trace from 5.5 commit 29ac245dd04c5416d57a90b0ab3c4d08cbc4d723

#3  <signal handler called>
#4  0x00000000008500ae in udf_handler::cleanup (this=0x7f11c2875968) at 5.5/sql/item_func.cc:3454
#5  0x00000000008514e0 in Item_udf_func::cleanup (this=0x7f11c28758a0) at 5.5/sql/item_func.cc:3766
#6  0x00000000006073a1 in Item::delete_self (this=0x7f11c28758a0) at 5.5/sql/item.h:1434
#7  0x000000000060162f in Query_arena::free_items (this=0x7f11c2874bf8) at 5.5/sql/sql_class.cc:3164
#8  0x00000000006fcf32 in closefrm (table=0x7f11c2828e60, free_share=true) at 5.5/sql/table.cc:2773
#9  0x00000000005d4378 in intern_close_table (table=0x7f11c2828e60) at 5.5/sql/sql_base.cc:929
#10 0x00000000005d43e5 in free_cache_entry (table=0x7f11c2828e60) at 5.5/sql/sql_base.cc:952
#11 0x00000000005d4763 in close_cached_tables (thd=0x0, tables=0x0, wait_for_refresh=false, timeout=31536000) at 5.5/sql/sql_base.cc:1059
#12 0x00000000005d3111 in table_def_start_shutdown () at 5.5/sql/sql_base.cc:410
#13 0x0000000000586faf in clean_up (print_message=true) at 5.5/sql/mysqld.cc:1822
#14 0x0000000000586d9e in unireg_end () at 5.5/sql/mysqld.cc:1735
#15 0x0000000000586cc0 in kill_server (sig_ptr=0x0) at 5.5/sql/mysqld.cc:1663
#16 0x0000000000586cdd in kill_server_thread (arg=0x7f11ed3b9e98) at 5.5/sql/mysqld.cc:1686
#17 0x00007f11ecfaab50 in start_thread (arg=<optimized out>) at pthread_create.c:304
#18 0x00007f11eb26095d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:112

Comment by Sergei Golubchik [ 2015-12-06 ]

I cannot repeat this. elenst, could you please show a complete test case?

Comment by Elena Stepanova [ 2015-12-06 ]

I do the following:

  • build the attached noconst.c as g++ -shared -o noconst.so noconst.c -I/home/elenst/git/5.5/sql -I/home/elenst/git/5.5/include
  • start the debug server with noconst.so in the plugin dir;
  • run

    CREATE FUNCTION noconst RETURNS STRING SONAME 'noconst.so';
    create table t1 (n int key not null auto_increment,  msg char(11) as (noconst('Hello World')) virtual);
    insert into t1() values();
    select * from t1;

  • shutdown server;
    => observe the crash.

Reproducible on 5.5 commit 13ad179c96ee8c8c4043806b8575c851e3676f0d

-

Comment by Olivier Bertrand [ 2015-12-08 ]

Does this mean that UDFs are no more banned from virtual columns?
If so, it should be documented.

Comment by Sergei Golubchik [ 2015-12-08 ]

They were not banned, were they? If they were banned, one would not be able to create a virtual column with a UDF in the first place.

Comment by Elena Stepanova [ 2015-12-08 ]

serg, it was the point of my initial comment: the documentation says they cannot be used, while in fact they can.
I don't know whether they had ever been (or supposed to be) forbidden, or it is just a documentation mistake.

Generated at Thu Feb 08 07:28:42 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.