mirror of
https://github.com/MariaDB/server.git
synced 2025-06-04 18:03:14 +03:00
Moved randomize and my_rnd under mysys
Added my_uuid Added pre-support for PAGE_CHECKSUM Added syntax for CREATE ... PAGE_CHECKSUM=# TABLE_CHECKSUM=# Reserved place for page checksums on index, bitmap and block pages Added index number to header of index pages Added linked list for free directory entries (speeds up inserts with BLOCK format) Calculate checksums in original column order (fixes bug with checksum on rows with BLOCK format) Cleaned up all index handling to use 'info->s->keypage_header' (variable size) as the header for index pages (before this was '2') Added 0xffffffff to end of index and block data bases and 0xfffffffe at end of bitmap pages when page checksums are not enabled Added _ma_get_page_used() and _ma_get_used_and_node() to simplify index page header handling rec_per_key_part is now in double precision Reserved place in index file for my_guid and nulls_per_key_part Give error HA_ERR_NEW_FILE if trying to open a Maria file with new, not yet supported extensions Lots of renames to increase readability: randomize() -> my_rnd_init() st_maria_info -> st_maria_handler st_maria_info -> MARIA_HA st_maria_isaminfo -> st_maria_info rand_struct -> my_rand_struct rec_per_key_rows -> records_at_analyze client/mysqladmin.cc: rand_struct -> my_rrnd_struct include/maria.h: st_maria_info -> MARIA_HA st_maria_isaminfo -> st_maria_info Changed analyze statistics to be of double precission Changed offset to field to be 32bits instead of 64 (safe as a record without blobs can't be that big) include/my_base.h: Added HA_OPTION_PAGE_CHECKSUM & HA_CREATE_PAGE_CHECKSUM Fixed comments Added HA_ERR_NEW_FILE include/my_sys.h: Added prototypes and structures for my_uuid() and my_rnd() include/myisamchk.h: Changed some buffers to size_t Added possibility to have key statistics with double precission include/mysql_com.h: Move rand functions to mysys libmysql/Makefile.shared: Added my_rnd mysql-test/r/maria.result: Updated results mysql-test/t/maria.test: More tests for checksum mysys/Makefile.am: Added my_rnd.c and my_uuid.c server-tools/instance-manager/listener.cc: Fixed include order (my_global.h should always be first) server-tools/instance-manager/mysql_connection.cc: Fixed include order (my_global.h should always be first) Use my_rnd_init() server-tools/instance-manager/mysql_connection.h: rand_struct -> my_rand_struct sql/handler.h: Added flag for page checksums sql/item_func.cc: Use new my_rnd() interface sql/item_func.h: Use new my_rnd() interface sql/item_strfunc.cc: Use new my_rnd() interface sql/lex.h: Added PAGE_CHECKSUM and TABLE_CHECKSUM sql/mysql_priv.h: Use new my_rnd() interface sql/mysqld.cc: Use new my_rnd() interface sql/password.c: Move my_rnd() to mysys Use new my_rnd() interface sql/sql_class.cc: Use new my_rnd() interface sql/sql_class.h: Use new my_rnd() interface sql/sql_crypt.cc: Use new my_rnd() interface sql/sql_crypt.h: Use new my_rnd() interface sql/sql_show.cc: Simpler handling of ha_choice_values Added PAGE_CHECKSUM sql/sql_table.cc: Enable correct checksum handling (for now) if not running in compatible mode sql/sql_yacc.yy: Added table option PAGE_CHECKSUM Added future compatible table option TABLE_CHECKSUM (alias for CHECKSUM) Added 'choice' target to simplify code sql/table.cc: Store flag for PAGE_CHECKSUM sql/table.h: Added support for PAGE_CHECKSUM storage/maria/ha_maria.cc: Remove protection for incompatbile frm and MAI (Slow, not needed test) Rec_per_key is now in double Remember row type for table Give warning if one Maria uses another row type than requested Removed some old ASK_MONTY entries (added comments instead) Added handling of PAGE_CHECKSUM flags storage/maria/ma_bitmap.c: Added page checksums to bitmap pages Added special bitmap marker for bitmap pages (Used to find bugs when running without page checksums) storage/maria/ma_blockrec.c: Added a free-link list over directory entries. This makes insert of small rows faster as we don't have to scan the whole directory to find a not used entry. Moved SANITY_CHECKS to maria_def.h Simplify code by introducing dir_entry_pos() Added support for PAGE_CHECKSUM storage/maria/ma_blockrec.h: Added DIR_FREE_SIZE (linked list of free directory entries) Added PAGE_CHECKSUM Added 'dir_entry_pos()' storage/maria/ma_check.c: Check that index pages has correct index number Calculate rec_per_key with double precission Simplify code by using '_ma_get_used_and_node()' Check free directory list Remove wrong end \n from messages maria_data_on_page() -> _ma_get_page_used() maria_putint() -> _ma_store_page_used() rec_per_key_rows -> records_at_analyze storage/maria/ma_checksum.c: Calculate checksum in original column order storage/maria/ma_create.c: Store original column order in index file Reserve place for nulls_per_key_part (future) Added support for PAGE_CHECKSUM storage/maria/ma_dbug.c: Fixed wrong debug output of key of type 'ulong' storage/maria/ma_delete.c: maria_data_on_page() -> _ma_get_used_and_node() maria_data_on_page() -> _ma_get_page_used() maria_putint() -> _ma_store_page_used() Added page header (index key number) to all index pages Reserved page for checksum on index pages Use keypage_header storage/maria/ma_ft_update.c: maria_putint() -> _ma_store_page_used() Store key number at start of page storage/maria/ma_loghandler.h: st_maria_info -> MARIA_HA storage/maria/ma_open.c: rec_per_key is now in double precission Added 'nulls_per_key_part' Added 'extra_options' (flags for future) Added support for PAGE_CHECKSUM Give error HA_ERR_NEW_FILE when using unsupported maria extensions Added comments Add maria_uuid to index file Added functions to store and read column_nr map. Changed some functions to return my_bool instead of uint storage/maria/ma_page.c: Added checks that pages has correct key nr Store 0xffffffff in checksum position if page checksums are not enabled Moved key-page-delete link to take into account keypage header storage/maria/ma_preload.c: Remove old MyISAM dependent code When scanning pages, only add pages to page cache for the requested index storage/maria/ma_range.c: maria_data_on_page() -> _ma_get_used_and_node() Use keypage_header storage/maria/ma_rt_index.c: Fixed indentation storage/maria/ma_rt_index.h: Added support for dynamic index page header Reserved place for PAGE_CHECKSUM storage/maria/ma_rt_key.c: Fixed indentation maria_data_on_page() -> _ma_get_page_used() maria_putint() -> maria_store_page_used() storage/maria/ma_rt_mbr.c: Fixed indentation storage/maria/ma_rt_split.c: Fixed indentation maria_data_on_page () -> _ma_get_page_used() storage/maria/ma_rt_test.c: Fixed indentation storage/maria/ma_search.c: Remove support of using -1 as 'last used index' to _ma_check_index() maria_data_on_page() -> _ma_get_page_used() maria_data_on_page() -> _ma_get_used_and_node() Use keypage_header storage/maria/ma_sort.c: Changed some buffers to size_t Changed rec_per_key_part to double storage/maria/ma_static.c: Removed NEAR Added maria_uuid storage/maria/ma_test2.c: Moevd testflag == 2 to correct place Remove test of reading with index number -1 (not supported anymore) storage/maria/ma_test_recovery.expected: Updated results storage/maria/ma_test_recovery: Changed tmp table names so that one can run maria_chk on them storage/maria/ma_write.c: Fixed indentation Use keypage_header Store index number on index pages maria_putint() -> _ma_store_page_used() maria_data_on_page() -> ma_get_used_and_node() maria_data_on_page() -> _ma_get_page_used() Added PAGE_CHECKSUM Added Maria handler to some functions Removed some not needed casts storage/maria/maria_chk.c: Added error handling for HA_ERR_NEW_FILE Added information about page checksums rec_per_key_part changed to double maria_data_on_page() -> _ma_get_page_used() Use keypage_header storage/maria/maria_def.h: Added IDENTICAL_PAGES_AFTER_RECOVERY and SANITY_CHECKS Changed rec_per_key_part to double Added nulls_per_key_part rec_per_key_rows -> records_at_analyze st_maria_info -> MARIA_HA Reserve place for new statistics variables, uuid, checksums per page etc. Removed NEAR tags Changed some prototypes to use my_bool and size_t storage/maria/maria_pack.c: st_maria_info -> MARIA_HA Fixed indentation storage/myisam/mi_dbug.c: Fix wrong debug output for ULONG mysys/my_rnd.c: New BitKeeper file ``mysys/my_rnd.c'' mysys/my_uuid.c: New BitKeeper file ``mysys/my_uuid.c''
This commit is contained in:
parent
d097806323
commit
496741d576
@ -515,7 +515,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
|
|||||||
If this behaviour is ever changed, Docs should be notified.
|
If this behaviour is ever changed, Docs should be notified.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
struct rand_struct rand_st;
|
struct my_rnd_struct rand_st;
|
||||||
|
|
||||||
for (; argc > 0 ; argv++,argc--)
|
for (; argc > 0 ; argv++,argc--)
|
||||||
{
|
{
|
||||||
@ -827,7 +827,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
|
|||||||
time_t start_time;
|
time_t start_time;
|
||||||
/* Do initialization the same way as we do in mysqld */
|
/* Do initialization the same way as we do in mysqld */
|
||||||
start_time=time((time_t*) 0);
|
start_time=time((time_t*) 0);
|
||||||
randominit(&rand_st,(ulong) start_time,(ulong) start_time/2);
|
my_rnd_init(&rand_st,(ulong) start_time,(ulong) start_time/2);
|
||||||
|
|
||||||
if (argc < 2)
|
if (argc < 2)
|
||||||
{
|
{
|
||||||
|
@ -110,7 +110,7 @@ extern "C" {
|
|||||||
|
|
||||||
typedef ulonglong MARIA_RECORD_POS;
|
typedef ulonglong MARIA_RECORD_POS;
|
||||||
|
|
||||||
typedef struct st_maria_isaminfo /* Struct from h_info */
|
typedef struct st_maria_info
|
||||||
{
|
{
|
||||||
ha_rows records; /* Records in database */
|
ha_rows records; /* Records in database */
|
||||||
ha_rows deleted; /* Deleted records in database */
|
ha_rows deleted; /* Deleted records in database */
|
||||||
@ -126,7 +126,7 @@ typedef struct st_maria_isaminfo /* Struct from h_info */
|
|||||||
time_t check_time;
|
time_t check_time;
|
||||||
time_t update_time;
|
time_t update_time;
|
||||||
ulong record_offset;
|
ulong record_offset;
|
||||||
ulong *rec_per_key; /* for sql optimizing */
|
double *rec_per_key; /* for sql optimizing */
|
||||||
ulong reclength; /* Recordlength */
|
ulong reclength; /* Recordlength */
|
||||||
ulong mean_reclength; /* Mean recordlength (if packed) */
|
ulong mean_reclength; /* Mean recordlength (if packed) */
|
||||||
char *data_file_name, *index_file_name;
|
char *data_file_name, *index_file_name;
|
||||||
@ -156,9 +156,9 @@ typedef struct st_maria_create_info
|
|||||||
my_bool with_auto_increment, transactional;
|
my_bool with_auto_increment, transactional;
|
||||||
} MARIA_CREATE_INFO;
|
} MARIA_CREATE_INFO;
|
||||||
|
|
||||||
struct st_maria_info; /* For referense */
|
|
||||||
struct st_maria_share;
|
struct st_maria_share;
|
||||||
typedef struct st_maria_info MARIA_HA;
|
struct st_maria_handler; /* For referense */
|
||||||
|
typedef struct st_maria_handler MARIA_HA;
|
||||||
struct st_maria_s_param;
|
struct st_maria_s_param;
|
||||||
|
|
||||||
typedef struct st_maria_keydef /* Key definition with open & info */
|
typedef struct st_maria_keydef /* Key definition with open & info */
|
||||||
@ -178,7 +178,7 @@ typedef struct st_maria_keydef /* Key definition with open & info */
|
|||||||
|
|
||||||
HA_KEYSEG *seg, *end;
|
HA_KEYSEG *seg, *end;
|
||||||
struct st_mysql_ftparser *parser; /* Fulltext [pre]parser */
|
struct st_mysql_ftparser *parser; /* Fulltext [pre]parser */
|
||||||
int (*bin_search)(struct st_maria_info *info,
|
int (*bin_search)(MARIA_HA *info,
|
||||||
struct st_maria_keydef *keyinfo, uchar *page, uchar *key,
|
struct st_maria_keydef *keyinfo, uchar *page, uchar *key,
|
||||||
uint key_len, uint comp_flag, uchar **ret_pos,
|
uint key_len, uint comp_flag, uchar **ret_pos,
|
||||||
uchar *buff, my_bool *was_last_key);
|
uchar *buff, my_bool *was_last_key);
|
||||||
@ -189,8 +189,8 @@ typedef struct st_maria_keydef /* Key definition with open & info */
|
|||||||
const uchar *key, struct st_maria_s_param *s_temp);
|
const uchar *key, struct st_maria_s_param *s_temp);
|
||||||
void (*store_key)(struct st_maria_keydef *keyinfo, uchar *key_pos,
|
void (*store_key)(struct st_maria_keydef *keyinfo, uchar *key_pos,
|
||||||
struct st_maria_s_param *s_temp);
|
struct st_maria_s_param *s_temp);
|
||||||
int (*ck_insert)(struct st_maria_info *inf, uint k_nr, uchar *k, uint klen);
|
int (*ck_insert)(MARIA_HA *inf, uint k_nr, uchar *k, uint klen);
|
||||||
int (*ck_delete)(struct st_maria_info *inf, uint k_nr, uchar *k, uint klen);
|
int (*ck_delete)(MARIA_HA *inf, uint k_nr, uchar *k, uint klen);
|
||||||
} MARIA_KEYDEF;
|
} MARIA_KEYDEF;
|
||||||
|
|
||||||
|
|
||||||
@ -222,9 +222,10 @@ struct st_maria_bit_buff;
|
|||||||
|
|
||||||
typedef struct st_maria_columndef /* column information */
|
typedef struct st_maria_columndef /* column information */
|
||||||
{
|
{
|
||||||
uint64 offset; /* Offset to position in row */
|
|
||||||
enum en_fieldtype type;
|
enum en_fieldtype type;
|
||||||
|
uint32 offset; /* Offset to position in row */
|
||||||
uint16 length; /* length of field */
|
uint16 length; /* length of field */
|
||||||
|
uint16 column_nr;
|
||||||
/* Intern variable (size of total storage area for the row) */
|
/* Intern variable (size of total storage area for the row) */
|
||||||
uint16 fill_length;
|
uint16 fill_length;
|
||||||
uint16 null_pos; /* Position for null marker */
|
uint16 null_pos; /* Position for null marker */
|
||||||
@ -257,34 +258,34 @@ extern PAGECACHE maria_pagecache_var, *maria_pagecache;
|
|||||||
|
|
||||||
extern int maria_init(void);
|
extern int maria_init(void);
|
||||||
extern void maria_end(void);
|
extern void maria_end(void);
|
||||||
extern int maria_close(struct st_maria_info *file);
|
extern int maria_close(MARIA_HA *file);
|
||||||
extern int maria_delete(struct st_maria_info *file, const uchar *buff);
|
extern int maria_delete(MARIA_HA *file, const uchar *buff);
|
||||||
extern struct st_maria_info *maria_open(const char *name, int mode,
|
extern MARIA_HA *maria_open(const char *name, int mode,
|
||||||
uint wait_if_locked);
|
uint wait_if_locked);
|
||||||
extern struct st_maria_info *maria_clone(struct st_maria_share *share, int mode);
|
extern MARIA_HA *maria_clone(struct st_maria_share *share, int mode);
|
||||||
extern int maria_panic(enum ha_panic_function function);
|
extern int maria_panic(enum ha_panic_function function);
|
||||||
extern int maria_rfirst(struct st_maria_info *file, uchar *buf, int inx);
|
extern int maria_rfirst(MARIA_HA *file, uchar *buf, int inx);
|
||||||
extern int maria_rkey(struct st_maria_info *file, uchar *buf, int inx,
|
extern int maria_rkey(MARIA_HA *file, uchar *buf, int inx,
|
||||||
const uchar *key, key_part_map keypart_map,
|
const uchar *key, key_part_map keypart_map,
|
||||||
enum ha_rkey_function search_flag);
|
enum ha_rkey_function search_flag);
|
||||||
extern int maria_rlast(struct st_maria_info *file, uchar *buf, int inx);
|
extern int maria_rlast(MARIA_HA *file, uchar *buf, int inx);
|
||||||
extern int maria_rnext(struct st_maria_info *file, uchar *buf, int inx);
|
extern int maria_rnext(MARIA_HA *file, uchar *buf, int inx);
|
||||||
extern int maria_rnext_same(struct st_maria_info *info, uchar *buf);
|
extern int maria_rnext_same(MARIA_HA *info, uchar *buf);
|
||||||
extern int maria_rprev(struct st_maria_info *file, uchar *buf, int inx);
|
extern int maria_rprev(MARIA_HA *file, uchar *buf, int inx);
|
||||||
extern int maria_rrnd(struct st_maria_info *file, uchar *buf,
|
extern int maria_rrnd(MARIA_HA *file, uchar *buf,
|
||||||
MARIA_RECORD_POS pos);
|
MARIA_RECORD_POS pos);
|
||||||
extern int maria_scan_init(struct st_maria_info *file);
|
extern int maria_scan_init(MARIA_HA *file);
|
||||||
extern int maria_scan(struct st_maria_info *file, uchar *buf);
|
extern int maria_scan(MARIA_HA *file, uchar *buf);
|
||||||
extern void maria_scan_end(struct st_maria_info *file);
|
extern void maria_scan_end(MARIA_HA *file);
|
||||||
extern int maria_rsame(struct st_maria_info *file, uchar *record, int inx);
|
extern int maria_rsame(MARIA_HA *file, uchar *record, int inx);
|
||||||
extern int maria_rsame_with_pos(struct st_maria_info *file, uchar *record,
|
extern int maria_rsame_with_pos(MARIA_HA *file, uchar *record,
|
||||||
int inx, MARIA_RECORD_POS pos);
|
int inx, MARIA_RECORD_POS pos);
|
||||||
extern int maria_update(struct st_maria_info *file, const uchar *old,
|
extern int maria_update(MARIA_HA *file, const uchar *old,
|
||||||
uchar *new_record);
|
uchar *new_record);
|
||||||
extern int maria_write(struct st_maria_info *file, uchar *buff);
|
extern int maria_write(MARIA_HA *file, uchar *buff);
|
||||||
extern MARIA_RECORD_POS maria_position(struct st_maria_info *file);
|
extern MARIA_RECORD_POS maria_position(MARIA_HA *file);
|
||||||
extern int maria_status(struct st_maria_info *info, MARIA_INFO *x, uint flag);
|
extern int maria_status(MARIA_HA *info, MARIA_INFO *x, uint flag);
|
||||||
extern int maria_lock_database(struct st_maria_info *file, int lock_type);
|
extern int maria_lock_database(MARIA_HA *file, int lock_type);
|
||||||
extern int maria_create(const char *name, enum data_file_type record_type,
|
extern int maria_create(const char *name, enum data_file_type record_type,
|
||||||
uint keys, MARIA_KEYDEF *keydef,
|
uint keys, MARIA_KEYDEF *keydef,
|
||||||
uint columns, MARIA_COLUMNDEF *columndef,
|
uint columns, MARIA_COLUMNDEF *columndef,
|
||||||
@ -292,16 +293,16 @@ extern int maria_create(const char *name, enum data_file_type record_type,
|
|||||||
MARIA_CREATE_INFO *create_info, uint flags);
|
MARIA_CREATE_INFO *create_info, uint flags);
|
||||||
extern int maria_delete_table(const char *name);
|
extern int maria_delete_table(const char *name);
|
||||||
extern int maria_rename(const char *from, const char *to);
|
extern int maria_rename(const char *from, const char *to);
|
||||||
extern int maria_extra(struct st_maria_info *file,
|
extern int maria_extra(MARIA_HA *file,
|
||||||
enum ha_extra_function function, void *extra_arg);
|
enum ha_extra_function function, void *extra_arg);
|
||||||
extern int maria_reset(struct st_maria_info *file);
|
extern int maria_reset(MARIA_HA *file);
|
||||||
extern ha_rows maria_records_in_range(struct st_maria_info *info, int inx,
|
extern ha_rows maria_records_in_range(MARIA_HA *info, int inx,
|
||||||
key_range *min_key, key_range *max_key);
|
key_range *min_key, key_range *max_key);
|
||||||
extern int maria_is_changed(struct st_maria_info *info);
|
extern int maria_is_changed(MARIA_HA *info);
|
||||||
extern int maria_delete_all_rows(struct st_maria_info *info);
|
extern int maria_delete_all_rows(MARIA_HA *info);
|
||||||
extern uint maria_get_pointer_length(ulonglong file_length, uint def);
|
extern uint maria_get_pointer_length(ulonglong file_length, uint def);
|
||||||
extern int maria_commit(struct st_maria_info *info);
|
extern int maria_commit(MARIA_HA *info);
|
||||||
extern int maria_begin(struct st_maria_info *info);
|
extern int maria_begin(MARIA_HA *info);
|
||||||
|
|
||||||
/* this is used to pass to mysql_mariachk_table */
|
/* this is used to pass to mysql_mariachk_table */
|
||||||
|
|
||||||
@ -402,7 +403,7 @@ int maria_change_to_newfile(const char *filename, const char *old_ext,
|
|||||||
const char *new_ext, myf myflags);
|
const char *new_ext, myf myflags);
|
||||||
void maria_lock_memory(HA_CHECK *param);
|
void maria_lock_memory(HA_CHECK *param);
|
||||||
int maria_update_state_info(HA_CHECK *param, MARIA_HA *info, uint update);
|
int maria_update_state_info(HA_CHECK *param, MARIA_HA *info, uint update);
|
||||||
void maria_update_key_parts(MARIA_KEYDEF *keyinfo, ulong *rec_per_key_part,
|
void maria_update_key_parts(MARIA_KEYDEF *keyinfo, double *rec_per_key_part,
|
||||||
ulonglong *unique, ulonglong *notnull,
|
ulonglong *unique, ulonglong *notnull,
|
||||||
ulonglong records);
|
ulonglong records);
|
||||||
int maria_filecopy(HA_CHECK *param, File to, File from, my_off_t start,
|
int maria_filecopy(HA_CHECK *param, File to, File from, my_off_t start,
|
||||||
|
@ -293,6 +293,7 @@ enum ha_base_keytype {
|
|||||||
#define HA_OPTION_CREATE_FROM_ENGINE 256
|
#define HA_OPTION_CREATE_FROM_ENGINE 256
|
||||||
#define HA_OPTION_RELIES_ON_SQL_LAYER 512
|
#define HA_OPTION_RELIES_ON_SQL_LAYER 512
|
||||||
#define HA_OPTION_NULL_FIELDS 1024
|
#define HA_OPTION_NULL_FIELDS 1024
|
||||||
|
#define HA_OPTION_PAGE_CHECKSUM 2048
|
||||||
#define HA_OPTION_TEMP_COMPRESS_RECORD ((uint) 16384) /* set by isamchk */
|
#define HA_OPTION_TEMP_COMPRESS_RECORD ((uint) 16384) /* set by isamchk */
|
||||||
#define HA_OPTION_READ_ONLY_DATA ((uint) 32768) /* Set by isamchk */
|
#define HA_OPTION_READ_ONLY_DATA ((uint) 32768) /* Set by isamchk */
|
||||||
|
|
||||||
@ -302,6 +303,7 @@ enum ha_base_keytype {
|
|||||||
#define HA_PACK_RECORD 2 /* Request packed record format */
|
#define HA_PACK_RECORD 2 /* Request packed record format */
|
||||||
#define HA_CREATE_TMP_TABLE 4
|
#define HA_CREATE_TMP_TABLE 4
|
||||||
#define HA_CREATE_CHECKSUM 8
|
#define HA_CREATE_CHECKSUM 8
|
||||||
|
#define HA_CREATE_PAGE_CHECKSUM 16
|
||||||
#define HA_CREATE_DELAY_KEY_WRITE 64
|
#define HA_CREATE_DELAY_KEY_WRITE 64
|
||||||
#define HA_CREATE_RELIES_ON_SQL_LAYER 128
|
#define HA_CREATE_RELIES_ON_SQL_LAYER 128
|
||||||
|
|
||||||
@ -348,12 +350,15 @@ enum ha_base_keytype {
|
|||||||
*/
|
*/
|
||||||
#define HA_STATUS_AUTO 64
|
#define HA_STATUS_AUTO 64
|
||||||
|
|
||||||
/* Errorcodes given by functions */
|
/*
|
||||||
|
Errorcodes given by handler functions
|
||||||
|
|
||||||
|
opt_sum_query() assumes these codes are > 1
|
||||||
|
Do not add error numbers before HA_ERR_FIRST.
|
||||||
|
If necessary to add lower numbers, change HA_ERR_FIRST accordingly.
|
||||||
|
*/
|
||||||
|
#define HA_ERR_FIRST 120 /* Copy of first error nr.*/
|
||||||
|
|
||||||
/* opt_sum_query() assumes these codes are > 1 */
|
|
||||||
/* Do not add error numbers before HA_ERR_FIRST. */
|
|
||||||
/* If necessary to add lower numbers, change HA_ERR_FIRST accordingly. */
|
|
||||||
#define HA_ERR_FIRST 120 /*Copy first error nr.*/
|
|
||||||
#define HA_ERR_KEY_NOT_FOUND 120 /* Didn't find key on read or update */
|
#define HA_ERR_KEY_NOT_FOUND 120 /* Didn't find key on read or update */
|
||||||
#define HA_ERR_FOUND_DUPP_KEY 121 /* Dupplicate key on write */
|
#define HA_ERR_FOUND_DUPP_KEY 121 /* Dupplicate key on write */
|
||||||
#define HA_ERR_RECORD_CHANGED 123 /* Uppdate with is recoverable */
|
#define HA_ERR_RECORD_CHANGED 123 /* Uppdate with is recoverable */
|
||||||
@ -374,7 +379,7 @@ enum ha_base_keytype {
|
|||||||
#define HA_WRONG_CREATE_OPTION 140 /* Wrong create option */
|
#define HA_WRONG_CREATE_OPTION 140 /* Wrong create option */
|
||||||
#define HA_ERR_FOUND_DUPP_UNIQUE 141 /* Dupplicate unique on write */
|
#define HA_ERR_FOUND_DUPP_UNIQUE 141 /* Dupplicate unique on write */
|
||||||
#define HA_ERR_UNKNOWN_CHARSET 142 /* Can't open charset */
|
#define HA_ERR_UNKNOWN_CHARSET 142 /* Can't open charset */
|
||||||
#define HA_ERR_WRONG_MRG_TABLE_DEF 143 /* conflicting MyISAM tables in MERGE */
|
#define HA_ERR_WRONG_MRG_TABLE_DEF 143 /* conflicting tables in MERGE */
|
||||||
#define HA_ERR_CRASHED_ON_REPAIR 144 /* Last (automatic?) repair failed */
|
#define HA_ERR_CRASHED_ON_REPAIR 144 /* Last (automatic?) repair failed */
|
||||||
#define HA_ERR_CRASHED_ON_USAGE 145 /* Table must be repaired */
|
#define HA_ERR_CRASHED_ON_USAGE 145 /* Table must be repaired */
|
||||||
#define HA_ERR_LOCK_WAIT_TIMEOUT 146
|
#define HA_ERR_LOCK_WAIT_TIMEOUT 146
|
||||||
@ -389,28 +394,33 @@ enum ha_base_keytype {
|
|||||||
#define HA_ERR_NO_SUCH_TABLE 155 /* The table does not exist in engine */
|
#define HA_ERR_NO_SUCH_TABLE 155 /* The table does not exist in engine */
|
||||||
#define HA_ERR_TABLE_EXIST 156 /* The table existed in storage engine */
|
#define HA_ERR_TABLE_EXIST 156 /* The table existed in storage engine */
|
||||||
#define HA_ERR_NO_CONNECTION 157 /* Could not connect to storage engine */
|
#define HA_ERR_NO_CONNECTION 157 /* Could not connect to storage engine */
|
||||||
#define HA_ERR_NULL_IN_SPATIAL 158 /* NULLs are not supported in spatial index */
|
/* NULLs are not supported in spatial index */
|
||||||
|
#define HA_ERR_NULL_IN_SPATIAL 158
|
||||||
#define HA_ERR_TABLE_DEF_CHANGED 159 /* The table changed in storage engine */
|
#define HA_ERR_TABLE_DEF_CHANGED 159 /* The table changed in storage engine */
|
||||||
#define HA_ERR_NO_PARTITION_FOUND 160 /* There's no partition in table for
|
#define HA_ERR_NO_PARTITION_FOUND 160 /* There's no partition in table for
|
||||||
given value */
|
given value */
|
||||||
#define HA_ERR_RBR_LOGGING_FAILED 161 /* Row-based binlogging of row failed */
|
#define HA_ERR_RBR_LOGGING_FAILED 161 /* Row-based binlogging of row failed */
|
||||||
#define HA_ERR_DROP_INDEX_FK 162 /* Index needed in foreign key constr. */
|
#define HA_ERR_DROP_INDEX_FK 162 /* Index needed in foreign key constr */
|
||||||
#define HA_ERR_FOREIGN_DUPLICATE_KEY 163 /* Upholding foreign key constraints
|
/*
|
||||||
would lead to a duplicate key
|
Upholding foreign key constraints would lead to a duplicate key error
|
||||||
error in some other table. */
|
in some other table.
|
||||||
#define HA_ERR_TABLE_NEEDS_UPGRADE 164 /* The table changed in storage engine */
|
*/
|
||||||
#define HA_ERR_TABLE_READONLY 165 /* The table is not writable */
|
#define HA_ERR_FOREIGN_DUPLICATE_KEY 163
|
||||||
|
/* The table changed in storage engine */
|
||||||
|
#define HA_ERR_TABLE_NEEDS_UPGRADE 164
|
||||||
|
#define HA_ERR_TABLE_READONLY 165 /* The table is not writable */
|
||||||
|
|
||||||
#define HA_ERR_AUTOINC_READ_FAILED 166 /* Failed to get next autoinc value */
|
#define HA_ERR_AUTOINC_READ_FAILED 166 /* Failed to get next autoinc value */
|
||||||
#define HA_ERR_AUTOINC_ERANGE 167 /* Failed to set row autoinc value */
|
#define HA_ERR_AUTOINC_ERANGE 167 /* Failed to set row autoinc value */
|
||||||
#define HA_ERR_GENERIC 168 /* Generic error */
|
#define HA_ERR_GENERIC 168 /* Generic error */
|
||||||
#define HA_ERR_RECORD_IS_THE_SAME 169 /* row not actually updated :
|
/* row not actually updated: new values same as the old values */
|
||||||
new values same as the old values */
|
#define HA_ERR_RECORD_IS_THE_SAME 169
|
||||||
|
/* It is not possible to log this statement */
|
||||||
|
#define HA_ERR_LOGGING_IMPOSSIBLE 170
|
||||||
|
#define HA_ERR_NEW_FILE 171 /* New file format */
|
||||||
|
#define HA_ERR_LAST 171 /* Copy of last error nr */
|
||||||
|
|
||||||
#define HA_ERR_LOGGING_IMPOSSIBLE 170 /* It is not possible to log this
|
/* Number of different errors */
|
||||||
statement */
|
|
||||||
#define HA_ERR_LAST 170 /*Copy last error nr.*/
|
|
||||||
/* Add error numbers before HA_ERR_LAST and change it accordingly. */
|
|
||||||
#define HA_ERR_ERRORS (HA_ERR_LAST - HA_ERR_FIRST + 1)
|
#define HA_ERR_ERRORS (HA_ERR_LAST - HA_ERR_FIRST + 1)
|
||||||
|
|
||||||
/* Other constants */
|
/* Other constants */
|
||||||
|
@ -902,6 +902,18 @@ int my_getpagesize(void);
|
|||||||
|
|
||||||
int my_msync(int, void *, size_t, int);
|
int my_msync(int, void *, size_t, int);
|
||||||
|
|
||||||
|
#define MY_UUID_SIZE 16
|
||||||
|
void my_uuid_init(ulong seed1, ulong seed2);
|
||||||
|
void my_uuid(uchar *guid);
|
||||||
|
|
||||||
|
struct my_rnd_struct {
|
||||||
|
unsigned long seed1,seed2,max_value;
|
||||||
|
double max_value_dbl;
|
||||||
|
};
|
||||||
|
|
||||||
|
void my_rnd_init(struct my_rnd_struct *rand_st, ulong seed1, ulong seed2);
|
||||||
|
double my_rnd(struct my_rnd_struct *rand_st);
|
||||||
|
|
||||||
/* character sets */
|
/* character sets */
|
||||||
extern uint get_charset_number(const char *cs_name, uint cs_flags);
|
extern uint get_charset_number(const char *cs_name, uint cs_flags);
|
||||||
extern uint get_collation_number(const char *name);
|
extern uint get_collation_number(const char *name);
|
||||||
|
@ -128,9 +128,10 @@ typedef struct st_handler_check_param
|
|||||||
ha_checksum key_crc[HA_MAX_POSSIBLE_KEY];
|
ha_checksum key_crc[HA_MAX_POSSIBLE_KEY];
|
||||||
ha_checksum tmp_key_crc[HA_MAX_POSSIBLE_KEY];
|
ha_checksum tmp_key_crc[HA_MAX_POSSIBLE_KEY];
|
||||||
ha_checksum tmp_record_checksum;
|
ha_checksum tmp_record_checksum;
|
||||||
ulong use_buffers, read_buffer_length, write_buffer_length;
|
size_t use_buffers, read_buffer_length, write_buffer_length;
|
||||||
ulong sort_buffer_length, sort_key_blocks;
|
size_t sort_buffer_length, sort_key_blocks;
|
||||||
ulong rec_per_key_part[HA_MAX_KEY_SEG * HA_MAX_POSSIBLE_KEY];
|
ulong rec_per_key_part[HA_MAX_KEY_SEG * HA_MAX_POSSIBLE_KEY];
|
||||||
|
double new_rec_per_key_part[HA_MAX_KEY_SEG * HA_MAX_POSSIBLE_KEY];
|
||||||
uint out_flag, warning_printed, error_printed, verbose;
|
uint out_flag, warning_printed, error_printed, verbose;
|
||||||
uint opt_sort_key, total_files, max_level;
|
uint opt_sort_key, total_files, max_level;
|
||||||
uint testflag, key_cache_block_size, pagecache_block_size;
|
uint testflag, key_cache_block_size, pagecache_block_size;
|
||||||
|
@ -365,11 +365,7 @@ void my_net_set_read_timeout(NET *net, uint timeout);
|
|||||||
struct sockaddr;
|
struct sockaddr;
|
||||||
int my_connect(my_socket s, const struct sockaddr *name, unsigned int namelen,
|
int my_connect(my_socket s, const struct sockaddr *name, unsigned int namelen,
|
||||||
unsigned int timeout);
|
unsigned int timeout);
|
||||||
|
struct my_rnd_struct;
|
||||||
struct rand_struct {
|
|
||||||
unsigned long seed1,seed2,max_value;
|
|
||||||
double max_value_dbl;
|
|
||||||
};
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
@ -417,10 +413,8 @@ extern "C" {
|
|||||||
implemented in sql/password.c
|
implemented in sql/password.c
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void randominit(struct rand_struct *, unsigned long seed1,
|
void create_random_string(char *to, unsigned int length,
|
||||||
unsigned long seed2);
|
struct my_rnd_struct *rand_st);
|
||||||
double my_rnd(struct rand_struct *);
|
|
||||||
void create_random_string(char *to, unsigned int length, struct rand_struct *rand_st);
|
|
||||||
|
|
||||||
void hash_password(unsigned long *to, const char *password, unsigned int password_len);
|
void hash_password(unsigned long *to, const char *password, unsigned int password_len);
|
||||||
void make_scrambled_password_323(char *to, const char *password);
|
void make_scrambled_password_323(char *to, const char *password);
|
||||||
|
@ -68,7 +68,7 @@ mysysobjects1 = my_init.lo my_static.lo my_malloc.lo my_realloc.lo \
|
|||||||
mf_iocache2.lo my_seek.lo my_sleep.lo \
|
mf_iocache2.lo my_seek.lo my_sleep.lo \
|
||||||
my_pread.lo mf_cache.lo md5.lo sha1.lo \
|
my_pread.lo mf_cache.lo md5.lo sha1.lo \
|
||||||
my_getopt.lo my_gethostbyname.lo my_port.lo \
|
my_getopt.lo my_gethostbyname.lo my_port.lo \
|
||||||
my_rename.lo my_chsize.lo my_sync.lo
|
my_rename.lo my_chsize.lo my_sync.lo my_rnd.lo
|
||||||
sqlobjects = net.lo
|
sqlobjects = net.lo
|
||||||
sql_cmn_objects = pack.lo client.lo my_time.lo
|
sql_cmn_objects = pack.lo client.lo my_time.lo
|
||||||
|
|
||||||
|
@ -596,14 +596,14 @@ Error 1146 Table 'test.t3' doesn't exist
|
|||||||
checksum table t1, t2, t3;
|
checksum table t1, t2, t3;
|
||||||
Table Checksum
|
Table Checksum
|
||||||
test.t1 3442722830
|
test.t1 3442722830
|
||||||
test.t2 2948697075
|
test.t2 3442722830
|
||||||
test.t3 NULL
|
test.t3 NULL
|
||||||
Warnings:
|
Warnings:
|
||||||
Error 1146 Table 'test.t3' doesn't exist
|
Error 1146 Table 'test.t3' doesn't exist
|
||||||
checksum table t1, t2, t3 extended;
|
checksum table t1, t2, t3 extended;
|
||||||
Table Checksum
|
Table Checksum
|
||||||
test.t1 2948697075
|
test.t1 3442722830
|
||||||
test.t2 2948697075
|
test.t2 3442722830
|
||||||
test.t3 NULL
|
test.t3 NULL
|
||||||
Warnings:
|
Warnings:
|
||||||
Error 1146 Table 'test.t3' doesn't exist
|
Error 1146 Table 'test.t3' doesn't exist
|
||||||
@ -665,6 +665,25 @@ checksum table t2;
|
|||||||
Table Checksum
|
Table Checksum
|
||||||
test.t2 984116287
|
test.t2 984116287
|
||||||
drop table t1, t2;
|
drop table t1, t2;
|
||||||
|
CREATE TABLE t1 (
|
||||||
|
twenty int(4),
|
||||||
|
hundred int(4) NOT NULL
|
||||||
|
) CHECKSUM=1;
|
||||||
|
INSERT INTO t1 VALUES (11,91);
|
||||||
|
check table t1 extended;
|
||||||
|
Table Op Msg_type Msg_text
|
||||||
|
test.t1 check status OK
|
||||||
|
checksum table t1;
|
||||||
|
Table Checksum
|
||||||
|
test.t1 3235292310
|
||||||
|
checksum table t1 extended;
|
||||||
|
Table Checksum
|
||||||
|
test.t1 3235292310
|
||||||
|
alter table t1 engine=myisam;
|
||||||
|
checksum table t1;
|
||||||
|
Table Checksum
|
||||||
|
test.t1 3235292310
|
||||||
|
drop table t1;
|
||||||
show variables like 'maria_stats_method';
|
show variables like 'maria_stats_method';
|
||||||
Variable_name Value
|
Variable_name Value
|
||||||
maria_stats_method nulls_unequal
|
maria_stats_method nulls_unequal
|
||||||
@ -1836,23 +1855,39 @@ t1 CREATE TABLE `t1` (
|
|||||||
) ENGINE=MARIA DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC TRANSACTIONAL=0
|
) ENGINE=MARIA DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC TRANSACTIONAL=0
|
||||||
drop table t1;
|
drop table t1;
|
||||||
create table t1 (a int) row_format=dynamic transactional=1;
|
create table t1 (a int) row_format=dynamic transactional=1;
|
||||||
|
Warnings:
|
||||||
|
Note 1475 Row format set to PAGE because of TRANSACTIONAL=1 option
|
||||||
show create table t1;
|
show create table t1;
|
||||||
Table Create Table
|
Table Create Table
|
||||||
t1 CREATE TABLE `t1` (
|
t1 CREATE TABLE `t1` (
|
||||||
`a` int(11) DEFAULT NULL
|
`a` int(11) DEFAULT NULL
|
||||||
) ENGINE=MARIA DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC TRANSACTIONAL=1
|
) ENGINE=MARIA DEFAULT CHARSET=latin1 ROW_FORMAT=PAGE TRANSACTIONAL=1
|
||||||
alter table t1 row_format=PAGE;
|
alter table t1 row_format=PAGE;
|
||||||
show create table t1;
|
show create table t1;
|
||||||
Table Create Table
|
Table Create Table
|
||||||
t1 CREATE TABLE `t1` (
|
t1 CREATE TABLE `t1` (
|
||||||
`a` int(11) DEFAULT NULL
|
`a` int(11) DEFAULT NULL
|
||||||
) ENGINE=MARIA DEFAULT CHARSET=latin1 ROW_FORMAT=PAGE TRANSACTIONAL=1
|
) ENGINE=MARIA DEFAULT CHARSET=latin1 ROW_FORMAT=PAGE TRANSACTIONAL=1
|
||||||
|
alter table t1 row_format=DYNAMIC;
|
||||||
|
Warnings:
|
||||||
|
Note 1475 Row format set to PAGE because of TRANSACTIONAL=1 option
|
||||||
|
show create table t1;
|
||||||
|
Table Create Table
|
||||||
|
t1 CREATE TABLE `t1` (
|
||||||
|
`a` int(11) DEFAULT NULL
|
||||||
|
) ENGINE=MARIA DEFAULT CHARSET=latin1 ROW_FORMAT=PAGE TRANSACTIONAL=1
|
||||||
alter table t1 transactional=0;
|
alter table t1 transactional=0;
|
||||||
show create table t1;
|
show create table t1;
|
||||||
Table Create Table
|
Table Create Table
|
||||||
t1 CREATE TABLE `t1` (
|
t1 CREATE TABLE `t1` (
|
||||||
`a` int(11) DEFAULT NULL
|
`a` int(11) DEFAULT NULL
|
||||||
) ENGINE=MARIA DEFAULT CHARSET=latin1 ROW_FORMAT=PAGE TRANSACTIONAL=0
|
) ENGINE=MARIA DEFAULT CHARSET=latin1 ROW_FORMAT=PAGE TRANSACTIONAL=0
|
||||||
|
alter table t1 row_format=DYNAMIC;
|
||||||
|
show create table t1;
|
||||||
|
Table Create Table
|
||||||
|
t1 CREATE TABLE `t1` (
|
||||||
|
`a` int(11) DEFAULT NULL
|
||||||
|
) ENGINE=MARIA DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC TRANSACTIONAL=0
|
||||||
drop table t1;
|
drop table t1;
|
||||||
create table t1 (a int) row_format=PAGE;
|
create table t1 (a int) row_format=PAGE;
|
||||||
show create table t1;
|
show create table t1;
|
||||||
@ -1861,6 +1896,19 @@ t1 CREATE TABLE `t1` (
|
|||||||
`a` int(11) DEFAULT NULL
|
`a` int(11) DEFAULT NULL
|
||||||
) ENGINE=MARIA DEFAULT CHARSET=latin1 ROW_FORMAT=PAGE
|
) ENGINE=MARIA DEFAULT CHARSET=latin1 ROW_FORMAT=PAGE
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
create table t1 (a int) row_format=PAGE TRANSACTIONAL=DEFAULT;
|
||||||
|
show create table t1;
|
||||||
|
Table Create Table
|
||||||
|
t1 CREATE TABLE `t1` (
|
||||||
|
`a` int(11) DEFAULT NULL
|
||||||
|
) ENGINE=MARIA DEFAULT CHARSET=latin1 ROW_FORMAT=PAGE
|
||||||
|
alter table t1 row_format=DYNAMIC;
|
||||||
|
show create table t1;
|
||||||
|
Table Create Table
|
||||||
|
t1 CREATE TABLE `t1` (
|
||||||
|
`a` int(11) DEFAULT NULL
|
||||||
|
) ENGINE=MARIA DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC
|
||||||
|
drop table t1;
|
||||||
create table t1 (a int) row_format=page;
|
create table t1 (a int) row_format=page;
|
||||||
insert delayed into t1 values(1);
|
insert delayed into t1 values(1);
|
||||||
ERROR HY000: Table storage engine for 't1' doesn't have this option
|
ERROR HY000: Table storage engine for 't1' doesn't have this option
|
||||||
|
@ -638,6 +638,22 @@ checksum table t1;
|
|||||||
checksum table t2;
|
checksum table t2;
|
||||||
drop table t1, t2;
|
drop table t1, t2;
|
||||||
|
|
||||||
|
CREATE TABLE t1 (
|
||||||
|
twenty int(4),
|
||||||
|
hundred int(4) NOT NULL
|
||||||
|
) CHECKSUM=1;
|
||||||
|
INSERT INTO t1 VALUES (11,91);
|
||||||
|
check table t1 extended;
|
||||||
|
checksum table t1;
|
||||||
|
checksum table t1 extended;
|
||||||
|
alter table t1 row_format=static;
|
||||||
|
checksum table t1;
|
||||||
|
alter table t1 row_format=packed;
|
||||||
|
checksum table t1;
|
||||||
|
alter table t1 engine=myisam;
|
||||||
|
checksum table t1;
|
||||||
|
drop table t1;
|
||||||
|
|
||||||
#
|
#
|
||||||
# maria_stats_method variable.
|
# maria_stats_method variable.
|
||||||
#
|
#
|
||||||
@ -1130,12 +1146,21 @@ create table t1 (a int) row_format=dynamic transactional=1;
|
|||||||
show create table t1;
|
show create table t1;
|
||||||
alter table t1 row_format=PAGE;
|
alter table t1 row_format=PAGE;
|
||||||
show create table t1;
|
show create table t1;
|
||||||
|
alter table t1 row_format=DYNAMIC;
|
||||||
|
show create table t1;
|
||||||
alter table t1 transactional=0;
|
alter table t1 transactional=0;
|
||||||
show create table t1;
|
show create table t1;
|
||||||
|
alter table t1 row_format=DYNAMIC;
|
||||||
|
show create table t1;
|
||||||
drop table t1;
|
drop table t1;
|
||||||
create table t1 (a int) row_format=PAGE;
|
create table t1 (a int) row_format=PAGE;
|
||||||
show create table t1;
|
show create table t1;
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
create table t1 (a int) row_format=PAGE TRANSACTIONAL=DEFAULT;
|
||||||
|
show create table t1;
|
||||||
|
alter table t1 row_format=DYNAMIC;
|
||||||
|
show create table t1;
|
||||||
|
drop table t1;
|
||||||
|
|
||||||
# Verify that INSERT DELAYED is disabled only for transactional tables
|
# Verify that INSERT DELAYED is disabled only for transactional tables
|
||||||
create table t1 (a int) row_format=page;
|
create table t1 (a int) row_format=page;
|
||||||
|
@ -34,6 +34,7 @@ libmysys_a_SOURCES = my_init.c my_getwd.c mf_getdate.c my_mmap.c \
|
|||||||
my_vle.c my_atomic.c lf_hash.c \
|
my_vle.c my_atomic.c lf_hash.c \
|
||||||
lf_dynarray.c lf_alloc-pin.c \
|
lf_dynarray.c lf_alloc-pin.c \
|
||||||
my_fopen.c my_fstream.c my_getsystime.c \
|
my_fopen.c my_fstream.c my_getsystime.c \
|
||||||
|
my_rnd.c my_uuid.c \
|
||||||
my_error.c errors.c my_div.c my_messnc.c \
|
my_error.c errors.c my_div.c my_messnc.c \
|
||||||
mf_format.c mf_same.c mf_dirname.c mf_fn_ext.c \
|
mf_format.c mf_same.c mf_dirname.c mf_fn_ext.c \
|
||||||
my_symlink.c my_symlink2.c \
|
my_symlink.c my_symlink2.c \
|
||||||
|
55
mysys/my_rnd.c
Normal file
55
mysys/my_rnd.c
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
/* Copyright (C) 2007 MySQL AB & Michael Widenius
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; version 2 of the License.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
|
#include <mysys_priv.h>
|
||||||
|
#include <m_string.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
Initialize random generator
|
||||||
|
|
||||||
|
NOTES
|
||||||
|
MySQL's password checks depends on this, so don't do any changes
|
||||||
|
that changes the random numbers that are generated!
|
||||||
|
*/
|
||||||
|
|
||||||
|
void my_rnd_init(struct my_rnd_struct *rand_st, ulong seed1, ulong seed2)
|
||||||
|
{
|
||||||
|
#ifdef HAVE_purify
|
||||||
|
bzero((char*) rand_st,sizeof(*rand_st)); /* Avoid UMC varnings */
|
||||||
|
#endif
|
||||||
|
rand_st->max_value= 0x3FFFFFFFL;
|
||||||
|
rand_st->max_value_dbl=(double) rand_st->max_value;
|
||||||
|
rand_st->seed1=seed1%rand_st->max_value ;
|
||||||
|
rand_st->seed2=seed2%rand_st->max_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Generate random number.
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
my_rnd()
|
||||||
|
rand_st INOUT Structure used for number generation
|
||||||
|
|
||||||
|
RETURN VALUE
|
||||||
|
generated pseudo random number
|
||||||
|
*/
|
||||||
|
|
||||||
|
double my_rnd(struct my_rnd_struct *rand_st)
|
||||||
|
{
|
||||||
|
rand_st->seed1=(rand_st->seed1*3+rand_st->seed2) % rand_st->max_value;
|
||||||
|
rand_st->seed2=(rand_st->seed1+rand_st->seed2+33) % rand_st->max_value;
|
||||||
|
return (((double) rand_st->seed1)/rand_st->max_value_dbl);
|
||||||
|
}
|
169
mysys/my_uuid.c
Normal file
169
mysys/my_uuid.c
Normal file
@ -0,0 +1,169 @@
|
|||||||
|
/* Copyright (C) 2007 MySQL AB, Sergei Golubchik & Michael Widenius
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; version 2 of the License.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
|
/*
|
||||||
|
implements Universal Unique Identifiers (UUIDs), as in
|
||||||
|
DCE 1.1: Remote Procedure Call,
|
||||||
|
Open Group Technical Standard Document Number C706, October 1997,
|
||||||
|
(supersedes C309 DCE: Remote Procedure Call 8/1994,
|
||||||
|
which was basis for ISO/IEC 11578:1996 specification)
|
||||||
|
|
||||||
|
A UUID has the following structure:
|
||||||
|
|
||||||
|
Field NDR Data Type Octet # Note
|
||||||
|
time_low unsigned long 0-3 The low field of the
|
||||||
|
timestamp.
|
||||||
|
time_mid unsigned short 4-5 The middle field of
|
||||||
|
the timestamp.
|
||||||
|
time_hi_and_version unsigned short 6-7 The high field of the
|
||||||
|
timestamp multiplexed
|
||||||
|
with the version number.
|
||||||
|
clock_seq_hi_and_reserved unsigned small 8 The high field of the
|
||||||
|
clock sequence multi-
|
||||||
|
plexed with the variant.
|
||||||
|
clock_seq_low unsigned small 9 The low field of the
|
||||||
|
clock sequence.
|
||||||
|
node character 10-15 The spatially unique node
|
||||||
|
identifier.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "mysys_priv.h"
|
||||||
|
#include <m_string.h>
|
||||||
|
|
||||||
|
static my_bool my_uuid_inited= 0;
|
||||||
|
static struct my_rnd_struct uuid_rand;
|
||||||
|
static uint nanoseq;
|
||||||
|
static ulonglong uuid_time= 0;
|
||||||
|
static uchar uuid_suffix[2+6]; /* clock_seq and node */
|
||||||
|
|
||||||
|
#ifdef THREAD
|
||||||
|
pthread_mutex_t LOCK_uuid_generator;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
Number of 100-nanosecond intervals between
|
||||||
|
1582-10-15 00:00:00.00 and 1970-01-01 00:00:00.00
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define UUID_TIME_OFFSET ((ulonglong) 141427 * 24 * 60 * 60 * 1000 * 10)
|
||||||
|
#define UUID_VERSION 0x1000
|
||||||
|
#define UUID_VARIANT 0x8000
|
||||||
|
|
||||||
|
|
||||||
|
/* Helper function */
|
||||||
|
|
||||||
|
static void set_clock_seq()
|
||||||
|
{
|
||||||
|
uint16 clock_seq= ((uint)(my_rnd(&uuid_rand)*16383)) | UUID_VARIANT;
|
||||||
|
int2store(uuid_suffix, clock_seq);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Init structures needed for my_uuid
|
||||||
|
|
||||||
|
@func my_uuid_init()
|
||||||
|
@param seed1 Seed for random generator
|
||||||
|
@param seed2 Seed for random generator
|
||||||
|
|
||||||
|
@note
|
||||||
|
Seed1 & seed2 should NOT depend on clock. This is to be able to
|
||||||
|
generate a random mac address according to UUID specs.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void my_uuid_init(ulong seed1, ulong seed2)
|
||||||
|
{
|
||||||
|
uchar *mac= uuid_suffix+2;
|
||||||
|
ulonglong now;
|
||||||
|
|
||||||
|
if (my_uuid_inited)
|
||||||
|
return;
|
||||||
|
my_uuid_inited= 1;
|
||||||
|
now= my_getsystime();
|
||||||
|
nanoseq= 0;
|
||||||
|
|
||||||
|
if (my_gethwaddr(mac))
|
||||||
|
{
|
||||||
|
uint i;
|
||||||
|
/*
|
||||||
|
Generating random "hardware addr"
|
||||||
|
|
||||||
|
Specs explicitly specify that node identifier should NOT
|
||||||
|
correlate with a clock_seq value, so we use a separate
|
||||||
|
randominit() here.
|
||||||
|
*/
|
||||||
|
/* purecov: begin inspected */
|
||||||
|
my_rnd_init(&uuid_rand, (ulong) (seed2+ now/2), (seed1 + now)+random());
|
||||||
|
for (i=0; i < sizeof(mac); i++)
|
||||||
|
mac[i]= (uchar)(my_rnd(&uuid_rand)*255);
|
||||||
|
/* purecov: end */
|
||||||
|
}
|
||||||
|
my_rnd_init(&uuid_rand, (ulong) (seed1 + now),
|
||||||
|
(ulong) (now/2+ seed2 + getpid()));
|
||||||
|
set_clock_seq();
|
||||||
|
pthread_mutex_init(&LOCK_uuid_generator, MY_MUTEX_INIT_FAST);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Create a global unique identifier (uuid)
|
||||||
|
|
||||||
|
@func my_uuid()
|
||||||
|
@param to Store uuid here. Must be of size MY_uuid_SIZE (16)
|
||||||
|
*/
|
||||||
|
|
||||||
|
void my_uuid(uchar *to)
|
||||||
|
{
|
||||||
|
ulonglong tv;
|
||||||
|
uint32 time_low;
|
||||||
|
uint16 time_mid, time_hi_and_version;
|
||||||
|
|
||||||
|
DBUG_ASSERT(my_uuid_inited);
|
||||||
|
|
||||||
|
pthread_mutex_lock(&LOCK_uuid_generator);
|
||||||
|
tv= my_getsystime() + UUID_TIME_OFFSET + nanoseq;
|
||||||
|
if (unlikely(tv < uuid_time))
|
||||||
|
set_clock_seq();
|
||||||
|
else if (unlikely(tv == uuid_time))
|
||||||
|
{
|
||||||
|
/* special protection for low-res system clocks */
|
||||||
|
nanoseq++;
|
||||||
|
tv++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (nanoseq && likely(tv-nanoseq >= uuid_time))
|
||||||
|
{
|
||||||
|
tv-=nanoseq;
|
||||||
|
nanoseq=0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
uuid_time=tv;
|
||||||
|
pthread_mutex_unlock(&LOCK_uuid_generator);
|
||||||
|
|
||||||
|
time_low= (uint32) (tv & 0xFFFFFFFF);
|
||||||
|
time_mid= (uint16) ((tv >> 32) & 0xFFFF);
|
||||||
|
time_hi_and_version= (uint16) ((tv >> 48) | UUID_VERSION);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Note, that the standard does NOT specify byte ordering in
|
||||||
|
multi-byte fields. it's implementation defined (but must be
|
||||||
|
the same for all fields).
|
||||||
|
*/
|
||||||
|
int4store(to, time_low);
|
||||||
|
int2store(to+4, time_mid);
|
||||||
|
int2store(to+6, time_hi_and_version);
|
||||||
|
bmove(to+8, uuid_suffix, sizeof(uuid_suffix));
|
||||||
|
}
|
@ -17,12 +17,12 @@
|
|||||||
#pragma implementation
|
#pragma implementation
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "listener.h"
|
|
||||||
|
|
||||||
#include <my_global.h>
|
#include <my_global.h>
|
||||||
#include <mysql.h>
|
#include <mysql.h>
|
||||||
#include <violite.h>
|
#include <my_sys.h>
|
||||||
|
#include "listener.h"
|
||||||
|
|
||||||
|
#include <violite.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#ifndef __WIN__
|
#ifndef __WIN__
|
||||||
#include <sys/un.h>
|
#include <sys/un.h>
|
||||||
|
@ -17,13 +17,12 @@
|
|||||||
#pragma implementation
|
#pragma implementation
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "mysql_connection.h"
|
|
||||||
|
|
||||||
#include <m_string.h>
|
|
||||||
#include <m_string.h>
|
|
||||||
#include <my_global.h>
|
#include <my_global.h>
|
||||||
#include <mysql.h>
|
#include <mysql.h>
|
||||||
#include <my_sys.h>
|
#include <my_sys.h>
|
||||||
|
#include "mysql_connection.h"
|
||||||
|
|
||||||
|
#include <m_string.h>
|
||||||
#include <violite.h>
|
#include <violite.h>
|
||||||
|
|
||||||
#include "command.h"
|
#include "command.h"
|
||||||
@ -88,7 +87,7 @@ bool Mysql_connection::init()
|
|||||||
{
|
{
|
||||||
ulong seed1= (ulong) &rand_st + rand();
|
ulong seed1= (ulong) &rand_st + rand();
|
||||||
ulong seed2= (ulong) rand() + (ulong) time(0);
|
ulong seed2= (ulong) rand() + (ulong) time(0);
|
||||||
randominit(&rand_st, seed1, seed2);
|
my_rnd_init(&rand_st, seed1, seed2);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Fill scramble - server's random message used for handshake */
|
/* Fill scramble - server's random message used for handshake */
|
||||||
|
@ -17,7 +17,6 @@
|
|||||||
#define INCLUDES_MYSQL_INSTANCE_MANAGER_MYSQL_CONNECTION_H
|
#define INCLUDES_MYSQL_INSTANCE_MANAGER_MYSQL_CONNECTION_H
|
||||||
|
|
||||||
#include "thread_registry.h"
|
#include "thread_registry.h"
|
||||||
#include <mysql_com.h>
|
|
||||||
|
|
||||||
#if defined(__GNUC__) && defined(USE_PRAGMA_INTERFACE)
|
#if defined(__GNUC__) && defined(USE_PRAGMA_INTERFACE)
|
||||||
#pragma interface
|
#pragma interface
|
||||||
@ -55,7 +54,7 @@ private:
|
|||||||
Thread_registry *thread_registry;
|
Thread_registry *thread_registry;
|
||||||
User_map *user_map;
|
User_map *user_map;
|
||||||
NET net;
|
NET net;
|
||||||
struct rand_struct rand_st;
|
struct my_rnd_struct rand_st;
|
||||||
char scramble[SCRAMBLE_LENGTH + 1];
|
char scramble[SCRAMBLE_LENGTH + 1];
|
||||||
uint status;
|
uint status;
|
||||||
ulong client_capabilities;
|
ulong client_capabilities;
|
||||||
|
@ -327,6 +327,7 @@ enum enum_binlog_command {
|
|||||||
#define HA_CREATE_USED_CONNECTION (1L << 18)
|
#define HA_CREATE_USED_CONNECTION (1L << 18)
|
||||||
#define HA_CREATE_USED_KEY_BLOCK_SIZE (1L << 19)
|
#define HA_CREATE_USED_KEY_BLOCK_SIZE (1L << 19)
|
||||||
#define HA_CREATE_USED_TRANSACTIONAL (1L << 20)
|
#define HA_CREATE_USED_TRANSACTIONAL (1L << 20)
|
||||||
|
#define HA_CREATE_USED_PAGE_CHECKSUM (1L << 21)
|
||||||
|
|
||||||
typedef ulonglong my_xid; // this line is the same as in log_event.h
|
typedef ulonglong my_xid; // this line is the same as in log_event.h
|
||||||
#define MYSQL_XID_PREFIX "MySQLXid"
|
#define MYSQL_XID_PREFIX "MySQLXid"
|
||||||
@ -786,6 +787,7 @@ typedef struct st_ha_create_information
|
|||||||
bool frm_only; /* 1 if no ha_create_table() */
|
bool frm_only; /* 1 if no ha_create_table() */
|
||||||
bool varchar; /* 1 if table has a VARCHAR */
|
bool varchar; /* 1 if table has a VARCHAR */
|
||||||
enum ha_storage_media storage_media; /* DEFAULT, DISK or MEMORY */
|
enum ha_storage_media storage_media; /* DEFAULT, DISK or MEMORY */
|
||||||
|
enum ha_choice page_checksum; /* If we have page_checksums */
|
||||||
} HA_CREATE_INFO;
|
} HA_CREATE_INFO;
|
||||||
|
|
||||||
|
|
||||||
|
@ -2132,7 +2132,7 @@ void Item_func_rand::seed_random(Item *arg)
|
|||||||
args[0] is a constant.
|
args[0] is a constant.
|
||||||
*/
|
*/
|
||||||
uint32 tmp= (uint32) arg->val_int();
|
uint32 tmp= (uint32) arg->val_int();
|
||||||
randominit(rand, (uint32) (tmp*0x10001L+55555555L),
|
my_rnd_init(rand, (uint32) (tmp*0x10001L+55555555L),
|
||||||
(uint32) (tmp*0x10000001L));
|
(uint32) (tmp*0x10000001L));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2152,7 +2152,7 @@ bool Item_func_rand::fix_fields(THD *thd,Item **ref)
|
|||||||
No need to send a Rand log event if seed was given eg: RAND(seed),
|
No need to send a Rand log event if seed was given eg: RAND(seed),
|
||||||
as it will be replicated in the query as such.
|
as it will be replicated in the query as such.
|
||||||
*/
|
*/
|
||||||
if (!rand && !(rand= (struct rand_struct*)
|
if (!rand && !(rand= (struct my_rnd_struct*)
|
||||||
thd->stmt_arena->alloc(sizeof(*rand))))
|
thd->stmt_arena->alloc(sizeof(*rand))))
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
|
@ -664,7 +664,7 @@ public:
|
|||||||
|
|
||||||
class Item_func_rand :public Item_real_func
|
class Item_func_rand :public Item_real_func
|
||||||
{
|
{
|
||||||
struct rand_struct *rand;
|
struct my_rnd_struct *rand;
|
||||||
public:
|
public:
|
||||||
Item_func_rand(Item *a) :Item_real_func(a), rand(0) {}
|
Item_func_rand(Item *a) :Item_real_func(a), rand(0) {}
|
||||||
Item_func_rand() :Item_real_func() {}
|
Item_func_rand() :Item_real_func() {}
|
||||||
|
@ -3303,7 +3303,7 @@ err:
|
|||||||
which was basis for ISO/IEC 11578:1996 specification)
|
which was basis for ISO/IEC 11578:1996 specification)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static struct rand_struct uuid_rand;
|
static struct my_rnd_struct uuid_rand;
|
||||||
static uint nanoseq;
|
static uint nanoseq;
|
||||||
static ulonglong uuid_time=0;
|
static ulonglong uuid_time=0;
|
||||||
static char clock_seq_and_node_str[]="-0000-000000000000";
|
static char clock_seq_and_node_str[]="-0000-000000000000";
|
||||||
@ -3351,9 +3351,9 @@ String *Item_func_uuid::val_str(String *str)
|
|||||||
generating random "hardware addr"
|
generating random "hardware addr"
|
||||||
and because specs explicitly specify that it should NOT correlate
|
and because specs explicitly specify that it should NOT correlate
|
||||||
with a clock_seq value (initialized random below), we use a separate
|
with a clock_seq value (initialized random below), we use a separate
|
||||||
randominit() here
|
my_rnd_init() here
|
||||||
*/
|
*/
|
||||||
randominit(&uuid_rand, tmp + (ulong) thd, tmp + (ulong)global_query_id);
|
my_rnd_init(&uuid_rand, tmp + (ulong) thd, tmp + (ulong)global_query_id);
|
||||||
for (i=0; i < (int)sizeof(mac); i++)
|
for (i=0; i < (int)sizeof(mac); i++)
|
||||||
mac[i]=(uchar)(my_rnd(&uuid_rand)*255);
|
mac[i]=(uchar)(my_rnd(&uuid_rand)*255);
|
||||||
/* purecov: end */
|
/* purecov: end */
|
||||||
@ -3364,7 +3364,7 @@ String *Item_func_uuid::val_str(String *str)
|
|||||||
*--s=_dig_vec_lower[mac[i] & 15];
|
*--s=_dig_vec_lower[mac[i] & 15];
|
||||||
*--s=_dig_vec_lower[mac[i] >> 4];
|
*--s=_dig_vec_lower[mac[i] >> 4];
|
||||||
}
|
}
|
||||||
randominit(&uuid_rand, tmp + (ulong) server_start_time,
|
my_rnd_init(&uuid_rand, tmp + (ulong) server_start_time,
|
||||||
tmp + (ulong) thd->status_var.bytes_sent);
|
tmp + (ulong) thd->status_var.bytes_sent);
|
||||||
set_clock_seq_str();
|
set_clock_seq_str();
|
||||||
}
|
}
|
||||||
|
@ -381,6 +381,7 @@ static SYMBOL symbols[] = {
|
|||||||
{ "PACK_KEYS", SYM(PACK_KEYS_SYM)},
|
{ "PACK_KEYS", SYM(PACK_KEYS_SYM)},
|
||||||
{ "PARSER", SYM(PARSER_SYM)},
|
{ "PARSER", SYM(PARSER_SYM)},
|
||||||
{ "PAGE", SYM(PAGE_SYM)},
|
{ "PAGE", SYM(PAGE_SYM)},
|
||||||
|
{ "PAGE_CHECKSUM", SYM(PAGE_CHECKSUM_SYM)},
|
||||||
{ "PARTIAL", SYM(PARTIAL)},
|
{ "PARTIAL", SYM(PARTIAL)},
|
||||||
{ "PARTITION", SYM(PARTITION_SYM)},
|
{ "PARTITION", SYM(PARTITION_SYM)},
|
||||||
{ "PARTITIONING", SYM(PARTITIONING_SYM)},
|
{ "PARTITIONING", SYM(PARTITIONING_SYM)},
|
||||||
@ -513,7 +514,8 @@ static SYMBOL symbols[] = {
|
|||||||
{ "SUSPEND", SYM(SUSPEND_SYM)},
|
{ "SUSPEND", SYM(SUSPEND_SYM)},
|
||||||
{ "TABLE", SYM(TABLE_SYM)},
|
{ "TABLE", SYM(TABLE_SYM)},
|
||||||
{ "TABLES", SYM(TABLES)},
|
{ "TABLES", SYM(TABLES)},
|
||||||
{ "TABLESPACE", SYM(TABLESPACE)},
|
{ "TABLESPACE", SYM(TABLESPACE)},
|
||||||
|
{ "TABLE_CHECKSUM", SYM(TABLE_CHECKSUM_SYM)},
|
||||||
{ "TEMPORARY", SYM(TEMPORARY)},
|
{ "TEMPORARY", SYM(TEMPORARY)},
|
||||||
{ "TEMPTABLE", SYM(TEMPTABLE_SYM)},
|
{ "TEMPTABLE", SYM(TEMPTABLE_SYM)},
|
||||||
{ "TERMINATED", SYM(TERMINATED)},
|
{ "TERMINATED", SYM(TERMINATED)},
|
||||||
|
@ -1810,7 +1810,7 @@ extern SHOW_VAR status_vars[];
|
|||||||
extern struct system_variables global_system_variables;
|
extern struct system_variables global_system_variables;
|
||||||
extern struct system_variables max_system_variables;
|
extern struct system_variables max_system_variables;
|
||||||
extern struct system_status_var global_status_var;
|
extern struct system_status_var global_status_var;
|
||||||
extern struct rand_struct sql_rand;
|
extern struct my_rnd_struct sql_rand;
|
||||||
|
|
||||||
extern const char *opt_date_time_formats[];
|
extern const char *opt_date_time_formats[];
|
||||||
extern KNOWN_DATE_TIME_FORMAT known_date_time_formats[];
|
extern KNOWN_DATE_TIME_FORMAT known_date_time_formats[];
|
||||||
|
@ -610,7 +610,7 @@ static char **defaults_argv;
|
|||||||
static char *opt_bin_logname;
|
static char *opt_bin_logname;
|
||||||
|
|
||||||
static my_socket unix_sock,ip_sock;
|
static my_socket unix_sock,ip_sock;
|
||||||
struct rand_struct sql_rand; // used by sql_class.cc:THD::THD()
|
struct my_rnd_struct sql_rand; // used by sql_class.cc:THD::THD()
|
||||||
|
|
||||||
#ifndef EMBEDDED_LIBRARY
|
#ifndef EMBEDDED_LIBRARY
|
||||||
struct passwd *user_info;
|
struct passwd *user_info;
|
||||||
@ -3239,7 +3239,7 @@ static int init_server_components()
|
|||||||
query_cache_set_min_res_unit(query_cache_min_res_unit);
|
query_cache_set_min_res_unit(query_cache_min_res_unit);
|
||||||
query_cache_init();
|
query_cache_init();
|
||||||
query_cache_resize(query_cache_size);
|
query_cache_resize(query_cache_size);
|
||||||
randominit(&sql_rand,(ulong) server_start_time,(ulong) server_start_time/2);
|
my_rnd_init(&sql_rand,(ulong) server_start_time,(ulong) server_start_time/2);
|
||||||
reset_floating_point_exceptions();
|
reset_floating_point_exceptions();
|
||||||
init_thr_lock();
|
init_thr_lock();
|
||||||
#ifdef HAVE_REPLICATION
|
#ifdef HAVE_REPLICATION
|
||||||
|
@ -69,41 +69,12 @@
|
|||||||
/*
|
/*
|
||||||
New (MySQL 3.21+) random generation structure initialization
|
New (MySQL 3.21+) random generation structure initialization
|
||||||
SYNOPSIS
|
SYNOPSIS
|
||||||
randominit()
|
my_rnd_init()
|
||||||
rand_st OUT Structure to initialize
|
rand_st OUT Structure to initialize
|
||||||
seed1 IN First initialization parameter
|
seed1 IN First initialization parameter
|
||||||
seed2 IN Second initialization parameter
|
seed2 IN Second initialization parameter
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void randominit(struct rand_struct *rand_st, ulong seed1, ulong seed2)
|
|
||||||
{ /* For mysql 3.21.# */
|
|
||||||
#ifdef HAVE_purify
|
|
||||||
bzero((char*) rand_st,sizeof(*rand_st)); /* Avoid UMC varnings */
|
|
||||||
#endif
|
|
||||||
rand_st->max_value= 0x3FFFFFFFL;
|
|
||||||
rand_st->max_value_dbl=(double) rand_st->max_value;
|
|
||||||
rand_st->seed1=seed1%rand_st->max_value ;
|
|
||||||
rand_st->seed2=seed2%rand_st->max_value;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
Generate random number.
|
|
||||||
SYNOPSIS
|
|
||||||
my_rnd()
|
|
||||||
rand_st INOUT Structure used for number generation
|
|
||||||
RETURN VALUE
|
|
||||||
generated pseudo random number
|
|
||||||
*/
|
|
||||||
|
|
||||||
double my_rnd(struct rand_struct *rand_st)
|
|
||||||
{
|
|
||||||
rand_st->seed1=(rand_st->seed1*3+rand_st->seed2) % rand_st->max_value;
|
|
||||||
rand_st->seed2=(rand_st->seed1+rand_st->seed2+33) % rand_st->max_value;
|
|
||||||
return (((double) rand_st->seed1)/rand_st->max_value_dbl);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Generate binary hash from raw text string
|
Generate binary hash from raw text string
|
||||||
Used for Pre-4.1 password handling
|
Used for Pre-4.1 password handling
|
||||||
@ -164,7 +135,7 @@ void make_scrambled_password_323(char *to, const char *password)
|
|||||||
|
|
||||||
void scramble_323(char *to, const char *message, const char *password)
|
void scramble_323(char *to, const char *message, const char *password)
|
||||||
{
|
{
|
||||||
struct rand_struct rand_st;
|
struct my_rnd_struct rand_st;
|
||||||
ulong hash_pass[2], hash_message[2];
|
ulong hash_pass[2], hash_message[2];
|
||||||
|
|
||||||
if (password && password[0])
|
if (password && password[0])
|
||||||
@ -173,7 +144,7 @@ void scramble_323(char *to, const char *message, const char *password)
|
|||||||
const char *message_end= message + SCRAMBLE_LENGTH_323;
|
const char *message_end= message + SCRAMBLE_LENGTH_323;
|
||||||
hash_password(hash_pass,password, (uint) strlen(password));
|
hash_password(hash_pass,password, (uint) strlen(password));
|
||||||
hash_password(hash_message, message, SCRAMBLE_LENGTH_323);
|
hash_password(hash_message, message, SCRAMBLE_LENGTH_323);
|
||||||
randominit(&rand_st,hash_pass[0] ^ hash_message[0],
|
my_rnd_init(&rand_st,hash_pass[0] ^ hash_message[0],
|
||||||
hash_pass[1] ^ hash_message[1]);
|
hash_pass[1] ^ hash_message[1]);
|
||||||
for (; message < message_end; message++)
|
for (; message < message_end; message++)
|
||||||
*to++= (char) (floor(my_rnd(&rand_st)*31)+64);
|
*to++= (char) (floor(my_rnd(&rand_st)*31)+64);
|
||||||
@ -206,13 +177,13 @@ my_bool
|
|||||||
check_scramble_323(const char *scrambled, const char *message,
|
check_scramble_323(const char *scrambled, const char *message,
|
||||||
ulong *hash_pass)
|
ulong *hash_pass)
|
||||||
{
|
{
|
||||||
struct rand_struct rand_st;
|
struct my_rnd_struct rand_st;
|
||||||
ulong hash_message[2];
|
ulong hash_message[2];
|
||||||
char buff[16],*to,extra; /* Big enough for check */
|
char buff[16],*to,extra; /* Big enough for check */
|
||||||
const char *pos;
|
const char *pos;
|
||||||
|
|
||||||
hash_password(hash_message, message, SCRAMBLE_LENGTH_323);
|
hash_password(hash_message, message, SCRAMBLE_LENGTH_323);
|
||||||
randominit(&rand_st,hash_pass[0] ^ hash_message[0],
|
my_rnd_init(&rand_st,hash_pass[0] ^ hash_message[0],
|
||||||
hash_pass[1] ^ hash_message[1]);
|
hash_pass[1] ^ hash_message[1]);
|
||||||
to=buff;
|
to=buff;
|
||||||
DBUG_ASSERT(sizeof(buff) > SCRAMBLE_LENGTH_323);
|
DBUG_ASSERT(sizeof(buff) > SCRAMBLE_LENGTH_323);
|
||||||
@ -293,7 +264,8 @@ void make_password_from_salt_323(char *to, const ulong *salt)
|
|||||||
rand_st INOUT structure used for number generation
|
rand_st INOUT structure used for number generation
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void create_random_string(char *to, uint length, struct rand_struct *rand_st)
|
void create_random_string(char *to, uint length,
|
||||||
|
struct my_rnd_struct *rand_st)
|
||||||
{
|
{
|
||||||
char *end= to + length;
|
char *end= to + length;
|
||||||
/* Use pointer arithmetics as it is faster way to do so. */
|
/* Use pointer arithmetics as it is faster way to do so. */
|
||||||
|
@ -446,7 +446,7 @@ THD::THD()
|
|||||||
|
|
||||||
tablespace_op=FALSE;
|
tablespace_op=FALSE;
|
||||||
tmp= sql_rnd_with_mutex();
|
tmp= sql_rnd_with_mutex();
|
||||||
randominit(&rand, tmp + (ulong) &rand, tmp + (ulong) ::global_query_id);
|
my_rnd_init(&rand, tmp + (ulong) &rand, tmp + (ulong) ::global_query_id);
|
||||||
substitute_null_with_insert_id = FALSE;
|
substitute_null_with_insert_id = FALSE;
|
||||||
thr_lock_info_init(&lock_info); /* safety: will be reset after start */
|
thr_lock_info_init(&lock_info); /* safety: will be reset after start */
|
||||||
thr_lock_owner_init(&main_lock_id, &lock_info);
|
thr_lock_owner_init(&main_lock_id, &lock_info);
|
||||||
|
@ -993,7 +993,7 @@ public:
|
|||||||
String packet; // dynamic buffer for network I/O
|
String packet; // dynamic buffer for network I/O
|
||||||
String convert_buffer; // buffer for charset conversions
|
String convert_buffer; // buffer for charset conversions
|
||||||
struct sockaddr_in remote; // client socket address
|
struct sockaddr_in remote; // client socket address
|
||||||
struct rand_struct rand; // used for authentication
|
struct my_rnd_struct rand; // used for authentication
|
||||||
struct system_variables variables; // Changeable local variables
|
struct system_variables variables; // Changeable local variables
|
||||||
struct system_status_var status_var; // Per thread statistic vars
|
struct system_status_var status_var; // Per thread statistic vars
|
||||||
struct system_status_var *initial_status_var; /* used by show status */
|
struct system_status_var *initial_status_var; /* used by show status */
|
||||||
|
@ -38,7 +38,7 @@ SQL_CRYPT::SQL_CRYPT(const char *password)
|
|||||||
void SQL_CRYPT::crypt_init(ulong *rand_nr)
|
void SQL_CRYPT::crypt_init(ulong *rand_nr)
|
||||||
{
|
{
|
||||||
uint i;
|
uint i;
|
||||||
randominit(&rand,rand_nr[0],rand_nr[1]);
|
my_rnd_init(&rand,rand_nr[0],rand_nr[1]);
|
||||||
|
|
||||||
for (i=0 ; i<=255; i++)
|
for (i=0 ; i<=255; i++)
|
||||||
decode_buff[i]= (char) i;
|
decode_buff[i]= (char) i;
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
|
|
||||||
class SQL_CRYPT :public Sql_alloc
|
class SQL_CRYPT :public Sql_alloc
|
||||||
{
|
{
|
||||||
struct rand_struct rand,org_rand;
|
struct my_rnd_struct rand,org_rand;
|
||||||
char decode_buff[256],encode_buff[256];
|
char decode_buff[256],encode_buff[256];
|
||||||
uint shift;
|
uint shift;
|
||||||
void crypt_init(ulong *seed);
|
void crypt_init(ulong *seed);
|
||||||
|
@ -70,6 +70,9 @@ static TYPELIB grant_types = { sizeof(grant_names)/sizeof(char **),
|
|||||||
grant_names, NULL};
|
grant_names, NULL};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Match the values of enum ha_choice */
|
||||||
|
static const char *ha_choice_values[] = {"", "0", "1"};
|
||||||
|
|
||||||
static void store_key_options(THD *thd, String *packet, TABLE *table,
|
static void store_key_options(THD *thd, String *packet, TABLE *table,
|
||||||
KEY *key_info);
|
KEY *key_info);
|
||||||
|
|
||||||
@ -1153,6 +1156,8 @@ int store_create_info(THD *thd, TABLE_LIST *table_list, String *packet,
|
|||||||
|
|
||||||
key_info= table->key_info;
|
key_info= table->key_info;
|
||||||
bzero((char*) &create_info, sizeof(create_info));
|
bzero((char*) &create_info, sizeof(create_info));
|
||||||
|
/* Allow update_create_info to update row type */
|
||||||
|
create_info.row_type= share->row_type;
|
||||||
file->update_create_info(&create_info);
|
file->update_create_info(&create_info);
|
||||||
primary_key= share->primary_key;
|
primary_key= share->primary_key;
|
||||||
|
|
||||||
@ -1337,19 +1342,25 @@ int store_create_info(THD *thd, TABLE_LIST *table_list, String *packet,
|
|||||||
packet->append(STRING_WITH_LEN(" PACK_KEYS=1"));
|
packet->append(STRING_WITH_LEN(" PACK_KEYS=1"));
|
||||||
if (share->db_create_options & HA_OPTION_NO_PACK_KEYS)
|
if (share->db_create_options & HA_OPTION_NO_PACK_KEYS)
|
||||||
packet->append(STRING_WITH_LEN(" PACK_KEYS=0"));
|
packet->append(STRING_WITH_LEN(" PACK_KEYS=0"));
|
||||||
|
/* We use CHECKSUM, instead of TABLE_CHECKSUM, for backward compability */
|
||||||
if (share->db_create_options & HA_OPTION_CHECKSUM)
|
if (share->db_create_options & HA_OPTION_CHECKSUM)
|
||||||
packet->append(STRING_WITH_LEN(" CHECKSUM=1"));
|
packet->append(STRING_WITH_LEN(" CHECKSUM=1"));
|
||||||
|
if (share->page_checksum != HA_CHOICE_UNDEF)
|
||||||
|
{
|
||||||
|
packet->append(STRING_WITH_LEN(" PAGE_CHECKSUM="));
|
||||||
|
packet->append(ha_choice_values[(uint) share->page_checksum], 1);
|
||||||
|
}
|
||||||
if (share->db_create_options & HA_OPTION_DELAY_KEY_WRITE)
|
if (share->db_create_options & HA_OPTION_DELAY_KEY_WRITE)
|
||||||
packet->append(STRING_WITH_LEN(" DELAY_KEY_WRITE=1"));
|
packet->append(STRING_WITH_LEN(" DELAY_KEY_WRITE=1"));
|
||||||
if (share->row_type != ROW_TYPE_DEFAULT)
|
if (create_info.row_type != ROW_TYPE_DEFAULT)
|
||||||
{
|
{
|
||||||
packet->append(STRING_WITH_LEN(" ROW_FORMAT="));
|
packet->append(STRING_WITH_LEN(" ROW_FORMAT="));
|
||||||
packet->append(ha_row_type[(uint) share->row_type]);
|
packet->append(ha_row_type[(uint) create_info.row_type]);
|
||||||
}
|
}
|
||||||
if (share->transactional != HA_CHOICE_UNDEF)
|
if (share->transactional != HA_CHOICE_UNDEF)
|
||||||
{
|
{
|
||||||
packet->append(STRING_WITH_LEN(" TRANSACTIONAL="));
|
packet->append(STRING_WITH_LEN(" TRANSACTIONAL="));
|
||||||
packet->append(share->transactional == HA_CHOICE_YES ? "1" : "0", 1);
|
packet->append(ha_choice_values[(uint) share->transactional], 1);
|
||||||
}
|
}
|
||||||
if (table->s->key_block_size)
|
if (table->s->key_block_size)
|
||||||
{
|
{
|
||||||
@ -3001,8 +3012,12 @@ static int get_schema_tables_record(THD *thd, struct st_table_list *tables,
|
|||||||
ptr=strmov(ptr," pack_keys=1");
|
ptr=strmov(ptr," pack_keys=1");
|
||||||
if (share->db_create_options & HA_OPTION_NO_PACK_KEYS)
|
if (share->db_create_options & HA_OPTION_NO_PACK_KEYS)
|
||||||
ptr=strmov(ptr," pack_keys=0");
|
ptr=strmov(ptr," pack_keys=0");
|
||||||
|
/* We use CHECKSUM, instead of TABLE_CHECKSUM, for backward compability */
|
||||||
if (share->db_create_options & HA_OPTION_CHECKSUM)
|
if (share->db_create_options & HA_OPTION_CHECKSUM)
|
||||||
ptr=strmov(ptr," checksum=1");
|
ptr=strmov(ptr," checksum=1");
|
||||||
|
if (share->page_checksum != HA_CHOICE_UNDEF)
|
||||||
|
ptr= strxmov(ptr, " page_checksum=",
|
||||||
|
ha_choice_values[(uint) share->page_checksum], NullS);
|
||||||
if (share->db_create_options & HA_OPTION_DELAY_KEY_WRITE)
|
if (share->db_create_options & HA_OPTION_DELAY_KEY_WRITE)
|
||||||
ptr=strmov(ptr," delay_key_write=1");
|
ptr=strmov(ptr," delay_key_write=1");
|
||||||
if (share->row_type != ROW_TYPE_DEFAULT)
|
if (share->row_type != ROW_TYPE_DEFAULT)
|
||||||
@ -3015,6 +3030,9 @@ static int get_schema_tables_record(THD *thd, struct st_table_list *tables,
|
|||||||
show_table->part_info->no_parts > 0)
|
show_table->part_info->no_parts > 0)
|
||||||
ptr= strmov(ptr, " partitioned");
|
ptr= strmov(ptr, " partitioned");
|
||||||
#endif
|
#endif
|
||||||
|
if (share->transactional != HA_CHOICE_UNDEF)
|
||||||
|
ptr= strxmov(ptr, " transactional=",
|
||||||
|
ha_choice_values[(uint) share->transactional], NullS);
|
||||||
table->field[19]->store(option_buff+1,
|
table->field[19]->store(option_buff+1,
|
||||||
(ptr == option_buff ? 0 :
|
(ptr == option_buff ? 0 :
|
||||||
(uint) (ptr-option_buff)-1), cs);
|
(uint) (ptr-option_buff)-1), cs);
|
||||||
|
@ -7082,10 +7082,9 @@ bool mysql_checksum_table(THD *thd, TABLE_LIST *tables,
|
|||||||
for (uint i= 0; i < t->s->fields; i++ )
|
for (uint i= 0; i < t->s->fields; i++ )
|
||||||
{
|
{
|
||||||
Field *f= t->field[i];
|
Field *f= t->field[i];
|
||||||
#ifdef NOT_YET
|
if (! thd->variables.old_mode &&
|
||||||
if (f->is_real_null(0))
|
f->is_real_null(0))
|
||||||
continue;
|
continue;
|
||||||
#endif
|
|
||||||
if ((f->type() == MYSQL_TYPE_BLOB) ||
|
if ((f->type() == MYSQL_TYPE_BLOB) ||
|
||||||
(f->type() == MYSQL_TYPE_VARCHAR))
|
(f->type() == MYSQL_TYPE_VARCHAR))
|
||||||
{
|
{
|
||||||
|
@ -470,6 +470,7 @@ Item* handle_sql2003_note184_exception(THD *thd, Item* left, bool equal,
|
|||||||
enum enum_tx_isolation tx_isolation;
|
enum enum_tx_isolation tx_isolation;
|
||||||
enum Cast_target cast_type;
|
enum Cast_target cast_type;
|
||||||
enum Item_udftype udf_type;
|
enum Item_udftype udf_type;
|
||||||
|
enum ha_choice choice;
|
||||||
CHARSET_INFO *charset;
|
CHARSET_INFO *charset;
|
||||||
thr_lock_type lock_type;
|
thr_lock_type lock_type;
|
||||||
interval_type interval, interval_time_st;
|
interval_type interval, interval_time_st;
|
||||||
@ -858,6 +859,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
|
|||||||
%token OWNER_SYM
|
%token OWNER_SYM
|
||||||
%token PACK_KEYS_SYM
|
%token PACK_KEYS_SYM
|
||||||
%token PAGE_SYM
|
%token PAGE_SYM
|
||||||
|
%token PAGE_CHECKSUM_SYM
|
||||||
%token PARAM_MARKER
|
%token PARAM_MARKER
|
||||||
%token PARSER_SYM
|
%token PARSER_SYM
|
||||||
%token PARTIAL /* SQL-2003-N */
|
%token PARTIAL /* SQL-2003-N */
|
||||||
@ -993,6 +995,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
|
|||||||
%token TABLESPACE
|
%token TABLESPACE
|
||||||
%token TABLE_REF_PRIORITY
|
%token TABLE_REF_PRIORITY
|
||||||
%token TABLE_SYM /* SQL-2003-R */
|
%token TABLE_SYM /* SQL-2003-R */
|
||||||
|
%token TABLE_CHECKSUM_SYM
|
||||||
%token TEMPORARY /* SQL-2003-N */
|
%token TEMPORARY /* SQL-2003-N */
|
||||||
%token TEMPTABLE_SYM
|
%token TEMPTABLE_SYM
|
||||||
%token TERMINATED
|
%token TERMINATED
|
||||||
@ -1126,6 +1129,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
|
|||||||
%type <ulonglong_number>
|
%type <ulonglong_number>
|
||||||
ulonglong_num real_ulonglong_num size_number
|
ulonglong_num real_ulonglong_num size_number
|
||||||
|
|
||||||
|
%type <choice> choice
|
||||||
|
|
||||||
%type <p_elem_value>
|
%type <p_elem_value>
|
||||||
part_bit_expr
|
part_bit_expr
|
||||||
|
|
||||||
@ -4335,6 +4340,12 @@ create_table_option:
|
|||||||
Lex->create_info.used_fields|= HA_CREATE_USED_PACK_KEYS;
|
Lex->create_info.used_fields|= HA_CREATE_USED_PACK_KEYS;
|
||||||
}
|
}
|
||||||
| CHECKSUM_SYM opt_equal ulong_num { Lex->create_info.table_options|= $3 ? HA_OPTION_CHECKSUM : HA_OPTION_NO_CHECKSUM; Lex->create_info.used_fields|= HA_CREATE_USED_CHECKSUM; }
|
| CHECKSUM_SYM opt_equal ulong_num { Lex->create_info.table_options|= $3 ? HA_OPTION_CHECKSUM : HA_OPTION_NO_CHECKSUM; Lex->create_info.used_fields|= HA_CREATE_USED_CHECKSUM; }
|
||||||
|
| TABLE_CHECKSUM_SYM opt_equal ulong_num { Lex->create_info.table_options|= $3 ? HA_OPTION_CHECKSUM : HA_OPTION_NO_CHECKSUM; Lex->create_info.used_fields|= HA_CREATE_USED_CHECKSUM; }
|
||||||
|
| PAGE_CHECKSUM_SYM opt_equal choice
|
||||||
|
{
|
||||||
|
Lex->create_info.used_fields|= HA_CREATE_USED_PAGE_CHECKSUM;
|
||||||
|
Lex->create_info.page_checksum= $3;
|
||||||
|
}
|
||||||
| DELAY_KEY_WRITE_SYM opt_equal ulong_num { Lex->create_info.table_options|= $3 ? HA_OPTION_DELAY_KEY_WRITE : HA_OPTION_NO_DELAY_KEY_WRITE; Lex->create_info.used_fields|= HA_CREATE_USED_DELAY_KEY_WRITE; }
|
| DELAY_KEY_WRITE_SYM opt_equal ulong_num { Lex->create_info.table_options|= $3 ? HA_OPTION_DELAY_KEY_WRITE : HA_OPTION_NO_DELAY_KEY_WRITE; Lex->create_info.used_fields|= HA_CREATE_USED_DELAY_KEY_WRITE; }
|
||||||
| ROW_FORMAT_SYM opt_equal row_types { Lex->create_info.row_type= $3; Lex->create_info.used_fields|= HA_CREATE_USED_ROW_FORMAT; }
|
| ROW_FORMAT_SYM opt_equal row_types { Lex->create_info.row_type= $3; Lex->create_info.used_fields|= HA_CREATE_USED_ROW_FORMAT; }
|
||||||
| UNION_SYM opt_equal '(' table_list ')'
|
| UNION_SYM opt_equal '(' table_list ')'
|
||||||
@ -4366,11 +4377,10 @@ create_table_option:
|
|||||||
Lex->create_info.used_fields|= HA_CREATE_USED_KEY_BLOCK_SIZE;
|
Lex->create_info.used_fields|= HA_CREATE_USED_KEY_BLOCK_SIZE;
|
||||||
Lex->create_info.key_block_size= $3;
|
Lex->create_info.key_block_size= $3;
|
||||||
}
|
}
|
||||||
| TRANSACTIONAL_SYM opt_equal ulong_num
|
| TRANSACTIONAL_SYM opt_equal choice
|
||||||
{
|
{
|
||||||
Lex->create_info.used_fields|= HA_CREATE_USED_TRANSACTIONAL;
|
Lex->create_info.used_fields|= HA_CREATE_USED_TRANSACTIONAL;
|
||||||
Lex->create_info.transactional= ($3 != 0 ? HA_CHOICE_YES :
|
Lex->create_info.transactional= $3;
|
||||||
HA_CHOICE_NO);
|
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
@ -8000,6 +8010,11 @@ dec_num:
|
|||||||
| FLOAT_NUM
|
| FLOAT_NUM
|
||||||
;
|
;
|
||||||
|
|
||||||
|
choice:
|
||||||
|
ulong_num { $$= $1 != 0 ? HA_CHOICE_YES : HA_CHOICE_NO; }
|
||||||
|
| DEFAULT { $$= HA_CHOICE_UNDEF; }
|
||||||
|
;
|
||||||
|
|
||||||
procedure_clause:
|
procedure_clause:
|
||||||
/* empty */
|
/* empty */
|
||||||
| PROCEDURE ident /* Procedure name */
|
| PROCEDURE ident /* Procedure name */
|
||||||
@ -10046,6 +10061,7 @@ keyword_sp:
|
|||||||
| ONE_SYM {}
|
| ONE_SYM {}
|
||||||
| PACK_KEYS_SYM {}
|
| PACK_KEYS_SYM {}
|
||||||
| PAGE_SYM {}
|
| PAGE_SYM {}
|
||||||
|
| PAGE_CHECKSUM_SYM {}
|
||||||
| PARTIAL {}
|
| PARTIAL {}
|
||||||
| PARTITIONING_SYM {}
|
| PARTITIONING_SYM {}
|
||||||
| PARTITIONS_SYM {}
|
| PARTITIONS_SYM {}
|
||||||
@ -10108,6 +10124,7 @@ keyword_sp:
|
|||||||
| SUBPARTITIONS_SYM {}
|
| SUBPARTITIONS_SYM {}
|
||||||
| SUPER_SYM {}
|
| SUPER_SYM {}
|
||||||
| SUSPEND_SYM {}
|
| SUSPEND_SYM {}
|
||||||
|
| TABLE_CHECKSUM_SYM {}
|
||||||
| TABLES {}
|
| TABLES {}
|
||||||
| TABLESPACE {}
|
| TABLESPACE {}
|
||||||
| TEMPORARY {}
|
| TEMPORARY {}
|
||||||
|
@ -655,7 +655,8 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
|
|||||||
if (!head[32]) // New frm file in 3.23
|
if (!head[32]) // New frm file in 3.23
|
||||||
{
|
{
|
||||||
share->avg_row_length= uint4korr(head+34);
|
share->avg_row_length= uint4korr(head+34);
|
||||||
share->transactional= (ha_choice) head[39];
|
share->transactional= (ha_choice) (head[39] & 3);
|
||||||
|
share->page_checksum= (ha_choice) ((head[39] >> 2) & 3);
|
||||||
share->row_type= (row_type) head[40];
|
share->row_type= (row_type) head[40];
|
||||||
share->table_charset= get_charset((uint) head[38],MYF(0));
|
share->table_charset= get_charset((uint) head[38],MYF(0));
|
||||||
share->null_field_first= 1;
|
share->null_field_first= 1;
|
||||||
@ -2373,7 +2374,8 @@ File create_frm(THD *thd, const char *name, const char *db,
|
|||||||
int4store(fileinfo+34,create_info->avg_row_length);
|
int4store(fileinfo+34,create_info->avg_row_length);
|
||||||
fileinfo[38]= (create_info->default_table_charset ?
|
fileinfo[38]= (create_info->default_table_charset ?
|
||||||
create_info->default_table_charset->number : 0);
|
create_info->default_table_charset->number : 0);
|
||||||
fileinfo[39]= (uchar) create_info->transactional;
|
fileinfo[39]= (uchar) ((uint) create_info->transactional |
|
||||||
|
((uint) create_info->page_checksum << 2));
|
||||||
fileinfo[40]= (uchar) create_info->row_type;
|
fileinfo[40]= (uchar) create_info->row_type;
|
||||||
/* Next few bytes where for RAID support */
|
/* Next few bytes where for RAID support */
|
||||||
fileinfo[41]= 0;
|
fileinfo[41]= 0;
|
||||||
|
@ -204,6 +204,7 @@ typedef struct st_table_share
|
|||||||
enum row_type row_type; /* How rows are stored */
|
enum row_type row_type; /* How rows are stored */
|
||||||
enum tmp_table_type tmp_table;
|
enum tmp_table_type tmp_table;
|
||||||
enum ha_choice transactional;
|
enum ha_choice transactional;
|
||||||
|
enum ha_choice page_checksum;
|
||||||
|
|
||||||
uint ref_count; /* How many TABLE objects uses this */
|
uint ref_count; /* How many TABLE objects uses this */
|
||||||
uint open_count; /* Number of tables in open list */
|
uint open_count; /* Number of tables in open list */
|
||||||
|
@ -372,8 +372,9 @@ int table2maria(TABLE *table_arg, MARIA_KEYDEF **keydef_out,
|
|||||||
- compare FULLTEXT keys;
|
- compare FULLTEXT keys;
|
||||||
- compare SPATIAL keys;
|
- compare SPATIAL keys;
|
||||||
- compare FIELD_SKIP_ZERO which is converted to FIELD_NORMAL correctly
|
- compare FIELD_SKIP_ZERO which is converted to FIELD_NORMAL correctly
|
||||||
(should be corretly detected in table2maria).
|
(should be correctly detected in table2maria).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int maria_check_definition(MARIA_KEYDEF *t1_keyinfo,
|
int maria_check_definition(MARIA_KEYDEF *t1_keyinfo,
|
||||||
MARIA_COLUMNDEF *t1_recinfo,
|
MARIA_COLUMNDEF *t1_recinfo,
|
||||||
uint t1_keys, uint t1_recs,
|
uint t1_keys, uint t1_recs,
|
||||||
@ -725,9 +726,6 @@ bool ha_maria::check_if_locking_is_allowed(uint sql_command,
|
|||||||
|
|
||||||
int ha_maria::open(const char *name, int mode, uint test_if_locked)
|
int ha_maria::open(const char *name, int mode, uint test_if_locked)
|
||||||
{
|
{
|
||||||
MARIA_KEYDEF *keyinfo;
|
|
||||||
MARIA_COLUMNDEF *recinfo= 0;
|
|
||||||
uint recs;
|
|
||||||
uint i;
|
uint i;
|
||||||
|
|
||||||
#ifdef NOT_USED
|
#ifdef NOT_USED
|
||||||
@ -753,39 +751,6 @@ int ha_maria::open(const char *name, int mode, uint test_if_locked)
|
|||||||
if (!(file= maria_open(name, mode, test_if_locked | HA_OPEN_FROM_SQL_LAYER)))
|
if (!(file= maria_open(name, mode, test_if_locked | HA_OPEN_FROM_SQL_LAYER)))
|
||||||
return (my_errno ? my_errno : -1);
|
return (my_errno ? my_errno : -1);
|
||||||
|
|
||||||
/**
|
|
||||||
@todo ASK_MONTY
|
|
||||||
This is a protection for the case of a frm and MAI containing incompatible
|
|
||||||
table definitions (as in BUG#25908). This was merged from MyISAM.
|
|
||||||
But it breaks maria.test and ps_maria.test ("incorrect key file") if the
|
|
||||||
table is BLOCK_RECORD (does it have to do with column reordering done in
|
|
||||||
ma_create.c ?).
|
|
||||||
*/
|
|
||||||
if (!table->s->tmp_table) /* No need to perform a check for tmp table */
|
|
||||||
{
|
|
||||||
if ((my_errno= table2maria(table, &keyinfo, &recinfo, &recs)))
|
|
||||||
{
|
|
||||||
/* purecov: begin inspected */
|
|
||||||
DBUG_PRINT("error", ("Failed to convert TABLE object to Maria "
|
|
||||||
"key and column definition"));
|
|
||||||
goto err;
|
|
||||||
/* purecov: end */
|
|
||||||
}
|
|
||||||
#ifdef ASK_MONTY
|
|
||||||
if (maria_check_definition(keyinfo, recinfo, table->s->keys, recs,
|
|
||||||
file->s->keyinfo, file->s->columndef,
|
|
||||||
file->s->base.keys, file->s->base.fields, true))
|
|
||||||
#else
|
|
||||||
if (0)
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
/* purecov: begin inspected */
|
|
||||||
my_errno= HA_ERR_CRASHED;
|
|
||||||
goto err;
|
|
||||||
/* purecov: end */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (test_if_locked & (HA_OPEN_IGNORE_IF_LOCKED | HA_OPEN_TMP_TABLE))
|
if (test_if_locked & (HA_OPEN_IGNORE_IF_LOCKED | HA_OPEN_TMP_TABLE))
|
||||||
VOID(maria_extra(file, HA_EXTRA_NO_WAIT_LOCK, 0));
|
VOID(maria_extra(file, HA_EXTRA_NO_WAIT_LOCK, 0));
|
||||||
|
|
||||||
@ -817,16 +782,6 @@ int ha_maria::open(const char *name, int mode, uint test_if_locked)
|
|||||||
table->key_info[i].block_size= file->s->keyinfo[i].block_length;
|
table->key_info[i].block_size= file->s->keyinfo[i].block_length;
|
||||||
}
|
}
|
||||||
my_errno= 0;
|
my_errno= 0;
|
||||||
goto end;
|
|
||||||
err:
|
|
||||||
this->close();
|
|
||||||
end:
|
|
||||||
/*
|
|
||||||
Both recinfo and keydef are allocated by my_multi_malloc(), thus only
|
|
||||||
recinfo must be freed.
|
|
||||||
*/
|
|
||||||
if (recinfo)
|
|
||||||
my_free((uchar*) recinfo, MYF(0));
|
|
||||||
return my_errno;
|
return my_errno;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1918,9 +1873,12 @@ int ha_maria::info(uint flag)
|
|||||||
share->keys_for_keyread.intersect(share->keys_in_use);
|
share->keys_for_keyread.intersect(share->keys_in_use);
|
||||||
share->db_record_offset= maria_info.record_offset;
|
share->db_record_offset= maria_info.record_offset;
|
||||||
if (share->key_parts)
|
if (share->key_parts)
|
||||||
memcpy((char*) table->key_info[0].rec_per_key,
|
{
|
||||||
(char*) maria_info.rec_per_key,
|
ulong *to= table->key_info[0].rec_per_key, *end;
|
||||||
sizeof(table->key_info[0].rec_per_key) * share->key_parts);
|
double *from= maria_info.rec_per_key;
|
||||||
|
for (end= to+ share->key_parts ; to < end ; to++, from++)
|
||||||
|
*to= (ulong) (*from + 0.5);
|
||||||
|
}
|
||||||
if (share->tmp_table == NO_TMP_TABLE)
|
if (share->tmp_table == NO_TMP_TABLE)
|
||||||
pthread_mutex_unlock(&share->mutex);
|
pthread_mutex_unlock(&share->mutex);
|
||||||
|
|
||||||
@ -2112,6 +2070,10 @@ void ha_maria::update_create_info(HA_CREATE_INFO *create_info)
|
|||||||
}
|
}
|
||||||
create_info->data_file_name= data_file_name;
|
create_info->data_file_name= data_file_name;
|
||||||
create_info->index_file_name= index_file_name;
|
create_info->index_file_name= index_file_name;
|
||||||
|
/* We need to restore the row type as Maria can change it */
|
||||||
|
if (create_info->row_type != ROW_TYPE_DEFAULT &&
|
||||||
|
!(create_info->used_fields & HA_CREATE_USED_ROW_FORMAT))
|
||||||
|
create_info->row_type= get_row_type();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -2161,7 +2123,16 @@ int ha_maria::create(const char *name, register TABLE *table_arg,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/* Note: BLOCK_RECORD is used if table is transactional */
|
||||||
row_type= maria_row_type(ha_create_info);
|
row_type= maria_row_type(ha_create_info);
|
||||||
|
if (ha_create_info->transactional == HA_CHOICE_YES &&
|
||||||
|
ha_create_info->row_type != ROW_TYPE_PAGE &&
|
||||||
|
ha_create_info->row_type != ROW_TYPE_NOT_USED &&
|
||||||
|
ha_create_info->row_type != ROW_TYPE_DEFAULT)
|
||||||
|
push_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
|
||||||
|
ER_ILLEGAL_HA_CREATE_OPTION,
|
||||||
|
"Row format set to PAGE because of TRANSACTIONAL=1 option");
|
||||||
|
|
||||||
if ((error= table2maria(table_arg, &keydef, &recinfo, &records)))
|
if ((error= table2maria(table_arg, &keydef, &recinfo, &records)))
|
||||||
DBUG_RETURN(error); /* purecov: inspected */
|
DBUG_RETURN(error); /* purecov: inspected */
|
||||||
bzero((char*) &create_info, sizeof(create_info));
|
bzero((char*) &create_info, sizeof(create_info));
|
||||||
@ -2175,18 +2146,13 @@ int ha_maria::create(const char *name, register TABLE *table_arg,
|
|||||||
share->avg_row_length);
|
share->avg_row_length);
|
||||||
create_info.data_file_name= ha_create_info->data_file_name;
|
create_info.data_file_name= ha_create_info->data_file_name;
|
||||||
create_info.index_file_name= ha_create_info->index_file_name;
|
create_info.index_file_name= ha_create_info->index_file_name;
|
||||||
#ifdef ASK_MONTY
|
|
||||||
/**
|
/*
|
||||||
@todo ASK_MONTY
|
Table is transactional:
|
||||||
Where "transactional" in the frm and in the engine can go out of sync.
|
- If the user specify that table is transactional (in this case
|
||||||
Don't we want to do, after the setting, this test:
|
row type is forced to BLOCK_RECORD)
|
||||||
if (!create_info.transactional &&
|
- If they specify BLOCK_RECORD without specifying transactional behaviour
|
||||||
ha_create_info->transactional == HA_CHOICE_YES)
|
|
||||||
error;
|
|
||||||
?
|
|
||||||
Why fool the user?
|
|
||||||
*/
|
*/
|
||||||
#endif
|
|
||||||
create_info.transactional= (row_type == BLOCK_RECORD &&
|
create_info.transactional= (row_type == BLOCK_RECORD &&
|
||||||
ha_create_info->transactional != HA_CHOICE_NO);
|
ha_create_info->transactional != HA_CHOICE_NO);
|
||||||
|
|
||||||
@ -2198,6 +2164,8 @@ int ha_maria::create(const char *name, register TABLE *table_arg,
|
|||||||
create_flags|= HA_CREATE_CHECKSUM;
|
create_flags|= HA_CREATE_CHECKSUM;
|
||||||
if (options & HA_OPTION_DELAY_KEY_WRITE)
|
if (options & HA_OPTION_DELAY_KEY_WRITE)
|
||||||
create_flags|= HA_CREATE_DELAY_KEY_WRITE;
|
create_flags|= HA_CREATE_DELAY_KEY_WRITE;
|
||||||
|
if (ha_create_info->page_checksum != HA_CHOICE_NO)
|
||||||
|
create_flags|= HA_CREATE_PAGE_CHECKSUM;
|
||||||
|
|
||||||
/* TODO: Check that the following fn_format is really needed */
|
/* TODO: Check that the following fn_format is really needed */
|
||||||
error=
|
error=
|
||||||
|
@ -130,8 +130,11 @@
|
|||||||
#define FULL_HEAD_PAGE 4
|
#define FULL_HEAD_PAGE 4
|
||||||
#define FULL_TAIL_PAGE 7
|
#define FULL_TAIL_PAGE 7
|
||||||
|
|
||||||
/** all bitmap pages end with this 2-byte signature */
|
/* If we don't have page checksum enabled, the bitmap page ends with this */
|
||||||
uchar maria_bitmap_marker[2]= {(uchar) 'b',(uchar) 'm'};
|
uchar maria_bitmap_marker[4]=
|
||||||
|
{(uchar) 255, (uchar) 255, (uchar) 255, (uchar) 254};
|
||||||
|
uchar maria_normal_page_marker[4]=
|
||||||
|
{(uchar) 255, (uchar) 255, (uchar) 255, (uchar) 255};
|
||||||
|
|
||||||
static my_bool _ma_read_bitmap_page(MARIA_SHARE *share,
|
static my_bool _ma_read_bitmap_page(MARIA_SHARE *share,
|
||||||
MARIA_FILE_BITMAP *bitmap,
|
MARIA_FILE_BITMAP *bitmap,
|
||||||
@ -186,7 +189,7 @@ my_bool _ma_bitmap_init(MARIA_SHARE *share, File file)
|
|||||||
bitmap->changed= 0;
|
bitmap->changed= 0;
|
||||||
bitmap->block_size= share->block_size;
|
bitmap->block_size= share->block_size;
|
||||||
/* Size needs to be alligned on 6 */
|
/* Size needs to be alligned on 6 */
|
||||||
aligned_bit_blocks= share->block_size / 6;
|
aligned_bit_blocks= (share->block_size - PAGE_SUFFIX_SIZE) / 6;
|
||||||
bitmap->total_size= aligned_bit_blocks * 6;
|
bitmap->total_size= aligned_bit_blocks * 6;
|
||||||
/*
|
/*
|
||||||
In each 6 bytes, we have 6*8/3 = 16 pages covered
|
In each 6 bytes, we have 6*8/3 = 16 pages covered
|
||||||
@ -452,10 +455,6 @@ static void _ma_print_bitmap(MARIA_FILE_BITMAP *bitmap)
|
|||||||
fprintf(DBUG_FILE,"\nBitmap page changes at page %lu\n",
|
fprintf(DBUG_FILE,"\nBitmap page changes at page %lu\n",
|
||||||
(ulong) bitmap->page);
|
(ulong) bitmap->page);
|
||||||
|
|
||||||
DBUG_ASSERT(memcmp(bitmap->map + bitmap->block_size -
|
|
||||||
sizeof(maria_bitmap_marker),
|
|
||||||
maria_bitmap_marker, sizeof(maria_bitmap_marker)) == 0);
|
|
||||||
|
|
||||||
page= (ulong) bitmap->page+1;
|
page= (ulong) bitmap->page+1;
|
||||||
for (pos= bitmap->map, org_pos= bitmap->map + bitmap->block_size ;
|
for (pos= bitmap->map, org_pos= bitmap->map + bitmap->block_size ;
|
||||||
pos < end ;
|
pos < end ;
|
||||||
@ -541,14 +540,30 @@ static my_bool _ma_read_bitmap_page(MARIA_SHARE *share,
|
|||||||
}
|
}
|
||||||
bitmap->used_size= bitmap->total_size;
|
bitmap->used_size= bitmap->total_size;
|
||||||
DBUG_ASSERT(share->pagecache->block_size == bitmap->block_size);
|
DBUG_ASSERT(share->pagecache->block_size == bitmap->block_size);
|
||||||
res= ((pagecache_read(share->pagecache,
|
res= pagecache_read(share->pagecache,
|
||||||
(PAGECACHE_FILE*)&bitmap->file, page, 0,
|
(PAGECACHE_FILE*)&bitmap->file, page, 0,
|
||||||
(uchar*) bitmap->map,
|
(uchar*) bitmap->map,
|
||||||
PAGECACHE_PLAIN_PAGE,
|
PAGECACHE_PLAIN_PAGE,
|
||||||
PAGECACHE_LOCK_LEFT_UNLOCKED, 0) == NULL) ||
|
PAGECACHE_LOCK_LEFT_UNLOCKED, 0) == NULL;
|
||||||
memcmp(bitmap->map + bitmap->block_size -
|
|
||||||
sizeof(maria_bitmap_marker),
|
/*
|
||||||
maria_bitmap_marker, sizeof(maria_bitmap_marker)));
|
We can't check maria_bitmap_marker here as if the bitmap page
|
||||||
|
previously had a true checksum and the user switched mode to not checksum
|
||||||
|
this may have any value, except maria_normal_page_marker.
|
||||||
|
|
||||||
|
Using maria_normal_page_marker gives us a protection against bugs
|
||||||
|
when running without any checksums.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (!res && !(share->options & HA_OPTION_PAGE_CHECKSUM) &&
|
||||||
|
!memcmp(bitmap->map + bitmap->block_size -
|
||||||
|
sizeof(maria_normal_page_marker),
|
||||||
|
maria_normal_page_marker,
|
||||||
|
sizeof(maria_normal_page_marker)))
|
||||||
|
{
|
||||||
|
res= 1;
|
||||||
|
my_errno= HA_ERR_WRONG_IN_RECORD; /* File crashed */
|
||||||
|
}
|
||||||
#ifndef DBUG_OFF
|
#ifndef DBUG_OFF
|
||||||
if (!res)
|
if (!res)
|
||||||
memcpy(bitmap->map + bitmap->block_size, bitmap->map, bitmap->block_size);
|
memcpy(bitmap->map + bitmap->block_size, bitmap->map, bitmap->block_size);
|
||||||
@ -1425,6 +1440,7 @@ static my_bool write_rest_of_head(MARIA_HA *info, uint position,
|
|||||||
row->space_on_head_page contains minimum number of bytes we
|
row->space_on_head_page contains minimum number of bytes we
|
||||||
expect to put on the head page.
|
expect to put on the head page.
|
||||||
1 error
|
1 error
|
||||||
|
my_errno is set to error
|
||||||
*/
|
*/
|
||||||
|
|
||||||
my_bool _ma_bitmap_find_place(MARIA_HA *info, MARIA_ROW *row,
|
my_bool _ma_bitmap_find_place(MARIA_HA *info, MARIA_ROW *row,
|
||||||
@ -2065,9 +2081,16 @@ int _ma_bitmap_create_first(MARIA_SHARE *share)
|
|||||||
{
|
{
|
||||||
uint block_size= share->bitmap.block_size;
|
uint block_size= share->bitmap.block_size;
|
||||||
File file= share->bitmap.file.file;
|
File file= share->bitmap.file.file;
|
||||||
|
char marker[sizeof(maria_bitmap_marker)];
|
||||||
|
|
||||||
|
if (share->options & HA_OPTION_PAGE_CHECKSUM)
|
||||||
|
bzero(marker, sizeof(marker));
|
||||||
|
else
|
||||||
|
bmove(marker, maria_bitmap_marker, sizeof(marker));
|
||||||
|
|
||||||
if (my_chsize(file, block_size - sizeof(maria_bitmap_marker),
|
if (my_chsize(file, block_size - sizeof(maria_bitmap_marker),
|
||||||
0, MYF(MY_WME)) ||
|
0, MYF(MY_WME)) ||
|
||||||
my_pwrite(file, maria_bitmap_marker, sizeof(maria_bitmap_marker),
|
my_pwrite(file, marker, sizeof(maria_bitmap_marker),
|
||||||
block_size - sizeof(maria_bitmap_marker),
|
block_size - sizeof(maria_bitmap_marker),
|
||||||
MYF(MY_NABP | MY_WME)))
|
MYF(MY_NABP | MY_WME)))
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -52,10 +52,11 @@
|
|||||||
|
|
||||||
Page header:
|
Page header:
|
||||||
|
|
||||||
LSN 7 bytes Log position for last page change
|
LSN 7 bytes Log position for last page change
|
||||||
PAGE_TYPE 1 uchar 1 for head / 2 for tail / 3 for blob
|
PAGE_TYPE 1 uchar 1 for head / 2 for tail / 3 for blob
|
||||||
NO 1 uchar Number of row/tail entries on page
|
DIR_COUNT 1 uchar Number of row/tail entries on page
|
||||||
empty space 2 bytes Empty space on page
|
FREE_DIR_LINK 1 uchar Pointer to first free director entry or 255 if no
|
||||||
|
empty space 2 bytes Empty space on page
|
||||||
|
|
||||||
The most significant bit in PAGE_TYPE is set to 1 if the data on the page
|
The most significant bit in PAGE_TYPE is set to 1 if the data on the page
|
||||||
can be compacted to get more space. (PAGE_CAN_BE_COMPACTED)
|
can be compacted to get more space. (PAGE_CAN_BE_COMPACTED)
|
||||||
@ -65,22 +66,27 @@
|
|||||||
Row directory of NO entries, that consist of the following for each row
|
Row directory of NO entries, that consist of the following for each row
|
||||||
(in reverse order; i.e., first record is stored last):
|
(in reverse order; i.e., first record is stored last):
|
||||||
|
|
||||||
Position 2 bytes Position of row on page
|
Position 2 bytes Position of row on page
|
||||||
Length 2 bytes Length of entry
|
Length 2 bytes Length of entry
|
||||||
|
|
||||||
For Position and Length, the 1 most significant bit of the position and
|
For Position and Length, the 1 most significant bit of the position and
|
||||||
the 1 most significant bit of the length could be used for some states of
|
the 1 most significant bit of the length could be used for some states of
|
||||||
the row (in other words, we should try to keep these reserved)
|
the row (in other words, we should try to keep these reserved)
|
||||||
|
|
||||||
eof flag 1 uchar Reserved for full page read testing. (Ie, did the
|
Position is 0 if the entry is not used. In this case length[0] points
|
||||||
previous write get the whole block on disk.
|
to a previous free entry (255 if no previous entry) and length[1]
|
||||||
|
to the next free entry (or 255 if last free entry). This works because
|
||||||
|
the directory entry 255 can never be marked free (if the first directory
|
||||||
|
entry is freed, the directory is shrinked).
|
||||||
|
|
||||||
|
checksum 4 bytes Reserved for full page read testing and live backup.
|
||||||
|
|
||||||
----------------
|
----------------
|
||||||
|
|
||||||
Structure of blob pages:
|
Structure of blob pages:
|
||||||
|
|
||||||
LSN 7 bytes Log position for last page change
|
LSN 7 bytes Log position for last page change
|
||||||
PAGE_TYPE 1 uchar 3
|
PAGE_TYPE 1 uchar 3
|
||||||
|
|
||||||
data
|
data
|
||||||
|
|
||||||
@ -104,7 +110,7 @@
|
|||||||
Number of ROW_EXTENT's 1-3 uchar Length encoded, optional
|
Number of ROW_EXTENT's 1-3 uchar Length encoded, optional
|
||||||
This is the number of extents the
|
This is the number of extents the
|
||||||
row is split into
|
row is split into
|
||||||
First row_extent 7 uchar Pointer to first row extent (optional)
|
First row_extent 7 uchar Pointer to first row extent (optional)
|
||||||
|
|
||||||
Total length of length array 1-3 uchar Only used if we have
|
Total length of length array 1-3 uchar Only used if we have
|
||||||
char/varchar/blob fields.
|
char/varchar/blob fields.
|
||||||
@ -206,7 +212,7 @@
|
|||||||
to handle DROP COLUMN, we must store in the index header the fields
|
to handle DROP COLUMN, we must store in the index header the fields
|
||||||
that has been dropped. When unpacking a row we will ignore dropped
|
that has been dropped. When unpacking a row we will ignore dropped
|
||||||
fields. When storing a row, we will mark a dropped field either with a
|
fields. When storing a row, we will mark a dropped field either with a
|
||||||
null in the null bit map or in the empty_bits and not store any data
|
null in the null bit map or in the empty_bits and not store any data
|
||||||
for it.
|
for it.
|
||||||
TODO: Add code for handling dropped fields.
|
TODO: Add code for handling dropped fields.
|
||||||
|
|
||||||
@ -229,6 +235,7 @@
|
|||||||
|
|
||||||
00 00 00 00 00 00 00 LSN
|
00 00 00 00 00 00 00 LSN
|
||||||
01 Only one row in page
|
01 Only one row in page
|
||||||
|
FF No free dir entry
|
||||||
xx xx Empty space on page
|
xx xx Empty space on page
|
||||||
|
|
||||||
10 Flag: row split, VER_PTR exists
|
10 Flag: row split, VER_PTR exists
|
||||||
@ -252,11 +259,10 @@
|
|||||||
|
|
||||||
..... until end of page
|
..... until end of page
|
||||||
|
|
||||||
09 00 F4 1F 00 (Start position 9, length 8180, end byte)
|
09 00 F4 1F Start position 9, length 8180
|
||||||
|
xx xx xx xx Checksum
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define SANITY_CHECKS
|
|
||||||
|
|
||||||
#include "maria_def.h"
|
#include "maria_def.h"
|
||||||
#include "ma_blockrec.h"
|
#include "ma_blockrec.h"
|
||||||
#include <lf.h>
|
#include <lf.h>
|
||||||
@ -599,17 +605,42 @@ static my_bool extend_area_on_page(uchar *buff, uchar *dir,
|
|||||||
uint *ret_length)
|
uint *ret_length)
|
||||||
{
|
{
|
||||||
uint rec_offset, length;
|
uint rec_offset, length;
|
||||||
|
uint max_entry= (uint) buff[DIR_COUNT_OFFSET];
|
||||||
DBUG_ENTER("extend_area_on_page");
|
DBUG_ENTER("extend_area_on_page");
|
||||||
|
|
||||||
rec_offset= uint2korr(dir);
|
rec_offset= uint2korr(dir);
|
||||||
length= uint2korr(dir + 2);
|
if (rec_offset)
|
||||||
DBUG_PRINT("enter", ("rec_offset: %u length: %u request_length: %u",
|
{
|
||||||
rec_offset, length, request_length));
|
/* Extending old row; Mark current space as 'free' */
|
||||||
|
length= uint2korr(dir + 2);
|
||||||
|
DBUG_PRINT("info", ("rec_offset: %u length: %u request_length: %u "
|
||||||
|
"empty_space: %u",
|
||||||
|
rec_offset, length, request_length, *empty_space));
|
||||||
|
|
||||||
*empty_space+= length;
|
*empty_space+= length;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Reusing free directory entry; Free it from the directory list */
|
||||||
|
if (dir[2] == END_OF_DIR_FREE_LIST)
|
||||||
|
buff[DIR_FREE_OFFSET]= dir[3];
|
||||||
|
else
|
||||||
|
{
|
||||||
|
uchar *prev_dir= dir_entry_pos(buff, block_size, (uint) dir[2]);
|
||||||
|
DBUG_ASSERT(uint2korr(prev_dir) == 0 && prev_dir[3] == (uchar) rownr);
|
||||||
|
prev_dir[3]= dir[3];
|
||||||
|
}
|
||||||
|
if (dir[3] != END_OF_DIR_FREE_LIST)
|
||||||
|
{
|
||||||
|
uchar *next_dir= dir_entry_pos(buff, block_size, (uint) dir[3]);
|
||||||
|
DBUG_ASSERT(uint2korr(next_dir) == 0 && next_dir[2] == (uchar) rownr);
|
||||||
|
next_dir[2]= dir[2];
|
||||||
|
}
|
||||||
|
rec_offset= start_of_next_entry(dir);
|
||||||
|
length= 0;
|
||||||
|
}
|
||||||
if (length < request_length)
|
if (length < request_length)
|
||||||
{
|
{
|
||||||
uint max_entry= (uint) ((uchar*) buff)[DIR_COUNT_OFFSET];
|
|
||||||
uint old_rec_offset;
|
uint old_rec_offset;
|
||||||
/*
|
/*
|
||||||
New data did not fit in old position.
|
New data did not fit in old position.
|
||||||
@ -646,7 +677,13 @@ static my_bool extend_area_on_page(uchar *buff, uchar *dir,
|
|||||||
rec_offset= uint2korr(dir);
|
rec_offset= uint2korr(dir);
|
||||||
length= uint2korr(dir+2);
|
length= uint2korr(dir+2);
|
||||||
if (length < request_length)
|
if (length < request_length)
|
||||||
|
{
|
||||||
|
DBUG_PRINT("error", ("Not enough space: "
|
||||||
|
"length: %u request_length: %u",
|
||||||
|
length, request_length));
|
||||||
|
my_errno= HA_ERR_WRONG_IN_RECORD; /* File crashed */
|
||||||
DBUG_RETURN(1); /* Error in block */
|
DBUG_RETURN(1); /* Error in block */
|
||||||
|
}
|
||||||
*empty_space= length; /* All space is here */
|
*empty_space= length; /* All space is here */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -824,60 +861,76 @@ static uint empty_space_on_page(uchar *buff, uint block_size)
|
|||||||
|
|
||||||
buff[EMPTY_SPACE_OFFSET] is NOT updated but left up to the caller
|
buff[EMPTY_SPACE_OFFSET] is NOT updated but left up to the caller
|
||||||
|
|
||||||
|
See start of file for description of how free directory entires are linked
|
||||||
|
|
||||||
RETURN
|
RETURN
|
||||||
0 Error (directory full or last block goes over directory)
|
0 Error (directory full or last block goes over directory)
|
||||||
# Pointer to directory entry on page
|
# Pointer to directory entry on page
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static uchar *find_free_position(uchar *buff, uint block_size, uint *res_rownr,
|
static uchar *find_free_position(uchar *buff, uint block_size, uint *res_rownr,
|
||||||
uint *res_length, uint *empty_space)
|
uint *res_length, uint *empty_space)
|
||||||
{
|
{
|
||||||
uint max_entry= (uint) ((uchar*) buff)[DIR_COUNT_OFFSET];
|
uint max_entry, free_entry;
|
||||||
uint entry, length, first_pos;
|
uint length, first_pos;
|
||||||
uchar *dir, *end;
|
uchar *dir, *first_dir;
|
||||||
DBUG_ENTER("find_free_position");
|
DBUG_ENTER("find_free_position");
|
||||||
DBUG_PRINT("info", ("max_entry: %u", max_entry));
|
|
||||||
|
|
||||||
dir= (buff + block_size - DIR_ENTRY_SIZE * max_entry - PAGE_SUFFIX_SIZE);
|
|
||||||
end= buff + block_size - PAGE_SUFFIX_SIZE - DIR_ENTRY_SIZE;
|
|
||||||
|
|
||||||
|
max_entry= (uint) buff[DIR_COUNT_OFFSET];
|
||||||
|
free_entry= (uint) buff[DIR_FREE_OFFSET];
|
||||||
*empty_space= uint2korr(buff + EMPTY_SPACE_OFFSET);
|
*empty_space= uint2korr(buff + EMPTY_SPACE_OFFSET);
|
||||||
|
|
||||||
/* Search after first empty position */
|
DBUG_PRINT("info", ("max_entry: %u free_entry: %u", max_entry, free_entry));
|
||||||
first_pos= PAGE_HEADER_SIZE;
|
|
||||||
for (entry= 0 ; dir <= end ; end-= DIR_ENTRY_SIZE, entry++)
|
first_dir= dir_entry_pos(buff, block_size, max_entry - 1);
|
||||||
|
|
||||||
|
/* Search after first free position */
|
||||||
|
if (free_entry != END_OF_DIR_FREE_LIST)
|
||||||
{
|
{
|
||||||
uint tmp= uint2korr(end);
|
if (free_entry >= max_entry)
|
||||||
if (!tmp) /* Found not used entry */
|
DBUG_RETURN(0);
|
||||||
|
dir= dir_entry_pos(buff, block_size, free_entry);
|
||||||
|
DBUG_ASSERT(uint2korr(dir) == 0 && dir[2] == END_OF_DIR_FREE_LIST);
|
||||||
|
/* Relink free list */
|
||||||
|
if ((buff[DIR_FREE_OFFSET]= dir[3]) != END_OF_DIR_FREE_LIST)
|
||||||
{
|
{
|
||||||
length= start_of_next_entry(end) - first_pos;
|
uchar *next_entry= dir_entry_pos(buff, block_size, (uint) dir[3]);
|
||||||
int2store(end, first_pos); /* Update dir entry */
|
DBUG_ASSERT((uint) next_entry[2] == free_entry &&
|
||||||
int2store(end + 2, length);
|
uint2korr(next_entry) == 0);
|
||||||
*res_rownr= entry;
|
next_entry[2]= END_OF_DIR_FREE_LIST; /* Backlink */
|
||||||
*res_length= length;
|
|
||||||
DBUG_RETURN(end);
|
|
||||||
}
|
}
|
||||||
first_pos= tmp + uint2korr(end + 2);
|
|
||||||
|
first_pos= end_of_previous_entry(dir, buff + block_size -
|
||||||
|
PAGE_SUFFIX_SIZE);
|
||||||
|
length= start_of_next_entry(dir) - first_pos;
|
||||||
|
int2store(dir, first_pos); /* Update dir entry */
|
||||||
|
int2store(dir + 2, length);
|
||||||
|
*res_rownr= free_entry;
|
||||||
|
*res_length= length;
|
||||||
|
DBUG_RETURN(dir);
|
||||||
}
|
}
|
||||||
/* No empty places in dir; create a new one */
|
/* No free places in dir; create a new one */
|
||||||
dir= end;
|
|
||||||
/* Check if there is place for the directory entry */
|
/* Check if there is place for the directory entry */
|
||||||
if (max_entry == MAX_ROWS_PER_PAGE)
|
if (max_entry == MAX_ROWS_PER_PAGE)
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
/* Check if there is place for the directory entry */
|
dir= first_dir - DIR_ENTRY_SIZE;
|
||||||
|
/* Last used place on page */
|
||||||
|
first_pos= uint2korr(first_dir) + uint2korr(first_dir + 2);
|
||||||
|
/* Check if there is place for the directory entry on the page */
|
||||||
if ((uint) (dir - buff) < first_pos)
|
if ((uint) (dir - buff) < first_pos)
|
||||||
{
|
{
|
||||||
/* Create place for directory */
|
/* Create place for directory */
|
||||||
compact_page(buff, block_size, max_entry-1, 0);
|
compact_page(buff, block_size, max_entry-1, 0);
|
||||||
first_pos= (uint2korr(end + DIR_ENTRY_SIZE) +
|
first_pos= (uint2korr(first_dir) + uint2korr(first_dir + 2));
|
||||||
uint2korr(end + DIR_ENTRY_SIZE+ 2));
|
|
||||||
*empty_space= uint2korr(buff + EMPTY_SPACE_OFFSET);
|
*empty_space= uint2korr(buff + EMPTY_SPACE_OFFSET);
|
||||||
|
DBUG_ASSERT(*empty_space > DIR_ENTRY_SIZE);
|
||||||
}
|
}
|
||||||
buff[DIR_COUNT_OFFSET]= (uchar) (uchar) max_entry+1;
|
buff[DIR_COUNT_OFFSET]= (uchar) max_entry+1;
|
||||||
length= (uint) (dir - buff - first_pos);
|
length= (uint) (dir - buff - first_pos);
|
||||||
DBUG_ASSERT(length <= *empty_space - DIR_ENTRY_SIZE);
|
DBUG_ASSERT(length <= *empty_space - DIR_ENTRY_SIZE);
|
||||||
int2store(dir, first_pos);
|
int2store(dir, first_pos);
|
||||||
int2store(dir+2, length); /* Current max length */
|
int2store(dir+2, length); /* Max length of region */
|
||||||
*res_rownr= max_entry;
|
*res_rownr= max_entry;
|
||||||
*res_length= length;
|
*res_length= length;
|
||||||
|
|
||||||
@ -1082,8 +1135,8 @@ static void compact_page(uchar *buff, uint block_size, uint rownr,
|
|||||||
PAGE_SUFFIX_SIZE) / DIR_ENTRY_SIZE);
|
PAGE_SUFFIX_SIZE) / DIR_ENTRY_SIZE);
|
||||||
|
|
||||||
/* Move all entries before and including rownr up to start of page */
|
/* Move all entries before and including rownr up to start of page */
|
||||||
dir= buff + block_size - DIR_ENTRY_SIZE * (rownr+1) - PAGE_SUFFIX_SIZE;
|
dir= dir_entry_pos(buff, block_size, rownr);
|
||||||
end= buff + block_size - DIR_ENTRY_SIZE - PAGE_SUFFIX_SIZE;
|
end= dir_entry_pos(buff, block_size, 0);
|
||||||
page_pos= next_free_pos= start_of_found_block= PAGE_HEADER_SIZE;
|
page_pos= next_free_pos= start_of_found_block= PAGE_HEADER_SIZE;
|
||||||
diff= 0;
|
diff= 0;
|
||||||
for (; dir <= end ; end-= DIR_ENTRY_SIZE)
|
for (; dir <= end ; end-= DIR_ENTRY_SIZE)
|
||||||
@ -1172,7 +1225,7 @@ static void compact_page(uchar *buff, uint block_size, uint rownr,
|
|||||||
if (extend_block)
|
if (extend_block)
|
||||||
{
|
{
|
||||||
/* Extend last block cover whole page */
|
/* Extend last block cover whole page */
|
||||||
uint length= (uint) (dir - buff) - start_of_found_block;
|
uint length= ((uint) (dir - buff) - start_of_found_block);
|
||||||
int2store(dir+2, length);
|
int2store(dir+2, length);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1202,22 +1255,31 @@ static void compact_page(uchar *buff, uint block_size, uint rownr,
|
|||||||
EMPTY_SPACE is not updated
|
EMPTY_SPACE is not updated
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void make_empty_page(uchar *buff, uint block_size, uint page_type)
|
static void make_empty_page(MARIA_HA *info, uchar *buff, uint page_type)
|
||||||
{
|
{
|
||||||
|
uint block_size= info->s->block_size;
|
||||||
|
DBUG_ENTER("make_empty_page");
|
||||||
|
|
||||||
bzero(buff, PAGE_HEADER_SIZE);
|
bzero(buff, PAGE_HEADER_SIZE);
|
||||||
|
|
||||||
|
#ifndef DONT_ZERO_PAGE_BLOCKS
|
||||||
/*
|
/*
|
||||||
We zero the rest of the block to avoid getting old memory information
|
We zero the rest of the block to avoid getting old memory information
|
||||||
to disk and to allow the file to be compressed better if archived.
|
to disk and to allow the file to be compressed better if archived.
|
||||||
The rest of the code does not assume the block is zeroed above
|
The code does not assume the block is zeroed.
|
||||||
PAGE_OVERHEAD_SIZE
|
|
||||||
*/
|
*/
|
||||||
bzero(buff+ PAGE_HEADER_SIZE, block_size - PAGE_HEADER_SIZE);
|
bzero(buff+ PAGE_HEADER_SIZE, block_size - PAGE_HEADER_SIZE -
|
||||||
|
DIR_ENTRY_SIZE - PAGE_SUFFIX_SIZE);
|
||||||
|
#endif
|
||||||
buff[PAGE_TYPE_OFFSET]= (uchar) page_type;
|
buff[PAGE_TYPE_OFFSET]= (uchar) page_type;
|
||||||
buff[DIR_COUNT_OFFSET]= 1;
|
buff[DIR_COUNT_OFFSET]= 1;
|
||||||
/* Store position to the first row */
|
buff[DIR_FREE_OFFSET]= END_OF_DIR_FREE_LIST;
|
||||||
int2store(buff + block_size - PAGE_SUFFIX_SIZE - DIR_ENTRY_SIZE,
|
int2store(buff + block_size - PAGE_SUFFIX_SIZE - DIR_ENTRY_SIZE,
|
||||||
PAGE_HEADER_SIZE);
|
PAGE_HEADER_SIZE);
|
||||||
|
if (!(info->s->options & HA_OPTION_PAGE_CHECKSUM))
|
||||||
|
bfill(buff + block_size - KEYPAGE_CHECKSUM_SIZE,
|
||||||
|
KEYPAGE_CHECKSUM_SIZE, (uchar) 255);
|
||||||
|
DBUG_VOID_RETURN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1269,7 +1331,7 @@ static my_bool get_head_or_tail_page(MARIA_HA *info,
|
|||||||
if (block->org_bitmap_value == 0) /* Empty block */
|
if (block->org_bitmap_value == 0) /* Empty block */
|
||||||
{
|
{
|
||||||
/* New page */
|
/* New page */
|
||||||
make_empty_page(buff, block_size, page_type);
|
make_empty_page(info, buff, page_type);
|
||||||
res->buff= buff;
|
res->buff= buff;
|
||||||
res->empty_space= res->length= (block_size - PAGE_OVERHEAD_SIZE);
|
res->empty_space= res->length= (block_size - PAGE_OVERHEAD_SIZE);
|
||||||
res->data= (buff + PAGE_HEADER_SIZE);
|
res->data= (buff + PAGE_HEADER_SIZE);
|
||||||
@ -1302,8 +1364,7 @@ static my_bool get_head_or_tail_page(MARIA_HA *info,
|
|||||||
{
|
{
|
||||||
compact_page(res->buff, block_size, res->rownr, 1);
|
compact_page(res->buff, block_size, res->rownr, 1);
|
||||||
/* All empty space are now after current position */
|
/* All empty space are now after current position */
|
||||||
dir= (res->buff + block_size - DIR_ENTRY_SIZE * res->rownr -
|
dir= dir_entry_pos(res->buff, block_size, res->rownr);
|
||||||
DIR_ENTRY_SIZE - PAGE_SUFFIX_SIZE);
|
|
||||||
res->length= res->empty_space= uint2korr(dir+2);
|
res->length= res->empty_space= uint2korr(dir+2);
|
||||||
}
|
}
|
||||||
if (res->length < length)
|
if (res->length < length)
|
||||||
@ -1407,7 +1468,7 @@ static my_bool write_tail(MARIA_HA *info,
|
|||||||
during _ma_bitmap_find_place() allocate more entries on the tail page
|
during _ma_bitmap_find_place() allocate more entries on the tail page
|
||||||
than it can hold
|
than it can hold
|
||||||
*/
|
*/
|
||||||
block->empty_space= ((uint) ((uchar*) row_pos.buff)[DIR_COUNT_OFFSET] <=
|
block->empty_space= ((uint) (row_pos.buff)[DIR_COUNT_OFFSET] <=
|
||||||
MAX_ROWS_PER_PAGE - 1 - share->base.blobs ?
|
MAX_ROWS_PER_PAGE - 1 - share->base.blobs ?
|
||||||
empty_space : 0);
|
empty_space : 0);
|
||||||
block->used= BLOCKUSED_USED | BLOCKUSED_TAIL;
|
block->used= BLOCKUSED_USED | BLOCKUSED_TAIL;
|
||||||
@ -1509,6 +1570,9 @@ static my_bool write_full_pages(MARIA_HA *info,
|
|||||||
copy_length= min(data_size, length);
|
copy_length= min(data_size, length);
|
||||||
memcpy(buff + LSN_SIZE + PAGE_TYPE_SIZE, data, copy_length);
|
memcpy(buff + LSN_SIZE + PAGE_TYPE_SIZE, data, copy_length);
|
||||||
length-= copy_length;
|
length-= copy_length;
|
||||||
|
if (!(info->s->options & HA_OPTION_PAGE_CHECKSUM))
|
||||||
|
bfill(buff + block_size - KEYPAGE_CHECKSUM_SIZE,
|
||||||
|
KEYPAGE_CHECKSUM_SIZE, (uchar) 255);
|
||||||
|
|
||||||
DBUG_ASSERT(share->pagecache->block_size == block_size);
|
DBUG_ASSERT(share->pagecache->block_size == block_size);
|
||||||
if (pagecache_write(share->pagecache,
|
if (pagecache_write(share->pagecache,
|
||||||
@ -2330,7 +2394,7 @@ static my_bool write_block_record(MARIA_HA *info,
|
|||||||
(uint) (log_array_pos - log_array),
|
(uint) (log_array_pos - log_array),
|
||||||
log_array, log_data);
|
log_array, log_data);
|
||||||
if (log_array != tmp_log_array)
|
if (log_array != tmp_log_array)
|
||||||
my_free((uchar*) log_array, MYF(0));
|
my_free(log_array, MYF(0));
|
||||||
if (error)
|
if (error)
|
||||||
goto disk_err;
|
goto disk_err;
|
||||||
}
|
}
|
||||||
@ -2510,6 +2574,7 @@ static my_bool allocate_and_write_block_record(MARIA_HA *info,
|
|||||||
|
|
||||||
if (_ma_bitmap_find_place(info, row, blocks))
|
if (_ma_bitmap_find_place(info, row, blocks))
|
||||||
DBUG_RETURN(1); /* Error reading bitmap */
|
DBUG_RETURN(1); /* Error reading bitmap */
|
||||||
|
|
||||||
/* page will be pinned & locked by get_head_or_tail_page */
|
/* page will be pinned & locked by get_head_or_tail_page */
|
||||||
if (get_head_or_tail_page(info, blocks->block, info->buff,
|
if (get_head_or_tail_page(info, blocks->block, info->buff,
|
||||||
row->space_on_head_page, HEAD_PAGE,
|
row->space_on_head_page, HEAD_PAGE,
|
||||||
@ -2710,8 +2775,7 @@ static my_bool _ma_update_block_record2(MARIA_HA *info,
|
|||||||
|
|
||||||
org_empty_size= uint2korr(buff + EMPTY_SPACE_OFFSET);
|
org_empty_size= uint2korr(buff + EMPTY_SPACE_OFFSET);
|
||||||
rownr= ma_recordpos_to_dir_entry(record_pos);
|
rownr= ma_recordpos_to_dir_entry(record_pos);
|
||||||
dir= (buff + block_size - DIR_ENTRY_SIZE * rownr -
|
dir= dir_entry_pos(buff, block_size, rownr);
|
||||||
DIR_ENTRY_SIZE - PAGE_SUFFIX_SIZE);
|
|
||||||
|
|
||||||
if ((org_empty_size + cur_row->head_length) >= new_row->total_length)
|
if ((org_empty_size + cur_row->head_length) >= new_row->total_length)
|
||||||
{
|
{
|
||||||
@ -2820,9 +2884,9 @@ my_bool _ma_update_block_record(MARIA_HA *info, MARIA_RECORD_POS record_pos,
|
|||||||
static int delete_dir_entry(uchar *buff, uint block_size, uint record_number,
|
static int delete_dir_entry(uchar *buff, uint block_size, uint record_number,
|
||||||
uint *empty_space_res)
|
uint *empty_space_res)
|
||||||
{
|
{
|
||||||
uint number_of_records= (uint) ((uchar *) buff)[DIR_COUNT_OFFSET];
|
uint number_of_records= (uint) buff[DIR_COUNT_OFFSET];
|
||||||
uint length, empty_space;
|
uint length, empty_space;
|
||||||
uchar *dir, *org_dir;
|
uchar *dir;
|
||||||
DBUG_ENTER("delete_dir_entry");
|
DBUG_ENTER("delete_dir_entry");
|
||||||
|
|
||||||
#ifdef SANITY_CHECKS
|
#ifdef SANITY_CHECKS
|
||||||
@ -2838,33 +2902,74 @@ static int delete_dir_entry(uchar *buff, uint block_size, uint record_number,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
empty_space= uint2korr(buff + EMPTY_SPACE_OFFSET);
|
empty_space= uint2korr(buff + EMPTY_SPACE_OFFSET);
|
||||||
org_dir= dir= (buff + block_size - DIR_ENTRY_SIZE * record_number -
|
dir= dir_entry_pos(buff, block_size, record_number);
|
||||||
DIR_ENTRY_SIZE - PAGE_SUFFIX_SIZE);
|
|
||||||
length= uint2korr(dir + 2);
|
length= uint2korr(dir + 2);
|
||||||
|
|
||||||
if (record_number == number_of_records - 1)
|
if (record_number == number_of_records - 1)
|
||||||
{
|
{
|
||||||
/* Delete this entry and all following empty directory entries */
|
/* Delete this entry and all following free directory entries */
|
||||||
uchar *end= buff + block_size - PAGE_SUFFIX_SIZE;
|
uchar *end= buff + block_size - PAGE_SUFFIX_SIZE;
|
||||||
do
|
number_of_records--;
|
||||||
|
dir+= DIR_ENTRY_SIZE;
|
||||||
|
empty_space+= DIR_ENTRY_SIZE;
|
||||||
|
|
||||||
|
/* Unlink and free the next empty ones */
|
||||||
|
while (dir < end && dir[0] == 0 && dir[1] == 0)
|
||||||
{
|
{
|
||||||
number_of_records--;
|
number_of_records--;
|
||||||
|
if (dir[2] == END_OF_DIR_FREE_LIST)
|
||||||
|
buff[DIR_FREE_OFFSET]= dir[3];
|
||||||
|
else
|
||||||
|
{
|
||||||
|
uchar *prev_entry= dir_entry_pos(buff, block_size, (uint) dir[2]);
|
||||||
|
DBUG_ASSERT(uint2korr(prev_entry) == 0 && prev_entry[3] ==
|
||||||
|
number_of_records);
|
||||||
|
prev_entry[3]= dir[3];
|
||||||
|
}
|
||||||
|
if (dir[3] != END_OF_DIR_FREE_LIST)
|
||||||
|
{
|
||||||
|
uchar *next_entry= dir_entry_pos(buff, block_size, (uint) dir[3]);
|
||||||
|
DBUG_ASSERT(uint2korr(next_entry) == 0 && next_entry[2] ==
|
||||||
|
number_of_records);
|
||||||
|
next_entry[2]= dir[2];
|
||||||
|
}
|
||||||
dir+= DIR_ENTRY_SIZE;
|
dir+= DIR_ENTRY_SIZE;
|
||||||
empty_space+= DIR_ENTRY_SIZE;
|
empty_space+= DIR_ENTRY_SIZE;
|
||||||
} while (dir < end && dir[0] == 0 && dir[1] == 0);
|
}
|
||||||
|
|
||||||
if (number_of_records == 0)
|
if (number_of_records == 0)
|
||||||
{
|
{
|
||||||
|
/* All entries on page deleted */
|
||||||
|
DBUG_PRINT("info", ("Page marked as unallocated"));
|
||||||
buff[PAGE_TYPE_OFFSET]= UNALLOCATED_PAGE;
|
buff[PAGE_TYPE_OFFSET]= UNALLOCATED_PAGE;
|
||||||
|
#ifdef IDENTICAL_PAGES_AFTER_RECOVERY
|
||||||
|
{
|
||||||
|
uchar *dir= dir_entry_pos(buff, block_size, record_number);
|
||||||
|
bzero(dir, (record_number+1) * DIR_ENTRY_SIZE);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
*empty_space_res= block_size;
|
*empty_space_res= block_size;
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
}
|
}
|
||||||
buff[DIR_COUNT_OFFSET]= (uchar) number_of_records;
|
buff[DIR_COUNT_OFFSET]= (uchar) number_of_records;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Update directory */
|
||||||
|
dir[0]= dir[1]= 0;
|
||||||
|
dir[2]= END_OF_DIR_FREE_LIST;
|
||||||
|
if ((dir[3]= buff[DIR_FREE_OFFSET]) != END_OF_DIR_FREE_LIST)
|
||||||
|
{
|
||||||
|
/* Relink next entry to point to newly freed entry */
|
||||||
|
uchar *next_entry= dir_entry_pos(buff, block_size, (uint) dir[3]);
|
||||||
|
DBUG_ASSERT(uint2korr(next_entry) == 0 &&
|
||||||
|
next_entry[2] == END_OF_DIR_FREE_LIST);
|
||||||
|
next_entry[2]= record_number;
|
||||||
|
}
|
||||||
|
buff[DIR_FREE_OFFSET]= record_number;
|
||||||
|
}
|
||||||
empty_space+= length;
|
empty_space+= length;
|
||||||
|
|
||||||
/* Update directory */
|
|
||||||
org_dir[0]= org_dir[1]= 0; org_dir[2]= org_dir[3]= 0; /* Delete entry */
|
|
||||||
int2store(buff + EMPTY_SPACE_OFFSET, empty_space);
|
int2store(buff + EMPTY_SPACE_OFFSET, empty_space);
|
||||||
buff[PAGE_TYPE_OFFSET]|= (uchar) PAGE_CAN_BE_COMPACTED;
|
buff[PAGE_TYPE_OFFSET]|= (uchar) PAGE_CAN_BE_COMPACTED;
|
||||||
|
|
||||||
@ -3118,7 +3223,7 @@ err:
|
|||||||
static uchar *get_record_position(uchar *buff, uint block_size,
|
static uchar *get_record_position(uchar *buff, uint block_size,
|
||||||
uint record_number, uchar **end_of_data)
|
uint record_number, uchar **end_of_data)
|
||||||
{
|
{
|
||||||
uint number_of_records= (uint) ((uchar *) buff)[DIR_COUNT_OFFSET];
|
uint number_of_records= (uint) buff[DIR_COUNT_OFFSET];
|
||||||
uchar *dir;
|
uchar *dir;
|
||||||
uchar *data;
|
uchar *data;
|
||||||
uint offset, length;
|
uint offset, length;
|
||||||
@ -3135,8 +3240,7 @@ static uchar *get_record_position(uchar *buff, uint block_size,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
dir= (buff + block_size - DIR_ENTRY_SIZE * record_number -
|
dir= dir_entry_pos(buff, block_size, record_number);
|
||||||
DIR_ENTRY_SIZE - PAGE_SUFFIX_SIZE);
|
|
||||||
offset= uint2korr(dir);
|
offset= uint2korr(dir);
|
||||||
length= uint2korr(dir + 2);
|
length= uint2korr(dir + 2);
|
||||||
#ifdef SANITY_CHECKS
|
#ifdef SANITY_CHECKS
|
||||||
@ -3258,7 +3362,7 @@ static uchar *read_next_extent(MARIA_HA *info, MARIA_EXTENT_CURSOR *extent,
|
|||||||
goto crashed;
|
goto crashed;
|
||||||
extent->page++; /* point to next page */
|
extent->page++; /* point to next page */
|
||||||
extent->page_count--;
|
extent->page_count--;
|
||||||
*end_of_data= buff + share->block_size;
|
*end_of_data= buff + share->block_size - PAGE_SUFFIX_SIZE;
|
||||||
info->cur_row.full_page_count++; /* For maria_chk */
|
info->cur_row.full_page_count++; /* For maria_chk */
|
||||||
DBUG_RETURN(extent->data_start= buff + LSN_SIZE + PAGE_TYPE_SIZE);
|
DBUG_RETURN(extent->data_start= buff + LSN_SIZE + PAGE_TYPE_SIZE);
|
||||||
}
|
}
|
||||||
@ -4079,8 +4183,8 @@ static void _ma_print_directory(uchar *buff, uint block_size)
|
|||||||
uint end_of_prev_row= PAGE_HEADER_SIZE;
|
uint end_of_prev_row= PAGE_HEADER_SIZE;
|
||||||
uchar *dir, *end;
|
uchar *dir, *end;
|
||||||
|
|
||||||
dir= buff + block_size - DIR_ENTRY_SIZE * max_entry - PAGE_SUFFIX_SIZE;
|
dir= dir_entry_pos(buff, block_size, max_entry-1);
|
||||||
end= buff + block_size - DIR_ENTRY_SIZE - PAGE_SUFFIX_SIZE;
|
end= dir_entry_pos(buff, block_size, 0);
|
||||||
|
|
||||||
DBUG_LOCK_FILE;
|
DBUG_LOCK_FILE;
|
||||||
fprintf(DBUG_FILE,"Directory dump (pos:length):\n");
|
fprintf(DBUG_FILE,"Directory dump (pos:length):\n");
|
||||||
@ -4634,7 +4738,7 @@ uint _ma_apply_redo_insert_row_head_or_tail(MARIA_HA *info, LSN lsn,
|
|||||||
DBUG_ASSERT(rownr == 0);
|
DBUG_ASSERT(rownr == 0);
|
||||||
if (rownr != 0)
|
if (rownr != 0)
|
||||||
goto err;
|
goto err;
|
||||||
make_empty_page(buff, block_size, page_type);
|
make_empty_page(info, buff, page_type);
|
||||||
empty_space= (block_size - PAGE_OVERHEAD_SIZE);
|
empty_space= (block_size - PAGE_OVERHEAD_SIZE);
|
||||||
rec_offset= PAGE_HEADER_SIZE;
|
rec_offset= PAGE_HEADER_SIZE;
|
||||||
dir= buff+ block_size - PAGE_SUFFIX_SIZE - DIR_ENTRY_SIZE;
|
dir= buff+ block_size - PAGE_SUFFIX_SIZE - DIR_ENTRY_SIZE;
|
||||||
@ -4643,7 +4747,6 @@ uint _ma_apply_redo_insert_row_head_or_tail(MARIA_HA *info, LSN lsn,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
uint max_entry;
|
|
||||||
if (!(buff= pagecache_read(share->pagecache, &info->dfile,
|
if (!(buff= pagecache_read(share->pagecache, &info->dfile,
|
||||||
page, 0, 0,
|
page, 0, 0,
|
||||||
PAGECACHE_PLAIN_PAGE, PAGECACHE_LOCK_WRITE,
|
PAGECACHE_PLAIN_PAGE, PAGECACHE_LOCK_WRITE,
|
||||||
@ -4664,25 +4767,27 @@ uint _ma_apply_redo_insert_row_head_or_tail(MARIA_HA *info, LSN lsn,
|
|||||||
unlock_method= PAGECACHE_LOCK_WRITE_UNLOCK;
|
unlock_method= PAGECACHE_LOCK_WRITE_UNLOCK;
|
||||||
unpin_method= PAGECACHE_UNPIN;
|
unpin_method= PAGECACHE_UNPIN;
|
||||||
|
|
||||||
max_entry= (uint) ((uchar*) buff)[DIR_COUNT_OFFSET];
|
|
||||||
if (((buff[PAGE_TYPE_OFFSET] & PAGE_TYPE_MASK) != page_type))
|
if (((buff[PAGE_TYPE_OFFSET] & PAGE_TYPE_MASK) != page_type))
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
This is a page that has been freed before and now should be
|
This is a page that has been freed before and now should be
|
||||||
changed to new type.
|
changed to new type.
|
||||||
*/
|
*/
|
||||||
if ((buff[PAGE_TYPE_OFFSET] & PAGE_TYPE_MASK) != BLOB_PAGE &&
|
DBUG_ASSERT(rownr == 0);
|
||||||
(buff[PAGE_TYPE_OFFSET] & PAGE_TYPE_MASK) != UNALLOCATED_PAGE)
|
if (((buff[PAGE_TYPE_OFFSET] & PAGE_TYPE_MASK) != BLOB_PAGE &&
|
||||||
|
(buff[PAGE_TYPE_OFFSET] & PAGE_TYPE_MASK) != UNALLOCATED_PAGE) ||
|
||||||
|
rownr != 0)
|
||||||
goto err;
|
goto err;
|
||||||
make_empty_page(buff, block_size, page_type);
|
make_empty_page(info, buff, page_type);
|
||||||
empty_space= (block_size - PAGE_OVERHEAD_SIZE);
|
empty_space= (block_size - PAGE_OVERHEAD_SIZE);
|
||||||
rec_offset= PAGE_HEADER_SIZE;
|
rec_offset= PAGE_HEADER_SIZE;
|
||||||
dir= buff+ block_size - PAGE_SUFFIX_SIZE - DIR_ENTRY_SIZE;
|
dir= buff+ block_size - PAGE_SUFFIX_SIZE - DIR_ENTRY_SIZE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
dir= (buff + block_size - DIR_ENTRY_SIZE * (rownr + 1) -
|
uint max_entry= (uint) buff[DIR_COUNT_OFFSET];
|
||||||
PAGE_SUFFIX_SIZE);
|
|
||||||
|
dir= dir_entry_pos(buff, block_size, rownr);
|
||||||
empty_space= uint2korr(buff + EMPTY_SPACE_OFFSET);
|
empty_space= uint2korr(buff + EMPTY_SPACE_OFFSET);
|
||||||
|
|
||||||
if (max_entry <= rownr)
|
if (max_entry <= rownr)
|
||||||
@ -4698,7 +4803,7 @@ uint _ma_apply_redo_insert_row_head_or_tail(MARIA_HA *info, LSN lsn,
|
|||||||
/* Create place for directory & data */
|
/* Create place for directory & data */
|
||||||
compact_page(buff, block_size, max_entry - 1, 0);
|
compact_page(buff, block_size, max_entry - 1, 0);
|
||||||
rec_offset= (uint2korr(dir + DIR_ENTRY_SIZE) +
|
rec_offset= (uint2korr(dir + DIR_ENTRY_SIZE) +
|
||||||
uint2korr(dir + DIR_ENTRY_SIZE +2));
|
uint2korr(dir + DIR_ENTRY_SIZE + 2));
|
||||||
empty_space= uint2korr(buff + EMPTY_SPACE_OFFSET);
|
empty_space= uint2korr(buff + EMPTY_SPACE_OFFSET);
|
||||||
DBUG_ASSERT(!((uint) (dir - buff) < rec_offset + data_length));
|
DBUG_ASSERT(!((uint) (dir - buff) < rec_offset + data_length));
|
||||||
if ((uint) (dir - buff) < rec_offset + data_length)
|
if ((uint) (dir - buff) < rec_offset + data_length)
|
||||||
@ -4916,6 +5021,15 @@ uint _ma_apply_redo_purge_blocks(MARIA_HA *info,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
buff[PAGE_TYPE_OFFSET]= UNALLOCATED_PAGE;
|
buff[PAGE_TYPE_OFFSET]= UNALLOCATED_PAGE;
|
||||||
|
#ifdef IDENTICAL_PAGES_AFTER_RECOVERY
|
||||||
|
{
|
||||||
|
uint number_of_records= (uint) buff[DIR_COUNT_OFFSET];
|
||||||
|
uchar *dir= dir_entry_pos(buff, info->s->block_size,
|
||||||
|
number_of_records-1);
|
||||||
|
buff[DIR_FREE_OFFSET]= END_OF_DIR_FREE_LIST;
|
||||||
|
bzero(dir, number_of_records * DIR_ENTRY_SIZE);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
lsn_store(buff, lsn);
|
lsn_store(buff, lsn);
|
||||||
if (pagecache_write(share->pagecache,
|
if (pagecache_write(share->pagecache,
|
||||||
&info->dfile, page+i, 0,
|
&info->dfile, page+i, 0,
|
||||||
|
@ -13,22 +13,25 @@
|
|||||||
along with this program; if not, write to the Free Software
|
along with this program; if not, write to the Free Software
|
||||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Storage of records in block
|
Storage of records in block
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define LSN_SIZE 7
|
#define LSN_SIZE 7
|
||||||
#define DIR_COUNT_SIZE 1 /* Stores number of rows on page */
|
#define DIR_COUNT_SIZE 1 /* Stores number of rows on page */
|
||||||
|
#define DIR_FREE_SIZE 1 /* Pointer to first free dir entry */
|
||||||
#define EMPTY_SPACE_SIZE 2 /* Stores empty space on page */
|
#define EMPTY_SPACE_SIZE 2 /* Stores empty space on page */
|
||||||
#define PAGE_TYPE_SIZE 1
|
#define PAGE_TYPE_SIZE 1
|
||||||
#define PAGE_SUFFIX_SIZE 0 /* Bytes for page suffix */
|
#define PAGE_SUFFIX_SIZE 4 /* Bytes for checksum */
|
||||||
#define PAGE_HEADER_SIZE (LSN_SIZE + DIR_COUNT_SIZE + EMPTY_SPACE_SIZE +\
|
#define PAGE_HEADER_SIZE (LSN_SIZE + DIR_COUNT_SIZE + DIR_FREE_SIZE +\
|
||||||
PAGE_TYPE_SIZE)
|
EMPTY_SPACE_SIZE + PAGE_TYPE_SIZE)
|
||||||
#define PAGE_OVERHEAD_SIZE (PAGE_HEADER_SIZE + DIR_ENTRY_SIZE + \
|
#define PAGE_OVERHEAD_SIZE (PAGE_HEADER_SIZE + DIR_ENTRY_SIZE + \
|
||||||
PAGE_SUFFIX_SIZE)
|
PAGE_SUFFIX_SIZE)
|
||||||
#define BLOCK_RECORD_POINTER_SIZE 6
|
#define BLOCK_RECORD_POINTER_SIZE 6
|
||||||
|
|
||||||
#define FULL_PAGE_SIZE(block_size) ((block_size) - LSN_SIZE - PAGE_TYPE_SIZE)
|
#define FULL_PAGE_SIZE(block_size) ((block_size) - LSN_SIZE - PAGE_TYPE_SIZE - \
|
||||||
|
PAGE_SUFFIX_SIZE)
|
||||||
|
|
||||||
#define ROW_EXTENT_PAGE_SIZE 5
|
#define ROW_EXTENT_PAGE_SIZE 5
|
||||||
#define ROW_EXTENT_COUNT_SIZE 2
|
#define ROW_EXTENT_COUNT_SIZE 2
|
||||||
@ -40,7 +43,6 @@
|
|||||||
#define EXTRA_LENGTH_FIELDS 3
|
#define EXTRA_LENGTH_FIELDS 3
|
||||||
|
|
||||||
/* Size for the different parts in the row header (and head page) */
|
/* Size for the different parts in the row header (and head page) */
|
||||||
|
|
||||||
#define FLAG_SIZE 1
|
#define FLAG_SIZE 1
|
||||||
#define TRANSID_SIZE 6
|
#define TRANSID_SIZE 6
|
||||||
#define VERPTR_SIZE 7
|
#define VERPTR_SIZE 7
|
||||||
@ -51,12 +53,13 @@
|
|||||||
#define BASE_ROW_HEADER_SIZE FLAG_SIZE
|
#define BASE_ROW_HEADER_SIZE FLAG_SIZE
|
||||||
#define TRANS_ROW_EXTRA_HEADER_SIZE TRANSID_SIZE
|
#define TRANS_ROW_EXTRA_HEADER_SIZE TRANSID_SIZE
|
||||||
|
|
||||||
#define PAGE_TYPE_MASK 127
|
#define PAGE_TYPE_MASK 7
|
||||||
enum en_page_type { UNALLOCATED_PAGE, HEAD_PAGE, TAIL_PAGE, BLOB_PAGE, MAX_PAGE_TYPE };
|
enum en_page_type { UNALLOCATED_PAGE, HEAD_PAGE, TAIL_PAGE, BLOB_PAGE, MAX_PAGE_TYPE };
|
||||||
|
|
||||||
#define PAGE_TYPE_OFFSET LSN_SIZE
|
#define PAGE_TYPE_OFFSET LSN_SIZE
|
||||||
#define DIR_COUNT_OFFSET LSN_SIZE+PAGE_TYPE_SIZE
|
#define DIR_COUNT_OFFSET (LSN_SIZE+PAGE_TYPE_SIZE)
|
||||||
#define EMPTY_SPACE_OFFSET (DIR_COUNT_OFFSET + DIR_COUNT_SIZE)
|
#define DIR_FREE_OFFSET (DIR_COUNT_OFFSET+DIR_COUNT_SIZE)
|
||||||
|
#define EMPTY_SPACE_OFFSET (DIR_FREE_OFFSET+DIR_FREE_SIZE)
|
||||||
|
|
||||||
#define PAGE_CAN_BE_COMPACTED 128 /* Bit in PAGE_TYPE */
|
#define PAGE_CAN_BE_COMPACTED 128 /* Bit in PAGE_TYPE */
|
||||||
|
|
||||||
@ -84,6 +87,7 @@ enum en_page_type { UNALLOCATED_PAGE, HEAD_PAGE, TAIL_PAGE, BLOB_PAGE, MAX_PAGE_
|
|||||||
|
|
||||||
/* We use 1 uchar in record header to store number of directory entries */
|
/* We use 1 uchar in record header to store number of directory entries */
|
||||||
#define MAX_ROWS_PER_PAGE 255
|
#define MAX_ROWS_PER_PAGE 255
|
||||||
|
#define END_OF_DIR_FREE_LIST ((uchar) 255)
|
||||||
|
|
||||||
/* Bits for MARIA_BITMAP_BLOCKS->used */
|
/* Bits for MARIA_BITMAP_BLOCKS->used */
|
||||||
/* We stored data on disk in the block */
|
/* We stored data on disk in the block */
|
||||||
@ -123,6 +127,12 @@ static inline uint ma_recordpos_to_dir_entry(MARIA_RECORD_POS record_pos)
|
|||||||
return (uint) (record_pos & 255);
|
return (uint) (record_pos & 255);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline uchar *dir_entry_pos(uchar *buff, uint block_size, uint pos)
|
||||||
|
{
|
||||||
|
return (buff + block_size - DIR_ENTRY_SIZE * pos - PAGE_SUFFIX_SIZE -
|
||||||
|
DIR_ENTRY_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
/* ma_blockrec.c */
|
/* ma_blockrec.c */
|
||||||
void _ma_init_block_record_data(void);
|
void _ma_init_block_record_data(void);
|
||||||
my_bool _ma_once_init_block_record(MARIA_SHARE *share, File dfile);
|
my_bool _ma_once_init_block_record(MARIA_SHARE *share, File dfile);
|
||||||
|
@ -264,7 +264,8 @@ static int check_k_link(HA_CHECK *param, register MARIA_HA *info,
|
|||||||
{
|
{
|
||||||
uint block_size= info->s->block_size;
|
uint block_size= info->s->block_size;
|
||||||
ha_rows records;
|
ha_rows records;
|
||||||
char llbuff[21], llbuff2[21], *buff;
|
char llbuff[21], llbuff2[21];
|
||||||
|
uchar *buff;
|
||||||
DBUG_ENTER("check_k_link");
|
DBUG_ENTER("check_k_link");
|
||||||
|
|
||||||
records= (ha_rows) (info->state->key_file_length / block_size);
|
records= (ha_rows) (info->state->key_file_length / block_size);
|
||||||
@ -313,7 +314,11 @@ static int check_k_link(HA_CHECK *param, register MARIA_HA *info,
|
|||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
/* purecov: end */
|
/* purecov: end */
|
||||||
}
|
}
|
||||||
next_link=mi_sizekorr(buff);
|
if (_ma_get_keynr(info, buff) != MARIA_DELETE_KEY_NR)
|
||||||
|
_ma_check_print_error(param, "Page at %s is not delete marked",
|
||||||
|
llstr(next_link, llbuff));
|
||||||
|
|
||||||
|
next_link= mi_sizekorr(buff + info->s->keypage_header);
|
||||||
records--;
|
records--;
|
||||||
param->key_file_blocks+=block_size;
|
param->key_file_blocks+=block_size;
|
||||||
}
|
}
|
||||||
@ -418,7 +423,7 @@ int maria_chk_key(HA_CHECK *param, register MARIA_HA *info)
|
|||||||
ha_rows keys;
|
ha_rows keys;
|
||||||
ha_checksum old_record_checksum,init_checksum;
|
ha_checksum old_record_checksum,init_checksum;
|
||||||
my_off_t all_keydata,all_totaldata,key_totlength,length;
|
my_off_t all_keydata,all_totaldata,key_totlength,length;
|
||||||
ulong *rec_per_key_part;
|
double *rec_per_key_part;
|
||||||
MARIA_SHARE *share=info->s;
|
MARIA_SHARE *share=info->s;
|
||||||
MARIA_KEYDEF *keyinfo;
|
MARIA_KEYDEF *keyinfo;
|
||||||
char buff[22],buff2[22];
|
char buff[22],buff2[22];
|
||||||
@ -444,7 +449,7 @@ int maria_chk_key(HA_CHECK *param, register MARIA_HA *info)
|
|||||||
old_record_checksum= (calc_checksum(info->state->records +
|
old_record_checksum= (calc_checksum(info->state->records +
|
||||||
info->state->del-1) *
|
info->state->del-1) *
|
||||||
share->base.pack_reclength);
|
share->base.pack_reclength);
|
||||||
rec_per_key_part= param->rec_per_key_part;
|
rec_per_key_part= param->new_rec_per_key_part;
|
||||||
for (key= 0,keyinfo= &share->keyinfo[0]; key < share->base.keys ;
|
for (key= 0,keyinfo= &share->keyinfo[0]; key < share->base.keys ;
|
||||||
rec_per_key_part+=keyinfo->keysegs, key++, keyinfo++)
|
rec_per_key_part+=keyinfo->keysegs, key++, keyinfo++)
|
||||||
{
|
{
|
||||||
@ -454,7 +459,7 @@ int maria_chk_key(HA_CHECK *param, register MARIA_HA *info)
|
|||||||
/* Remember old statistics for key */
|
/* Remember old statistics for key */
|
||||||
memcpy((char*) rec_per_key_part,
|
memcpy((char*) rec_per_key_part,
|
||||||
(char*) (share->state.rec_per_key_part +
|
(char*) (share->state.rec_per_key_part +
|
||||||
(uint) (rec_per_key_part - param->rec_per_key_part)),
|
(uint) (rec_per_key_part - param->new_rec_per_key_part)),
|
||||||
keyinfo->keysegs*sizeof(*rec_per_key_part));
|
keyinfo->keysegs*sizeof(*rec_per_key_part));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -627,7 +632,7 @@ static int chk_index_down(HA_CHECK *param, MARIA_HA *info,
|
|||||||
{
|
{
|
||||||
/* purecov: begin tested */
|
/* purecov: begin tested */
|
||||||
_ma_check_print_error(param, "Mis-aligned key block: %s "
|
_ma_check_print_error(param, "Mis-aligned key block: %s "
|
||||||
"minimum key block length: %u",
|
"key block length: %u",
|
||||||
llstr(page, llbuff), info->s->block_size);
|
llstr(page, llbuff), info->s->block_size);
|
||||||
goto err;
|
goto err;
|
||||||
/* purecov: end */
|
/* purecov: end */
|
||||||
@ -742,7 +747,7 @@ int maria_collect_stats_nonulls_next(HA_KEYSEG *keyseg, ulonglong *notnull,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Check if index is ok */
|
/* Check if index is ok */
|
||||||
|
|
||||||
static int chk_index(HA_CHECK *param, MARIA_HA *info, MARIA_KEYDEF *keyinfo,
|
static int chk_index(HA_CHECK *param, MARIA_HA *info, MARIA_KEYDEF *keyinfo,
|
||||||
my_off_t page, uchar *buff, ha_rows *keys,
|
my_off_t page, uchar *buff, ha_rows *keys,
|
||||||
@ -755,7 +760,7 @@ static int chk_index(HA_CHECK *param, MARIA_HA *info, MARIA_KEYDEF *keyinfo,
|
|||||||
char llbuff[22];
|
char llbuff[22];
|
||||||
uint diff_pos[2];
|
uint diff_pos[2];
|
||||||
DBUG_ENTER("chk_index");
|
DBUG_ENTER("chk_index");
|
||||||
DBUG_DUMP("buff",(uchar*) buff,maria_data_on_page(buff));
|
DBUG_DUMP("buff", buff, _ma_get_page_used(info, buff));
|
||||||
|
|
||||||
/* TODO: implement appropriate check for RTree keys */
|
/* TODO: implement appropriate check for RTree keys */
|
||||||
if (keyinfo->flag & HA_SPATIAL)
|
if (keyinfo->flag & HA_SPATIAL)
|
||||||
@ -771,16 +776,22 @@ static int chk_index(HA_CHECK *param, MARIA_HA *info, MARIA_KEYDEF *keyinfo,
|
|||||||
comp_flag=SEARCH_FIND | SEARCH_UPDATE; /* Not real duplicates */
|
comp_flag=SEARCH_FIND | SEARCH_UPDATE; /* Not real duplicates */
|
||||||
else
|
else
|
||||||
comp_flag=SEARCH_SAME; /* Keys in positionorder */
|
comp_flag=SEARCH_SAME; /* Keys in positionorder */
|
||||||
nod_flag=_ma_test_if_nod(buff);
|
|
||||||
used_length= maria_data_on_page(buff);
|
|
||||||
keypos=buff+2+nod_flag;
|
|
||||||
endpos=buff+used_length;
|
|
||||||
|
|
||||||
param->keydata+=used_length; param->totaldata+=keyinfo->block_length; /* INFO */
|
_ma_get_used_and_nod(info, buff, used_length, nod_flag);
|
||||||
|
keypos= buff + info->s->keypage_header + nod_flag;
|
||||||
|
endpos= buff + used_length;
|
||||||
|
|
||||||
|
param->keydata+= used_length;
|
||||||
|
param->totaldata+= keyinfo->block_length; /* INFO */
|
||||||
param->key_blocks++;
|
param->key_blocks++;
|
||||||
if (level > param->max_level)
|
if (level > param->max_level)
|
||||||
param->max_level=level;
|
param->max_level=level;
|
||||||
|
|
||||||
|
if (_ma_get_keynr(info, buff) != (uint) (keyinfo - info->s->keyinfo))
|
||||||
|
_ma_check_print_error(param, "Page at %s is not marked for index %u",
|
||||||
|
llstr(page, llbuff),
|
||||||
|
(uint) (keyinfo - info->s->keyinfo));
|
||||||
|
|
||||||
if (used_length > keyinfo->block_length)
|
if (used_length > keyinfo->block_length)
|
||||||
{
|
{
|
||||||
_ma_check_print_error(param,"Wrong pageinfo at page: %s",
|
_ma_check_print_error(param,"Wrong pageinfo at page: %s",
|
||||||
@ -1388,7 +1399,7 @@ end:
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Check if layout on a page is ok
|
Check if layout on head or tail page is ok
|
||||||
|
|
||||||
NOTES
|
NOTES
|
||||||
This is for rows-in-block format.
|
This is for rows-in-block format.
|
||||||
@ -1399,17 +1410,62 @@ static int check_page_layout(HA_CHECK *param, MARIA_HA *info,
|
|||||||
uint row_count, uint head_empty,
|
uint row_count, uint head_empty,
|
||||||
uint *real_rows_found)
|
uint *real_rows_found)
|
||||||
{
|
{
|
||||||
uint empty, last_row_end, row, first_dir_entry;
|
uint empty, last_row_end, row, first_dir_entry, free_entry, block_size;
|
||||||
|
uint free_entries, prev_free_entry;
|
||||||
uchar *dir_entry;
|
uchar *dir_entry;
|
||||||
char llbuff[22];
|
char llbuff[22];
|
||||||
|
my_bool error_in_free_list= 0;
|
||||||
DBUG_ENTER("check_page_layout");
|
DBUG_ENTER("check_page_layout");
|
||||||
|
|
||||||
|
block_size= info->s->block_size;
|
||||||
empty= 0;
|
empty= 0;
|
||||||
last_row_end= PAGE_HEADER_SIZE;
|
last_row_end= PAGE_HEADER_SIZE;
|
||||||
*real_rows_found= 0;
|
*real_rows_found= 0;
|
||||||
|
|
||||||
|
/* Check free directory list */
|
||||||
|
free_entry= (uint) page[DIR_FREE_OFFSET];
|
||||||
|
free_entries= 0;
|
||||||
|
prev_free_entry= END_OF_DIR_FREE_LIST;
|
||||||
|
while (free_entry != END_OF_DIR_FREE_LIST)
|
||||||
|
{
|
||||||
|
uchar *dir;
|
||||||
|
if (free_entry > row_count)
|
||||||
|
{
|
||||||
|
_ma_check_print_error(param,
|
||||||
|
"Page %9s: Directory free entry points outside "
|
||||||
|
"directory",
|
||||||
|
llstr(page_pos, llbuff));
|
||||||
|
error_in_free_list= 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
dir= dir_entry_pos(page, block_size, free_entry);
|
||||||
|
if (uint2korr(dir) != 0)
|
||||||
|
{
|
||||||
|
_ma_check_print_error(param,
|
||||||
|
"Page %9s: Directory free entry points to "
|
||||||
|
"not deleted entry",
|
||||||
|
llstr(page_pos, llbuff));
|
||||||
|
error_in_free_list= 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (dir[2] != prev_free_entry)
|
||||||
|
{
|
||||||
|
_ma_check_print_error(param,
|
||||||
|
"Page %9s: Directory free list back pointer "
|
||||||
|
"points to wrong entry",
|
||||||
|
llstr(page_pos, llbuff));
|
||||||
|
error_in_free_list= 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
prev_free_entry= free_entry;
|
||||||
|
free_entry= dir[3];
|
||||||
|
free_entries++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check directry */
|
||||||
dir_entry= page+ info->s->block_size - PAGE_SUFFIX_SIZE;
|
dir_entry= page+ info->s->block_size - PAGE_SUFFIX_SIZE;
|
||||||
first_dir_entry= info->s->block_size - row_count* DIR_ENTRY_SIZE;
|
first_dir_entry= (info->s->block_size - row_count* DIR_ENTRY_SIZE -
|
||||||
|
PAGE_SUFFIX_SIZE);
|
||||||
for (row= 0 ; row < row_count ; row++)
|
for (row= 0 ; row < row_count ; row++)
|
||||||
{
|
{
|
||||||
uint pos, length;
|
uint pos, length;
|
||||||
@ -1417,6 +1473,7 @@ static int check_page_layout(HA_CHECK *param, MARIA_HA *info,
|
|||||||
pos= uint2korr(dir_entry);
|
pos= uint2korr(dir_entry);
|
||||||
if (!pos)
|
if (!pos)
|
||||||
{
|
{
|
||||||
|
free_entries--;
|
||||||
if (row == row_count -1)
|
if (row == row_count -1)
|
||||||
{
|
{
|
||||||
_ma_check_print_error(param,
|
_ma_check_print_error(param,
|
||||||
@ -1454,9 +1511,18 @@ static int check_page_layout(HA_CHECK *param, MARIA_HA *info,
|
|||||||
_ma_check_print_error(param,
|
_ma_check_print_error(param,
|
||||||
"Page %9s: Wrong empty size. Stored: %5u Actual: %5u",
|
"Page %9s: Wrong empty size. Stored: %5u Actual: %5u",
|
||||||
llstr(page_pos, llbuff), head_empty, empty);
|
llstr(page_pos, llbuff), head_empty, empty);
|
||||||
DBUG_RETURN(param->err_count++ > MAXERR || !(param->testflag & T_VERBOSE));
|
param->err_count++;
|
||||||
}
|
}
|
||||||
DBUG_RETURN(0);
|
if (free_entries != 0 && !error_in_free_list)
|
||||||
|
{
|
||||||
|
_ma_check_print_error(param,
|
||||||
|
"Page %9s: Directory free link don't include "
|
||||||
|
"all free entries",
|
||||||
|
llstr(page_pos, llbuff));
|
||||||
|
param->err_count++;
|
||||||
|
}
|
||||||
|
DBUG_RETURN(param->err_count &&
|
||||||
|
(param->err_count >= MAXERR || !(param->testflag & T_VERBOSE)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1665,7 +1731,7 @@ static int check_block_record(HA_CHECK *param, MARIA_HA *info, int extend,
|
|||||||
if (page_type == UNALLOCATED_PAGE || page_type >= MAX_PAGE_TYPE)
|
if (page_type == UNALLOCATED_PAGE || page_type >= MAX_PAGE_TYPE)
|
||||||
{
|
{
|
||||||
_ma_check_print_error(param,
|
_ma_check_print_error(param,
|
||||||
"Page %9s: Found wrong page type %d\n",
|
"Page %9s: Found wrong page type %d",
|
||||||
llstr(pos, llbuff), page_type);
|
llstr(pos, llbuff), page_type);
|
||||||
if (param->err_count++ > MAXERR || !(param->testflag & T_VERBOSE))
|
if (param->err_count++ > MAXERR || !(param->testflag & T_VERBOSE))
|
||||||
goto err;
|
goto err;
|
||||||
@ -1831,7 +1897,7 @@ int maria_chk_data_link(HA_CHECK *param, MARIA_HA *info,int extend)
|
|||||||
(HA_OPTION_CHECKSUM | HA_OPTION_COMPRESS_RECORD)))
|
(HA_OPTION_CHECKSUM | HA_OPTION_COMPRESS_RECORD)))
|
||||||
{
|
{
|
||||||
_ma_check_print_warning(param,
|
_ma_check_print_warning(param,
|
||||||
"Record checksum is not the same as checksum stored in the index file\n");
|
"Record checksum is not the same as checksum stored in the index file");
|
||||||
error=1;
|
error=1;
|
||||||
}
|
}
|
||||||
else if (!extend)
|
else if (!extend)
|
||||||
@ -2424,7 +2490,7 @@ int maria_movepoint(register MARIA_HA *info, uchar *record,
|
|||||||
(uint) (SEARCH_SAME | SEARCH_SAVE_BUFF),
|
(uint) (SEARCH_SAME | SEARCH_SAVE_BUFF),
|
||||||
info->s->state.key_root[i]))
|
info->s->state.key_root[i]))
|
||||||
DBUG_RETURN(-1);
|
DBUG_RETURN(-1);
|
||||||
nod_flag=_ma_test_if_nod(info->buff);
|
nod_flag=_ma_test_if_nod(info, info->buff);
|
||||||
_ma_dpointer(info,info->int_keypos-nod_flag-
|
_ma_dpointer(info,info->int_keypos-nod_flag-
|
||||||
info->s->rec_reflength,newpos);
|
info->s->rec_reflength,newpos);
|
||||||
if (_ma_write_keypage(info,keyinfo,info->last_keypage,
|
if (_ma_write_keypage(info,keyinfo,info->last_keypage,
|
||||||
@ -2620,11 +2686,11 @@ static int sort_one_index(HA_CHECK *param, MARIA_HA *info,
|
|||||||
llstr(pagepos,llbuff));
|
llstr(pagepos,llbuff));
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
if ((nod_flag=_ma_test_if_nod(buff)) || keyinfo->flag & HA_FULLTEXT)
|
if ((nod_flag=_ma_test_if_nod(info, buff)) || keyinfo->flag & HA_FULLTEXT)
|
||||||
{
|
{
|
||||||
used_length= maria_data_on_page(buff);
|
used_length= _ma_get_page_used(info, buff);
|
||||||
keypos=buff+2+nod_flag;
|
keypos=buff + info->s->keypage_header + nod_flag;
|
||||||
endpos=buff+used_length;
|
endpos=buff + used_length;
|
||||||
for ( ;; )
|
for ( ;; )
|
||||||
{
|
{
|
||||||
if (nod_flag)
|
if (nod_flag)
|
||||||
@ -2666,7 +2732,7 @@ static int sort_one_index(HA_CHECK *param, MARIA_HA *info,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Fill block with zero and write it to the new index file */
|
/* Fill block with zero and write it to the new index file */
|
||||||
length= maria_data_on_page(buff);
|
length= _ma_get_page_used(info, buff);
|
||||||
bzero((uchar*) buff+length,keyinfo->block_length-length);
|
bzero((uchar*) buff+length,keyinfo->block_length-length);
|
||||||
if (my_pwrite(new_file,(uchar*) buff,(uint) keyinfo->block_length,
|
if (my_pwrite(new_file,(uchar*) buff,(uint) keyinfo->block_length,
|
||||||
new_page_pos,MYF(MY_NABP | MY_WAIT_IF_FULL)))
|
new_page_pos,MYF(MY_NABP | MY_WAIT_IF_FULL)))
|
||||||
@ -2775,7 +2841,7 @@ int maria_repair_by_sort(HA_CHECK *param, register MARIA_HA *info,
|
|||||||
MARIA_SORT_PARAM sort_param;
|
MARIA_SORT_PARAM sort_param;
|
||||||
MARIA_SHARE *share=info->s;
|
MARIA_SHARE *share=info->s;
|
||||||
HA_KEYSEG *keyseg;
|
HA_KEYSEG *keyseg;
|
||||||
ulong *rec_per_key_part;
|
double *rec_per_key_part;
|
||||||
char llbuff[22];
|
char llbuff[22];
|
||||||
MARIA_SORT_INFO sort_info;
|
MARIA_SORT_INFO sort_info;
|
||||||
ulonglong key_map=share->state.key_map;
|
ulonglong key_map=share->state.key_map;
|
||||||
@ -2912,7 +2978,7 @@ int maria_repair_by_sort(HA_CHECK *param, register MARIA_HA *info,
|
|||||||
if (param->testflag & T_CALC_CHECKSUM)
|
if (param->testflag & T_CALC_CHECKSUM)
|
||||||
sort_param.calc_checksum= 1;
|
sort_param.calc_checksum= 1;
|
||||||
|
|
||||||
rec_per_key_part= param->rec_per_key_part;
|
rec_per_key_part= param->new_rec_per_key_part;
|
||||||
for (sort_param.key=0 ; sort_param.key < share->base.keys ;
|
for (sort_param.key=0 ; sort_param.key < share->base.keys ;
|
||||||
rec_per_key_part+=sort_param.keyinfo->keysegs, sort_param.key++)
|
rec_per_key_part+=sort_param.keyinfo->keysegs, sort_param.key++)
|
||||||
{
|
{
|
||||||
@ -2924,7 +2990,7 @@ int maria_repair_by_sort(HA_CHECK *param, register MARIA_HA *info,
|
|||||||
/* Remember old statistics for key */
|
/* Remember old statistics for key */
|
||||||
memcpy((char*) rec_per_key_part,
|
memcpy((char*) rec_per_key_part,
|
||||||
(char*) (share->state.rec_per_key_part +
|
(char*) (share->state.rec_per_key_part +
|
||||||
(uint) (rec_per_key_part - param->rec_per_key_part)),
|
(uint) (rec_per_key_part - param->new_rec_per_key_part)),
|
||||||
sort_param.keyinfo->keysegs*sizeof(*rec_per_key_part));
|
sort_param.keyinfo->keysegs*sizeof(*rec_per_key_part));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -2990,8 +3056,8 @@ int maria_repair_by_sort(HA_CHECK *param, register MARIA_HA *info,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (_ma_create_index_by_sort(&sort_param,
|
if (_ma_create_index_by_sort(&sort_param,
|
||||||
(my_bool) (!(param->testflag & T_VERBOSE)),
|
(my_bool) (!(param->testflag & T_VERBOSE)),
|
||||||
(uint) param->sort_buffer_length))
|
(size_t) param->sort_buffer_length))
|
||||||
{
|
{
|
||||||
param->retry_repair=1;
|
param->retry_repair=1;
|
||||||
goto err;
|
goto err;
|
||||||
@ -3004,9 +3070,11 @@ int maria_repair_by_sort(HA_CHECK *param, register MARIA_HA *info,
|
|||||||
sort_info.max_records= (ha_rows) info->state->records;
|
sort_info.max_records= (ha_rows) info->state->records;
|
||||||
|
|
||||||
if (param->testflag & T_STATISTICS)
|
if (param->testflag & T_STATISTICS)
|
||||||
maria_update_key_parts(sort_param.keyinfo, rec_per_key_part, sort_param.unique,
|
maria_update_key_parts(sort_param.keyinfo, rec_per_key_part,
|
||||||
param->stats_method == MI_STATS_METHOD_IGNORE_NULLS?
|
sort_param.unique,
|
||||||
sort_param.notnull: NULL,(ulonglong) info->state->records);
|
param->stats_method == MI_STATS_METHOD_IGNORE_NULLS?
|
||||||
|
sort_param.notnull : NULL,
|
||||||
|
(ulonglong) info->state->records);
|
||||||
maria_set_key_active(share->state.key_map, sort_param.key);
|
maria_set_key_active(share->state.key_map, sort_param.key);
|
||||||
|
|
||||||
if (sort_param.fix_datafile)
|
if (sort_param.fix_datafile)
|
||||||
@ -3200,7 +3268,7 @@ int maria_repair_parallel(HA_CHECK *param, register MARIA_HA *info,
|
|||||||
File new_file;
|
File new_file;
|
||||||
MARIA_SORT_PARAM *sort_param=0;
|
MARIA_SORT_PARAM *sort_param=0;
|
||||||
MARIA_SHARE *share=info->s;
|
MARIA_SHARE *share=info->s;
|
||||||
ulong *rec_per_key_part;
|
double *rec_per_key_part;
|
||||||
HA_KEYSEG *keyseg;
|
HA_KEYSEG *keyseg;
|
||||||
char llbuff[22];
|
char llbuff[22];
|
||||||
IO_CACHE new_data_cache; /* For non-quick repair. */
|
IO_CACHE new_data_cache; /* For non-quick repair. */
|
||||||
@ -3377,7 +3445,7 @@ int maria_repair_parallel(HA_CHECK *param, register MARIA_HA *info,
|
|||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
total_key_length=0;
|
total_key_length=0;
|
||||||
rec_per_key_part= param->rec_per_key_part;
|
rec_per_key_part= param->new_rec_per_key_part;
|
||||||
info->state->records=info->state->del=share->state.split=0;
|
info->state->records=info->state->del=share->state.split=0;
|
||||||
info->state->empty=0;
|
info->state->empty=0;
|
||||||
|
|
||||||
@ -3392,7 +3460,7 @@ int maria_repair_parallel(HA_CHECK *param, register MARIA_HA *info,
|
|||||||
/* Remember old statistics for key */
|
/* Remember old statistics for key */
|
||||||
memcpy((char*) rec_per_key_part,
|
memcpy((char*) rec_per_key_part,
|
||||||
(char*) (share->state.rec_per_key_part+
|
(char*) (share->state.rec_per_key_part+
|
||||||
(uint) (rec_per_key_part - param->rec_per_key_part)),
|
(uint) (rec_per_key_part - param->new_rec_per_key_part)),
|
||||||
sort_param[i].keyinfo->keysegs*sizeof(*rec_per_key_part));
|
sort_param[i].keyinfo->keysegs*sizeof(*rec_per_key_part));
|
||||||
istep=0;
|
istep=0;
|
||||||
continue;
|
continue;
|
||||||
@ -4656,12 +4724,14 @@ static int sort_insert_key(MARIA_SORT_PARAM *sort_param,
|
|||||||
_ma_check_print_error(param,"To many key-block-levels; Try increasing sort_key_blocks");
|
_ma_check_print_error(param,"To many key-block-levels; Try increasing sort_key_blocks");
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
}
|
}
|
||||||
a_length=2+nod_flag;
|
a_length= info->s->keypage_header + nod_flag;
|
||||||
key_block->end_pos=anc_buff+2;
|
key_block->end_pos= anc_buff + info->s->keypage_header;
|
||||||
|
_ma_store_keynr(info, anc_buff, (uint) (sort_param->keyinfo -
|
||||||
|
info->s->keyinfo));
|
||||||
lastkey=0; /* No previous key in block */
|
lastkey=0; /* No previous key in block */
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
a_length= maria_data_on_page(anc_buff);
|
a_length= _ma_get_page_used(info, anc_buff);
|
||||||
|
|
||||||
/* Save pointer to previous block */
|
/* Save pointer to previous block */
|
||||||
if (nod_flag)
|
if (nod_flag)
|
||||||
@ -4672,7 +4742,7 @@ static int sort_insert_key(MARIA_SORT_PARAM *sort_param,
|
|||||||
&s_temp);
|
&s_temp);
|
||||||
(*keyinfo->store_key)(keyinfo, key_block->end_pos+nod_flag,&s_temp);
|
(*keyinfo->store_key)(keyinfo, key_block->end_pos+nod_flag,&s_temp);
|
||||||
a_length+=t_length;
|
a_length+=t_length;
|
||||||
maria_putint(anc_buff,a_length,nod_flag);
|
_ma_store_page_used(info, anc_buff, a_length, nod_flag);
|
||||||
key_block->end_pos+=t_length;
|
key_block->end_pos+=t_length;
|
||||||
if (a_length <= keyinfo->block_length)
|
if (a_length <= keyinfo->block_length)
|
||||||
{
|
{
|
||||||
@ -4681,8 +4751,8 @@ static int sort_insert_key(MARIA_SORT_PARAM *sort_param,
|
|||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Fill block with end-zero and write filled block */
|
/* Fill block with end-zero and write filled block */
|
||||||
maria_putint(anc_buff,key_block->last_length,nod_flag);
|
_ma_store_page_used(info, anc_buff, key_block->last_length, nod_flag);
|
||||||
bzero(anc_buff+key_block->last_length,
|
bzero(anc_buff+key_block->last_length,
|
||||||
keyinfo->block_length- key_block->last_length);
|
keyinfo->block_length- key_block->last_length);
|
||||||
key_file_length=info->state->key_file_length;
|
key_file_length=info->state->key_file_length;
|
||||||
@ -4698,7 +4768,7 @@ static int sort_insert_key(MARIA_SORT_PARAM *sort_param,
|
|||||||
else if (my_pwrite(info->s->kfile.file, anc_buff,
|
else if (my_pwrite(info->s->kfile.file, anc_buff,
|
||||||
(uint) keyinfo->block_length,filepos, param->myf_rw))
|
(uint) keyinfo->block_length,filepos, param->myf_rw))
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
DBUG_DUMP("buff",anc_buff,maria_data_on_page(anc_buff));
|
DBUG_DUMP("buff", anc_buff, _ma_get_page_used(info, anc_buff));
|
||||||
|
|
||||||
/* Write separator-key to block in next level */
|
/* Write separator-key to block in next level */
|
||||||
if (sort_insert_key(sort_param,key_block+1,key_block->lastkey,filepos))
|
if (sort_insert_key(sort_param,key_block+1,key_block->lastkey,filepos))
|
||||||
@ -4792,7 +4862,7 @@ int _ma_flush_pending_blocks(MARIA_SORT_PARAM *sort_param)
|
|||||||
for (key_block=sort_info->key_block ; key_block->inited ; key_block++)
|
for (key_block=sort_info->key_block ; key_block->inited ; key_block++)
|
||||||
{
|
{
|
||||||
key_block->inited=0;
|
key_block->inited=0;
|
||||||
length= maria_data_on_page(key_block->buff);
|
length= _ma_get_page_used(info, key_block->buff);
|
||||||
if (nod_flag)
|
if (nod_flag)
|
||||||
_ma_kpointer(info,key_block->end_pos,filepos);
|
_ma_kpointer(info,key_block->end_pos,filepos);
|
||||||
key_file_length=info->state->key_file_length;
|
key_file_length=info->state->key_file_length;
|
||||||
@ -5079,13 +5149,13 @@ int maria_update_state_info(HA_CHECK *param, MARIA_HA *info,uint update)
|
|||||||
if (update & UPDATE_STAT)
|
if (update & UPDATE_STAT)
|
||||||
{
|
{
|
||||||
uint i, key_parts= mi_uint2korr(share->state.header.key_parts);
|
uint i, key_parts= mi_uint2korr(share->state.header.key_parts);
|
||||||
share->state.rec_per_key_rows=info->state->records;
|
share->state.records_at_analyze= info->state->records;
|
||||||
share->state.changed&= ~STATE_NOT_ANALYZED;
|
share->state.changed&= ~STATE_NOT_ANALYZED;
|
||||||
if (info->state->records)
|
if (info->state->records)
|
||||||
{
|
{
|
||||||
for (i=0; i<key_parts; i++)
|
for (i=0; i<key_parts; i++)
|
||||||
{
|
{
|
||||||
if (!(share->state.rec_per_key_part[i]=param->rec_per_key_part[i]))
|
if (!(share->state.rec_per_key_part[i]=param->new_rec_per_key_part[i]))
|
||||||
share->state.changed|= STATE_NOT_ANALYZED;
|
share->state.changed|= STATE_NOT_ANALYZED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -5246,13 +5316,14 @@ void _ma_update_auto_increment_key(HA_CHECK *param, MARIA_HA *info,
|
|||||||
IGNORE_NULLS n/a tuples that don't have NULLs
|
IGNORE_NULLS n/a tuples that don't have NULLs
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void maria_update_key_parts(MARIA_KEYDEF *keyinfo, ulong *rec_per_key_part,
|
void maria_update_key_parts(MARIA_KEYDEF *keyinfo, double *rec_per_key_part,
|
||||||
ulonglong *unique, ulonglong *notnull,
|
ulonglong *unique, ulonglong *notnull,
|
||||||
ulonglong records)
|
ulonglong records)
|
||||||
{
|
{
|
||||||
ulonglong count=0,tmp, unique_tuples;
|
ulonglong count=0, unique_tuples;
|
||||||
ulonglong tuples= records;
|
ulonglong tuples= records;
|
||||||
uint parts;
|
uint parts;
|
||||||
|
double tmp;
|
||||||
for (parts=0 ; parts < keyinfo->keysegs ; parts++)
|
for (parts=0 ; parts < keyinfo->keysegs ; parts++)
|
||||||
{
|
{
|
||||||
count+=unique[parts];
|
count+=unique[parts];
|
||||||
@ -5271,20 +5342,17 @@ void maria_update_key_parts(MARIA_KEYDEF *keyinfo, ulong *rec_per_key_part,
|
|||||||
if (unique_tuples == 0)
|
if (unique_tuples == 0)
|
||||||
tmp= 1;
|
tmp= 1;
|
||||||
else if (count == 0)
|
else if (count == 0)
|
||||||
tmp= tuples; /* 1 unique tuple */
|
tmp= ulonglong2double(tuples); /* 1 unique tuple */
|
||||||
else
|
else
|
||||||
tmp= (tuples + unique_tuples/2) / unique_tuples;
|
tmp= ulonglong2double(tuples) / ulonglong2double(unique_tuples);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
for some weird keys (e.g. FULLTEXT) tmp can be <1 here.
|
for some weird keys (e.g. FULLTEXT) tmp can be <1 here.
|
||||||
let's ensure it is not
|
let's ensure it is not
|
||||||
*/
|
*/
|
||||||
set_if_bigger(tmp,1);
|
set_if_bigger(tmp,1);
|
||||||
if (tmp >= (ulonglong) ~(ulong) 0)
|
|
||||||
tmp=(ulonglong) ~(ulong) 0;
|
|
||||||
|
|
||||||
*rec_per_key_part=(ulong) tmp;
|
*rec_per_key_part++= tmp;
|
||||||
rec_per_key_part++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,23 +17,40 @@
|
|||||||
|
|
||||||
#include "maria_def.h"
|
#include "maria_def.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
Calculate a checksum for the record
|
||||||
|
|
||||||
|
_ma_checksum()
|
||||||
|
@param info Maria handler
|
||||||
|
@param record Record
|
||||||
|
|
||||||
|
@note
|
||||||
|
To ensure that the checksum is independent of the row format
|
||||||
|
we need to always calculate the checksum in the original field order.
|
||||||
|
|
||||||
|
@return checksum
|
||||||
|
*/
|
||||||
|
|
||||||
ha_checksum _ma_checksum(MARIA_HA *info, const uchar *record)
|
ha_checksum _ma_checksum(MARIA_HA *info, const uchar *record)
|
||||||
{
|
{
|
||||||
ha_checksum crc=0;
|
ha_checksum crc=0;
|
||||||
MARIA_COLUMNDEF *column= info->s->columndef;
|
uint i,end;
|
||||||
MARIA_COLUMNDEF *column_end= column+ info->s->base.fields;
|
MARIA_COLUMNDEF *base_column= info->s->columndef;
|
||||||
|
uint16 *column_nr= info->s->column_nr;
|
||||||
|
|
||||||
if (info->s->base.null_bytes)
|
if (info->s->base.null_bytes)
|
||||||
crc= my_checksum(crc, record, info->s->base.null_bytes);
|
crc= my_checksum(crc, record, info->s->base.null_bytes);
|
||||||
|
|
||||||
for ( ; column != column_end ; column++)
|
for (i= 0, end= info->s->base.fields ; i < end ; i++)
|
||||||
{
|
{
|
||||||
const uchar *pos= record + column->offset;
|
MARIA_COLUMNDEF *column= base_column + column_nr[i];
|
||||||
|
const uchar *pos;
|
||||||
ulong length;
|
ulong length;
|
||||||
|
|
||||||
if (record[column->null_pos] & column->null_bit)
|
if (record[column->null_pos] & column->null_bit)
|
||||||
continue; /* Null field */
|
continue; /* Null field */
|
||||||
|
|
||||||
|
pos= record + column->offset;
|
||||||
switch (column->type) {
|
switch (column->type) {
|
||||||
case FIELD_BLOB:
|
case FIELD_BLOB:
|
||||||
{
|
{
|
||||||
|
@ -50,7 +50,7 @@ int maria_create(const char *name, enum data_file_type datafile_type,
|
|||||||
key_length,info_length,key_segs,options,min_key_length_skip,
|
key_length,info_length,key_segs,options,min_key_length_skip,
|
||||||
base_pos,long_varchar_count,varchar_length,
|
base_pos,long_varchar_count,varchar_length,
|
||||||
unique_key_parts,fulltext_keys,offset, not_block_record_extra_length;
|
unique_key_parts,fulltext_keys,offset, not_block_record_extra_length;
|
||||||
uint max_field_lengths, extra_header_size;
|
uint max_field_lengths, extra_header_size, column_nr;
|
||||||
ulong reclength, real_reclength,min_pack_length;
|
ulong reclength, real_reclength,min_pack_length;
|
||||||
char filename[FN_REFLEN], linkname[FN_REFLEN], *linkname_ptr;
|
char filename[FN_REFLEN], linkname[FN_REFLEN], *linkname_ptr;
|
||||||
ulong pack_reclength;
|
ulong pack_reclength;
|
||||||
@ -62,7 +62,9 @@ int maria_create(const char *name, enum data_file_type datafile_type,
|
|||||||
MARIA_UNIQUEDEF *uniquedef;
|
MARIA_UNIQUEDEF *uniquedef;
|
||||||
HA_KEYSEG *keyseg,tmp_keyseg;
|
HA_KEYSEG *keyseg,tmp_keyseg;
|
||||||
MARIA_COLUMNDEF *column, *end_column;
|
MARIA_COLUMNDEF *column, *end_column;
|
||||||
ulong *rec_per_key_part;
|
double *rec_per_key_part;
|
||||||
|
ulong *nulls_per_key_part;
|
||||||
|
uint16 *column_array;
|
||||||
my_off_t key_root[HA_MAX_POSSIBLE_KEY], kfile_size_before_extension;
|
my_off_t key_root[HA_MAX_POSSIBLE_KEY], kfile_size_before_extension;
|
||||||
MARIA_CREATE_INFO tmp_create_info;
|
MARIA_CREATE_INFO tmp_create_info;
|
||||||
my_bool tmp_table= FALSE; /* cache for presence of HA_OPTION_TMP_TABLE */
|
my_bool tmp_table= FALSE; /* cache for presence of HA_OPTION_TMP_TABLE */
|
||||||
@ -111,9 +113,16 @@ int maria_create(const char *name, enum data_file_type datafile_type,
|
|||||||
ci->reloc_rows=ci->max_rows; /* Check if wrong parameter */
|
ci->reloc_rows=ci->max_rows; /* Check if wrong parameter */
|
||||||
|
|
||||||
if (!(rec_per_key_part=
|
if (!(rec_per_key_part=
|
||||||
(ulong*) my_malloc((keys + uniques)*HA_MAX_KEY_SEG*sizeof(long),
|
(double*) my_malloc((keys + uniques)*HA_MAX_KEY_SEG*sizeof(double) +
|
||||||
MYF(MY_WME | MY_ZEROFILL))))
|
(keys + uniques)*HA_MAX_KEY_SEG*sizeof(ulong) +
|
||||||
|
sizeof(uint16) * columns,
|
||||||
|
MYF(MY_WME | MY_ZEROFILL))))
|
||||||
DBUG_RETURN(my_errno);
|
DBUG_RETURN(my_errno);
|
||||||
|
nulls_per_key_part= (ulong*) (rec_per_key_part +
|
||||||
|
(keys + uniques) * HA_MAX_KEY_SEG);
|
||||||
|
column_array= (uint16*) (nulls_per_key_part +
|
||||||
|
(keys + uniques) * HA_MAX_KEY_SEG);
|
||||||
|
|
||||||
|
|
||||||
/* Start by checking fields and field-types used */
|
/* Start by checking fields and field-types used */
|
||||||
|
|
||||||
@ -121,12 +130,14 @@ int maria_create(const char *name, enum data_file_type datafile_type,
|
|||||||
pack_reclength= max_field_lengths= 0;
|
pack_reclength= max_field_lengths= 0;
|
||||||
reclength= min_pack_length= ci->null_bytes;
|
reclength= min_pack_length= ci->null_bytes;
|
||||||
forced_packed= 0;
|
forced_packed= 0;
|
||||||
|
column_nr= 0;
|
||||||
|
|
||||||
for (column= columndef, end_column= column + columns ;
|
for (column= columndef, end_column= column + columns ;
|
||||||
column != end_column ;
|
column != end_column ;
|
||||||
column++)
|
column++)
|
||||||
{
|
{
|
||||||
/* Fill in not used struct parts */
|
/* Fill in not used struct parts */
|
||||||
|
column->column_nr= column_nr++;
|
||||||
column->offset= reclength;
|
column->offset= reclength;
|
||||||
column->empty_pos= 0;
|
column->empty_pos= 0;
|
||||||
column->empty_bit= 0;
|
column->empty_bit= 0;
|
||||||
@ -282,6 +293,8 @@ int maria_create(const char *name, enum data_file_type datafile_type,
|
|||||||
options|= HA_OPTION_DELAY_KEY_WRITE;
|
options|= HA_OPTION_DELAY_KEY_WRITE;
|
||||||
if (flags & HA_CREATE_RELIES_ON_SQL_LAYER)
|
if (flags & HA_CREATE_RELIES_ON_SQL_LAYER)
|
||||||
options|= HA_OPTION_RELIES_ON_SQL_LAYER;
|
options|= HA_OPTION_RELIES_ON_SQL_LAYER;
|
||||||
|
if (flags & HA_CREATE_PAGE_CHECKSUM)
|
||||||
|
options|= HA_OPTION_PAGE_CHECKSUM;
|
||||||
|
|
||||||
pack_bytes= (packed + 7) / 8;
|
pack_bytes= (packed + 7) / 8;
|
||||||
if (pack_reclength != INT_MAX32)
|
if (pack_reclength != INT_MAX32)
|
||||||
@ -315,7 +328,7 @@ int maria_create(const char *name, enum data_file_type datafile_type,
|
|||||||
ulonglong data_file_length= ci->data_file_length;
|
ulonglong data_file_length= ci->data_file_length;
|
||||||
if (!data_file_length)
|
if (!data_file_length)
|
||||||
data_file_length= ((((ulonglong) 1 << ((BLOCK_RECORD_POINTER_SIZE-1) *
|
data_file_length= ((((ulonglong) 1 << ((BLOCK_RECORD_POINTER_SIZE-1) *
|
||||||
8)) -1));
|
8)) -1) * maria_block_size);
|
||||||
if (rows_per_page > 0)
|
if (rows_per_page > 0)
|
||||||
{
|
{
|
||||||
set_if_smaller(rows_per_page, MAX_ROWS_PER_PAGE);
|
set_if_smaller(rows_per_page, MAX_ROWS_PER_PAGE);
|
||||||
@ -335,15 +348,19 @@ int maria_create(const char *name, enum data_file_type datafile_type,
|
|||||||
max_rows= (ulonglong) ci->max_rows;
|
max_rows= (ulonglong) ci->max_rows;
|
||||||
if (datafile_type == BLOCK_RECORD)
|
if (datafile_type == BLOCK_RECORD)
|
||||||
{
|
{
|
||||||
/* The + 1 is for record position withing page */
|
/*
|
||||||
|
The + 1 is for record position withing page
|
||||||
|
The / 2 is because we need one bit for knowing if there is transid's
|
||||||
|
after the row pointer
|
||||||
|
*/
|
||||||
pointer= maria_get_pointer_length((ci->data_file_length /
|
pointer= maria_get_pointer_length((ci->data_file_length /
|
||||||
maria_block_size), 3) + 1;
|
(maria_block_size * 2)), 3) + 1;
|
||||||
set_if_smaller(pointer, BLOCK_RECORD_POINTER_SIZE);
|
set_if_smaller(pointer, BLOCK_RECORD_POINTER_SIZE);
|
||||||
|
|
||||||
if (!max_rows)
|
if (!max_rows)
|
||||||
max_rows= (((((ulonglong) 1 << ((pointer-1)*8)) -1) * maria_block_size) /
|
max_rows= (((((ulonglong) 1 << ((pointer-1)*8)) -1) * maria_block_size) /
|
||||||
min_pack_length);
|
min_pack_length / 2);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (datafile_type != STATIC_RECORD)
|
if (datafile_type != STATIC_RECORD)
|
||||||
@ -366,7 +383,8 @@ int maria_create(const char *name, enum data_file_type datafile_type,
|
|||||||
|
|
||||||
max_key_length=0; tot_length=0 ; key_segs=0;
|
max_key_length=0; tot_length=0 ; key_segs=0;
|
||||||
fulltext_keys=0;
|
fulltext_keys=0;
|
||||||
share.state.rec_per_key_part=rec_per_key_part;
|
share.state.rec_per_key_part= rec_per_key_part;
|
||||||
|
share.state.nulls_per_key_part= nulls_per_key_part;
|
||||||
share.state.key_root=key_root;
|
share.state.key_root=key_root;
|
||||||
share.state.key_del= HA_OFFSET_ERROR;
|
share.state.key_del= HA_OFFSET_ERROR;
|
||||||
if (uniques)
|
if (uniques)
|
||||||
@ -607,7 +625,7 @@ int maria_create(const char *name, enum data_file_type datafile_type,
|
|||||||
keys * MARIA_KEYDEF_SIZE+
|
keys * MARIA_KEYDEF_SIZE+
|
||||||
uniques * MARIA_UNIQUEDEF_SIZE +
|
uniques * MARIA_UNIQUEDEF_SIZE +
|
||||||
(key_segs + unique_key_parts)*HA_KEYSEG_SIZE+
|
(key_segs + unique_key_parts)*HA_KEYSEG_SIZE+
|
||||||
columns*MARIA_COLUMNDEF_SIZE);
|
columns*(MARIA_COLUMNDEF_SIZE + 2));
|
||||||
|
|
||||||
DBUG_PRINT("info", ("info_length: %u", info_length));
|
DBUG_PRINT("info", ("info_length: %u", info_length));
|
||||||
/* There are only 16 bits for the total header length. */
|
/* There are only 16 bits for the total header length. */
|
||||||
@ -621,9 +639,9 @@ int maria_create(const char *name, enum data_file_type datafile_type,
|
|||||||
}
|
}
|
||||||
|
|
||||||
bmove(share.state.header.file_version,(uchar*) maria_file_magic,4);
|
bmove(share.state.header.file_version,(uchar*) maria_file_magic,4);
|
||||||
ci->old_options=options| (ci->old_options & HA_OPTION_TEMP_COMPRESS_RECORD ?
|
ci->old_options=options | (ci->old_options & HA_OPTION_TEMP_COMPRESS_RECORD ?
|
||||||
HA_OPTION_COMPRESS_RECORD |
|
HA_OPTION_COMPRESS_RECORD |
|
||||||
HA_OPTION_TEMP_COMPRESS_RECORD: 0);
|
HA_OPTION_TEMP_COMPRESS_RECORD: 0);
|
||||||
mi_int2store(share.state.header.options,ci->old_options);
|
mi_int2store(share.state.header.options,ci->old_options);
|
||||||
mi_int2store(share.state.header.header_length,info_length);
|
mi_int2store(share.state.header.header_length,info_length);
|
||||||
mi_int2store(share.state.header.state_info_length,MARIA_STATE_INFO_SIZE);
|
mi_int2store(share.state.header.state_info_length,MARIA_STATE_INFO_SIZE);
|
||||||
@ -900,6 +918,7 @@ int maria_create(const char *name, enum data_file_type datafile_type,
|
|||||||
(qsort_cmp) compare_columns);
|
(qsort_cmp) compare_columns);
|
||||||
for (i=0 ; i < share.base.fields ; i++)
|
for (i=0 ; i < share.base.fields ; i++)
|
||||||
{
|
{
|
||||||
|
column_array[col_order[i]->column_nr]= i;
|
||||||
if (_ma_columndef_write(file, col_order[i]))
|
if (_ma_columndef_write(file, col_order[i]))
|
||||||
{
|
{
|
||||||
my_free((uchar*) col_order, MYF(0));
|
my_free((uchar*) col_order, MYF(0));
|
||||||
@ -911,9 +930,14 @@ int maria_create(const char *name, enum data_file_type datafile_type,
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (i=0 ; i < share.base.fields ; i++)
|
for (i=0 ; i < share.base.fields ; i++)
|
||||||
|
{
|
||||||
|
column_array[i]= (uint16) i;
|
||||||
if (_ma_columndef_write(file, &columndef[i]))
|
if (_ma_columndef_write(file, &columndef[i]))
|
||||||
goto err;
|
goto err;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
if (_ma_column_nr_write(file, column_array, columns))
|
||||||
|
goto err;
|
||||||
|
|
||||||
if ((kfile_size_before_extension= my_tell(file,MYF(0))) == MY_FILEPOS_ERROR)
|
if ((kfile_size_before_extension= my_tell(file,MYF(0))) == MY_FILEPOS_ERROR)
|
||||||
goto err;
|
goto err;
|
||||||
|
@ -92,7 +92,7 @@ void _ma_print_key(FILE *stream, register HA_KEYSEG *keyseg,
|
|||||||
key=end;
|
key=end;
|
||||||
break;
|
break;
|
||||||
case HA_KEYTYPE_ULONG_INT:
|
case HA_KEYTYPE_ULONG_INT:
|
||||||
l_1=mi_sint4korr(key);
|
l_1=mi_uint4korr(key);
|
||||||
VOID(fprintf(stream,"%lu",(ulong) l_1));
|
VOID(fprintf(stream,"%lu",(ulong) l_1));
|
||||||
key=end;
|
key=end;
|
||||||
break;
|
break;
|
||||||
|
@ -176,8 +176,8 @@ static int _ma_ck_real_delete(register MARIA_HA *info, MARIA_KEYDEF *keyinfo,
|
|||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
if ((error=d_search(info,keyinfo,
|
if ((error=d_search(info,keyinfo,
|
||||||
(keyinfo->flag & HA_FULLTEXT ? SEARCH_FIND | SEARCH_UPDATE
|
(keyinfo->flag & HA_FULLTEXT ?
|
||||||
: SEARCH_SAME),
|
SEARCH_FIND | SEARCH_UPDATE : SEARCH_SAME),
|
||||||
key,key_length,old_root,root_buff)) >0)
|
key,key_length,old_root,root_buff)) >0)
|
||||||
{
|
{
|
||||||
if (error == 2)
|
if (error == 2)
|
||||||
@ -187,11 +187,14 @@ static int _ma_ck_real_delete(register MARIA_HA *info, MARIA_KEYDEF *keyinfo,
|
|||||||
}
|
}
|
||||||
else /* error == 1 */
|
else /* error == 1 */
|
||||||
{
|
{
|
||||||
if (maria_data_on_page(root_buff) <= (nod_flag=_ma_test_if_nod(root_buff))+3)
|
uint used_length;
|
||||||
|
_ma_get_used_and_nod(info, root_buff, used_length, nod_flag);
|
||||||
|
if (used_length <= nod_flag + info->s->keypage_header + 1)
|
||||||
{
|
{
|
||||||
error=0;
|
error=0;
|
||||||
if (nod_flag)
|
if (nod_flag)
|
||||||
*root= _ma_kpos(nod_flag,root_buff+2+nod_flag);
|
*root= _ma_kpos(nod_flag, root_buff +info->s->keypage_header +
|
||||||
|
nod_flag);
|
||||||
else
|
else
|
||||||
*root=HA_OFFSET_ERROR;
|
*root=HA_OFFSET_ERROR;
|
||||||
if (_ma_dispose(info,keyinfo,old_root,DFLT_INIT_HITS))
|
if (_ma_dispose(info,keyinfo,old_root,DFLT_INIT_HITS))
|
||||||
@ -209,13 +212,14 @@ err:
|
|||||||
} /* _ma_ck_real_delete */
|
} /* _ma_ck_real_delete */
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Remove key below key root
|
@brief Remove key below key root
|
||||||
** Return values:
|
|
||||||
** 1 if there are less buffers; In this case anc_buff is not saved
|
@return
|
||||||
** 2 if there are more buffers
|
@retval 1 If there are less buffers; In this case anc_buff is not saved
|
||||||
** -1 on errors
|
@retval 2 If there are more buffers
|
||||||
*/
|
@retval -1 On errors
|
||||||
|
*/
|
||||||
|
|
||||||
static int d_search(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
|
static int d_search(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
|
||||||
uint comp_flag, uchar *key, uint key_length,
|
uint comp_flag, uchar *key, uint key_length,
|
||||||
@ -228,7 +232,7 @@ static int d_search(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
|
|||||||
my_off_t leaf_page,next_block;
|
my_off_t leaf_page,next_block;
|
||||||
uchar lastkey[HA_MAX_KEY_BUFF];
|
uchar lastkey[HA_MAX_KEY_BUFF];
|
||||||
DBUG_ENTER("d_search");
|
DBUG_ENTER("d_search");
|
||||||
DBUG_DUMP("page",anc_buff,maria_data_on_page(anc_buff));
|
DBUG_DUMP("page",anc_buff,_ma_get_page_used(info, anc_buff));
|
||||||
|
|
||||||
search_key_length= (comp_flag & SEARCH_FIND) ? key_length : USE_WHOLE_KEY;
|
search_key_length= (comp_flag & SEARCH_FIND) ? key_length : USE_WHOLE_KEY;
|
||||||
flag=(*keyinfo->bin_search)(info,keyinfo,anc_buff,key, search_key_length,
|
flag=(*keyinfo->bin_search)(info,keyinfo,anc_buff,key, search_key_length,
|
||||||
@ -238,7 +242,7 @@ static int d_search(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
|
|||||||
DBUG_PRINT("error",("Found wrong key"));
|
DBUG_PRINT("error",("Found wrong key"));
|
||||||
DBUG_RETURN(-1);
|
DBUG_RETURN(-1);
|
||||||
}
|
}
|
||||||
nod_flag=_ma_test_if_nod(anc_buff);
|
nod_flag=_ma_test_if_nod(info, anc_buff);
|
||||||
|
|
||||||
if (!flag && keyinfo->flag & HA_FULLTEXT)
|
if (!flag && keyinfo->flag & HA_FULLTEXT)
|
||||||
{
|
{
|
||||||
@ -338,14 +342,14 @@ static int d_search(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
|
|||||||
else
|
else
|
||||||
{ /* Found key */
|
{ /* Found key */
|
||||||
uint tmp;
|
uint tmp;
|
||||||
length= maria_data_on_page(anc_buff);
|
length= _ma_get_page_used(info, anc_buff);
|
||||||
if (!(tmp= remove_key(keyinfo,nod_flag,keypos,lastkey,anc_buff+length,
|
if (!(tmp= remove_key(keyinfo,nod_flag,keypos,lastkey,anc_buff+length,
|
||||||
&next_block)))
|
&next_block)))
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
length-= tmp;
|
length-= tmp;
|
||||||
|
|
||||||
maria_putint(anc_buff,length,nod_flag);
|
_ma_store_page_used(info, anc_buff, length, nod_flag);
|
||||||
if (!nod_flag)
|
if (!nod_flag)
|
||||||
{ /* On leaf page */
|
{ /* On leaf page */
|
||||||
if (_ma_write_keypage(info,keyinfo,page,DFLT_INIT_HITS,anc_buff))
|
if (_ma_write_keypage(info,keyinfo,page,DFLT_INIT_HITS,anc_buff))
|
||||||
@ -375,7 +379,8 @@ static int d_search(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
|
|||||||
(uchar*) 0,(uchar*) 0,(my_off_t) 0,(my_bool) 0);
|
(uchar*) 0,(uchar*) 0,(my_off_t) 0,(my_bool) 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (ret_value == 0 && maria_data_on_page(anc_buff) > keyinfo->block_length)
|
if (ret_value == 0 && _ma_get_page_used(info, anc_buff) >
|
||||||
|
(uint) (keyinfo->block_length - KEYPAGE_CHECKSUM_SIZE))
|
||||||
{
|
{
|
||||||
save_flag=1;
|
save_flag=1;
|
||||||
ret_value= _ma_split_page(info,keyinfo,key,anc_buff,lastkey,0) | 2;
|
ret_value= _ma_split_page(info,keyinfo,key,anc_buff,lastkey,0) | 2;
|
||||||
@ -384,7 +389,7 @@ static int d_search(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
|
|||||||
ret_value|= _ma_write_keypage(info,keyinfo,page,DFLT_INIT_HITS,anc_buff);
|
ret_value|= _ma_write_keypage(info,keyinfo,page,DFLT_INIT_HITS,anc_buff);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DBUG_DUMP("page",anc_buff,maria_data_on_page(anc_buff));
|
DBUG_DUMP("page", anc_buff, _ma_get_page_used(info, anc_buff));
|
||||||
}
|
}
|
||||||
my_afree(leaf_buff);
|
my_afree(leaf_buff);
|
||||||
DBUG_PRINT("exit",("Return: %d",ret_value));
|
DBUG_PRINT("exit",("Return: %d",ret_value));
|
||||||
@ -407,7 +412,7 @@ static int del(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
|
|||||||
uchar *ret_key) /* key before keypos in anc_buff */
|
uchar *ret_key) /* key before keypos in anc_buff */
|
||||||
{
|
{
|
||||||
int ret_value,length;
|
int ret_value,length;
|
||||||
uint a_length,nod_flag,tmp;
|
uint a_length, nod_flag, used_length, tmp;
|
||||||
my_off_t next_page;
|
my_off_t next_page;
|
||||||
uchar keybuff[HA_MAX_KEY_BUFF],*endpos,*next_buff,*key_start, *prev_key;
|
uchar keybuff[HA_MAX_KEY_BUFF],*endpos,*next_buff,*key_start, *prev_key;
|
||||||
MARIA_SHARE *share=info->s;
|
MARIA_SHARE *share=info->s;
|
||||||
@ -415,14 +420,16 @@ static int del(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
|
|||||||
DBUG_ENTER("del");
|
DBUG_ENTER("del");
|
||||||
DBUG_PRINT("enter",("leaf_page: %ld keypos: 0x%lx", (long) leaf_page,
|
DBUG_PRINT("enter",("leaf_page: %ld keypos: 0x%lx", (long) leaf_page,
|
||||||
(ulong) keypos));
|
(ulong) keypos));
|
||||||
DBUG_DUMP("leaf_buff",leaf_buff,maria_data_on_page(leaf_buff));
|
|
||||||
|
|
||||||
endpos= leaf_buff+ maria_data_on_page(leaf_buff);
|
_ma_get_used_and_nod(info, leaf_buff, used_length, nod_flag);
|
||||||
|
DBUG_DUMP("leaf_buff", leaf_buff, used_length);
|
||||||
|
|
||||||
|
endpos= leaf_buff + used_length;
|
||||||
if (!(key_start= _ma_get_last_key(info,keyinfo,leaf_buff,keybuff,endpos,
|
if (!(key_start= _ma_get_last_key(info,keyinfo,leaf_buff,keybuff,endpos,
|
||||||
&tmp)))
|
&tmp)))
|
||||||
DBUG_RETURN(-1);
|
DBUG_RETURN(-1);
|
||||||
|
|
||||||
if ((nod_flag=_ma_test_if_nod(leaf_buff)))
|
if (nod_flag)
|
||||||
{
|
{
|
||||||
next_page= _ma_kpos(nod_flag,endpos);
|
next_page= _ma_kpos(nod_flag,endpos);
|
||||||
if (!(next_buff= (uchar*) my_alloca((uint) keyinfo->block_length+
|
if (!(next_buff= (uchar*) my_alloca((uint) keyinfo->block_length+
|
||||||
@ -432,18 +439,22 @@ static int del(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
|
|||||||
ret_value= -1;
|
ret_value= -1;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DBUG_DUMP("next_page",next_buff,maria_data_on_page(next_buff));
|
DBUG_DUMP("next_page", next_buff, _ma_get_page_used(info, next_buff));
|
||||||
if ((ret_value=del(info,keyinfo,key,anc_buff,next_page,next_buff,
|
if ((ret_value=del(info,keyinfo,key,anc_buff,next_page,next_buff,
|
||||||
keypos,next_block,ret_key)) >0)
|
keypos,next_block,ret_key)) >0)
|
||||||
{
|
{
|
||||||
endpos=leaf_buff+maria_data_on_page(leaf_buff);
|
/* Get new length after key was deleted */
|
||||||
|
endpos=leaf_buff+_ma_get_page_used(info, leaf_buff);
|
||||||
if (ret_value == 1)
|
if (ret_value == 1)
|
||||||
{
|
{
|
||||||
ret_value=underflow(info,keyinfo,leaf_buff,next_page,
|
ret_value=underflow(info,keyinfo,leaf_buff,next_page,
|
||||||
next_buff,endpos);
|
next_buff,endpos);
|
||||||
if (ret_value == 0 && maria_data_on_page(leaf_buff) > keyinfo->block_length)
|
if (ret_value == 0 &&
|
||||||
|
_ma_get_page_used(info, leaf_buff) >
|
||||||
|
(uint) (keyinfo->block_length - KEYPAGE_CHECKSUM_SIZE))
|
||||||
{
|
{
|
||||||
ret_value= _ma_split_page(info,keyinfo,key,leaf_buff,ret_key,0) | 2;
|
ret_value= (_ma_split_page(info,keyinfo,key,leaf_buff,ret_key,0) |
|
||||||
|
2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -464,20 +475,19 @@ static int del(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Remove last key from leaf page */
|
/* Remove last key from leaf page */
|
||||||
|
_ma_store_page_used(info, leaf_buff, key_start-leaf_buff, nod_flag);
|
||||||
maria_putint(leaf_buff,key_start-leaf_buff,nod_flag);
|
|
||||||
if (_ma_write_keypage(info,keyinfo,leaf_page,DFLT_INIT_HITS,leaf_buff))
|
if (_ma_write_keypage(info,keyinfo,leaf_page,DFLT_INIT_HITS,leaf_buff))
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
/* Place last key in ancestor page on deleted key position */
|
/* Place last key in ancestor page on deleted key position */
|
||||||
|
|
||||||
a_length= maria_data_on_page(anc_buff);
|
a_length= _ma_get_page_used(info, anc_buff);
|
||||||
endpos=anc_buff+a_length;
|
endpos=anc_buff+a_length;
|
||||||
if (keypos != anc_buff+2+share->base.key_reflength &&
|
if (keypos != anc_buff+info->s->keypage_header + share->base.key_reflength &&
|
||||||
!_ma_get_last_key(info,keyinfo,anc_buff,ret_key,keypos,&tmp))
|
!_ma_get_last_key(info,keyinfo,anc_buff,ret_key,keypos,&tmp))
|
||||||
goto err;
|
goto err;
|
||||||
prev_key=(keypos == anc_buff+2+share->base.key_reflength ?
|
prev_key= (keypos == anc_buff + info->s->keypage_header +
|
||||||
0 : ret_key);
|
share->base.key_reflength ? 0 : ret_key);
|
||||||
length=(*keyinfo->pack_key)(keyinfo,share->base.key_reflength,
|
length=(*keyinfo->pack_key)(keyinfo,share->base.key_reflength,
|
||||||
keypos == endpos ? (uchar*) 0 : keypos,
|
keypos == endpos ? (uchar*) 0 : keypos,
|
||||||
prev_key, prev_key,
|
prev_key, prev_key,
|
||||||
@ -491,11 +501,12 @@ static int del(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
|
|||||||
if (!(*keyinfo->get_key)(keyinfo,share->base.key_reflength,&keypos,ret_key))
|
if (!(*keyinfo->get_key)(keyinfo,share->base.key_reflength,&keypos,ret_key))
|
||||||
goto err;
|
goto err;
|
||||||
_ma_kpointer(info,keypos - share->base.key_reflength,next_block);
|
_ma_kpointer(info,keypos - share->base.key_reflength,next_block);
|
||||||
maria_putint(anc_buff,a_length+length,share->base.key_reflength);
|
_ma_store_page_used(info, anc_buff, a_length + length,
|
||||||
|
share->base.key_reflength);
|
||||||
|
|
||||||
DBUG_RETURN( maria_data_on_page(leaf_buff) <=
|
DBUG_RETURN(_ma_get_page_used(info, leaf_buff) <=
|
||||||
(info->quick_mode ? MARIA_MIN_KEYBLOCK_LENGTH :
|
(info->quick_mode ? MARIA_MIN_KEYBLOCK_LENGTH :
|
||||||
(uint) keyinfo->underflow_block_length));
|
(uint) keyinfo->underflow_block_length));
|
||||||
err:
|
err:
|
||||||
DBUG_RETURN(-1);
|
DBUG_RETURN(-1);
|
||||||
} /* del */
|
} /* del */
|
||||||
@ -521,22 +532,22 @@ static int underflow(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
|
|||||||
DBUG_ENTER("underflow");
|
DBUG_ENTER("underflow");
|
||||||
DBUG_PRINT("enter",("leaf_page: %ld keypos: 0x%lx",(long) leaf_page,
|
DBUG_PRINT("enter",("leaf_page: %ld keypos: 0x%lx",(long) leaf_page,
|
||||||
(ulong) keypos));
|
(ulong) keypos));
|
||||||
DBUG_DUMP("anc_buff",anc_buff,maria_data_on_page(anc_buff));
|
DBUG_DUMP("anc_buff", anc_buff, _ma_get_page_used(info, anc_buff));
|
||||||
DBUG_DUMP("leaf_buff",leaf_buff,maria_data_on_page(leaf_buff));
|
DBUG_DUMP("leaf_buff", leaf_buff, _ma_get_page_used(info, leaf_buff));
|
||||||
|
|
||||||
buff=info->buff;
|
buff=info->buff;
|
||||||
info->keyread_buff_used=1;
|
info->keyread_buff_used=1;
|
||||||
next_keypos=keypos;
|
next_keypos=keypos;
|
||||||
nod_flag=_ma_test_if_nod(leaf_buff);
|
nod_flag= _ma_test_if_nod(info, leaf_buff);
|
||||||
p_length=nod_flag+2;
|
p_length= nod_flag+info->s->keypage_header;
|
||||||
anc_length= maria_data_on_page(anc_buff);
|
anc_length= _ma_get_page_used(info, anc_buff);
|
||||||
leaf_length= maria_data_on_page(leaf_buff);
|
leaf_length= _ma_get_page_used(info, leaf_buff);
|
||||||
key_reflength=share->base.key_reflength;
|
key_reflength=share->base.key_reflength;
|
||||||
if (info->s->keyinfo+info->lastinx == keyinfo)
|
if (info->s->keyinfo+info->lastinx == keyinfo)
|
||||||
info->page_changed=1;
|
info->page_changed=1;
|
||||||
|
|
||||||
if ((keypos < anc_buff+anc_length && (info->state->records & 1)) ||
|
if ((keypos < anc_buff + anc_length && (info->state->records & 1)) ||
|
||||||
keypos == anc_buff+2+key_reflength)
|
keypos == anc_buff + info->s->keypage_header + key_reflength)
|
||||||
{ /* Use page right of anc-page */
|
{ /* Use page right of anc-page */
|
||||||
DBUG_PRINT("test",("use right page"));
|
DBUG_PRINT("test",("use right page"));
|
||||||
|
|
||||||
@ -557,14 +568,15 @@ static int underflow(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
|
|||||||
next_page= _ma_kpos(key_reflength,next_keypos);
|
next_page= _ma_kpos(key_reflength,next_keypos);
|
||||||
if (!_ma_fetch_keypage(info,keyinfo,next_page,DFLT_INIT_HITS,buff,0))
|
if (!_ma_fetch_keypage(info,keyinfo,next_page,DFLT_INIT_HITS,buff,0))
|
||||||
goto err;
|
goto err;
|
||||||
buff_length= maria_data_on_page(buff);
|
buff_length= _ma_get_page_used(info, buff);
|
||||||
DBUG_DUMP("next",buff,buff_length);
|
DBUG_DUMP("next",buff,buff_length);
|
||||||
|
|
||||||
/* find keys to make a big key-page */
|
/* find keys to make a big key-page */
|
||||||
bmove(next_keypos-key_reflength, buff+2, key_reflength);
|
bmove(next_keypos-key_reflength, buff + info->s->keypage_header,
|
||||||
if (!_ma_get_last_key(info,keyinfo,anc_buff,anc_key,next_keypos,&length)
|
key_reflength);
|
||||||
|| !_ma_get_last_key(info,keyinfo,leaf_buff,leaf_key,
|
if (!_ma_get_last_key(info,keyinfo,anc_buff,anc_key,next_keypos,&length) ||
|
||||||
leaf_buff+leaf_length,&length))
|
!_ma_get_last_key(info,keyinfo,leaf_buff,leaf_key,
|
||||||
|
leaf_buff+leaf_length,&length))
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
/* merge pages and put parting key from anc_buff between */
|
/* merge pages and put parting key from anc_buff between */
|
||||||
@ -579,7 +591,7 @@ static int underflow(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
|
|||||||
memcpy(buff, leaf_buff,(size_t) leaf_length);
|
memcpy(buff, leaf_buff,(size_t) leaf_length);
|
||||||
(*keyinfo->store_key)(keyinfo,buff+leaf_length,&s_temp);
|
(*keyinfo->store_key)(keyinfo,buff+leaf_length,&s_temp);
|
||||||
buff_length=(uint) (endpos-buff);
|
buff_length=(uint) (endpos-buff);
|
||||||
maria_putint(buff,buff_length,nod_flag);
|
_ma_store_page_used(info, buff, buff_length, nod_flag);
|
||||||
|
|
||||||
/* remove key from anc_buff */
|
/* remove key from anc_buff */
|
||||||
|
|
||||||
@ -588,9 +600,9 @@ static int underflow(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
|
|||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
anc_length-=s_length;
|
anc_length-=s_length;
|
||||||
maria_putint(anc_buff,anc_length,key_reflength);
|
_ma_store_page_used(info, anc_buff, anc_length, key_reflength);
|
||||||
|
|
||||||
if (buff_length <= keyinfo->block_length)
|
if (buff_length <= (uint) (keyinfo->block_length - KEYPAGE_CHECKSUM_SIZE))
|
||||||
{ /* Keys in one page */
|
{ /* Keys in one page */
|
||||||
memcpy(leaf_buff,buff,(size_t) buff_length);
|
memcpy(leaf_buff,buff,(size_t) buff_length);
|
||||||
if (_ma_dispose(info,keyinfo,next_page,DFLT_INIT_HITS))
|
if (_ma_dispose(info,keyinfo,next_page,DFLT_INIT_HITS))
|
||||||
@ -601,21 +613,22 @@ static int underflow(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
|
|||||||
endpos=anc_buff+anc_length;
|
endpos=anc_buff+anc_length;
|
||||||
DBUG_PRINT("test",("anc_buff: 0x%lx endpos: 0x%lx",
|
DBUG_PRINT("test",("anc_buff: 0x%lx endpos: 0x%lx",
|
||||||
(long) anc_buff, (long) endpos));
|
(long) anc_buff, (long) endpos));
|
||||||
if (keypos != anc_buff+2+key_reflength &&
|
if (keypos != anc_buff + info->s->keypage_header + key_reflength &&
|
||||||
!_ma_get_last_key(info,keyinfo,anc_buff,anc_key,keypos,&length))
|
!_ma_get_last_key(info,keyinfo,anc_buff,anc_key,keypos,&length))
|
||||||
goto err;
|
goto err;
|
||||||
if (!(half_pos= _ma_find_half_pos(nod_flag, keyinfo, buff, leaf_key,
|
if (!(half_pos= _ma_find_half_pos(info, nod_flag, keyinfo, buff,
|
||||||
&key_length, &after_key)))
|
leaf_key, &key_length, &after_key)))
|
||||||
goto err;
|
goto err;
|
||||||
length=(uint) (half_pos-buff);
|
length=(uint) (half_pos-buff);
|
||||||
memcpy(leaf_buff,buff,(size_t) length);
|
memcpy(leaf_buff,buff,(size_t) length);
|
||||||
maria_putint(leaf_buff,length,nod_flag);
|
_ma_store_page_used(info, leaf_buff, length, nod_flag);
|
||||||
|
|
||||||
/* Correct new keypointer to leaf_page */
|
/* Correct new keypointer to leaf_page */
|
||||||
half_pos=after_key;
|
half_pos=after_key;
|
||||||
_ma_kpointer(info,leaf_key+key_length,next_page);
|
_ma_kpointer(info,leaf_key+key_length,next_page);
|
||||||
/* Save key in anc_buff */
|
/* Save key in anc_buff */
|
||||||
prev_key=(keypos == anc_buff+2+key_reflength ? (uchar*) 0 : anc_key),
|
prev_key=(keypos == anc_buff + info->s->keypage_header + key_reflength ?
|
||||||
|
(uchar*) 0 : anc_key),
|
||||||
t_length=(*keyinfo->pack_key)(keyinfo,key_reflength,
|
t_length=(*keyinfo->pack_key)(keyinfo,key_reflength,
|
||||||
(keypos == endpos ? (uchar*) 0 :
|
(keypos == endpos ? (uchar*) 0 :
|
||||||
keypos),
|
keypos),
|
||||||
@ -626,21 +639,23 @@ static int underflow(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
|
|||||||
else
|
else
|
||||||
bmove(keypos,keypos-t_length,(uint) (endpos-keypos)+t_length);
|
bmove(keypos,keypos-t_length,(uint) (endpos-keypos)+t_length);
|
||||||
(*keyinfo->store_key)(keyinfo,keypos,&s_temp);
|
(*keyinfo->store_key)(keyinfo,keypos,&s_temp);
|
||||||
maria_putint(anc_buff,(anc_length+=t_length),key_reflength);
|
anc_length+= t_length;
|
||||||
|
_ma_store_page_used(info, anc_buff, anc_length, key_reflength);
|
||||||
|
|
||||||
/* Store key first in new page */
|
/* Store key first in new page */
|
||||||
if (nod_flag)
|
if (nod_flag)
|
||||||
bmove(buff+2,half_pos-nod_flag,(size_t) nod_flag);
|
bmove(buff+info->s->keypage_header, half_pos-nod_flag,
|
||||||
|
(size_t) nod_flag);
|
||||||
if (!(*keyinfo->get_key)(keyinfo,nod_flag,&half_pos,leaf_key))
|
if (!(*keyinfo->get_key)(keyinfo,nod_flag,&half_pos,leaf_key))
|
||||||
goto err;
|
goto err;
|
||||||
t_length=(int) (*keyinfo->pack_key)(keyinfo, nod_flag, (uchar*) 0,
|
t_length=(int) (*keyinfo->pack_key)(keyinfo, nod_flag, (uchar*) 0,
|
||||||
(uchar*) 0, (uchar*) 0,
|
(uchar*) 0, (uchar*) 0,
|
||||||
leaf_key, &s_temp);
|
leaf_key, &s_temp);
|
||||||
/* t_length will always be > 0 for a new page !*/
|
/* t_length will always be > 0 for a new page !*/
|
||||||
length=(uint) ((buff+maria_data_on_page(buff))-half_pos);
|
length=(uint) ((buff+_ma_get_page_used(info, buff))-half_pos);
|
||||||
bmove(buff+p_length+t_length, half_pos, (size_t) length);
|
bmove(buff+p_length+t_length, half_pos, (size_t) length);
|
||||||
(*keyinfo->store_key)(keyinfo,buff+p_length,&s_temp);
|
(*keyinfo->store_key)(keyinfo,buff+p_length,&s_temp);
|
||||||
maria_putint(buff,length+t_length+p_length,nod_flag);
|
_ma_store_page_used(info, buff, length + t_length + p_length, nod_flag);
|
||||||
|
|
||||||
if (_ma_write_keypage(info,keyinfo,next_page,DFLT_INIT_HITS,buff))
|
if (_ma_write_keypage(info,keyinfo,next_page,DFLT_INIT_HITS,buff))
|
||||||
goto err;
|
goto err;
|
||||||
@ -659,12 +674,13 @@ static int underflow(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
|
|||||||
next_page= _ma_kpos(key_reflength,keypos);
|
next_page= _ma_kpos(key_reflength,keypos);
|
||||||
if (!_ma_fetch_keypage(info,keyinfo,next_page,DFLT_INIT_HITS,buff,0))
|
if (!_ma_fetch_keypage(info,keyinfo,next_page,DFLT_INIT_HITS,buff,0))
|
||||||
goto err;
|
goto err;
|
||||||
buff_length= maria_data_on_page(buff);
|
buff_length= _ma_get_page_used(info, buff);
|
||||||
endpos=buff+buff_length;
|
endpos=buff+buff_length;
|
||||||
DBUG_DUMP("prev",buff,buff_length);
|
DBUG_DUMP("prev",buff,buff_length);
|
||||||
|
|
||||||
/* find keys to make a big key-page */
|
/* find keys to make a big key-page */
|
||||||
bmove(next_keypos - key_reflength, leaf_buff+2, key_reflength);
|
bmove(next_keypos - key_reflength, leaf_buff + info->s->keypage_header,
|
||||||
|
key_reflength);
|
||||||
next_keypos=keypos;
|
next_keypos=keypos;
|
||||||
if (!(*keyinfo->get_key)(keyinfo,key_reflength,&next_keypos,
|
if (!(*keyinfo->get_key)(keyinfo,key_reflength,&next_keypos,
|
||||||
anc_key))
|
anc_key))
|
||||||
@ -688,7 +704,7 @@ static int underflow(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
|
|||||||
|
|
||||||
(*keyinfo->store_key)(keyinfo,endpos,&s_temp);
|
(*keyinfo->store_key)(keyinfo,endpos,&s_temp);
|
||||||
buff_length=buff_length+leaf_length-p_length+t_length;
|
buff_length=buff_length+leaf_length-p_length+t_length;
|
||||||
maria_putint(buff,buff_length,nod_flag);
|
_ma_store_page_used(info, buff, buff_length, nod_flag);
|
||||||
|
|
||||||
/* remove key from anc_buff */
|
/* remove key from anc_buff */
|
||||||
if (!(s_length= remove_key(keyinfo,key_reflength,keypos,anc_key,
|
if (!(s_length= remove_key(keyinfo,key_reflength,keypos,anc_key,
|
||||||
@ -696,22 +712,22 @@ static int underflow(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
|
|||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
anc_length-=s_length;
|
anc_length-=s_length;
|
||||||
maria_putint(anc_buff,anc_length,key_reflength);
|
_ma_store_page_used(info, anc_buff, anc_length, key_reflength);
|
||||||
|
|
||||||
if (buff_length <= keyinfo->block_length)
|
if (buff_length <= (uint) (keyinfo->block_length - KEYPAGE_CHECKSUM_SIZE))
|
||||||
{ /* Keys in one page */
|
{ /* Keys in one page */
|
||||||
if (_ma_dispose(info,keyinfo,leaf_page,DFLT_INIT_HITS))
|
if (_ma_dispose(info,keyinfo,leaf_page,DFLT_INIT_HITS))
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{ /* Page is full */
|
{ /* Page is full */
|
||||||
if (keypos == anc_buff+2+key_reflength)
|
if (keypos == anc_buff+ info->s->keypage_header + key_reflength)
|
||||||
anc_pos=0; /* First key */
|
anc_pos=0; /* First key */
|
||||||
else if (!_ma_get_last_key(info,keyinfo,anc_buff,anc_pos=anc_key,keypos,
|
else if (!_ma_get_last_key(info,keyinfo,anc_buff,anc_pos=anc_key,keypos,
|
||||||
&length))
|
&length))
|
||||||
goto err;
|
goto err;
|
||||||
endpos= _ma_find_half_pos(nod_flag,keyinfo,buff,leaf_key,
|
endpos= _ma_find_half_pos(info, nod_flag, keyinfo, buff, leaf_key,
|
||||||
&key_length, &half_pos);
|
&key_length, &half_pos);
|
||||||
if (!endpos)
|
if (!endpos)
|
||||||
goto err;
|
goto err;
|
||||||
_ma_kpointer(info,leaf_key+key_length,leaf_page);
|
_ma_kpointer(info,leaf_key+key_length,leaf_page);
|
||||||
@ -730,11 +746,13 @@ static int underflow(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
|
|||||||
else
|
else
|
||||||
bmove(keypos,keypos-t_length,(uint) (temp_pos-keypos)+t_length);
|
bmove(keypos,keypos-t_length,(uint) (temp_pos-keypos)+t_length);
|
||||||
(*keyinfo->store_key)(keyinfo,keypos,&s_temp);
|
(*keyinfo->store_key)(keyinfo,keypos,&s_temp);
|
||||||
maria_putint(anc_buff,(anc_length+=t_length),key_reflength);
|
anc_length+= t_length;
|
||||||
|
_ma_store_page_used(info, anc_buff, anc_length, key_reflength);
|
||||||
|
|
||||||
/* Store first key on new page */
|
/* Store first key on new page */
|
||||||
if (nod_flag)
|
if (nod_flag)
|
||||||
bmove(leaf_buff+2,half_pos-nod_flag,(size_t) nod_flag);
|
bmove(leaf_buff + info->s->keypage_header, half_pos-nod_flag,
|
||||||
|
(size_t) nod_flag);
|
||||||
if (!(length=(*keyinfo->get_key)(keyinfo,nod_flag,&half_pos,leaf_key)))
|
if (!(length=(*keyinfo->get_key)(keyinfo,nod_flag,&half_pos,leaf_key)))
|
||||||
goto err;
|
goto err;
|
||||||
DBUG_DUMP("key_to_leaf",leaf_key,length);
|
DBUG_DUMP("key_to_leaf",leaf_key,length);
|
||||||
@ -745,14 +763,16 @@ static int underflow(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
|
|||||||
bmove(leaf_buff+p_length+t_length,half_pos,
|
bmove(leaf_buff+p_length+t_length,half_pos,
|
||||||
(size_t) length);
|
(size_t) length);
|
||||||
(*keyinfo->store_key)(keyinfo,leaf_buff+p_length,&s_temp);
|
(*keyinfo->store_key)(keyinfo,leaf_buff+p_length,&s_temp);
|
||||||
maria_putint(leaf_buff,length+t_length+p_length,nod_flag);
|
_ma_store_page_used(info, leaf_buff, length + t_length + p_length,
|
||||||
|
nod_flag);
|
||||||
if (_ma_write_keypage(info,keyinfo,leaf_page,DFLT_INIT_HITS,leaf_buff))
|
if (_ma_write_keypage(info,keyinfo,leaf_page,DFLT_INIT_HITS,leaf_buff))
|
||||||
goto err;
|
goto err;
|
||||||
maria_putint(buff,endpos-buff,nod_flag);
|
_ma_store_page_used(info, buff, (uint) (endpos - buff),nod_flag);
|
||||||
}
|
}
|
||||||
if (_ma_write_keypage(info,keyinfo,next_page,DFLT_INIT_HITS,buff))
|
if (_ma_write_keypage(info,keyinfo,next_page,DFLT_INIT_HITS,buff))
|
||||||
goto err;
|
goto err;
|
||||||
DBUG_RETURN(anc_length <= (uint) keyinfo->block_length/2);
|
DBUG_RETURN(anc_length <= (uint)
|
||||||
|
(keyinfo->block_length - KEYPAGE_CHECKSUM_SIZE)/2);
|
||||||
|
|
||||||
err:
|
err:
|
||||||
DBUG_RETURN(-1);
|
DBUG_RETURN(-1);
|
||||||
|
@ -327,9 +327,10 @@ uint _ma_ft_convert_to_ft2(MARIA_HA *info, uint keynr, uchar *key)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* creating pageful of keys */
|
/* creating pageful of keys */
|
||||||
maria_putint(info->buff,length+2,0);
|
_ma_store_keynr(info, info->buff, keynr);
|
||||||
memcpy(info->buff+2, key_ptr, length);
|
_ma_store_page_used(info, info->buff, length + info->s->keypage_header, 0);
|
||||||
info->keyread_buff_used=info->page_changed=1; /* info->buff is used */
|
memcpy(info->buff + info->s->keypage_header, key_ptr, length);
|
||||||
|
info->keyread_buff_used= info->page_changed=1; /* info->buff is used */
|
||||||
if ((root= _ma_new(info,keyinfo,DFLT_INIT_HITS)) == HA_OFFSET_ERROR ||
|
if ((root= _ma_new(info,keyinfo,DFLT_INIT_HITS)) == HA_OFFSET_ERROR ||
|
||||||
_ma_write_keypage(info,keyinfo,root,DFLT_INIT_HITS,info->buff))
|
_ma_write_keypage(info,keyinfo,root,DFLT_INIT_HITS,info->buff))
|
||||||
DBUG_RETURN(-1);
|
DBUG_RETURN(-1);
|
||||||
|
@ -46,7 +46,7 @@
|
|||||||
/* short transaction ID type */
|
/* short transaction ID type */
|
||||||
typedef uint16 SHORT_TRANSACTION_ID;
|
typedef uint16 SHORT_TRANSACTION_ID;
|
||||||
|
|
||||||
struct st_maria_info;
|
struct st_maria_handler;
|
||||||
|
|
||||||
/* Length of CRC at end of pages */
|
/* Length of CRC at end of pages */
|
||||||
#define CRC_LENGTH 4
|
#define CRC_LENGTH 4
|
||||||
@ -228,7 +228,7 @@ extern my_bool translog_init(const char *directory, uint32 log_file_max_size,
|
|||||||
extern my_bool
|
extern my_bool
|
||||||
translog_write_record(LSN *lsn, enum translog_record_type type,
|
translog_write_record(LSN *lsn, enum translog_record_type type,
|
||||||
struct st_transaction *trn,
|
struct st_transaction *trn,
|
||||||
struct st_maria_info *tbl_info,
|
MARIA_HA *tbl_info,
|
||||||
translog_size_t rec_len, uint part_no,
|
translog_size_t rec_len, uint part_no,
|
||||||
LEX_STRING *parts_data, uchar *store_share_id);
|
LEX_STRING *parts_data, uchar *store_share_id);
|
||||||
|
|
||||||
@ -263,7 +263,7 @@ extern my_bool translog_unlock();
|
|||||||
extern void translog_lock_assert_owner();
|
extern void translog_lock_assert_owner();
|
||||||
extern TRANSLOG_ADDRESS translog_get_horizon();
|
extern TRANSLOG_ADDRESS translog_get_horizon();
|
||||||
extern TRANSLOG_ADDRESS translog_get_horizon_no_lock();
|
extern TRANSLOG_ADDRESS translog_get_horizon_no_lock();
|
||||||
extern int translog_assign_id_to_share(struct st_maria_info *tbl_info,
|
extern int translog_assign_id_to_share(struct st_maria_handler *tbl_info,
|
||||||
struct st_transaction *trn);
|
struct st_transaction *trn);
|
||||||
extern void translog_deassign_id_from_share(struct st_maria_share *share);
|
extern void translog_deassign_id_from_share(struct st_maria_share *share);
|
||||||
extern void
|
extern void
|
||||||
@ -298,11 +298,13 @@ struct st_translog_parts
|
|||||||
};
|
};
|
||||||
|
|
||||||
typedef my_bool(*prewrite_rec_hook) (enum translog_record_type type,
|
typedef my_bool(*prewrite_rec_hook) (enum translog_record_type type,
|
||||||
TRN *trn, struct st_maria_info *tbl_info,
|
TRN *trn,
|
||||||
|
struct st_maria_handler *tbl_info,
|
||||||
struct st_translog_parts *parts);
|
struct st_translog_parts *parts);
|
||||||
|
|
||||||
typedef my_bool(*inwrite_rec_hook) (enum translog_record_type type,
|
typedef my_bool(*inwrite_rec_hook) (enum translog_record_type type,
|
||||||
TRN *trn, struct st_maria_info *tbl_info,
|
TRN *trn,
|
||||||
|
struct st_maria_handler *tbl_info,
|
||||||
LSN *lsn,
|
LSN *lsn,
|
||||||
struct st_translog_parts *parts);
|
struct st_translog_parts *parts);
|
||||||
|
|
||||||
|
@ -81,8 +81,8 @@ MARIA_HA *_ma_test_if_reopen(const char *filename)
|
|||||||
share Share of already open table
|
share Share of already open table
|
||||||
mode Mode of table (O_RDONLY | O_RDWR)
|
mode Mode of table (O_RDONLY | O_RDWR)
|
||||||
data_file Filedescriptor of data file to use < 0 if one should open
|
data_file Filedescriptor of data file to use < 0 if one should open
|
||||||
open it.
|
open it.
|
||||||
|
|
||||||
RETURN
|
RETURN
|
||||||
# Maria handler
|
# Maria handler
|
||||||
0 Error
|
0 Error
|
||||||
@ -252,7 +252,8 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags)
|
|||||||
char *disk_cache, *disk_pos, *end_pos;
|
char *disk_cache, *disk_pos, *end_pos;
|
||||||
MARIA_HA info,*m_info,*old_info;
|
MARIA_HA info,*m_info,*old_info;
|
||||||
MARIA_SHARE share_buff,*share;
|
MARIA_SHARE share_buff,*share;
|
||||||
ulong rec_per_key_part[HA_MAX_POSSIBLE_KEY*HA_MAX_KEY_SEG];
|
double rec_per_key_part[HA_MAX_POSSIBLE_KEY*HA_MAX_KEY_SEG];
|
||||||
|
long nulls_per_key_part[HA_MAX_POSSIBLE_KEY*HA_MAX_KEY_SEG];
|
||||||
my_off_t key_root[HA_MAX_POSSIBLE_KEY];
|
my_off_t key_root[HA_MAX_POSSIBLE_KEY];
|
||||||
ulonglong max_key_file_length, max_data_file_length;
|
ulonglong max_key_file_length, max_data_file_length;
|
||||||
File data_file= -1;
|
File data_file= -1;
|
||||||
@ -273,7 +274,8 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags)
|
|||||||
{
|
{
|
||||||
share= &share_buff;
|
share= &share_buff;
|
||||||
bzero((uchar*) &share_buff,sizeof(share_buff));
|
bzero((uchar*) &share_buff,sizeof(share_buff));
|
||||||
share_buff.state.rec_per_key_part=rec_per_key_part;
|
share_buff.state.rec_per_key_part= rec_per_key_part;
|
||||||
|
share_buff.state.nulls_per_key_part= nulls_per_key_part;
|
||||||
share_buff.state.key_root=key_root;
|
share_buff.state.key_root=key_root;
|
||||||
share_buff.pagecache= multi_pagecache_search(name_buff, strlen(name_buff),
|
share_buff.pagecache= multi_pagecache_search(name_buff, strlen(name_buff),
|
||||||
maria_pagecache);
|
maria_pagecache);
|
||||||
@ -314,10 +316,11 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags)
|
|||||||
HA_OPTION_COMPRESS_RECORD | HA_OPTION_READ_ONLY_DATA |
|
HA_OPTION_COMPRESS_RECORD | HA_OPTION_READ_ONLY_DATA |
|
||||||
HA_OPTION_TEMP_COMPRESS_RECORD | HA_OPTION_CHECKSUM |
|
HA_OPTION_TEMP_COMPRESS_RECORD | HA_OPTION_CHECKSUM |
|
||||||
HA_OPTION_TMP_TABLE | HA_OPTION_DELAY_KEY_WRITE |
|
HA_OPTION_TMP_TABLE | HA_OPTION_DELAY_KEY_WRITE |
|
||||||
HA_OPTION_RELIES_ON_SQL_LAYER | HA_OPTION_NULL_FIELDS))
|
HA_OPTION_RELIES_ON_SQL_LAYER | HA_OPTION_NULL_FIELDS |
|
||||||
|
HA_OPTION_PAGE_CHECKSUM))
|
||||||
{
|
{
|
||||||
DBUG_PRINT("error",("wrong options: 0x%lx", share->options));
|
DBUG_PRINT("error",("wrong options: 0x%lx", share->options));
|
||||||
my_errno=HA_ERR_OLD_FILE;
|
my_errno=HA_ERR_NEW_FILE;
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
if ((share->options & HA_OPTION_RELIES_ON_SQL_LAYER) &&
|
if ((share->options & HA_OPTION_RELIES_ON_SQL_LAYER) &&
|
||||||
@ -441,7 +444,10 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags)
|
|||||||
|
|
||||||
if (!my_multi_malloc(MY_WME,
|
if (!my_multi_malloc(MY_WME,
|
||||||
&share,sizeof(*share),
|
&share,sizeof(*share),
|
||||||
&share->state.rec_per_key_part,sizeof(long)*key_parts,
|
&share->state.rec_per_key_part,
|
||||||
|
sizeof(double) * key_parts,
|
||||||
|
&share->state.nulls_per_key_part,
|
||||||
|
sizeof(long)* key_parts,
|
||||||
&share->keyinfo,keys*sizeof(MARIA_KEYDEF),
|
&share->keyinfo,keys*sizeof(MARIA_KEYDEF),
|
||||||
&share->uniqueinfo,uniques*sizeof(MARIA_UNIQUEDEF),
|
&share->uniqueinfo,uniques*sizeof(MARIA_UNIQUEDEF),
|
||||||
&share->keyparts,
|
&share->keyparts,
|
||||||
@ -449,6 +455,7 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags)
|
|||||||
sizeof(HA_KEYSEG),
|
sizeof(HA_KEYSEG),
|
||||||
&share->columndef,
|
&share->columndef,
|
||||||
(share->base.fields+1)*sizeof(MARIA_COLUMNDEF),
|
(share->base.fields+1)*sizeof(MARIA_COLUMNDEF),
|
||||||
|
&share->column_nr, share->base.fields*sizeof(uint16),
|
||||||
&share->blobs,sizeof(MARIA_BLOB)*share->base.blobs,
|
&share->blobs,sizeof(MARIA_BLOB)*share->base.blobs,
|
||||||
&share->unique_file_name,strlen(name_buff)+1,
|
&share->unique_file_name,strlen(name_buff)+1,
|
||||||
&share->index_file_name,strlen(index_name)+1,
|
&share->index_file_name,strlen(index_name)+1,
|
||||||
@ -465,7 +472,9 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags)
|
|||||||
|
|
||||||
*share=share_buff;
|
*share=share_buff;
|
||||||
memcpy((char*) share->state.rec_per_key_part,
|
memcpy((char*) share->state.rec_per_key_part,
|
||||||
(char*) rec_per_key_part, sizeof(long)*key_parts);
|
(char*) rec_per_key_part, sizeof(double)*key_parts);
|
||||||
|
memcpy((char*) share->state.nulls_per_key_part,
|
||||||
|
(char*) nulls_per_key_part, sizeof(long)*key_parts);
|
||||||
memcpy((char*) share->state.key_root,
|
memcpy((char*) share->state.key_root,
|
||||||
(char*) key_root, sizeof(my_off_t)*keys);
|
(char*) key_root, sizeof(my_off_t)*keys);
|
||||||
strmov(share->unique_file_name, name_buff);
|
strmov(share->unique_file_name, name_buff);
|
||||||
@ -595,6 +604,10 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags)
|
|||||||
share->base.null_bytes +
|
share->base.null_bytes +
|
||||||
share->base.pack_bytes +
|
share->base.pack_bytes +
|
||||||
test(share->options & HA_OPTION_CHECKSUM));
|
test(share->options & HA_OPTION_CHECKSUM));
|
||||||
|
share->keypage_header= ((share->base.born_transactional ? LSN_STORE_SIZE :
|
||||||
|
0) + KEYPAGE_KEYID_SIZE + KEYPAGE_FLAG_SIZE +
|
||||||
|
KEYPAGE_USED_SIZE);
|
||||||
|
|
||||||
if (open_flags & HA_OPEN_COPY)
|
if (open_flags & HA_OPEN_COPY)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
@ -666,6 +679,8 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
share->columndef[i].type=(int) FIELD_LAST; /* End marker */
|
share->columndef[i].type=(int) FIELD_LAST; /* End marker */
|
||||||
|
disk_pos= _ma_column_nr_read(disk_pos, share->column_nr,
|
||||||
|
share->base.fields);
|
||||||
|
|
||||||
if ((share->data_file_type == BLOCK_RECORD ||
|
if ((share->data_file_type == BLOCK_RECORD ||
|
||||||
share->data_file_type == COMPRESSED_RECORD))
|
share->data_file_type == COMPRESSED_RECORD))
|
||||||
@ -693,7 +708,7 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags)
|
|||||||
if ((*share->once_init)(share, info.dfile.file))
|
if ((*share->once_init)(share, info.dfile.file))
|
||||||
goto err;
|
goto err;
|
||||||
share->is_log_table= FALSE;
|
share->is_log_table= FALSE;
|
||||||
if (open_flags & HA_OPEN_TMP_TABLE)
|
if (open_flags & HA_OPEN_TMP_TABLE)
|
||||||
share->options|= HA_OPTION_TMP_TABLE;
|
share->options|= HA_OPTION_TMP_TABLE;
|
||||||
if (open_flags & HA_OPEN_DELAY_KEY_WRITE)
|
if (open_flags & HA_OPEN_DELAY_KEY_WRITE)
|
||||||
share->options|= HA_OPTION_DELAY_KEY_WRITE;
|
share->options|= HA_OPTION_DELAY_KEY_WRITE;
|
||||||
@ -771,7 +786,7 @@ err:
|
|||||||
VOID(my_close(data_file, MYF(0)));
|
VOID(my_close(data_file, MYF(0)));
|
||||||
if (old_info)
|
if (old_info)
|
||||||
break; /* Don't remove open table */
|
break; /* Don't remove open table */
|
||||||
(*share->once_end)(share);
|
(*share->once_end)(share);
|
||||||
/* fall through */
|
/* fall through */
|
||||||
case 4:
|
case 4:
|
||||||
my_free((uchar*) share,MYF(0));
|
my_free((uchar*) share,MYF(0));
|
||||||
@ -914,7 +929,7 @@ void _ma_setup_functions(register MARIA_SHARE *share)
|
|||||||
share->file_read= _ma_nommap_pread;
|
share->file_read= _ma_nommap_pread;
|
||||||
share->file_write= _ma_nommap_pwrite;
|
share->file_write= _ma_nommap_pwrite;
|
||||||
share->calc_check_checksum= share->calc_checksum;
|
share->calc_check_checksum= share->calc_checksum;
|
||||||
|
|
||||||
if (!(share->options & HA_OPTION_CHECKSUM) &&
|
if (!(share->options & HA_OPTION_CHECKSUM) &&
|
||||||
share->data_file_type != COMPRESSED_RECORD)
|
share->data_file_type != COMPRESSED_RECORD)
|
||||||
share->calc_checksum= share->calc_write_checksum= 0;
|
share->calc_checksum= share->calc_write_checksum= 0;
|
||||||
@ -1095,10 +1110,13 @@ uint _ma_state_info_write_sub(File file, MARIA_STATE_INFO *state, uint pWrite)
|
|||||||
mi_int8store(ptr,(ulonglong) state->create_time); ptr+= 8;
|
mi_int8store(ptr,(ulonglong) state->create_time); ptr+= 8;
|
||||||
mi_int8store(ptr,(ulonglong) state->recover_time); ptr+= 8;
|
mi_int8store(ptr,(ulonglong) state->recover_time); ptr+= 8;
|
||||||
mi_int8store(ptr,(ulonglong) state->check_time); ptr+= 8;
|
mi_int8store(ptr,(ulonglong) state->check_time); ptr+= 8;
|
||||||
mi_sizestore(ptr,state->rec_per_key_rows); ptr+= 8;
|
mi_sizestore(ptr, state->records_at_analyze); ptr+= 8;
|
||||||
|
/* reserve place for some information per key */
|
||||||
|
bzero(ptr, keys*4); ptr+= keys*4;
|
||||||
for (i=0 ; i < key_parts ; i++)
|
for (i=0 ; i < key_parts ; i++)
|
||||||
{
|
{
|
||||||
mi_int4store(ptr,state->rec_per_key_part[i]); ptr+=4;
|
float8store(ptr, state->rec_per_key_part[i]); ptr+= 8;
|
||||||
|
mi_int4store(ptr, state->nulls_per_key_part[i]); ptr+= 4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1135,7 +1153,9 @@ static uchar *_ma_state_info_read(uchar *ptr, MARIA_STATE_INFO *state)
|
|||||||
state->state.key_empty= mi_sizekorr(ptr); ptr+= 8;
|
state->state.key_empty= mi_sizekorr(ptr); ptr+= 8;
|
||||||
state->auto_increment=mi_uint8korr(ptr); ptr+= 8;
|
state->auto_increment=mi_uint8korr(ptr); ptr+= 8;
|
||||||
state->state.checksum=(ha_checksum) mi_uint8korr(ptr);ptr+= 8;
|
state->state.checksum=(ha_checksum) mi_uint8korr(ptr);ptr+= 8;
|
||||||
|
/* Not used (legacy from MyISAM) */
|
||||||
state->process= mi_uint4korr(ptr); ptr+= 4;
|
state->process= mi_uint4korr(ptr); ptr+= 4;
|
||||||
|
/* Not used (legacy from MyISAM) */
|
||||||
state->unique = mi_uint4korr(ptr); ptr+= 4;
|
state->unique = mi_uint4korr(ptr); ptr+= 4;
|
||||||
state->status = mi_uint4korr(ptr); ptr+= 4;
|
state->status = mi_uint4korr(ptr); ptr+= 4;
|
||||||
state->update_count=mi_uint4korr(ptr); ptr+= 4;
|
state->update_count=mi_uint4korr(ptr); ptr+= 4;
|
||||||
@ -1154,10 +1174,12 @@ static uchar *_ma_state_info_read(uchar *ptr, MARIA_STATE_INFO *state)
|
|||||||
state->create_time = (time_t) mi_sizekorr(ptr); ptr+= 8;
|
state->create_time = (time_t) mi_sizekorr(ptr); ptr+= 8;
|
||||||
state->recover_time =(time_t) mi_sizekorr(ptr); ptr+= 8;
|
state->recover_time =(time_t) mi_sizekorr(ptr); ptr+= 8;
|
||||||
state->check_time = (time_t) mi_sizekorr(ptr); ptr+= 8;
|
state->check_time = (time_t) mi_sizekorr(ptr); ptr+= 8;
|
||||||
state->rec_per_key_rows=mi_sizekorr(ptr); ptr+= 8;
|
state->records_at_analyze= mi_sizekorr(ptr); ptr+= 8;
|
||||||
|
ptr+= keys * 4; /* Skip reserved bytes */
|
||||||
for (i=0 ; i < key_parts ; i++)
|
for (i=0 ; i < key_parts ; i++)
|
||||||
{
|
{
|
||||||
state->rec_per_key_part[i]= mi_uint4korr(ptr); ptr+=4;
|
float8get(state->rec_per_key_part[i], ptr); ptr+= 8;
|
||||||
|
state->nulls_per_key_part[i]= mi_uint4korr(ptr); ptr+= 4;
|
||||||
}
|
}
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
@ -1199,6 +1221,8 @@ uint _ma_base_info_write(File file, MARIA_BASE_INFO *base)
|
|||||||
{
|
{
|
||||||
uchar buff[MARIA_BASE_INFO_SIZE], *ptr=buff;
|
uchar buff[MARIA_BASE_INFO_SIZE], *ptr=buff;
|
||||||
|
|
||||||
|
bmove(ptr, maria_uuid, MY_UUID_SIZE);
|
||||||
|
ptr+= MY_UUID_SIZE;
|
||||||
mi_sizestore(ptr,base->keystart); ptr+= 8;
|
mi_sizestore(ptr,base->keystart); ptr+= 8;
|
||||||
mi_sizestore(ptr,base->max_data_file_length); ptr+= 8;
|
mi_sizestore(ptr,base->max_data_file_length); ptr+= 8;
|
||||||
mi_sizestore(ptr,base->max_key_file_length); ptr+= 8;
|
mi_sizestore(ptr,base->max_key_file_length); ptr+= 8;
|
||||||
@ -1215,7 +1239,7 @@ uint _ma_base_info_write(File file, MARIA_BASE_INFO *base)
|
|||||||
mi_int2store(ptr,base->fixed_not_null_fields_length); ptr+= 2;
|
mi_int2store(ptr,base->fixed_not_null_fields_length); ptr+= 2;
|
||||||
mi_int2store(ptr,base->max_field_lengths); ptr+= 2;
|
mi_int2store(ptr,base->max_field_lengths); ptr+= 2;
|
||||||
mi_int2store(ptr,base->pack_fields); ptr+= 2;
|
mi_int2store(ptr,base->pack_fields); ptr+= 2;
|
||||||
mi_int2store(ptr,0); ptr+= 2;
|
mi_int2store(ptr,base->extra_options) ptr+= 2;
|
||||||
mi_int2store(ptr,base->null_bytes); ptr+= 2;
|
mi_int2store(ptr,base->null_bytes); ptr+= 2;
|
||||||
mi_int2store(ptr,base->original_null_bytes); ptr+= 2;
|
mi_int2store(ptr,base->original_null_bytes); ptr+= 2;
|
||||||
mi_int2store(ptr,base->field_offsets); ptr+= 2;
|
mi_int2store(ptr,base->field_offsets); ptr+= 2;
|
||||||
@ -1241,6 +1265,7 @@ uint _ma_base_info_write(File file, MARIA_BASE_INFO *base)
|
|||||||
|
|
||||||
static uchar *_ma_base_info_read(uchar *ptr, MARIA_BASE_INFO *base)
|
static uchar *_ma_base_info_read(uchar *ptr, MARIA_BASE_INFO *base)
|
||||||
{
|
{
|
||||||
|
bmove(base->uuid, ptr, MY_UUID_SIZE); ptr+= MY_UUID_SIZE;
|
||||||
base->keystart= mi_sizekorr(ptr); ptr+= 8;
|
base->keystart= mi_sizekorr(ptr); ptr+= 8;
|
||||||
base->max_data_file_length= mi_sizekorr(ptr); ptr+= 8;
|
base->max_data_file_length= mi_sizekorr(ptr); ptr+= 8;
|
||||||
base->max_key_file_length= mi_sizekorr(ptr); ptr+= 8;
|
base->max_key_file_length= mi_sizekorr(ptr); ptr+= 8;
|
||||||
@ -1257,7 +1282,7 @@ static uchar *_ma_base_info_read(uchar *ptr, MARIA_BASE_INFO *base)
|
|||||||
base->fixed_not_null_fields_length= mi_uint2korr(ptr);ptr+= 2;
|
base->fixed_not_null_fields_length= mi_uint2korr(ptr);ptr+= 2;
|
||||||
base->max_field_lengths= mi_uint2korr(ptr); ptr+= 2;
|
base->max_field_lengths= mi_uint2korr(ptr); ptr+= 2;
|
||||||
base->pack_fields= mi_uint2korr(ptr); ptr+= 2;
|
base->pack_fields= mi_uint2korr(ptr); ptr+= 2;
|
||||||
ptr+= 2;
|
base->extra_options= mi_uint2korr(ptr); ptr+= 2;
|
||||||
base->null_bytes= mi_uint2korr(ptr); ptr+= 2;
|
base->null_bytes= mi_uint2korr(ptr); ptr+= 2;
|
||||||
base->original_null_bytes= mi_uint2korr(ptr); ptr+= 2;
|
base->original_null_bytes= mi_uint2korr(ptr); ptr+= 2;
|
||||||
base->field_offsets= mi_uint2korr(ptr); ptr+= 2;
|
base->field_offsets= mi_uint2korr(ptr); ptr+= 2;
|
||||||
@ -1284,7 +1309,7 @@ static uchar *_ma_base_info_read(uchar *ptr, MARIA_BASE_INFO *base)
|
|||||||
maria_keydef
|
maria_keydef
|
||||||
---------------------------------------------------------------------------*/
|
---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
uint _ma_keydef_write(File file, MARIA_KEYDEF *keydef)
|
my_bool _ma_keydef_write(File file, MARIA_KEYDEF *keydef)
|
||||||
{
|
{
|
||||||
uchar buff[MARIA_KEYDEF_SIZE];
|
uchar buff[MARIA_KEYDEF_SIZE];
|
||||||
uchar *ptr=buff;
|
uchar *ptr=buff;
|
||||||
@ -1320,7 +1345,7 @@ char *_ma_keydef_read(char *ptr, MARIA_KEYDEF *keydef)
|
|||||||
** maria_keyseg
|
** maria_keyseg
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
int _ma_keyseg_write(File file, const HA_KEYSEG *keyseg)
|
my_bool _ma_keyseg_write(File file, const HA_KEYSEG *keyseg)
|
||||||
{
|
{
|
||||||
uchar buff[HA_KEYSEG_SIZE];
|
uchar buff[HA_KEYSEG_SIZE];
|
||||||
uchar *ptr=buff;
|
uchar *ptr=buff;
|
||||||
@ -1370,7 +1395,7 @@ char *_ma_keyseg_read(char *ptr, HA_KEYSEG *keyseg)
|
|||||||
maria_uniquedef
|
maria_uniquedef
|
||||||
---------------------------------------------------------------------------*/
|
---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
uint _ma_uniquedef_write(File file, MARIA_UNIQUEDEF *def)
|
my_bool _ma_uniquedef_write(File file, MARIA_UNIQUEDEF *def)
|
||||||
{
|
{
|
||||||
uchar buff[MARIA_UNIQUEDEF_SIZE];
|
uchar buff[MARIA_UNIQUEDEF_SIZE];
|
||||||
uchar *ptr=buff;
|
uchar *ptr=buff;
|
||||||
@ -1394,12 +1419,12 @@ char *_ma_uniquedef_read(char *ptr, MARIA_UNIQUEDEF *def)
|
|||||||
** MARIA_COLUMNDEF
|
** MARIA_COLUMNDEF
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
uint _ma_columndef_write(File file, MARIA_COLUMNDEF *columndef)
|
my_bool _ma_columndef_write(File file, MARIA_COLUMNDEF *columndef)
|
||||||
{
|
{
|
||||||
uchar buff[MARIA_COLUMNDEF_SIZE];
|
uchar buff[MARIA_COLUMNDEF_SIZE];
|
||||||
uchar *ptr=buff;
|
uchar *ptr=buff;
|
||||||
|
|
||||||
mi_int6store(ptr,columndef->offset); ptr+= 6;
|
mi_int2store(ptr,(ulong) columndef->offset); ptr+= 2;
|
||||||
mi_int2store(ptr,columndef->type); ptr+= 2;
|
mi_int2store(ptr,columndef->type); ptr+= 2;
|
||||||
mi_int2store(ptr,columndef->length); ptr+= 2;
|
mi_int2store(ptr,columndef->length); ptr+= 2;
|
||||||
mi_int2store(ptr,columndef->fill_length); ptr+= 2;
|
mi_int2store(ptr,columndef->fill_length); ptr+= 2;
|
||||||
@ -1407,12 +1432,13 @@ uint _ma_columndef_write(File file, MARIA_COLUMNDEF *columndef)
|
|||||||
mi_int2store(ptr,columndef->empty_pos); ptr+= 2;
|
mi_int2store(ptr,columndef->empty_pos); ptr+= 2;
|
||||||
(*ptr++)= columndef->null_bit;
|
(*ptr++)= columndef->null_bit;
|
||||||
(*ptr++)= columndef->empty_bit;
|
(*ptr++)= columndef->empty_bit;
|
||||||
|
ptr[0]= ptr[1]= ptr[2]= ptr[3]= 0; ptr+= 4; /* For future */
|
||||||
return my_write(file, buff, (size_t) (ptr-buff), MYF(MY_NABP)) != 0;
|
return my_write(file, buff, (size_t) (ptr-buff), MYF(MY_NABP)) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *_ma_columndef_read(char *ptr, MARIA_COLUMNDEF *columndef)
|
char *_ma_columndef_read(char *ptr, MARIA_COLUMNDEF *columndef)
|
||||||
{
|
{
|
||||||
columndef->offset= mi_uint6korr(ptr); ptr+= 6;
|
columndef->offset= mi_uint2korr(ptr); ptr+= 2;
|
||||||
columndef->type= mi_sint2korr(ptr); ptr+= 2;
|
columndef->type= mi_sint2korr(ptr); ptr+= 2;
|
||||||
columndef->length= mi_uint2korr(ptr); ptr+= 2;
|
columndef->length= mi_uint2korr(ptr); ptr+= 2;
|
||||||
columndef->fill_length= mi_uint2korr(ptr); ptr+= 2;
|
columndef->fill_length= mi_uint2korr(ptr); ptr+= 2;
|
||||||
@ -1420,9 +1446,36 @@ char *_ma_columndef_read(char *ptr, MARIA_COLUMNDEF *columndef)
|
|||||||
columndef->empty_pos= mi_uint2korr(ptr); ptr+= 2;
|
columndef->empty_pos= mi_uint2korr(ptr); ptr+= 2;
|
||||||
columndef->null_bit= (uint8) *ptr++;
|
columndef->null_bit= (uint8) *ptr++;
|
||||||
columndef->empty_bit= (uint8) *ptr++;
|
columndef->empty_bit= (uint8) *ptr++;
|
||||||
|
ptr+= 4;
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
my_bool _ma_column_nr_write(File file, uint16 *offsets, uint columns)
|
||||||
|
{
|
||||||
|
uchar *buff, *ptr, *end;
|
||||||
|
size_t size= columns*2;
|
||||||
|
my_bool res;
|
||||||
|
|
||||||
|
if (!(buff= (uchar*) my_alloca(size)))
|
||||||
|
return 1;
|
||||||
|
for (ptr= buff, end= ptr + size; ptr < end ; ptr+= 2, offsets++)
|
||||||
|
int2store(ptr, *offsets);
|
||||||
|
res= my_write(file, buff, size, MYF(MY_NABP)) != 0;
|
||||||
|
my_afree(buff);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uchar *_ma_column_nr_read(uchar *ptr, uint16 *offsets, uint columns)
|
||||||
|
{
|
||||||
|
uchar *end;
|
||||||
|
size_t size= columns*2;
|
||||||
|
for (end= ptr + size; ptr < end ; ptr+=2, offsets++)
|
||||||
|
*offsets= uint2korr(ptr);
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
Open data file
|
Open data file
|
||||||
We can't use dup() here as the data file descriptors need to have different
|
We can't use dup() here as the data file descriptors need to have different
|
||||||
|
@ -48,17 +48,21 @@ uchar *_ma_fetch_keypage(register MARIA_HA *info, MARIA_KEYDEF *keyinfo,
|
|||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
info->last_keypage=page;
|
info->last_keypage=page;
|
||||||
page_size= maria_data_on_page(tmp);
|
#ifdef EXTRA_DEBUG
|
||||||
if (page_size < 4 || page_size > keyinfo->block_length)
|
page_size= _ma_get_page_used(info, tmp);
|
||||||
|
if (page_size < 4 || page_size > keyinfo->block_length ||
|
||||||
|
_ma_get_keynr(info, tmp) > info->s->base.keys)
|
||||||
{
|
{
|
||||||
DBUG_PRINT("error",("page %lu had wrong page length: %u",
|
DBUG_PRINT("error",("page %lu had wrong page length: %u keynr: %u",
|
||||||
(ulong) page, page_size));
|
(ulong) page, page_size,
|
||||||
|
_ma_get_keynr(info, tmp)));
|
||||||
DBUG_DUMP("page", (char*) tmp, keyinfo->block_length);
|
DBUG_DUMP("page", (char*) tmp, keyinfo->block_length);
|
||||||
info->last_keypage = HA_OFFSET_ERROR;
|
info->last_keypage = HA_OFFSET_ERROR;
|
||||||
maria_print_error(info->s, HA_ERR_CRASHED);
|
maria_print_error(info->s, HA_ERR_CRASHED);
|
||||||
my_errno= HA_ERR_CRASHED;
|
my_errno= HA_ERR_CRASHED;
|
||||||
tmp= 0;
|
tmp= 0;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
DBUG_RETURN(tmp);
|
DBUG_RETURN(tmp);
|
||||||
} /* _ma_fetch_keypage */
|
} /* _ma_fetch_keypage */
|
||||||
|
|
||||||
@ -84,19 +88,27 @@ int _ma_write_keypage(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
|
|||||||
DBUG_RETURN((-1));
|
DBUG_RETURN((-1));
|
||||||
}
|
}
|
||||||
DBUG_PRINT("page",("write page at: %lu",(long) page));
|
DBUG_PRINT("page",("write page at: %lu",(long) page));
|
||||||
DBUG_DUMP("buff",(uchar*) buff,maria_data_on_page(buff));
|
DBUG_DUMP("buff", buff,_ma_get_page_used(info, buff));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Verify that keynr is correct */
|
||||||
|
DBUG_ASSERT(_ma_get_keynr(info, buff) ==
|
||||||
|
(uint) (keyinfo - info->s->keyinfo));
|
||||||
|
|
||||||
#ifdef HAVE_purify
|
#ifdef HAVE_purify
|
||||||
{
|
{
|
||||||
/* Clear unitialized part of page to avoid valgrind/purify warnings */
|
/* Clear unitialized part of page to avoid valgrind/purify warnings */
|
||||||
uint length= maria_data_on_page(buff);
|
uint length= _ma_get_page_used(info, buff);
|
||||||
bzero((uchar*) buff+length,keyinfo->block_length-length);
|
bzero(buff+length, keyinfo->block_length-length);
|
||||||
length=keyinfo->block_length;
|
length=keyinfo->block_length;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
DBUG_ASSERT(info->s->pagecache->block_size == keyinfo->block_length);
|
DBUG_ASSERT(info->s->pagecache->block_size == keyinfo->block_length);
|
||||||
|
if (!(info->s->options & HA_OPTION_PAGE_CHECKSUM))
|
||||||
|
bfill(buff + keyinfo->block_length - KEYPAGE_CHECKSUM_SIZE,
|
||||||
|
KEYPAGE_CHECKSUM_SIZE, (uchar) 255);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
TODO: replace PAGECACHE_PLAIN_PAGE with PAGECACHE_LSN_PAGE when
|
TODO: replace PAGECACHE_PLAIN_PAGE with PAGECACHE_LSN_PAGE when
|
||||||
LSN on the pages will be implemented
|
LSN on the pages will be implemented
|
||||||
@ -116,7 +128,7 @@ int _ma_dispose(register MARIA_HA *info, MARIA_KEYDEF *keyinfo, my_off_t pos,
|
|||||||
int level)
|
int level)
|
||||||
{
|
{
|
||||||
my_off_t old_link;
|
my_off_t old_link;
|
||||||
char buff[8];
|
char buff[MAX_KEYPAGE_HEADER_SIZE+8];
|
||||||
uint offset;
|
uint offset;
|
||||||
pgcache_page_no_t page_no;
|
pgcache_page_no_t page_no;
|
||||||
DBUG_ENTER("_ma_dispose");
|
DBUG_ENTER("_ma_dispose");
|
||||||
@ -126,7 +138,9 @@ int _ma_dispose(register MARIA_HA *info, MARIA_KEYDEF *keyinfo, my_off_t pos,
|
|||||||
info->s->state.key_del= pos;
|
info->s->state.key_del= pos;
|
||||||
page_no= pos / keyinfo->block_length;
|
page_no= pos / keyinfo->block_length;
|
||||||
offset= pos % keyinfo->block_length;
|
offset= pos % keyinfo->block_length;
|
||||||
mi_sizestore(buff,old_link);
|
bzero(buff, info->s->keypage_header);
|
||||||
|
_ma_store_keynr(info, buff, (uchar) MARIA_DELETE_KEY_NR);
|
||||||
|
mi_sizestore(buff + info->s->keypage_header, old_link);
|
||||||
info->s->state.changed|= STATE_NOT_SORTED_PAGES;
|
info->s->state.changed|= STATE_NOT_SORTED_PAGES;
|
||||||
|
|
||||||
DBUG_ASSERT(info->s->pagecache->block_size == keyinfo->block_length &&
|
DBUG_ASSERT(info->s->pagecache->block_size == keyinfo->block_length &&
|
||||||
@ -141,11 +155,11 @@ int _ma_dispose(register MARIA_HA *info, MARIA_KEYDEF *keyinfo, my_off_t pos,
|
|||||||
PAGECACHE_LOCK_LEFT_UNLOCKED,
|
PAGECACHE_LOCK_LEFT_UNLOCKED,
|
||||||
PAGECACHE_PIN_LEFT_UNPINNED,
|
PAGECACHE_PIN_LEFT_UNPINNED,
|
||||||
PAGECACHE_WRITE_DELAY, 0,
|
PAGECACHE_WRITE_DELAY, 0,
|
||||||
offset, sizeof(buff), 0, 0));
|
offset, info->s->keypage_header+8, 0, 0));
|
||||||
} /* _ma_dispose */
|
} /* _ma_dispose */
|
||||||
|
|
||||||
|
|
||||||
/* Make new page on disk */
|
/* Make new page on disk */
|
||||||
|
|
||||||
my_off_t _ma_new(register MARIA_HA *info, MARIA_KEYDEF *keyinfo, int level)
|
my_off_t _ma_new(register MARIA_HA *info, MARIA_KEYDEF *keyinfo, int level)
|
||||||
{
|
{
|
||||||
@ -166,6 +180,7 @@ my_off_t _ma_new(register MARIA_HA *info, MARIA_KEYDEF *keyinfo, int level)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
/* QQ: Remove this alloc (We don't have to copy the page) */
|
||||||
buff= alloca(info->s->block_size);
|
buff= alloca(info->s->block_size);
|
||||||
DBUG_ASSERT(info->s->pagecache->block_size == keyinfo->block_length &&
|
DBUG_ASSERT(info->s->pagecache->block_size == keyinfo->block_length &&
|
||||||
info->s->pagecache->block_size == info->s->block_size);
|
info->s->pagecache->block_size == info->s->block_size);
|
||||||
@ -180,7 +195,7 @@ my_off_t _ma_new(register MARIA_HA *info, MARIA_KEYDEF *keyinfo, int level)
|
|||||||
PAGECACHE_LOCK_LEFT_UNLOCKED, 0))
|
PAGECACHE_LOCK_LEFT_UNLOCKED, 0))
|
||||||
pos= HA_OFFSET_ERROR;
|
pos= HA_OFFSET_ERROR;
|
||||||
else
|
else
|
||||||
info->s->state.key_del= mi_sizekorr(buff);
|
info->s->state.key_del= mi_sizekorr(buff+info->s->keypage_header);
|
||||||
}
|
}
|
||||||
info->s->state.changed|= STATE_NOT_SORTED_PAGES;
|
info->s->state.changed|= STATE_NOT_SORTED_PAGES;
|
||||||
DBUG_PRINT("exit",("Pos: %ld",(long) pos));
|
DBUG_PRINT("exit",("Pos: %ld",(long) pos));
|
||||||
|
@ -40,12 +40,10 @@
|
|||||||
|
|
||||||
int maria_preload(MARIA_HA *info, ulonglong key_map, my_bool ignore_leaves)
|
int maria_preload(MARIA_HA *info, ulonglong key_map, my_bool ignore_leaves)
|
||||||
{
|
{
|
||||||
uint i;
|
|
||||||
ulong length, block_length= 0;
|
ulong length, block_length= 0;
|
||||||
uchar *buff= NULL;
|
uchar *buff= NULL;
|
||||||
MARIA_SHARE* share= info->s;
|
MARIA_SHARE* share= info->s;
|
||||||
uint keys= share->state.header.keys;
|
uint keys= share->state.header.keys;
|
||||||
MARIA_KEYDEF *keyinfo= share->keyinfo;
|
|
||||||
my_off_t key_file_length= share->state.state.key_file_length;
|
my_off_t key_file_length= share->state.state.key_file_length;
|
||||||
my_off_t pos= share->base.keystart;
|
my_off_t pos= share->base.keystart;
|
||||||
DBUG_ENTER("maria_preload");
|
DBUG_ENTER("maria_preload");
|
||||||
@ -53,20 +51,7 @@ int maria_preload(MARIA_HA *info, ulonglong key_map, my_bool ignore_leaves)
|
|||||||
if (!keys || !maria_is_any_key_active(key_map) || key_file_length == pos)
|
if (!keys || !maria_is_any_key_active(key_map) || key_file_length == pos)
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
|
|
||||||
block_length= keyinfo[0].block_length;
|
block_length= share->pagecache->block_size;
|
||||||
|
|
||||||
if (ignore_leaves)
|
|
||||||
{
|
|
||||||
/* Check whether all indexes use the same block size */
|
|
||||||
for (i= 1 ; i < keys ; i++)
|
|
||||||
{
|
|
||||||
if (keyinfo[i].block_length != block_length)
|
|
||||||
DBUG_RETURN(my_errno= HA_ERR_NON_UNIQUE_BLOCK_SIZE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
block_length= share->pagecache->block_size;
|
|
||||||
|
|
||||||
length= info->preload_buff_size/block_length * block_length;
|
length= info->preload_buff_size/block_length * block_length;
|
||||||
set_if_bigger(length, block_length);
|
set_if_bigger(length, block_length);
|
||||||
|
|
||||||
@ -78,6 +63,7 @@ int maria_preload(MARIA_HA *info, ulonglong key_map, my_bool ignore_leaves)
|
|||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
|
uchar *end;
|
||||||
/* Read the next block of index file into the preload buffer */
|
/* Read the next block of index file into the preload buffer */
|
||||||
if ((my_off_t) length > (key_file_length-pos))
|
if ((my_off_t) length > (key_file_length-pos))
|
||||||
length= (ulong) (key_file_length-pos);
|
length= (ulong) (key_file_length-pos);
|
||||||
@ -85,41 +71,25 @@ int maria_preload(MARIA_HA *info, ulonglong key_map, my_bool ignore_leaves)
|
|||||||
MYF(MY_FAE|MY_FNABP)))
|
MYF(MY_FAE|MY_FNABP)))
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
if (ignore_leaves)
|
for (end= buff + length ; buff < end ; buff+= block_length)
|
||||||
{
|
{
|
||||||
uchar *end= buff+length;
|
uint keynr= _ma_get_keynr(info, buff);
|
||||||
do
|
if ((ignore_leaves && !_ma_test_if_nod(info, buff)) ||
|
||||||
|
keynr == MARIA_DELETE_KEY_NR ||
|
||||||
|
!(key_map & ((ulonglong) 1 << keynr)))
|
||||||
{
|
{
|
||||||
if (_ma_test_if_nod(buff))
|
DBUG_ASSERT(share->pagecache->block_size == block_length);
|
||||||
{
|
if (pagecache_write(share->pagecache,
|
||||||
DBUG_ASSERT(share->pagecache->block_size == block_length);
|
&share->kfile, pos / block_length,
|
||||||
if (pagecache_write(share->pagecache,
|
DFLT_INIT_HITS,
|
||||||
&share->kfile, pos / block_length,
|
(uchar*) buff,
|
||||||
DFLT_INIT_HITS,
|
PAGECACHE_PLAIN_PAGE,
|
||||||
(uchar*) buff,
|
PAGECACHE_LOCK_LEFT_UNLOCKED,
|
||||||
PAGECACHE_PLAIN_PAGE,
|
PAGECACHE_PIN_LEFT_UNPINNED,
|
||||||
PAGECACHE_LOCK_LEFT_UNLOCKED,
|
PAGECACHE_WRITE_DONE, 0))
|
||||||
PAGECACHE_PIN_LEFT_UNPINNED,
|
goto err;
|
||||||
PAGECACHE_WRITE_DONE, 0))
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
pos+= block_length;
|
|
||||||
}
|
}
|
||||||
while ((buff+= block_length) != end);
|
pos+= block_length;
|
||||||
buff= end-length;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (pagecache_write(share->pagecache,
|
|
||||||
&share->kfile, pos / block_length,
|
|
||||||
DFLT_INIT_HITS,
|
|
||||||
(uchar*) buff,
|
|
||||||
PAGECACHE_PLAIN_PAGE,
|
|
||||||
PAGECACHE_LOCK_LEFT_UNLOCKED,
|
|
||||||
PAGECACHE_PIN_LEFT_UNPINNED,
|
|
||||||
PAGECACHE_WRITE_DONE, 0))
|
|
||||||
goto err;
|
|
||||||
pos+= length;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
while (pos != key_file_length);
|
while (pos != key_file_length);
|
||||||
|
@ -215,7 +215,7 @@ static double _ma_search_pos(register MARIA_HA *info,
|
|||||||
goto err;
|
goto err;
|
||||||
flag=(*keyinfo->bin_search)(info, keyinfo, buff, key, key_len, nextflag,
|
flag=(*keyinfo->bin_search)(info, keyinfo, buff, key, key_len, nextflag,
|
||||||
&keypos,info->lastkey, &after_key);
|
&keypos,info->lastkey, &after_key);
|
||||||
nod_flag=_ma_test_if_nod(buff);
|
nod_flag=_ma_test_if_nod(info, buff);
|
||||||
keynr= _ma_keynr(info,keyinfo,buff,keypos,&max_keynr);
|
keynr= _ma_keynr(info,keyinfo,buff,keypos,&max_keynr);
|
||||||
|
|
||||||
if (flag)
|
if (flag)
|
||||||
@ -262,17 +262,17 @@ err:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Get keynummer of current key and max number of keys in nod */
|
/* Get keynummer of current key and max number of keys in nod */
|
||||||
|
|
||||||
static uint _ma_keynr(MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
|
static uint _ma_keynr(MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
|
||||||
uchar *page, uchar *keypos, uint *ret_max_key)
|
uchar *page, uchar *keypos, uint *ret_max_key)
|
||||||
{
|
{
|
||||||
uint nod_flag,keynr,max_key;
|
uint nod_flag, used_length, keynr, max_key;
|
||||||
uchar t_buff[HA_MAX_KEY_BUFF],*end;
|
uchar t_buff[HA_MAX_KEY_BUFF],*end;
|
||||||
|
|
||||||
end= page+maria_data_on_page(page);
|
_ma_get_used_and_nod(info, page, used_length, nod_flag);
|
||||||
nod_flag=_ma_test_if_nod(page);
|
end= page+ used_length;
|
||||||
page+=2+nod_flag;
|
page+= info->s->keypage_header + nod_flag;
|
||||||
|
|
||||||
if (!(keyinfo->flag & (HA_VAR_LENGTH_KEY | HA_BINARY_PACK_KEY)))
|
if (!(keyinfo->flag & (HA_VAR_LENGTH_KEY | HA_BINARY_PACK_KEY)))
|
||||||
{
|
{
|
||||||
|
@ -60,48 +60,48 @@ static int maria_rtree_find_req(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
|
|||||||
int res;
|
int res;
|
||||||
uchar *page_buf, *k, *last;
|
uchar *page_buf, *k, *last;
|
||||||
int k_len;
|
int k_len;
|
||||||
uint *saved_key = (uint*) (info->maria_rtree_recursion_state) + level;
|
uint *saved_key= (uint*) (info->maria_rtree_recursion_state) + level;
|
||||||
|
|
||||||
if (!(page_buf = (uchar*) my_alloca((uint)keyinfo->block_length)))
|
if (!(page_buf= (uchar*) my_alloca((uint)keyinfo->block_length)))
|
||||||
{
|
{
|
||||||
my_errno = HA_ERR_OUT_OF_MEM;
|
my_errno= HA_ERR_OUT_OF_MEM;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (!_ma_fetch_keypage(info, keyinfo, page, DFLT_INIT_HITS, page_buf, 0))
|
if (!_ma_fetch_keypage(info, keyinfo, page, DFLT_INIT_HITS, page_buf, 0))
|
||||||
goto err1;
|
goto err1;
|
||||||
nod_flag = _ma_test_if_nod(page_buf);
|
nod_flag= _ma_test_if_nod(info, page_buf);
|
||||||
|
|
||||||
k_len = keyinfo->keylength - info->s->base.rec_reflength;
|
k_len= keyinfo->keylength - info->s->base.rec_reflength;
|
||||||
|
|
||||||
if(info->maria_rtree_recursion_depth >= level)
|
if (info->maria_rtree_recursion_depth >= level)
|
||||||
{
|
{
|
||||||
k= page_buf + *saved_key;
|
k= page_buf + *saved_key;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
k = rt_PAGE_FIRST_KEY(page_buf, nod_flag);
|
k= rt_PAGE_FIRST_KEY(info, page_buf, nod_flag);
|
||||||
}
|
}
|
||||||
last= rt_PAGE_END(page_buf);
|
last= rt_PAGE_END(info, page_buf);
|
||||||
|
|
||||||
for (; k < last; k = rt_PAGE_NEXT_KEY(k, k_len, nod_flag))
|
for (; k < last; k= rt_PAGE_NEXT_KEY(k, k_len, nod_flag))
|
||||||
{
|
{
|
||||||
if (nod_flag)
|
if (nod_flag)
|
||||||
{
|
{
|
||||||
/* this is an internal node in the tree */
|
/* this is an internal node in the tree */
|
||||||
if (!(res = maria_rtree_key_cmp(keyinfo->seg,
|
if (!(res= maria_rtree_key_cmp(keyinfo->seg,
|
||||||
info->first_mbr_key, k,
|
info->first_mbr_key, k,
|
||||||
info->last_rkey_length, nod_cmp_flag)))
|
info->last_rkey_length, nod_cmp_flag)))
|
||||||
{
|
{
|
||||||
switch ((res = maria_rtree_find_req(info, keyinfo, search_flag,
|
switch ((res= maria_rtree_find_req(info, keyinfo, search_flag,
|
||||||
nod_cmp_flag,
|
nod_cmp_flag,
|
||||||
_ma_kpos(nod_flag, k),
|
_ma_kpos(nod_flag, k),
|
||||||
level + 1)))
|
level + 1)))
|
||||||
{
|
{
|
||||||
case 0: /* found - exit from recursion */
|
case 0: /* found - exit from recursion */
|
||||||
*saved_key = k - page_buf;
|
*saved_key= k - page_buf;
|
||||||
goto ok;
|
goto ok;
|
||||||
case 1: /* not found - continue searching */
|
case 1: /* not found - continue searching */
|
||||||
info->maria_rtree_recursion_depth = level;
|
info->maria_rtree_recursion_depth= level;
|
||||||
break;
|
break;
|
||||||
default: /* error */
|
default: /* error */
|
||||||
case -1:
|
case -1:
|
||||||
@ -115,33 +115,33 @@ static int maria_rtree_find_req(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
|
|||||||
if (!maria_rtree_key_cmp(keyinfo->seg, info->first_mbr_key,
|
if (!maria_rtree_key_cmp(keyinfo->seg, info->first_mbr_key,
|
||||||
k, info->last_rkey_length, search_flag))
|
k, info->last_rkey_length, search_flag))
|
||||||
{
|
{
|
||||||
uchar *after_key = (uchar*) rt_PAGE_NEXT_KEY(k, k_len, nod_flag);
|
uchar *after_key= (uchar*) rt_PAGE_NEXT_KEY(k, k_len, nod_flag);
|
||||||
info->cur_row.lastpos = _ma_dpos(info, 0, after_key);
|
info->cur_row.lastpos= _ma_dpos(info, 0, after_key);
|
||||||
info->lastkey_length = k_len + info->s->base.rec_reflength;
|
info->lastkey_length= k_len + info->s->base.rec_reflength;
|
||||||
memcpy(info->lastkey, k, info->lastkey_length);
|
memcpy(info->lastkey, k, info->lastkey_length);
|
||||||
info->maria_rtree_recursion_depth = level;
|
info->maria_rtree_recursion_depth= level;
|
||||||
*saved_key = last - page_buf;
|
*saved_key= last - page_buf;
|
||||||
|
|
||||||
if (after_key < last)
|
if (after_key < last)
|
||||||
{
|
{
|
||||||
info->int_keypos = info->buff;
|
info->int_keypos= info->buff;
|
||||||
info->int_maxpos = info->buff + (last - after_key);
|
info->int_maxpos= info->buff + (last - after_key);
|
||||||
memcpy(info->buff, after_key, last - after_key);
|
memcpy(info->buff, after_key, last - after_key);
|
||||||
info->keyread_buff_used = 0;
|
info->keyread_buff_used= 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
info->keyread_buff_used = 1;
|
info->keyread_buff_used= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
res = 0;
|
res= 0;
|
||||||
goto ok;
|
goto ok;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
info->cur_row.lastpos = HA_OFFSET_ERROR;
|
info->cur_row.lastpos= HA_OFFSET_ERROR;
|
||||||
my_errno = HA_ERR_KEY_NOT_FOUND;
|
my_errno= HA_ERR_KEY_NOT_FOUND;
|
||||||
res = 1;
|
res= 1;
|
||||||
|
|
||||||
ok:
|
ok:
|
||||||
my_afree((uchar*)page_buf);
|
my_afree((uchar*)page_buf);
|
||||||
@ -149,7 +149,7 @@ ok:
|
|||||||
|
|
||||||
err1:
|
err1:
|
||||||
my_afree((uchar*)page_buf);
|
my_afree((uchar*)page_buf);
|
||||||
info->cur_row.lastpos = HA_OFFSET_ERROR;
|
info->cur_row.lastpos= HA_OFFSET_ERROR;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -176,9 +176,9 @@ int maria_rtree_find_first(MARIA_HA *info, uint keynr, uchar *key,
|
|||||||
{
|
{
|
||||||
my_off_t root;
|
my_off_t root;
|
||||||
uint nod_cmp_flag;
|
uint nod_cmp_flag;
|
||||||
MARIA_KEYDEF *keyinfo = info->s->keyinfo + keynr;
|
MARIA_KEYDEF *keyinfo= info->s->keyinfo + keynr;
|
||||||
|
|
||||||
if ((root = info->s->state.key_root[keynr]) == HA_OFFSET_ERROR)
|
if ((root= info->s->state.key_root[keynr]) == HA_OFFSET_ERROR)
|
||||||
{
|
{
|
||||||
my_errno= HA_ERR_END_OF_FILE;
|
my_errno= HA_ERR_END_OF_FILE;
|
||||||
return -1;
|
return -1;
|
||||||
@ -190,10 +190,10 @@ int maria_rtree_find_first(MARIA_HA *info, uint keynr, uchar *key,
|
|||||||
(minimum bounding rectangle)
|
(minimum bounding rectangle)
|
||||||
*/
|
*/
|
||||||
memcpy(info->first_mbr_key, key, keyinfo->keylength);
|
memcpy(info->first_mbr_key, key, keyinfo->keylength);
|
||||||
info->last_rkey_length = key_length;
|
info->last_rkey_length= key_length;
|
||||||
|
|
||||||
info->maria_rtree_recursion_depth = -1;
|
info->maria_rtree_recursion_depth= -1;
|
||||||
info->keyread_buff_used = 1;
|
info->keyread_buff_used= 1;
|
||||||
|
|
||||||
nod_cmp_flag= ((search_flag & (MBR_EQUAL | MBR_WITHIN)) ?
|
nod_cmp_flag= ((search_flag & (MBR_EQUAL | MBR_WITHIN)) ?
|
||||||
MBR_WITHIN : MBR_INTERSECT);
|
MBR_WITHIN : MBR_INTERSECT);
|
||||||
@ -221,7 +221,7 @@ int maria_rtree_find_next(MARIA_HA *info, uint keynr, uint search_flag)
|
|||||||
{
|
{
|
||||||
my_off_t root;
|
my_off_t root;
|
||||||
uint nod_cmp_flag;
|
uint nod_cmp_flag;
|
||||||
MARIA_KEYDEF *keyinfo = info->s->keyinfo + keynr;
|
MARIA_KEYDEF *keyinfo= info->s->keyinfo + keynr;
|
||||||
|
|
||||||
if (info->update & HA_STATE_DELETED)
|
if (info->update & HA_STATE_DELETED)
|
||||||
return maria_rtree_find_first(info, keynr, info->lastkey,
|
return maria_rtree_find_first(info, keynr, info->lastkey,
|
||||||
@ -252,13 +252,13 @@ int maria_rtree_find_next(MARIA_HA *info, uint keynr, uint search_flag)
|
|||||||
key+= keyinfo->keylength;
|
key+= keyinfo->keylength;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ((root = info->s->state.key_root[keynr]) == HA_OFFSET_ERROR)
|
if ((root= info->s->state.key_root[keynr]) == HA_OFFSET_ERROR)
|
||||||
{
|
{
|
||||||
my_errno= HA_ERR_END_OF_FILE;
|
my_errno= HA_ERR_END_OF_FILE;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
nod_cmp_flag = ((search_flag & (MBR_EQUAL | MBR_WITHIN)) ?
|
nod_cmp_flag= ((search_flag & (MBR_EQUAL | MBR_WITHIN)) ?
|
||||||
MBR_WITHIN : MBR_INTERSECT);
|
MBR_WITHIN : MBR_INTERSECT);
|
||||||
return maria_rtree_find_req(info, keyinfo, search_flag, nod_cmp_flag, root, 0);
|
return maria_rtree_find_req(info, keyinfo, search_flag, nod_cmp_flag, root, 0);
|
||||||
}
|
}
|
||||||
@ -276,8 +276,8 @@ int maria_rtree_find_next(MARIA_HA *info, uint keynr, uint search_flag)
|
|||||||
1 Not found
|
1 Not found
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int maria_rtree_get_req(MARIA_HA *info, MARIA_KEYDEF *keyinfo, uint key_length,
|
static int maria_rtree_get_req(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
|
||||||
my_off_t page, int level)
|
uint key_length, my_off_t page, int level)
|
||||||
{
|
{
|
||||||
uchar *page_buf, *last, *k;
|
uchar *page_buf, *last, *k;
|
||||||
uint nod_flag, k_len;
|
uint nod_flag, k_len;
|
||||||
@ -288,39 +288,39 @@ static int maria_rtree_get_req(MARIA_HA *info, MARIA_KEYDEF *keyinfo, uint key_l
|
|||||||
return -1;
|
return -1;
|
||||||
if (!_ma_fetch_keypage(info, keyinfo, page, DFLT_INIT_HITS, page_buf, 0))
|
if (!_ma_fetch_keypage(info, keyinfo, page, DFLT_INIT_HITS, page_buf, 0))
|
||||||
goto err1;
|
goto err1;
|
||||||
nod_flag = _ma_test_if_nod(page_buf);
|
nod_flag= _ma_test_if_nod(info, page_buf);
|
||||||
|
|
||||||
k_len = keyinfo->keylength - info->s->base.rec_reflength;
|
k_len= keyinfo->keylength - info->s->base.rec_reflength;
|
||||||
|
|
||||||
if(info->maria_rtree_recursion_depth >= level)
|
if(info->maria_rtree_recursion_depth >= level)
|
||||||
{
|
{
|
||||||
k = page_buf + *saved_key;
|
k= page_buf + *saved_key;
|
||||||
if (!nod_flag)
|
if (!nod_flag)
|
||||||
{
|
{
|
||||||
/* Only leaf pages contain data references. */
|
/* Only leaf pages contain data references. */
|
||||||
/* Need to check next key with data reference. */
|
/* Need to check next key with data reference. */
|
||||||
k = rt_PAGE_NEXT_KEY(k, k_len, nod_flag);
|
k= rt_PAGE_NEXT_KEY(k, k_len, nod_flag);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
k = rt_PAGE_FIRST_KEY(page_buf, nod_flag);
|
k= rt_PAGE_FIRST_KEY(info, page_buf, nod_flag);
|
||||||
}
|
}
|
||||||
last = rt_PAGE_END(page_buf);
|
last= rt_PAGE_END(info, page_buf);
|
||||||
|
|
||||||
for (; k < last; k = rt_PAGE_NEXT_KEY(k, k_len, nod_flag))
|
for (; k < last; k= rt_PAGE_NEXT_KEY(k, k_len, nod_flag))
|
||||||
{
|
{
|
||||||
if (nod_flag)
|
if (nod_flag)
|
||||||
{
|
{
|
||||||
/* this is an internal node in the tree */
|
/* this is an internal node in the tree */
|
||||||
switch ((res = maria_rtree_get_req(info, keyinfo, key_length,
|
switch ((res= maria_rtree_get_req(info, keyinfo, key_length,
|
||||||
_ma_kpos(nod_flag, k), level + 1)))
|
_ma_kpos(nod_flag, k), level + 1)))
|
||||||
{
|
{
|
||||||
case 0: /* found - exit from recursion */
|
case 0: /* found - exit from recursion */
|
||||||
*saved_key = k - page_buf;
|
*saved_key= k - page_buf;
|
||||||
goto ok;
|
goto ok;
|
||||||
case 1: /* not found - continue searching */
|
case 1: /* not found - continue searching */
|
||||||
info->maria_rtree_recursion_depth = level;
|
info->maria_rtree_recursion_depth= level;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
case -1: /* error */
|
case -1: /* error */
|
||||||
@ -330,33 +330,33 @@ static int maria_rtree_get_req(MARIA_HA *info, MARIA_KEYDEF *keyinfo, uint key_l
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* this is a leaf */
|
/* this is a leaf */
|
||||||
uchar *after_key = rt_PAGE_NEXT_KEY(k, k_len, nod_flag);
|
uchar *after_key= rt_PAGE_NEXT_KEY(k, k_len, nod_flag);
|
||||||
info->cur_row.lastpos = _ma_dpos(info, 0, after_key);
|
info->cur_row.lastpos= _ma_dpos(info, 0, after_key);
|
||||||
info->lastkey_length = k_len + info->s->base.rec_reflength;
|
info->lastkey_length= k_len + info->s->base.rec_reflength;
|
||||||
memcpy(info->lastkey, k, info->lastkey_length);
|
memcpy(info->lastkey, k, info->lastkey_length);
|
||||||
|
|
||||||
info->maria_rtree_recursion_depth = level;
|
info->maria_rtree_recursion_depth= level;
|
||||||
*saved_key = k - page_buf;
|
*saved_key= k - page_buf;
|
||||||
|
|
||||||
if (after_key < last)
|
if (after_key < last)
|
||||||
{
|
{
|
||||||
info->int_keypos = (uchar*) saved_key;
|
info->int_keypos= (uchar*) saved_key;
|
||||||
memcpy(info->buff, page_buf, keyinfo->block_length);
|
memcpy(info->buff, page_buf, keyinfo->block_length);
|
||||||
info->int_maxpos = rt_PAGE_END(info->buff);
|
info->int_maxpos= rt_PAGE_END(info, info->buff);
|
||||||
info->keyread_buff_used = 0;
|
info->keyread_buff_used= 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
info->keyread_buff_used = 1;
|
info->keyread_buff_used= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
res = 0;
|
res= 0;
|
||||||
goto ok;
|
goto ok;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
info->cur_row.lastpos = HA_OFFSET_ERROR;
|
info->cur_row.lastpos= HA_OFFSET_ERROR;
|
||||||
my_errno = HA_ERR_KEY_NOT_FOUND;
|
my_errno= HA_ERR_KEY_NOT_FOUND;
|
||||||
res = 1;
|
res= 1;
|
||||||
|
|
||||||
ok:
|
ok:
|
||||||
my_afree((uchar*)page_buf);
|
my_afree((uchar*)page_buf);
|
||||||
@ -364,7 +364,7 @@ ok:
|
|||||||
|
|
||||||
err1:
|
err1:
|
||||||
my_afree((uchar*)page_buf);
|
my_afree((uchar*)page_buf);
|
||||||
info->cur_row.lastpos = HA_OFFSET_ERROR;
|
info->cur_row.lastpos= HA_OFFSET_ERROR;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -381,16 +381,16 @@ err1:
|
|||||||
int maria_rtree_get_first(MARIA_HA *info, uint keynr, uint key_length)
|
int maria_rtree_get_first(MARIA_HA *info, uint keynr, uint key_length)
|
||||||
{
|
{
|
||||||
my_off_t root;
|
my_off_t root;
|
||||||
MARIA_KEYDEF *keyinfo = info->s->keyinfo + keynr;
|
MARIA_KEYDEF *keyinfo= info->s->keyinfo + keynr;
|
||||||
|
|
||||||
if ((root = info->s->state.key_root[keynr]) == HA_OFFSET_ERROR)
|
if ((root= info->s->state.key_root[keynr]) == HA_OFFSET_ERROR)
|
||||||
{
|
{
|
||||||
my_errno= HA_ERR_END_OF_FILE;
|
my_errno= HA_ERR_END_OF_FILE;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
info->maria_rtree_recursion_depth = -1;
|
info->maria_rtree_recursion_depth= -1;
|
||||||
info->keyread_buff_used = 1;
|
info->keyread_buff_used= 1;
|
||||||
|
|
||||||
return maria_rtree_get_req(info, &keyinfo[keynr], key_length, root, 0);
|
return maria_rtree_get_req(info, &keyinfo[keynr], key_length, root, 0);
|
||||||
}
|
}
|
||||||
@ -408,32 +408,32 @@ int maria_rtree_get_first(MARIA_HA *info, uint keynr, uint key_length)
|
|||||||
int maria_rtree_get_next(MARIA_HA *info, uint keynr, uint key_length)
|
int maria_rtree_get_next(MARIA_HA *info, uint keynr, uint key_length)
|
||||||
{
|
{
|
||||||
my_off_t root;
|
my_off_t root;
|
||||||
MARIA_KEYDEF *keyinfo = info->s->keyinfo + keynr;
|
MARIA_KEYDEF *keyinfo= info->s->keyinfo + keynr;
|
||||||
|
|
||||||
if (!info->keyread_buff_used)
|
if (!info->keyread_buff_used)
|
||||||
{
|
{
|
||||||
uint k_len = keyinfo->keylength - info->s->base.rec_reflength;
|
uint k_len= keyinfo->keylength - info->s->base.rec_reflength;
|
||||||
/* rt_PAGE_NEXT_KEY(info->int_keypos) */
|
/* rt_PAGE_NEXT_KEY(info->int_keypos) */
|
||||||
uchar *key = info->buff + *(int*)info->int_keypos + k_len +
|
uchar *key= info->buff + *(int*)info->int_keypos + k_len +
|
||||||
info->s->base.rec_reflength;
|
info->s->base.rec_reflength;
|
||||||
/* rt_PAGE_NEXT_KEY(key) */
|
/* rt_PAGE_NEXT_KEY(key) */
|
||||||
uchar *after_key = key + k_len + info->s->base.rec_reflength;
|
uchar *after_key= key + k_len + info->s->base.rec_reflength;
|
||||||
|
|
||||||
info->cur_row.lastpos = _ma_dpos(info, 0, after_key);
|
info->cur_row.lastpos= _ma_dpos(info, 0, after_key);
|
||||||
info->lastkey_length = k_len + info->s->base.rec_reflength;
|
info->lastkey_length= k_len + info->s->base.rec_reflength;
|
||||||
memcpy(info->lastkey, key, k_len + info->s->base.rec_reflength);
|
memcpy(info->lastkey, key, k_len + info->s->base.rec_reflength);
|
||||||
|
|
||||||
*(int*)info->int_keypos = key - info->buff;
|
*(int*)info->int_keypos= key - info->buff;
|
||||||
if (after_key >= info->int_maxpos)
|
if (after_key >= info->int_maxpos)
|
||||||
{
|
{
|
||||||
info->keyread_buff_used = 1;
|
info->keyread_buff_used= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if ((root = info->s->state.key_root[keynr]) == HA_OFFSET_ERROR)
|
if ((root= info->s->state.key_root[keynr]) == HA_OFFSET_ERROR)
|
||||||
{
|
{
|
||||||
my_errno= HA_ERR_END_OF_FILE;
|
my_errno= HA_ERR_END_OF_FILE;
|
||||||
return -1;
|
return -1;
|
||||||
@ -455,27 +455,27 @@ static uchar *maria_rtree_pick_key(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
|
|||||||
uint nod_flag)
|
uint nod_flag)
|
||||||
{
|
{
|
||||||
double increase;
|
double increase;
|
||||||
double best_incr = DBL_MAX;
|
double best_incr= DBL_MAX;
|
||||||
double perimeter;
|
double perimeter;
|
||||||
double best_perimeter;
|
double best_perimeter;
|
||||||
uchar *best_key;
|
uchar *best_key;
|
||||||
uchar *k = rt_PAGE_FIRST_KEY(page_buf, nod_flag);
|
uchar *k= rt_PAGE_FIRST_KEY(page_buf, nod_flag);
|
||||||
uchar *last = rt_PAGE_END(page_buf);
|
uchar *last= rt_PAGE_END(info, page_buf);
|
||||||
|
|
||||||
LINT_INIT(best_perimeter);
|
LINT_INIT(best_perimeter);
|
||||||
LINT_INIT(best_key);
|
LINT_INIT(best_key);
|
||||||
|
|
||||||
for (; k < last; k = rt_PAGE_NEXT_KEY(k, key_length, nod_flag))
|
for (; k < last; k= rt_PAGE_NEXT_KEY(k, key_length, nod_flag))
|
||||||
{
|
{
|
||||||
if ((increase = maria_rtree_perimeter_increase(keyinfo->seg, k, key, key_length,
|
if ((increase= maria_rtree_perimeter_increase(keyinfo->seg, k, key, key_length,
|
||||||
&perimeter)) == -1)
|
&perimeter)) == -1)
|
||||||
return NULL;
|
return NULL;
|
||||||
if ((increase < best_incr)||
|
if ((increase < best_incr)||
|
||||||
(increase == best_incr && perimeter < best_perimeter))
|
(increase == best_incr && perimeter < best_perimeter))
|
||||||
{
|
{
|
||||||
best_key = k;
|
best_key= k;
|
||||||
best_perimeter= perimeter;
|
best_perimeter= perimeter;
|
||||||
best_incr = increase;
|
best_incr= increase;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return best_key;
|
return best_key;
|
||||||
@ -490,37 +490,37 @@ static uchar *maria_rtree_pick_key(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
|
|||||||
uint nod_flag)
|
uint nod_flag)
|
||||||
{
|
{
|
||||||
double increase;
|
double increase;
|
||||||
double best_incr = DBL_MAX;
|
double best_incr= DBL_MAX;
|
||||||
double area;
|
double area;
|
||||||
double best_area;
|
double best_area;
|
||||||
uchar *best_key;
|
uchar *best_key;
|
||||||
uchar *k = rt_PAGE_FIRST_KEY(page_buf, nod_flag);
|
uchar *k= rt_PAGE_FIRST_KEY(info, page_buf, nod_flag);
|
||||||
uchar *last = rt_PAGE_END(page_buf);
|
uchar *last= rt_PAGE_END(info, page_buf);
|
||||||
|
|
||||||
LINT_INIT(best_area);
|
LINT_INIT(best_area);
|
||||||
LINT_INIT(best_key);
|
LINT_INIT(best_key);
|
||||||
|
|
||||||
for (; k < last; k = rt_PAGE_NEXT_KEY(k, key_length, nod_flag))
|
for (; k < last; k= rt_PAGE_NEXT_KEY(k, key_length, nod_flag))
|
||||||
{
|
{
|
||||||
/* The following is safe as -1.0 is an exact number */
|
/* The following is safe as -1.0 is an exact number */
|
||||||
if ((increase = maria_rtree_area_increase(keyinfo->seg, k, key, key_length,
|
if ((increase= maria_rtree_area_increase(keyinfo->seg, k, key, key_length,
|
||||||
&area)) == -1.0)
|
&area)) == -1.0)
|
||||||
return NULL;
|
return NULL;
|
||||||
/* The following should be safe, even if we compare doubles */
|
/* The following should be safe, even if we compare doubles */
|
||||||
if (increase < best_incr)
|
if (increase < best_incr)
|
||||||
{
|
{
|
||||||
best_key = k;
|
best_key= k;
|
||||||
best_area = area;
|
best_area= area;
|
||||||
best_incr = increase;
|
best_incr= increase;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* The following should be safe, even if we compare doubles */
|
/* The following should be safe, even if we compare doubles */
|
||||||
if ((increase == best_incr) && (area < best_area))
|
if ((increase == best_incr) && (area < best_area))
|
||||||
{
|
{
|
||||||
best_key = k;
|
best_key= k;
|
||||||
best_area = area;
|
best_area= area;
|
||||||
best_incr = increase;
|
best_incr= increase;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -552,22 +552,22 @@ static int maria_rtree_insert_req(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
|
|||||||
if (!(page_buf= (uchar*) my_alloca((uint)keyinfo->block_length +
|
if (!(page_buf= (uchar*) my_alloca((uint)keyinfo->block_length +
|
||||||
HA_MAX_KEY_BUFF)))
|
HA_MAX_KEY_BUFF)))
|
||||||
{
|
{
|
||||||
my_errno = HA_ERR_OUT_OF_MEM;
|
my_errno= HA_ERR_OUT_OF_MEM;
|
||||||
DBUG_RETURN(-1); /* purecov: inspected */
|
DBUG_RETURN(-1); /* purecov: inspected */
|
||||||
}
|
}
|
||||||
if (!_ma_fetch_keypage(info, keyinfo, page, DFLT_INIT_HITS, page_buf, 0))
|
if (!_ma_fetch_keypage(info, keyinfo, page, DFLT_INIT_HITS, page_buf, 0))
|
||||||
goto err1;
|
goto err1;
|
||||||
nod_flag = _ma_test_if_nod(page_buf);
|
nod_flag= _ma_test_if_nod(info, page_buf);
|
||||||
DBUG_PRINT("rtree", ("page: %lu level: %d ins_level: %d nod_flag: %u",
|
DBUG_PRINT("rtree", ("page: %lu level: %d ins_level: %d nod_flag: %u",
|
||||||
(ulong) page, level, ins_level, nod_flag));
|
(ulong) page, level, ins_level, nod_flag));
|
||||||
|
|
||||||
if ((ins_level == -1 && nod_flag) || /* key: go down to leaf */
|
if ((ins_level == -1 && nod_flag) || /* key: go down to leaf */
|
||||||
(ins_level > -1 && ins_level > level)) /* branch: go down to ins_level */
|
(ins_level > -1 && ins_level > level)) /* branch: go down to ins_level */
|
||||||
{
|
{
|
||||||
if ((k = maria_rtree_pick_key(info, keyinfo, key, key_length, page_buf,
|
if ((k= maria_rtree_pick_key(info, keyinfo, key, key_length, page_buf,
|
||||||
nod_flag)) == NULL)
|
nod_flag)) == NULL)
|
||||||
goto err1;
|
goto err1;
|
||||||
switch ((res = maria_rtree_insert_req(info, keyinfo, key, key_length,
|
switch ((res= maria_rtree_insert_req(info, keyinfo, key, key_length,
|
||||||
_ma_kpos(nod_flag, k), new_page,
|
_ma_kpos(nod_flag, k), new_page,
|
||||||
ins_level, level + 1)))
|
ins_level, level + 1)))
|
||||||
{
|
{
|
||||||
@ -580,7 +580,7 @@ static int maria_rtree_insert_req(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
|
|||||||
}
|
}
|
||||||
case 1: /* child was split */
|
case 1: /* child was split */
|
||||||
{
|
{
|
||||||
uchar *new_key = page_buf + keyinfo->block_length + nod_flag;
|
uchar *new_key= page_buf + keyinfo->block_length + nod_flag;
|
||||||
/* set proper MBR for key */
|
/* set proper MBR for key */
|
||||||
if (maria_rtree_set_key_mbr(info, keyinfo, k, key_length,
|
if (maria_rtree_set_key_mbr(info, keyinfo, k, key_length,
|
||||||
_ma_kpos(nod_flag, k)))
|
_ma_kpos(nod_flag, k)))
|
||||||
@ -590,8 +590,8 @@ static int maria_rtree_insert_req(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
|
|||||||
if (maria_rtree_set_key_mbr(info, keyinfo, new_key, key_length,
|
if (maria_rtree_set_key_mbr(info, keyinfo, new_key, key_length,
|
||||||
*new_page))
|
*new_page))
|
||||||
goto err1;
|
goto err1;
|
||||||
res = maria_rtree_add_key(info, keyinfo, new_key, key_length,
|
res= maria_rtree_add_key(info, keyinfo, new_key, key_length,
|
||||||
page_buf, new_page);
|
page_buf, new_page);
|
||||||
if (_ma_write_keypage(info, keyinfo, page, DFLT_INIT_HITS, page_buf))
|
if (_ma_write_keypage(info, keyinfo, page, DFLT_INIT_HITS, page_buf))
|
||||||
goto err1;
|
goto err1;
|
||||||
goto ok;
|
goto ok;
|
||||||
@ -605,7 +605,7 @@ static int maria_rtree_insert_req(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
res = maria_rtree_add_key(info, keyinfo, key, key_length, page_buf,
|
res= maria_rtree_add_key(info, keyinfo, key, key_length, page_buf,
|
||||||
new_page);
|
new_page);
|
||||||
if (_ma_write_keypage(info, keyinfo, page, DFLT_INIT_HITS, page_buf))
|
if (_ma_write_keypage(info, keyinfo, page, DFLT_INIT_HITS, page_buf))
|
||||||
goto err1;
|
goto err1;
|
||||||
@ -634,26 +634,27 @@ static int maria_rtree_insert_level(MARIA_HA *info, uint keynr, uchar *key,
|
|||||||
uint key_length, int ins_level)
|
uint key_length, int ins_level)
|
||||||
{
|
{
|
||||||
my_off_t old_root;
|
my_off_t old_root;
|
||||||
MARIA_KEYDEF *keyinfo = info->s->keyinfo + keynr;
|
MARIA_KEYDEF *keyinfo= info->s->keyinfo + keynr;
|
||||||
int res;
|
int res;
|
||||||
my_off_t new_page;
|
my_off_t new_page;
|
||||||
DBUG_ENTER("maria_rtree_insert_level");
|
DBUG_ENTER("maria_rtree_insert_level");
|
||||||
|
|
||||||
if ((old_root = info->s->state.key_root[keynr]) == HA_OFFSET_ERROR)
|
if ((old_root= info->s->state.key_root[keynr]) == HA_OFFSET_ERROR)
|
||||||
{
|
{
|
||||||
if ((old_root = _ma_new(info, keyinfo, DFLT_INIT_HITS)) == HA_OFFSET_ERROR)
|
if ((old_root= _ma_new(info, keyinfo, DFLT_INIT_HITS)) == HA_OFFSET_ERROR)
|
||||||
DBUG_RETURN(-1);
|
DBUG_RETURN(-1);
|
||||||
info->keyread_buff_used = 1;
|
info->keyread_buff_used= 1;
|
||||||
maria_putint(info->buff, 2, 0);
|
_ma_store_page_used(info, info->buff, info->s->keypage_header, 0);
|
||||||
res = maria_rtree_add_key(info, keyinfo, key, key_length, info->buff, NULL);
|
res= maria_rtree_add_key(info, keyinfo, key, key_length, info->buff,
|
||||||
|
NULL);
|
||||||
if (_ma_write_keypage(info, keyinfo, old_root, DFLT_INIT_HITS, info->buff))
|
if (_ma_write_keypage(info, keyinfo, old_root, DFLT_INIT_HITS, info->buff))
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
info->s->state.key_root[keynr] = old_root;
|
info->s->state.key_root[keynr]= old_root;
|
||||||
DBUG_RETURN(res);
|
DBUG_RETURN(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch ((res = maria_rtree_insert_req(info, keyinfo, key, key_length,
|
switch ((res= maria_rtree_insert_req(info, keyinfo, key, key_length,
|
||||||
old_root, &new_page, ins_level, 0)))
|
old_root, &new_page, ins_level, 0)))
|
||||||
{
|
{
|
||||||
case 0: /* root was not split */
|
case 0: /* root was not split */
|
||||||
{
|
{
|
||||||
@ -663,22 +664,23 @@ static int maria_rtree_insert_level(MARIA_HA *info, uint keynr, uchar *key,
|
|||||||
{
|
{
|
||||||
uchar *new_root_buf, *new_key;
|
uchar *new_root_buf, *new_key;
|
||||||
my_off_t new_root;
|
my_off_t new_root;
|
||||||
uint nod_flag = info->s->base.key_reflength;
|
uint nod_flag= info->s->base.key_reflength;
|
||||||
|
|
||||||
DBUG_PRINT("rtree", ("root was split, grow a new root"));
|
DBUG_PRINT("rtree", ("root was split, grow a new root"));
|
||||||
if (!(new_root_buf= (uchar*) my_alloca((uint)keyinfo->block_length +
|
if (!(new_root_buf= (uchar*) my_alloca((uint)keyinfo->block_length +
|
||||||
HA_MAX_KEY_BUFF)))
|
HA_MAX_KEY_BUFF)))
|
||||||
{
|
{
|
||||||
my_errno = HA_ERR_OUT_OF_MEM;
|
my_errno= HA_ERR_OUT_OF_MEM;
|
||||||
DBUG_RETURN(-1); /* purecov: inspected */
|
DBUG_RETURN(-1); /* purecov: inspected */
|
||||||
}
|
}
|
||||||
|
|
||||||
maria_putint(new_root_buf, 2, nod_flag);
|
_ma_store_page_used(info, new_root_buf, info->s->keypage_header,
|
||||||
if ((new_root = _ma_new(info, keyinfo, DFLT_INIT_HITS)) ==
|
nod_flag);
|
||||||
|
if ((new_root= _ma_new(info, keyinfo, DFLT_INIT_HITS)) ==
|
||||||
HA_OFFSET_ERROR)
|
HA_OFFSET_ERROR)
|
||||||
goto err1;
|
goto err1;
|
||||||
|
|
||||||
new_key = new_root_buf + keyinfo->block_length + nod_flag;
|
new_key= new_root_buf + keyinfo->block_length + nod_flag;
|
||||||
|
|
||||||
_ma_kpointer(info, new_key - nod_flag, old_root);
|
_ma_kpointer(info, new_key - nod_flag, old_root);
|
||||||
if (maria_rtree_set_key_mbr(info, keyinfo, new_key, key_length,
|
if (maria_rtree_set_key_mbr(info, keyinfo, new_key, key_length,
|
||||||
@ -699,10 +701,10 @@ static int maria_rtree_insert_level(MARIA_HA *info, uint keynr, uchar *key,
|
|||||||
if (_ma_write_keypage(info, keyinfo, new_root,
|
if (_ma_write_keypage(info, keyinfo, new_root,
|
||||||
DFLT_INIT_HITS, new_root_buf))
|
DFLT_INIT_HITS, new_root_buf))
|
||||||
goto err1;
|
goto err1;
|
||||||
info->s->state.key_root[keynr] = new_root;
|
info->s->state.key_root[keynr]= new_root;
|
||||||
DBUG_PRINT("rtree", ("new root page: %lu level: %d nod_flag: %u",
|
DBUG_PRINT("rtree", ("new root page: %lu level: %d nod_flag: %u",
|
||||||
(ulong) new_root, 0,
|
(ulong) new_root, 0,
|
||||||
_ma_test_if_nod(new_root_buf)));
|
_ma_test_if_nod(info, new_root_buf)));
|
||||||
|
|
||||||
my_afree((uchar*)new_root_buf);
|
my_afree((uchar*)new_root_buf);
|
||||||
break;
|
break;
|
||||||
@ -753,13 +755,13 @@ static int maria_rtree_fill_reinsert_list(stPageList *ReinsertList, my_off_t pag
|
|||||||
if (ReinsertList->n_pages == ReinsertList->m_pages)
|
if (ReinsertList->n_pages == ReinsertList->m_pages)
|
||||||
{
|
{
|
||||||
ReinsertList->m_pages += REINSERT_BUFFER_INC;
|
ReinsertList->m_pages += REINSERT_BUFFER_INC;
|
||||||
if (!(ReinsertList->pages = (stPageLevel*)my_realloc((uchar*)ReinsertList->pages,
|
if (!(ReinsertList->pages= (stPageLevel*)my_realloc((uchar*)ReinsertList->pages,
|
||||||
ReinsertList->m_pages * sizeof(stPageLevel), MYF(MY_ALLOW_ZERO_PTR))))
|
ReinsertList->m_pages * sizeof(stPageLevel), MYF(MY_ALLOW_ZERO_PTR))))
|
||||||
goto err1;
|
goto err1;
|
||||||
}
|
}
|
||||||
/* save page to ReinsertList */
|
/* save page to ReinsertList */
|
||||||
ReinsertList->pages[ReinsertList->n_pages].offs = page;
|
ReinsertList->pages[ReinsertList->n_pages].offs= page;
|
||||||
ReinsertList->pages[ReinsertList->n_pages].level = level;
|
ReinsertList->pages[ReinsertList->n_pages].level= level;
|
||||||
ReinsertList->n_pages++;
|
ReinsertList->n_pages++;
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
|
|
||||||
@ -790,28 +792,28 @@ static int maria_rtree_delete_req(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
|
|||||||
uchar *page_buf, *last, *k;
|
uchar *page_buf, *last, *k;
|
||||||
DBUG_ENTER("maria_rtree_delete_req");
|
DBUG_ENTER("maria_rtree_delete_req");
|
||||||
|
|
||||||
if (!(page_buf = (uchar*) my_alloca((uint)keyinfo->block_length)))
|
if (!(page_buf= (uchar*) my_alloca((uint)keyinfo->block_length)))
|
||||||
{
|
{
|
||||||
my_errno = HA_ERR_OUT_OF_MEM;
|
my_errno= HA_ERR_OUT_OF_MEM;
|
||||||
DBUG_RETURN(-1); /* purecov: inspected */
|
DBUG_RETURN(-1); /* purecov: inspected */
|
||||||
}
|
}
|
||||||
if (!_ma_fetch_keypage(info, keyinfo, page, DFLT_INIT_HITS, page_buf, 0))
|
if (!_ma_fetch_keypage(info, keyinfo, page, DFLT_INIT_HITS, page_buf, 0))
|
||||||
goto err1;
|
goto err1;
|
||||||
nod_flag = _ma_test_if_nod(page_buf);
|
nod_flag= _ma_test_if_nod(info, page_buf);
|
||||||
DBUG_PRINT("rtree", ("page: %lu level: %d nod_flag: %u",
|
DBUG_PRINT("rtree", ("page: %lu level: %d nod_flag: %u",
|
||||||
(ulong) page, level, nod_flag));
|
(ulong) page, level, nod_flag));
|
||||||
|
|
||||||
k = rt_PAGE_FIRST_KEY(page_buf, nod_flag);
|
k= rt_PAGE_FIRST_KEY(info, page_buf, nod_flag);
|
||||||
last = rt_PAGE_END(page_buf);
|
last= rt_PAGE_END(info, page_buf);
|
||||||
|
|
||||||
for (i = 0; k < last; k = rt_PAGE_NEXT_KEY(k, key_length, nod_flag), i++)
|
for (i= 0; k < last; k= rt_PAGE_NEXT_KEY(k, key_length, nod_flag), i++)
|
||||||
{
|
{
|
||||||
if (nod_flag)
|
if (nod_flag)
|
||||||
{
|
{
|
||||||
/* not leaf */
|
/* not leaf */
|
||||||
if (!maria_rtree_key_cmp(keyinfo->seg, key, k, key_length, MBR_WITHIN))
|
if (!maria_rtree_key_cmp(keyinfo->seg, key, k, key_length, MBR_WITHIN))
|
||||||
{
|
{
|
||||||
switch ((res = maria_rtree_delete_req(info, keyinfo, key, key_length,
|
switch ((res= maria_rtree_delete_req(info, keyinfo, key, key_length,
|
||||||
_ma_kpos(nod_flag, k), page_size, ReinsertList, level + 1)))
|
_ma_kpos(nod_flag, k), page_size, ReinsertList, level + 1)))
|
||||||
{
|
{
|
||||||
case 0: /* deleted */
|
case 0: /* deleted */
|
||||||
@ -853,7 +855,7 @@ static int maria_rtree_delete_req(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
|
|||||||
if (_ma_write_keypage(info, keyinfo, page,
|
if (_ma_write_keypage(info, keyinfo, page,
|
||||||
DFLT_INIT_HITS, page_buf))
|
DFLT_INIT_HITS, page_buf))
|
||||||
goto err1;
|
goto err1;
|
||||||
*page_size = maria_data_on_page(page_buf);
|
*page_size= _ma_get_page_used(info, page_buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
goto ok;
|
goto ok;
|
||||||
@ -868,8 +870,8 @@ static int maria_rtree_delete_req(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
|
|||||||
if (_ma_write_keypage(info, keyinfo, page,
|
if (_ma_write_keypage(info, keyinfo, page,
|
||||||
DFLT_INIT_HITS, page_buf))
|
DFLT_INIT_HITS, page_buf))
|
||||||
goto err1;
|
goto err1;
|
||||||
*page_size = maria_data_on_page(page_buf);
|
*page_size= _ma_get_page_used(info, page_buf);
|
||||||
res = 0;
|
res= 0;
|
||||||
goto ok;
|
goto ok;
|
||||||
}
|
}
|
||||||
default: /* error */
|
default: /* error */
|
||||||
@ -883,20 +885,21 @@ static int maria_rtree_delete_req(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* leaf */
|
/* leaf */
|
||||||
if (!maria_rtree_key_cmp(keyinfo->seg, key, k, key_length, MBR_EQUAL | MBR_DATA))
|
if (!maria_rtree_key_cmp(keyinfo->seg, key, k, key_length,
|
||||||
|
MBR_EQUAL | MBR_DATA))
|
||||||
{
|
{
|
||||||
maria_rtree_delete_key(info, page_buf, k, key_length, nod_flag);
|
maria_rtree_delete_key(info, page_buf, k, key_length, nod_flag);
|
||||||
*page_size = maria_data_on_page(page_buf);
|
*page_size= _ma_get_page_used(info, page_buf);
|
||||||
if (*page_size == 2)
|
if (*page_size == info->s->keypage_header)
|
||||||
{
|
{
|
||||||
/* last key in the leaf */
|
/* last key in the leaf */
|
||||||
res = 2;
|
res= 2;
|
||||||
if (_ma_dispose(info, keyinfo, page, DFLT_INIT_HITS))
|
if (_ma_dispose(info, keyinfo, page, DFLT_INIT_HITS))
|
||||||
goto err1;
|
goto err1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
res = 0;
|
res= 0;
|
||||||
if (_ma_write_keypage(info, keyinfo, page, DFLT_INIT_HITS, page_buf))
|
if (_ma_write_keypage(info, keyinfo, page, DFLT_INIT_HITS, page_buf))
|
||||||
goto err1;
|
goto err1;
|
||||||
}
|
}
|
||||||
@ -904,7 +907,7 @@ static int maria_rtree_delete_req(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
res = 1;
|
res= 1;
|
||||||
|
|
||||||
ok:
|
ok:
|
||||||
my_afree((uchar*)page_buf);
|
my_afree((uchar*)page_buf);
|
||||||
@ -929,10 +932,10 @@ int maria_rtree_delete(MARIA_HA *info, uint keynr, uchar *key, uint key_length)
|
|||||||
uint page_size;
|
uint page_size;
|
||||||
stPageList ReinsertList;
|
stPageList ReinsertList;
|
||||||
my_off_t old_root;
|
my_off_t old_root;
|
||||||
MARIA_KEYDEF *keyinfo = info->s->keyinfo + keynr;
|
MARIA_KEYDEF *keyinfo= info->s->keyinfo + keynr;
|
||||||
DBUG_ENTER("maria_rtree_delete");
|
DBUG_ENTER("maria_rtree_delete");
|
||||||
|
|
||||||
if ((old_root = info->s->state.key_root[keynr]) == HA_OFFSET_ERROR)
|
if ((old_root= info->s->state.key_root[keynr]) == HA_OFFSET_ERROR)
|
||||||
{
|
{
|
||||||
my_errno= HA_ERR_END_OF_FILE;
|
my_errno= HA_ERR_END_OF_FILE;
|
||||||
DBUG_RETURN(-1); /* purecov: inspected */
|
DBUG_RETURN(-1); /* purecov: inspected */
|
||||||
@ -940,43 +943,43 @@ int maria_rtree_delete(MARIA_HA *info, uint keynr, uchar *key, uint key_length)
|
|||||||
DBUG_PRINT("rtree", ("starting deletion at root page: %lu",
|
DBUG_PRINT("rtree", ("starting deletion at root page: %lu",
|
||||||
(ulong) old_root));
|
(ulong) old_root));
|
||||||
|
|
||||||
ReinsertList.pages = NULL;
|
ReinsertList.pages= NULL;
|
||||||
ReinsertList.n_pages = 0;
|
ReinsertList.n_pages= 0;
|
||||||
ReinsertList.m_pages = 0;
|
ReinsertList.m_pages= 0;
|
||||||
|
|
||||||
switch (maria_rtree_delete_req(info, keyinfo, key, key_length, old_root,
|
switch (maria_rtree_delete_req(info, keyinfo, key, key_length, old_root,
|
||||||
&page_size, &ReinsertList, 0))
|
&page_size, &ReinsertList, 0))
|
||||||
{
|
{
|
||||||
case 2: /* empty */
|
case 2: /* empty */
|
||||||
{
|
{
|
||||||
info->s->state.key_root[keynr] = HA_OFFSET_ERROR;
|
info->s->state.key_root[keynr]= HA_OFFSET_ERROR;
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
case 0: /* deleted */
|
case 0: /* deleted */
|
||||||
{
|
{
|
||||||
uint nod_flag;
|
uint nod_flag;
|
||||||
ulong i;
|
ulong i;
|
||||||
for (i = 0; i < ReinsertList.n_pages; ++i)
|
for (i= 0; i < ReinsertList.n_pages; ++i)
|
||||||
{
|
{
|
||||||
uchar *page_buf, *k, *last;
|
uchar *page_buf, *k, *last;
|
||||||
|
|
||||||
if (!(page_buf = (uchar*) my_alloca((uint)keyinfo->block_length)))
|
if (!(page_buf= (uchar*) my_alloca((uint)keyinfo->block_length)))
|
||||||
{
|
{
|
||||||
my_errno = HA_ERR_OUT_OF_MEM;
|
my_errno= HA_ERR_OUT_OF_MEM;
|
||||||
goto err1;
|
goto err1;
|
||||||
}
|
}
|
||||||
if (!_ma_fetch_keypage(info, keyinfo, ReinsertList.pages[i].offs,
|
if (!_ma_fetch_keypage(info, keyinfo, ReinsertList.pages[i].offs,
|
||||||
DFLT_INIT_HITS, page_buf, 0))
|
DFLT_INIT_HITS, page_buf, 0))
|
||||||
goto err1;
|
goto err1;
|
||||||
nod_flag = _ma_test_if_nod(page_buf);
|
nod_flag= _ma_test_if_nod(info, page_buf);
|
||||||
DBUG_PRINT("rtree", ("reinserting keys from "
|
DBUG_PRINT("rtree", ("reinserting keys from "
|
||||||
"page: %lu level: %d nod_flag: %u",
|
"page: %lu level: %d nod_flag: %u",
|
||||||
(ulong) ReinsertList.pages[i].offs,
|
(ulong) ReinsertList.pages[i].offs,
|
||||||
ReinsertList.pages[i].level, nod_flag));
|
ReinsertList.pages[i].level, nod_flag));
|
||||||
|
|
||||||
k = rt_PAGE_FIRST_KEY(page_buf, nod_flag);
|
k= rt_PAGE_FIRST_KEY(info, page_buf, nod_flag);
|
||||||
last = rt_PAGE_END(page_buf);
|
last= rt_PAGE_END(info, page_buf);
|
||||||
for (; k < last; k = rt_PAGE_NEXT_KEY(k, key_length, nod_flag))
|
for (; k < last; k= rt_PAGE_NEXT_KEY(k, key_length, nod_flag))
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
if ((res=
|
if ((res=
|
||||||
@ -1008,20 +1011,22 @@ int maria_rtree_delete(MARIA_HA *info, uint keynr, uchar *key, uint key_length)
|
|||||||
my_free((uchar*) ReinsertList.pages, MYF(0));
|
my_free((uchar*) ReinsertList.pages, MYF(0));
|
||||||
|
|
||||||
/* check for redundant root (not leaf, 1 child) and eliminate */
|
/* check for redundant root (not leaf, 1 child) and eliminate */
|
||||||
if ((old_root = info->s->state.key_root[keynr]) == HA_OFFSET_ERROR)
|
if ((old_root= info->s->state.key_root[keynr]) == HA_OFFSET_ERROR)
|
||||||
goto err1;
|
goto err1;
|
||||||
if (!_ma_fetch_keypage(info, keyinfo, old_root, DFLT_INIT_HITS,
|
if (!_ma_fetch_keypage(info, keyinfo, old_root, DFLT_INIT_HITS,
|
||||||
info->buff, 0))
|
info->buff, 0))
|
||||||
goto err1;
|
goto err1;
|
||||||
nod_flag = _ma_test_if_nod(info->buff);
|
nod_flag= _ma_test_if_nod(info, info->buff);
|
||||||
page_size = maria_data_on_page(info->buff);
|
page_size= _ma_get_page_used(info, info->buff);
|
||||||
if (nod_flag && (page_size == 2 + key_length + nod_flag))
|
if (nod_flag && (page_size == info->s->keypage_header + key_length +
|
||||||
|
nod_flag))
|
||||||
{
|
{
|
||||||
my_off_t new_root = _ma_kpos(nod_flag,
|
my_off_t new_root= _ma_kpos(nod_flag,
|
||||||
rt_PAGE_FIRST_KEY(info->buff, nod_flag));
|
rt_PAGE_FIRST_KEY(info, info->buff,
|
||||||
|
nod_flag));
|
||||||
if (_ma_dispose(info, keyinfo, old_root, DFLT_INIT_HITS))
|
if (_ma_dispose(info, keyinfo, old_root, DFLT_INIT_HITS))
|
||||||
goto err1;
|
goto err1;
|
||||||
info->s->state.key_root[keynr] = new_root;
|
info->s->state.key_root[keynr]= new_root;
|
||||||
}
|
}
|
||||||
info->update= HA_STATE_DELETED;
|
info->update= HA_STATE_DELETED;
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
@ -1031,7 +1036,7 @@ err1:
|
|||||||
}
|
}
|
||||||
case 1: /* not found */
|
case 1: /* not found */
|
||||||
{
|
{
|
||||||
my_errno = HA_ERR_KEY_NOT_FOUND;
|
my_errno= HA_ERR_KEY_NOT_FOUND;
|
||||||
DBUG_RETURN(-1); /* purecov: inspected */
|
DBUG_RETURN(-1); /* purecov: inspected */
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@ -1051,35 +1056,35 @@ err1:
|
|||||||
ha_rows maria_rtree_estimate(MARIA_HA *info, uint keynr, uchar *key,
|
ha_rows maria_rtree_estimate(MARIA_HA *info, uint keynr, uchar *key,
|
||||||
uint key_length, uint flag)
|
uint key_length, uint flag)
|
||||||
{
|
{
|
||||||
MARIA_KEYDEF *keyinfo = info->s->keyinfo + keynr;
|
MARIA_KEYDEF *keyinfo= info->s->keyinfo + keynr;
|
||||||
my_off_t root;
|
my_off_t root;
|
||||||
uint i = 0;
|
uint i= 0;
|
||||||
uint nod_flag, k_len;
|
uint nod_flag, k_len;
|
||||||
uchar *page_buf, *k, *last;
|
uchar *page_buf, *k, *last;
|
||||||
double area = 0;
|
double area= 0;
|
||||||
ha_rows res = 0;
|
ha_rows res= 0;
|
||||||
|
|
||||||
if (flag & MBR_DISJOINT)
|
if (flag & MBR_DISJOINT)
|
||||||
return info->state->records;
|
return info->state->records;
|
||||||
|
|
||||||
if ((root = info->s->state.key_root[keynr]) == HA_OFFSET_ERROR)
|
if ((root= info->s->state.key_root[keynr]) == HA_OFFSET_ERROR)
|
||||||
return HA_POS_ERROR;
|
return HA_POS_ERROR;
|
||||||
if (!(page_buf= (uchar*) my_alloca((uint)keyinfo->block_length)))
|
if (!(page_buf= (uchar*) my_alloca((uint)keyinfo->block_length)))
|
||||||
return HA_POS_ERROR;
|
return HA_POS_ERROR;
|
||||||
if (!_ma_fetch_keypage(info, keyinfo, root, DFLT_INIT_HITS, page_buf, 0))
|
if (!_ma_fetch_keypage(info, keyinfo, root, DFLT_INIT_HITS, page_buf, 0))
|
||||||
goto err1;
|
goto err1;
|
||||||
nod_flag = _ma_test_if_nod(page_buf);
|
nod_flag= _ma_test_if_nod(info, page_buf);
|
||||||
|
|
||||||
k_len = keyinfo->keylength - info->s->base.rec_reflength;
|
k_len= keyinfo->keylength - info->s->base.rec_reflength;
|
||||||
|
|
||||||
k = rt_PAGE_FIRST_KEY(page_buf, nod_flag);
|
k= rt_PAGE_FIRST_KEY(info, page_buf, nod_flag);
|
||||||
last = rt_PAGE_END(page_buf);
|
last= rt_PAGE_END(info, page_buf);
|
||||||
|
|
||||||
for (; k < last; k = rt_PAGE_NEXT_KEY(k, k_len, nod_flag), i++)
|
for (; k < last; k= rt_PAGE_NEXT_KEY(k, k_len, nod_flag), i++)
|
||||||
{
|
{
|
||||||
if (nod_flag)
|
if (nod_flag)
|
||||||
{
|
{
|
||||||
double k_area = maria_rtree_rect_volume(keyinfo->seg, k, key_length);
|
double k_area= maria_rtree_rect_volume(keyinfo->seg, k, key_length);
|
||||||
|
|
||||||
/* The following should be safe, even if we compare doubles */
|
/* The following should be safe, even if we compare doubles */
|
||||||
if (k_area == 0)
|
if (k_area == 0)
|
||||||
@ -1124,9 +1129,9 @@ ha_rows maria_rtree_estimate(MARIA_HA *info, uint keynr, uchar *key,
|
|||||||
if (nod_flag)
|
if (nod_flag)
|
||||||
{
|
{
|
||||||
if (i)
|
if (i)
|
||||||
res = (ha_rows) (area / i * info->state->records);
|
res= (ha_rows) (area / i * info->state->records);
|
||||||
else
|
else
|
||||||
res = HA_POS_ERROR;
|
res= HA_POS_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
my_afree((uchar*)page_buf);
|
my_afree((uchar*)page_buf);
|
||||||
|
@ -19,12 +19,12 @@
|
|||||||
|
|
||||||
#ifdef HAVE_RTREE_KEYS
|
#ifdef HAVE_RTREE_KEYS
|
||||||
|
|
||||||
#define rt_PAGE_FIRST_KEY(page, nod_flag) (page + 2 + nod_flag)
|
#define rt_PAGE_FIRST_KEY(info, page, nod_flag) (page + info->s->keypage_header + nod_flag)
|
||||||
#define rt_PAGE_NEXT_KEY(key, key_length, nod_flag) (key + key_length + \
|
#define rt_PAGE_NEXT_KEY(key, key_length, nod_flag) (key + key_length + \
|
||||||
(nod_flag ? nod_flag : info->s->base.rec_reflength))
|
(nod_flag ? nod_flag : info->s->base.rec_reflength))
|
||||||
#define rt_PAGE_END(page) (page + maria_data_on_page(page))
|
#define rt_PAGE_END(info, page) (page + _ma_get_page_used(info, page))
|
||||||
|
|
||||||
#define rt_PAGE_MIN_SIZE(block_length) ((uint)(block_length) / 3)
|
#define rt_PAGE_MIN_SIZE(block_length) ((uint)(block_length - KEYPAGE_CHECKSUM_SIZE) / 3)
|
||||||
|
|
||||||
int maria_rtree_insert(MARIA_HA *info, uint keynr, uchar *key,
|
int maria_rtree_insert(MARIA_HA *info, uint keynr, uchar *key,
|
||||||
uint key_length);
|
uint key_length);
|
||||||
|
@ -32,8 +32,8 @@
|
|||||||
int maria_rtree_add_key(MARIA_HA *info, MARIA_KEYDEF *keyinfo, uchar *key,
|
int maria_rtree_add_key(MARIA_HA *info, MARIA_KEYDEF *keyinfo, uchar *key,
|
||||||
uint key_length, uchar *page_buf, my_off_t *new_page)
|
uint key_length, uchar *page_buf, my_off_t *new_page)
|
||||||
{
|
{
|
||||||
uint page_size = maria_data_on_page(page_buf);
|
uint page_size= _ma_get_page_used(info, page_buf);
|
||||||
uint nod_flag = _ma_test_if_nod(page_buf);
|
uint nod_flag= _ma_test_if_nod(info, page_buf);
|
||||||
DBUG_ENTER("maria_rtree_add_key");
|
DBUG_ENTER("maria_rtree_add_key");
|
||||||
|
|
||||||
if (page_size + key_length + info->s->base.rec_reflength <=
|
if (page_size + key_length + info->s->base.rec_reflength <=
|
||||||
@ -44,8 +44,9 @@ int maria_rtree_add_key(MARIA_HA *info, MARIA_KEYDEF *keyinfo, uchar *key,
|
|||||||
{
|
{
|
||||||
/* save key */
|
/* save key */
|
||||||
DBUG_ASSERT(_ma_kpos(nod_flag, key) < info->state->key_file_length);
|
DBUG_ASSERT(_ma_kpos(nod_flag, key) < info->state->key_file_length);
|
||||||
memcpy(rt_PAGE_END(page_buf), key - nod_flag, key_length + nod_flag);
|
memcpy(rt_PAGE_END(info, page_buf), key - nod_flag,
|
||||||
page_size += key_length + nod_flag;
|
key_length + nod_flag);
|
||||||
|
page_size+= key_length + nod_flag;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -54,11 +55,11 @@ int maria_rtree_add_key(MARIA_HA *info, MARIA_KEYDEF *keyinfo, uchar *key,
|
|||||||
info->s->base.rec_reflength) <
|
info->s->base.rec_reflength) <
|
||||||
info->state->data_file_length +
|
info->state->data_file_length +
|
||||||
info->s->base.pack_reclength);
|
info->s->base.pack_reclength);
|
||||||
memcpy(rt_PAGE_END(page_buf), key, key_length +
|
memcpy(rt_PAGE_END(info, page_buf), key, key_length +
|
||||||
info->s->base.rec_reflength);
|
info->s->base.rec_reflength);
|
||||||
page_size += key_length + info->s->base.rec_reflength;
|
page_size+= key_length + info->s->base.rec_reflength;
|
||||||
}
|
}
|
||||||
maria_putint(page_buf, page_size, nod_flag);
|
_ma_store_page_used(info, page_buf, page_size, nod_flag);
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -74,18 +75,18 @@ int maria_rtree_add_key(MARIA_HA *info, MARIA_KEYDEF *keyinfo, uchar *key,
|
|||||||
int maria_rtree_delete_key(MARIA_HA *info, uchar *page_buf, uchar *key,
|
int maria_rtree_delete_key(MARIA_HA *info, uchar *page_buf, uchar *key,
|
||||||
uint key_length, uint nod_flag)
|
uint key_length, uint nod_flag)
|
||||||
{
|
{
|
||||||
uint16 page_size = maria_data_on_page(page_buf);
|
uint16 page_size= _ma_get_page_used(info, page_buf);
|
||||||
uchar *key_start;
|
uchar *key_start;
|
||||||
|
|
||||||
key_start= key - nod_flag;
|
key_start= key - nod_flag;
|
||||||
if (!nod_flag)
|
if (!nod_flag)
|
||||||
key_length += info->s->base.rec_reflength;
|
key_length+= info->s->base.rec_reflength;
|
||||||
|
|
||||||
memmove(key_start, key + key_length, page_size - key_length -
|
memmove(key_start, key + key_length, page_size - key_length -
|
||||||
(key - page_buf));
|
(key - page_buf));
|
||||||
page_size-= key_length + nod_flag;
|
page_size-= key_length + nod_flag;
|
||||||
|
|
||||||
maria_putint(page_buf, page_size, nod_flag);
|
_ma_store_page_used(info, page_buf, page_size, nod_flag);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,10 +64,10 @@
|
|||||||
#define RT_CMP_KORR(type, korr_func, len, nextflag) \
|
#define RT_CMP_KORR(type, korr_func, len, nextflag) \
|
||||||
{ \
|
{ \
|
||||||
type amin, amax, bmin, bmax; \
|
type amin, amax, bmin, bmax; \
|
||||||
amin = korr_func(a); \
|
amin= korr_func(a); \
|
||||||
bmin = korr_func(b); \
|
bmin= korr_func(b); \
|
||||||
amax = korr_func(a+len); \
|
amax= korr_func(a+len); \
|
||||||
bmax = korr_func(b+len); \
|
bmax= korr_func(b+len); \
|
||||||
RT_CMP(nextflag); \
|
RT_CMP(nextflag); \
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -153,7 +153,7 @@ int maria_rtree_key_cmp(HA_KEYSEG *keyseg, uchar *b, uchar *a, uint key_length,
|
|||||||
end:
|
end:
|
||||||
if (nextflag & MBR_DATA)
|
if (nextflag & MBR_DATA)
|
||||||
{
|
{
|
||||||
uchar *end = a + keyseg->length;
|
uchar *end= a + keyseg->length;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
if (*a++ != *b++)
|
if (*a++ != *b++)
|
||||||
@ -166,8 +166,8 @@ end:
|
|||||||
#define RT_VOL_KORR(type, korr_func, len, cast) \
|
#define RT_VOL_KORR(type, korr_func, len, cast) \
|
||||||
{ \
|
{ \
|
||||||
type amin, amax; \
|
type amin, amax; \
|
||||||
amin = korr_func(a); \
|
amin= korr_func(a); \
|
||||||
amax = korr_func(a+len); \
|
amax= korr_func(a+len); \
|
||||||
res *= (cast(amax) - cast(amin)); \
|
res *= (cast(amax) - cast(amin)); \
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -184,7 +184,7 @@ end:
|
|||||||
*/
|
*/
|
||||||
double maria_rtree_rect_volume(HA_KEYSEG *keyseg, uchar *a, uint key_length)
|
double maria_rtree_rect_volume(HA_KEYSEG *keyseg, uchar *a, uint key_length)
|
||||||
{
|
{
|
||||||
double res = 1;
|
double res= 1;
|
||||||
for (; (int)key_length > 0; keyseg += 2)
|
for (; (int)key_length > 0; keyseg += 2)
|
||||||
{
|
{
|
||||||
uint32 keyseg_length;
|
uint32 keyseg_length;
|
||||||
@ -228,7 +228,7 @@ double maria_rtree_rect_volume(HA_KEYSEG *keyseg, uchar *a, uint key_length)
|
|||||||
RT_VOL_GET(double, mi_float8get, 8, (double));
|
RT_VOL_GET(double, mi_float8get, 8, (double));
|
||||||
break;
|
break;
|
||||||
case HA_KEYTYPE_END:
|
case HA_KEYTYPE_END:
|
||||||
key_length = 0;
|
key_length= 0;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return -1;
|
return -1;
|
||||||
@ -243,10 +243,10 @@ double maria_rtree_rect_volume(HA_KEYSEG *keyseg, uchar *a, uint key_length)
|
|||||||
#define RT_D_MBR_KORR(type, korr_func, len, cast) \
|
#define RT_D_MBR_KORR(type, korr_func, len, cast) \
|
||||||
{ \
|
{ \
|
||||||
type amin, amax; \
|
type amin, amax; \
|
||||||
amin = korr_func(a); \
|
amin= korr_func(a); \
|
||||||
amax = korr_func(a+len); \
|
amax= korr_func(a+len); \
|
||||||
*res++ = cast(amin); \
|
*res++= cast(amin); \
|
||||||
*res++ = cast(amax); \
|
*res++= cast(amax); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define RT_D_MBR_GET(type, get_func, len, cast) \
|
#define RT_D_MBR_GET(type, get_func, len, cast) \
|
||||||
@ -254,8 +254,8 @@ double maria_rtree_rect_volume(HA_KEYSEG *keyseg, uchar *a, uint key_length)
|
|||||||
type amin, amax; \
|
type amin, amax; \
|
||||||
get_func(amin, a); \
|
get_func(amin, a); \
|
||||||
get_func(amax, a+len); \
|
get_func(amax, a+len); \
|
||||||
*res++ = cast(amin); \
|
*res++= cast(amin); \
|
||||||
*res++ = cast(amax); \
|
*res++= cast(amax); \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -308,7 +308,7 @@ int maria_rtree_d_mbr(HA_KEYSEG *keyseg, uchar *a, uint key_length, double *res)
|
|||||||
RT_D_MBR_GET(double, mi_float8get, 8, (double));
|
RT_D_MBR_GET(double, mi_float8get, 8, (double));
|
||||||
break;
|
break;
|
||||||
case HA_KEYTYPE_END:
|
case HA_KEYTYPE_END:
|
||||||
key_length = 0;
|
key_length= 0;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return 1;
|
return 1;
|
||||||
@ -323,12 +323,12 @@ int maria_rtree_d_mbr(HA_KEYSEG *keyseg, uchar *a, uint key_length, double *res)
|
|||||||
#define RT_COMB_KORR(type, korr_func, store_func, len) \
|
#define RT_COMB_KORR(type, korr_func, store_func, len) \
|
||||||
{ \
|
{ \
|
||||||
type amin, amax, bmin, bmax; \
|
type amin, amax, bmin, bmax; \
|
||||||
amin = korr_func(a); \
|
amin= korr_func(a); \
|
||||||
bmin = korr_func(b); \
|
bmin= korr_func(b); \
|
||||||
amax = korr_func(a+len); \
|
amax= korr_func(a+len); \
|
||||||
bmax = korr_func(b+len); \
|
bmax= korr_func(b+len); \
|
||||||
amin = min(amin, bmin); \
|
amin= min(amin, bmin); \
|
||||||
amax = max(amax, bmax); \
|
amax= max(amax, bmax); \
|
||||||
store_func(c, amin); \
|
store_func(c, amin); \
|
||||||
store_func(c+len, amax); \
|
store_func(c+len, amax); \
|
||||||
}
|
}
|
||||||
@ -340,8 +340,8 @@ int maria_rtree_d_mbr(HA_KEYSEG *keyseg, uchar *a, uint key_length, double *res)
|
|||||||
get_func(bmin, b); \
|
get_func(bmin, b); \
|
||||||
get_func(amax, a+len); \
|
get_func(amax, a+len); \
|
||||||
get_func(bmax, b+len); \
|
get_func(bmax, b+len); \
|
||||||
amin = min(amin, bmin); \
|
amin= min(amin, bmin); \
|
||||||
amax = max(amax, bmax); \
|
amax= max(amax, bmax); \
|
||||||
store_func(c, amin); \
|
store_func(c, amin); \
|
||||||
store_func(c+len, amax); \
|
store_func(c+len, amax); \
|
||||||
}
|
}
|
||||||
@ -415,12 +415,12 @@ int maria_rtree_combine_rect(HA_KEYSEG *keyseg, uchar* a, uchar* b, uchar* c,
|
|||||||
#define RT_OVL_AREA_KORR(type, korr_func, len) \
|
#define RT_OVL_AREA_KORR(type, korr_func, len) \
|
||||||
{ \
|
{ \
|
||||||
type amin, amax, bmin, bmax; \
|
type amin, amax, bmin, bmax; \
|
||||||
amin = korr_func(a); \
|
amin= korr_func(a); \
|
||||||
bmin = korr_func(b); \
|
bmin= korr_func(b); \
|
||||||
amax = korr_func(a+len); \
|
amax= korr_func(a+len); \
|
||||||
bmax = korr_func(b+len); \
|
bmax= korr_func(b+len); \
|
||||||
amin = max(amin, bmin); \
|
amin= max(amin, bmin); \
|
||||||
amax = min(amax, bmax); \
|
amax= min(amax, bmax); \
|
||||||
if (amin >= amax) \
|
if (amin >= amax) \
|
||||||
return 0; \
|
return 0; \
|
||||||
res *= amax - amin; \
|
res *= amax - amin; \
|
||||||
@ -433,8 +433,8 @@ int maria_rtree_combine_rect(HA_KEYSEG *keyseg, uchar* a, uchar* b, uchar* c,
|
|||||||
get_func(bmin, b); \
|
get_func(bmin, b); \
|
||||||
get_func(amax, a+len); \
|
get_func(amax, a+len); \
|
||||||
get_func(bmax, b+len); \
|
get_func(bmax, b+len); \
|
||||||
amin = max(amin, bmin); \
|
amin= max(amin, bmin); \
|
||||||
amax = min(amax, bmax); \
|
amax= min(amax, bmax); \
|
||||||
if (amin >= amax) \
|
if (amin >= amax) \
|
||||||
return 0; \
|
return 0; \
|
||||||
res *= amax - amin; \
|
res *= amax - amin; \
|
||||||
@ -446,7 +446,7 @@ Calculates overlapping area of two MBRs a & b
|
|||||||
double maria_rtree_overlapping_area(HA_KEYSEG *keyseg, uchar* a, uchar* b,
|
double maria_rtree_overlapping_area(HA_KEYSEG *keyseg, uchar* a, uchar* b,
|
||||||
uint key_length)
|
uint key_length)
|
||||||
{
|
{
|
||||||
double res = 1;
|
double res= 1;
|
||||||
for (; (int) key_length > 0 ; keyseg += 2)
|
for (; (int) key_length > 0 ; keyseg += 2)
|
||||||
{
|
{
|
||||||
uint32 keyseg_length;
|
uint32 keyseg_length;
|
||||||
@ -505,10 +505,10 @@ double maria_rtree_overlapping_area(HA_KEYSEG *keyseg, uchar* a, uchar* b,
|
|||||||
#define RT_AREA_INC_KORR(type, korr_func, len) \
|
#define RT_AREA_INC_KORR(type, korr_func, len) \
|
||||||
{ \
|
{ \
|
||||||
type amin, amax, bmin, bmax; \
|
type amin, amax, bmin, bmax; \
|
||||||
amin = korr_func(a); \
|
amin= korr_func(a); \
|
||||||
bmin = korr_func(b); \
|
bmin= korr_func(b); \
|
||||||
amax = korr_func(a+len); \
|
amax= korr_func(a+len); \
|
||||||
bmax = korr_func(b+len); \
|
bmax= korr_func(b+len); \
|
||||||
a_area *= (((double)amax) - ((double)amin)); \
|
a_area *= (((double)amax) - ((double)amin)); \
|
||||||
loc_ab_area *= ((double)max(amax, bmax) - (double)min(amin, bmin)); \
|
loc_ab_area *= ((double)max(amax, bmax) - (double)min(amin, bmin)); \
|
||||||
}
|
}
|
||||||
@ -599,10 +599,10 @@ safe_end:
|
|||||||
#define RT_PERIM_INC_KORR(type, korr_func, len) \
|
#define RT_PERIM_INC_KORR(type, korr_func, len) \
|
||||||
{ \
|
{ \
|
||||||
type amin, amax, bmin, bmax; \
|
type amin, amax, bmin, bmax; \
|
||||||
amin = korr_func(a); \
|
amin= korr_func(a); \
|
||||||
bmin = korr_func(b); \
|
bmin= korr_func(b); \
|
||||||
amax = korr_func(a+len); \
|
amax= korr_func(a+len); \
|
||||||
bmax = korr_func(b+len); \
|
bmax= korr_func(b+len); \
|
||||||
a_perim+= (((double)amax) - ((double)amin)); \
|
a_perim+= (((double)amax) - ((double)amin)); \
|
||||||
*ab_perim+= ((double)max(amax, bmax) - (double)min(amin, bmin)); \
|
*ab_perim+= ((double)max(amax, bmax) - (double)min(amin, bmin)); \
|
||||||
}
|
}
|
||||||
@ -624,7 +624,7 @@ Calculates MBR_PERIMETER(a+b) - MBR_PERIMETER(a)
|
|||||||
double maria_rtree_perimeter_increase(HA_KEYSEG *keyseg, uchar* a, uchar* b,
|
double maria_rtree_perimeter_increase(HA_KEYSEG *keyseg, uchar* a, uchar* b,
|
||||||
uint key_length, double *ab_perim)
|
uint key_length, double *ab_perim)
|
||||||
{
|
{
|
||||||
double a_perim = 0.0;
|
double a_perim= 0.0;
|
||||||
|
|
||||||
*ab_perim= 0.0;
|
*ab_perim= 0.0;
|
||||||
for (; (int)key_length > 0; keyseg += 2)
|
for (; (int)key_length > 0; keyseg += 2)
|
||||||
@ -690,17 +690,17 @@ double maria_rtree_perimeter_increase(HA_KEYSEG *keyseg, uchar* a, uchar* b,
|
|||||||
#define RT_PAGE_MBR_KORR(type, korr_func, store_func, len) \
|
#define RT_PAGE_MBR_KORR(type, korr_func, store_func, len) \
|
||||||
{ \
|
{ \
|
||||||
type amin, amax, bmin, bmax; \
|
type amin, amax, bmin, bmax; \
|
||||||
amin = korr_func(k + inc); \
|
amin= korr_func(k + inc); \
|
||||||
amax = korr_func(k + inc + len); \
|
amax= korr_func(k + inc + len); \
|
||||||
k = rt_PAGE_NEXT_KEY(k, k_len, nod_flag); \
|
k= rt_PAGE_NEXT_KEY(k, k_len, nod_flag); \
|
||||||
for (; k < last; k = rt_PAGE_NEXT_KEY(k, k_len, nod_flag)) \
|
for (; k < last; k= rt_PAGE_NEXT_KEY(k, k_len, nod_flag)) \
|
||||||
{ \
|
{ \
|
||||||
bmin = korr_func(k + inc); \
|
bmin= korr_func(k + inc); \
|
||||||
bmax = korr_func(k + inc + len); \
|
bmax= korr_func(k + inc + len); \
|
||||||
if (amin > bmin) \
|
if (amin > bmin) \
|
||||||
amin = bmin; \
|
amin= bmin; \
|
||||||
if (amax < bmax) \
|
if (amax < bmax) \
|
||||||
amax = bmax; \
|
amax= bmax; \
|
||||||
} \
|
} \
|
||||||
store_func(c, amin); \
|
store_func(c, amin); \
|
||||||
c += len; \
|
c += len; \
|
||||||
@ -714,15 +714,15 @@ double maria_rtree_perimeter_increase(HA_KEYSEG *keyseg, uchar* a, uchar* b,
|
|||||||
type amin, amax, bmin, bmax; \
|
type amin, amax, bmin, bmax; \
|
||||||
get_func(amin, k + inc); \
|
get_func(amin, k + inc); \
|
||||||
get_func(amax, k + inc + len); \
|
get_func(amax, k + inc + len); \
|
||||||
k = rt_PAGE_NEXT_KEY(k, k_len, nod_flag); \
|
k= rt_PAGE_NEXT_KEY(k, k_len, nod_flag); \
|
||||||
for (; k < last; k = rt_PAGE_NEXT_KEY(k, k_len, nod_flag)) \
|
for (; k < last; k= rt_PAGE_NEXT_KEY(k, k_len, nod_flag)) \
|
||||||
{ \
|
{ \
|
||||||
get_func(bmin, k + inc); \
|
get_func(bmin, k + inc); \
|
||||||
get_func(bmax, k + inc + len); \
|
get_func(bmax, k + inc + len); \
|
||||||
if (amin > bmin) \
|
if (amin > bmin) \
|
||||||
amin = bmin; \
|
amin= bmin; \
|
||||||
if (amax < bmax) \
|
if (amax < bmax) \
|
||||||
amax = bmax; \
|
amax= bmax; \
|
||||||
} \
|
} \
|
||||||
store_func(c, amin); \
|
store_func(c, amin); \
|
||||||
c += len; \
|
c += len; \
|
||||||
@ -732,16 +732,16 @@ double maria_rtree_perimeter_increase(HA_KEYSEG *keyseg, uchar* a, uchar* b,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Calculates key page total MBR = MBR(key1) + MBR(key2) + ...
|
Calculates key page total MBR= MBR(key1) + MBR(key2) + ...
|
||||||
*/
|
*/
|
||||||
int maria_rtree_page_mbr(MARIA_HA *info, HA_KEYSEG *keyseg, uchar *page_buf,
|
int maria_rtree_page_mbr(MARIA_HA *info, HA_KEYSEG *keyseg, uchar *page_buf,
|
||||||
uchar *c, uint key_length)
|
uchar *c, uint key_length)
|
||||||
{
|
{
|
||||||
uint inc = 0;
|
uint inc= 0;
|
||||||
uint k_len = key_length;
|
uint k_len= key_length;
|
||||||
uint nod_flag = _ma_test_if_nod(page_buf);
|
uint nod_flag= _ma_test_if_nod(info, page_buf);
|
||||||
uchar *k;
|
uchar *k;
|
||||||
uchar *last = rt_PAGE_END(page_buf);
|
uchar *last= rt_PAGE_END(info, page_buf);
|
||||||
|
|
||||||
for (; (int)key_length > 0; keyseg += 2)
|
for (; (int)key_length > 0; keyseg += 2)
|
||||||
{
|
{
|
||||||
@ -753,7 +753,7 @@ int maria_rtree_page_mbr(MARIA_HA *info, HA_KEYSEG *keyseg, uchar *page_buf,
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
k = rt_PAGE_FIRST_KEY(page_buf, nod_flag);
|
k= rt_PAGE_FIRST_KEY(info, page_buf, nod_flag);
|
||||||
|
|
||||||
switch ((enum ha_base_keytype) keyseg->type) {
|
switch ((enum ha_base_keytype) keyseg->type) {
|
||||||
case HA_KEYTYPE_INT8:
|
case HA_KEYTYPE_INT8:
|
||||||
|
@ -32,25 +32,25 @@ typedef struct
|
|||||||
|
|
||||||
inline static double *reserve_coords(double **d_buffer, int n_dim)
|
inline static double *reserve_coords(double **d_buffer, int n_dim)
|
||||||
{
|
{
|
||||||
double *coords = *d_buffer;
|
double *coords= *d_buffer;
|
||||||
(*d_buffer) += n_dim * 2;
|
(*d_buffer)+= n_dim * 2;
|
||||||
return coords;
|
return coords;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mbr_join(double *a, const double *b, int n_dim)
|
static void mbr_join(double *a, const double *b, int n_dim)
|
||||||
{
|
{
|
||||||
double *end = a + n_dim * 2;
|
double *end= a + n_dim * 2;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
if (a[0] > b[0])
|
if (a[0] > b[0])
|
||||||
a[0] = b[0];
|
a[0]= b[0];
|
||||||
|
|
||||||
if (a[1] < b[1])
|
if (a[1] < b[1])
|
||||||
a[1] = b[1];
|
a[1]= b[1];
|
||||||
|
|
||||||
a += 2;
|
a+= 2;
|
||||||
b += 2;
|
b+= 2;
|
||||||
}while (a != end);
|
} while (a != end);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -58,29 +58,29 @@ Counts the square of mbr which is a join of a and b
|
|||||||
*/
|
*/
|
||||||
static double mbr_join_square(const double *a, const double *b, int n_dim)
|
static double mbr_join_square(const double *a, const double *b, int n_dim)
|
||||||
{
|
{
|
||||||
const double *end = a + n_dim * 2;
|
const double *end= a + n_dim * 2;
|
||||||
double square = 1.0;
|
double square= 1.0;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
square *=
|
square *=
|
||||||
((a[1] < b[1]) ? b[1] : a[1]) - ((a[0] > b[0]) ? b[0] : a[0]);
|
((a[1] < b[1]) ? b[1] : a[1]) - ((a[0] > b[0]) ? b[0] : a[0]);
|
||||||
|
|
||||||
a += 2;
|
a+= 2;
|
||||||
b += 2;
|
b+= 2;
|
||||||
}while (a != end);
|
} while (a != end);
|
||||||
|
|
||||||
return square;
|
return square;
|
||||||
}
|
}
|
||||||
|
|
||||||
static double count_square(const double *a, int n_dim)
|
static double count_square(const double *a, int n_dim)
|
||||||
{
|
{
|
||||||
const double *end = a + n_dim * 2;
|
const double *end= a + n_dim * 2;
|
||||||
double square = 1.0;
|
double square= 1.0;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
square *= a[1] - a[0];
|
square *= a[1] - a[0];
|
||||||
a += 2;
|
a+= 2;
|
||||||
}while (a != end);
|
} while (a != end);
|
||||||
return square;
|
return square;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -96,25 +96,25 @@ static void pick_seeds(SplitStruct *node, int n_entries,
|
|||||||
SplitStruct **seed_a, SplitStruct **seed_b, int n_dim)
|
SplitStruct **seed_a, SplitStruct **seed_b, int n_dim)
|
||||||
{
|
{
|
||||||
SplitStruct *cur1;
|
SplitStruct *cur1;
|
||||||
SplitStruct *lim1 = node + (n_entries - 1);
|
SplitStruct *lim1= node + (n_entries - 1);
|
||||||
SplitStruct *cur2;
|
SplitStruct *cur2;
|
||||||
SplitStruct *lim2 = node + n_entries;
|
SplitStruct *lim2= node + n_entries;
|
||||||
|
|
||||||
double max_d = -DBL_MAX;
|
double max_d= -DBL_MAX;
|
||||||
double d;
|
double d;
|
||||||
|
|
||||||
for (cur1 = node; cur1 < lim1; ++cur1)
|
for (cur1= node; cur1 < lim1; cur1++)
|
||||||
{
|
{
|
||||||
for (cur2=cur1 + 1; cur2 < lim2; ++cur2)
|
for (cur2=cur1 + 1; cur2 < lim2; cur2++)
|
||||||
{
|
{
|
||||||
|
|
||||||
d = mbr_join_square(cur1->coords, cur2->coords, n_dim) - cur1->square -
|
d= mbr_join_square(cur1->coords, cur2->coords, n_dim) - cur1->square -
|
||||||
cur2->square;
|
cur2->square;
|
||||||
if (d > max_d)
|
if (d > max_d)
|
||||||
{
|
{
|
||||||
max_d = d;
|
max_d= d;
|
||||||
*seed_a = cur1;
|
*seed_a= cur1;
|
||||||
*seed_b = cur2;
|
*seed_b= cur2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -126,12 +126,12 @@ Select next node and group where to add
|
|||||||
static void pick_next(SplitStruct *node, int n_entries, double *g1, double *g2,
|
static void pick_next(SplitStruct *node, int n_entries, double *g1, double *g2,
|
||||||
SplitStruct **choice, int *n_group, int n_dim)
|
SplitStruct **choice, int *n_group, int n_dim)
|
||||||
{
|
{
|
||||||
SplitStruct *cur = node;
|
SplitStruct *cur= node;
|
||||||
SplitStruct *end = node + n_entries;
|
SplitStruct *end= node + n_entries;
|
||||||
|
|
||||||
double max_diff = -DBL_MAX;
|
double max_diff= -DBL_MAX;
|
||||||
|
|
||||||
for (; cur<end; ++cur)
|
for (; cur < end; cur++)
|
||||||
{
|
{
|
||||||
double diff;
|
double diff;
|
||||||
double abs_diff;
|
double abs_diff;
|
||||||
@ -141,15 +141,15 @@ static void pick_next(SplitStruct *node, int n_entries, double *g1, double *g2,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
diff = mbr_join_square(g1, cur->coords, n_dim) -
|
diff= mbr_join_square(g1, cur->coords, n_dim) -
|
||||||
mbr_join_square(g2, cur->coords, n_dim);
|
mbr_join_square(g2, cur->coords, n_dim);
|
||||||
|
|
||||||
abs_diff = fabs(diff);
|
abs_diff= fabs(diff);
|
||||||
if (abs_diff > max_diff)
|
if (abs_diff > max_diff)
|
||||||
{
|
{
|
||||||
max_diff = abs_diff;
|
max_diff= abs_diff;
|
||||||
*n_group = 1 + (diff > 0);
|
*n_group= 1 + (diff > 0);
|
||||||
*choice = cur;
|
*choice= cur;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -159,15 +159,16 @@ Mark not-in-group entries as n_group
|
|||||||
*/
|
*/
|
||||||
static void mark_all_entries(SplitStruct *node, int n_entries, int n_group)
|
static void mark_all_entries(SplitStruct *node, int n_entries, int n_group)
|
||||||
{
|
{
|
||||||
SplitStruct *cur = node;
|
SplitStruct *cur= node;
|
||||||
SplitStruct *end = node + n_entries;
|
SplitStruct *end= node + n_entries;
|
||||||
for (; cur<end; ++cur)
|
|
||||||
|
for (; cur < end; cur++)
|
||||||
{
|
{
|
||||||
if (cur->n_node)
|
if (cur->n_node)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
cur->n_node = n_group;
|
cur->n_node= n_group;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -181,12 +182,12 @@ static int split_maria_rtree_node(SplitStruct *node, int n_entries,
|
|||||||
SplitStruct *cur;
|
SplitStruct *cur;
|
||||||
SplitStruct *a;
|
SplitStruct *a;
|
||||||
SplitStruct *b;
|
SplitStruct *b;
|
||||||
double *g1 = reserve_coords(d_buffer, n_dim);
|
double *g1= reserve_coords(d_buffer, n_dim);
|
||||||
double *g2 = reserve_coords(d_buffer, n_dim);
|
double *g2= reserve_coords(d_buffer, n_dim);
|
||||||
SplitStruct *next;
|
SplitStruct *next;
|
||||||
int next_node;
|
int next_node;
|
||||||
int i;
|
int i;
|
||||||
SplitStruct *end = node + n_entries;
|
SplitStruct *end= node + n_entries;
|
||||||
LINT_INIT(a);
|
LINT_INIT(a);
|
||||||
LINT_INIT(b);
|
LINT_INIT(b);
|
||||||
LINT_INIT(next);
|
LINT_INIT(next);
|
||||||
@ -197,22 +198,22 @@ static int split_maria_rtree_node(SplitStruct *node, int n_entries,
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
cur = node;
|
cur= node;
|
||||||
for (; cur<end; ++cur)
|
for (; cur < end; cur++)
|
||||||
{
|
{
|
||||||
cur->square = count_square(cur->coords, n_dim);
|
cur->square= count_square(cur->coords, n_dim);
|
||||||
cur->n_node = 0;
|
cur->n_node= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
pick_seeds(node, n_entries, &a, &b, n_dim);
|
pick_seeds(node, n_entries, &a, &b, n_dim);
|
||||||
a->n_node = 1;
|
a->n_node= 1;
|
||||||
b->n_node = 2;
|
b->n_node= 2;
|
||||||
|
|
||||||
|
|
||||||
copy_coords(g1, a->coords, n_dim);
|
copy_coords(g1, a->coords, n_dim);
|
||||||
size1 += key_size;
|
size1+= key_size;
|
||||||
copy_coords(g2, b->coords, n_dim);
|
copy_coords(g2, b->coords, n_dim);
|
||||||
size2 += key_size;
|
size2+= key_size;
|
||||||
|
|
||||||
|
|
||||||
for (i=n_entries - 2; i>0; --i)
|
for (i=n_entries - 2; i>0; --i)
|
||||||
@ -232,15 +233,15 @@ static int split_maria_rtree_node(SplitStruct *node, int n_entries,
|
|||||||
pick_next(node, n_entries, g1, g2, &next, &next_node, n_dim);
|
pick_next(node, n_entries, g1, g2, &next, &next_node, n_dim);
|
||||||
if (next_node == 1)
|
if (next_node == 1)
|
||||||
{
|
{
|
||||||
size1 += key_size;
|
size1+= key_size;
|
||||||
mbr_join(g1, next->coords, n_dim);
|
mbr_join(g1, next->coords, n_dim);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
size2 += key_size;
|
size2+= key_size;
|
||||||
mbr_join(g2, next->coords, n_dim);
|
mbr_join(g2, next->coords, n_dim);
|
||||||
}
|
}
|
||||||
next->n_node = next_node;
|
next->n_node= next_node;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -262,14 +263,15 @@ int maria_rtree_split_page(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
|
|||||||
uchar *source_cur, *cur1, *cur2;
|
uchar *source_cur, *cur1, *cur2;
|
||||||
uchar *new_page;
|
uchar *new_page;
|
||||||
int err_code= 0;
|
int err_code= 0;
|
||||||
uint nod_flag= _ma_test_if_nod(page);
|
uint nod_flag= _ma_test_if_nod(info, page);
|
||||||
uint full_length= key_length + (nod_flag ? nod_flag :
|
uint full_length= key_length + (nod_flag ? nod_flag :
|
||||||
info->s->base.rec_reflength);
|
info->s->base.rec_reflength);
|
||||||
int max_keys= (maria_data_on_page(page)-2) / (full_length);
|
int max_keys= ((_ma_get_page_used(info, page) - info->s->keypage_header) /
|
||||||
|
(full_length));
|
||||||
DBUG_ENTER("maria_rtree_split_page");
|
DBUG_ENTER("maria_rtree_split_page");
|
||||||
DBUG_PRINT("rtree", ("splitting block"));
|
DBUG_PRINT("rtree", ("splitting block"));
|
||||||
|
|
||||||
n_dim = keyinfo->keysegs / 2;
|
n_dim= keyinfo->keysegs / 2;
|
||||||
|
|
||||||
if (!(coord_buf= (double*) my_alloca(n_dim * 2 * sizeof(double) *
|
if (!(coord_buf= (double*) my_alloca(n_dim * 2 * sizeof(double) *
|
||||||
(max_keys + 1 + 4) +
|
(max_keys + 1 + 4) +
|
||||||
@ -278,66 +280,69 @@ int maria_rtree_split_page(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
|
|||||||
|
|
||||||
task= (SplitStruct *)(coord_buf + n_dim * 2 * (max_keys + 1 + 4));
|
task= (SplitStruct *)(coord_buf + n_dim * 2 * (max_keys + 1 + 4));
|
||||||
|
|
||||||
next_coord = coord_buf;
|
next_coord= coord_buf;
|
||||||
|
|
||||||
stop = task + max_keys;
|
stop= task + max_keys;
|
||||||
source_cur = rt_PAGE_FIRST_KEY(page, nod_flag);
|
source_cur= rt_PAGE_FIRST_KEY(info, page, nod_flag);
|
||||||
|
|
||||||
for (cur = task; cur < stop; ++cur, source_cur = rt_PAGE_NEXT_KEY(source_cur,
|
for (cur= task; cur < stop; cur++, source_cur= rt_PAGE_NEXT_KEY(source_cur,
|
||||||
key_length, nod_flag))
|
key_length, nod_flag))
|
||||||
{
|
{
|
||||||
cur->coords = reserve_coords(&next_coord, n_dim);
|
cur->coords= reserve_coords(&next_coord, n_dim);
|
||||||
cur->key = source_cur;
|
cur->key= source_cur;
|
||||||
maria_rtree_d_mbr(keyinfo->seg, source_cur, key_length, cur->coords);
|
maria_rtree_d_mbr(keyinfo->seg, source_cur, key_length, cur->coords);
|
||||||
}
|
}
|
||||||
|
|
||||||
cur->coords = reserve_coords(&next_coord, n_dim);
|
cur->coords= reserve_coords(&next_coord, n_dim);
|
||||||
maria_rtree_d_mbr(keyinfo->seg, key, key_length, cur->coords);
|
maria_rtree_d_mbr(keyinfo->seg, key, key_length, cur->coords);
|
||||||
cur->key = key;
|
cur->key= key;
|
||||||
|
|
||||||
old_coord = next_coord;
|
old_coord= next_coord;
|
||||||
|
|
||||||
if (split_maria_rtree_node(task, max_keys + 1,
|
if (split_maria_rtree_node(task, max_keys + 1,
|
||||||
maria_data_on_page(page) + full_length + 2, full_length,
|
_ma_get_page_used(info, page) + full_length + 2,
|
||||||
|
full_length,
|
||||||
rt_PAGE_MIN_SIZE(keyinfo->block_length),
|
rt_PAGE_MIN_SIZE(keyinfo->block_length),
|
||||||
2, 2, &next_coord, n_dim))
|
2, 2, &next_coord, n_dim))
|
||||||
{
|
{
|
||||||
err_code = 1;
|
err_code= 1;
|
||||||
goto split_err;
|
goto split_err;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(new_page = (uchar*) my_alloca((uint)keyinfo->block_length)))
|
if (!(new_page= (uchar*) my_alloca((uint)keyinfo->block_length)))
|
||||||
{
|
{
|
||||||
err_code= -1;
|
err_code= -1;
|
||||||
goto split_err;
|
goto split_err;
|
||||||
}
|
}
|
||||||
|
|
||||||
stop = task + (max_keys + 1);
|
stop= task + (max_keys + 1);
|
||||||
cur1 = rt_PAGE_FIRST_KEY(page, nod_flag);
|
cur1= rt_PAGE_FIRST_KEY(info, page, nod_flag);
|
||||||
cur2 = rt_PAGE_FIRST_KEY(new_page, nod_flag);
|
cur2= rt_PAGE_FIRST_KEY(info, new_page, nod_flag);
|
||||||
|
|
||||||
n1= n2 = 0;
|
n1= n2= 0;
|
||||||
for (cur = task; cur < stop; ++cur)
|
for (cur= task; cur < stop; cur++)
|
||||||
{
|
{
|
||||||
uchar *to;
|
uchar *to;
|
||||||
if (cur->n_node == 1)
|
if (cur->n_node == 1)
|
||||||
{
|
{
|
||||||
to = cur1;
|
to= cur1;
|
||||||
cur1 = rt_PAGE_NEXT_KEY(cur1, key_length, nod_flag);
|
cur1= rt_PAGE_NEXT_KEY(cur1, key_length, nod_flag);
|
||||||
++n1;
|
n1++;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
to = cur2;
|
to= cur2;
|
||||||
cur2 = rt_PAGE_NEXT_KEY(cur2, key_length, nod_flag);
|
cur2= rt_PAGE_NEXT_KEY(cur2, key_length, nod_flag);
|
||||||
++n2;
|
n2++;
|
||||||
}
|
}
|
||||||
if (to != cur->key)
|
if (to != cur->key)
|
||||||
memcpy(to - nod_flag, cur->key - nod_flag, full_length);
|
memcpy(to - nod_flag, cur->key - nod_flag, full_length);
|
||||||
}
|
}
|
||||||
|
|
||||||
maria_putint(page, 2 + n1 * full_length, nod_flag);
|
_ma_store_page_used(info, page, info->s->keypage_header + n1 * full_length,
|
||||||
maria_putint(new_page, 2 + n2 * full_length, nod_flag);
|
nod_flag);
|
||||||
|
_ma_store_page_used(info, new_page, info->s->keypage_header +
|
||||||
|
n2 * full_length, nod_flag);
|
||||||
|
|
||||||
if ((*new_page_offs= _ma_new(info, keyinfo, DFLT_INIT_HITS)) ==
|
if ((*new_page_offs= _ma_new(info, keyinfo, DFLT_INIT_HITS)) ==
|
||||||
HA_OFFSET_ERROR)
|
HA_OFFSET_ERROR)
|
||||||
|
@ -122,7 +122,8 @@ static int run_test(const char *filename)
|
|||||||
|
|
||||||
/* Define 2*ndims columns for coordinates*/
|
/* Define 2*ndims columns for coordinates*/
|
||||||
|
|
||||||
for (i=1; i<=2*ndims ;i++){
|
for (i=1; i<=2*ndims ;i++)
|
||||||
|
{
|
||||||
recinfo[i].type=FIELD_NORMAL;
|
recinfo[i].type=FIELD_NORMAL;
|
||||||
recinfo[i].length=key_length;
|
recinfo[i].length=key_length;
|
||||||
rec_length+=key_length;
|
rec_length+=key_length;
|
||||||
@ -135,7 +136,8 @@ static int run_test(const char *filename)
|
|||||||
keyinfo[0].flag=0;
|
keyinfo[0].flag=0;
|
||||||
keyinfo[0].key_alg=KEYALG;
|
keyinfo[0].key_alg=KEYALG;
|
||||||
|
|
||||||
for (i=0; i<2*ndims; i++){
|
for (i=0; i<2*ndims; i++)
|
||||||
|
{
|
||||||
keyinfo[0].seg[i].type= key_type;
|
keyinfo[0].seg[i].type= key_type;
|
||||||
keyinfo[0].seg[i].flag=0; /* Things like HA_REVERSE_SORT */
|
keyinfo[0].seg[i].flag=0; /* Things like HA_REVERSE_SORT */
|
||||||
keyinfo[0].seg[i].start= (key_length*i)+1;
|
keyinfo[0].seg[i].start= (key_length*i)+1;
|
||||||
|
@ -27,8 +27,6 @@ static my_bool _ma_get_prev_key(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
|
|||||||
|
|
||||||
int _ma_check_index(MARIA_HA *info, int inx)
|
int _ma_check_index(MARIA_HA *info, int inx)
|
||||||
{
|
{
|
||||||
if (inx == -1) /* Use last index */
|
|
||||||
inx=info->lastinx;
|
|
||||||
if (inx < 0 || ! maria_is_key_active(info->s->state.key_map, inx))
|
if (inx < 0 || ! maria_is_key_active(info->s->state.key_map, inx))
|
||||||
{
|
{
|
||||||
my_errno=HA_ERR_WRONG_INDEX;
|
my_errno=HA_ERR_WRONG_INDEX;
|
||||||
@ -59,7 +57,7 @@ int _ma_search(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
|
|||||||
{
|
{
|
||||||
my_bool last_key;
|
my_bool last_key;
|
||||||
int error,flag;
|
int error,flag;
|
||||||
uint nod_flag;
|
uint nod_flag, used_length;
|
||||||
uchar *keypos,*maxpos;
|
uchar *keypos,*maxpos;
|
||||||
uchar lastkey[HA_MAX_KEY_BUFF],*buff;
|
uchar lastkey[HA_MAX_KEY_BUFF],*buff;
|
||||||
DBUG_ENTER("_ma_search");
|
DBUG_ENTER("_ma_search");
|
||||||
@ -80,14 +78,14 @@ int _ma_search(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
|
|||||||
info->keyread_buff,
|
info->keyread_buff,
|
||||||
test(!(nextflag & SEARCH_SAVE_BUFF)))))
|
test(!(nextflag & SEARCH_SAVE_BUFF)))))
|
||||||
goto err;
|
goto err;
|
||||||
DBUG_DUMP("page", buff, maria_data_on_page(buff));
|
DBUG_DUMP("page", buff, _ma_get_page_used(info, buff));
|
||||||
|
|
||||||
flag=(*keyinfo->bin_search)(info,keyinfo,buff,key,key_len,nextflag,
|
flag=(*keyinfo->bin_search)(info,keyinfo,buff,key,key_len,nextflag,
|
||||||
&keypos,lastkey, &last_key);
|
&keypos,lastkey, &last_key);
|
||||||
if (flag == MARIA_FOUND_WRONG_KEY)
|
if (flag == MARIA_FOUND_WRONG_KEY)
|
||||||
DBUG_RETURN(-1);
|
DBUG_RETURN(-1);
|
||||||
nod_flag=_ma_test_if_nod(buff);
|
_ma_get_used_and_nod(info, buff, used_length, nod_flag);
|
||||||
maxpos=buff+maria_data_on_page(buff)-1;
|
maxpos= buff + used_length -1;
|
||||||
|
|
||||||
if (flag)
|
if (flag)
|
||||||
{
|
{
|
||||||
@ -98,7 +96,7 @@ int _ma_search(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
|
|||||||
if (flag >0)
|
if (flag >0)
|
||||||
{
|
{
|
||||||
if (nextflag & (SEARCH_SMALLER | SEARCH_LAST) &&
|
if (nextflag & (SEARCH_SMALLER | SEARCH_LAST) &&
|
||||||
keypos == buff+2+nod_flag)
|
keypos == buff + info->s->keypage_header + nod_flag)
|
||||||
DBUG_RETURN(1); /* Bigger than key */
|
DBUG_RETURN(1); /* Bigger than key */
|
||||||
}
|
}
|
||||||
else if (nextflag & SEARCH_BIGGER && keypos >= maxpos)
|
else if (nextflag & SEARCH_BIGGER && keypos >= maxpos)
|
||||||
@ -157,7 +155,8 @@ int _ma_search(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
|
|||||||
info->int_keytree_version=keyinfo->version;
|
info->int_keytree_version=keyinfo->version;
|
||||||
info->last_search_keypage=info->last_keypage;
|
info->last_search_keypage=info->last_keypage;
|
||||||
info->page_changed=0;
|
info->page_changed=0;
|
||||||
info->keyread_buff_used= (info->keyread_buff != buff); /* If we have to reread */
|
/* Set marker that buffer was used (Marker for mi_search_next()) */
|
||||||
|
info->keyread_buff_used= (info->keyread_buff != buff);
|
||||||
|
|
||||||
DBUG_PRINT("exit",("found key at %lu",(ulong) info->cur_row.lastpos));
|
DBUG_PRINT("exit",("found key at %lu",(ulong) info->cur_row.lastpos));
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
@ -179,17 +178,21 @@ int _ma_bin_search(MARIA_HA *info, register MARIA_KEYDEF *keyinfo, uchar *page,
|
|||||||
uchar *key, uint key_len, uint comp_flag, uchar **ret_pos,
|
uchar *key, uint key_len, uint comp_flag, uchar **ret_pos,
|
||||||
uchar *buff __attribute__((unused)), my_bool *last_key)
|
uchar *buff __attribute__((unused)), my_bool *last_key)
|
||||||
{
|
{
|
||||||
reg4 int start,mid,end,save_end;
|
|
||||||
int flag;
|
int flag;
|
||||||
uint totlength,nod_flag,not_used[2];
|
uint start, mid, end, save_end, totlength, nod_flag, used_length;
|
||||||
|
uint not_used[2];
|
||||||
DBUG_ENTER("_ma_bin_search");
|
DBUG_ENTER("_ma_bin_search");
|
||||||
|
|
||||||
LINT_INIT(flag);
|
LINT_INIT(flag);
|
||||||
totlength=keyinfo->keylength+(nod_flag=_ma_test_if_nod(page));
|
_ma_get_used_and_nod(info, page, used_length, nod_flag);
|
||||||
start=0; mid=1;
|
|
||||||
save_end=end=(int) ((maria_data_on_page(page)-2-nod_flag)/totlength-1);
|
totlength= keyinfo->keylength + nod_flag;
|
||||||
DBUG_PRINT("test",("page_length: %d end: %d",maria_data_on_page(page),end));
|
start=0;
|
||||||
page+=2+nod_flag;
|
mid=1;
|
||||||
|
save_end= end= ((used_length - nod_flag - info->s->keypage_header) /
|
||||||
|
totlength-1);
|
||||||
|
DBUG_PRINT("test",("page_length: %u end: %u", used_length, end));
|
||||||
|
page+= info->s->keypage_header + nod_flag;
|
||||||
|
|
||||||
while (start != end)
|
while (start != end)
|
||||||
{
|
{
|
||||||
@ -244,14 +247,16 @@ int _ma_seq_search(MARIA_HA *info, register MARIA_KEYDEF *keyinfo, uchar *page,
|
|||||||
uchar *buff, my_bool *last_key)
|
uchar *buff, my_bool *last_key)
|
||||||
{
|
{
|
||||||
int flag;
|
int flag;
|
||||||
uint nod_flag,length,not_used[2];
|
uint nod_flag, length, used_length, not_used[2];
|
||||||
uchar t_buff[HA_MAX_KEY_BUFF],*end;
|
uchar t_buff[HA_MAX_KEY_BUFF],*end;
|
||||||
DBUG_ENTER("_ma_seq_search");
|
DBUG_ENTER("_ma_seq_search");
|
||||||
|
|
||||||
LINT_INIT(flag); LINT_INIT(length);
|
LINT_INIT(flag);
|
||||||
end= page+maria_data_on_page(page);
|
LINT_INIT(length);
|
||||||
nod_flag=_ma_test_if_nod(page);
|
|
||||||
page+=2+nod_flag;
|
_ma_get_used_and_nod(info, page, used_length, nod_flag);
|
||||||
|
end= page + used_length;
|
||||||
|
page+= info->s->keypage_header + nod_flag;
|
||||||
*ret_pos=page;
|
*ret_pos=page;
|
||||||
t_buff[0]=0; /* Avoid bugs */
|
t_buff[0]=0; /* Avoid bugs */
|
||||||
while (page < end)
|
while (page < end)
|
||||||
@ -294,7 +299,7 @@ int _ma_prefix_search(MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
|
|||||||
flag is the value returned by ha_key_cmp and as treated as final
|
flag is the value returned by ha_key_cmp and as treated as final
|
||||||
*/
|
*/
|
||||||
int flag=0, my_flag=-1;
|
int flag=0, my_flag=-1;
|
||||||
uint nod_flag, length, len, matched, cmplen, kseg_len;
|
uint nod_flag, used_length, length, len, matched, cmplen, kseg_len;
|
||||||
uint prefix_len,suffix_len;
|
uint prefix_len,suffix_len;
|
||||||
int key_len_skip, seg_len_pack, key_len_left;
|
int key_len_skip, seg_len_pack, key_len_left;
|
||||||
uchar *end;
|
uchar *end;
|
||||||
@ -314,11 +319,11 @@ int _ma_prefix_search(MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
|
|||||||
LINT_INIT(saved_vseg);
|
LINT_INIT(saved_vseg);
|
||||||
|
|
||||||
t_buff[0]=0; /* Avoid bugs */
|
t_buff[0]=0; /* Avoid bugs */
|
||||||
end= page+maria_data_on_page(page);
|
_ma_get_used_and_nod(info, page, used_length, nod_flag);
|
||||||
nod_flag=_ma_test_if_nod(page);
|
end= page + used_length;
|
||||||
page+=2+nod_flag;
|
page+= info->s->keypage_header + nod_flag;
|
||||||
*ret_pos=page;
|
*ret_pos= page;
|
||||||
kseg= (uchar*) key;
|
kseg= key;
|
||||||
|
|
||||||
get_key_pack_length(kseg_len, length_pack, kseg);
|
get_key_pack_length(kseg_len, length_pack, kseg);
|
||||||
key_len_skip=length_pack+kseg_len;
|
key_len_skip=length_pack+kseg_len;
|
||||||
@ -974,7 +979,11 @@ uint _ma_get_binary_pack_key(register MARIA_KEYDEF *keyinfo, uint nod_flag,
|
|||||||
if (keyseg->flag & HA_NULL_PART)
|
if (keyseg->flag & HA_NULL_PART)
|
||||||
{
|
{
|
||||||
/* If prefix is used up, switch to rest. */
|
/* If prefix is used up, switch to rest. */
|
||||||
if (from == from_end) { from=page; from_end=page_end; }
|
if (from == from_end)
|
||||||
|
{
|
||||||
|
from=page;
|
||||||
|
from_end=page_end;
|
||||||
|
}
|
||||||
if (!(*key++ = *from++))
|
if (!(*key++ = *from++))
|
||||||
continue; /* Null part */
|
continue; /* Null part */
|
||||||
}
|
}
|
||||||
@ -1044,8 +1053,11 @@ uint _ma_get_binary_pack_key(register MARIA_KEYDEF *keyinfo, uint nod_flag,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Get key at position without knowledge of previous key */
|
/*
|
||||||
/* Returns pointer to next key */
|
@brief Get key at position without knowledge of previous key
|
||||||
|
|
||||||
|
@return pointer to next key
|
||||||
|
*/
|
||||||
|
|
||||||
uchar *_ma_get_key(MARIA_HA *info, MARIA_KEYDEF *keyinfo, uchar *page,
|
uchar *_ma_get_key(MARIA_HA *info, MARIA_KEYDEF *keyinfo, uchar *page,
|
||||||
uchar *key, uchar *keypos, uint *return_key_length)
|
uchar *key, uchar *keypos, uint *return_key_length)
|
||||||
@ -1053,7 +1065,7 @@ uchar *_ma_get_key(MARIA_HA *info, MARIA_KEYDEF *keyinfo, uchar *page,
|
|||||||
uint nod_flag;
|
uint nod_flag;
|
||||||
DBUG_ENTER("_ma_get_key");
|
DBUG_ENTER("_ma_get_key");
|
||||||
|
|
||||||
nod_flag=_ma_test_if_nod(page);
|
nod_flag=_ma_test_if_nod(info, page);
|
||||||
if (! (keyinfo->flag & (HA_VAR_LENGTH_KEY | HA_BINARY_PACK_KEY)))
|
if (! (keyinfo->flag & (HA_VAR_LENGTH_KEY | HA_BINARY_PACK_KEY)))
|
||||||
{
|
{
|
||||||
bmove((uchar*) key,(uchar*) keypos,keyinfo->keylength+nod_flag);
|
bmove((uchar*) key,(uchar*) keypos,keyinfo->keylength+nod_flag);
|
||||||
@ -1061,7 +1073,7 @@ uchar *_ma_get_key(MARIA_HA *info, MARIA_KEYDEF *keyinfo, uchar *page,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
page+=2+nod_flag;
|
page+= info->s->keypage_header + nod_flag;
|
||||||
key[0]=0; /* safety */
|
key[0]=0; /* safety */
|
||||||
while (page <= keypos)
|
while (page <= keypos)
|
||||||
{
|
{
|
||||||
@ -1080,8 +1092,13 @@ uchar *_ma_get_key(MARIA_HA *info, MARIA_KEYDEF *keyinfo, uchar *page,
|
|||||||
} /* _ma_get_key */
|
} /* _ma_get_key */
|
||||||
|
|
||||||
|
|
||||||
/* Get key at position without knowledge of previous key */
|
/*
|
||||||
/* Returns 0 if ok */
|
@brief Get key at position without knowledge of previous key
|
||||||
|
|
||||||
|
@return
|
||||||
|
@retval 0 ok
|
||||||
|
@retval 1 error
|
||||||
|
*/
|
||||||
|
|
||||||
static my_bool _ma_get_prev_key(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
|
static my_bool _ma_get_prev_key(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
|
||||||
uchar *page, uchar *key, uchar *keypos,
|
uchar *page, uchar *key, uchar *keypos,
|
||||||
@ -1090,7 +1107,7 @@ static my_bool _ma_get_prev_key(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
|
|||||||
uint nod_flag;
|
uint nod_flag;
|
||||||
DBUG_ENTER("_ma_get_prev_key");
|
DBUG_ENTER("_ma_get_prev_key");
|
||||||
|
|
||||||
nod_flag=_ma_test_if_nod(page);
|
nod_flag=_ma_test_if_nod(info, page);
|
||||||
if (! (keyinfo->flag & (HA_VAR_LENGTH_KEY | HA_BINARY_PACK_KEY)))
|
if (! (keyinfo->flag & (HA_VAR_LENGTH_KEY | HA_BINARY_PACK_KEY)))
|
||||||
{
|
{
|
||||||
*return_key_length=keyinfo->keylength;
|
*return_key_length=keyinfo->keylength;
|
||||||
@ -1100,7 +1117,7 @@ static my_bool _ma_get_prev_key(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
page+=2+nod_flag;
|
page+= info->s->keypage_header + nod_flag;
|
||||||
key[0]=0; /* safety */
|
key[0]=0; /* safety */
|
||||||
while (page < keypos)
|
while (page < keypos)
|
||||||
{
|
{
|
||||||
@ -1117,9 +1134,12 @@ static my_bool _ma_get_prev_key(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
|
|||||||
} /* _ma_get_key */
|
} /* _ma_get_key */
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
@brief Get last key from key-page
|
||||||
|
|
||||||
/* Get last key from key-page */
|
@return
|
||||||
/* Return pointer to where key starts */
|
@retval pointer to where key starts
|
||||||
|
*/
|
||||||
|
|
||||||
uchar *_ma_get_last_key(MARIA_HA *info, MARIA_KEYDEF *keyinfo, uchar *page,
|
uchar *_ma_get_last_key(MARIA_HA *info, MARIA_KEYDEF *keyinfo, uchar *page,
|
||||||
uchar *lastkey, uchar *endpos, uint *return_key_length)
|
uchar *lastkey, uchar *endpos, uint *return_key_length)
|
||||||
@ -1130,7 +1150,7 @@ uchar *_ma_get_last_key(MARIA_HA *info, MARIA_KEYDEF *keyinfo, uchar *page,
|
|||||||
DBUG_PRINT("enter",("page: 0x%lx endpos: 0x%lx", (long) page,
|
DBUG_PRINT("enter",("page: 0x%lx endpos: 0x%lx", (long) page,
|
||||||
(long) endpos));
|
(long) endpos));
|
||||||
|
|
||||||
nod_flag=_ma_test_if_nod(page);
|
nod_flag=_ma_test_if_nod(info, page);
|
||||||
if (! (keyinfo->flag & (HA_VAR_LENGTH_KEY | HA_BINARY_PACK_KEY)))
|
if (! (keyinfo->flag & (HA_VAR_LENGTH_KEY | HA_BINARY_PACK_KEY)))
|
||||||
{
|
{
|
||||||
lastpos=endpos-keyinfo->keylength-nod_flag;
|
lastpos=endpos-keyinfo->keylength-nod_flag;
|
||||||
@ -1140,7 +1160,8 @@ uchar *_ma_get_last_key(MARIA_HA *info, MARIA_KEYDEF *keyinfo, uchar *page,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
lastpos=(page+=2+nod_flag);
|
page+= info->s->keypage_header + nod_flag;
|
||||||
|
lastpos= page;
|
||||||
lastkey[0]=0;
|
lastkey[0]=0;
|
||||||
while (page < endpos)
|
while (page < endpos)
|
||||||
{
|
{
|
||||||
@ -1162,7 +1183,7 @@ uchar *_ma_get_last_key(MARIA_HA *info, MARIA_KEYDEF *keyinfo, uchar *page,
|
|||||||
} /* _ma_get_last_key */
|
} /* _ma_get_last_key */
|
||||||
|
|
||||||
|
|
||||||
/* Calculate length of key */
|
/* Calculate length of key */
|
||||||
|
|
||||||
uint _ma_keylength(MARIA_KEYDEF *keyinfo, register const uchar *key)
|
uint _ma_keylength(MARIA_KEYDEF *keyinfo, register const uchar *key)
|
||||||
{
|
{
|
||||||
@ -1276,7 +1297,7 @@ int _ma_search_next(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Last used buffer is in info->keyread_buff */
|
/* Last used buffer is in info->keyread_buff */
|
||||||
nod_flag=_ma_test_if_nod(info->keyread_buff);
|
nod_flag=_ma_test_if_nod(info, info->keyread_buff);
|
||||||
|
|
||||||
if (nextflag & SEARCH_BIGGER) /* Next key */
|
if (nextflag & SEARCH_BIGGER) /* Next key */
|
||||||
{
|
{
|
||||||
@ -1300,7 +1321,7 @@ int _ma_search_next(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
|
|||||||
info->int_keypos, &length);
|
info->int_keypos, &length);
|
||||||
if (!info->int_keypos)
|
if (!info->int_keypos)
|
||||||
DBUG_RETURN(-1);
|
DBUG_RETURN(-1);
|
||||||
if (info->int_keypos == info->keyread_buff+2)
|
if (info->int_keypos == info->keyread_buff + info->s->keypage_header)
|
||||||
DBUG_RETURN(_ma_search(info,keyinfo,key, USE_WHOLE_KEY,
|
DBUG_RETURN(_ma_search(info,keyinfo,key, USE_WHOLE_KEY,
|
||||||
nextflag | SEARCH_SAVE_BUFF, pos));
|
nextflag | SEARCH_SAVE_BUFF, pos));
|
||||||
if ((error= _ma_search(info,keyinfo,key, USE_WHOLE_KEY,
|
if ((error= _ma_search(info,keyinfo,key, USE_WHOLE_KEY,
|
||||||
@ -1339,20 +1360,23 @@ int _ma_search_first(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
|
|||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
if (!_ma_fetch_keypage(info,keyinfo,pos,DFLT_INIT_HITS,info->keyread_buff,0))
|
if (!_ma_fetch_keypage(info,keyinfo,pos,DFLT_INIT_HITS,
|
||||||
|
info->keyread_buff,0))
|
||||||
{
|
{
|
||||||
info->cur_row.lastpos= HA_OFFSET_ERROR;
|
info->cur_row.lastpos= HA_OFFSET_ERROR;
|
||||||
DBUG_RETURN(-1);
|
DBUG_RETURN(-1);
|
||||||
}
|
}
|
||||||
nod_flag=_ma_test_if_nod(info->keyread_buff);
|
nod_flag=_ma_test_if_nod(info, info->keyread_buff);
|
||||||
page=info->keyread_buff+2+nod_flag;
|
page= info->keyread_buff + info->s->keypage_header + nod_flag;
|
||||||
} while ((pos= _ma_kpos(nod_flag,page)) != HA_OFFSET_ERROR);
|
} while ((pos= _ma_kpos(nod_flag,page)) != HA_OFFSET_ERROR);
|
||||||
|
|
||||||
if (!(info->lastkey_length=(*keyinfo->get_key)(keyinfo,nod_flag,&page,
|
if (!(info->lastkey_length=(*keyinfo->get_key)(keyinfo,nod_flag,&page,
|
||||||
info->lastkey)))
|
info->lastkey)))
|
||||||
DBUG_RETURN(-1); /* Crashed */
|
DBUG_RETURN(-1); /* Crashed */
|
||||||
|
|
||||||
info->int_keypos=page; info->int_maxpos=info->keyread_buff+maria_data_on_page(info->keyread_buff)-1;
|
info->int_keypos=page;
|
||||||
|
info->int_maxpos= (info->keyread_buff +
|
||||||
|
_ma_get_page_used(info, info->keyread_buff)-1);
|
||||||
info->int_nod_flag=nod_flag;
|
info->int_nod_flag=nod_flag;
|
||||||
info->int_keytree_version=keyinfo->version;
|
info->int_keytree_version=keyinfo->version;
|
||||||
info->last_search_keypage=info->last_keypage;
|
info->last_search_keypage=info->last_keypage;
|
||||||
@ -1371,7 +1395,7 @@ int _ma_search_last(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
|
|||||||
register my_off_t pos)
|
register my_off_t pos)
|
||||||
{
|
{
|
||||||
uint nod_flag;
|
uint nod_flag;
|
||||||
uchar *buff,*page;
|
uchar *buff,*end_of_page;
|
||||||
DBUG_ENTER("_ma_search_last");
|
DBUG_ENTER("_ma_search_last");
|
||||||
|
|
||||||
if (pos == HA_OFFSET_ERROR)
|
if (pos == HA_OFFSET_ERROR)
|
||||||
@ -1384,20 +1408,21 @@ int _ma_search_last(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
|
|||||||
buff=info->keyread_buff;
|
buff=info->keyread_buff;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
|
uint used_length;
|
||||||
if (!_ma_fetch_keypage(info,keyinfo,pos,DFLT_INIT_HITS,buff,0))
|
if (!_ma_fetch_keypage(info,keyinfo,pos,DFLT_INIT_HITS,buff,0))
|
||||||
{
|
{
|
||||||
info->cur_row.lastpos= HA_OFFSET_ERROR;
|
info->cur_row.lastpos= HA_OFFSET_ERROR;
|
||||||
DBUG_RETURN(-1);
|
DBUG_RETURN(-1);
|
||||||
}
|
}
|
||||||
page= buff+maria_data_on_page(buff);
|
_ma_get_used_and_nod(info, buff, used_length, nod_flag);
|
||||||
nod_flag=_ma_test_if_nod(buff);
|
end_of_page= buff + used_length;
|
||||||
} while ((pos= _ma_kpos(nod_flag,page)) != HA_OFFSET_ERROR);
|
} while ((pos= _ma_kpos(nod_flag, end_of_page)) != HA_OFFSET_ERROR);
|
||||||
|
|
||||||
if (!_ma_get_last_key(info,keyinfo,buff,info->lastkey,page,
|
if (!_ma_get_last_key(info, keyinfo, buff, info->lastkey, end_of_page,
|
||||||
&info->lastkey_length))
|
&info->lastkey_length))
|
||||||
DBUG_RETURN(-1);
|
DBUG_RETURN(-1);
|
||||||
info->cur_row.lastpos= _ma_dpos(info,0,info->lastkey+info->lastkey_length);
|
info->cur_row.lastpos= _ma_dpos(info,0,info->lastkey+info->lastkey_length);
|
||||||
info->int_keypos=info->int_maxpos=page;
|
info->int_keypos= info->int_maxpos= end_of_page;
|
||||||
info->int_nod_flag=nod_flag;
|
info->int_nod_flag=nod_flag;
|
||||||
info->int_keytree_version=keyinfo->version;
|
info->int_keytree_version=keyinfo->version;
|
||||||
info->last_search_keypage=info->last_keypage;
|
info->last_search_keypage=info->last_keypage;
|
||||||
|
@ -93,7 +93,7 @@ my_var_write(MARIA_SORT_PARAM *info, IO_CACHE *to_file, uchar *bufs);
|
|||||||
_ma_create_index_by_sort()
|
_ma_create_index_by_sort()
|
||||||
info Sort parameters
|
info Sort parameters
|
||||||
no_messages Set to 1 if no output
|
no_messages Set to 1 if no output
|
||||||
sortbuff_size Size if sortbuffer to allocate
|
sortbuff_size Size of sortbuffer to allocate
|
||||||
|
|
||||||
RESULT
|
RESULT
|
||||||
0 ok
|
0 ok
|
||||||
@ -101,10 +101,11 @@ my_var_write(MARIA_SORT_PARAM *info, IO_CACHE *to_file, uchar *bufs);
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
int _ma_create_index_by_sort(MARIA_SORT_PARAM *info, my_bool no_messages,
|
int _ma_create_index_by_sort(MARIA_SORT_PARAM *info, my_bool no_messages,
|
||||||
ulong sortbuff_size)
|
size_t sortbuff_size)
|
||||||
{
|
{
|
||||||
int error,maxbuffer,skr;
|
int error,maxbuffer,skr;
|
||||||
uint memavl,old_memavl,keys,sort_length;
|
size_t memavl,old_memavl;
|
||||||
|
uint keys,sort_length;
|
||||||
DYNAMIC_ARRAY buffpek;
|
DYNAMIC_ARRAY buffpek;
|
||||||
ha_rows records;
|
ha_rows records;
|
||||||
uchar **sort_keys;
|
uchar **sort_keys;
|
||||||
@ -314,8 +315,9 @@ pthread_handler_t _ma_thr_find_all_keys(void *arg)
|
|||||||
{
|
{
|
||||||
MARIA_SORT_PARAM *sort_param= (MARIA_SORT_PARAM*) arg;
|
MARIA_SORT_PARAM *sort_param= (MARIA_SORT_PARAM*) arg;
|
||||||
int error;
|
int error;
|
||||||
uint memavl,old_memavl,keys,sort_length;
|
size_t memavl,old_memavl;
|
||||||
uint idx, maxbuffer;
|
uint sort_length;
|
||||||
|
ulong idx, maxbuffer, keys;
|
||||||
uchar **sort_keys=0;
|
uchar **sort_keys=0;
|
||||||
|
|
||||||
LINT_INIT(keys);
|
LINT_INIT(keys);
|
||||||
@ -356,19 +358,18 @@ pthread_handler_t _ma_thr_find_all_keys(void *arg)
|
|||||||
|
|
||||||
while (memavl >= MIN_SORT_MEMORY)
|
while (memavl >= MIN_SORT_MEMORY)
|
||||||
{
|
{
|
||||||
if ((my_off_t) (idx+1)*(sort_length+sizeof(char*)) <=
|
if ((my_off_t) (idx+1)*(sort_length+sizeof(char*)) <= (my_off_t) memavl)
|
||||||
(my_off_t) memavl)
|
|
||||||
keys= idx+1;
|
keys= idx+1;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
uint skr;
|
ulong skr;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
skr= maxbuffer;
|
skr= maxbuffer;
|
||||||
if (memavl < sizeof(BUFFPEK)*maxbuffer ||
|
if (memavl < sizeof(BUFFPEK)*maxbuffer ||
|
||||||
(keys=(memavl-sizeof(BUFFPEK)*maxbuffer)/
|
(keys=(memavl-sizeof(BUFFPEK)*maxbuffer)/
|
||||||
(sort_length+sizeof(char*))) <= 1 ||
|
(sort_length+sizeof(char*))) <= 1 ||
|
||||||
keys < (uint) maxbuffer)
|
keys < maxbuffer)
|
||||||
{
|
{
|
||||||
_ma_check_print_error(sort_param->sort_info->param,
|
_ma_check_print_error(sort_param->sort_info->param,
|
||||||
"maria_sort_buffer_size is too small");
|
"maria_sort_buffer_size is too small");
|
||||||
@ -404,8 +405,8 @@ pthread_handler_t _ma_thr_find_all_keys(void *arg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (sort_param->sort_info->param->testflag & T_VERBOSE)
|
if (sort_param->sort_info->param->testflag & T_VERBOSE)
|
||||||
printf("Key %d - Allocating buffer for %d keys\n",
|
printf("Key %d - Allocating buffer for %lu keys\n",
|
||||||
sort_param->key+1, keys);
|
sort_param->key+1, (ulong) keys);
|
||||||
sort_param->sort_keys= sort_keys;
|
sort_param->sort_keys= sort_keys;
|
||||||
|
|
||||||
idx= error= 0;
|
idx= error= 0;
|
||||||
@ -493,7 +494,7 @@ int _ma_thr_write_keys(MARIA_SORT_PARAM *sort_param)
|
|||||||
MARIA_SORT_INFO *sort_info=sort_param->sort_info;
|
MARIA_SORT_INFO *sort_info=sort_param->sort_info;
|
||||||
HA_CHECK *param=sort_info->param;
|
HA_CHECK *param=sort_info->param;
|
||||||
ulong length, keys;
|
ulong length, keys;
|
||||||
ulong *rec_per_key_part=param->rec_per_key_part;
|
double *rec_per_key_part= param->new_rec_per_key_part;
|
||||||
int got_error=sort_info->got_error;
|
int got_error=sort_info->got_error;
|
||||||
uint i;
|
uint i;
|
||||||
MARIA_HA *info=sort_info->info;
|
MARIA_HA *info=sort_info->info;
|
||||||
|
@ -24,10 +24,12 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
LIST *maria_open_list=0;
|
LIST *maria_open_list=0;
|
||||||
uchar NEAR maria_file_magic[]=
|
uchar maria_file_magic[]=
|
||||||
{ (uchar) 254, (uchar) 254, (uchar) 9, '\001', };
|
{ (uchar) 254, (uchar) 254, (uchar) 9, '\001', };
|
||||||
uchar NEAR maria_pack_file_magic[]=
|
uchar maria_pack_file_magic[]=
|
||||||
{ (uchar) 254, (uchar) 254, (uchar) 10, '\001', };
|
{ (uchar) 254, (uchar) 254, (uchar) 10, '\001', };
|
||||||
|
/* Unique number for this maria instance */
|
||||||
|
uchar maria_uuid[MY_UUID_SIZE];
|
||||||
uint maria_quick_table_bits=9;
|
uint maria_quick_table_bits=9;
|
||||||
ulong maria_block_size= MARIA_KEY_BLOCK_LENGTH;
|
ulong maria_block_size= MARIA_KEY_BLOCK_LENGTH;
|
||||||
my_bool maria_flush= 0, maria_single_user= 0;
|
my_bool maria_flush= 0, maria_single_user= 0;
|
||||||
@ -64,7 +66,7 @@ uchar maria_zero_string[]= {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
|
|||||||
Position is , == , >= , <= , > , <
|
Position is , == , >= , <= , > , <
|
||||||
*/
|
*/
|
||||||
|
|
||||||
uint NEAR maria_read_vec[]=
|
uint maria_read_vec[]=
|
||||||
{
|
{
|
||||||
SEARCH_FIND, SEARCH_FIND | SEARCH_BIGGER, SEARCH_FIND | SEARCH_SMALLER,
|
SEARCH_FIND, SEARCH_FIND | SEARCH_BIGGER, SEARCH_FIND | SEARCH_SMALLER,
|
||||||
SEARCH_NO_FIND | SEARCH_BIGGER, SEARCH_NO_FIND | SEARCH_SMALLER,
|
SEARCH_NO_FIND | SEARCH_BIGGER, SEARCH_NO_FIND | SEARCH_SMALLER,
|
||||||
@ -72,7 +74,7 @@ uint NEAR maria_read_vec[]=
|
|||||||
MBR_CONTAIN, MBR_INTERSECT, MBR_WITHIN, MBR_DISJOINT, MBR_EQUAL
|
MBR_CONTAIN, MBR_INTERSECT, MBR_WITHIN, MBR_DISJOINT, MBR_EQUAL
|
||||||
};
|
};
|
||||||
|
|
||||||
uint NEAR maria_readnext_vec[]=
|
uint maria_readnext_vec[]=
|
||||||
{
|
{
|
||||||
SEARCH_BIGGER, SEARCH_BIGGER, SEARCH_SMALLER, SEARCH_BIGGER, SEARCH_SMALLER,
|
SEARCH_BIGGER, SEARCH_BIGGER, SEARCH_SMALLER, SEARCH_BIGGER, SEARCH_SMALLER,
|
||||||
SEARCH_BIGGER, SEARCH_SMALLER, SEARCH_SMALLER
|
SEARCH_BIGGER, SEARCH_SMALLER, SEARCH_SMALLER
|
||||||
|
@ -42,8 +42,7 @@ static uint rnd(uint max_value);
|
|||||||
static void fix_length(uchar *record,uint length);
|
static void fix_length(uchar *record,uint length);
|
||||||
static void put_blob_in_record(char *blob_pos,char **blob_buffer,
|
static void put_blob_in_record(char *blob_pos,char **blob_buffer,
|
||||||
ulong *length);
|
ulong *length);
|
||||||
static void copy_key(struct st_maria_info *info,uint inx,
|
static void copy_key(MARIA_HA *info, uint inx, uchar *record, uchar *key);
|
||||||
uchar *record,uchar *key);
|
|
||||||
|
|
||||||
static int verbose=0,testflag=0,
|
static int verbose=0,testflag=0,
|
||||||
first_key=0,async_io=0,pagecacheing=0,write_cacheing=0,locking=0,
|
first_key=0,async_io=0,pagecacheing=0,write_cacheing=0,locking=0,
|
||||||
@ -300,8 +299,6 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (testflag == 2)
|
|
||||||
goto end;
|
|
||||||
|
|
||||||
if (write_cacheing)
|
if (write_cacheing)
|
||||||
{
|
{
|
||||||
@ -311,6 +308,10 @@ int main(int argc, char *argv[])
|
|||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (testflag == 2)
|
||||||
|
goto end;
|
||||||
|
|
||||||
#ifdef REMOVE_WHEN_WE_HAVE_RESIZE
|
#ifdef REMOVE_WHEN_WE_HAVE_RESIZE
|
||||||
if (pagecacheing)
|
if (pagecacheing)
|
||||||
resize_pagecache(maria_pagecache, maria_block_size,
|
resize_pagecache(maria_pagecache, maria_block_size,
|
||||||
@ -453,7 +454,7 @@ int main(int argc, char *argv[])
|
|||||||
info.recpos= maria_position(file);
|
info.recpos= maria_position(file);
|
||||||
int skr=maria_rnext(file,read_record2,0);
|
int skr=maria_rnext(file,read_record2,0);
|
||||||
if ((skr && my_errno != HA_ERR_END_OF_FILE) ||
|
if ((skr && my_errno != HA_ERR_END_OF_FILE) ||
|
||||||
maria_rprev(file,read_record2,-1) ||
|
maria_rprev(file,read_record2,0) ||
|
||||||
memcmp(read_record,read_record2,reclength) != 0 ||
|
memcmp(read_record,read_record2,reclength) != 0 ||
|
||||||
info.recpos != maria_position(file))
|
info.recpos != maria_position(file))
|
||||||
{
|
{
|
||||||
@ -872,7 +873,7 @@ int main(int argc, char *argv[])
|
|||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
opt_delete++;
|
opt_delete++;
|
||||||
#if 0
|
#if TO_BE_REMOVED
|
||||||
/
|
/
|
||||||
/*
|
/*
|
||||||
179 is ok, 180 causes a difference between runtime and log-applying.
|
179 is ok, 180 causes a difference between runtime and log-applying.
|
||||||
|
@ -107,14 +107,14 @@ do
|
|||||||
table=`echo $prog | sed -e 's;.*ma_\(test[0-9]\).*;\1;' `
|
table=`echo $prog | sed -e 's;.*ma_\(test[0-9]\).*;\1;' `
|
||||||
$maria_path/maria_chk -dvv $table | grep -v "Creation time:"> $tmp/maria_chk_message.good.txt 2>&1
|
$maria_path/maria_chk -dvv $table | grep -v "Creation time:"> $tmp/maria_chk_message.good.txt 2>&1
|
||||||
checksum=`$maria_path/maria_chk -dss $table`
|
checksum=`$maria_path/maria_chk -dss $table`
|
||||||
mv $table.MAD $tmp/$table.MAD.good
|
mv $table.MAD $tmp/$table-good.MAD
|
||||||
rm $table.MAI
|
mv $table.MAI $tmp/$table-good.MAI
|
||||||
apply_log "shouldnotchangelog"
|
apply_log "shouldnotchangelog"
|
||||||
cmp $table.MAD $tmp/$table.MAD.good
|
cmp $table.MAD $tmp/$table-good.MAD
|
||||||
check_table_is_same
|
check_table_is_same
|
||||||
echo "testing idempotency"
|
echo "testing idempotency"
|
||||||
apply_log "shouldnotchangelog"
|
apply_log "shouldnotchangelog"
|
||||||
cmp $table.MAD $tmp/$table.MAD.good
|
cmp $table.MAD $tmp/$table-good.MAD
|
||||||
check_table_is_same
|
check_table_is_same
|
||||||
shift
|
shift
|
||||||
done
|
done
|
||||||
@ -145,8 +145,8 @@ do
|
|||||||
table=`echo $prog | sed -e 's;.*ma_\(test[0-9]\).*;\1;' `
|
table=`echo $prog | sed -e 's;.*ma_\(test[0-9]\).*;\1;' `
|
||||||
$maria_path/maria_chk -dvv $table | grep -v "Creation time:"> $tmp/maria_chk_message.good.txt 2>&1
|
$maria_path/maria_chk -dvv $table | grep -v "Creation time:"> $tmp/maria_chk_message.good.txt 2>&1
|
||||||
checksum=`$maria_path/maria_chk -dss $table`
|
checksum=`$maria_path/maria_chk -dss $table`
|
||||||
mv $table.MAD $tmp/$table.MAD.good
|
mv $table.MAD $tmp/$table-good.MAD
|
||||||
rm $table.MAI
|
mv $table.MAI $tmp/$table-good.MAI
|
||||||
rm maria_log.* maria_log_control
|
rm maria_log.* maria_log_control
|
||||||
echo "TEST WITH $prog $abort_run_args$test_undo (additional aborted work)"
|
echo "TEST WITH $prog $abort_run_args$test_undo (additional aborted work)"
|
||||||
$maria_path/$prog $abort_run_args$test_undo
|
$maria_path/$prog $abort_run_args$test_undo
|
||||||
|
@ -39,36 +39,36 @@ applying log
|
|||||||
Differences in maria_chk -dvv, recovery not yet perfect !
|
Differences in maria_chk -dvv, recovery not yet perfect !
|
||||||
========DIFF START=======
|
========DIFF START=======
|
||||||
11c11
|
11c11
|
||||||
< Datafile length: 90112 Keyfile length: 204800
|
< Datafile length: 114688 Keyfile length: 204800
|
||||||
---
|
---
|
||||||
> Datafile length: 90112 Keyfile length: 8192
|
> Datafile length: 114688 Keyfile length: 8192
|
||||||
========DIFF END=======
|
========DIFF END=======
|
||||||
testing idempotency
|
testing idempotency
|
||||||
applying log
|
applying log
|
||||||
Differences in maria_chk -dvv, recovery not yet perfect !
|
Differences in maria_chk -dvv, recovery not yet perfect !
|
||||||
========DIFF START=======
|
========DIFF START=======
|
||||||
11c11
|
11c11
|
||||||
< Datafile length: 90112 Keyfile length: 204800
|
< Datafile length: 114688 Keyfile length: 204800
|
||||||
---
|
---
|
||||||
> Datafile length: 90112 Keyfile length: 8192
|
> Datafile length: 114688 Keyfile length: 8192
|
||||||
========DIFF END=======
|
========DIFF END=======
|
||||||
TEST WITH ma_test2 -s -M -T -c -b
|
TEST WITH ma_test2 -s -M -T -c -b
|
||||||
applying log
|
applying log
|
||||||
Differences in maria_chk -dvv, recovery not yet perfect !
|
Differences in maria_chk -dvv, recovery not yet perfect !
|
||||||
========DIFF START=======
|
========DIFF START=======
|
||||||
11c11
|
11c11
|
||||||
< Datafile length: 81920 Keyfile length: 172032
|
< Datafile length: 114688 Keyfile length: 155648
|
||||||
---
|
---
|
||||||
> Datafile length: 81920 Keyfile length: 8192
|
> Datafile length: 114688 Keyfile length: 8192
|
||||||
========DIFF END=======
|
========DIFF END=======
|
||||||
testing idempotency
|
testing idempotency
|
||||||
applying log
|
applying log
|
||||||
Differences in maria_chk -dvv, recovery not yet perfect !
|
Differences in maria_chk -dvv, recovery not yet perfect !
|
||||||
========DIFF START=======
|
========DIFF START=======
|
||||||
11c11
|
11c11
|
||||||
< Datafile length: 81920 Keyfile length: 172032
|
< Datafile length: 114688 Keyfile length: 155648
|
||||||
---
|
---
|
||||||
> Datafile length: 81920 Keyfile length: 8192
|
> Datafile length: 114688 Keyfile length: 8192
|
||||||
========DIFF END=======
|
========DIFF END=======
|
||||||
Testing the REDO AND UNDO PHASE
|
Testing the REDO AND UNDO PHASE
|
||||||
TEST WITH ma_test1 -s -M -T -c -N --testflag=1 (commit at end)
|
TEST WITH ma_test1 -s -M -T -c -N --testflag=1 (commit at end)
|
||||||
@ -218,7 +218,7 @@ Differences in maria_chk -dvv, recovery not yet perfect !
|
|||||||
11c11
|
11c11
|
||||||
< Datafile length: 8192 Keyfile length: 8192
|
< Datafile length: 8192 Keyfile length: 8192
|
||||||
---
|
---
|
||||||
> Datafile length: 90112 Keyfile length: 204800
|
> Datafile length: 114688 Keyfile length: 204800
|
||||||
========DIFF END=======
|
========DIFF END=======
|
||||||
testing idempotency
|
testing idempotency
|
||||||
applying log
|
applying log
|
||||||
@ -231,7 +231,7 @@ Differences in maria_chk -dvv, recovery not yet perfect !
|
|||||||
11c11
|
11c11
|
||||||
< Datafile length: 8192 Keyfile length: 8192
|
< Datafile length: 8192 Keyfile length: 8192
|
||||||
---
|
---
|
||||||
> Datafile length: 90112 Keyfile length: 204800
|
> Datafile length: 114688 Keyfile length: 204800
|
||||||
========DIFF END=======
|
========DIFF END=======
|
||||||
testing applying of CLRs to recreate table
|
testing applying of CLRs to recreate table
|
||||||
applying log
|
applying log
|
||||||
@ -244,7 +244,7 @@ Differences in maria_chk -dvv, recovery not yet perfect !
|
|||||||
11c11
|
11c11
|
||||||
< Datafile length: 8192 Keyfile length: 8192
|
< Datafile length: 8192 Keyfile length: 8192
|
||||||
---
|
---
|
||||||
> Datafile length: 90112 Keyfile length: 8192
|
> Datafile length: 114688 Keyfile length: 8192
|
||||||
========DIFF END=======
|
========DIFF END=======
|
||||||
TEST WITH ma_test1 -s -M -T -c -N --testflag=1 (commit at end)
|
TEST WITH ma_test1 -s -M -T -c -N --testflag=1 (commit at end)
|
||||||
TEST WITH ma_test1 -s -M -T -c -N --testflag=2 --test-undo=2 (additional aborted work)
|
TEST WITH ma_test1 -s -M -T -c -N --testflag=2 --test-undo=2 (additional aborted work)
|
||||||
@ -393,7 +393,7 @@ Differences in maria_chk -dvv, recovery not yet perfect !
|
|||||||
11c11
|
11c11
|
||||||
< Datafile length: 8192 Keyfile length: 8192
|
< Datafile length: 8192 Keyfile length: 8192
|
||||||
---
|
---
|
||||||
> Datafile length: 90112 Keyfile length: 204800
|
> Datafile length: 114688 Keyfile length: 204800
|
||||||
========DIFF END=======
|
========DIFF END=======
|
||||||
testing idempotency
|
testing idempotency
|
||||||
applying log
|
applying log
|
||||||
@ -406,7 +406,7 @@ Differences in maria_chk -dvv, recovery not yet perfect !
|
|||||||
11c11
|
11c11
|
||||||
< Datafile length: 8192 Keyfile length: 8192
|
< Datafile length: 8192 Keyfile length: 8192
|
||||||
---
|
---
|
||||||
> Datafile length: 90112 Keyfile length: 204800
|
> Datafile length: 114688 Keyfile length: 204800
|
||||||
========DIFF END=======
|
========DIFF END=======
|
||||||
testing applying of CLRs to recreate table
|
testing applying of CLRs to recreate table
|
||||||
applying log
|
applying log
|
||||||
@ -419,7 +419,7 @@ Differences in maria_chk -dvv, recovery not yet perfect !
|
|||||||
11c11
|
11c11
|
||||||
< Datafile length: 8192 Keyfile length: 8192
|
< Datafile length: 8192 Keyfile length: 8192
|
||||||
---
|
---
|
||||||
> Datafile length: 90112 Keyfile length: 8192
|
> Datafile length: 114688 Keyfile length: 8192
|
||||||
========DIFF END=======
|
========DIFF END=======
|
||||||
TEST WITH ma_test1 -s -M -T -c -N --testflag=1 (commit at end)
|
TEST WITH ma_test1 -s -M -T -c -N --testflag=1 (commit at end)
|
||||||
TEST WITH ma_test1 -s -M -T -c -N --testflag=2 --test-undo=3 (additional aborted work)
|
TEST WITH ma_test1 -s -M -T -c -N --testflag=2 --test-undo=3 (additional aborted work)
|
||||||
@ -568,7 +568,7 @@ Differences in maria_chk -dvv, recovery not yet perfect !
|
|||||||
11c11
|
11c11
|
||||||
< Datafile length: 8192 Keyfile length: 8192
|
< Datafile length: 8192 Keyfile length: 8192
|
||||||
---
|
---
|
||||||
> Datafile length: 90112 Keyfile length: 204800
|
> Datafile length: 114688 Keyfile length: 204800
|
||||||
========DIFF END=======
|
========DIFF END=======
|
||||||
testing idempotency
|
testing idempotency
|
||||||
applying log
|
applying log
|
||||||
@ -581,7 +581,7 @@ Differences in maria_chk -dvv, recovery not yet perfect !
|
|||||||
11c11
|
11c11
|
||||||
< Datafile length: 8192 Keyfile length: 8192
|
< Datafile length: 8192 Keyfile length: 8192
|
||||||
---
|
---
|
||||||
> Datafile length: 90112 Keyfile length: 204800
|
> Datafile length: 114688 Keyfile length: 204800
|
||||||
========DIFF END=======
|
========DIFF END=======
|
||||||
testing applying of CLRs to recreate table
|
testing applying of CLRs to recreate table
|
||||||
applying log
|
applying log
|
||||||
@ -594,7 +594,7 @@ Differences in maria_chk -dvv, recovery not yet perfect !
|
|||||||
11c11
|
11c11
|
||||||
< Datafile length: 8192 Keyfile length: 8192
|
< Datafile length: 8192 Keyfile length: 8192
|
||||||
---
|
---
|
||||||
> Datafile length: 90112 Keyfile length: 8192
|
> Datafile length: 114688 Keyfile length: 8192
|
||||||
========DIFF END=======
|
========DIFF END=======
|
||||||
TEST WITH ma_test1 -s -M -T -c -N -b --testflag=1 (commit at end)
|
TEST WITH ma_test1 -s -M -T -c -N -b --testflag=1 (commit at end)
|
||||||
TEST WITH ma_test1 -s -M -T -c -N -b --testflag=2 --test-undo=1 (additional aborted work)
|
TEST WITH ma_test1 -s -M -T -c -N -b --testflag=2 --test-undo=1 (additional aborted work)
|
||||||
@ -743,7 +743,7 @@ Differences in maria_chk -dvv, recovery not yet perfect !
|
|||||||
11c11
|
11c11
|
||||||
< Datafile length: 8192 Keyfile length: 8192
|
< Datafile length: 8192 Keyfile length: 8192
|
||||||
---
|
---
|
||||||
> Datafile length: 81920 Keyfile length: 212992
|
> Datafile length: 114688 Keyfile length: 212992
|
||||||
========DIFF END=======
|
========DIFF END=======
|
||||||
testing idempotency
|
testing idempotency
|
||||||
applying log
|
applying log
|
||||||
@ -756,7 +756,7 @@ Differences in maria_chk -dvv, recovery not yet perfect !
|
|||||||
11c11
|
11c11
|
||||||
< Datafile length: 8192 Keyfile length: 8192
|
< Datafile length: 8192 Keyfile length: 8192
|
||||||
---
|
---
|
||||||
> Datafile length: 81920 Keyfile length: 212992
|
> Datafile length: 114688 Keyfile length: 212992
|
||||||
========DIFF END=======
|
========DIFF END=======
|
||||||
testing applying of CLRs to recreate table
|
testing applying of CLRs to recreate table
|
||||||
applying log
|
applying log
|
||||||
@ -769,7 +769,7 @@ Differences in maria_chk -dvv, recovery not yet perfect !
|
|||||||
11c11
|
11c11
|
||||||
< Datafile length: 8192 Keyfile length: 8192
|
< Datafile length: 8192 Keyfile length: 8192
|
||||||
---
|
---
|
||||||
> Datafile length: 81920 Keyfile length: 8192
|
> Datafile length: 114688 Keyfile length: 8192
|
||||||
========DIFF END=======
|
========DIFF END=======
|
||||||
TEST WITH ma_test1 -s -M -T -c -N -b --testflag=1 (commit at end)
|
TEST WITH ma_test1 -s -M -T -c -N -b --testflag=1 (commit at end)
|
||||||
TEST WITH ma_test1 -s -M -T -c -N -b --testflag=2 --test-undo=2 (additional aborted work)
|
TEST WITH ma_test1 -s -M -T -c -N -b --testflag=2 --test-undo=2 (additional aborted work)
|
||||||
@ -918,7 +918,7 @@ Differences in maria_chk -dvv, recovery not yet perfect !
|
|||||||
11c11
|
11c11
|
||||||
< Datafile length: 8192 Keyfile length: 8192
|
< Datafile length: 8192 Keyfile length: 8192
|
||||||
---
|
---
|
||||||
> Datafile length: 81920 Keyfile length: 212992
|
> Datafile length: 114688 Keyfile length: 212992
|
||||||
========DIFF END=======
|
========DIFF END=======
|
||||||
testing idempotency
|
testing idempotency
|
||||||
applying log
|
applying log
|
||||||
@ -931,7 +931,7 @@ Differences in maria_chk -dvv, recovery not yet perfect !
|
|||||||
11c11
|
11c11
|
||||||
< Datafile length: 8192 Keyfile length: 8192
|
< Datafile length: 8192 Keyfile length: 8192
|
||||||
---
|
---
|
||||||
> Datafile length: 81920 Keyfile length: 212992
|
> Datafile length: 114688 Keyfile length: 212992
|
||||||
========DIFF END=======
|
========DIFF END=======
|
||||||
testing applying of CLRs to recreate table
|
testing applying of CLRs to recreate table
|
||||||
applying log
|
applying log
|
||||||
@ -944,7 +944,7 @@ Differences in maria_chk -dvv, recovery not yet perfect !
|
|||||||
11c11
|
11c11
|
||||||
< Datafile length: 8192 Keyfile length: 8192
|
< Datafile length: 8192 Keyfile length: 8192
|
||||||
---
|
---
|
||||||
> Datafile length: 81920 Keyfile length: 8192
|
> Datafile length: 114688 Keyfile length: 8192
|
||||||
========DIFF END=======
|
========DIFF END=======
|
||||||
TEST WITH ma_test1 -s -M -T -c -N -b --testflag=1 (commit at end)
|
TEST WITH ma_test1 -s -M -T -c -N -b --testflag=1 (commit at end)
|
||||||
TEST WITH ma_test1 -s -M -T -c -N -b --testflag=2 --test-undo=3 (additional aborted work)
|
TEST WITH ma_test1 -s -M -T -c -N -b --testflag=2 --test-undo=3 (additional aborted work)
|
||||||
@ -1093,7 +1093,7 @@ Differences in maria_chk -dvv, recovery not yet perfect !
|
|||||||
11c11
|
11c11
|
||||||
< Datafile length: 8192 Keyfile length: 8192
|
< Datafile length: 8192 Keyfile length: 8192
|
||||||
---
|
---
|
||||||
> Datafile length: 81920 Keyfile length: 212992
|
> Datafile length: 114688 Keyfile length: 212992
|
||||||
========DIFF END=======
|
========DIFF END=======
|
||||||
testing idempotency
|
testing idempotency
|
||||||
applying log
|
applying log
|
||||||
@ -1106,7 +1106,7 @@ Differences in maria_chk -dvv, recovery not yet perfect !
|
|||||||
11c11
|
11c11
|
||||||
< Datafile length: 8192 Keyfile length: 8192
|
< Datafile length: 8192 Keyfile length: 8192
|
||||||
---
|
---
|
||||||
> Datafile length: 81920 Keyfile length: 212992
|
> Datafile length: 114688 Keyfile length: 212992
|
||||||
========DIFF END=======
|
========DIFF END=======
|
||||||
testing applying of CLRs to recreate table
|
testing applying of CLRs to recreate table
|
||||||
applying log
|
applying log
|
||||||
@ -1119,5 +1119,5 @@ Differences in maria_chk -dvv, recovery not yet perfect !
|
|||||||
11c11
|
11c11
|
||||||
< Datafile length: 8192 Keyfile length: 8192
|
< Datafile length: 8192 Keyfile length: 8192
|
||||||
---
|
---
|
||||||
> Datafile length: 81920 Keyfile length: 8192
|
> Datafile length: 114688 Keyfile length: 8192
|
||||||
========DIFF END=======
|
========DIFF END=======
|
||||||
|
@ -30,9 +30,9 @@ static int w_search(MARIA_HA *info,MARIA_KEYDEF *keyinfo,
|
|||||||
static int _ma_balance_page(MARIA_HA *info,MARIA_KEYDEF *keyinfo,uchar *key,
|
static int _ma_balance_page(MARIA_HA *info,MARIA_KEYDEF *keyinfo,uchar *key,
|
||||||
uchar *curr_buff,uchar *father_buff,
|
uchar *curr_buff,uchar *father_buff,
|
||||||
uchar *father_keypos,my_off_t father_page);
|
uchar *father_keypos,my_off_t father_page);
|
||||||
static uchar *_ma_find_last_pos(MARIA_KEYDEF *keyinfo, uchar *page,
|
static uchar *_ma_find_last_pos(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
|
||||||
uchar *key, uint *return_key_length,
|
uchar *page, uchar *key,
|
||||||
uchar **after_key);
|
uint *return_key_length, uchar **after_key);
|
||||||
int _ma_ck_write_tree(register MARIA_HA *info, uint keynr,uchar *key,
|
int _ma_ck_write_tree(register MARIA_HA *info, uint keynr,uchar *key,
|
||||||
uint key_length);
|
uint key_length);
|
||||||
int _ma_ck_write_btree(register MARIA_HA *info, uint keynr,uchar *key,
|
int _ma_ck_write_btree(register MARIA_HA *info, uint keynr,uchar *key,
|
||||||
@ -115,7 +115,7 @@ int maria_write(MARIA_HA *info, uchar *record)
|
|||||||
*/
|
*/
|
||||||
if ((filepos= (*share->write_record_init)(info, record)) ==
|
if ((filepos= (*share->write_record_init)(info, record)) ==
|
||||||
HA_OFFSET_ERROR)
|
HA_OFFSET_ERROR)
|
||||||
goto err2;
|
goto err2;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Write all keys to indextree */
|
/* Write all keys to indextree */
|
||||||
@ -280,6 +280,7 @@ err:
|
|||||||
my_errno=save_errno;
|
my_errno=save_errno;
|
||||||
err2:
|
err2:
|
||||||
save_errno=my_errno;
|
save_errno=my_errno;
|
||||||
|
DBUG_ASSERT(save_errno);
|
||||||
DBUG_PRINT("error", ("got error: %d", save_errno));
|
DBUG_PRINT("error", ("got error: %d", save_errno));
|
||||||
VOID(_ma_writeinfo(info,WRITEINFO_UPDATE_KEYFILE));
|
VOID(_ma_writeinfo(info,WRITEINFO_UPDATE_KEYFILE));
|
||||||
allow_break(); /* Allow SIGHUP & SIGINT */
|
allow_break(); /* Allow SIGHUP & SIGINT */
|
||||||
@ -297,10 +298,7 @@ int _ma_ck_write(MARIA_HA *info, uint keynr, uchar *key, uint key_length)
|
|||||||
{
|
{
|
||||||
DBUG_RETURN(_ma_ck_write_tree(info, keynr, key, key_length));
|
DBUG_RETURN(_ma_ck_write_tree(info, keynr, key, key_length));
|
||||||
}
|
}
|
||||||
else
|
DBUG_RETURN(_ma_ck_write_btree(info, keynr, key, key_length));
|
||||||
{
|
|
||||||
DBUG_RETURN(_ma_ck_write_btree(info, keynr, key, key_length));
|
|
||||||
}
|
|
||||||
} /* _ma_ck_write */
|
} /* _ma_ck_write */
|
||||||
|
|
||||||
|
|
||||||
@ -369,12 +367,18 @@ int _ma_enlarge_root(MARIA_HA *info, MARIA_KEYDEF *keyinfo, uchar *key,
|
|||||||
DBUG_ENTER("_ma_enlarge_root");
|
DBUG_ENTER("_ma_enlarge_root");
|
||||||
|
|
||||||
nod_flag= (*root != HA_OFFSET_ERROR) ? share->base.key_reflength : 0;
|
nod_flag= (*root != HA_OFFSET_ERROR) ? share->base.key_reflength : 0;
|
||||||
_ma_kpointer(info,info->buff+2,*root); /* if nod */
|
/* Store pointer to prev page if nod */
|
||||||
|
_ma_kpointer(info, info->buff + info->s->keypage_header, *root);
|
||||||
t_length=(*keyinfo->pack_key)(keyinfo,nod_flag,(uchar*) 0,
|
t_length=(*keyinfo->pack_key)(keyinfo,nod_flag,(uchar*) 0,
|
||||||
(uchar*) 0, (uchar*) 0, key,&s_temp);
|
(uchar*) 0, (uchar*) 0, key,&s_temp);
|
||||||
maria_putint(info->buff,t_length+2+nod_flag,nod_flag);
|
|
||||||
(*keyinfo->store_key)(keyinfo,info->buff+2+nod_flag,&s_temp);
|
_ma_store_keynr(info, info->buff, (keyinfo - info->s->keyinfo));
|
||||||
info->keyread_buff_used=info->page_changed=1; /* info->buff is used */
|
_ma_store_page_used(info, info->buff, info->s->keypage_header +
|
||||||
|
t_length + nod_flag, nod_flag);
|
||||||
|
(*keyinfo->store_key)(keyinfo, info->buff + info->s->keypage_header +
|
||||||
|
nod_flag, &s_temp);
|
||||||
|
/* Mark that info->buff was used */
|
||||||
|
info->keyread_buff_used= info->page_changed= 1;
|
||||||
if ((*root= _ma_new(info,keyinfo,DFLT_INIT_HITS)) == HA_OFFSET_ERROR ||
|
if ((*root= _ma_new(info,keyinfo,DFLT_INIT_HITS)) == HA_OFFSET_ERROR ||
|
||||||
_ma_write_keypage(info,keyinfo,*root,DFLT_INIT_HITS,info->buff))
|
_ma_write_keypage(info,keyinfo,*root,DFLT_INIT_HITS,info->buff))
|
||||||
DBUG_RETURN(-1);
|
DBUG_RETURN(-1);
|
||||||
@ -382,12 +386,14 @@ int _ma_enlarge_root(MARIA_HA *info, MARIA_KEYDEF *keyinfo, uchar *key,
|
|||||||
} /* _ma_enlarge_root */
|
} /* _ma_enlarge_root */
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Search after a position for a key and store it there
|
Search after a position for a key and store it there
|
||||||
Returns -1 = error
|
|
||||||
0 = ok
|
@return
|
||||||
1 = key should be stored in higher tree
|
@retval -1 error
|
||||||
*/
|
@retval 0 ok
|
||||||
|
@retval 1 key should be stored in higher tree
|
||||||
|
*/
|
||||||
|
|
||||||
static int w_search(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
|
static int w_search(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
|
||||||
uint comp_flag, uchar *key, uint key_length, my_off_t page,
|
uint comp_flag, uchar *key, uint key_length, my_off_t page,
|
||||||
@ -412,7 +418,7 @@ static int w_search(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
|
|||||||
|
|
||||||
flag=(*keyinfo->bin_search)(info,keyinfo,temp_buff,key,search_key_length,
|
flag=(*keyinfo->bin_search)(info,keyinfo,temp_buff,key,search_key_length,
|
||||||
comp_flag, &keypos, keybuff, &was_last_key);
|
comp_flag, &keypos, keybuff, &was_last_key);
|
||||||
nod_flag= _ma_test_if_nod(temp_buff);
|
nod_flag= _ma_test_if_nod(info, temp_buff);
|
||||||
if (flag == 0)
|
if (flag == 0)
|
||||||
{
|
{
|
||||||
uint tmp_key_length;
|
uint tmp_key_length;
|
||||||
@ -445,7 +451,8 @@ static int w_search(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
|
|||||||
keyinfo=&info->s->ft2_keyinfo;
|
keyinfo=&info->s->ft2_keyinfo;
|
||||||
get_key_full_length_rdonly(off, key);
|
get_key_full_length_rdonly(off, key);
|
||||||
key+=off;
|
key+=off;
|
||||||
keypos-=keyinfo->keylength+nod_flag; /* we'll modify key entry 'in vivo' */
|
/* we'll modify key entry 'in vivo' */
|
||||||
|
keypos-= keyinfo->keylength + nod_flag;
|
||||||
error= _ma_ck_real_write_btree(info, keyinfo, key, 0,
|
error= _ma_ck_real_write_btree(info, keyinfo, key, 0,
|
||||||
&root, comp_flag);
|
&root, comp_flag);
|
||||||
_ma_dpointer(info, keypos+HA_FT_WLEN, root);
|
_ma_dpointer(info, keypos+HA_FT_WLEN, root);
|
||||||
@ -528,17 +535,17 @@ int _ma_insert(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
|
|||||||
DBUG_EXECUTE("key", _ma_print_key(DBUG_FILE,keyinfo->seg,key,
|
DBUG_EXECUTE("key", _ma_print_key(DBUG_FILE,keyinfo->seg,key,
|
||||||
USE_WHOLE_KEY););
|
USE_WHOLE_KEY););
|
||||||
|
|
||||||
nod_flag=_ma_test_if_nod(anc_buff);
|
_ma_get_used_and_nod(info, anc_buff, a_length, nod_flag);
|
||||||
a_length= maria_data_on_page(anc_buff);
|
|
||||||
endpos= anc_buff+ a_length;
|
endpos= anc_buff+ a_length;
|
||||||
prev_key=(key_pos == anc_buff+2+nod_flag ? (uchar*) 0 : key_buff);
|
prev_key= (key_pos == anc_buff + info->s->keypage_header + nod_flag ?
|
||||||
|
(uchar*) 0 : key_buff);
|
||||||
t_length=(*keyinfo->pack_key)(keyinfo,nod_flag,
|
t_length=(*keyinfo->pack_key)(keyinfo,nod_flag,
|
||||||
(key_pos == endpos ? (uchar*) 0 : key_pos),
|
(key_pos == endpos ? (uchar*) 0 : key_pos),
|
||||||
prev_key, prev_key,
|
prev_key, prev_key,
|
||||||
key,&s_temp);
|
key,&s_temp);
|
||||||
#ifndef DBUG_OFF
|
#ifndef DBUG_OFF
|
||||||
if (key_pos != anc_buff+2+nod_flag && (keyinfo->flag &
|
if (key_pos != anc_buff + info->s->keypage_header + nod_flag &&
|
||||||
(HA_BINARY_PACK_KEY | HA_PACK_KEY)))
|
(keyinfo->flag & (HA_BINARY_PACK_KEY | HA_PACK_KEY)))
|
||||||
{
|
{
|
||||||
DBUG_DUMP("prev_key",(uchar*) key_buff, _ma_keylength(keyinfo,key_buff));
|
DBUG_DUMP("prev_key",(uchar*) key_buff, _ma_keylength(keyinfo,key_buff));
|
||||||
}
|
}
|
||||||
@ -572,11 +579,11 @@ int _ma_insert(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
|
|||||||
}
|
}
|
||||||
(*keyinfo->store_key)(keyinfo,key_pos,&s_temp);
|
(*keyinfo->store_key)(keyinfo,key_pos,&s_temp);
|
||||||
a_length+=t_length;
|
a_length+=t_length;
|
||||||
maria_putint(anc_buff,a_length,nod_flag);
|
_ma_store_page_used(info, anc_buff, a_length, nod_flag);
|
||||||
if (a_length <= keyinfo->block_length)
|
if (a_length <= (uint) keyinfo->block_length - KEYPAGE_CHECKSUM_SIZE)
|
||||||
{
|
{
|
||||||
if (keyinfo->block_length - a_length < 32 &&
|
if (keyinfo->block_length - KEYPAGE_CHECKSUM_SIZE - a_length < 32 &&
|
||||||
keyinfo->flag & HA_FULLTEXT && key_pos == endpos &&
|
(keyinfo->flag & HA_FULLTEXT) && key_pos == endpos &&
|
||||||
info->s->base.key_reflength <= info->s->base.rec_reflength &&
|
info->s->base.key_reflength <= info->s->base.rec_reflength &&
|
||||||
info->s->options & (HA_OPTION_PACK_RECORD | HA_OPTION_COMPRESS_RECORD))
|
info->s->options & (HA_OPTION_PACK_RECORD | HA_OPTION_COMPRESS_RECORD))
|
||||||
{
|
{
|
||||||
@ -585,7 +592,7 @@ int _ma_insert(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
|
|||||||
Let's consider converting.
|
Let's consider converting.
|
||||||
We'll compare 'key' and the first key at anc_buff
|
We'll compare 'key' and the first key at anc_buff
|
||||||
*/
|
*/
|
||||||
uchar *a=key, *b=anc_buff+2+nod_flag;
|
uchar *a= key, *b= anc_buff + info->s->keypage_header + nod_flag;
|
||||||
uint alen, blen, ft2len=info->s->ft2_keyinfo.keylength;
|
uint alen, blen, ft2len=info->s->ft2_keyinfo.keylength;
|
||||||
/* the very first key on the page is always unpacked */
|
/* the very first key on the page is always unpacked */
|
||||||
DBUG_ASSERT((*b & 128) == 0);
|
DBUG_ASSERT((*b & 128) == 0);
|
||||||
@ -600,25 +607,28 @@ int _ma_insert(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
|
|||||||
ha_compare_text(keyinfo->seg->charset, (uchar*) a, alen,
|
ha_compare_text(keyinfo->seg->charset, (uchar*) a, alen,
|
||||||
(uchar*) b, blen, 0, 0) == 0)
|
(uchar*) b, blen, 0, 0) == 0)
|
||||||
{
|
{
|
||||||
/* yup. converting */
|
/* Yup. converting */
|
||||||
info->ft1_to_ft2=(DYNAMIC_ARRAY *)
|
info->ft1_to_ft2=(DYNAMIC_ARRAY *)
|
||||||
my_malloc(sizeof(DYNAMIC_ARRAY), MYF(MY_WME));
|
my_malloc(sizeof(DYNAMIC_ARRAY), MYF(MY_WME));
|
||||||
my_init_dynamic_array(info->ft1_to_ft2, ft2len, 300, 50);
|
my_init_dynamic_array(info->ft1_to_ft2, ft2len, 300, 50);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
now, adding all keys from the page to dynarray
|
Now, adding all keys from the page to dynarray
|
||||||
if the page is a leaf (if not keys will be deleted later)
|
if the page is a leaf (if not keys will be deleted later)
|
||||||
*/
|
*/
|
||||||
if (!nod_flag)
|
if (!nod_flag)
|
||||||
{
|
{
|
||||||
/* let's leave the first key on the page, though, because
|
/*
|
||||||
we cannot easily dispatch an empty page here */
|
Let's leave the first key on the page, though, because
|
||||||
|
we cannot easily dispatch an empty page here
|
||||||
|
*/
|
||||||
b+=blen+ft2len+2;
|
b+=blen+ft2len+2;
|
||||||
for (a=anc_buff+a_length ; b < a ; b+=ft2len+2)
|
for (a=anc_buff+a_length ; b < a ; b+=ft2len+2)
|
||||||
insert_dynamic(info->ft1_to_ft2, (char*) b);
|
insert_dynamic(info->ft1_to_ft2, (char*) b);
|
||||||
|
|
||||||
/* fixing the page's length - it contains only one key now */
|
/* fixing the page's length - it contains only one key now */
|
||||||
maria_putint(anc_buff,2+blen+ft2len+2,0);
|
_ma_store_page_used(info, anc_buff, info->s->keypage_header + blen +
|
||||||
|
ft2len + 2, 0);
|
||||||
}
|
}
|
||||||
/* the rest will be done when we're back from recursion */
|
/* the rest will be done when we're back from recursion */
|
||||||
}
|
}
|
||||||
@ -648,31 +658,33 @@ int _ma_split_page(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
|
|||||||
MARIA_KEY_PARAM s_temp;
|
MARIA_KEY_PARAM s_temp;
|
||||||
DBUG_ENTER("maria_split_page");
|
DBUG_ENTER("maria_split_page");
|
||||||
LINT_INIT(after_key);
|
LINT_INIT(after_key);
|
||||||
DBUG_DUMP("buff",(uchar*) buff,maria_data_on_page(buff));
|
DBUG_DUMP("buff", buff, _ma_get_page_used(info, buff));
|
||||||
|
|
||||||
if (info->s->keyinfo+info->lastinx == keyinfo)
|
if (info->s->keyinfo+info->lastinx == keyinfo)
|
||||||
info->page_changed=1; /* Info->buff is used */
|
info->page_changed=1; /* Info->buff is used */
|
||||||
info->keyread_buff_used=1;
|
info->keyread_buff_used=1;
|
||||||
nod_flag=_ma_test_if_nod(buff);
|
nod_flag=_ma_test_if_nod(info, buff);
|
||||||
key_ref_length=2+nod_flag;
|
key_ref_length= info->s->keypage_header + nod_flag;
|
||||||
if (insert_last_key)
|
if (insert_last_key)
|
||||||
key_pos= _ma_find_last_pos(keyinfo,buff,key_buff, &key_length, &after_key);
|
key_pos= _ma_find_last_pos(info, keyinfo, buff, key_buff, &key_length,
|
||||||
|
&after_key);
|
||||||
else
|
else
|
||||||
key_pos= _ma_find_half_pos(nod_flag,keyinfo,buff,key_buff, &key_length,
|
key_pos= _ma_find_half_pos(info, nod_flag, keyinfo, buff, key_buff,
|
||||||
&after_key);
|
&key_length, &after_key);
|
||||||
if (!key_pos)
|
if (!key_pos)
|
||||||
DBUG_RETURN(-1);
|
DBUG_RETURN(-1);
|
||||||
|
|
||||||
length=(uint) (key_pos-buff);
|
length=(uint) (key_pos-buff);
|
||||||
a_length= maria_data_on_page(buff);
|
a_length= _ma_get_page_used(info, buff);
|
||||||
maria_putint(buff,length,nod_flag);
|
_ma_store_page_used(info, buff, length, nod_flag);
|
||||||
|
|
||||||
key_pos=after_key;
|
key_pos=after_key;
|
||||||
if (nod_flag)
|
if (nod_flag)
|
||||||
{
|
{
|
||||||
DBUG_PRINT("test",("Splitting nod"));
|
DBUG_PRINT("test",("Splitting nod"));
|
||||||
pos=key_pos-nod_flag;
|
pos=key_pos-nod_flag;
|
||||||
memcpy((uchar*) info->buff+2,(uchar*) pos,(size_t) nod_flag);
|
memcpy((uchar*) info->buff + info->s->keypage_header, (uchar*) pos,
|
||||||
|
(size_t) nod_flag);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Move middle item to key and pointer to new page */
|
/* Move middle item to key and pointer to new page */
|
||||||
@ -691,8 +703,14 @@ int _ma_split_page(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
|
|||||||
memcpy((uchar*) info->buff+key_ref_length+t_length,(uchar*) key_pos,
|
memcpy((uchar*) info->buff+key_ref_length+t_length,(uchar*) key_pos,
|
||||||
(size_t) length);
|
(size_t) length);
|
||||||
(*keyinfo->store_key)(keyinfo,info->buff+key_ref_length,&s_temp);
|
(*keyinfo->store_key)(keyinfo,info->buff+key_ref_length,&s_temp);
|
||||||
maria_putint(info->buff,length+t_length+key_ref_length,nod_flag);
|
_ma_store_page_used(info, info->buff, length + t_length + key_ref_length,
|
||||||
|
nod_flag);
|
||||||
|
|
||||||
|
/* Copy key number */
|
||||||
|
info->buff[info->s->keypage_header - KEYPAGE_USED_SIZE - KEYPAGE_KEYID_SIZE -
|
||||||
|
KEYPAGE_FLAG_SIZE]=
|
||||||
|
buff[info->s->keypage_header - KEYPAGE_USED_SIZE - KEYPAGE_KEYID_SIZE -
|
||||||
|
KEYPAGE_FLAG_SIZE];
|
||||||
if (_ma_write_keypage(info,keyinfo,new_pos,DFLT_INIT_HITS,info->buff))
|
if (_ma_write_keypage(info,keyinfo,new_pos,DFLT_INIT_HITS,info->buff))
|
||||||
DBUG_RETURN(-1);
|
DBUG_RETURN(-1);
|
||||||
DBUG_DUMP("key",(uchar*) key, _ma_keylength(keyinfo,key));
|
DBUG_DUMP("key",(uchar*) key, _ma_keylength(keyinfo,key));
|
||||||
@ -700,25 +718,26 @@ int _ma_split_page(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
|
|||||||
} /* _ma_split_page */
|
} /* _ma_split_page */
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Calculate how to much to move to split a page in two
|
Calculate how to much to move to split a page in two
|
||||||
Returns pointer to start of key.
|
|
||||||
key will contain the key.
|
|
||||||
return_key_length will contain the length of key
|
|
||||||
after_key will contain the position to where the next key starts
|
|
||||||
*/
|
|
||||||
|
|
||||||
uchar *_ma_find_half_pos(uint nod_flag, MARIA_KEYDEF *keyinfo, uchar *page,
|
Returns pointer to start of key.
|
||||||
uchar *key, uint *return_key_length,
|
key will contain the key.
|
||||||
|
return_key_length will contain the length of key
|
||||||
|
after_key will contain the position to where the next key starts
|
||||||
|
*/
|
||||||
|
|
||||||
|
uchar *_ma_find_half_pos(MARIA_HA *info, uint nod_flag, MARIA_KEYDEF *keyinfo,
|
||||||
|
uchar *page, uchar *key, uint *return_key_length,
|
||||||
uchar **after_key)
|
uchar **after_key)
|
||||||
{
|
{
|
||||||
uint keys,length,key_ref_length;
|
uint keys,length,key_ref_length;
|
||||||
uchar *end,*lastpos;
|
uchar *end,*lastpos;
|
||||||
DBUG_ENTER("_ma_find_half_pos");
|
DBUG_ENTER("_ma_find_half_pos");
|
||||||
|
|
||||||
key_ref_length=2+nod_flag;
|
key_ref_length= info->s->keypage_header + nod_flag;
|
||||||
length= maria_data_on_page(page)-key_ref_length;
|
length= _ma_get_page_used(info, page) - key_ref_length;
|
||||||
page+=key_ref_length;
|
page+= key_ref_length; /* Point to first key */
|
||||||
if (!(keyinfo->flag &
|
if (!(keyinfo->flag &
|
||||||
(HA_PACK_KEY | HA_SPACE_PACK_USED | HA_VAR_LENGTH_KEY |
|
(HA_PACK_KEY | HA_SPACE_PACK_USED | HA_VAR_LENGTH_KEY |
|
||||||
HA_BINARY_PACK_KEY)))
|
HA_BINARY_PACK_KEY)))
|
||||||
@ -754,7 +773,8 @@ uchar *_ma_find_half_pos(uint nod_flag, MARIA_KEYDEF *keyinfo, uchar *page,
|
|||||||
key will contain the last key
|
key will contain the last key
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static uchar *_ma_find_last_pos(MARIA_KEYDEF *keyinfo, uchar *page,
|
static uchar *_ma_find_last_pos(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
|
||||||
|
uchar *page,
|
||||||
uchar *key, uint *return_key_length,
|
uchar *key, uint *return_key_length,
|
||||||
uchar **after_key)
|
uchar **after_key)
|
||||||
{
|
{
|
||||||
@ -763,8 +783,8 @@ static uchar *_ma_find_last_pos(MARIA_KEYDEF *keyinfo, uchar *page,
|
|||||||
uchar key_buff[HA_MAX_KEY_BUFF];
|
uchar key_buff[HA_MAX_KEY_BUFF];
|
||||||
DBUG_ENTER("_ma_find_last_pos");
|
DBUG_ENTER("_ma_find_last_pos");
|
||||||
|
|
||||||
key_ref_length=2;
|
key_ref_length= info->s->keypage_header;
|
||||||
length= maria_data_on_page(page)-key_ref_length;
|
length= _ma_get_page_used(info, page) - key_ref_length;
|
||||||
page+=key_ref_length;
|
page+=key_ref_length;
|
||||||
if (!(keyinfo->flag &
|
if (!(keyinfo->flag &
|
||||||
(HA_PACK_KEY | HA_SPACE_PACK_USED | HA_VAR_LENGTH_KEY |
|
(HA_PACK_KEY | HA_SPACE_PACK_USED | HA_VAR_LENGTH_KEY |
|
||||||
@ -821,15 +841,16 @@ static int _ma_balance_page(register MARIA_HA *info, MARIA_KEYDEF *keyinfo,
|
|||||||
DBUG_ENTER("_ma_balance_page");
|
DBUG_ENTER("_ma_balance_page");
|
||||||
|
|
||||||
k_length=keyinfo->keylength;
|
k_length=keyinfo->keylength;
|
||||||
father_length= maria_data_on_page(father_buff);
|
father_length= _ma_get_page_used(info, father_buff);
|
||||||
father_keylength=k_length+info->s->base.key_reflength;
|
father_keylength= k_length + info->s->base.key_reflength;
|
||||||
nod_flag=_ma_test_if_nod(curr_buff);
|
nod_flag=_ma_test_if_nod(info, curr_buff);
|
||||||
curr_keylength=k_length+nod_flag;
|
curr_keylength=k_length+nod_flag;
|
||||||
info->page_changed=1;
|
info->page_changed=1;
|
||||||
|
|
||||||
if ((father_key_pos != father_buff+father_length &&
|
if ((father_key_pos != father_buff+father_length &&
|
||||||
(info->state->records & 1)) ||
|
(info->state->records & 1)) ||
|
||||||
father_key_pos == father_buff+2+info->s->base.key_reflength)
|
father_key_pos == father_buff+ info->s->keypage_header +
|
||||||
|
info->s->base.key_reflength)
|
||||||
{
|
{
|
||||||
right=1;
|
right=1;
|
||||||
next_page= _ma_kpos(info->s->base.key_reflength,
|
next_page= _ma_kpos(info->s->base.key_reflength,
|
||||||
@ -849,42 +870,46 @@ static int _ma_balance_page(register MARIA_HA *info, MARIA_KEYDEF *keyinfo,
|
|||||||
|
|
||||||
if (!_ma_fetch_keypage(info,keyinfo,next_page,DFLT_INIT_HITS,info->buff,0))
|
if (!_ma_fetch_keypage(info,keyinfo,next_page,DFLT_INIT_HITS,info->buff,0))
|
||||||
goto err;
|
goto err;
|
||||||
DBUG_DUMP("next",(uchar*) info->buff,maria_data_on_page(info->buff));
|
DBUG_DUMP("next", info->buff, _ma_get_page_used(info, info->buff));
|
||||||
|
|
||||||
/* Test if there is room to share keys */
|
/* Test if there is room to share keys */
|
||||||
|
|
||||||
left_length= maria_data_on_page(curr_buff);
|
left_length= _ma_get_page_used(info, curr_buff);
|
||||||
right_length= maria_data_on_page(buff);
|
right_length= _ma_get_page_used(info, buff);
|
||||||
keys=(left_length+right_length-4-nod_flag*2)/curr_keylength;
|
keys= ((left_length+right_length-info->s->keypage_header*2-nod_flag*2)/
|
||||||
|
curr_keylength);
|
||||||
|
|
||||||
if ((right ? right_length : left_length) + curr_keylength <=
|
if ((right ? right_length : left_length) + curr_keylength <=
|
||||||
keyinfo->block_length)
|
(uint) keyinfo->block_length - KEYPAGE_CHECKSUM_SIZE)
|
||||||
{ /* Merge buffs */
|
{ /* Merge buffs */
|
||||||
new_left_length=2+nod_flag+(keys/2)*curr_keylength;
|
new_left_length= info->s->keypage_header+nod_flag+(keys/2)*curr_keylength;
|
||||||
new_right_length=2+nod_flag+((keys+1)/2)*curr_keylength;
|
new_right_length=info->s->keypage_header+nod_flag+(((keys+1)/2)*
|
||||||
maria_putint(curr_buff,new_left_length,nod_flag);
|
curr_keylength);
|
||||||
maria_putint(buff,new_right_length,nod_flag);
|
_ma_store_page_used(info, curr_buff,new_left_length,nod_flag);
|
||||||
|
_ma_store_page_used(info, buff,new_right_length,nod_flag);
|
||||||
|
|
||||||
if (left_length < new_left_length)
|
if (left_length < new_left_length)
|
||||||
{ /* Move keys buff -> leaf */
|
{ /* Move keys buff -> leaf */
|
||||||
pos=curr_buff+left_length;
|
pos=curr_buff+left_length;
|
||||||
memcpy((uchar*) pos,(uchar*) father_key_pos, (size_t) k_length);
|
memcpy(pos,father_key_pos, (size_t) k_length);
|
||||||
memcpy((uchar*) pos+k_length, (uchar*) buff+2,
|
memcpy(pos+k_length, buff + info->s->keypage_header,
|
||||||
(size_t) (length=new_left_length - left_length - k_length));
|
(size_t) (length=new_left_length - left_length - k_length));
|
||||||
pos=buff+2+length;
|
pos= buff + info->s->keypage_header + length;
|
||||||
memcpy((uchar*) father_key_pos,(uchar*) pos,(size_t) k_length);
|
memcpy(father_key_pos, pos, (size_t) k_length);
|
||||||
bmove((uchar*) buff+2,(uchar*) pos+k_length,new_right_length);
|
bmove(buff + info->s->keypage_header, pos + k_length, new_right_length);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{ /* Move keys -> buff */
|
{ /* Move keys -> buff */
|
||||||
|
|
||||||
bmove_upp((uchar*) buff+new_right_length,(uchar*) buff+right_length,
|
bmove_upp(buff + new_right_length, buff + right_length,
|
||||||
right_length-2);
|
right_length - info->s->keypage_header);
|
||||||
length=new_right_length-right_length-k_length;
|
length=new_right_length-right_length-k_length;
|
||||||
memcpy((uchar*) buff+2+length,father_key_pos,(size_t) k_length);
|
memcpy(buff + info->s->keypage_header + length, father_key_pos,
|
||||||
|
(size_t) k_length);
|
||||||
pos=curr_buff+new_left_length;
|
pos=curr_buff+new_left_length;
|
||||||
memcpy((uchar*) father_key_pos,(uchar*) pos,(size_t) k_length);
|
memcpy(father_key_pos, pos, (size_t) k_length);
|
||||||
memcpy((uchar*) buff+2,(uchar*) pos+k_length,(size_t) length);
|
memcpy(buff + info->s->keypage_header, pos+k_length,
|
||||||
|
(size_t) length);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_ma_write_keypage(info,keyinfo,next_page,DFLT_INIT_HITS,info->buff) ||
|
if (_ma_write_keypage(info,keyinfo,next_page,DFLT_INIT_HITS,info->buff) ||
|
||||||
@ -896,7 +921,13 @@ static int _ma_balance_page(register MARIA_HA *info, MARIA_KEYDEF *keyinfo,
|
|||||||
/* curr_buff[] and buff[] are full, lets split and make new nod */
|
/* curr_buff[] and buff[] are full, lets split and make new nod */
|
||||||
|
|
||||||
extra_buff=info->buff+info->s->base.max_key_block_length;
|
extra_buff=info->buff+info->s->base.max_key_block_length;
|
||||||
new_left_length=new_right_length=2+nod_flag+(keys+1)/3*curr_keylength;
|
new_left_length= new_right_length= (info->s->keypage_header + nod_flag +
|
||||||
|
(keys+1) / 3 * curr_keylength);
|
||||||
|
/*
|
||||||
|
5 is the minum number of keys we can have here. This comes from
|
||||||
|
the fact that each full page can store at least 2 keys and in this case
|
||||||
|
we have a 'split' key, ie 2+2+1 = 5
|
||||||
|
*/
|
||||||
if (keys == 5) /* Too few keys to balance */
|
if (keys == 5) /* Too few keys to balance */
|
||||||
new_left_length-=curr_keylength;
|
new_left_length-=curr_keylength;
|
||||||
extra_length=nod_flag+left_length+right_length-
|
extra_length=nod_flag+left_length+right_length-
|
||||||
@ -905,28 +936,37 @@ static int _ma_balance_page(register MARIA_HA *info, MARIA_KEYDEF *keyinfo,
|
|||||||
left_length, right_length,
|
left_length, right_length,
|
||||||
new_left_length, new_right_length,
|
new_left_length, new_right_length,
|
||||||
extra_length));
|
extra_length));
|
||||||
maria_putint(curr_buff,new_left_length,nod_flag);
|
_ma_store_page_used(info, curr_buff,new_left_length,nod_flag);
|
||||||
maria_putint(buff,new_right_length,nod_flag);
|
_ma_store_page_used(info, buff,new_right_length,nod_flag);
|
||||||
maria_putint(extra_buff,extra_length+2,nod_flag);
|
/* Copy key number */
|
||||||
|
bzero(extra_buff, info->s->keypage_header);
|
||||||
|
extra_buff[info->s->keypage_header - KEYPAGE_USED_SIZE - KEYPAGE_KEYID_SIZE -
|
||||||
|
KEYPAGE_FLAG_SIZE]=
|
||||||
|
buff[info->s->keypage_header - KEYPAGE_USED_SIZE - KEYPAGE_KEYID_SIZE -
|
||||||
|
KEYPAGE_FLAG_SIZE];
|
||||||
|
_ma_store_page_used(info, extra_buff, extra_length + info->s->keypage_header,
|
||||||
|
nod_flag);
|
||||||
|
|
||||||
/* move first largest keys to new page */
|
/* move first largest keys to new page */
|
||||||
pos=buff+right_length-extra_length;
|
pos=buff+right_length-extra_length;
|
||||||
memcpy((uchar*) extra_buff+2,pos,(size_t) extra_length);
|
memcpy(extra_buff + info->s->keypage_header, pos,
|
||||||
|
(size_t) extra_length);
|
||||||
/* Save new parting key */
|
/* Save new parting key */
|
||||||
memcpy(tmp_part_key, pos-k_length,k_length);
|
memcpy(tmp_part_key, pos-k_length,k_length);
|
||||||
/* Make place for new keys */
|
/* Make place for new keys */
|
||||||
bmove_upp((uchar*) buff+new_right_length,(uchar*) pos-k_length,
|
bmove_upp(buff+ new_right_length, pos - k_length,
|
||||||
right_length-extra_length-k_length-2);
|
right_length - extra_length - k_length - info->s->keypage_header);
|
||||||
/* Copy keys from left page */
|
/* Copy keys from left page */
|
||||||
pos= curr_buff+new_left_length;
|
pos= curr_buff+new_left_length;
|
||||||
memcpy((uchar*) buff+2,(uchar*) pos+k_length,
|
memcpy(buff + info->s->keypage_header, pos + k_length,
|
||||||
(size_t) (length=left_length-new_left_length-k_length));
|
(size_t) (length=left_length-new_left_length-k_length));
|
||||||
/* Copy old parting key */
|
/* Copy old parting key */
|
||||||
memcpy((uchar*) buff+2+length,father_key_pos,(size_t) k_length);
|
memcpy(buff + info->s->keypage_header + length,
|
||||||
|
father_key_pos, (size_t) k_length);
|
||||||
|
|
||||||
/* Move new parting keys up to caller */
|
/* Move new parting keys up to caller */
|
||||||
memcpy((uchar*) (right ? key : father_key_pos),pos,(size_t) k_length);
|
memcpy((right ? key : father_key_pos),pos,(size_t) k_length);
|
||||||
memcpy((uchar*) (right ? father_key_pos : key),tmp_part_key, k_length);
|
memcpy((right ? father_key_pos : key),tmp_part_key, k_length);
|
||||||
|
|
||||||
if ((new_pos= _ma_new(info,keyinfo,DFLT_INIT_HITS)) == HA_OFFSET_ERROR)
|
if ((new_pos= _ma_new(info,keyinfo,DFLT_INIT_HITS)) == HA_OFFSET_ERROR)
|
||||||
goto err;
|
goto err;
|
||||||
@ -973,7 +1013,7 @@ static int keys_compare(bulk_insert_param *param, uchar *key1, uchar *key2)
|
|||||||
{
|
{
|
||||||
uint not_used[2];
|
uint not_used[2];
|
||||||
return ha_key_cmp(param->info->s->keyinfo[param->keynr].seg,
|
return ha_key_cmp(param->info->s->keyinfo[param->keynr].seg,
|
||||||
(uchar*) key1, (uchar*) key2, USE_WHOLE_KEY, SEARCH_SAME,
|
key1, key2, USE_WHOLE_KEY, SEARCH_SAME,
|
||||||
not_used);
|
not_used);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -830,6 +830,9 @@ static int maria_chk(HA_CHECK *param, char *filename)
|
|||||||
case HA_ERR_OLD_FILE:
|
case HA_ERR_OLD_FILE:
|
||||||
_ma_check_print_error(param,"'%s' is a old type of MARIA-table", filename);
|
_ma_check_print_error(param,"'%s' is a old type of MARIA-table", filename);
|
||||||
break;
|
break;
|
||||||
|
case HA_ERR_NEW_FILE:
|
||||||
|
_ma_check_print_error(param,"'%s' uses new features not supported by this version of the MARIA library", filename);
|
||||||
|
break;
|
||||||
case HA_ERR_END_OF_FILE:
|
case HA_ERR_END_OF_FILE:
|
||||||
_ma_check_print_error(param,"Couldn't read complete header from '%s'", filename);
|
_ma_check_print_error(param,"Couldn't read complete header from '%s'", filename);
|
||||||
break;
|
break;
|
||||||
@ -1302,6 +1305,8 @@ static void descript(HA_CHECK *param, register MARIA_HA *info, char *name)
|
|||||||
if (share->options & HA_OPTION_DELAY_KEY_WRITE)
|
if (share->options & HA_OPTION_DELAY_KEY_WRITE)
|
||||||
printf("Keys are only flushed at close\n");
|
printf("Keys are only flushed at close\n");
|
||||||
|
|
||||||
|
if (share->options & HA_OPTION_PAGE_CHECKSUM)
|
||||||
|
printf("Page checksums are used\n");
|
||||||
}
|
}
|
||||||
printf("Data records: %16s Deleted blocks: %18s\n",
|
printf("Data records: %16s Deleted blocks: %18s\n",
|
||||||
llstr(info->state->records,llbuff),llstr(info->state->del,llbuff2));
|
llstr(info->state->records,llbuff),llstr(info->state->del,llbuff2));
|
||||||
@ -1381,7 +1386,7 @@ static void descript(HA_CHECK *param, register MARIA_HA *info, char *name)
|
|||||||
else
|
else
|
||||||
buff[0]=0;
|
buff[0]=0;
|
||||||
if (param->testflag & T_VERBOSE)
|
if (param->testflag & T_VERBOSE)
|
||||||
printf("%11lu %12s %10d",
|
printf("%11.0g %12s %10d",
|
||||||
share->state.rec_per_key_part[keyseg_nr++],
|
share->state.rec_per_key_part[keyseg_nr++],
|
||||||
buff,keyinfo->block_length);
|
buff,keyinfo->block_length);
|
||||||
VOID(putchar('\n'));
|
VOID(putchar('\n'));
|
||||||
@ -1402,7 +1407,7 @@ static void descript(HA_CHECK *param, register MARIA_HA *info, char *name)
|
|||||||
printf(" %-6ld%-3d %-21s",
|
printf(" %-6ld%-3d %-21s",
|
||||||
(long) keyseg->start+1,keyseg->length,buff);
|
(long) keyseg->start+1,keyseg->length,buff);
|
||||||
if (param->testflag & T_VERBOSE)
|
if (param->testflag & T_VERBOSE)
|
||||||
printf("%11lu", share->state.rec_per_key_part[keyseg_nr++]);
|
printf("%11.0g", share->state.rec_per_key_part[keyseg_nr++]);
|
||||||
VOID(putchar('\n'));
|
VOID(putchar('\n'));
|
||||||
}
|
}
|
||||||
keyseg++;
|
keyseg++;
|
||||||
@ -1681,7 +1686,7 @@ static int sort_record_index(MARIA_SORT_PARAM *sort_param,MARIA_HA *info,
|
|||||||
HA_CHECK *param=sort_info->param;
|
HA_CHECK *param=sort_info->param;
|
||||||
DBUG_ENTER("sort_record_index");
|
DBUG_ENTER("sort_record_index");
|
||||||
|
|
||||||
nod_flag=_ma_test_if_nod(buff);
|
nod_flag=_ma_test_if_nod(info, buff);
|
||||||
temp_buff=0;
|
temp_buff=0;
|
||||||
|
|
||||||
if (nod_flag)
|
if (nod_flag)
|
||||||
@ -1692,9 +1697,9 @@ static int sort_record_index(MARIA_SORT_PARAM *sort_param,MARIA_HA *info,
|
|||||||
DBUG_RETURN(-1);
|
DBUG_RETURN(-1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
used_length= maria_data_on_page(buff);
|
used_length= _ma_get_page_used(info, buff);
|
||||||
keypos=buff+2+nod_flag;
|
keypos= buff + info->s->keypage_header + nod_flag;
|
||||||
endpos=buff+used_length;
|
endpos= buff + used_length;
|
||||||
for ( ;; )
|
for ( ;; )
|
||||||
{
|
{
|
||||||
_sanity(__FILE__,__LINE__);
|
_sanity(__FILE__,__LINE__);
|
||||||
|
@ -25,13 +25,16 @@
|
|||||||
#else
|
#else
|
||||||
#include <my_no_pthread.h>
|
#include <my_no_pthread.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "ma_loghandler.h"
|
#include "ma_loghandler.h"
|
||||||
#include "ma_control_file.h"
|
#include "ma_control_file.h"
|
||||||
|
|
||||||
|
/* For testing recovery */
|
||||||
|
#define IDENTICAL_PAGES_AFTER_RECOVERY 1
|
||||||
|
/* Do extra sanity checking */
|
||||||
|
#define SANITY_CHECKS 1
|
||||||
|
|
||||||
#define MAX_NONMAPPED_INSERTS 1000
|
#define MAX_NONMAPPED_INSERTS 1000
|
||||||
#define MARIA_MAX_TREE_LEVELS 32
|
#define MARIA_MAX_TREE_LEVELS 32
|
||||||
#define SANITY_CHECKS
|
|
||||||
|
|
||||||
struct st_transaction;
|
struct st_transaction;
|
||||||
|
|
||||||
@ -79,11 +82,12 @@ typedef struct st_maria_state_info
|
|||||||
ulong unique; /* Unique number for this process */
|
ulong unique; /* Unique number for this process */
|
||||||
ulong update_count; /* Updated for each write lock */
|
ulong update_count; /* Updated for each write lock */
|
||||||
ulong status;
|
ulong status;
|
||||||
ulong *rec_per_key_part;
|
double *rec_per_key_part;
|
||||||
|
ulong *nulls_per_key_part;
|
||||||
ha_checksum checksum; /* Table checksum */
|
ha_checksum checksum; /* Table checksum */
|
||||||
my_off_t *key_root; /* Start of key trees */
|
my_off_t *key_root; /* Start of key trees */
|
||||||
my_off_t key_del; /* delete links for index pages */
|
my_off_t key_del; /* delete links for index pages */
|
||||||
my_off_t rec_per_key_rows; /* Rows when calculating rec_per_key */
|
my_off_t records_at_analyze; /* Rows when calculating rec_per_key */
|
||||||
|
|
||||||
ulong sec_index_changed; /* Updated when new sec_index */
|
ulong sec_index_changed; /* Updated when new sec_index */
|
||||||
ulong sec_index_used; /* which extra index are in use */
|
ulong sec_index_used; /* which extra index are in use */
|
||||||
@ -108,18 +112,19 @@ typedef struct st_maria_state_info
|
|||||||
|
|
||||||
#define MARIA_STATE_INFO_SIZE \
|
#define MARIA_STATE_INFO_SIZE \
|
||||||
(24 + LSN_STORE_SIZE*2 + 4 + 11*8 + 4*4 + 8 + 3*4 + 5*8)
|
(24 + LSN_STORE_SIZE*2 + 4 + 11*8 + 4*4 + 8 + 3*4 + 5*8)
|
||||||
#define MARIA_STATE_KEY_SIZE 8
|
#define MARIA_STATE_KEY_SIZE (8 + 4)
|
||||||
#define MARIA_STATE_KEYBLOCK_SIZE 8
|
#define MARIA_STATE_KEYBLOCK_SIZE 8
|
||||||
#define MARIA_STATE_KEYSEG_SIZE 4
|
#define MARIA_STATE_KEYSEG_SIZE 12
|
||||||
#define MARIA_STATE_EXTRA_SIZE (MARIA_MAX_KEY*MARIA_STATE_KEY_SIZE + MARIA_MAX_KEY*HA_MAX_KEY_SEG*MARIA_STATE_KEYSEG_SIZE)
|
#define MARIA_STATE_EXTRA_SIZE (MARIA_MAX_KEY*MARIA_STATE_KEY_SIZE + MARIA_MAX_KEY*HA_MAX_KEY_SEG*MARIA_STATE_KEYSEG_SIZE)
|
||||||
#define MARIA_KEYDEF_SIZE (2+ 5*2)
|
#define MARIA_KEYDEF_SIZE (2+ 5*2)
|
||||||
#define MARIA_UNIQUEDEF_SIZE (2+1+1)
|
#define MARIA_UNIQUEDEF_SIZE (2+1+1)
|
||||||
#define HA_KEYSEG_SIZE (6+ 2*2 + 4*2)
|
#define HA_KEYSEG_SIZE (6+ 2*2 + 4*2)
|
||||||
#define MARIA_COLUMNDEF_SIZE (6+2+2+2+2+2+1+1)
|
#define MARIA_COLUMNDEF_SIZE (6+2+2+2+2+2+1+1)
|
||||||
#define MARIA_BASE_INFO_SIZE (5*8 + 6*4 + 11*2 + 6 + 5*2 + 1 + 16)
|
#define MARIA_BASE_INFO_SIZE (MY_UUID_SIZE + 5*8 + 6*4 + 11*2 + 6 + 5*2 + 1 + 16)
|
||||||
#define MARIA_INDEX_BLOCK_MARGIN 16 /* Safety margin for .MYI tables */
|
#define MARIA_INDEX_BLOCK_MARGIN 16 /* Safety margin for .MYI tables */
|
||||||
/* Internal management bytes needed to store 2 keys on an index page */
|
/* Internal management bytes needed to store 2 keys on an index page */
|
||||||
#define MARIA_INDEX_MIN_OVERHEAD_SIZE (4 + (TRANSID_SIZE+1) * 2)
|
#define MARIA_INDEX_OVERHEAD_SIZE (TRANSID_SIZE * 2)
|
||||||
|
#define MARIA_DELETE_KEY_NR 255 /* keynr for deleted blocks */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Basic information of the Maria table. This is stored on disk
|
Basic information of the Maria table. This is stored on disk
|
||||||
@ -171,9 +176,12 @@ typedef struct st_ma_base_info
|
|||||||
uint default_rec_buff_size;
|
uint default_rec_buff_size;
|
||||||
/* Extra number of bytes the row format require in the record buffer */
|
/* Extra number of bytes the row format require in the record buffer */
|
||||||
uint extra_rec_buff_size;
|
uint extra_rec_buff_size;
|
||||||
|
/* Tuning flags that can be ignored by older Maria versions */
|
||||||
|
uint extra_options;
|
||||||
|
|
||||||
/* The following are from the header */
|
/* The following are from the header */
|
||||||
uint key_parts, all_key_parts;
|
uint key_parts, all_key_parts;
|
||||||
|
uchar uuid[MY_UUID_SIZE];
|
||||||
/**
|
/**
|
||||||
@brief If false, we disable logging, versioning, transaction etc. Observe
|
@brief If false, we disable logging, versioning, transaction etc. Observe
|
||||||
difference with MARIA_SHARE::now_transactional
|
difference with MARIA_SHARE::now_transactional
|
||||||
@ -233,6 +241,7 @@ typedef struct st_maria_share
|
|||||||
MARIA_COLUMNDEF *columndef; /* Pointer to column information */
|
MARIA_COLUMNDEF *columndef; /* Pointer to column information */
|
||||||
MARIA_PACK pack; /* Data about packed records */
|
MARIA_PACK pack; /* Data about packed records */
|
||||||
MARIA_BLOB *blobs; /* Pointer to blobs */
|
MARIA_BLOB *blobs; /* Pointer to blobs */
|
||||||
|
uint16 *column_nr; /* Original column order */
|
||||||
char *unique_file_name; /* realpath() of index file */
|
char *unique_file_name; /* realpath() of index file */
|
||||||
char *data_file_name; /* Resolved path names from symlinks */
|
char *data_file_name; /* Resolved path names from symlinks */
|
||||||
char *index_file_name;
|
char *index_file_name;
|
||||||
@ -247,38 +256,38 @@ typedef struct st_maria_share
|
|||||||
/* Called when the last instance of the table is closed */
|
/* Called when the last instance of the table is closed */
|
||||||
my_bool (*once_end)(struct st_maria_share *);
|
my_bool (*once_end)(struct st_maria_share *);
|
||||||
/* Is called for every open of the table */
|
/* Is called for every open of the table */
|
||||||
my_bool (*init)(struct st_maria_info *);
|
my_bool (*init)(MARIA_HA *);
|
||||||
/* Is called for every close of the table */
|
/* Is called for every close of the table */
|
||||||
void (*end)(struct st_maria_info *);
|
void (*end)(MARIA_HA *);
|
||||||
/* Called when we want to read a record from a specific position */
|
/* Called when we want to read a record from a specific position */
|
||||||
int (*read_record)(struct st_maria_info *, uchar *, MARIA_RECORD_POS);
|
int (*read_record)(MARIA_HA *, uchar *, MARIA_RECORD_POS);
|
||||||
/* Initialize a scan */
|
/* Initialize a scan */
|
||||||
my_bool (*scan_init)(struct st_maria_info *);
|
my_bool (*scan_init)(MARIA_HA *);
|
||||||
/* Read next record while scanning */
|
/* Read next record while scanning */
|
||||||
int (*scan)(struct st_maria_info *, uchar *, MARIA_RECORD_POS, my_bool);
|
int (*scan)(MARIA_HA *, uchar *, MARIA_RECORD_POS, my_bool);
|
||||||
/* End scan */
|
/* End scan */
|
||||||
void (*scan_end)(struct st_maria_info *);
|
void (*scan_end)(MARIA_HA *);
|
||||||
/* Pre-write of row (some handlers may do the actual write here) */
|
/* Pre-write of row (some handlers may do the actual write here) */
|
||||||
MARIA_RECORD_POS (*write_record_init)(struct st_maria_info *, const uchar *);
|
MARIA_RECORD_POS (*write_record_init)(MARIA_HA *, const uchar *);
|
||||||
/* Write record (or accept write_record_init) */
|
/* Write record (or accept write_record_init) */
|
||||||
my_bool (*write_record)(struct st_maria_info *, const uchar *);
|
my_bool (*write_record)(MARIA_HA *, const uchar *);
|
||||||
/* Called when write failed */
|
/* Called when write failed */
|
||||||
my_bool (*write_record_abort)(struct st_maria_info *);
|
my_bool (*write_record_abort)(MARIA_HA *);
|
||||||
my_bool (*update_record)(struct st_maria_info *, MARIA_RECORD_POS,
|
my_bool (*update_record)(MARIA_HA *, MARIA_RECORD_POS,
|
||||||
const uchar *, const uchar *);
|
const uchar *, const uchar *);
|
||||||
my_bool (*delete_record)(struct st_maria_info *, const uchar *record);
|
my_bool (*delete_record)(MARIA_HA *, const uchar *record);
|
||||||
my_bool (*compare_record)(struct st_maria_info *, const uchar *);
|
my_bool (*compare_record)(MARIA_HA *, const uchar *);
|
||||||
/* calculate checksum for a row */
|
/* calculate checksum for a row */
|
||||||
ha_checksum(*calc_checksum)(struct st_maria_info *, const uchar *);
|
ha_checksum(*calc_checksum)(MARIA_HA *, const uchar *);
|
||||||
/*
|
/*
|
||||||
Calculate checksum for a row during write. May be 0 if we calculate
|
Calculate checksum for a row during write. May be 0 if we calculate
|
||||||
the checksum in write_record_init()
|
the checksum in write_record_init()
|
||||||
*/
|
*/
|
||||||
ha_checksum(*calc_write_checksum)(struct st_maria_info *, const uchar *);
|
ha_checksum(*calc_write_checksum)(MARIA_HA *, const uchar *);
|
||||||
/* calculate checksum for a row during check table */
|
/* calculate checksum for a row during check table */
|
||||||
ha_checksum(*calc_check_checksum)(struct st_maria_info *, const uchar *);
|
ha_checksum(*calc_check_checksum)(MARIA_HA *, const uchar *);
|
||||||
/* Compare a row in memory with a row on disk */
|
/* Compare a row in memory with a row on disk */
|
||||||
my_bool (*compare_unique)(struct st_maria_info *, MARIA_UNIQUEDEF *,
|
my_bool (*compare_unique)(MARIA_HA *, MARIA_UNIQUEDEF *,
|
||||||
const uchar *record, MARIA_RECORD_POS pos);
|
const uchar *record, MARIA_RECORD_POS pos);
|
||||||
/* Mapings to read/write the data file */
|
/* Mapings to read/write the data file */
|
||||||
uint (*file_read)(MARIA_HA *, uchar *, uint, my_off_t, myf);
|
uint (*file_read)(MARIA_HA *, uchar *, uint, my_off_t, myf);
|
||||||
@ -293,6 +302,7 @@ typedef struct st_maria_share
|
|||||||
ulong state_diff_length;
|
ulong state_diff_length;
|
||||||
uint rec_reflength; /* rec_reflength in use now */
|
uint rec_reflength; /* rec_reflength in use now */
|
||||||
uint unique_name_length;
|
uint unique_name_length;
|
||||||
|
uint keypage_header;
|
||||||
uint32 ftparsers; /* Number of distinct ftparsers
|
uint32 ftparsers; /* Number of distinct ftparsers
|
||||||
+ 1 */
|
+ 1 */
|
||||||
PAGECACHE_FILE kfile; /* Shared keyfile */
|
PAGECACHE_FILE kfile; /* Shared keyfile */
|
||||||
@ -396,7 +406,7 @@ typedef struct st_maria_block_scan
|
|||||||
} MARIA_BLOCK_SCAN;
|
} MARIA_BLOCK_SCAN;
|
||||||
|
|
||||||
|
|
||||||
struct st_maria_info
|
struct st_maria_handler
|
||||||
{
|
{
|
||||||
MARIA_SHARE *s; /* Shared between open:s */
|
MARIA_SHARE *s; /* Shared between open:s */
|
||||||
struct st_transaction *trn; /* Pointer to active transaction */
|
struct st_transaction *trn; /* Pointer to active transaction */
|
||||||
@ -424,7 +434,7 @@ struct st_maria_info
|
|||||||
uchar *update_field_data; /* Used by update in rows-in-block */
|
uchar *update_field_data; /* Used by update in rows-in-block */
|
||||||
uint int_nod_flag; /* -""- */
|
uint int_nod_flag; /* -""- */
|
||||||
uint32 int_keytree_version; /* -""- */
|
uint32 int_keytree_version; /* -""- */
|
||||||
int (*read_record) (struct st_maria_info *, uchar*, MARIA_RECORD_POS);
|
int (*read_record)(MARIA_HA *, uchar*, MARIA_RECORD_POS);
|
||||||
invalidator_by_filename invalidator; /* query cache invalidator */
|
invalidator_by_filename invalidator; /* query cache invalidator */
|
||||||
ulong this_unique; /* uniq filenumber or thread */
|
ulong this_unique; /* uniq filenumber or thread */
|
||||||
ulong last_unique; /* last unique number */
|
ulong last_unique; /* last unique number */
|
||||||
@ -513,10 +523,32 @@ struct st_maria_info
|
|||||||
#define READING_NEXT 1
|
#define READING_NEXT 1
|
||||||
#define READING_HEADER 2
|
#define READING_HEADER 2
|
||||||
|
|
||||||
#define maria_data_on_page(x) ((uint) mi_uint2korr(x) & 32767)
|
/* Number of bytes on key pages to indicate used size */
|
||||||
#define maria_putint(x,y,nod) { uint16 boh=(nod ? (uint16) 32768 : 0) + (uint16) (y);\
|
#define KEYPAGE_USED_SIZE 2
|
||||||
mi_int2store(x,boh); }
|
#define KEYPAGE_KEYID_SIZE 1
|
||||||
#define _ma_test_if_nod(x) (x[0] & 128 ? info->s->base.key_reflength : 0)
|
#define KEYPAGE_FLAG_SIZE 1
|
||||||
|
#define KEYPAGE_CHECKSUM_SIZE 4
|
||||||
|
#define MAX_KEYPAGE_HEADER_SIZE (LSN_STORE_SIZE + KEYPAGE_USED_SIZE + \
|
||||||
|
KEYPAGE_KEYID_SIZE + KEYPAGE_FLAG_SIZE)
|
||||||
|
|
||||||
|
#define _ma_get_page_used(info,x) \
|
||||||
|
(((uint) mi_uint2korr(x + (info)->s->keypage_header - KEYPAGE_USED_SIZE)) & \
|
||||||
|
32767)
|
||||||
|
#define _ma_store_page_used(info,x,y,nod) \
|
||||||
|
{ uint16 boh=(nod ? (uint16) 32768 : 0) + (uint16) (y); \
|
||||||
|
mi_int2store(x + (info)->s->keypage_header - KEYPAGE_USED_SIZE, boh); }
|
||||||
|
#define _ma_test_if_nod(info,x) \
|
||||||
|
(x[(info)->s->keypage_header-KEYPAGE_USED_SIZE] & 128 ? \
|
||||||
|
(info)->s->base.key_reflength : 0)
|
||||||
|
#define _ma_get_used_and_nod(info,buff,length,nod) \
|
||||||
|
{ \
|
||||||
|
nod= 0; \
|
||||||
|
length= mi_uint2korr((buff) + (info)->s->keypage_header - \
|
||||||
|
KEYPAGE_USED_SIZE); \
|
||||||
|
if (length & 32768) {length&= 32767; nod= (info)->s->base.key_reflength; } \
|
||||||
|
}
|
||||||
|
#define _ma_store_keynr(info, x, nr) x[(info)->s->keypage_header - KEYPAGE_KEYID_SIZE - KEYPAGE_FLAG_SIZE - KEYPAGE_USED_SIZE]= nr
|
||||||
|
#define _ma_get_keynr(info, x) ((uchar) x[(info)->s->keypage_header - KEYPAGE_KEYID_SIZE - KEYPAGE_FLAG_SIZE - KEYPAGE_USED_SIZE])
|
||||||
#define maria_mark_crashed(x) do{(x)->s->state.changed|= STATE_CRASHED; \
|
#define maria_mark_crashed(x) do{(x)->s->state.changed|= STATE_CRASHED; \
|
||||||
DBUG_PRINT("error", ("Marked table crashed")); \
|
DBUG_PRINT("error", ("Marked table crashed")); \
|
||||||
}while(0)
|
}while(0)
|
||||||
@ -559,7 +591,7 @@ struct st_maria_info
|
|||||||
{ length=mi_uint2korr((key)+1)+3; } \
|
{ length=mi_uint2korr((key)+1)+3; } \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define maria_max_key_length() ((maria_block_size - MARIA_INDEX_MIN_OVERHEAD_SIZE)/2)
|
#define maria_max_key_length() ((maria_block_size - MAX_KEYPAGE_HEADER_SIZE)/2 - MARIA_INDEX_OVERHEAD_SIZE)
|
||||||
#define get_pack_length(length) ((length) >= 255 ? 3 : 1)
|
#define get_pack_length(length) ((length) >= 255 ? 3 : 1)
|
||||||
|
|
||||||
#define MARIA_MIN_BLOCK_LENGTH 20 /* Because of delete-link */
|
#define MARIA_MIN_BLOCK_LENGTH 20 /* Because of delete-link */
|
||||||
@ -610,8 +642,9 @@ extern pthread_mutex_t THR_LOCK_maria;
|
|||||||
|
|
||||||
/* Some extern variables */
|
/* Some extern variables */
|
||||||
extern LIST *maria_open_list;
|
extern LIST *maria_open_list;
|
||||||
extern uchar NEAR maria_file_magic[], NEAR maria_pack_file_magic[];
|
extern uchar maria_file_magic[], maria_pack_file_magic[];
|
||||||
extern uint NEAR maria_read_vec[], NEAR maria_readnext_vec[];
|
extern uchar maria_uuid[MY_UUID_SIZE];
|
||||||
|
extern uint maria_read_vec[], maria_readnext_vec[];
|
||||||
extern uint maria_quick_table_bits;
|
extern uint maria_quick_table_bits;
|
||||||
extern const char *maria_data_root;
|
extern const char *maria_data_root;
|
||||||
extern uchar maria_zero_string[];
|
extern uchar maria_zero_string[];
|
||||||
@ -671,7 +704,8 @@ extern int _ma_insert(MARIA_HA *info, MARIA_KEYDEF *keyinfo, uchar *key,
|
|||||||
extern int _ma_split_page(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
|
extern int _ma_split_page(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
|
||||||
uchar *key, uchar *buff, uchar *key_buff,
|
uchar *key, uchar *buff, uchar *key_buff,
|
||||||
my_bool insert_last);
|
my_bool insert_last);
|
||||||
extern uchar *_ma_find_half_pos(uint nod_flag, MARIA_KEYDEF *keyinfo,
|
extern uchar *_ma_find_half_pos(MARIA_HA *info, uint nod_flag,
|
||||||
|
MARIA_KEYDEF *keyinfo,
|
||||||
uchar *page, uchar *key,
|
uchar *page, uchar *key,
|
||||||
uint *return_key_length,
|
uint *return_key_length,
|
||||||
uchar ** after_key);
|
uchar ** after_key);
|
||||||
@ -714,7 +748,7 @@ extern int _ma_decrement_open_count(MARIA_HA *info);
|
|||||||
extern int _ma_check_index(MARIA_HA *info, int inx);
|
extern int _ma_check_index(MARIA_HA *info, int inx);
|
||||||
extern int _ma_search(MARIA_HA *info, MARIA_KEYDEF *keyinfo, uchar *key,
|
extern int _ma_search(MARIA_HA *info, MARIA_KEYDEF *keyinfo, uchar *key,
|
||||||
uint key_len, uint nextflag, my_off_t pos);
|
uint key_len, uint nextflag, my_off_t pos);
|
||||||
extern int _ma_bin_search(struct st_maria_info *info, MARIA_KEYDEF *keyinfo,
|
extern int _ma_bin_search(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
|
||||||
uchar *page, uchar *key, uint key_len,
|
uchar *page, uchar *key, uint key_len,
|
||||||
uint comp_flag, uchar **ret_pos, uchar *buff,
|
uint comp_flag, uchar **ret_pos, uchar *buff,
|
||||||
my_bool *was_last_key);
|
my_bool *was_last_key);
|
||||||
@ -877,14 +911,16 @@ uint _ma_state_info_write(MARIA_SHARE *share, uint pWrite);
|
|||||||
uint _ma_state_info_write_sub(File file, MARIA_STATE_INFO *state, uint pWrite);
|
uint _ma_state_info_write_sub(File file, MARIA_STATE_INFO *state, uint pWrite);
|
||||||
uint _ma_state_info_read_dsk(File file, MARIA_STATE_INFO *state);
|
uint _ma_state_info_read_dsk(File file, MARIA_STATE_INFO *state);
|
||||||
uint _ma_base_info_write(File file, MARIA_BASE_INFO *base);
|
uint _ma_base_info_write(File file, MARIA_BASE_INFO *base);
|
||||||
int _ma_keyseg_write(File file, const HA_KEYSEG *keyseg);
|
my_bool _ma_keyseg_write(File file, const HA_KEYSEG *keyseg);
|
||||||
char *_ma_keyseg_read(char *ptr, HA_KEYSEG *keyseg);
|
char *_ma_keyseg_read(char *ptr, HA_KEYSEG *keyseg);
|
||||||
uint _ma_keydef_write(File file, MARIA_KEYDEF *keydef);
|
my_bool _ma_keydef_write(File file, MARIA_KEYDEF *keydef);
|
||||||
char *_ma_keydef_read(char *ptr, MARIA_KEYDEF *keydef);
|
char *_ma_keydef_read(char *ptr, MARIA_KEYDEF *keydef);
|
||||||
uint _ma_uniquedef_write(File file, MARIA_UNIQUEDEF *keydef);
|
my_bool _ma_uniquedef_write(File file, MARIA_UNIQUEDEF *keydef);
|
||||||
char *_ma_uniquedef_read(char *ptr, MARIA_UNIQUEDEF *keydef);
|
char *_ma_uniquedef_read(char *ptr, MARIA_UNIQUEDEF *keydef);
|
||||||
uint _ma_columndef_write(File file, MARIA_COLUMNDEF *columndef);
|
my_bool _ma_columndef_write(File file, MARIA_COLUMNDEF *columndef);
|
||||||
char *_ma_columndef_read(char *ptr, MARIA_COLUMNDEF *columndef);
|
char *_ma_columndef_read(char *ptr, MARIA_COLUMNDEF *columndef);
|
||||||
|
my_bool _ma_column_nr_write(File file, uint16 *offsets, uint columns);
|
||||||
|
uchar *_ma_column_nr_read(uchar *ptr, uint16 *offsets, uint columns);
|
||||||
ulong _ma_calc_total_blob_length(MARIA_HA *info, const uchar *record);
|
ulong _ma_calc_total_blob_length(MARIA_HA *info, const uchar *record);
|
||||||
ha_checksum _ma_checksum(MARIA_HA *info, const uchar *buf);
|
ha_checksum _ma_checksum(MARIA_HA *info, const uchar *buf);
|
||||||
ha_checksum _ma_static_checksum(MARIA_HA *info, const uchar *buf);
|
ha_checksum _ma_static_checksum(MARIA_HA *info, const uchar *buf);
|
||||||
@ -940,7 +976,7 @@ int _ma_flush_table_files_after_repair(HA_CHECK *param, MARIA_HA *info);
|
|||||||
|
|
||||||
int _ma_sort_write_record(MARIA_SORT_PARAM *sort_param);
|
int _ma_sort_write_record(MARIA_SORT_PARAM *sort_param);
|
||||||
int _ma_create_index_by_sort(MARIA_SORT_PARAM *info, my_bool no_messages,
|
int _ma_create_index_by_sort(MARIA_SORT_PARAM *info, my_bool no_messages,
|
||||||
ulong);
|
size_t);
|
||||||
int _ma_sync_table_files(const MARIA_HA *info);
|
int _ma_sync_table_files(const MARIA_HA *info);
|
||||||
int _ma_initialize_data_file(MARIA_SHARE *share, File dfile);
|
int _ma_initialize_data_file(MARIA_SHARE *share, File dfile);
|
||||||
int _ma_update_create_rename_lsn(MARIA_SHARE *share,
|
int _ma_update_create_rename_lsn(MARIA_SHARE *share,
|
||||||
|
@ -860,7 +860,7 @@ static int get_statistic(PACK_MRG_INFO *mrg,HUFF_COUNTS *huff_counts)
|
|||||||
ha_rows record_count;
|
ha_rows record_count;
|
||||||
HUFF_COUNTS *count,*end_count;
|
HUFF_COUNTS *count,*end_count;
|
||||||
TREE_ELEMENT *element;
|
TREE_ELEMENT *element;
|
||||||
ha_checksum(*calc_checksum) (struct st_maria_info *, const uchar *);
|
ha_checksum(*calc_checksum)(MARIA_HA *, const uchar *);
|
||||||
DBUG_ENTER("get_statistic");
|
DBUG_ENTER("get_statistic");
|
||||||
|
|
||||||
reclength= mrg->file[0]->s->base.reclength;
|
reclength= mrg->file[0]->s->base.reclength;
|
||||||
@ -873,8 +873,8 @@ static int get_statistic(PACK_MRG_INFO *mrg,HUFF_COUNTS *huff_counts)
|
|||||||
/* Check how to calculate checksum */
|
/* Check how to calculate checksum */
|
||||||
if (mrg->file[0]->s->data_file_type == STATIC_RECORD)
|
if (mrg->file[0]->s->data_file_type == STATIC_RECORD)
|
||||||
calc_checksum= _ma_static_checksum;
|
calc_checksum= _ma_static_checksum;
|
||||||
else
|
else
|
||||||
calc_checksum= _ma_checksum;
|
calc_checksum= _ma_checksum;
|
||||||
|
|
||||||
mrg_reset(mrg);
|
mrg_reset(mrg);
|
||||||
while ((error=mrg_rrnd(mrg,record)) != HA_ERR_END_OF_FILE)
|
while ((error=mrg_rrnd(mrg,record)) != HA_ERR_END_OF_FILE)
|
||||||
|
@ -92,7 +92,7 @@ void _mi_print_key(FILE *stream, register HA_KEYSEG *keyseg,
|
|||||||
key=end;
|
key=end;
|
||||||
break;
|
break;
|
||||||
case HA_KEYTYPE_ULONG_INT:
|
case HA_KEYTYPE_ULONG_INT:
|
||||||
l_1=mi_sint4korr(key);
|
l_1=mi_uint4korr(key);
|
||||||
VOID(fprintf(stream,"%lu",(ulong) l_1));
|
VOID(fprintf(stream,"%lu",(ulong) l_1));
|
||||||
key=end;
|
key=end;
|
||||||
break;
|
break;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user