121
121
=================
122
122
[Warning: this description is work in progress and may be incomplete]
123
123
The table record is stored in a fixed-size buffer:
125
125
record: null_bytes, column1_data, column2_data, ...
127
The offsets of the parts of the buffer are also fixed: every column has
127
The offsets of the parts of the buffer are also fixed: every column has
128
128
an offset to its column{i}_data, and if it is nullable it also has its own
131
131
The record buffer only includes data about columns that are marked in the
132
132
relevant column set (table->read_set and/or table->write_set, depending on
134
134
<not-sure>It could be that it is required that null bits of non-present
135
135
columns are set to 1</not-sure>
137
137
VARIOUS EXCEPTIONS AND SPECIAL CASES
139
f the table has no nullable columns, then null_bytes is still
140
present, its length is one byte <not-sure> which must be set to 0xFF
139
f the table has no nullable columns, then null_bytes is still
140
present, its length is one byte <not-sure> which must be set to 0xFF
141
141
at all times. </not-sure>
143
143
If the table has columns of type BIT, then certain bits from those columns
144
144
may be stored in null_bytes as well. Grep around for Field_bit for
147
For blob columns (see Field_blob), the record buffer stores length of the
148
data, following by memory pointer to the blob data. The pointer is owned
147
For blob columns (see Field_blob), the record buffer stores length of the
148
data, following by memory pointer to the blob data. The pointer is owned
149
149
by the storage engine and is valid until the next operation.
151
151
If a blob column has NULL value, then its length and blob data pointer
313
313
/* Estimates calculation */
314
314
virtual double scan_time(void)
315
315
{ return uint64_t2double(stats.data_file_length) / IO_SIZE + 2; }
316
virtual double read_time(uint32_t index __attribute__((unused)),
317
uint32_t ranges, ha_rows rows)
316
virtual double read_time(uint32_t, uint32_t ranges, ha_rows rows)
318
317
{ return rows2double(ranges+rows); }
320
319
virtual double index_only_read_time(uint32_t keynr, double records);
322
321
virtual ha_rows multi_range_read_info_const(uint32_t keyno, RANGE_SEQ_IF *seq,
323
void *seq_init_param,
322
void *seq_init_param,
324
323
uint32_t n_ranges, uint32_t *bufsz,
325
324
uint32_t *flags, COST_VECT *cost);
326
325
virtual int multi_range_read_info(uint32_t keyno, uint32_t n_ranges, uint32_t keys,
443
442
row if available. If the key value is null, begin at the first key of the
446
virtual int index_read_idx_map(unsigned char * buf, uint32_t index, const unsigned char * key,
445
virtual int index_read_idx_map(unsigned char * buf, uint32_t index,
446
const unsigned char * key,
447
447
key_part_map keypart_map,
448
448
enum ha_rkey_function find_flag);
449
virtual int index_next(unsigned char * buf __attribute__((unused)))
450
{ return HA_ERR_WRONG_COMMAND; }
451
virtual int index_prev(unsigned char * buf __attribute__((unused)))
452
{ return HA_ERR_WRONG_COMMAND; }
453
virtual int index_first(unsigned char * buf __attribute__((unused)))
454
{ return HA_ERR_WRONG_COMMAND; }
455
virtual int index_last(unsigned char * buf __attribute__((unused)))
456
{ return HA_ERR_WRONG_COMMAND; }
457
virtual int index_next_same(unsigned char *buf __attribute__((unused)),
458
const unsigned char *key __attribute__((unused)),
459
uint32_t keylen __attribute__((unused)));
449
virtual int index_next(unsigned char *)
450
{ return HA_ERR_WRONG_COMMAND; }
451
virtual int index_prev(unsigned char *)
452
{ return HA_ERR_WRONG_COMMAND; }
453
virtual int index_first(unsigned char *)
454
{ return HA_ERR_WRONG_COMMAND; }
455
virtual int index_last(unsigned char *)
456
{ return HA_ERR_WRONG_COMMAND; }
457
virtual int index_next_same(unsigned char *, const unsigned char *, uint32_t);
462
460
The following functions works like index_read, but it find the last
474
472
virtual int read_range_next();
475
473
int compare_key(key_range *range);
476
474
int compare_key2(key_range *range);
477
virtual int rnd_next(unsigned char *buf __attribute__((unused)))=0;
478
virtual int rnd_pos(unsigned char * buf __attribute__((unused)),
479
unsigned char *pos __attribute__((unused)))=0;
475
virtual int rnd_next(unsigned char *)=0;
476
virtual int rnd_pos(unsigned char *, unsigned char *)=0;
481
478
One has to use this method when to find
482
479
random position by record as the plain
489
486
The following function is only needed for tables that may be temporary
490
487
tables during joins.
492
virtual int restart_rnd_next(unsigned char *buf __attribute__((unused)),
493
unsigned char *pos __attribute__((unused)))
494
{ return HA_ERR_WRONG_COMMAND; }
495
virtual int rnd_same(unsigned char *buf __attribute__((unused)),
496
uint32_t inx __attribute__((unused)))
497
{ return HA_ERR_WRONG_COMMAND; }
498
virtual ha_rows records_in_range(uint32_t inx __attribute__((unused)),
499
key_range *min_key __attribute__((unused)),
500
key_range *max_key __attribute__((unused)))
489
virtual int restart_rnd_next(unsigned char *, unsigned char *)
490
{ return HA_ERR_WRONG_COMMAND; }
491
virtual int rnd_same(unsigned char *, uint32_t)
492
{ return HA_ERR_WRONG_COMMAND; }
493
virtual ha_rows records_in_range(uint32_t, key_range *, key_range *)
501
494
{ return (ha_rows) 10; }
502
495
virtual void position(const unsigned char *record)=0;
503
496
virtual int info(uint)=0; // see my_base.h for full description
504
virtual uint32_t calculate_key_hash_value(Field **field_array __attribute__((unused)))
497
virtual uint32_t calculate_key_hash_value(Field **)
505
498
{ assert(0); return 0; }
506
virtual int extra(enum ha_extra_function operation __attribute__((unused)))
499
virtual int extra(enum ha_extra_function)
508
virtual int extra_opt(enum ha_extra_function operation,
509
uint32_t cache_size __attribute__((unused)))
501
virtual int extra_opt(enum ha_extra_function operation, uint32_t)
510
502
{ return extra(operation); }
531
523
virtual void try_semi_consistent_read(bool) {}
532
524
virtual void unlock_row(void) {}
533
virtual int start_stmt(Session *session __attribute__((unused)),
534
thr_lock_type lock_type __attribute__((unused)))
525
virtual int start_stmt(Session *, thr_lock_type)
536
527
virtual void get_auto_increment(uint64_t offset, uint64_t increment,
537
528
uint64_t nb_desired_values,
557
548
insert_id_for_cur_row;
560
virtual void update_create_info(HA_CREATE_INFO *create_info __attribute__((unused))) {}
551
virtual void update_create_info(HA_CREATE_INFO *) {}
561
552
int check_old_types(void);
562
virtual int assign_to_keycache(Session* session __attribute__((unused)),
563
HA_CHECK_OPT* check_opt __attribute__((unused)))
553
virtual int assign_to_keycache(Session*, HA_CHECK_OPT *)
564
554
{ return HA_ADMIN_NOT_IMPLEMENTED; }
565
555
/* end of the list of admin commands */
567
557
virtual int indexes_are_disabled(void) {return 0;}
568
558
virtual char *update_table_comment(const char * comment)
569
559
{ return (char*) comment;}
570
virtual void append_create_info(String *packet __attribute__((unused)))
560
virtual void append_create_info(String *)
573
563
If index == MAX_KEY then a check for table is made and if index <
579
569
@retval true Foreign key defined on table or index
580
570
@retval false No foreign key defined
582
virtual bool is_fk_defined_on_table_or_index(uint32_t index __attribute__((unused)))
572
virtual bool is_fk_defined_on_table_or_index(uint32_t)
583
573
{ return false; }
584
574
virtual char* get_foreign_key_create_info(void)
585
575
{ return(NULL);} /* gets foreign key create string from InnoDB */
586
576
/** used in ALTER Table; 1 if changing storage engine is allowed */
587
577
virtual bool can_switch_engines(void) { return 1; }
588
578
/** used in REPLACE; is > 0 if table is referred by a FOREIGN KEY */
589
virtual int get_foreign_key_list(Session *session __attribute__((unused)),
590
List<FOREIGN_KEY_INFO> *f_key_list __attribute__((unused)))
579
virtual int get_foreign_key_list(Session *, List<FOREIGN_KEY_INFO> *)
592
581
virtual uint32_t referenced_by_foreign_key() { return 0;}
593
582
virtual void init_table_handle_for_HANDLER()
594
583
{ return; } /* prepare InnoDB for HANDLER */
595
virtual void free_foreign_key_create_info(char* str __attribute__((unused))) {}
584
virtual void free_foreign_key_create_info(char *) {}
596
585
/** The following can be called without an open handler */
597
586
virtual const char *table_type() const =0;
609
598
virtual const char **bas_ext() const =0;
611
virtual int get_default_no_partitions(HA_CREATE_INFO *info __attribute__((unused))) { return 1;}
612
virtual bool get_no_parts(const char *name __attribute__((unused)),
600
virtual int get_default_no_partitions(HA_CREATE_INFO *) { return 1;}
601
virtual bool get_no_parts(const char *, uint32_t *no_parts)
619
607
virtual uint32_t index_flags(uint32_t idx, uint32_t part, bool all_parts) const =0;
621
virtual int add_index(Table *table_arg __attribute__((unused)),
622
KEY *key_info __attribute__((unused)),
623
uint32_t num_of_keys __attribute__((unused)))
624
{ return (HA_ERR_WRONG_COMMAND); }
625
virtual int prepare_drop_index(Table *table_arg __attribute__((unused)),
626
uint32_t *key_num __attribute__((unused)),
627
uint32_t num_of_keys __attribute__((unused)))
628
{ return (HA_ERR_WRONG_COMMAND); }
629
virtual int final_drop_index(Table *table_arg __attribute__((unused)))
609
virtual int add_index(Table *, KEY *, uint32_t)
610
{ return (HA_ERR_WRONG_COMMAND); }
611
virtual int prepare_drop_index(Table *, uint32_t *, uint32_t)
612
{ return (HA_ERR_WRONG_COMMAND); }
613
virtual int final_drop_index(Table *)
630
614
{ return (HA_ERR_WRONG_COMMAND); }
632
616
uint32_t max_record_length() const
646
630
virtual uint32_t max_supported_key_parts(void) const { return MAX_REF_PARTS; }
647
631
virtual uint32_t max_supported_key_length(void) const { return MAX_KEY_LENGTH; }
648
632
virtual uint32_t max_supported_key_part_length(void) const { return 255; }
649
virtual uint32_t min_record_length(uint32_t options __attribute__((unused))) const
633
virtual uint32_t min_record_length(uint32_t) const
652
636
virtual bool low_byte_first(void) const { return 1; }
699
683
This method offers the storage engine, the possibility to store a reference
700
to a table name which is going to be used with query cache.
684
to a table name which is going to be used with query cache.
701
685
The method is called each time a statement is written to the cache and can
702
686
be used to verify if a specific statement is cachable. It also offers
703
687
the possibility to register a generic (but static) call back function which
719
register_query_cache_table(Session *session __attribute__((unused)),
720
char *table_key __attribute__((unused)),
721
uint32_t key_length __attribute__((unused)),
703
register_query_cache_table(Session *, char *, uint32_t,
722
704
qc_engine_callback *engine_callback,
723
uint64_t *engine_data __attribute__((unused)))
725
707
*engine_callback= 0;
757
739
The pushed conditions form a stack (from which one can remove the
758
740
last pushed condition using cond_pop).
759
The table handler filters out rows using (pushed_cond1 AND pushed_cond2
741
The table handler filters out rows using (pushed_cond1 AND pushed_cond2
760
742
AND ... AND pushed_condN)
761
743
or less restrictive condition, depending on handler's capabilities.
763
745
handler->ha_reset() call empties the condition stack.
764
746
Calls to rnd_init/rnd_end, index_init/index_end etc do not affect the
767
749
virtual const COND *cond_push(const COND *cond) { return cond; }
774
756
virtual void cond_pop(void) { return; }
777
*idx_cond_push(uint32_t keyno __attribute__((unused)),
778
Item* idx_cond __attribute__((unused)))
758
virtual Item *idx_cond_push(uint32_t, Item *idx_cond)
779
759
{ return idx_cond; }
782
762
Part of old fast alter table, to be depricated
785
check_if_incompatible_data(HA_CREATE_INFO *create_info __attribute__((unused)),
786
uint32_t table_changes __attribute__((unused)))
765
check_if_incompatible_data(HA_CREATE_INFO *, uint32_t)
787
766
{ return COMPATIBLE_DATA_NO; }
789
768
/* On-line ALTER Table interface */
811
790
just changing the frm file) without any change in the handler
815
check_if_supported_alter(Table *altered_table __attribute__((unused)),
816
HA_CREATE_INFO *create_info,
817
HA_ALTER_FLAGS *alter_flags __attribute__((unused)),
818
uint32_t table_changes)
793
virtual int check_if_supported_alter(Table *, HA_CREATE_INFO *create_info,
794
HA_ALTER_FLAGS * alter_flags, uint32_t table_changes)
820
796
if (this->check_if_incompatible_data(create_info, table_changes)
821
797
== COMPATIBLE_DATA_NO)
839
815
@retval error error code passed from storage engine
841
virtual int alter_table_phase1(Session *session __attribute__((unused)),
842
Table *altered_table __attribute__((unused)),
843
HA_CREATE_INFO *create_info __attribute__((unused)),
844
HA_ALTER_INFO *alter_info __attribute__((unused)),
845
HA_ALTER_FLAGS *alter_flags __attribute__((unused)))
817
virtual int alter_table_phase1(Session *, Table *, HA_CREATE_INFO *, HA_ALTER_INFO *,
847
820
return HA_ERR_UNSUPPORTED;
864
837
this call is to be wrapped with a DDL lock. This is currently NOT
867
virtual int alter_table_phase2(Session *session __attribute__((unused)),
868
Table *altered_table __attribute__((unused)),
869
HA_CREATE_INFO *create_info __attribute__((unused)),
870
HA_ALTER_INFO *alter_info __attribute__((unused)),
871
HA_ALTER_FLAGS *alter_flags __attribute__((unused)))
840
virtual int alter_table_phase2(Session *, Table *, HA_CREATE_INFO *, HA_ALTER_INFO *,
873
843
return HA_ERR_UNSUPPORTED;
879
849
@param session The thread handle
880
850
@param table The altered table, re-opened
882
virtual int alter_table_phase3(Session *session __attribute__((unused)),
883
Table *table __attribute__((unused)))
852
virtual int alter_table_phase3(Session *, Table *)
885
854
return HA_ERR_UNSUPPORTED;
916
885
lock conflict with NOWAIT option
917
886
@retval HA_ERR_LOCK_DEADLOCK Deadlock detected
919
virtual int lock_table(Session *session __attribute__((unused)),
920
int lock_type __attribute__((unused)),
921
int lock_timeout __attribute__((unused)))
888
virtual int lock_table(Session *, int, int)
923
890
return HA_ERR_WRONG_COMMAND;
962
929
virtual int open(const char *name, int mode, uint32_t test_if_locked)=0;
963
virtual int index_init(uint32_t idx,
964
bool sorted __attribute__((unused)))
930
virtual int index_init(uint32_t idx, bool)
965
931
{ active_index= idx; return 0; }
966
932
virtual int index_end() { active_index= MAX_KEY; return 0; }
974
940
virtual int rnd_init(bool scan)= 0;
975
941
virtual int rnd_end() { return 0; }
976
virtual int write_row(unsigned char *buf __attribute__((unused)))
978
return HA_ERR_WRONG_COMMAND;
981
virtual int update_row(const unsigned char *old_data __attribute__((unused)),
982
unsigned char *new_data __attribute__((unused)))
984
return HA_ERR_WRONG_COMMAND;
987
virtual int delete_row(const unsigned char *buf __attribute__((unused)))
942
virtual int write_row(unsigned char *)
944
return HA_ERR_WRONG_COMMAND;
947
virtual int update_row(const unsigned char *, unsigned char *)
949
return HA_ERR_WRONG_COMMAND;
952
virtual int delete_row(const unsigned char *)
989
954
return HA_ERR_WRONG_COMMAND;
1018
983
@return non-0 in case of failure, 0 in case of success.
1019
984
When lock_type is F_UNLCK, the return value is ignored.
1021
virtual int external_lock(Session *session __attribute__((unused)),
1022
int lock_type __attribute__((unused)))
986
virtual int external_lock(Session *, int)
1026
990
virtual void release_auto_increment(void) { return; };
1027
991
/** admin commands - called from mysql_admin_table */
1028
virtual int check_for_upgrade(HA_CHECK_OPT *check_opt __attribute__((unused)))
992
virtual int check_for_upgrade(HA_CHECK_OPT *)
1030
virtual int check(Session* session __attribute__((unused)),
1031
HA_CHECK_OPT* check_opt __attribute__((unused)))
994
virtual int check(Session *, HA_CHECK_OPT *)
1032
995
{ return HA_ADMIN_NOT_IMPLEMENTED; }
1036
999
to specify CHECK option to use to call check()
1037
1000
upon the table.
1039
virtual int repair(Session* session __attribute__((unused)),
1040
HA_CHECK_OPT* check_opt __attribute__((unused)))
1002
virtual int repair(Session *, HA_CHECK_OPT *)
1041
1003
{ return HA_ADMIN_NOT_IMPLEMENTED; }
1042
virtual void start_bulk_insert(ha_rows rows __attribute__((unused)))
1004
virtual void start_bulk_insert(ha_rows)
1044
1006
virtual int end_bulk_insert(void) { return 0; }
1045
virtual int index_read(unsigned char * buf __attribute__((unused)),
1046
const unsigned char * key __attribute__((unused)),
1047
uint32_t key_len __attribute__((unused)),
1048
enum ha_rkey_function find_flag __attribute__((unused)))
1007
virtual int index_read(unsigned char *, const unsigned char *,
1008
uint32_t, enum ha_rkey_function)
1049
1009
{ return HA_ERR_WRONG_COMMAND; }
1050
virtual int index_read_last(unsigned char * buf __attribute__((unused)),
1051
const unsigned char * key __attribute__((unused)),
1052
uint32_t key_len __attribute__((unused)))
1010
virtual int index_read_last(unsigned char *, const unsigned char *, uint32_t)
1053
1011
{ return (my_errno= HA_ERR_WRONG_COMMAND); }
1055
1013
This method is similar to update_row, however the handler doesn't need
1064
1022
@retval 0 Bulk delete used by handler
1065
1023
@retval 1 Bulk delete not used, normal operation used
1067
virtual int bulk_update_row(const unsigned char *old_data __attribute__((unused)),
1068
unsigned char *new_data __attribute__((unused)),
1069
uint32_t *dup_key_found __attribute__((unused)))
1025
virtual int bulk_update_row(const unsigned char *, unsigned char *, uint32_t *)
1072
1028
return HA_ERR_WRONG_COMMAND;
1085
1041
is emulated by doing a 'DELETE FROM t'. HA_ERR_WRONG_COMMAND is
1086
1042
returned by storage engines that don't support this operation.
1088
virtual int reset_auto_increment(uint64_t value __attribute__((unused)))
1044
virtual int reset_auto_increment(uint64_t)
1089
1045
{ return HA_ERR_WRONG_COMMAND; }
1090
virtual int optimize(Session* session __attribute__((unused)),
1091
HA_CHECK_OPT* check_opt __attribute__((unused)))
1092
{ return HA_ADMIN_NOT_IMPLEMENTED; }
1093
virtual int analyze(Session* session __attribute__((unused)),
1094
HA_CHECK_OPT* check_opt __attribute__((unused)))
1095
{ return HA_ADMIN_NOT_IMPLEMENTED; }
1096
virtual bool check_and_repair(Session *session __attribute__((unused)))
1046
virtual int optimize(Session *, HA_CHECK_OPT *)
1047
{ return HA_ADMIN_NOT_IMPLEMENTED; }
1048
virtual int analyze(Session *, HA_CHECK_OPT *)
1049
{ return HA_ADMIN_NOT_IMPLEMENTED; }
1050
virtual bool check_and_repair(Session *)
1097
1051
{ return true; }
1098
virtual int disable_indexes(uint32_t mode __attribute__((unused)))
1099
{ return HA_ERR_WRONG_COMMAND; }
1100
virtual int enable_indexes(uint32_t mode __attribute__((unused)))
1101
{ return HA_ERR_WRONG_COMMAND; }
1102
virtual int discard_or_import_tablespace(bool discard __attribute__((unused)))
1052
virtual int disable_indexes(uint32_t)
1053
{ return HA_ERR_WRONG_COMMAND; }
1054
virtual int enable_indexes(uint32_t)
1055
{ return HA_ERR_WRONG_COMMAND; }
1056
virtual int discard_or_import_tablespace(bool)
1103
1057
{ return (my_errno=HA_ERR_WRONG_COMMAND); }
1104
1058
virtual void prepare_for_alter(void) { return; }
1105
1059
virtual void drop_table(const char *name);
1106
virtual int create(const char *name __attribute__((unused)),
1107
Table *form __attribute__((unused)),
1108
HA_CREATE_INFO *info __attribute__((unused)))=0;
1060
virtual int create(const char *, Table *, HA_CREATE_INFO *)=0;
1110
virtual int create_handler_files(const char *name __attribute__((unused)),
1111
const char *old_name __attribute__((unused)),
1112
int action_flag __attribute__((unused)),
1113
HA_CREATE_INFO *info __attribute__((unused)))
1062
virtual int create_handler_files(const char *, const char *, int, HA_CREATE_INFO *)
1114
1063
{ return false; }
1120
1069
A Disk-Sweep MRR interface implementation
1122
1071
This implementation makes range (and, in the future, 'ref') scans to read
1123
table rows in disk sweeps.
1072
table rows in disk sweeps.
1125
1074
Currently it is used by MyISAM and InnoDB. Potentially it can be used with
1126
1075
any table handler that has non-clustered indexes and on-disk rows.
1159
1108
void init(handler *h_arg, Table *table_arg)
1162
1111
table= table_arg;
1164
int dsmrr_init(handler *h, KEY *key, RANGE_SEQ_IF *seq_funcs,
1165
void *seq_init_param, uint32_t n_ranges, uint32_t mode,
1113
int dsmrr_init(handler *h, KEY *key, RANGE_SEQ_IF *seq_funcs,
1114
void *seq_init_param, uint32_t n_ranges, uint32_t mode,
1166
1115
HANDLER_BUFFER *buf);
1167
1116
void dsmrr_close();
1168
1117
int dsmrr_fill_buffer(handler *h);
1171
1120
int dsmrr_info(uint32_t keyno, uint32_t n_ranges, uint32_t keys, uint32_t *bufsz,
1172
1121
uint32_t *flags, COST_VECT *cost);
1174
ha_rows dsmrr_info_const(uint32_t keyno, RANGE_SEQ_IF *seq,
1123
ha_rows dsmrr_info_const(uint32_t keyno, RANGE_SEQ_IF *seq,
1175
1124
void *seq_init_param, uint32_t n_ranges, uint32_t *bufsz,
1176
1125
uint32_t *flags, COST_VECT *cost);
1178
1127
bool key_uses_partial_cols(uint32_t keyno);
1179
bool choose_mrr_impl(uint32_t keyno, ha_rows rows, uint32_t *flags, uint32_t *bufsz,
1128
bool choose_mrr_impl(uint32_t keyno, ha_rows rows, uint32_t *flags, uint32_t *bufsz,
1180
1129
COST_VECT *cost);
1181
bool get_disk_sweep_mrr_cost(uint32_t keynr, ha_rows rows, uint32_t flags,
1130
bool get_disk_sweep_mrr_cost(uint32_t keynr, ha_rows rows, uint32_t flags,
1182
1131
uint32_t *buffer_size, COST_VECT *cost);
1403
1352
Table *drop_locked_tables(Session *session,const char *db, const char *table_name);
1404
1353
void abort_locked_tables(Session *session,const char *db, const char *table_name);
1405
1354
void execute_init_command(Session *session, sys_var_str *init_command_var,
1406
rw_lock_t *var_mutex);
1355
pthread_rwlock_t *var_mutex);
1407
1356
extern Field *not_found_field;
1408
1357
extern Field *view_ref_found;