1 /*
2    Copyright (c) 2000, 2013, Oracle and/or its affiliates.
3    Copyright (c) 2009, 2013, Monty Program Ab.
4 
5    This program is free software; you can redistribute it and/or modify
6    it under the terms of the GNU General Public License as published by
7    the Free Software Foundation; version 2 of the License.
8 
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU General Public License for more details.
13 
14    You should have received a copy of the GNU General Public License
15    along with this program; if not, write to the Free Software
16    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335  USA */
17 
18 /* This file should be included when using myisam_funktions */
19 
20 #ifndef _myisam_h
21 #define _myisam_h
22 #ifdef	__cplusplus
23 extern "C" {
24 #endif
25 
26 #include <my_base.h>
27 #include <m_ctype.h>
28 #include "keycache.h"
29 #include "my_compare.h"
30 #include <myisamchk.h>
31 #include <mysql/plugin.h>
32 #include <my_check_opt.h>
33 /*
34   Limit max keys according to HA_MAX_POSSIBLE_KEY; See myisamchk.h for details
35 */
36 
37 #if MAX_INDEXES > HA_MAX_POSSIBLE_KEY
38 #define MI_MAX_KEY                  HA_MAX_POSSIBLE_KEY /* Max allowed keys */
39 #else
40 #define MI_MAX_KEY                  MAX_INDEXES         /* Max allowed keys */
41 #endif
42 
43 #define MI_MAX_POSSIBLE_KEY_BUFF    HA_MAX_POSSIBLE_KEY_BUFF
44 /*
45   The following defines can be increased if necessary.
46   But beware the dependency of MI_MAX_POSSIBLE_KEY_BUFF and MI_MAX_KEY_LENGTH.
47 */
48 #define MI_MAX_KEY_LENGTH           1000            /* Max length in bytes */
49 #define MI_MAX_KEY_SEG              16              /* Max segments for key */
50 
51 #define MI_NAME_IEXT	".MYI"
52 #define MI_NAME_DEXT	".MYD"
53 
54 /* Possible values for myisam_block_size (must be power of 2) */
55 #define MI_KEY_BLOCK_LENGTH	1024	/* default key block length */
56 #define MI_MIN_KEY_BLOCK_LENGTH	1024	/* Min key block length */
57 #define MI_MAX_KEY_BLOCK_LENGTH	16384
58 
59 /*
60   In the following macros '_keyno_' is 0 .. keys-1.
61   If there can be more keys than bits in the key_map, the highest bit
62   is for all upper keys. They cannot be switched individually.
63   This means that clearing of high keys is ignored, setting one high key
64   sets all high keys.
65 */
66 #define MI_KEYMAP_BITS      (8 * SIZEOF_LONG_LONG)
67 #define MI_KEYMAP_HIGH_MASK (1ULL << (MI_KEYMAP_BITS - 1))
68 #define mi_get_mask_all_keys_active(_keys_) \
69                             (((_keys_) < MI_KEYMAP_BITS) ? \
70                              ((1ULL << (_keys_)) - 1ULL) : \
71                              (~ 0ULL))
72 
73 #if MI_MAX_KEY > MI_KEYMAP_BITS
74 
75 #define mi_is_key_active(_keymap_,_keyno_) \
76                             (((_keyno_) < MI_KEYMAP_BITS) ? \
77                              MY_TEST((_keymap_) & (1ULL << (_keyno_))) : \
78                              MY_TEST((_keymap_) & MI_KEYMAP_HIGH_MASK))
79 #define mi_set_key_active(_keymap_,_keyno_) \
80                             (_keymap_)|= (((_keyno_) < MI_KEYMAP_BITS) ? \
81                                           (1ULL << (_keyno_)) : \
82                                           MI_KEYMAP_HIGH_MASK)
83 #define mi_clear_key_active(_keymap_,_keyno_) \
84                             (_keymap_)&= (((_keyno_) < MI_KEYMAP_BITS) ? \
85                                           (~ (1ULL << (_keyno_))) : \
86                                           (~ (0ULL)) /*ignore*/ )
87 
88 #else
89 
90 #define mi_is_key_active(_keymap_,_keyno_) \
91                             MY_TEST((_keymap_) & (1ULL << (_keyno_)))
92 #define mi_set_key_active(_keymap_,_keyno_) \
93                             (_keymap_)|= (1ULL << (_keyno_))
94 #define mi_clear_key_active(_keymap_,_keyno_) \
95                             (_keymap_)&= (~ (1ULL << (_keyno_)))
96 
97 #endif
98 
99 #define mi_is_any_key_active(_keymap_) \
100                             MY_TEST((_keymap_))
101 #define mi_is_all_keys_active(_keymap_,_keys_) \
102                             ((_keymap_) == mi_get_mask_all_keys_active(_keys_))
103 #define mi_set_all_keys_active(_keymap_,_keys_) \
104                             (_keymap_)= mi_get_mask_all_keys_active(_keys_)
105 #define mi_clear_all_keys_active(_keymap_) \
106                             (_keymap_)= 0
107 #define mi_intersect_keys_active(_to_,_from_) \
108                             (_to_)&= (_from_)
109 #define mi_is_any_intersect_keys_active(_keymap1_,_keys_,_keymap2_) \
110                             ((_keymap1_) & (_keymap2_) & \
111                              mi_get_mask_all_keys_active(_keys_))
112 #define mi_copy_keys_active(_to_,_maxkeys_,_from_) \
113                             (_to_)= (mi_get_mask_all_keys_active(_maxkeys_) & \
114                                      (_from_))
115 
116 	/* Param to/from mi_info */
117 
118 typedef struct st_mi_isaminfo		/* Struct from h_info */
119 {
120   ha_rows records;			/* Records in database */
121   ha_rows deleted;			/* Deleted records in database */
122   my_off_t recpos;			/* Pos for last used record */
123   my_off_t newrecpos;			/* Pos if we write new record */
124   my_off_t dupp_key_pos;		/* Position to record with dupp key */
125   my_off_t data_file_length,		/* Length of data file */
126            max_data_file_length,
127            index_file_length,
128            max_index_file_length,
129            delete_length;
130   ulong reclength;			/* Recordlength */
131   ulong mean_reclength;			/* Mean recordlength (if packed) */
132   ulonglong auto_increment;
133   ulonglong key_map;			/* Which keys are used */
134   char  *data_file_name, *index_file_name;
135   uint  keys;				/* Number of keys in use */
136   uint	options;			/* HA_OPTION_... used */
137   int	errkey,				/* With key was dupplicated on err */
138 	sortkey;			/* clustered by this key */
139   File	filenr;				/* (uniq) filenr for datafile */
140   time_t create_time;			/* When table was created */
141   time_t check_time;
142   time_t update_time;
143   uint  reflength;
144   ulong record_offset;
145   ulong *rec_per_key;			/* for sql optimizing */
146 } MI_ISAMINFO;
147 
148 
149 typedef struct st_mi_create_info
150 {
151   const char *index_file_name, *data_file_name;	/* If using symlinks */
152   ha_rows max_rows;
153   ha_rows reloc_rows;
154   ulonglong auto_increment;
155   ulonglong data_file_length;
156   ulonglong key_file_length;
157   uint old_options;
158   uint16 language;
159   my_bool with_auto_increment;
160 } MI_CREATE_INFO;
161 
162 struct st_myisam_info;			/* For referense */
163 struct st_mi_isam_share;
164 typedef struct st_myisam_info MI_INFO;
165 struct st_mi_s_param;
166 
167 typedef struct st_mi_keydef		/* Key definition with open & info */
168 {
169   struct st_mi_isam_share *share;       /* Pointer to base (set in mi_open) */
170   uint16 keysegs;			/* Number of key-segment */
171   uint16 flag;				/* NOSAME, PACK_USED */
172 
173   uint8  key_alg;			/* BTREE, RTREE */
174   uint16 block_length;			/* Length of keyblock (auto) */
175   uint16 underflow_block_length;	/* When to execute underflow */
176   uint16 keylength;			/* Tot length of keyparts (auto) */
177   uint16 minlength;			/* min length of (packed) key (auto) */
178   uint16 maxlength;			/* max length of (packed) key (auto) */
179   uint16 block_size_index;		/* block_size (auto) */
180   uint32 version;			/* For concurrent read/write */
181   uint32 ftkey_nr;                      /* full-text index number */
182 
183   HA_KEYSEG *seg,*end;
184   struct st_mysql_ftparser *parser;     /* Fulltext [pre]parser */
185   int (*bin_search)(struct st_myisam_info *info,struct st_mi_keydef *keyinfo,
186 		    uchar *page,uchar *key,
187 		    uint key_len,uint comp_flag,uchar * *ret_pos,
188 		    uchar *buff, my_bool *was_last_key);
189   uint (*get_key)(struct st_mi_keydef *keyinfo,uint nod_flag,uchar * *page,
190 		  uchar *key);
191   int (*pack_key)(struct st_mi_keydef *keyinfo,uint nod_flag,uchar *next_key,
192 		  uchar *org_key, uchar *prev_key, uchar *key,
193 		  struct st_mi_s_param *s_temp);
194   void (*store_key)(struct st_mi_keydef *keyinfo, uchar *key_pos,
195 		    struct st_mi_s_param *s_temp);
196   int (*ck_insert)(struct st_myisam_info *inf, uint k_nr, uchar *k, uint klen);
197   int (*ck_delete)(struct st_myisam_info *inf, uint k_nr, uchar *k, uint klen);
198 } MI_KEYDEF;
199 
200 
201 #define MI_UNIQUE_HASH_LENGTH	4
202 
203 typedef struct st_unique_def		/* Segment definition of unique */
204 {
205   uint16 keysegs;			/* Number of key-segment */
206   uchar key;				/* Mapped to which key */
207   uint8 null_are_equal;
208   HA_KEYSEG *seg,*end;
209 } MI_UNIQUEDEF;
210 
211 typedef struct st_mi_decode_tree	/* Decode huff-table */
212 {
213   uint16 *table;
214   uint	 quick_table_bits;
215   uchar	 *intervalls;
216 } MI_DECODE_TREE;
217 
218 
219 struct st_mi_bit_buff;
220 
221 /*
222   Note that null markers should always be first in a row !
223   When creating a column, one should only specify:
224   type, length, null_bit and null_pos
225 */
226 
227 typedef struct st_columndef		/* column information */
228 {
229   enum en_fieldtype type;
230   uint16 length;			/* length of field */
231   uint32 offset;			/* Offset to position in row */
232   uint8  null_bit;			/* If column may be 0 */
233   uint16 null_pos;			/* position for null marker */
234 
235 #ifndef NOT_PACKED_DATABASES
236   void (*unpack)(struct st_columndef *rec,struct st_mi_bit_buff *buff,
237 		 uchar *start,uchar *end);
238   enum en_fieldtype base_type;
239   uint space_length_bits,pack_type;
240   MI_DECODE_TREE *huff_tree;
241 #endif
242 } MI_COLUMNDEF;
243 
244 extern char * myisam_log_filename;		/* Name of logfile */
245 extern ulong myisam_block_size;
246 extern ulong myisam_concurrent_insert;
247 extern my_bool myisam_flush,myisam_delay_key_write,myisam_single_user;
248 extern my_off_t myisam_max_temp_length;
249 extern ulong myisam_data_pointer_size;
250 
251 /* usually used to check if a symlink points into the mysql data home */
252 /* which is normally forbidden                                        */
253 extern int (*myisam_test_invalid_symlink)(const char *filename);
254 extern ulonglong myisam_mmap_size, myisam_mmap_used;
255 extern mysql_mutex_t THR_LOCK_myisam_mmap;
256 
257 	/* Prototypes for myisam-functions */
258 
259 extern int mi_close(struct st_myisam_info *file);
260 extern int mi_delete(struct st_myisam_info *file,const uchar *buff);
261 extern struct st_myisam_info *mi_open(const char *name,int mode,
262 				      uint wait_if_locked);
263 extern int mi_panic(enum ha_panic_function function);
264 extern int mi_rfirst(struct st_myisam_info *file,uchar *buf,int inx);
265 extern int mi_rkey(MI_INFO *info, uchar *buf, int inx, const uchar *key,
266                    key_part_map keypart_map, enum ha_rkey_function search_flag);
267 extern int mi_rlast(struct st_myisam_info *file,uchar *buf,int inx);
268 extern int mi_rnext(struct st_myisam_info *file,uchar *buf,int inx);
269 extern int mi_rnext_same(struct st_myisam_info *info, uchar *buf);
270 extern int mi_rprev(struct st_myisam_info *file,uchar *buf,int inx);
271 extern int mi_rrnd(struct st_myisam_info *file,uchar *buf, my_off_t pos);
272 extern int mi_scan_init(struct st_myisam_info *file);
273 extern int mi_scan(struct st_myisam_info *file,uchar *buf);
274 extern int mi_rsame(struct st_myisam_info *file,uchar *record,int inx);
275 extern int mi_rsame_with_pos(struct st_myisam_info *file,uchar *record,
276 			     int inx, my_off_t pos);
277 extern int mi_update(struct st_myisam_info *file,const uchar *old,
278 		     const uchar *new_record);
279 extern int mi_write(struct st_myisam_info *file,const uchar *buff);
280 extern my_off_t mi_position(struct st_myisam_info *file);
281 extern int mi_status(struct st_myisam_info *info, MI_ISAMINFO *x, uint flag);
282 extern int mi_lock_database(struct st_myisam_info *file,int lock_type);
283 extern int mi_create(const char *name,uint keys,MI_KEYDEF *keydef,
284 		     uint columns, MI_COLUMNDEF *columndef,
285 		     uint uniques, MI_UNIQUEDEF *uniquedef,
286 		     MI_CREATE_INFO *create_info, uint flags);
287 extern int mi_delete_table(const char *name);
288 extern int mi_rename(const char *from, const char *to);
289 extern int mi_extra(struct st_myisam_info *file,
290 		    enum ha_extra_function function,
291 		    void *extra_arg);
292 extern int mi_reset(struct st_myisam_info *file);
293 extern ha_rows mi_records_in_range(MI_INFO *info,int inx,
294                                    key_range *min_key, key_range *max_key);
295 extern int mi_log(int activate_log);
296 extern int mi_is_changed(struct st_myisam_info *info);
297 extern int mi_delete_all_rows(struct st_myisam_info *info);
298 extern ulong _mi_calc_blob_length(uint length , const uchar *pos);
299 extern uint mi_get_pointer_length(ulonglong file_length, uint def);
300 extern int mi_make_backup_of_index(struct st_myisam_info *info,
301                                    time_t backup_time, myf flags);
302 #define myisam_max_key_length() HA_MAX_KEY_LENGTH
303 #define myisam_max_key_segments() HA_MAX_KEY_SEG
304 
305 #define MEMMAP_EXTRA_MARGIN     7       /* Write this as a suffix for mmap file */
306 /* this is used to pass to mysql_myisamchk_table */
307 
308 #define   MYISAMCHK_REPAIR 1  /* equivalent to myisamchk -r */
309 #define   MYISAMCHK_VERIFY 2  /* Verify, run repair if failure */
310 
311 typedef uint mi_bit_type;
312 
313 typedef struct st_mi_bit_buff
314 {                                       /* Used for packing of record */
315   mi_bit_type current_byte;
316   uint bits;
317   uchar *pos, *end, *blob_pos, *blob_end;
318   uint error;
319 } MI_BIT_BUFF;
320 
321 typedef struct st_sort_info
322 {
323   /* sync things */
324   mysql_mutex_t mutex;
325   mysql_cond_t  cond;
326   MI_INFO *info;
327   HA_CHECK *param;
328   uchar *buff;
329   SORT_KEY_BLOCKS *key_block, *key_block_end;
330   SORT_FT_BUF *ft_buf;
331   my_off_t filelength, dupp, buff_length;
332   ha_rows max_records;
333   uint current_key, total_keys;
334   volatile uint got_error;
335   uint threads_running;
336   myf myf_rw;
337   enum data_file_type new_data_file_type;
338 } MI_SORT_INFO;
339 
340 typedef struct st_mi_sort_param
341 {
342   pthread_t thr;
343   IO_CACHE read_cache, tempfile, tempfile_for_exceptions;
344   DYNAMIC_ARRAY buffpek;
345   MI_BIT_BUFF   bit_buff;               /* For parallel repair of packrec. */
346 
347   MI_KEYDEF *keyinfo;
348   MI_SORT_INFO *sort_info;
349   HA_KEYSEG *seg;
350   uchar **sort_keys;
351   uchar *rec_buff;
352   void *wordlist, *wordptr;
353   MEM_ROOT wordroot;
354   uchar *record;
355   MY_TMPDIR *tmpdir;
356 
357   /*
358     The next two are used to collect statistics, see update_key_parts for
359     description.
360   */
361   ulonglong unique[HA_MAX_KEY_SEG+1];
362   ulonglong notnull[HA_MAX_KEY_SEG+1];
363 
364   my_off_t pos,max_pos,filepos,start_recpos;
365   uint key, key_length,real_key_length;
366   uint maxbuffers, find_length;
367   ulonglong sortbuff_size;
368   ha_rows keys;
369   my_bool fix_datafile, master;
370   my_bool calc_checksum;                /* calculate table checksum */
371 
372   int (*key_cmp)(struct st_mi_sort_param *, const void *, const void *);
373   int (*key_read)(struct st_mi_sort_param *,void *);
374   int (*key_write)(struct st_mi_sort_param *, const void *);
375   void (*lock_in_memory)(HA_CHECK *);
376   int (*write_keys)(struct st_mi_sort_param *, uchar **,
377                     ulonglong , struct st_buffpek *, IO_CACHE *);
378   my_off_t (*read_to_buffer)(IO_CACHE *,struct st_buffpek *, uint);
379   int (*write_key)(struct st_mi_sort_param *, IO_CACHE *,uchar *,
380                    uint, ulonglong);
381 } MI_SORT_PARAM;
382 
383 /* functions in mi_check */
384 void myisamchk_init(HA_CHECK *param);
385 int chk_status(HA_CHECK *param, MI_INFO *info);
386 int chk_del(HA_CHECK *param, MI_INFO *info, ulonglong test_flag);
387 int chk_size(HA_CHECK *param, MI_INFO *info);
388 int chk_key(HA_CHECK *param, MI_INFO *info);
389 int chk_data_link(HA_CHECK *param, MI_INFO *info, my_bool extend);
390 int mi_repair(HA_CHECK *param, MI_INFO *info, char * name, int rep_quick);
391 int mi_sort_index(HA_CHECK *param, MI_INFO *info, char * name);
392 int mi_repair_by_sort(HA_CHECK *param, MI_INFO *info,
393 		      const char * name, int rep_quick);
394 int mi_repair_parallel(HA_CHECK *param, MI_INFO *info,
395 		      const char * name, int rep_quick);
396 int change_to_newfile(const char * filename, const char * old_ext,
397                       const char * new_ext, time_t backup_time, myf myflags);
398 int lock_file(HA_CHECK *param, File file, my_off_t start, int lock_type,
399 	      const char *filetype, const char *filename);
400 void lock_memory(HA_CHECK *param);
401 void update_auto_increment_key(HA_CHECK *param, MI_INFO *info,
402 			       my_bool repair);
403 int update_state_info(HA_CHECK *param, MI_INFO *info,uint update);
404 void update_key_parts(MI_KEYDEF *keyinfo, ulong *rec_per_key_part,
405                       ulonglong *unique, ulonglong *notnull,
406                       ulonglong records);
407 int filecopy(HA_CHECK *param, File to,File from,my_off_t start,
408 	     my_off_t length, const char *type);
409 int movepoint(MI_INFO *info,uchar *record,my_off_t oldpos,
410 	      my_off_t newpos, uint prot_key);
411 int write_data_suffix(MI_SORT_INFO *sort_info, my_bool fix_datafile);
412 int test_if_almost_full(MI_INFO *info);
413 int recreate_table(HA_CHECK *param, MI_INFO **org_info, char *filename);
414 void mi_disable_non_unique_index(MI_INFO *info, ha_rows rows);
415 my_bool mi_test_if_sort_rep(MI_INFO *info, ha_rows rows, ulonglong key_map,
416 			    my_bool force);
417 
418 int mi_init_bulk_insert(MI_INFO *info, size_t cache_size, ha_rows rows);
419 void mi_flush_bulk_insert(MI_INFO *info, uint inx);
420 int mi_end_bulk_insert(MI_INFO *info, my_bool abort);
421 int mi_assign_to_key_cache(MI_INFO *info, ulonglong key_map,
422 			   KEY_CACHE *key_cache);
423 void mi_change_key_cache(KEY_CACHE *old_key_cache,
424 			 KEY_CACHE *new_key_cache);
425 int mi_preload(MI_INFO *info, ulonglong key_map, my_bool ignore_leaves);
426 
427 int write_data_suffix(MI_SORT_INFO *sort_info, my_bool fix_datafile);
428 int flush_pending_blocks(MI_SORT_PARAM *param);
429 int sort_ft_buf_flush(MI_SORT_PARAM *sort_param);
430 int thr_write_keys(MI_SORT_PARAM *sort_param);
431 int sort_write_record(MI_SORT_PARAM *sort_param);
432 int _create_index_by_sort(MI_SORT_PARAM *info,my_bool no_messages, ulonglong);
433 my_bool mi_too_big_key_for_sort(MI_KEYDEF *key, ha_rows rows);
434 
435 #ifdef	__cplusplus
436 }
437 #endif
438 #endif
439