1 /*
2    Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
3 
4    This program is free software; you can redistribute it and/or modify
5    it under the terms of the GNU General Public License, version 2.0,
6    as published by the Free Software Foundation.
7 
8    This program is also distributed with certain software (including
9    but not limited to OpenSSL) that is licensed under separate terms,
10    as designated in a particular file or component or in included license
11    documentation.  The authors of MySQL hereby grant you an additional
12    permission to link the program and your derivative works with the
13    separately licensed software that they have included with MySQL.
14 
15    This program is distributed in the hope that it will be useful,
16    but WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18    GNU General Public License, version 2.0, for more details.
19 
20    You should have received a copy of the GNU General Public License
21    along with this program; if not, write to the Free Software
22    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA */
23 
24 
25 /* class for the the myisam merge handler */
26 
27 #include <myisammrg.h>
28 
29 /**
30   Represents one name of a MERGE child.
31 
32   @todo: Add MYRG_SHARE and store chlidren names in the
33   share.
34 */
35 
36 class Mrg_child_def: public Sql_alloc
37 {
38   /* Remembered MERGE child def version.  See top comment in ha_myisammrg.cc */
39   enum_table_ref_type m_child_table_ref_type;
40   ulonglong m_child_def_version;
41 public:
42   LEX_STRING db;
43   LEX_STRING name;
44 
45   /* Access MERGE child def version.  See top comment in ha_myisammrg.cc */
get_child_table_ref_type()46   inline enum_table_ref_type get_child_table_ref_type()
47   {
48     return m_child_table_ref_type;
49   }
get_child_def_version()50   inline ulonglong get_child_def_version()
51   {
52     return m_child_def_version;
53   }
set_child_def_version(enum_table_ref_type child_table_ref_type,ulonglong version)54   inline void set_child_def_version(enum_table_ref_type child_table_ref_type,
55                                     ulonglong version)
56   {
57     m_child_table_ref_type= child_table_ref_type;
58     m_child_def_version= version;
59   }
60 
Mrg_child_def(char * db_arg,size_t db_len_arg,char * table_name_arg,size_t table_name_len_arg)61   Mrg_child_def(char *db_arg, size_t db_len_arg,
62                 char *table_name_arg, size_t table_name_len_arg)
63   {
64     db.str= db_arg;
65     db.length= db_len_arg;
66     name.str= table_name_arg;
67     name.length= table_name_len_arg;
68     m_child_def_version= ~0ULL;
69     m_child_table_ref_type= TABLE_REF_NULL;
70   }
71 };
72 
73 
74 class ha_myisammrg: public handler
75 {
76   MYRG_INFO *file;
77   my_bool is_cloned;                    /* This instance has been cloned */
78 
79 public:
80   MEM_ROOT      children_mem_root;      /* mem root for children list */
81   List<Mrg_child_def> child_def_list;
82   TABLE_LIST    *children_l;            /* children list */
83   TABLE_LIST    **children_last_l;      /* children list end */
84   uint          test_if_locked;         /* flags from ::open() */
85 
86   ha_myisammrg(handlerton *hton, TABLE_SHARE *table_arg);
87   ~ha_myisammrg();
table_type()88   const char *table_type() const { return "MRG_MyISAM"; }
89   const char **bas_ext() const;
90   const char *index_type(uint key_number);
table_flags()91   ulonglong table_flags() const
92   {
93     return (HA_REC_NOT_IN_SEQ | HA_AUTO_PART_KEY | HA_NO_TRANSACTIONS |
94             HA_BINLOG_ROW_CAPABLE | HA_BINLOG_STMT_CAPABLE |
95 	    HA_NULL_IN_KEY | HA_CAN_INDEX_BLOBS | HA_FILE_BASED |
96             HA_ANY_INDEX_MAY_BE_UNIQUE | HA_CAN_BIT_FIELD |
97             HA_HAS_RECORDS |
98             HA_NO_COPY_ON_ALTER |
99             HA_DUPLICATE_POS);
100   }
index_flags(uint inx,uint part,bool all_parts)101   ulong index_flags(uint inx, uint part, bool all_parts) const
102   {
103     return ((table_share->key_info[inx].algorithm == HA_KEY_ALG_FULLTEXT) ?
104             0 : HA_READ_NEXT | HA_READ_PREV | HA_READ_RANGE |
105             HA_READ_ORDER | HA_KEYREAD_ONLY);
106   }
max_supported_keys()107   uint max_supported_keys()          const { return MI_MAX_KEY; }
max_supported_key_length()108   uint max_supported_key_length()    const { return MI_MAX_KEY_LENGTH; }
max_supported_key_part_length()109   uint max_supported_key_part_length() const { return MI_MAX_KEY_LENGTH; }
scan_time()110   double scan_time()
111   { return ulonglong2double(stats.data_file_length) / IO_SIZE + file->tables; }
112 
113   int open(const char *name, int mode, uint test_if_locked);
114   int add_children_list(void);
115   int attach_children(void);
116   int detach_children(void);
117   virtual handler *clone(const char *name, MEM_ROOT *mem_root);
118   int close(void);
119   int write_row(uchar * buf);
120   int update_row(const uchar * old_data, uchar * new_data);
121   int delete_row(const uchar * buf);
122   int index_read_map(uchar *buf, const uchar *key, key_part_map keypart_map,
123                      enum ha_rkey_function find_flag);
124   int index_read_idx_map(uchar *buf, uint index, const uchar *key,
125                          key_part_map keypart_map,
126                          enum ha_rkey_function find_flag);
127   int index_read_last_map(uchar *buf, const uchar *key, key_part_map keypart_map);
128   int index_next(uchar * buf);
129   int index_prev(uchar * buf);
130   int index_first(uchar * buf);
131   int index_last(uchar * buf);
132   int index_next_same(uchar *buf, const uchar *key, uint keylen);
133   int rnd_init(bool scan);
134   int rnd_next(uchar *buf);
135   int rnd_pos(uchar * buf, uchar *pos);
136   void position(const uchar *record);
137   ha_rows records_in_range(uint inx, key_range *min_key, key_range *max_key);
138   int truncate();
139   int info(uint);
140   int reset(void);
141   int extra(enum ha_extra_function operation);
142   int extra_opt(enum ha_extra_function operation, ulong cache_size);
143   int external_lock(THD *thd, int lock_type);
144   uint lock_count(void) const;
145   int create(const char *name, TABLE *form, HA_CREATE_INFO *create_info);
146   THR_LOCK_DATA **store_lock(THD *thd, THR_LOCK_DATA **to,
147 			     enum thr_lock_type lock_type);
148   void update_create_info(HA_CREATE_INFO *create_info);
149   void append_create_info(String *packet);
myrg_info()150   MYRG_INFO *myrg_info() { return file; }
table_ptr()151   TABLE *table_ptr() { return table; }
152   bool check_if_incompatible_data(HA_CREATE_INFO *info, uint table_changes);
153   int check(THD* thd, HA_CHECK_OPT* check_opt);
154   ha_rows records();
155 };
156