mysql_event_fill_row(THD *thd,
                     TABLE *table,
                     Event_parse_data *et,
                     sp_head *sp,
                     sql_mode_t sql_mode,
                     my_bool is_update)
{
  CHARSET_INFO *scs= system_charset_info;
  enum enum_events_table_field f_num;
  Field **fields= table->field;
  int rs= FALSE;

  DBUG_ENTER("mysql_event_fill_row");

  DBUG_PRINT("info", ("dbname=[%s]", et->dbname.str));
  DBUG_PRINT("info", ("name  =[%s]", et->name.str));

  DBUG_ASSERT(et->on_completion != Event_parse_data::ON_COMPLETION_DEFAULT);

  if (table->s->fields < ET_FIELD_COUNT)
  {
    /*
      Safety: this can only happen if someone started the server
      and then altered mysql.event.
    */
    my_error(ER_COL_COUNT_DOESNT_MATCH_CORRUPTED_V2, MYF(0),
             table->s->db.str, table->alias.c_ptr(),
             (int) ET_FIELD_COUNT, table->s->fields);
    DBUG_RETURN(TRUE);
  }

  if (fields[f_num= ET_FIELD_DEFINER]->
                              store(et->definer.str, et->definer.length, scs))
    goto err_truncate;

  if (fields[f_num= ET_FIELD_DB]->store(et->dbname.str, et->dbname.length, scs))
    goto err_truncate;

  if (fields[f_num= ET_FIELD_NAME]->store(et->name.str, et->name.length, scs))
    goto err_truncate;

  /* ON_COMPLETION field is NOT NULL thus not calling set_notnull()*/
  rs|= fields[ET_FIELD_ON_COMPLETION]->store((longlong)et->on_completion, TRUE);

  /*
    Set STATUS value unconditionally in case of CREATE EVENT.
    For ALTER EVENT set it only if value of this field was changed.
    Since STATUS field is NOT NULL call to set_notnull() is not needed.
  */
  if (!is_update || et->status_changed)
    rs|= fields[ET_FIELD_STATUS]->store((longlong)et->status, TRUE);
  rs|= fields[ET_FIELD_ORIGINATOR]->store((longlong)et->originator, TRUE);

  if (!is_update)
    rs|= fields[ET_FIELD_CREATED]->set_time();

  /*
    Change the SQL_MODE only if body was present in an ALTER EVENT and of course
    always during CREATE EVENT.
  */
  if (et->body_changed)
  {
    DBUG_ASSERT(sp->m_body.str);

    rs|= fields[ET_FIELD_SQL_MODE]->store((longlong)sql_mode, TRUE);

    if (fields[f_num= ET_FIELD_BODY]->store(sp->m_body.str,
                                            sp->m_body.length,
                                            scs))
    {
      goto err_truncate;
    }
  }

  if (et->expression)
  {
    const String *tz_name= thd->variables.time_zone->get_name();
    if (!is_update || !et->starts_null)
    {
      fields[ET_FIELD_TIME_ZONE]->set_notnull();
      rs|= fields[ET_FIELD_TIME_ZONE]->store(tz_name->ptr(), tz_name->length(),
                                             tz_name->charset());
    }

    fields[ET_FIELD_INTERVAL_EXPR]->set_notnull();
    rs|= fields[ET_FIELD_INTERVAL_EXPR]->store((longlong)et->expression, TRUE);

    fields[ET_FIELD_TRANSIENT_INTERVAL]->set_notnull();

    rs|= fields[ET_FIELD_TRANSIENT_INTERVAL]->
                            store(interval_type_to_name[et->interval].str,
                                  interval_type_to_name[et->interval].length,
                                  scs);

    fields[ET_FIELD_EXECUTE_AT]->set_null();

    if (!et->starts_null)
    {
      MYSQL_TIME time;
      my_tz_OFFSET0->gmt_sec_to_TIME(&time, et->starts);

      fields[ET_FIELD_STARTS]->set_notnull();
      fields[ET_FIELD_STARTS]->store_time(&time);
    }

    if (!et->ends_null)
    {
      MYSQL_TIME time;
      my_tz_OFFSET0->gmt_sec_to_TIME(&time, et->ends);

      fields[ET_FIELD_ENDS]->set_notnull();
      fields[ET_FIELD_ENDS]->store_time(&time);
    }
  }
  else if (et->execute_at)
  {
    const String *tz_name= thd->variables.time_zone->get_name();
    fields[ET_FIELD_TIME_ZONE]->set_notnull();
    rs|= fields[ET_FIELD_TIME_ZONE]->store(tz_name->ptr(), tz_name->length(),
                                           tz_name->charset());

    fields[ET_FIELD_INTERVAL_EXPR]->set_null();
    fields[ET_FIELD_TRANSIENT_INTERVAL]->set_null();
    fields[ET_FIELD_STARTS]->set_null();
    fields[ET_FIELD_ENDS]->set_null();

    MYSQL_TIME time;
    my_tz_OFFSET0->gmt_sec_to_TIME(&time, et->execute_at);

    fields[ET_FIELD_EXECUTE_AT]->set_notnull();
    fields[ET_FIELD_EXECUTE_AT]->store_time(&time);
  }
  else
  {
    DBUG_ASSERT(is_update);
    /*
      it is normal to be here when the action is update
      this is an error if the action is create. something is borked
    */
  }

  rs|= fields[ET_FIELD_MODIFIED]->set_time();

  if (et->comment.str)
  {
    if (fields[f_num= ET_FIELD_COMMENT]->
                          store(et->comment.str, et->comment.length, scs))
      goto err_truncate;
  }

  fields[ET_FIELD_CHARACTER_SET_CLIENT]->set_notnull();
  rs|= fields[ET_FIELD_CHARACTER_SET_CLIENT]->store(
    thd->variables.character_set_client->csname,
    strlen(thd->variables.character_set_client->csname),
    system_charset_info);

  fields[ET_FIELD_COLLATION_CONNECTION]->set_notnull();
  rs|= fields[ET_FIELD_COLLATION_CONNECTION]->store(
    thd->variables.collation_connection->name,
    strlen(thd->variables.collation_connection->name),
    system_charset_info);

  {
    CHARSET_INFO *db_cl= get_default_db_collation(thd, et->dbname.str);

    fields[ET_FIELD_DB_COLLATION]->set_notnull();
    rs|= fields[ET_FIELD_DB_COLLATION]->store(db_cl->name,
                                              strlen(db_cl->name),
                                              system_charset_info);
  }

  if (et->body_changed)
  {
    fields[ET_FIELD_BODY_UTF8]->set_notnull();
    rs|= fields[ET_FIELD_BODY_UTF8]->store(sp->m_body_utf8.str,
                                           sp->m_body_utf8.length,
                                           system_charset_info);
  }

  if (rs)
  {
    my_error(ER_EVENT_STORE_FAILED, MYF(0), fields[f_num]->field_name.str, rs);
    DBUG_RETURN(TRUE);
  }

  DBUG_RETURN(FALSE);

err_truncate:
  my_error(ER_EVENT_DATA_TOO_LONG, MYF(0), fields[f_num]->field_name.str);
  DBUG_RETURN(TRUE);
}