MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ha_example.cc
Go to the documentation of this file.
1 /* Copyright (c) 2004, 2012, Oracle and/or its affiliates. All rights reserved.
2 
3  This program is free software; you can redistribute it and/or modify
4  it under the terms of the GNU General Public License as published by
5  the Free Software Foundation; version 2 of the License.
6 
7  This program is distributed in the hope that it will be useful,
8  but WITHOUT ANY WARRANTY; without even the implied warranty of
9  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  GNU General Public License for more details.
11 
12  You should have received a copy of the GNU General Public License
13  along with this program; if not, write to the Free Software
14  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
15 
90 #include "sql_priv.h"
91 #include "sql_class.h" // MYSQL_HANDLERTON_INTERFACE_VERSION
92 #include "ha_example.h"
93 #include "probes_mysql.h"
94 #include "sql_plugin.h"
95 
96 static handler *example_create_handler(handlerton *hton,
98  MEM_ROOT *mem_root);
99 
100 handlerton *example_hton;
101 
102 /* Interface to mysqld, to check system tables supported by SE */
103 static const char* example_system_database();
104 static bool example_is_supported_system_table(const char *db,
105  const char *table_name,
106  bool is_sql_layer_system_table);
107 #ifdef HAVE_PSI_INTERFACE
108 static PSI_mutex_key ex_key_mutex_Example_share_mutex;
109 
110 static PSI_mutex_info all_example_mutexes[]=
111 {
112  { &ex_key_mutex_Example_share_mutex, "Example_share::mutex", 0}
113 };
114 
115 static void init_example_psi_keys()
116 {
117  const char* category= "example";
118  int count;
119 
120  count= array_elements(all_example_mutexes);
121  mysql_mutex_register(category, all_example_mutexes, count);
122 }
123 #endif
124 
125 Example_share::Example_share()
126 {
127  thr_lock_init(&lock);
128  mysql_mutex_init(ex_key_mutex_Example_share_mutex,
129  &mutex, MY_MUTEX_INIT_FAST);
130 }
131 
132 
133 static int example_init_func(void *p)
134 {
135  DBUG_ENTER("example_init_func");
136 
137 #ifdef HAVE_PSI_INTERFACE
138  init_example_psi_keys();
139 #endif
140 
141  example_hton= (handlerton *)p;
142  example_hton->state= SHOW_OPTION_YES;
143  example_hton->create= example_create_handler;
144  example_hton->flags= HTON_CAN_RECREATE;
145  example_hton->system_database= example_system_database;
146  example_hton->is_supported_system_table= example_is_supported_system_table;
147 
148  DBUG_RETURN(0);
149 }
150 
151 
160 Example_share *ha_example::get_share()
161 {
162  Example_share *tmp_share;
163 
164  DBUG_ENTER("ha_example::get_share()");
165 
167  if (!(tmp_share= static_cast<Example_share*>(get_ha_share_ptr())))
168  {
169  tmp_share= new Example_share;
170  if (!tmp_share)
171  goto err;
172 
173  set_ha_share_ptr(static_cast<Handler_share*>(tmp_share));
174  }
175 err:
177  DBUG_RETURN(tmp_share);
178 }
179 
180 
181 static handler* example_create_handler(handlerton *hton,
182  TABLE_SHARE *table,
183  MEM_ROOT *mem_root)
184 {
185  return new (mem_root) ha_example(hton, table);
186 }
187 
188 ha_example::ha_example(handlerton *hton, TABLE_SHARE *table_arg)
189  :handler(hton, table_arg)
190 {}
191 
192 
211 static const char *ha_example_exts[] = {
212  NullS
213 };
214 
215 const char **ha_example::bas_ext() const
216 {
217  return ha_example_exts;
218 }
219 
220 /*
221  Following handler function provides access to
222  system database specific to SE. This interface
223  is optional, so every SE need not implement it.
224 */
225 const char* ha_example_system_database= NULL;
226 const char* example_system_database()
227 {
228  return ha_example_system_database;
229 }
230 
231 /*
232  List of all system tables specific to the SE.
233  Array element would look like below,
234  { "<database_name>", "<system table name>" },
235  The last element MUST be,
236  { (const char*)NULL, (const char*)NULL }
237 
238  This array is optional, so every SE need not implement it.
239 */
240 static st_system_tablename ha_example_system_tables[]= {
241  {(const char*)NULL, (const char*)NULL}
242 };
243 
256 static bool example_is_supported_system_table(const char *db,
257  const char *table_name,
258  bool is_sql_layer_system_table)
259 {
260  st_system_tablename *systab;
261 
262  // Does this SE support "ALL" SQL layer system tables ?
263  if (is_sql_layer_system_table)
264  return false;
265 
266  // Check if this is SE layer system tables
267  systab= ha_example_system_tables;
268  while (systab && systab->db)
269  {
270  if (systab->db == db &&
271  strcmp(systab->tablename, table_name) == 0)
272  return true;
273  systab++;
274  }
275 
276  return false;
277 }
278 
279 
296 int ha_example::open(const char *name, int mode, uint test_if_locked)
297 {
298  DBUG_ENTER("ha_example::open");
299 
300  if (!(share = get_share()))
301  DBUG_RETURN(1);
302  thr_lock_data_init(&share->lock,&lock,NULL);
303 
304  DBUG_RETURN(0);
305 }
306 
307 
324 {
325  DBUG_ENTER("ha_example::close");
326  DBUG_RETURN(0);
327 }
328 
329 
361 {
362  DBUG_ENTER("ha_example::write_row");
363  /*
364  Example of a successful write_row. We don't store the data
365  anywhere; they are thrown away. A real implementation will
366  probably need to do something with 'buf'. We report a success
367  here, to pretend that the insert was successful.
368  */
369  DBUG_RETURN(0);
370 }
371 
372 
396 int ha_example::update_row(const uchar *old_data, uchar *new_data)
397 {
398 
399  DBUG_ENTER("ha_example::update_row");
400  DBUG_RETURN(HA_ERR_WRONG_COMMAND);
401 }
402 
403 
424 int ha_example::delete_row(const uchar *buf)
425 {
426  DBUG_ENTER("ha_example::delete_row");
427  DBUG_RETURN(HA_ERR_WRONG_COMMAND);
428 }
429 
430 
438 int ha_example::index_read_map(uchar *buf, const uchar *key,
439  key_part_map keypart_map __attribute__((unused)),
440  enum ha_rkey_function find_flag
441  __attribute__((unused)))
442 {
443  int rc;
444  DBUG_ENTER("ha_example::index_read");
445  MYSQL_INDEX_READ_ROW_START(table_share->db.str, table_share->table_name.str);
446  rc= HA_ERR_WRONG_COMMAND;
447  MYSQL_INDEX_READ_ROW_DONE(rc);
448  DBUG_RETURN(rc);
449 }
450 
451 
457 int ha_example::index_next(uchar *buf)
458 {
459  int rc;
460  DBUG_ENTER("ha_example::index_next");
461  MYSQL_INDEX_READ_ROW_START(table_share->db.str, table_share->table_name.str);
462  rc= HA_ERR_WRONG_COMMAND;
463  MYSQL_INDEX_READ_ROW_DONE(rc);
464  DBUG_RETURN(rc);
465 }
466 
467 
473 int ha_example::index_prev(uchar *buf)
474 {
475  int rc;
476  DBUG_ENTER("ha_example::index_prev");
477  MYSQL_INDEX_READ_ROW_START(table_share->db.str, table_share->table_name.str);
478  rc= HA_ERR_WRONG_COMMAND;
479  MYSQL_INDEX_READ_ROW_DONE(rc);
480  DBUG_RETURN(rc);
481 }
482 
483 
494 int ha_example::index_first(uchar *buf)
495 {
496  int rc;
497  DBUG_ENTER("ha_example::index_first");
498  MYSQL_INDEX_READ_ROW_START(table_share->db.str, table_share->table_name.str);
499  rc= HA_ERR_WRONG_COMMAND;
500  MYSQL_INDEX_READ_ROW_DONE(rc);
501  DBUG_RETURN(rc);
502 }
503 
504 
515 int ha_example::index_last(uchar *buf)
516 {
517  int rc;
518  DBUG_ENTER("ha_example::index_last");
519  MYSQL_INDEX_READ_ROW_START(table_share->db.str, table_share->table_name.str);
520  rc= HA_ERR_WRONG_COMMAND;
521  MYSQL_INDEX_READ_ROW_DONE(rc);
522  DBUG_RETURN(rc);
523 }
524 
525 
539 int ha_example::rnd_init(bool scan)
540 {
541  DBUG_ENTER("ha_example::rnd_init");
542  DBUG_RETURN(0);
543 }
544 
545 int ha_example::rnd_end()
546 {
547  DBUG_ENTER("ha_example::rnd_end");
548  DBUG_RETURN(0);
549 }
550 
551 
566 int ha_example::rnd_next(uchar *buf)
567 {
568  int rc;
569  DBUG_ENTER("ha_example::rnd_next");
570  MYSQL_READ_ROW_START(table_share->db.str, table_share->table_name.str,
571  TRUE);
572  rc= HA_ERR_END_OF_FILE;
573  MYSQL_READ_ROW_DONE(rc);
574  DBUG_RETURN(rc);
575 }
576 
577 
599 void ha_example::position(const uchar *record)
600 {
601  DBUG_ENTER("ha_example::position");
602  DBUG_VOID_RETURN;
603 }
604 
605 
619 int ha_example::rnd_pos(uchar *buf, uchar *pos)
620 {
621  int rc;
622  DBUG_ENTER("ha_example::rnd_pos");
623  MYSQL_READ_ROW_START(table_share->db.str, table_share->table_name.str,
624  TRUE);
625  rc= HA_ERR_WRONG_COMMAND;
626  MYSQL_READ_ROW_DONE(rc);
627  DBUG_RETURN(rc);
628 }
629 
630 
669 int ha_example::info(uint flag)
670 {
671  DBUG_ENTER("ha_example::info");
672  DBUG_RETURN(0);
673 }
674 
675 
685 int ha_example::extra(enum ha_extra_function operation)
686 {
687  DBUG_ENTER("ha_example::extra");
688  DBUG_RETURN(0);
689 }
690 
691 
712 {
713  DBUG_ENTER("ha_example::delete_all_rows");
714  DBUG_RETURN(HA_ERR_WRONG_COMMAND);
715 }
716 
717 
735 {
736  DBUG_ENTER("ha_example::truncate");
737  DBUG_RETURN(HA_ERR_WRONG_COMMAND);
738 }
739 
740 
758 int ha_example::external_lock(THD *thd, int lock_type)
759 {
760  DBUG_ENTER("ha_example::external_lock");
761  DBUG_RETURN(0);
762 }
763 
764 
803  THR_LOCK_DATA **to,
804  enum thr_lock_type lock_type)
805 {
806  if (lock_type != TL_IGNORE && lock.type == TL_UNLOCK)
807  lock.type=lock_type;
808  *to++= &lock;
809  return to;
810 }
811 
812 
833 {
834  DBUG_ENTER("ha_example::delete_table");
835  /* This is not implemented but we want someone to be able that it works. */
836  DBUG_RETURN(0);
837 }
838 
839 
854 int ha_example::rename_table(const char * from, const char * to)
855 {
856  DBUG_ENTER("ha_example::rename_table ");
857  DBUG_RETURN(HA_ERR_WRONG_COMMAND);
858 }
859 
860 
874 ha_rows ha_example::records_in_range(uint inx, key_range *min_key,
875  key_range *max_key)
876 {
877  DBUG_ENTER("ha_example::records_in_range");
878  DBUG_RETURN(10); // low number to force index usage
879 }
880 
881 
901 int ha_example::create(const char *name, TABLE *table_arg,
902  HA_CREATE_INFO *create_info)
903 {
904  DBUG_ENTER("ha_example::create");
905  /*
906  This is not implemented but we want someone to be able to see that it
907  works.
908  */
909  DBUG_RETURN(0);
910 }
911 
912 
913 struct st_mysql_storage_engine example_storage_engine=
914 { MYSQL_HANDLERTON_INTERFACE_VERSION };
915 
916 static ulong srv_enum_var= 0;
917 static ulong srv_ulong_var= 0;
918 static double srv_double_var= 0;
919 
920 const char *enum_var_names[]=
921 {
922  "e1", "e2", NullS
923 };
924 
925 TYPELIB enum_var_typelib=
926 {
927  array_elements(enum_var_names) - 1, "enum_var_typelib",
928  enum_var_names, NULL
929 };
930 
931 static MYSQL_SYSVAR_ENUM(
932  enum_var, // name
933  srv_enum_var, // varname
934  PLUGIN_VAR_RQCMDARG, // opt
935  "Sample ENUM system variable.", // comment
936  NULL, // check
937  NULL, // update
938  0, // def
939  &enum_var_typelib); // typelib
940 
941 static MYSQL_SYSVAR_ULONG(
942  ulong_var,
943  srv_ulong_var,
944  PLUGIN_VAR_RQCMDARG,
945  "0..1000",
946  NULL,
947  NULL,
948  8,
949  0,
950  1000,
951  0);
952 
953 static MYSQL_SYSVAR_DOUBLE(
954  double_var,
955  srv_double_var,
956  PLUGIN_VAR_RQCMDARG,
957  "0.500000..1000.500000",
958  NULL,
959  NULL,
960  8.5,
961  0.5,
962  1000.5,
963  0); // reserved always 0
964 
965 static MYSQL_THDVAR_DOUBLE(
966  double_thdvar,
967  PLUGIN_VAR_RQCMDARG,
968  "0.500000..1000.500000",
969  NULL,
970  NULL,
971  8.5,
972  0.5,
973  1000.5,
974  0);
975 
976 static struct st_mysql_sys_var* example_system_variables[]= {
977  MYSQL_SYSVAR(enum_var),
978  MYSQL_SYSVAR(ulong_var),
979  MYSQL_SYSVAR(double_var),
980  MYSQL_SYSVAR(double_thdvar),
981  NULL
982 };
983 
984 // this is an example of SHOW_FUNC and of my_snprintf() service
985 static int show_func_example(MYSQL_THD thd, struct st_mysql_show_var *var,
986  char *buf)
987 {
988  var->type= SHOW_CHAR;
989  var->value= buf; // it's of SHOW_VAR_FUNC_BUFF_SIZE bytes
990  my_snprintf(buf, SHOW_VAR_FUNC_BUFF_SIZE,
991  "enum_var is %lu, ulong_var is %lu, "
992  "double_var is %f, %.6b", // %b is a MySQL extension
993  srv_enum_var, srv_ulong_var, srv_double_var, "really");
994  return 0;
995 }
996 
997 static struct st_mysql_show_var func_status[]=
998 {
999  {"example_func_example", (char *)show_func_example, SHOW_FUNC},
1000  {0,0,SHOW_UNDEF}
1001 };
1002 
1003 mysql_declare_plugin(example)
1004 {
1005  MYSQL_STORAGE_ENGINE_PLUGIN,
1006  &example_storage_engine,
1007  "EXAMPLE",
1008  "Brian Aker, MySQL AB",
1009  "Example storage engine",
1010  PLUGIN_LICENSE_GPL,
1011  example_init_func, /* Plugin Init */
1012  NULL, /* Plugin Deinit */
1013  0x0001 /* 0.1 */,
1014  func_status, /* status variables */
1015  example_system_variables, /* system variables */
1016  NULL, /* config options */
1017  0, /* flags */
1018 }
1019 mysql_declare_plugin_end;