Uploaded image for project: 'MariaDB Server'
  1. MariaDB Server
  2. MDEV-8644

Using a UDF in a virtual column causes a crash when stopping the server

Details

    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.

      Attachments

        Activity

          bertrandop Olivier Bertrand created issue -
          bertrandop Olivier Bertrand made changes -
          Field Original Value New Value
          Description Because MariaDB does not accept a constant virtual column (other DBMS's do) I was obliged to write the noconst UDF as:
          {code}
          /***********************************************************************/
          /* 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) {
          strcpy(message, "noconst accepts only 1 argument");
          return true;
          } else if (args->arg_type[0] != STRING_RESULT) {
          strcpy(message, "noconst first argument must be a string");
          return true;
          } // endif arg

          initid->const_item = false;
          return false;
          } // end of noconst_init

          char *noconst(UDF_INIT *initid, UDF_ARGS *args, char *result,
          unsigned long *res_length, char *, char *)
          {
          *res_length = args->lengths[0];
          return args->args[0];
          } // end of noconst

          void noconst_deinit(UDF_INIT* initid)
          {
          } // end of noconst_deinit
          {code}
          No creating the table vjs, inserting one line to it and displaying it does work:
          {code}
          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)
          {code}
          However when stopping the server late on a crash occurs in the function:
          {code}
          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;
            }
          }
          {code}
          See the attach udf_crash.log
          Because MariaDB does not accept a constant virtual column (other DBMS's do) I was obliged to write the noconst UDF as:
          {code}
          /***********************************************************************/
          /* 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) {
          strcpy(message, "noconst accepts only 1 argument");
          return true;
          } else if (args->arg_type[0] != STRING_RESULT) {
          strcpy(message, "noconst first argument must be a string");
          return true;
          } // endif arg

          initid->const_item = false;
          return false;
          } // end of noconst_init

          char *noconst(UDF_INIT *initid, UDF_ARGS *args, char *result,
          unsigned long *res_length, char *, char *)
          {
          *res_length = args->lengths[0];
          return args->args[0];
          } // end of noconst

          void noconst_deinit(UDF_INIT* initid)
          {
          } // end of noconst_deinit
          {code}
          Now, creating the table t1, inserting one line to it and displaying it does work:
          {code}
          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)
          {code}
          However, later on when stopping the server a crash occurs in the function:
          {code}
          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;
            }
          }
          {code}
          See the attach udf_crash.log.
          The same kind of crash occurs with different other UDF's.
          bertrandop Olivier Bertrand made changes -
          Description Because MariaDB does not accept a constant virtual column (other DBMS's do) I was obliged to write the noconst UDF as:
          {code}
          /***********************************************************************/
          /* 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) {
          strcpy(message, "noconst accepts only 1 argument");
          return true;
          } else if (args->arg_type[0] != STRING_RESULT) {
          strcpy(message, "noconst first argument must be a string");
          return true;
          } // endif arg

          initid->const_item = false;
          return false;
          } // end of noconst_init

          char *noconst(UDF_INIT *initid, UDF_ARGS *args, char *result,
          unsigned long *res_length, char *, char *)
          {
          *res_length = args->lengths[0];
          return args->args[0];
          } // end of noconst

          void noconst_deinit(UDF_INIT* initid)
          {
          } // end of noconst_deinit
          {code}
          Now, creating the table t1, inserting one line to it and displaying it does work:
          {code}
          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)
          {code}
          However, later on when stopping the server a crash occurs in the function:
          {code}
          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;
            }
          }
          {code}
          See the attach udf_crash.log.
          The same kind of crash occurs with different other UDF's.
          Because MariaDB does not accept a constant virtual column (other DBMS's do) I was obliged to write the noconst UDF as:
          {code}
          /***********************************************************************/
          /* 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;
          return false;
          } // end of noconst_init

          char *noconst(UDF_INIT *initid, UDF_ARGS *args, char *result,
          unsigned long *res_length, char *, char *)
          {
          *res_length = args->lengths[0];
          return args->args[0];
          } // end of noconst
          {code}
          Now, creating the table t1, inserting one line to it and displaying it does work:
          {code}
          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)
          {code}
          However, later on when stopping the server a crash occurs in the function:
          {code}
          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;
            }
          }
          {code}
          See the attach udf_crash.log.
          The same kind of crash occurs with different other UDF's.
          bertrandop Olivier Bertrand made changes -
          Description Because MariaDB does not accept a constant virtual column (other DBMS's do) I was obliged to write the noconst UDF as:
          {code}
          /***********************************************************************/
          /* 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;
          return false;
          } // end of noconst_init

          char *noconst(UDF_INIT *initid, UDF_ARGS *args, char *result,
          unsigned long *res_length, char *, char *)
          {
          *res_length = args->lengths[0];
          return args->args[0];
          } // end of noconst
          {code}
          Now, creating the table t1, inserting one line to it and displaying it does work:
          {code}
          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)
          {code}
          However, later on when stopping the server a crash occurs in the function:
          {code}
          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;
            }
          }
          {code}
          See the attach udf_crash.log.
          The same kind of crash occurs with different other UDF's.
          Because MariaDB does not accept a constant virtual column (other DBMS's do) I was obliged to write the noconst UDF as:
          {code}
          /***********************************************************************/
          /* 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;
          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
          {code}
          Now, creating the table t1, inserting one line to it and displaying it does work:
          {code}
          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)
          {code}
          However, later on when stopping the server a crash occurs in the function:
          {code}
          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;
            }
          }
          {code}
          See the attach udf_crash.log.
          The same kind of crash occurs with different other UDF's.
          bertrandop Olivier Bertrand made changes -
          Description Because MariaDB does not accept a constant virtual column (other DBMS's do) I was obliged to write the noconst UDF as:
          {code}
          /***********************************************************************/
          /* 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;
          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
          {code}
          Now, creating the table t1, inserting one line to it and displaying it does work:
          {code}
          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)
          {code}
          However, later on when stopping the server a crash occurs in the function:
          {code}
          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;
            }
          }
          {code}
          See the attach udf_crash.log.
          The same kind of crash occurs with different other UDF's.
          Because MariaDB does not accept a constant virtual column (other DBMS's do) I was obliged to write the noconst UDF as:
          {code}
          /***********************************************************************/
          /* 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
          {code}
          Now, creating the table t1, inserting one line to it and displaying it does work:
          {code}
          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)
          {code}
          However, later on when stopping the server a crash occurs in the function:
          {code}
          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;
            }
          }
          {code}
          See the attach udf_crash.log.
          The same kind of crash occurs with different other UDF's.
          elenst Elena Stepanova made changes -
          Labels UDF Virtual UDF Virtual need_feedback
          bertrandop Olivier Bertrand made changes -
          Attachment noconst.c [ 39205 ]
          elenst Elena Stepanova made changes -
          Labels UDF Virtual need_feedback UDF Virtual
          elenst Elena Stepanova made changes -
          Status Open [ 1 ] Confirmed [ 10101 ]
          elenst Elena Stepanova made changes -
          Component/s OTHER [ 10125 ]
          Fix Version/s 10.1 [ 16100 ]
          Fix Version/s 10.0 [ 16000 ]
          Fix Version/s 5.5 [ 15800 ]
          Affects Version/s 10.1 [ 16100 ]
          Affects Version/s 10.0 [ 16000 ]
          Affects Version/s 5.5 [ 15800 ]
          Affects Version/s 10.1.5 [ 18813 ]
          Assignee Sergei Golubchik [ serg ]
          Environment Windows 7
          serg Sergei Golubchik made changes -
          Component/s OTHER [ 10125 ]
          serg Sergei Golubchik made changes -
          Summary Using an UDF in a virtual column causes a crash when stopping the server Using a UDF in a virtual column causes a crash when stopping the server
          serg Sergei Golubchik made changes -
          Status Confirmed [ 10101 ] In Progress [ 3 ]
          serg Sergei Golubchik made changes -
          Status In Progress [ 3 ] Stalled [ 10000 ]
          serg Sergei Golubchik made changes -
          Assignee Sergei Golubchik [ serg ] Elena Stepanova [ elenst ]
          elenst Elena Stepanova made changes -
          Assignee Elena Stepanova [ elenst ] Sergei Golubchik [ serg ]
          serg Sergei Golubchik made changes -
          Status Stalled [ 10000 ] In Progress [ 3 ]
          serg Sergei Golubchik made changes -
          Fix Version/s 5.5.47 [ 20300 ]
          Fix Version/s 10.0.23 [ 20401 ]
          Fix Version/s 10.1.10 [ 20402 ]
          Fix Version/s 5.5 [ 15800 ]
          Fix Version/s 10.0 [ 16000 ]
          Fix Version/s 10.1 [ 16100 ]
          Resolution Fixed [ 1 ]
          Status In Progress [ 3 ] Closed [ 6 ]
          serg Sergei Golubchik made changes -
          Workflow MariaDB v3 [ 71129 ] MariaDB v4 [ 149489 ]

          People

            serg Sergei Golubchik
            bertrandop Olivier Bertrand
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:

              Git Integration

                Error rendering 'com.xiplink.jira.git.jira_git_plugin:git-issue-webpanel'. Please contact your Jira administrators.