Drizzled Public API Documentation

myisam.h
00001 /* Copyright (C) 2000 MySQL AB
00002 
00003    This program is free software; you can redistribute it and/or modify
00004    it under the terms of the GNU General Public License as published by
00005    the Free Software Foundation; version 2 of the License.
00006 
00007    This program is distributed in the hope that it will be useful,
00008    but WITHOUT ANY WARRANTY; without even the implied warranty of
00009    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00010    GNU General Public License for more details.
00011 
00012    You should have received a copy of the GNU General Public License
00013    along with this program; if not, write to the Free Software
00014    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
00015 
00016 /* This file should be included when using myisam_funktions */
00017 
00018 #pragma once
00019 
00020 #include <drizzled/common_fwd.h>
00021 #include <drizzled/key_map.h>
00022 #include <drizzled/base.h>
00023 #include <plugin/myisam/my_handler.h>
00024 #include <drizzled/internal/iocache.h>
00025 
00026 /*
00027   Limit max keys according to HA_MAX_POSSIBLE_KEY
00028 */
00029 
00030 #if MAX_INDEXES > HA_MAX_POSSIBLE_KEY
00031 #define MI_MAX_KEY                  HA_MAX_POSSIBLE_KEY /* Max allowed keys */
00032 #else
00033 #define MI_MAX_KEY                  MAX_INDEXES         /* Max allowed keys */
00034 #endif
00035 
00036 /*
00037   The following defines can be increased if necessary.
00038   But beware the dependency of MI_MAX_POSSIBLE_KEY_BUFF and MI_MAX_KEY_LENGTH.
00039 */
00040 #define MI_MAX_KEY_LENGTH           1332            /* Max length in bytes */
00041 #define MI_MAX_KEY_SEG              16              /* Max segments for key */
00042 
00043 #define MI_MAX_POSSIBLE_KEY_BUFF (MI_MAX_KEY_LENGTH + 6 + 6) /* For mi_check */
00044 
00045 #define MI_MAX_KEY_BUFF  (MI_MAX_KEY_LENGTH+MI_MAX_KEY_SEG*6+8+8)
00046 #define MI_MAX_MSG_BUF      1024 /* used in CHECK TABLE, REPAIR TABLE */
00047 #define MI_NAME_IEXT  ".MYI"
00048 #define MI_NAME_DEXT  ".MYD"
00049 /* Max extra space to use when sorting keys */
00050 #define MI_MAX_TEMP_LENGTH  2*1024L*1024L*1024L
00051 
00052 /* Possible values for myisam_block_size (must be power of 2) */
00053 #define MI_KEY_BLOCK_LENGTH 1024  /* default key block length */
00054 #define MI_MIN_KEY_BLOCK_LENGTH 1024  /* Min key block length */
00055 #define MI_MAX_KEY_BLOCK_LENGTH 16384
00056 
00057 /*
00058   In the following macros '_keyno_' is 0 .. keys-1.
00059   If there can be more keys than bits in the key_map, the highest bit
00060   is for all upper keys. They cannot be switched individually.
00061   This means that clearing of high keys is ignored, setting one high key
00062   sets all high keys.
00063 */
00064 #define MI_KEYMAP_BITS      (64)
00065 #define MI_KEYMAP_HIGH_MASK (1UL << (MI_KEYMAP_BITS - 1))
00066 #define mi_get_mask_all_keys_active(_keys_) \
00067                             (((_keys_) < MI_KEYMAP_BITS) ? \
00068                              ((1UL << (_keys_)) - 1UL) : \
00069                              (~ 0UL))
00070 
00071 #if MI_MAX_KEY > MI_KEYMAP_BITS
00072 
00073 #define mi_is_key_active(_keymap_,_keyno_) \
00074                             (((_keyno_) < MI_KEYMAP_BITS) ? \
00075                              test((_keymap_) & (1UL << (_keyno_))) : \
00076                              test((_keymap_) & MI_KEYMAP_HIGH_MASK))
00077 #define mi_set_key_active(_keymap_,_keyno_) \
00078                             (_keymap_)|= (((_keyno_) < MI_KEYMAP_BITS) ? \
00079                                           (1UL << (_keyno_)) : \
00080                                           MI_KEYMAP_HIGH_MASK)
00081 #define mi_clear_key_active(_keymap_,_keyno_) \
00082                             (_keymap_)&= (((_keyno_) < MI_KEYMAP_BITS) ? \
00083                                           (~ (1UL << (_keyno_))) : \
00084                                           (~ (0UL)) /*ignore*/ )
00085 
00086 #else
00087 
00088 #define mi_is_key_active(_keymap_,_keyno_) \
00089                             test((_keymap_) & (1UL << (_keyno_)))
00090 #define mi_set_key_active(_keymap_,_keyno_) \
00091                             (_keymap_)|= (1UL << (_keyno_))
00092 #define mi_clear_key_active(_keymap_,_keyno_) \
00093                             (_keymap_)&= (~ (1UL << (_keyno_)))
00094 
00095 #endif
00096 
00097 #define mi_is_any_key_active(_keymap_) \
00098                             test((_keymap_))
00099 #define mi_is_all_keys_active(_keymap_,_keys_) \
00100                             ((_keymap_) == mi_get_mask_all_keys_active(_keys_))
00101 #define mi_set_all_keys_active(_keymap_,_keys_) \
00102                             (_keymap_)= mi_get_mask_all_keys_active(_keys_)
00103 #define mi_clear_all_keys_active(_keymap_) \
00104                             (_keymap_)= 0
00105 #define mi_intersect_keys_active(_to_,_from_) \
00106                             (_to_)&= (_from_)
00107 #define mi_is_any_intersect_keys_active(_keymap1_,_keys_,_keymap2_) \
00108                             ((_keymap1_) & (_keymap2_) & \
00109                              mi_get_mask_all_keys_active(_keys_))
00110 #define mi_copy_keys_active(_to_,_maxkeys_,_from_) \
00111                             (_to_)= (mi_get_mask_all_keys_active(_maxkeys_) & \
00112                                      (_from_))
00113 
00114 typedef uint32_t ha_checksum;
00115 
00116   /* Param to/from mi_status */
00117 typedef struct st_mi_isaminfo   /* Struct from h_info */
00118 {
00119   drizzled::ha_rows records;      /* Records in database */
00120   drizzled::ha_rows deleted;      /* Deleted records in database */
00121   drizzled::internal::my_off_t recpos;      /* Pos for last used record */
00122   drizzled::internal::my_off_t newrecpos;     /* Pos if we write new record */
00123   drizzled::internal::my_off_t dupp_key_pos;    /* Position to record with dupp key */
00124   drizzled::internal::my_off_t data_file_length,    /* Length of data file */
00125            max_data_file_length,
00126            index_file_length,
00127            max_index_file_length,
00128            delete_length;
00129   ulong reclength;      /* Recordlength */
00130   ulong mean_reclength;     /* Mean recordlength (if packed) */
00131   uint64_t auto_increment;
00132   uint64_t key_map;     /* Which keys are used */
00133   char  *data_file_name, *index_file_name;
00134   uint32_t  keys;       /* Number of keys in use */
00135   uint  options;      /* HA_OPTION_... used */
00136   int errkey,       /* With key was dupplicated on err */
00137   sortkey;      /* clustered by this key */
00138   int filenr;       /* (uniq) filenr for datafile */
00139   time_t create_time;     /* When table was created */
00140   time_t check_time;
00141   time_t update_time;
00142   uint32_t  reflength;
00143   ulong record_offset;
00144   ulong *rec_per_key;     /* for sql optimizing */
00145 } MI_ISAMINFO;
00146 
00147 
00148 typedef struct st_mi_create_info
00149 {
00150   const char *index_file_name, *data_file_name; /* If using symlinks */
00151   drizzled::ha_rows max_rows;
00152   drizzled::ha_rows reloc_rows;
00153   uint64_t auto_increment;
00154   uint64_t data_file_length;
00155   uint64_t key_file_length;
00156   uint32_t old_options;
00157   uint8_t language;
00158   bool with_auto_increment;
00159 
00160   st_mi_create_info():
00161     index_file_name(0),
00162     data_file_name(0),
00163     max_rows(0),
00164     reloc_rows(0),
00165     auto_increment(0),
00166     data_file_length(0),
00167     key_file_length(0),
00168     old_options(0),
00169     language(0),
00170     with_auto_increment(0)
00171   { }
00172 
00173 } MI_CREATE_INFO;
00174 
00175 struct st_myisam_info;      /* For referense */
00176 struct st_mi_isam_share;
00177 typedef struct st_myisam_info MI_INFO;
00178 struct st_mi_s_param;
00179 
00180 typedef struct st_mi_keydef   /* Key definition with open & info */
00181 {
00182   struct st_mi_isam_share *share;       /* Pointer to base (set in mi_open) */
00183   uint16_t keysegs;     /* Number of key-segment */
00184   uint16_t flag;        /* NOSAME, PACK_USED */
00185 
00186   uint8_t  key_alg;     /* BTREE, RTREE */
00187   uint16_t block_length;      /* Length of keyblock (auto) */
00188   uint16_t underflow_block_length;  /* When to execute underflow */
00189   uint16_t keylength;     /* Tot length of keyparts (auto) */
00190   uint16_t minlength;     /* min length of (packed) key (auto) */
00191   uint16_t maxlength;     /* max length of (packed) key (auto) */
00192   uint16_t block_size_index;    /* block_size (auto) */
00193   uint32_t version;     /* For concurrent read/write */
00194 
00195   HA_KEYSEG *seg,*end;
00196 
00197   int (*bin_search)(struct st_myisam_info *info,struct st_mi_keydef *keyinfo,
00198         unsigned char *page,unsigned char *key,
00199         uint32_t key_len,uint32_t comp_flag,unsigned char * *ret_pos,
00200         unsigned char *buff, bool *was_last_key);
00201   uint32_t (*get_key)(struct st_mi_keydef *keyinfo,uint32_t nod_flag,unsigned char * *page,
00202       unsigned char *key);
00203   int (*pack_key)(struct st_mi_keydef *keyinfo,uint32_t nod_flag,unsigned char *next_key,
00204       unsigned char *org_key, unsigned char *prev_key, unsigned char *key,
00205       struct st_mi_s_param *s_temp);
00206   void (*store_key)(struct st_mi_keydef *keyinfo, unsigned char *key_pos,
00207         struct st_mi_s_param *s_temp);
00208   int (*ck_insert)(struct st_myisam_info *inf, uint32_t k_nr, unsigned char *k, uint32_t klen);
00209   int (*ck_delete)(struct st_myisam_info *inf, uint32_t k_nr, unsigned char *k, uint32_t klen);
00210 } MI_KEYDEF;
00211 
00212 
00213 #define MI_UNIQUE_HASH_LENGTH 4
00214 
00215 typedef struct st_unique_def    /* Segment definition of unique */
00216 {
00217   uint16_t keysegs;     /* Number of key-segment */
00218   unsigned char key;        /* Mapped to which key */
00219   uint8_t null_are_equal;
00220   HA_KEYSEG *seg,*end;
00221 } MI_UNIQUEDEF;
00222 
00223 typedef struct st_mi_decode_tree  /* Decode huff-table */
00224 {
00225   uint16_t *table;
00226   uint   quick_table_bits;
00227   unsigned char  *intervalls;
00228 } MI_DECODE_TREE;
00229 
00230 
00231 struct st_mi_bit_buff;
00232 
00233 /*
00234   Note that null markers should always be first in a row !
00235   When creating a column, one should only specify:
00236   type, length, null_bit and null_pos
00237 */
00238 
00239 namespace drizzled
00240 {
00241 
00242 typedef struct st_columndef   /* column information */
00243 {
00244   int16_t  type;        /* en_fieldtype */
00245   uint16_t length;      /* length of field */
00246   uint32_t offset;      /* Offset to position in row */
00247   uint8_t  null_bit;      /* If column may be 0 */
00248   uint16_t null_pos;      /* position for null marker */
00249 
00250 #ifndef NOT_PACKED_DATABASES
00251   void (*unpack)(struct st_columndef *rec,struct st_mi_bit_buff *buff,
00252      unsigned char *start,unsigned char *end);
00253   enum drizzled::en_fieldtype base_type;
00254   uint32_t space_length_bits,pack_type;
00255   MI_DECODE_TREE *huff_tree;
00256 #endif
00257 } MI_COLUMNDEF;
00258 
00259 }
00260 
00261 
00262 extern char * myisam_log_filename;    /* Name of logfile */
00263 extern uint32_t myisam_block_size;
00264 extern uint32_t myisam_concurrent_insert;
00265 extern uint32_t myisam_bulk_insert_tree_size; 
00266 extern uint32_t data_pointer_size;
00267 
00268   /* Prototypes for myisam-functions */
00269 
00270 extern int mi_close(struct st_myisam_info *file);
00271 extern int mi_delete(struct st_myisam_info *file,const unsigned char *buff);
00272 extern struct st_myisam_info *mi_open(const drizzled::identifier::Table &identifier,
00273                                       int mode,
00274               uint32_t wait_if_locked);
00275 extern int mi_panic(enum drizzled::ha_panic_function function);
00276 extern int mi_rfirst(struct st_myisam_info *file,unsigned char *buf,int inx);
00277 extern int mi_rkey(MI_INFO *info, unsigned char *buf, int inx, const unsigned char *key,
00278                    drizzled::key_part_map keypart_map, enum drizzled::ha_rkey_function search_flag);
00279 extern int mi_rlast(struct st_myisam_info *file,unsigned char *buf,int inx);
00280 extern int mi_rnext(struct st_myisam_info *file,unsigned char *buf,int inx);
00281 extern int mi_rnext_same(struct st_myisam_info *info, unsigned char *buf);
00282 extern int mi_rprev(struct st_myisam_info *file,unsigned char *buf,int inx);
00283 extern int mi_rrnd(struct st_myisam_info *file,unsigned char *buf, drizzled::internal::my_off_t pos);
00284 extern int mi_scan_init(struct st_myisam_info *file);
00285 extern int mi_scan(struct st_myisam_info *file,unsigned char *buf);
00286 extern int mi_rsame(struct st_myisam_info *file,unsigned char *record,int inx);
00287 extern int mi_update(struct st_myisam_info *file,const unsigned char *old,
00288          unsigned char *new_record);
00289 extern int mi_write(struct st_myisam_info *file,unsigned char *buff);
00290 extern drizzled::internal::my_off_t mi_position(struct st_myisam_info *file);
00291 extern int mi_status(struct st_myisam_info *info, MI_ISAMINFO *x, uint32_t flag);
00292 extern int mi_lock_database(struct st_myisam_info *file,int lock_type);
00293 extern int mi_create(const char *name,uint32_t keys,MI_KEYDEF *keydef,
00294          uint32_t columns, drizzled::MI_COLUMNDEF *columndef,
00295          uint32_t uniques, MI_UNIQUEDEF *uniquedef,
00296          MI_CREATE_INFO *create_info, uint32_t flags);
00297 extern int mi_delete_table(const char *name);
00298 extern int mi_rename(const char *from, const char *to);
00299 extern int mi_extra(struct st_myisam_info *file,
00300         enum drizzled::ha_extra_function function,
00301         void *extra_arg);
00302 extern int mi_reset(struct st_myisam_info *file);
00303 extern drizzled::ha_rows mi_records_in_range(MI_INFO *info, int inx,
00304                                    drizzled::key_range *min_key, drizzled::key_range *max_key);
00305 extern int mi_log(int activate_log);
00306 extern int mi_delete_all_rows(struct st_myisam_info *info);
00307 extern ulong _mi_calc_blob_length(uint32_t length , const unsigned char *pos);
00308 extern uint32_t mi_get_pointer_length(uint64_t file_length, uint32_t def);
00309 
00310 /* this is used to pass to mysql_myisamchk_table */
00311 
00312 #define   MYISAMCHK_REPAIR 1  /* equivalent to myisamchk -r */
00313 #define   MYISAMCHK_VERIFY 2  /* Verify, run repair if failure */
00314 
00315 /*
00316   Definitions needed for myisamchk.c
00317 
00318   Entries marked as "QQ to be removed" are NOT used to
00319   pass check/repair options to mi_check.c. They are used
00320   internally by myisamchk.c or/and ha_myisam.cc and should NOT
00321   be stored together with other flags. They should be removed
00322   from the following list to make addition of new flags possible.
00323 */
00324 
00325 #define T_AUTO_INC              1
00326 #define T_AUTO_REPAIR           2              /* QQ to be removed */
00327 #define T_CALC_CHECKSUM         8
00328 #define T_CHECK                 16             /* QQ to be removed */
00329 #define T_CHECK_ONLY_CHANGED    32             /* QQ to be removed */
00330 #define T_CREATE_MISSING_KEYS   64
00331 #define T_DESCRIPT              128
00332 #define T_DONT_CHECK_CHECKSUM   256
00333 #define T_EXTEND                512
00334 #define T_FAST                  (1L << 10)     /* QQ to be removed */
00335 #define T_FORCE_CREATE          (1L << 11)     /* QQ to be removed */
00336 #define T_FORCE_UNIQUENESS      (1L << 12)
00337 #define T_INFO                  (1L << 13)
00338 #define T_MEDIUM                (1L << 14)
00339 #define T_QUICK                 (1L << 15)     /* QQ to be removed */
00340 #define T_READONLY              (1L << 16)     /* QQ to be removed */
00341 #define T_REP                   (1L << 17)
00342 #define T_REP_BY_SORT           (1L << 18)     /* QQ to be removed */
00343 #define T_REP_PARALLEL          (1L << 19)     /* QQ to be removed */
00344 #define T_RETRY_WITHOUT_QUICK   (1L << 20)
00345 #define T_SAFE_REPAIR           (1L << 21)
00346 #define T_SILENT                (1L << 22)
00347 #define T_SORT_INDEX            (1L << 23)     /* QQ to be removed */
00348 #define T_SORT_RECORDS          (1L << 24)     /* QQ to be removed */
00349 #define T_STATISTICS            (1L << 25)
00350 #define T_UNPACK                (1L << 26)
00351 #define T_UPDATE_STATE          (1L << 27)
00352 #define T_VERBOSE               (1L << 28)
00353 #define T_VERY_SILENT           (1L << 29)
00354 #define T_WAIT_FOREVER          (1L << 30)
00355 #define T_WRITE_LOOP            ((ulong) 1L << 31)
00356 
00357 #define T_REP_ANY               (T_REP | T_REP_BY_SORT | T_REP_PARALLEL)
00358 
00359 #define O_NEW_INDEX 1   /* Bits set in out_flag */
00360 #define O_NEW_DATA  2
00361 #define O_DATA_LOST 4
00362 
00363 /* these struct is used by my_check to tell it what to do */
00364 
00365 typedef struct st_sort_key_blocks   /* Used when sorting */
00366 {
00367   unsigned char *buff,*end_pos;
00368   unsigned char lastkey[MI_MAX_POSSIBLE_KEY_BUFF];
00369   uint32_t last_length;
00370   int inited;
00371 } SORT_KEY_BLOCKS;
00372 
00373 
00374 /*
00375   MyISAM supports several statistics collection methods. Currently statistics
00376   collection method is not stored in MyISAM file and has to be specified for
00377   each table analyze/repair operation in  MI_CHECK::stats_method.
00378 */
00379 
00380 typedef enum
00381 {
00382   /* Treat NULLs as inequal when collecting statistics (default for 4.1/5.0) */
00383   MI_STATS_METHOD_NULLS_NOT_EQUAL,
00384   /* Treat NULLs as equal when collecting statistics (like 4.0 did) */
00385   MI_STATS_METHOD_NULLS_EQUAL,
00386   /* Ignore NULLs - count only tuples without NULLs in the index components */
00387   MI_STATS_METHOD_IGNORE_NULLS
00388 } enum_mi_stats_method;
00389 
00390 typedef struct st_mi_check_param
00391 {
00392   uint64_t auto_increment_value;
00393   uint64_t max_data_file_length;
00394   uint64_t keys_in_use;
00395   uint64_t max_record_length;
00396   drizzled::internal::my_off_t search_after_block;
00397   drizzled::internal::my_off_t new_file_pos,key_file_blocks;
00398   drizzled::internal::my_off_t keydata,totaldata,key_blocks,start_check_pos;
00399   drizzled::ha_rows total_records,total_deleted;
00400   ha_checksum record_checksum,glob_crc;
00401   uint64_t use_buffers;
00402   size_t read_buffer_length, write_buffer_length,
00403          sort_buffer_length, sort_key_blocks;
00404   uint32_t out_flag,warning_printed,error_printed,verbose;
00405   uint32_t opt_sort_key,total_files,max_level;
00406   uint32_t testflag, key_cache_block_size;
00407   uint8_t language;
00408   bool using_global_keycache, opt_lock_memory, opt_follow_links;
00409   bool retry_repair, force_sort;
00410   char temp_filename[FN_REFLEN],*isam_file_name;
00411   int tmpfile_createflag;
00412   drizzled::myf myf_rw;
00413   drizzled::internal::io_cache_st read_cache;
00414 
00415   /*
00416     The next two are used to collect statistics, see update_key_parts for
00417     description.
00418   */
00419   uint64_t unique_count[MI_MAX_KEY_SEG+1];
00420   uint64_t notnull_count[MI_MAX_KEY_SEG+1];
00421 
00422   ha_checksum key_crc[HA_MAX_POSSIBLE_KEY];
00423   ulong rec_per_key_part[MI_MAX_KEY_SEG*HA_MAX_POSSIBLE_KEY];
00424   void *session;
00425   const char *db_name, *table_name;
00426   const char *op_name;
00427   enum_mi_stats_method stats_method;
00428 } MI_CHECK;
00429 
00430 typedef struct st_sort_info
00431 {
00432   drizzled::internal::my_off_t filelength,dupp,buff_length;
00433   drizzled::ha_rows max_records;
00434   uint32_t current_key, total_keys;
00435   drizzled::myf myf_rw;
00436   enum drizzled::data_file_type new_data_file_type;
00437   MI_INFO *info;
00438   MI_CHECK *param;
00439   unsigned char *buff;
00440   SORT_KEY_BLOCKS *key_block,*key_block_end;
00441   /* sync things */
00442   uint32_t got_error, threads_running;
00443   pthread_mutex_t mutex;
00444   pthread_cond_t  cond;
00445 } SORT_INFO;
00446 
00447 /* functions in mi_check */
00448 void myisamchk_init(MI_CHECK *param);
00449 int chk_status(MI_CHECK *param, MI_INFO *info);
00450 int chk_del(MI_CHECK *param, register MI_INFO *info, uint32_t test_flag);
00451 int chk_size(MI_CHECK *param, MI_INFO *info);
00452 int chk_key(MI_CHECK *param, MI_INFO *info);
00453 int chk_data_link(MI_CHECK *param, MI_INFO *info,int extend);
00454 int mi_repair(MI_CHECK *param, register MI_INFO *info,
00455         char * name, int rep_quick);
00456 int mi_sort_index(MI_CHECK *param, register MI_INFO *info, char * name);
00457 int mi_repair_by_sort(MI_CHECK *param, register MI_INFO *info,
00458           const char * name, int rep_quick);
00459 int change_to_newfile(const char * filename, const char * old_ext,
00460           const char * new_ext, uint32_t raid_chunks,
00461           drizzled::myf myflags);
00462 void lock_memory(MI_CHECK *param);
00463 void update_auto_increment_key(MI_CHECK *param, MI_INFO *info,
00464              bool repair);
00465 int update_state_info(MI_CHECK *param, MI_INFO *info,uint32_t update);
00466 void update_key_parts(MI_KEYDEF *keyinfo, ulong *rec_per_key_part,
00467                       uint64_t *unique, uint64_t *notnull,
00468                       uint64_t records);
00469 int filecopy(MI_CHECK *param, int to,int from,drizzled::internal::my_off_t start,
00470        drizzled::internal::my_off_t length, const char *type);
00471 int movepoint(MI_INFO *info,unsigned char *record,drizzled::internal::my_off_t oldpos,
00472         drizzled::internal::my_off_t newpos, uint32_t prot_key);
00473 int write_data_suffix(SORT_INFO *sort_info, bool fix_datafile);
00474 int test_if_almost_full(MI_INFO *info);
00475 bool mi_test_if_sort_rep(MI_INFO *info, drizzled::ha_rows rows, uint64_t key_map,
00476           bool force);
00477 
00478 int mi_init_bulk_insert(MI_INFO *info, uint32_t cache_size, drizzled::ha_rows rows);
00479 void mi_flush_bulk_insert(MI_INFO *info, uint32_t inx);
00480 void mi_end_bulk_insert(MI_INFO *info);
00481 int mi_preload(MI_INFO *info, uint64_t key_map, bool ignore_leaves);
00482