17 #define MYSQL_SERVER 1 
   20 #include "probes_mysql.h" 
   21 #include "ha_blackhole.h" 
   22 #include "sql_class.h"                           
   24 static bool is_slave_applier(THD *thd)
 
   26   return thd->system_thread == SYSTEM_THREAD_SLAVE_SQL ||
 
   27     thd->system_thread == SYSTEM_THREAD_SLAVE_WORKER;
 
   43 static HASH blackhole_open_tables;
 
   58 static const char *ha_blackhole_exts[] = {
 
   64   return ha_blackhole_exts;
 
   67 int ha_blackhole::open(
const char *
name, 
int mode, uint test_if_locked)
 
   69   DBUG_ENTER(
"ha_blackhole::open");
 
   71   if (!(share= get_share(name)))
 
   72     DBUG_RETURN(HA_ERR_OUT_OF_MEM);
 
   74   thr_lock_data_init(&share->lock, &lock, NULL);
 
   78 int ha_blackhole::close(
void)
 
   80   DBUG_ENTER(
"ha_blackhole::close");
 
   85 int ha_blackhole::create(
const char *name, 
TABLE *table_arg,
 
   88   DBUG_ENTER(
"ha_blackhole::create");
 
   98   DBUG_ENTER(
"ha_blackhole::truncate");
 
  102 const char *ha_blackhole::index_type(uint key_number)
 
  104   DBUG_ENTER(
"ha_blackhole::index_type");
 
  105   DBUG_RETURN((table_share->key_info[key_number].
flags & HA_FULLTEXT) ? 
 
  107               (table_share->key_info[key_number].
flags & HA_SPATIAL) ?
 
  109               (table_share->key_info[key_number].algorithm ==
 
  110                HA_KEY_ALG_RTREE) ? 
"RTREE" : 
"BTREE");
 
  113 int ha_blackhole::write_row(uchar * 
buf)
 
  115   DBUG_ENTER(
"ha_blackhole::write_row");
 
  116   DBUG_RETURN(table->next_number_field ? update_auto_increment() : 0);
 
  119 int ha_blackhole::update_row(
const uchar *old_data, uchar *new_data)
 
  121   DBUG_ENTER(
"ha_blackhole::update_row");
 
  123   if (is_slave_applier(thd) && thd->query() == NULL)
 
  125   DBUG_RETURN(HA_ERR_WRONG_COMMAND);
 
  128 int ha_blackhole::delete_row(
const uchar *buf)
 
  130   DBUG_ENTER(
"ha_blackhole::delete_row");
 
  132   if (is_slave_applier(thd) && thd->query() == NULL)
 
  134   DBUG_RETURN(HA_ERR_WRONG_COMMAND);
 
  139   DBUG_ENTER(
"ha_blackhole::rnd_init");
 
  147   DBUG_ENTER(
"ha_blackhole::rnd_next");
 
  148   MYSQL_READ_ROW_START(table_share->db.str, table_share->table_name.str,
 
  151   if (is_slave_applier(thd) && thd->query() == NULL)
 
  154     rc= HA_ERR_END_OF_FILE;
 
  155   MYSQL_READ_ROW_DONE(rc);
 
  156   table->status= rc ? STATUS_NOT_FOUND : 0;
 
  163   DBUG_ENTER(
"ha_blackhole::rnd_pos");
 
  164   MYSQL_READ_ROW_START(table_share->db.str, table_share->table_name.str,
 
  167   MYSQL_READ_ROW_DONE(0);
 
  172 void ha_blackhole::position(
const uchar *
record)
 
  174   DBUG_ENTER(
"ha_blackhole::position");
 
  180 int ha_blackhole::info(uint flag)
 
  182   DBUG_ENTER(
"ha_blackhole::info");
 
  185   if (flag & HA_STATUS_AUTO)
 
  186     stats.auto_increment_value= 1;
 
  190 int ha_blackhole::external_lock(THD *thd, 
int lock_type)
 
  192   DBUG_ENTER(
"ha_blackhole::external_lock");
 
  199                                          enum thr_lock_type lock_type)
 
  201   DBUG_ENTER(
"ha_blackhole::store_lock");
 
  202   if (lock_type != TL_IGNORE && lock.type == TL_UNLOCK)
 
  211     if ((lock_type >= TL_WRITE_CONCURRENT_INSERT &&
 
  212          lock_type <= TL_WRITE) && !thd_in_lock_tables(thd)
 
  213         && !thd_tablespace_op(thd))
 
  214       lock_type = TL_WRITE_ALLOW_WRITE;
 
  224     if (lock_type == TL_READ_NO_INSERT && !thd_in_lock_tables(thd))
 
  227     lock.type= lock_type;
 
  235                                  key_part_map keypart_map,
 
  236                              enum ha_rkey_function find_flag)
 
  239   DBUG_ENTER(
"ha_blackhole::index_read");
 
  240   MYSQL_INDEX_READ_ROW_START(table_share->db.str, table_share->table_name.str);
 
  242   if (is_slave_applier(thd) && thd->query() == NULL)
 
  245     rc= HA_ERR_END_OF_FILE;
 
  246   MYSQL_INDEX_READ_ROW_DONE(rc);
 
  247   table->status= rc ? STATUS_NOT_FOUND : 0;
 
  253                                  key_part_map keypart_map,
 
  254                                  enum ha_rkey_function find_flag)
 
  257   DBUG_ENTER(
"ha_blackhole::index_read_idx");
 
  258   MYSQL_INDEX_READ_ROW_START(table_share->db.str, table_share->table_name.str);
 
  260   if (is_slave_applier(thd) && thd->query() == NULL)
 
  263     rc= HA_ERR_END_OF_FILE;
 
  264   MYSQL_INDEX_READ_ROW_DONE(rc);
 
  265   table->status= rc ? STATUS_NOT_FOUND : 0;
 
  271                                       key_part_map keypart_map)
 
  274   DBUG_ENTER(
"ha_blackhole::index_read_last");
 
  275   MYSQL_INDEX_READ_ROW_START(table_share->db.str, table_share->table_name.str);
 
  277   if (is_slave_applier(thd) && thd->query() == NULL)
 
  280     rc= HA_ERR_END_OF_FILE;
 
  281   MYSQL_INDEX_READ_ROW_DONE(rc);
 
  282   table->status= rc ? STATUS_NOT_FOUND : 0;
 
  290   DBUG_ENTER(
"ha_blackhole::index_next");
 
  291   MYSQL_INDEX_READ_ROW_START(table_share->db.str, table_share->table_name.str);
 
  292   rc= HA_ERR_END_OF_FILE;
 
  293   MYSQL_INDEX_READ_ROW_DONE(rc);
 
  294   table->status= STATUS_NOT_FOUND;
 
  302   DBUG_ENTER(
"ha_blackhole::index_prev");
 
  303   MYSQL_INDEX_READ_ROW_START(table_share->db.str, table_share->table_name.str);
 
  304   rc= HA_ERR_END_OF_FILE;
 
  305   MYSQL_INDEX_READ_ROW_DONE(rc);
 
  306   table->status= STATUS_NOT_FOUND;
 
  314   DBUG_ENTER(
"ha_blackhole::index_first");
 
  315   MYSQL_INDEX_READ_ROW_START(table_share->db.str, table_share->table_name.str);
 
  316   rc= HA_ERR_END_OF_FILE;
 
  317   MYSQL_INDEX_READ_ROW_DONE(rc);
 
  318   table->status= STATUS_NOT_FOUND;
 
  326   DBUG_ENTER(
"ha_blackhole::index_last");
 
  327   MYSQL_INDEX_READ_ROW_START(table_share->db.str, table_share->table_name.str);
 
  328   rc= HA_ERR_END_OF_FILE;
 
  329   MYSQL_INDEX_READ_ROW_DONE(rc);
 
  330   table->status= STATUS_NOT_FOUND;
 
  340   length= (uint) strlen(table_name);
 
  344         my_hash_search(&blackhole_open_tables,
 
  345                        (uchar*) table_name, length)))
 
  349                                                  MYF(MY_WME | MY_ZEROFILL))))
 
  352     share->table_name_length= length;
 
  353     strmov(share->table_name, table_name);
 
  355     if (my_hash_insert(&blackhole_open_tables, (uchar*) share))
 
  362     thr_lock_init(&share->lock);
 
  374   if (!--share->use_count)
 
  375     my_hash_delete(&blackhole_open_tables, (uchar*) share);
 
  381   thr_lock_delete(&share->lock);
 
  386                                 my_bool not_used __attribute__((unused)))
 
  388   *length= share->table_name_length;
 
  389   return (uchar*) share->table_name;
 
  392 #ifdef HAVE_PSI_INTERFACE 
  393 static PSI_mutex_key bh_key_mutex_blackhole;
 
  395 static PSI_mutex_info all_blackhole_mutexes[]=
 
  397   { &bh_key_mutex_blackhole, 
"blackhole", PSI_FLAG_GLOBAL}
 
  400 void init_blackhole_psi_keys()
 
  402   const char* category= 
"blackhole";
 
  405   count= array_elements(all_blackhole_mutexes);
 
  410 static int blackhole_init(
void *p)
 
  414 #ifdef HAVE_PSI_INTERFACE 
  415   init_blackhole_psi_keys();
 
  419   blackhole_hton->state= SHOW_OPTION_YES;
 
  420   blackhole_hton->db_type= DB_TYPE_BLACKHOLE_DB;
 
  421   blackhole_hton->create= blackhole_create_handler;
 
  422   blackhole_hton->flags= HTON_CAN_RECREATE;
 
  425                    &blackhole_mutex, MY_MUTEX_INIT_FAST);
 
  426   (void) my_hash_init(&blackhole_open_tables, system_charset_info,32,0,0,
 
  427                       (my_hash_get_key) blackhole_get_key,
 
  428                       (my_hash_free_key) blackhole_free_key, 0);
 
  433 static int blackhole_fini(
void *p)
 
  435   my_hash_free(&blackhole_open_tables);
 
  442 { MYSQL_HANDLERTON_INTERFACE_VERSION };
 
  444 mysql_declare_plugin(blackhole)
 
  446   MYSQL_STORAGE_ENGINE_PLUGIN,
 
  447   &blackhole_storage_engine,
 
  450   "/dev/null storage engine (anything you write to it disappears)",
 
  460 mysql_declare_plugin_end;