mirror of
https://github.com/MariaDB/server.git
synced 2026-05-16 20:07:13 +02:00
Merge bk-internal.mysql.com:/home/bk/mysql-maria
into mysql.com:/home/my/mysql-maria client/mysqladmin.cc: Auto merged include/maria.h: Auto merged include/my_sys.h: Auto merged include/mysql_com.h: Auto merged mysql-test/r/maria.result: Auto merged server-tools/instance-manager/listener.cc: Auto merged sql/handler.h: Auto merged sql/item_func.cc: Auto merged sql/item_func.h: Auto merged sql/item_strfunc.cc: Auto merged sql/mysql_priv.h: Auto merged sql/mysqld.cc: Auto merged sql/sql_class.cc: Auto merged sql/sql_class.h: Auto merged sql/sql_show.cc: Auto merged sql/sql_table.cc: Auto merged sql/table.cc: Auto merged sql/table.h: Auto merged storage/maria/ma_bitmap.c: Auto merged storage/maria/ma_blockrec.c: Auto merged storage/maria/ma_blockrec.h: Auto merged storage/maria/ma_check.c: Auto merged storage/maria/ma_create.c: Auto merged storage/maria/ma_delete.c: Auto merged storage/maria/ma_loghandler.h: Auto merged storage/maria/ma_open.c: Auto merged storage/maria/ma_search.c: Auto merged storage/maria/ma_sort.c: Auto merged storage/maria/ma_test2.c: Auto merged storage/maria/ma_test_recovery.expected: Auto merged storage/maria/ma_write.c: Auto merged storage/maria/maria_chk.c: Auto merged storage/maria/maria_pack.c: Auto merged include/my_base.h: Trivial manual merge libmysql/Makefile.shared: Trivial manual merge sql/sql_yacc.yy: Manual merge storage/maria/ha_maria.cc: Trivial manual merge storage/maria/ma_page.c: Trivial manual merge storage/maria/maria_def.h: Trivial manual merge
This commit is contained in:
commit
df30832d11
64 changed files with 1873 additions and 1134 deletions
|
|
@ -528,7 +528,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
|
|||
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--)
|
||||
{
|
||||
|
|
@ -840,7 +840,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
|
|||
time_t start_time;
|
||||
/* Do initialization the same way as we do in mysqld */
|
||||
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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -110,7 +110,7 @@ extern "C" {
|
|||
|
||||
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 deleted; /* Deleted records in database */
|
||||
|
|
@ -126,7 +126,7 @@ typedef struct st_maria_isaminfo /* Struct from h_info */
|
|||
time_t check_time;
|
||||
time_t update_time;
|
||||
ulong record_offset;
|
||||
ulong *rec_per_key; /* for sql optimizing */
|
||||
double *rec_per_key; /* for sql optimizing */
|
||||
ulong reclength; /* Recordlength */
|
||||
ulong mean_reclength; /* Mean recordlength (if packed) */
|
||||
char *data_file_name, *index_file_name;
|
||||
|
|
@ -156,9 +156,9 @@ typedef struct st_maria_create_info
|
|||
my_bool with_auto_increment, transactional;
|
||||
} MARIA_CREATE_INFO;
|
||||
|
||||
struct st_maria_info; /* For referense */
|
||||
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;
|
||||
|
||||
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;
|
||||
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,
|
||||
uint key_len, uint comp_flag, uchar **ret_pos,
|
||||
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);
|
||||
void (*store_key)(struct st_maria_keydef *keyinfo, uchar *key_pos,
|
||||
struct st_maria_s_param *s_temp);
|
||||
int (*ck_insert)(struct st_maria_info *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_insert)(MARIA_HA *inf, uint k_nr, uchar *k, uint klen);
|
||||
int (*ck_delete)(MARIA_HA *inf, uint k_nr, uchar *k, uint klen);
|
||||
} MARIA_KEYDEF;
|
||||
|
||||
|
||||
|
|
@ -222,9 +222,10 @@ struct st_maria_bit_buff;
|
|||
|
||||
typedef struct st_maria_columndef /* column information */
|
||||
{
|
||||
uint64 offset; /* Offset to position in row */
|
||||
enum en_fieldtype type;
|
||||
uint32 offset; /* Offset to position in row */
|
||||
uint16 length; /* length of field */
|
||||
uint16 column_nr;
|
||||
/* Intern variable (size of total storage area for the row) */
|
||||
uint16 fill_length;
|
||||
uint16 null_pos; /* Position for null marker */
|
||||
|
|
@ -257,34 +258,34 @@ extern PAGECACHE maria_pagecache_var, *maria_pagecache;
|
|||
|
||||
extern int maria_init(void);
|
||||
extern void maria_end(void);
|
||||
extern int maria_close(struct st_maria_info *file);
|
||||
extern int maria_delete(struct st_maria_info *file, const uchar *buff);
|
||||
extern struct st_maria_info *maria_open(const char *name, int mode,
|
||||
extern int maria_close(MARIA_HA *file);
|
||||
extern int maria_delete(MARIA_HA *file, const uchar *buff);
|
||||
extern MARIA_HA *maria_open(const char *name, int mode,
|
||||
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_rfirst(struct st_maria_info *file, uchar *buf, int inx);
|
||||
extern int maria_rkey(struct st_maria_info *file, uchar *buf, int inx,
|
||||
extern int maria_rfirst(MARIA_HA *file, uchar *buf, int inx);
|
||||
extern int maria_rkey(MARIA_HA *file, uchar *buf, int inx,
|
||||
const uchar *key, key_part_map keypart_map,
|
||||
enum ha_rkey_function search_flag);
|
||||
extern int maria_rlast(struct st_maria_info *file, uchar *buf, int inx);
|
||||
extern int maria_rnext(struct st_maria_info *file, uchar *buf, int inx);
|
||||
extern int maria_rnext_same(struct st_maria_info *info, uchar *buf);
|
||||
extern int maria_rprev(struct st_maria_info *file, uchar *buf, int inx);
|
||||
extern int maria_rrnd(struct st_maria_info *file, uchar *buf,
|
||||
extern int maria_rlast(MARIA_HA *file, uchar *buf, int inx);
|
||||
extern int maria_rnext(MARIA_HA *file, uchar *buf, int inx);
|
||||
extern int maria_rnext_same(MARIA_HA *info, uchar *buf);
|
||||
extern int maria_rprev(MARIA_HA *file, uchar *buf, int inx);
|
||||
extern int maria_rrnd(MARIA_HA *file, uchar *buf,
|
||||
MARIA_RECORD_POS pos);
|
||||
extern int maria_scan_init(struct st_maria_info *file);
|
||||
extern int maria_scan(struct st_maria_info *file, uchar *buf);
|
||||
extern void maria_scan_end(struct st_maria_info *file);
|
||||
extern int maria_rsame(struct st_maria_info *file, uchar *record, int inx);
|
||||
extern int maria_rsame_with_pos(struct st_maria_info *file, uchar *record,
|
||||
extern int maria_scan_init(MARIA_HA *file);
|
||||
extern int maria_scan(MARIA_HA *file, uchar *buf);
|
||||
extern void maria_scan_end(MARIA_HA *file);
|
||||
extern int maria_rsame(MARIA_HA *file, uchar *record, int inx);
|
||||
extern int maria_rsame_with_pos(MARIA_HA *file, uchar *record,
|
||||
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);
|
||||
extern int maria_write(struct st_maria_info *file, uchar *buff);
|
||||
extern MARIA_RECORD_POS maria_position(struct st_maria_info *file);
|
||||
extern int maria_status(struct st_maria_info *info, MARIA_INFO *x, uint flag);
|
||||
extern int maria_lock_database(struct st_maria_info *file, int lock_type);
|
||||
extern int maria_write(MARIA_HA *file, uchar *buff);
|
||||
extern MARIA_RECORD_POS maria_position(MARIA_HA *file);
|
||||
extern int maria_status(MARIA_HA *info, MARIA_INFO *x, uint flag);
|
||||
extern int maria_lock_database(MARIA_HA *file, int lock_type);
|
||||
extern int maria_create(const char *name, enum data_file_type record_type,
|
||||
uint keys, MARIA_KEYDEF *keydef,
|
||||
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);
|
||||
extern int maria_delete_table(const char *name);
|
||||
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);
|
||||
extern int maria_reset(struct st_maria_info *file);
|
||||
extern ha_rows maria_records_in_range(struct st_maria_info *info, int inx,
|
||||
extern int maria_reset(MARIA_HA *file);
|
||||
extern ha_rows maria_records_in_range(MARIA_HA *info, int inx,
|
||||
key_range *min_key, key_range *max_key);
|
||||
extern int maria_is_changed(struct st_maria_info *info);
|
||||
extern int maria_delete_all_rows(struct st_maria_info *info);
|
||||
extern int maria_is_changed(MARIA_HA *info);
|
||||
extern int maria_delete_all_rows(MARIA_HA *info);
|
||||
extern uint maria_get_pointer_length(ulonglong file_length, uint def);
|
||||
extern int maria_commit(struct st_maria_info *info);
|
||||
extern int maria_begin(struct st_maria_info *info);
|
||||
extern int maria_commit(MARIA_HA *info);
|
||||
extern int maria_begin(MARIA_HA *info);
|
||||
|
||||
/* 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);
|
||||
void maria_lock_memory(HA_CHECK *param);
|
||||
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 records);
|
||||
int maria_filecopy(HA_CHECK *param, File to, File from, my_off_t start,
|
||||
|
|
|
|||
|
|
@ -295,6 +295,7 @@ enum ha_base_keytype {
|
|||
#define HA_OPTION_CREATE_FROM_ENGINE 256
|
||||
#define HA_OPTION_RELIES_ON_SQL_LAYER 512
|
||||
#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_READ_ONLY_DATA ((uint) 32768) /* Set by isamchk */
|
||||
|
||||
|
|
@ -305,6 +306,7 @@ enum ha_base_keytype {
|
|||
#define HA_CREATE_TMP_TABLE 4
|
||||
#define HA_CREATE_CHECKSUM 8
|
||||
#define HA_CREATE_KEEP_FILES 16 /* don't overwrite .MYD and MYI */
|
||||
#define HA_CREATE_PAGE_CHECKSUM 32
|
||||
#define HA_CREATE_DELAY_KEY_WRITE 64
|
||||
#define HA_CREATE_RELIES_ON_SQL_LAYER 128
|
||||
|
||||
|
|
@ -351,12 +353,15 @@ enum ha_base_keytype {
|
|||
*/
|
||||
#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_FOUND_DUPP_KEY 121 /* Dupplicate key on write */
|
||||
#define HA_ERR_RECORD_CHANGED 123 /* Uppdate with is recoverable */
|
||||
|
|
@ -377,7 +382,7 @@ enum ha_base_keytype {
|
|||
#define HA_WRONG_CREATE_OPTION 140 /* Wrong create option */
|
||||
#define HA_ERR_FOUND_DUPP_UNIQUE 141 /* Dupplicate unique on write */
|
||||
#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_USAGE 145 /* Table must be repaired */
|
||||
#define HA_ERR_LOCK_WAIT_TIMEOUT 146
|
||||
|
|
@ -392,28 +397,33 @@ enum ha_base_keytype {
|
|||
#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_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_NO_PARTITION_FOUND 160 /* There's no partition in table for
|
||||
given value */
|
||||
#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_FOREIGN_DUPLICATE_KEY 163 /* Upholding foreign key constraints
|
||||
would lead to a duplicate key
|
||||
error 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_DROP_INDEX_FK 162 /* Index needed in foreign key constr */
|
||||
/*
|
||||
Upholding foreign key constraints would lead to a duplicate key error
|
||||
in some other table.
|
||||
*/
|
||||
#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_ERANGE 167 /* Failed to set row autoinc value */
|
||||
#define HA_ERR_GENERIC 168 /* Generic error */
|
||||
#define HA_ERR_RECORD_IS_THE_SAME 169 /* row not actually updated :
|
||||
new values same as the old values */
|
||||
/* row not actually updated: 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
|
||||
statement */
|
||||
#define HA_ERR_LAST 170 /*Copy last error nr.*/
|
||||
/* Add error numbers before HA_ERR_LAST and change it accordingly. */
|
||||
/* Number of different errors */
|
||||
#define HA_ERR_ERRORS (HA_ERR_LAST - HA_ERR_FIRST + 1)
|
||||
|
||||
/* Other constants */
|
||||
|
|
|
|||
|
|
@ -907,6 +907,18 @@ int my_getpagesize(void);
|
|||
|
||||
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 */
|
||||
extern uint get_charset_number(const char *cs_name, uint cs_flags);
|
||||
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 tmp_key_crc[HA_MAX_POSSIBLE_KEY];
|
||||
ha_checksum tmp_record_checksum;
|
||||
ulong use_buffers, read_buffer_length, write_buffer_length;
|
||||
ulong sort_buffer_length, sort_key_blocks;
|
||||
size_t use_buffers, read_buffer_length, write_buffer_length;
|
||||
size_t sort_buffer_length, sort_key_blocks;
|
||||
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 opt_sort_key, total_files, max_level;
|
||||
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;
|
||||
int my_connect(my_socket s, const struct sockaddr *name, unsigned int namelen,
|
||||
unsigned int timeout);
|
||||
|
||||
struct rand_struct {
|
||||
unsigned long seed1,seed2,max_value;
|
||||
double max_value_dbl;
|
||||
};
|
||||
struct my_rnd_struct;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
@ -420,10 +416,8 @@ extern "C" {
|
|||
implemented in sql/password.c
|
||||
*/
|
||||
|
||||
void randominit(struct rand_struct *, unsigned long seed1,
|
||||
unsigned long seed2);
|
||||
double my_rnd(struct rand_struct *);
|
||||
void create_random_string(char *to, unsigned int length, struct rand_struct *rand_st);
|
||||
void create_random_string(char *to, unsigned int length,
|
||||
struct my_rnd_struct *rand_st);
|
||||
|
||||
void hash_password(unsigned long *to, const char *password, unsigned int password_len);
|
||||
void make_scrambled_password_323(char *to, const char *password);
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ mysysobjects1 = my_init.lo my_static.lo my_malloc.lo my_realloc.lo \
|
|||
my_compress.lo array.lo my_once.lo list.lo my_net.lo \
|
||||
charset.lo charset-def.lo hash.lo mf_iocache.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_rnd.lo \
|
||||
my_getopt.lo my_gethostbyname.lo my_port.lo \
|
||||
my_rename.lo my_chsize.lo my_sync.lo my_getsystime.lo
|
||||
sqlobjects = net.lo
|
||||
|
|
|
|||
|
|
@ -596,14 +596,14 @@ Error 1146 Table 'test.t3' doesn't exist
|
|||
checksum table t1, t2, t3;
|
||||
Table Checksum
|
||||
test.t1 3442722830
|
||||
test.t2 2948697075
|
||||
test.t2 3442722830
|
||||
test.t3 NULL
|
||||
Warnings:
|
||||
Error 1146 Table 'test.t3' doesn't exist
|
||||
checksum table t1, t2, t3 extended;
|
||||
Table Checksum
|
||||
test.t1 2948697075
|
||||
test.t2 2948697075
|
||||
test.t1 3442722830
|
||||
test.t2 3442722830
|
||||
test.t3 NULL
|
||||
Warnings:
|
||||
Error 1146 Table 'test.t3' doesn't exist
|
||||
|
|
@ -665,6 +665,25 @@ checksum table t2;
|
|||
Table Checksum
|
||||
test.t2 984116287
|
||||
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';
|
||||
Variable_name Value
|
||||
maria_stats_method nulls_unequal
|
||||
|
|
@ -1836,23 +1855,39 @@ t1 CREATE TABLE `t1` (
|
|||
) ENGINE=MARIA DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC TRANSACTIONAL=0
|
||||
drop table t1;
|
||||
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;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`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;
|
||||
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 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;
|
||||
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=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;
|
||||
create table t1 (a int) row_format=PAGE;
|
||||
show create table t1;
|
||||
|
|
@ -1861,6 +1896,19 @@ t1 CREATE TABLE `t1` (
|
|||
`a` int(11) DEFAULT NULL
|
||||
) ENGINE=MARIA DEFAULT CHARSET=latin1 ROW_FORMAT=PAGE
|
||||
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;
|
||||
insert delayed into t1 values(1);
|
||||
ERROR HY000: Table storage engine for 't1' doesn't have this option
|
||||
|
|
|
|||
|
|
@ -638,6 +638,22 @@ checksum table t1;
|
|||
checksum table 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.
|
||||
#
|
||||
|
|
@ -1130,12 +1146,21 @@ create table t1 (a int) row_format=dynamic transactional=1;
|
|||
show create table t1;
|
||||
alter table t1 row_format=PAGE;
|
||||
show create table t1;
|
||||
alter table t1 row_format=DYNAMIC;
|
||||
show create table t1;
|
||||
alter table t1 transactional=0;
|
||||
show create table t1;
|
||||
alter table t1 row_format=DYNAMIC;
|
||||
show create table t1;
|
||||
drop table t1;
|
||||
create table t1 (a int) row_format=PAGE;
|
||||
show create 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
|
||||
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 \
|
||||
lf_dynarray.c lf_alloc-pin.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 \
|
||||
mf_format.c mf_same.c mf_dirname.c mf_fn_ext.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
|
||||
#endif
|
||||
|
||||
#include "listener.h"
|
||||
|
||||
#include <my_global.h>
|
||||
#include <mysql.h>
|
||||
#include <violite.h>
|
||||
#include <my_sys.h>
|
||||
#include "listener.h"
|
||||
|
||||
#include <violite.h>
|
||||
#include <sys/stat.h>
|
||||
#ifndef __WIN__
|
||||
#include <sys/un.h>
|
||||
|
|
|
|||
|
|
@ -17,13 +17,12 @@
|
|||
#pragma implementation
|
||||
#endif
|
||||
|
||||
#include "mysql_connection.h"
|
||||
|
||||
#include <m_string.h>
|
||||
#include <m_string.h>
|
||||
#include <my_global.h>
|
||||
#include <mysql.h>
|
||||
#include <my_sys.h>
|
||||
#include "mysql_connection.h"
|
||||
|
||||
#include <m_string.h>
|
||||
#include <violite.h>
|
||||
|
||||
#include "command.h"
|
||||
|
|
@ -88,7 +87,7 @@ bool Mysql_connection::init()
|
|||
{
|
||||
ulong seed1= (ulong) &rand_st + rand();
|
||||
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 */
|
||||
|
|
|
|||
|
|
@ -17,7 +17,6 @@
|
|||
#define INCLUDES_MYSQL_INSTANCE_MANAGER_MYSQL_CONNECTION_H
|
||||
|
||||
#include "thread_registry.h"
|
||||
#include <mysql_com.h>
|
||||
|
||||
#if defined(__GNUC__) && defined(USE_PRAGMA_INTERFACE)
|
||||
#pragma interface
|
||||
|
|
@ -55,7 +54,7 @@ private:
|
|||
Thread_registry *thread_registry;
|
||||
User_map *user_map;
|
||||
NET net;
|
||||
struct rand_struct rand_st;
|
||||
struct my_rnd_struct rand_st;
|
||||
char scramble[SCRAMBLE_LENGTH + 1];
|
||||
uint status;
|
||||
ulong client_capabilities;
|
||||
|
|
|
|||
|
|
@ -327,6 +327,7 @@ enum enum_binlog_command {
|
|||
#define HA_CREATE_USED_CONNECTION (1L << 18)
|
||||
#define HA_CREATE_USED_KEY_BLOCK_SIZE (1L << 19)
|
||||
#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
|
||||
#define MYSQL_XID_PREFIX "MySQLXid"
|
||||
|
|
@ -823,6 +824,7 @@ typedef struct st_ha_create_information
|
|||
bool frm_only; /* 1 if no ha_create_table() */
|
||||
bool varchar; /* 1 if table has a VARCHAR */
|
||||
enum ha_storage_media storage_media; /* DEFAULT, DISK or MEMORY */
|
||||
enum ha_choice page_checksum; /* If we have page_checksums */
|
||||
} HA_CREATE_INFO;
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -2124,7 +2124,7 @@ void Item_func_rand::seed_random(Item *arg)
|
|||
args[0] is a constant.
|
||||
*/
|
||||
uint32 tmp= (uint32) arg->val_int();
|
||||
randominit(rand, (uint32) (tmp*0x10001L+55555555L),
|
||||
my_rnd_init(rand, (uint32) (tmp*0x10001L+55555555L),
|
||||
(uint32) (tmp*0x10000001L));
|
||||
}
|
||||
|
||||
|
|
@ -2144,7 +2144,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),
|
||||
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))))
|
||||
return TRUE;
|
||||
|
||||
|
|
|
|||
|
|
@ -652,7 +652,7 @@ public:
|
|||
|
||||
class Item_func_rand :public Item_real_func
|
||||
{
|
||||
struct rand_struct *rand;
|
||||
struct my_rnd_struct *rand;
|
||||
public:
|
||||
Item_func_rand(Item *a) :Item_real_func(a), rand(0) {}
|
||||
Item_func_rand() :Item_real_func() {}
|
||||
|
|
|
|||
|
|
@ -3321,7 +3321,7 @@ err:
|
|||
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 ulonglong uuid_time=0;
|
||||
static char clock_seq_and_node_str[]="-0000-000000000000";
|
||||
|
|
@ -3369,9 +3369,9 @@ String *Item_func_uuid::val_str(String *str)
|
|||
generating random "hardware addr"
|
||||
and because specs explicitly specify that it should NOT correlate
|
||||
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++)
|
||||
mac[i]=(uchar)(my_rnd(&uuid_rand)*255);
|
||||
/* purecov: end */
|
||||
|
|
@ -3382,7 +3382,7 @@ String *Item_func_uuid::val_str(String *str)
|
|||
*--s=_dig_vec_lower[mac[i] & 15];
|
||||
*--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);
|
||||
set_clock_seq_str();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -381,6 +381,7 @@ static SYMBOL symbols[] = {
|
|||
{ "PACK_KEYS", SYM(PACK_KEYS_SYM)},
|
||||
{ "PARSER", SYM(PARSER_SYM)},
|
||||
{ "PAGE", SYM(PAGE_SYM)},
|
||||
{ "PAGE_CHECKSUM", SYM(PAGE_CHECKSUM_SYM)},
|
||||
{ "PARTIAL", SYM(PARTIAL)},
|
||||
{ "PARTITION", SYM(PARTITION_SYM)},
|
||||
{ "PARTITIONING", SYM(PARTITIONING_SYM)},
|
||||
|
|
@ -513,7 +514,8 @@ static SYMBOL symbols[] = {
|
|||
{ "SUSPEND", SYM(SUSPEND_SYM)},
|
||||
{ "TABLE", SYM(TABLE_SYM)},
|
||||
{ "TABLES", SYM(TABLES)},
|
||||
{ "TABLESPACE", SYM(TABLESPACE)},
|
||||
{ "TABLESPACE", SYM(TABLESPACE)},
|
||||
{ "TABLE_CHECKSUM", SYM(TABLE_CHECKSUM_SYM)},
|
||||
{ "TEMPORARY", SYM(TEMPORARY)},
|
||||
{ "TEMPTABLE", SYM(TEMPTABLE_SYM)},
|
||||
{ "TERMINATED", SYM(TERMINATED)},
|
||||
|
|
|
|||
|
|
@ -1867,7 +1867,7 @@ extern struct system_variables global_system_variables;
|
|||
#ifdef MYSQL_SERVER
|
||||
extern struct system_variables max_system_variables;
|
||||
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 KNOWN_DATE_TIME_FORMAT known_date_time_formats[];
|
||||
|
|
|
|||
|
|
@ -611,7 +611,7 @@ static char **defaults_argv;
|
|||
static char *opt_bin_logname;
|
||||
|
||||
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
|
||||
struct passwd *user_info;
|
||||
|
|
@ -3248,7 +3248,7 @@ static int init_server_components()
|
|||
query_cache_set_min_res_unit(query_cache_min_res_unit);
|
||||
query_cache_init();
|
||||
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();
|
||||
init_thr_lock();
|
||||
#ifdef HAVE_REPLICATION
|
||||
|
|
|
|||
|
|
@ -69,41 +69,12 @@
|
|||
/*
|
||||
New (MySQL 3.21+) random generation structure initialization
|
||||
SYNOPSIS
|
||||
randominit()
|
||||
my_rnd_init()
|
||||
rand_st OUT Structure to initialize
|
||||
seed1 IN First 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
|
||||
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)
|
||||
{
|
||||
struct rand_struct rand_st;
|
||||
struct my_rnd_struct rand_st;
|
||||
ulong hash_pass[2], hash_message[2];
|
||||
|
||||
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;
|
||||
hash_password(hash_pass,password, (uint) strlen(password));
|
||||
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]);
|
||||
for (; message < message_end; message++)
|
||||
*to++= (char) (floor(my_rnd(&rand_st)*31)+64);
|
||||
|
|
@ -206,13 +177,13 @@ my_bool
|
|||
check_scramble_323(const char *scrambled, const char *message,
|
||||
ulong *hash_pass)
|
||||
{
|
||||
struct rand_struct rand_st;
|
||||
struct my_rnd_struct rand_st;
|
||||
ulong hash_message[2];
|
||||
char buff[16],*to,extra; /* Big enough for check */
|
||||
const char *pos;
|
||||
|
||||
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]);
|
||||
to=buff;
|
||||
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
|
||||
*/
|
||||
|
||||
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;
|
||||
/* Use pointer arithmetics as it is faster way to do so. */
|
||||
|
|
|
|||
|
|
@ -479,7 +479,7 @@ THD::THD()
|
|||
|
||||
tablespace_op=FALSE;
|
||||
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;
|
||||
thr_lock_info_init(&lock_info); /* safety: will be reset after start */
|
||||
thr_lock_owner_init(&main_lock_id, &lock_info);
|
||||
|
|
|
|||
|
|
@ -1023,7 +1023,7 @@ public:
|
|||
String packet; // dynamic buffer for network I/O
|
||||
String convert_buffer; // buffer for charset conversions
|
||||
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_status_var status_var; // Per thread statistic vars
|
||||
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)
|
||||
{
|
||||
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++)
|
||||
decode_buff[i]= (char) i;
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@
|
|||
|
||||
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];
|
||||
uint shift;
|
||||
void crypt_init(ulong *seed);
|
||||
|
|
|
|||
|
|
@ -70,6 +70,9 @@ static TYPELIB grant_types = { sizeof(grant_names)/sizeof(char **),
|
|||
grant_names, NULL};
|
||||
#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,
|
||||
KEY *key_info);
|
||||
|
||||
|
|
@ -1182,6 +1185,8 @@ int store_create_info(THD *thd, TABLE_LIST *table_list, String *packet,
|
|||
|
||||
key_info= table->key_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);
|
||||
primary_key= share->primary_key;
|
||||
|
||||
|
|
@ -1366,19 +1371,25 @@ int store_create_info(THD *thd, TABLE_LIST *table_list, String *packet,
|
|||
packet->append(STRING_WITH_LEN(" PACK_KEYS=1"));
|
||||
if (share->db_create_options & HA_OPTION_NO_PACK_KEYS)
|
||||
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)
|
||||
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)
|
||||
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(ha_row_type[(uint) share->row_type]);
|
||||
packet->append(ha_row_type[(uint) create_info.row_type]);
|
||||
}
|
||||
if (share->transactional != HA_CHOICE_UNDEF)
|
||||
{
|
||||
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)
|
||||
{
|
||||
|
|
@ -3462,8 +3473,12 @@ static int get_schema_tables_record(THD *thd, TABLE_LIST *tables,
|
|||
ptr=strmov(ptr," pack_keys=1");
|
||||
if (share->db_create_options & HA_OPTION_NO_PACK_KEYS)
|
||||
ptr=strmov(ptr," pack_keys=0");
|
||||
/* We use CHECKSUM, instead of TABLE_CHECKSUM, for backward compability */
|
||||
if (share->db_create_options & HA_OPTION_CHECKSUM)
|
||||
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)
|
||||
ptr=strmov(ptr," delay_key_write=1");
|
||||
if (share->row_type != ROW_TYPE_DEFAULT)
|
||||
|
|
@ -3482,6 +3497,9 @@ static int get_schema_tables_record(THD *thd, TABLE_LIST *tables,
|
|||
show_table->part_info->no_parts > 0)
|
||||
ptr= strmov(ptr, " partitioned");
|
||||
#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,
|
||||
(ptr == option_buff ? 0 :
|
||||
(uint) (ptr-option_buff)-1), cs);
|
||||
|
|
|
|||
|
|
@ -7037,10 +7037,9 @@ bool mysql_checksum_table(THD *thd, TABLE_LIST *tables,
|
|||
for (uint i= 0; i < t->s->fields; i++ )
|
||||
{
|
||||
Field *f= t->field[i];
|
||||
#ifdef NOT_YET
|
||||
if (f->is_real_null(0))
|
||||
if (! thd->variables.old_mode &&
|
||||
f->is_real_null(0))
|
||||
continue;
|
||||
#endif
|
||||
if ((f->type() == MYSQL_TYPE_BLOB) ||
|
||||
(f->type() == MYSQL_TYPE_VARCHAR))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -487,6 +487,7 @@ Item* handle_sql2003_note184_exception(THD *thd, Item* left, bool equal,
|
|||
enum enum_tx_isolation tx_isolation;
|
||||
enum Cast_target cast_type;
|
||||
enum Item_udftype udf_type;
|
||||
enum ha_choice choice;
|
||||
CHARSET_INFO *charset;
|
||||
thr_lock_type lock_type;
|
||||
interval_type interval, interval_time_st;
|
||||
|
|
@ -875,6 +876,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
|
|||
%token OWNER_SYM
|
||||
%token PACK_KEYS_SYM
|
||||
%token PAGE_SYM
|
||||
%token PAGE_CHECKSUM_SYM
|
||||
%token PARAM_MARKER
|
||||
%token PARSER_SYM
|
||||
%token PARTIAL /* SQL-2003-N */
|
||||
|
|
@ -1010,6 +1012,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
|
|||
%token TABLESPACE
|
||||
%token TABLE_REF_PRIORITY
|
||||
%token TABLE_SYM /* SQL-2003-R */
|
||||
%token TABLE_CHECKSUM_SYM
|
||||
%token TEMPORARY /* SQL-2003-N */
|
||||
%token TEMPTABLE_SYM
|
||||
%token TERMINATED
|
||||
|
|
@ -1145,6 +1148,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
|
|||
%type <ulonglong_number>
|
||||
ulonglong_num real_ulonglong_num size_number
|
||||
|
||||
%type <choice> choice
|
||||
|
||||
%type <p_elem_value>
|
||||
part_bit_expr
|
||||
|
||||
|
|
@ -4440,6 +4445,16 @@ create_table_option:
|
|||
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;
|
||||
|
|
@ -4499,11 +4514,10 @@ create_table_option:
|
|||
Lex->create_info.used_fields|= HA_CREATE_USED_KEY_BLOCK_SIZE;
|
||||
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.transactional= ($3 != 0 ? HA_CHOICE_YES :
|
||||
HA_CHOICE_NO);
|
||||
Lex->create_info.transactional= $3;
|
||||
}
|
||||
;
|
||||
|
||||
|
|
@ -8378,6 +8392,11 @@ dec_num:
|
|||
| FLOAT_NUM
|
||||
;
|
||||
|
||||
choice:
|
||||
ulong_num { $$= $1 != 0 ? HA_CHOICE_YES : HA_CHOICE_NO; }
|
||||
| DEFAULT { $$= HA_CHOICE_UNDEF; }
|
||||
;
|
||||
|
||||
procedure_clause:
|
||||
/* empty */
|
||||
| PROCEDURE ident /* Procedure name */
|
||||
|
|
@ -10574,6 +10593,7 @@ keyword_sp:
|
|||
| ONE_SYM {}
|
||||
| PACK_KEYS_SYM {}
|
||||
| PAGE_SYM {}
|
||||
| PAGE_CHECKSUM_SYM {}
|
||||
| PARTIAL {}
|
||||
| PARTITIONING_SYM {}
|
||||
| PARTITIONS_SYM {}
|
||||
|
|
@ -10637,6 +10657,7 @@ keyword_sp:
|
|||
| SUPER_SYM {}
|
||||
| SUSPEND_SYM {}
|
||||
| TABLES {}
|
||||
| TABLE_CHECKSUM_SYM {}
|
||||
| TABLESPACE {}
|
||||
| TEMPORARY {}
|
||||
| TEMPTABLE_SYM {}
|
||||
|
|
|
|||
|
|
@ -705,7 +705,8 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
|
|||
if (!head[32]) // New frm file in 3.23
|
||||
{
|
||||
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->table_charset= get_charset((uint) head[38],MYF(0));
|
||||
share->null_field_first= 1;
|
||||
|
|
@ -2438,7 +2439,8 @@ File create_frm(THD *thd, const char *name, const char *db,
|
|||
int4store(fileinfo+34,create_info->avg_row_length);
|
||||
fileinfo[38]= (create_info->default_table_charset ?
|
||||
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;
|
||||
/* Next few bytes where for RAID support */
|
||||
fileinfo[41]= 0;
|
||||
|
|
|
|||
|
|
@ -311,6 +311,7 @@ typedef struct st_table_share
|
|||
enum row_type row_type; /* How rows are stored */
|
||||
enum tmp_table_type tmp_table;
|
||||
enum ha_choice transactional;
|
||||
enum ha_choice page_checksum;
|
||||
|
||||
uint ref_count; /* How many TABLE objects uses this */
|
||||
uint open_count; /* Number of tables in open list */
|
||||
|
|
|
|||
|
|
@ -409,8 +409,9 @@ int table2maria(TABLE *table_arg, MARIA_KEYDEF **keydef_out,
|
|||
- compare FULLTEXT keys;
|
||||
- compare SPATIAL keys;
|
||||
- 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,
|
||||
MARIA_COLUMNDEF *t1_recinfo,
|
||||
uint t1_keys, uint t1_recs,
|
||||
|
|
@ -727,9 +728,6 @@ err:
|
|||
|
||||
int ha_maria::open(const char *name, int mode, uint test_if_locked)
|
||||
{
|
||||
MARIA_KEYDEF *keyinfo;
|
||||
MARIA_COLUMNDEF *recinfo= 0;
|
||||
uint recs;
|
||||
uint i;
|
||||
|
||||
#ifdef NOT_USED
|
||||
|
|
@ -755,39 +753,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)))
|
||||
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))
|
||||
VOID(maria_extra(file, HA_EXTRA_NO_WAIT_LOCK, 0));
|
||||
|
||||
|
|
@ -819,16 +784,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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
@ -1917,9 +1872,12 @@ int ha_maria::info(uint flag)
|
|||
share->keys_for_keyread.intersect(share->keys_in_use);
|
||||
share->db_record_offset= maria_info.record_offset;
|
||||
if (share->key_parts)
|
||||
memcpy((char*) table->key_info[0].rec_per_key,
|
||||
(char*) maria_info.rec_per_key,
|
||||
sizeof(table->key_info[0].rec_per_key) * share->key_parts);
|
||||
{
|
||||
ulong *to= table->key_info[0].rec_per_key, *end;
|
||||
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)
|
||||
pthread_mutex_unlock(&share->mutex);
|
||||
|
||||
|
|
@ -2111,6 +2069,10 @@ void ha_maria::update_create_info(HA_CREATE_INFO *create_info)
|
|||
}
|
||||
create_info->data_file_name= data_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();
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -2160,7 +2122,16 @@ int ha_maria::create(const char *name, register TABLE *table_arg,
|
|||
break;
|
||||
}
|
||||
}
|
||||
/* Note: BLOCK_RECORD is used if table is transactional */
|
||||
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)))
|
||||
DBUG_RETURN(error); /* purecov: inspected */
|
||||
bzero((char*) &create_info, sizeof(create_info));
|
||||
|
|
@ -2174,21 +2145,17 @@ int ha_maria::create(const char *name, register TABLE *table_arg,
|
|||
share->avg_row_length);
|
||||
create_info.data_file_name= ha_create_info->data_file_name;
|
||||
create_info.index_file_name= ha_create_info->index_file_name;
|
||||
#ifdef ASK_MONTY
|
||||
/**
|
||||
@todo ASK_MONTY
|
||||
Where "transactional" in the frm and in the engine can go out of sync.
|
||||
Don't we want to do, after the setting, this test:
|
||||
if (!create_info.transactional &&
|
||||
ha_create_info->transactional == HA_CHOICE_YES)
|
||||
error;
|
||||
?
|
||||
Why fool the user?
|
||||
|
||||
/*
|
||||
Table is transactional:
|
||||
- If the user specify that table is transactional (in this case
|
||||
row type is forced to BLOCK_RECORD)
|
||||
- If they specify BLOCK_RECORD without specifying transactional behaviour
|
||||
|
||||
Shouldn't this test be pushed down to maria_create()? Because currently,
|
||||
ma_test1 -T crashes: it creates a table with DYNAMIC_RECORD but has
|
||||
born_transactional==1, which confuses some recovery-related code.
|
||||
*/
|
||||
#endif
|
||||
create_info.transactional= (row_type == BLOCK_RECORD &&
|
||||
ha_create_info->transactional != HA_CHOICE_NO);
|
||||
|
||||
|
|
@ -2202,6 +2169,8 @@ int ha_maria::create(const char *name, register TABLE *table_arg,
|
|||
create_flags|= HA_CREATE_CHECKSUM;
|
||||
if (options & HA_OPTION_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 */
|
||||
error=
|
||||
|
|
|
|||
|
|
@ -130,8 +130,11 @@
|
|||
#define FULL_HEAD_PAGE 4
|
||||
#define FULL_TAIL_PAGE 7
|
||||
|
||||
/** all bitmap pages end with this 2-byte signature */
|
||||
uchar maria_bitmap_marker[2]= {(uchar) 'b',(uchar) 'm'};
|
||||
/* If we don't have page checksum enabled, the bitmap page ends with this */
|
||||
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,
|
||||
MARIA_FILE_BITMAP *bitmap,
|
||||
|
|
@ -186,7 +189,7 @@ my_bool _ma_bitmap_init(MARIA_SHARE *share, File file)
|
|||
bitmap->changed= 0;
|
||||
bitmap->block_size= share->block_size;
|
||||
/* 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;
|
||||
/*
|
||||
In each 6 bytes, we have 6*8/3 = 16 pages covered
|
||||
|
|
@ -455,10 +458,6 @@ static void _ma_print_bitmap(MARIA_FILE_BITMAP *bitmap)
|
|||
fprintf(DBUG_FILE,"\nBitmap page changes at page %lu\n",
|
||||
(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;
|
||||
for (pos= bitmap->map, org_pos= bitmap->map + bitmap->block_size ;
|
||||
pos < end ;
|
||||
|
|
@ -544,14 +543,30 @@ static my_bool _ma_read_bitmap_page(MARIA_SHARE *share,
|
|||
}
|
||||
bitmap->used_size= bitmap->total_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,
|
||||
(uchar*) bitmap->map,
|
||||
PAGECACHE_PLAIN_PAGE,
|
||||
PAGECACHE_LOCK_LEFT_UNLOCKED, 0) == NULL) ||
|
||||
memcmp(bitmap->map + bitmap->block_size -
|
||||
sizeof(maria_bitmap_marker),
|
||||
maria_bitmap_marker, sizeof(maria_bitmap_marker)));
|
||||
PAGECACHE_LOCK_LEFT_UNLOCKED, 0) == NULL;
|
||||
|
||||
/*
|
||||
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
|
||||
if (!res)
|
||||
memcpy(bitmap->map + bitmap->block_size, bitmap->map, bitmap->block_size);
|
||||
|
|
@ -1428,6 +1443,7 @@ static my_bool write_rest_of_head(MARIA_HA *info, uint position,
|
|||
row->space_on_head_page contains minimum number of bytes we
|
||||
expect to put on the head page.
|
||||
1 error
|
||||
my_errno is set to error
|
||||
*/
|
||||
|
||||
my_bool _ma_bitmap_find_place(MARIA_HA *info, MARIA_ROW *row,
|
||||
|
|
@ -2068,9 +2084,16 @@ int _ma_bitmap_create_first(MARIA_SHARE *share)
|
|||
{
|
||||
uint block_size= share->bitmap.block_size;
|
||||
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),
|
||||
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),
|
||||
MYF(MY_NABP | MY_WME)))
|
||||
return 1;
|
||||
|
|
|
|||
|
|
@ -52,10 +52,11 @@
|
|||
|
||||
Page header:
|
||||
|
||||
LSN 7 bytes Log position for last page change
|
||||
PAGE_TYPE 1 uchar 1 for head / 2 for tail / 3 for blob
|
||||
NO 1 uchar Number of row/tail entries on page
|
||||
empty space 2 bytes Empty space on page
|
||||
LSN 7 bytes Log position for last page change
|
||||
PAGE_TYPE 1 uchar 1 for head / 2 for tail / 3 for blob
|
||||
DIR_COUNT 1 uchar Number of row/tail entries 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
|
||||
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
|
||||
(in reverse order; i.e., first record is stored last):
|
||||
|
||||
Position 2 bytes Position of row on page
|
||||
Length 2 bytes Length of entry
|
||||
Position 2 bytes Position of row on page
|
||||
Length 2 bytes Length of entry
|
||||
|
||||
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 row (in other words, we should try to keep these reserved)
|
||||
|
||||
eof flag 1 uchar Reserved for full page read testing. (Ie, did the
|
||||
previous write get the whole block on disk.
|
||||
Position is 0 if the entry is not used. In this case length[0] points
|
||||
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:
|
||||
|
||||
LSN 7 bytes Log position for last page change
|
||||
PAGE_TYPE 1 uchar 3
|
||||
LSN 7 bytes Log position for last page change
|
||||
PAGE_TYPE 1 uchar 3
|
||||
|
||||
data
|
||||
|
||||
|
|
@ -104,7 +110,7 @@
|
|||
Number of ROW_EXTENT's 1-3 uchar Length encoded, optional
|
||||
This is the number of extents the
|
||||
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
|
||||
char/varchar/blob fields.
|
||||
|
|
@ -206,7 +212,7 @@
|
|||
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
|
||||
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.
|
||||
TODO: Add code for handling dropped fields.
|
||||
|
||||
|
|
@ -229,6 +235,7 @@
|
|||
|
||||
00 00 00 00 00 00 00 LSN
|
||||
01 Only one row in page
|
||||
FF No free dir entry
|
||||
xx xx Empty space on page
|
||||
|
||||
10 Flag: row split, VER_PTR exists
|
||||
|
|
@ -252,11 +259,10 @@
|
|||
|
||||
..... 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 "ma_blockrec.h"
|
||||
#include <lf.h>
|
||||
|
|
@ -625,17 +631,42 @@ static my_bool extend_area_on_page(uchar *buff, uchar *dir,
|
|||
uint *ret_length)
|
||||
{
|
||||
uint rec_offset, length;
|
||||
uint max_entry= (uint) buff[DIR_COUNT_OFFSET];
|
||||
DBUG_ENTER("extend_area_on_page");
|
||||
|
||||
rec_offset= uint2korr(dir);
|
||||
length= uint2korr(dir + 2);
|
||||
DBUG_PRINT("enter", ("rec_offset: %u length: %u request_length: %u",
|
||||
rec_offset, length, request_length));
|
||||
if (rec_offset)
|
||||
{
|
||||
/* 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)
|
||||
{
|
||||
uint max_entry= (uint) ((uchar*) buff)[DIR_COUNT_OFFSET];
|
||||
uint old_rec_offset;
|
||||
/*
|
||||
New data did not fit in old position.
|
||||
|
|
@ -672,7 +703,13 @@ static my_bool extend_area_on_page(uchar *buff, uchar *dir,
|
|||
rec_offset= uint2korr(dir);
|
||||
length= uint2korr(dir+2);
|
||||
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 */
|
||||
}
|
||||
*empty_space= length; /* All space is here */
|
||||
}
|
||||
}
|
||||
|
|
@ -850,60 +887,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
|
||||
|
||||
See start of file for description of how free directory entires are linked
|
||||
|
||||
RETURN
|
||||
0 Error (directory full or last block goes over directory)
|
||||
# Pointer to directory entry on page
|
||||
*/
|
||||
|
||||
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 entry, length, first_pos;
|
||||
uchar *dir, *end;
|
||||
uint max_entry, free_entry;
|
||||
uint length, first_pos;
|
||||
uchar *dir, *first_dir;
|
||||
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);
|
||||
|
||||
/* Search after first empty position */
|
||||
first_pos= PAGE_HEADER_SIZE;
|
||||
for (entry= 0 ; dir <= end ; end-= DIR_ENTRY_SIZE, entry++)
|
||||
DBUG_PRINT("info", ("max_entry: %u free_entry: %u", max_entry, free_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 (!tmp) /* Found not used entry */
|
||||
if (free_entry >= max_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;
|
||||
int2store(end, first_pos); /* Update dir entry */
|
||||
int2store(end + 2, length);
|
||||
*res_rownr= entry;
|
||||
*res_length= length;
|
||||
DBUG_RETURN(end);
|
||||
uchar *next_entry= dir_entry_pos(buff, block_size, (uint) dir[3]);
|
||||
DBUG_ASSERT((uint) next_entry[2] == free_entry &&
|
||||
uint2korr(next_entry) == 0);
|
||||
next_entry[2]= END_OF_DIR_FREE_LIST; /* Backlink */
|
||||
}
|
||||
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 */
|
||||
dir= end;
|
||||
/* No free places in dir; create a new one */
|
||||
|
||||
/* Check if there is place for the directory entry */
|
||||
if (max_entry == MAX_ROWS_PER_PAGE)
|
||||
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)
|
||||
{
|
||||
/* Create place for directory */
|
||||
compact_page(buff, block_size, max_entry-1, 0);
|
||||
first_pos= (uint2korr(end + DIR_ENTRY_SIZE) +
|
||||
uint2korr(end + DIR_ENTRY_SIZE+ 2));
|
||||
first_pos= (uint2korr(first_dir) + uint2korr(first_dir + 2));
|
||||
*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);
|
||||
DBUG_ASSERT(length <= *empty_space - DIR_ENTRY_SIZE);
|
||||
int2store(dir, first_pos);
|
||||
int2store(dir+2, length); /* Current max length */
|
||||
int2store(dir+2, length); /* Max length of region */
|
||||
*res_rownr= max_entry;
|
||||
*res_length= length;
|
||||
|
||||
|
|
@ -1108,8 +1161,8 @@ static void compact_page(uchar *buff, uint block_size, uint rownr,
|
|||
PAGE_SUFFIX_SIZE) / DIR_ENTRY_SIZE);
|
||||
|
||||
/* Move all entries before and including rownr up to start of page */
|
||||
dir= buff + block_size - DIR_ENTRY_SIZE * (rownr+1) - PAGE_SUFFIX_SIZE;
|
||||
end= buff + block_size - DIR_ENTRY_SIZE - PAGE_SUFFIX_SIZE;
|
||||
dir= dir_entry_pos(buff, block_size, rownr);
|
||||
end= dir_entry_pos(buff, block_size, 0);
|
||||
page_pos= next_free_pos= start_of_found_block= PAGE_HEADER_SIZE;
|
||||
diff= 0;
|
||||
for (; dir <= end ; end-= DIR_ENTRY_SIZE)
|
||||
|
|
@ -1198,7 +1251,7 @@ static void compact_page(uchar *buff, uint block_size, uint rownr,
|
|||
if (extend_block)
|
||||
{
|
||||
/* 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);
|
||||
}
|
||||
else
|
||||
|
|
@ -1228,22 +1281,31 @@ static void compact_page(uchar *buff, uint block_size, uint rownr,
|
|||
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);
|
||||
|
||||
#ifndef DONT_ZERO_PAGE_BLOCKS
|
||||
/*
|
||||
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.
|
||||
The rest of the code does not assume the block is zeroed above
|
||||
PAGE_OVERHEAD_SIZE
|
||||
The code does not assume the block is zeroed.
|
||||
*/
|
||||
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[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,
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1295,7 +1357,7 @@ static my_bool get_head_or_tail_page(MARIA_HA *info,
|
|||
if (block->org_bitmap_value == 0) /* Empty block */
|
||||
{
|
||||
/* New page */
|
||||
make_empty_page(buff, block_size, page_type);
|
||||
make_empty_page(info, buff, page_type);
|
||||
res->buff= buff;
|
||||
res->empty_space= res->length= (block_size - PAGE_OVERHEAD_SIZE);
|
||||
res->data= (buff + PAGE_HEADER_SIZE);
|
||||
|
|
@ -1328,8 +1390,7 @@ static my_bool get_head_or_tail_page(MARIA_HA *info,
|
|||
{
|
||||
compact_page(res->buff, block_size, res->rownr, 1);
|
||||
/* All empty space are now after current position */
|
||||
dir= (res->buff + block_size - DIR_ENTRY_SIZE * res->rownr -
|
||||
DIR_ENTRY_SIZE - PAGE_SUFFIX_SIZE);
|
||||
dir= dir_entry_pos(res->buff, block_size, res->rownr);
|
||||
res->length= res->empty_space= uint2korr(dir+2);
|
||||
}
|
||||
if (res->length < length)
|
||||
|
|
@ -1433,7 +1494,7 @@ static my_bool write_tail(MARIA_HA *info,
|
|||
during _ma_bitmap_find_place() allocate more entries on the tail page
|
||||
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 ?
|
||||
empty_space : 0);
|
||||
block->used= BLOCKUSED_USED | BLOCKUSED_TAIL;
|
||||
|
|
@ -1535,6 +1596,9 @@ static my_bool write_full_pages(MARIA_HA *info,
|
|||
copy_length= min(data_size, length);
|
||||
memcpy(buff + LSN_SIZE + PAGE_TYPE_SIZE, data, 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);
|
||||
if (pagecache_write(share->pagecache,
|
||||
|
|
@ -2363,7 +2427,7 @@ static my_bool write_block_record(MARIA_HA *info,
|
|||
(uint) (log_array_pos - log_array),
|
||||
log_array, log_data, NULL);
|
||||
if (log_array != tmp_log_array)
|
||||
my_free((uchar*) log_array, MYF(0));
|
||||
my_free(log_array, MYF(0));
|
||||
if (error)
|
||||
goto disk_err;
|
||||
}
|
||||
|
|
@ -2566,6 +2630,7 @@ static my_bool allocate_and_write_block_record(MARIA_HA *info,
|
|||
|
||||
if (_ma_bitmap_find_place(info, row, blocks))
|
||||
DBUG_RETURN(1); /* Error reading bitmap */
|
||||
|
||||
/* page will be pinned & locked by get_head_or_tail_page */
|
||||
if (get_head_or_tail_page(info, blocks->block, info->buff,
|
||||
row->space_on_head_page, HEAD_PAGE,
|
||||
|
|
@ -2791,8 +2856,7 @@ static my_bool _ma_update_block_record2(MARIA_HA *info,
|
|||
|
||||
org_empty_size= uint2korr(buff + EMPTY_SPACE_OFFSET);
|
||||
rownr= ma_recordpos_to_dir_entry(record_pos);
|
||||
dir= (buff + block_size - DIR_ENTRY_SIZE * rownr -
|
||||
DIR_ENTRY_SIZE - PAGE_SUFFIX_SIZE);
|
||||
dir= dir_entry_pos(buff, block_size, rownr);
|
||||
|
||||
if ((org_empty_size + cur_row->head_length) >= new_row->total_length)
|
||||
{
|
||||
|
|
@ -2903,9 +2967,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,
|
||||
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;
|
||||
uchar *dir, *org_dir;
|
||||
uchar *dir;
|
||||
DBUG_ENTER("delete_dir_entry");
|
||||
|
||||
#ifdef SANITY_CHECKS
|
||||
|
|
@ -2921,33 +2985,74 @@ static int delete_dir_entry(uchar *buff, uint block_size, uint record_number,
|
|||
#endif
|
||||
|
||||
empty_space= uint2korr(buff + EMPTY_SPACE_OFFSET);
|
||||
org_dir= dir= (buff + block_size - DIR_ENTRY_SIZE * record_number -
|
||||
DIR_ENTRY_SIZE - PAGE_SUFFIX_SIZE);
|
||||
dir= dir_entry_pos(buff, block_size, record_number);
|
||||
length= uint2korr(dir + 2);
|
||||
|
||||
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;
|
||||
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--;
|
||||
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;
|
||||
empty_space+= DIR_ENTRY_SIZE;
|
||||
} while (dir < end && dir[0] == 0 && dir[1] == 0);
|
||||
}
|
||||
|
||||
if (number_of_records == 0)
|
||||
{
|
||||
/* All entries on page deleted */
|
||||
DBUG_PRINT("info", ("Page marked as unallocated"));
|
||||
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;
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
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;
|
||||
|
||||
/* 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);
|
||||
buff[PAGE_TYPE_OFFSET]|= (uchar) PAGE_CAN_BE_COMPACTED;
|
||||
|
||||
|
|
@ -3214,7 +3319,7 @@ err:
|
|||
static uchar *get_record_position(uchar *buff, uint block_size,
|
||||
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 *data;
|
||||
uint offset, length;
|
||||
|
|
@ -3231,8 +3336,7 @@ static uchar *get_record_position(uchar *buff, uint block_size,
|
|||
}
|
||||
#endif
|
||||
|
||||
dir= (buff + block_size - DIR_ENTRY_SIZE * record_number -
|
||||
DIR_ENTRY_SIZE - PAGE_SUFFIX_SIZE);
|
||||
dir= dir_entry_pos(buff, block_size, record_number);
|
||||
offset= uint2korr(dir);
|
||||
length= uint2korr(dir + 2);
|
||||
#ifdef SANITY_CHECKS
|
||||
|
|
@ -3354,7 +3458,7 @@ static uchar *read_next_extent(MARIA_HA *info, MARIA_EXTENT_CURSOR *extent,
|
|||
goto crashed;
|
||||
extent->page++; /* point to next page */
|
||||
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 */
|
||||
DBUG_RETURN(extent->data_start= buff + LSN_SIZE + PAGE_TYPE_SIZE);
|
||||
}
|
||||
|
|
@ -4176,8 +4280,8 @@ static void _ma_print_directory(uchar *buff, uint block_size)
|
|||
uint end_of_prev_row= PAGE_HEADER_SIZE;
|
||||
uchar *dir, *end;
|
||||
|
||||
dir= buff + block_size - DIR_ENTRY_SIZE * max_entry - PAGE_SUFFIX_SIZE;
|
||||
end= buff + block_size - DIR_ENTRY_SIZE - PAGE_SUFFIX_SIZE;
|
||||
dir= dir_entry_pos(buff, block_size, max_entry-1);
|
||||
end= dir_entry_pos(buff, block_size, 0);
|
||||
|
||||
DBUG_LOCK_FILE;
|
||||
fprintf(DBUG_FILE,"Directory dump (pos:length):\n");
|
||||
|
|
@ -4936,7 +5040,7 @@ uint _ma_apply_redo_insert_row_head_or_tail(MARIA_HA *info, LSN lsn,
|
|||
DBUG_ASSERT(rownr == 0);
|
||||
if (rownr != 0)
|
||||
goto err;
|
||||
make_empty_page(buff, block_size, page_type);
|
||||
make_empty_page(info, buff, page_type);
|
||||
empty_space= (block_size - PAGE_OVERHEAD_SIZE);
|
||||
rec_offset= PAGE_HEADER_SIZE;
|
||||
dir= buff+ block_size - PAGE_SUFFIX_SIZE - DIR_ENTRY_SIZE;
|
||||
|
|
@ -4945,7 +5049,6 @@ uint _ma_apply_redo_insert_row_head_or_tail(MARIA_HA *info, LSN lsn,
|
|||
}
|
||||
else
|
||||
{
|
||||
uint max_entry;
|
||||
if (!(buff= pagecache_read(share->pagecache, &info->dfile,
|
||||
page, 0, 0,
|
||||
PAGECACHE_PLAIN_PAGE, PAGECACHE_LOCK_WRITE,
|
||||
|
|
@ -4966,25 +5069,27 @@ uint _ma_apply_redo_insert_row_head_or_tail(MARIA_HA *info, LSN lsn,
|
|||
unlock_method= PAGECACHE_LOCK_WRITE_UNLOCK;
|
||||
unpin_method= PAGECACHE_UNPIN;
|
||||
|
||||
max_entry= (uint) ((uchar*) buff)[DIR_COUNT_OFFSET];
|
||||
if (((buff[PAGE_TYPE_OFFSET] & PAGE_TYPE_MASK) != page_type))
|
||||
{
|
||||
/*
|
||||
This is a page that has been freed before and now should be
|
||||
changed to new type.
|
||||
*/
|
||||
if ((buff[PAGE_TYPE_OFFSET] & PAGE_TYPE_MASK) != BLOB_PAGE &&
|
||||
(buff[PAGE_TYPE_OFFSET] & PAGE_TYPE_MASK) != UNALLOCATED_PAGE)
|
||||
DBUG_ASSERT(rownr == 0);
|
||||
if (((buff[PAGE_TYPE_OFFSET] & PAGE_TYPE_MASK) != BLOB_PAGE &&
|
||||
(buff[PAGE_TYPE_OFFSET] & PAGE_TYPE_MASK) != UNALLOCATED_PAGE) ||
|
||||
rownr != 0)
|
||||
goto err;
|
||||
make_empty_page(buff, block_size, page_type);
|
||||
make_empty_page(info, buff, page_type);
|
||||
empty_space= (block_size - PAGE_OVERHEAD_SIZE);
|
||||
rec_offset= PAGE_HEADER_SIZE;
|
||||
dir= buff+ block_size - PAGE_SUFFIX_SIZE - DIR_ENTRY_SIZE;
|
||||
}
|
||||
else
|
||||
{
|
||||
dir= (buff + block_size - DIR_ENTRY_SIZE * (rownr + 1) -
|
||||
PAGE_SUFFIX_SIZE);
|
||||
uint max_entry= (uint) buff[DIR_COUNT_OFFSET];
|
||||
|
||||
dir= dir_entry_pos(buff, block_size, rownr);
|
||||
empty_space= uint2korr(buff + EMPTY_SPACE_OFFSET);
|
||||
|
||||
if (max_entry <= rownr)
|
||||
|
|
@ -5000,7 +5105,7 @@ uint _ma_apply_redo_insert_row_head_or_tail(MARIA_HA *info, LSN lsn,
|
|||
/* Create place for directory & data */
|
||||
compact_page(buff, block_size, max_entry - 1, 0);
|
||||
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);
|
||||
DBUG_ASSERT(!((uint) (dir - buff) < rec_offset + data_length));
|
||||
if ((uint) (dir - buff) < rec_offset + data_length)
|
||||
|
|
@ -5218,6 +5323,15 @@ uint _ma_apply_redo_purge_blocks(MARIA_HA *info,
|
|||
continue;
|
||||
}
|
||||
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);
|
||||
if (pagecache_write(share->pagecache,
|
||||
&info->dfile, page+i, 0,
|
||||
|
|
|
|||
|
|
@ -13,22 +13,25 @@
|
|||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
|
||||
/*
|
||||
Storage of records in block
|
||||
*/
|
||||
|
||||
#define LSN_SIZE 7
|
||||
#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 PAGE_TYPE_SIZE 1
|
||||
#define PAGE_SUFFIX_SIZE 0 /* Bytes for page suffix */
|
||||
#define PAGE_HEADER_SIZE (LSN_SIZE + DIR_COUNT_SIZE + EMPTY_SPACE_SIZE +\
|
||||
PAGE_TYPE_SIZE)
|
||||
#define PAGE_SUFFIX_SIZE 4 /* Bytes for checksum */
|
||||
#define PAGE_HEADER_SIZE (LSN_SIZE + DIR_COUNT_SIZE + DIR_FREE_SIZE +\
|
||||
EMPTY_SPACE_SIZE + PAGE_TYPE_SIZE)
|
||||
#define PAGE_OVERHEAD_SIZE (PAGE_HEADER_SIZE + DIR_ENTRY_SIZE + \
|
||||
PAGE_SUFFIX_SIZE)
|
||||
#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_COUNT_SIZE 2
|
||||
|
|
@ -40,7 +43,6 @@
|
|||
#define EXTRA_LENGTH_FIELDS 3
|
||||
|
||||
/* Size for the different parts in the row header (and head page) */
|
||||
|
||||
#define FLAG_SIZE 1
|
||||
#define TRANSID_SIZE 6
|
||||
#define VERPTR_SIZE 7
|
||||
|
|
@ -51,12 +53,13 @@
|
|||
#define BASE_ROW_HEADER_SIZE FLAG_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 };
|
||||
|
||||
#define PAGE_TYPE_OFFSET LSN_SIZE
|
||||
#define DIR_COUNT_OFFSET LSN_SIZE+PAGE_TYPE_SIZE
|
||||
#define EMPTY_SPACE_OFFSET (DIR_COUNT_OFFSET + DIR_COUNT_SIZE)
|
||||
#define DIR_COUNT_OFFSET (LSN_SIZE+PAGE_TYPE_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 */
|
||||
|
||||
|
|
@ -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 */
|
||||
#define MAX_ROWS_PER_PAGE 255
|
||||
#define END_OF_DIR_FREE_LIST ((uchar) 255)
|
||||
|
||||
/* Bits for MARIA_BITMAP_BLOCKS->used */
|
||||
/* 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);
|
||||
}
|
||||
|
||||
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 */
|
||||
void _ma_init_block_record_data(void);
|
||||
my_bool _ma_once_init_block_record(MARIA_SHARE *share, File dfile);
|
||||
|
|
|
|||
|
|
@ -314,7 +314,11 @@ static int check_k_link(HA_CHECK *param, register MARIA_HA *info,
|
|||
DBUG_RETURN(1);
|
||||
/* 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--;
|
||||
param->key_file_blocks+=block_size;
|
||||
}
|
||||
|
|
@ -419,7 +423,7 @@ int maria_chk_key(HA_CHECK *param, register MARIA_HA *info)
|
|||
ha_rows keys;
|
||||
ha_checksum old_record_checksum,init_checksum;
|
||||
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_KEYDEF *keyinfo;
|
||||
char buff[22],buff2[22];
|
||||
|
|
@ -445,7 +449,7 @@ int maria_chk_key(HA_CHECK *param, register MARIA_HA *info)
|
|||
old_record_checksum= (calc_checksum(info->state->records +
|
||||
info->state->del-1) *
|
||||
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 ;
|
||||
rec_per_key_part+=keyinfo->keysegs, key++, keyinfo++)
|
||||
{
|
||||
|
|
@ -455,7 +459,7 @@ int maria_chk_key(HA_CHECK *param, register MARIA_HA *info)
|
|||
/* Remember old statistics for key */
|
||||
memcpy((char*) 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));
|
||||
continue;
|
||||
}
|
||||
|
|
@ -628,7 +632,7 @@ static int chk_index_down(HA_CHECK *param, MARIA_HA *info,
|
|||
{
|
||||
/* purecov: begin tested */
|
||||
_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);
|
||||
goto err;
|
||||
/* purecov: end */
|
||||
|
|
@ -743,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,
|
||||
my_off_t page, uchar *buff, ha_rows *keys,
|
||||
|
|
@ -756,7 +760,7 @@ static int chk_index(HA_CHECK *param, MARIA_HA *info, MARIA_KEYDEF *keyinfo,
|
|||
char llbuff[22];
|
||||
uint diff_pos[2];
|
||||
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 */
|
||||
if (keyinfo->flag & HA_SPATIAL)
|
||||
|
|
@ -772,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 */
|
||||
else
|
||||
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++;
|
||||
if (level > param->max_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)
|
||||
{
|
||||
_ma_check_print_error(param,"Wrong pageinfo at page: %s",
|
||||
|
|
@ -1389,7 +1399,7 @@ end:
|
|||
|
||||
|
||||
/*
|
||||
Check if layout on a page is ok
|
||||
Check if layout on head or tail page is ok
|
||||
|
||||
NOTES
|
||||
This is for rows-in-block format.
|
||||
|
|
@ -1400,17 +1410,62 @@ static int check_page_layout(HA_CHECK *param, MARIA_HA *info,
|
|||
uint row_count, uint head_empty,
|
||||
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;
|
||||
char llbuff[22];
|
||||
my_bool error_in_free_list= 0;
|
||||
DBUG_ENTER("check_page_layout");
|
||||
|
||||
block_size= info->s->block_size;
|
||||
empty= 0;
|
||||
last_row_end= PAGE_HEADER_SIZE;
|
||||
*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;
|
||||
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++)
|
||||
{
|
||||
uint pos, length;
|
||||
|
|
@ -1418,6 +1473,7 @@ static int check_page_layout(HA_CHECK *param, MARIA_HA *info,
|
|||
pos= uint2korr(dir_entry);
|
||||
if (!pos)
|
||||
{
|
||||
free_entries--;
|
||||
if (row == row_count -1)
|
||||
{
|
||||
_ma_check_print_error(param,
|
||||
|
|
@ -1455,9 +1511,18 @@ static int check_page_layout(HA_CHECK *param, MARIA_HA *info,
|
|||
_ma_check_print_error(param,
|
||||
"Page %9s: Wrong empty size. Stored: %5u Actual: %5u",
|
||||
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)));
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1666,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)
|
||||
{
|
||||
_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);
|
||||
if (param->err_count++ > MAXERR || !(param->testflag & T_VERBOSE))
|
||||
goto err;
|
||||
|
|
@ -1832,7 +1897,7 @@ int maria_chk_data_link(HA_CHECK *param, MARIA_HA *info,int extend)
|
|||
(HA_OPTION_CHECKSUM | HA_OPTION_COMPRESS_RECORD)))
|
||||
{
|
||||
_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;
|
||||
}
|
||||
else if (!extend)
|
||||
|
|
@ -2425,7 +2490,7 @@ int maria_movepoint(register MARIA_HA *info, uchar *record,
|
|||
(uint) (SEARCH_SAME | SEARCH_SAVE_BUFF),
|
||||
info->s->state.key_root[i]))
|
||||
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-
|
||||
info->s->rec_reflength,newpos);
|
||||
if (_ma_write_keypage(info,keyinfo,info->last_keypage,
|
||||
|
|
@ -2621,11 +2686,11 @@ static int sort_one_index(HA_CHECK *param, MARIA_HA *info,
|
|||
llstr(pagepos,llbuff));
|
||||
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);
|
||||
keypos=buff+2+nod_flag;
|
||||
endpos=buff+used_length;
|
||||
used_length= _ma_get_page_used(info, buff);
|
||||
keypos=buff + info->s->keypage_header + nod_flag;
|
||||
endpos=buff + used_length;
|
||||
for ( ;; )
|
||||
{
|
||||
if (nod_flag)
|
||||
|
|
@ -2667,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 */
|
||||
length= maria_data_on_page(buff);
|
||||
length= _ma_get_page_used(info, buff);
|
||||
bzero((uchar*) buff+length,keyinfo->block_length-length);
|
||||
if (my_pwrite(new_file,(uchar*) buff,(uint) keyinfo->block_length,
|
||||
new_page_pos,MYF(MY_NABP | MY_WAIT_IF_FULL)))
|
||||
|
|
@ -2776,7 +2841,7 @@ int maria_repair_by_sort(HA_CHECK *param, register MARIA_HA *info,
|
|||
MARIA_SORT_PARAM sort_param;
|
||||
MARIA_SHARE *share=info->s;
|
||||
HA_KEYSEG *keyseg;
|
||||
ulong *rec_per_key_part;
|
||||
double *rec_per_key_part;
|
||||
char llbuff[22];
|
||||
MARIA_SORT_INFO sort_info;
|
||||
ulonglong key_map=share->state.key_map;
|
||||
|
|
@ -2913,7 +2978,7 @@ int maria_repair_by_sort(HA_CHECK *param, register MARIA_HA *info,
|
|||
if (param->testflag & T_CALC_CHECKSUM)
|
||||
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 ;
|
||||
rec_per_key_part+=sort_param.keyinfo->keysegs, sort_param.key++)
|
||||
{
|
||||
|
|
@ -2925,7 +2990,7 @@ int maria_repair_by_sort(HA_CHECK *param, register MARIA_HA *info,
|
|||
/* Remember old statistics for key */
|
||||
memcpy((char*) 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));
|
||||
continue;
|
||||
}
|
||||
|
|
@ -2991,8 +3056,8 @@ int maria_repair_by_sort(HA_CHECK *param, register MARIA_HA *info,
|
|||
}
|
||||
|
||||
if (_ma_create_index_by_sort(&sort_param,
|
||||
(my_bool) (!(param->testflag & T_VERBOSE)),
|
||||
(uint) param->sort_buffer_length))
|
||||
(my_bool) (!(param->testflag & T_VERBOSE)),
|
||||
(size_t) param->sort_buffer_length))
|
||||
{
|
||||
param->retry_repair=1;
|
||||
goto err;
|
||||
|
|
@ -3005,9 +3070,11 @@ int maria_repair_by_sort(HA_CHECK *param, register MARIA_HA *info,
|
|||
sort_info.max_records= (ha_rows) info->state->records;
|
||||
|
||||
if (param->testflag & T_STATISTICS)
|
||||
maria_update_key_parts(sort_param.keyinfo, rec_per_key_part, sort_param.unique,
|
||||
param->stats_method == MI_STATS_METHOD_IGNORE_NULLS?
|
||||
sort_param.notnull: NULL,(ulonglong) info->state->records);
|
||||
maria_update_key_parts(sort_param.keyinfo, rec_per_key_part,
|
||||
sort_param.unique,
|
||||
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);
|
||||
|
||||
if (sort_param.fix_datafile)
|
||||
|
|
@ -3201,7 +3268,7 @@ int maria_repair_parallel(HA_CHECK *param, register MARIA_HA *info,
|
|||
File new_file;
|
||||
MARIA_SORT_PARAM *sort_param=0;
|
||||
MARIA_SHARE *share=info->s;
|
||||
ulong *rec_per_key_part;
|
||||
double *rec_per_key_part;
|
||||
HA_KEYSEG *keyseg;
|
||||
char llbuff[22];
|
||||
IO_CACHE new_data_cache; /* For non-quick repair. */
|
||||
|
|
@ -3378,7 +3445,7 @@ int maria_repair_parallel(HA_CHECK *param, register MARIA_HA *info,
|
|||
goto err;
|
||||
}
|
||||
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->empty=0;
|
||||
|
||||
|
|
@ -3393,7 +3460,7 @@ int maria_repair_parallel(HA_CHECK *param, register MARIA_HA *info,
|
|||
/* Remember old statistics for key */
|
||||
memcpy((char*) 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));
|
||||
istep=0;
|
||||
continue;
|
||||
|
|
@ -4657,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");
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
a_length=2+nod_flag;
|
||||
key_block->end_pos=anc_buff+2;
|
||||
a_length= info->s->keypage_header + nod_flag;
|
||||
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 */
|
||||
}
|
||||
else
|
||||
a_length= maria_data_on_page(anc_buff);
|
||||
a_length= _ma_get_page_used(info, anc_buff);
|
||||
|
||||
/* Save pointer to previous block */
|
||||
if (nod_flag)
|
||||
|
|
@ -4673,7 +4742,7 @@ static int sort_insert_key(MARIA_SORT_PARAM *sort_param,
|
|||
&s_temp);
|
||||
(*keyinfo->store_key)(keyinfo, key_block->end_pos+nod_flag,&s_temp);
|
||||
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;
|
||||
if (a_length <= keyinfo->block_length)
|
||||
{
|
||||
|
|
@ -4682,8 +4751,8 @@ static int sort_insert_key(MARIA_SORT_PARAM *sort_param,
|
|||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
/* Fill block with end-zero and write filled block */
|
||||
maria_putint(anc_buff,key_block->last_length,nod_flag);
|
||||
/* Fill block with end-zero and write filled block */
|
||||
_ma_store_page_used(info, anc_buff, key_block->last_length, nod_flag);
|
||||
bzero(anc_buff+key_block->last_length,
|
||||
keyinfo->block_length- key_block->last_length);
|
||||
key_file_length=info->state->key_file_length;
|
||||
|
|
@ -4699,7 +4768,7 @@ static int sort_insert_key(MARIA_SORT_PARAM *sort_param,
|
|||
else if (my_pwrite(info->s->kfile.file, anc_buff,
|
||||
(uint) keyinfo->block_length,filepos, param->myf_rw))
|
||||
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 */
|
||||
if (sort_insert_key(sort_param,key_block+1,key_block->lastkey,filepos))
|
||||
|
|
@ -4793,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++)
|
||||
{
|
||||
key_block->inited=0;
|
||||
length= maria_data_on_page(key_block->buff);
|
||||
length= _ma_get_page_used(info, key_block->buff);
|
||||
if (nod_flag)
|
||||
_ma_kpointer(info,key_block->end_pos,filepos);
|
||||
key_file_length=info->state->key_file_length;
|
||||
|
|
@ -5080,13 +5149,13 @@ int maria_update_state_info(HA_CHECK *param, MARIA_HA *info,uint update)
|
|||
if (update & UPDATE_STAT)
|
||||
{
|
||||
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;
|
||||
if (info->state->records)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
@ -5247,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
|
||||
*/
|
||||
|
||||
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 records)
|
||||
{
|
||||
ulonglong count=0,tmp, unique_tuples;
|
||||
ulonglong count=0, unique_tuples;
|
||||
ulonglong tuples= records;
|
||||
uint parts;
|
||||
double tmp;
|
||||
for (parts=0 ; parts < keyinfo->keysegs ; parts++)
|
||||
{
|
||||
count+=unique[parts];
|
||||
|
|
@ -5272,20 +5342,17 @@ void maria_update_key_parts(MARIA_KEYDEF *keyinfo, ulong *rec_per_key_part,
|
|||
if (unique_tuples == 0)
|
||||
tmp= 1;
|
||||
else if (count == 0)
|
||||
tmp= tuples; /* 1 unique tuple */
|
||||
tmp= ulonglong2double(tuples); /* 1 unique tuple */
|
||||
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.
|
||||
let's ensure it is not
|
||||
*/
|
||||
set_if_bigger(tmp,1);
|
||||
if (tmp >= (ulonglong) ~(ulong) 0)
|
||||
tmp=(ulonglong) ~(ulong) 0;
|
||||
|
||||
*rec_per_key_part=(ulong) tmp;
|
||||
rec_per_key_part++;
|
||||
*rec_per_key_part++= tmp;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -17,23 +17,40 @@
|
|||
|
||||
#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 crc=0;
|
||||
MARIA_COLUMNDEF *column= info->s->columndef;
|
||||
MARIA_COLUMNDEF *column_end= column+ info->s->base.fields;
|
||||
uint i,end;
|
||||
MARIA_COLUMNDEF *base_column= info->s->columndef;
|
||||
uint16 *column_nr= info->s->column_nr;
|
||||
|
||||
if (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;
|
||||
|
||||
if (record[column->null_pos] & column->null_bit)
|
||||
continue; /* Null field */
|
||||
|
||||
pos= record + column->offset;
|
||||
switch (column->type) {
|
||||
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,
|
||||
base_pos,long_varchar_count,varchar_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;
|
||||
char filename[FN_REFLEN], linkname[FN_REFLEN], *linkname_ptr;
|
||||
ulong pack_reclength;
|
||||
|
|
@ -62,7 +62,9 @@ int maria_create(const char *name, enum data_file_type datafile_type,
|
|||
MARIA_UNIQUEDEF *uniquedef;
|
||||
HA_KEYSEG *keyseg,tmp_keyseg;
|
||||
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;
|
||||
MARIA_CREATE_INFO tmp_create_info;
|
||||
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 */
|
||||
|
||||
if (!(rec_per_key_part=
|
||||
(ulong*) my_malloc((keys + uniques)*HA_MAX_KEY_SEG*sizeof(long),
|
||||
MYF(MY_WME | MY_ZEROFILL))))
|
||||
(double*) my_malloc((keys + uniques)*HA_MAX_KEY_SEG*sizeof(double) +
|
||||
(keys + uniques)*HA_MAX_KEY_SEG*sizeof(ulong) +
|
||||
sizeof(uint16) * columns,
|
||||
MYF(MY_WME | MY_ZEROFILL))))
|
||||
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 */
|
||||
|
||||
|
|
@ -121,12 +130,14 @@ int maria_create(const char *name, enum data_file_type datafile_type,
|
|||
pack_reclength= max_field_lengths= 0;
|
||||
reclength= min_pack_length= ci->null_bytes;
|
||||
forced_packed= 0;
|
||||
column_nr= 0;
|
||||
|
||||
for (column= columndef, end_column= column + columns ;
|
||||
column != end_column ;
|
||||
column++)
|
||||
{
|
||||
/* Fill in not used struct parts */
|
||||
column->column_nr= column_nr++;
|
||||
column->offset= reclength;
|
||||
column->empty_pos= 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;
|
||||
if (flags & HA_CREATE_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;
|
||||
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;
|
||||
if (!data_file_length)
|
||||
data_file_length= ((((ulonglong) 1 << ((BLOCK_RECORD_POINTER_SIZE-1) *
|
||||
8)) -1));
|
||||
8)) -1) * maria_block_size);
|
||||
if (rows_per_page > 0)
|
||||
{
|
||||
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;
|
||||
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 /
|
||||
maria_block_size), 3) + 1;
|
||||
(maria_block_size * 2)), 3) + 1;
|
||||
set_if_smaller(pointer, BLOCK_RECORD_POINTER_SIZE);
|
||||
|
||||
if (!max_rows)
|
||||
max_rows= (((((ulonglong) 1 << ((pointer-1)*8)) -1) * maria_block_size) /
|
||||
min_pack_length);
|
||||
}
|
||||
min_pack_length / 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
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;
|
||||
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_del= HA_OFFSET_ERROR;
|
||||
if (uniques)
|
||||
|
|
@ -607,7 +625,7 @@ int maria_create(const char *name, enum data_file_type datafile_type,
|
|||
keys * MARIA_KEYDEF_SIZE+
|
||||
uniques * MARIA_UNIQUEDEF_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));
|
||||
/* 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);
|
||||
ci->old_options=options| (ci->old_options & HA_OPTION_TEMP_COMPRESS_RECORD ?
|
||||
HA_OPTION_COMPRESS_RECORD |
|
||||
HA_OPTION_TEMP_COMPRESS_RECORD: 0);
|
||||
ci->old_options=options | (ci->old_options & HA_OPTION_TEMP_COMPRESS_RECORD ?
|
||||
HA_OPTION_COMPRESS_RECORD |
|
||||
HA_OPTION_TEMP_COMPRESS_RECORD: 0);
|
||||
mi_int2store(share.state.header.options,ci->old_options);
|
||||
mi_int2store(share.state.header.header_length,info_length);
|
||||
mi_int2store(share.state.header.state_info_length,MARIA_STATE_INFO_SIZE);
|
||||
|
|
@ -901,6 +919,7 @@ int maria_create(const char *name, enum data_file_type datafile_type,
|
|||
(qsort_cmp) compare_columns);
|
||||
for (i=0 ; i < share.base.fields ; i++)
|
||||
{
|
||||
column_array[col_order[i]->column_nr]= i;
|
||||
if (_ma_columndef_write(file, col_order[i]))
|
||||
{
|
||||
my_free((uchar*) col_order, MYF(0));
|
||||
|
|
@ -912,9 +931,14 @@ int maria_create(const char *name, enum data_file_type datafile_type,
|
|||
else
|
||||
{
|
||||
for (i=0 ; i < share.base.fields ; i++)
|
||||
{
|
||||
column_array[i]= (uint16) i;
|
||||
if (_ma_columndef_write(file, &columndef[i]))
|
||||
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)
|
||||
goto err;
|
||||
|
|
|
|||
|
|
@ -92,7 +92,7 @@ void _ma_print_key(FILE *stream, register HA_KEYSEG *keyseg,
|
|||
key=end;
|
||||
break;
|
||||
case HA_KEYTYPE_ULONG_INT:
|
||||
l_1=mi_sint4korr(key);
|
||||
l_1=mi_uint4korr(key);
|
||||
VOID(fprintf(stream,"%lu",(ulong) l_1));
|
||||
key=end;
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -179,8 +179,8 @@ static int _ma_ck_real_delete(register MARIA_HA *info, MARIA_KEYDEF *keyinfo,
|
|||
goto err;
|
||||
}
|
||||
if ((error=d_search(info,keyinfo,
|
||||
(keyinfo->flag & HA_FULLTEXT ? SEARCH_FIND | SEARCH_UPDATE
|
||||
: SEARCH_SAME),
|
||||
(keyinfo->flag & HA_FULLTEXT ?
|
||||
SEARCH_FIND | SEARCH_UPDATE : SEARCH_SAME),
|
||||
key,key_length,old_root,root_buff)) >0)
|
||||
{
|
||||
if (error == 2)
|
||||
|
|
@ -190,11 +190,14 @@ static int _ma_ck_real_delete(register MARIA_HA *info, MARIA_KEYDEF *keyinfo,
|
|||
}
|
||||
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;
|
||||
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
|
||||
*root=HA_OFFSET_ERROR;
|
||||
if (_ma_dispose(info,keyinfo,old_root,DFLT_INIT_HITS))
|
||||
|
|
@ -212,13 +215,14 @@ err:
|
|||
} /* _ma_ck_real_delete */
|
||||
|
||||
|
||||
/*
|
||||
** Remove key below key root
|
||||
** Return values:
|
||||
** 1 if there are less buffers; In this case anc_buff is not saved
|
||||
** 2 if there are more buffers
|
||||
** -1 on errors
|
||||
*/
|
||||
/*
|
||||
@brief Remove key below key root
|
||||
|
||||
@return
|
||||
@retval 1 If there are less buffers; In this case anc_buff is not saved
|
||||
@retval 2 If there are more buffers
|
||||
@retval -1 On errors
|
||||
*/
|
||||
|
||||
static int d_search(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
|
||||
uint comp_flag, uchar *key, uint key_length,
|
||||
|
|
@ -231,7 +235,7 @@ static int d_search(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
|
|||
my_off_t leaf_page,next_block;
|
||||
uchar lastkey[HA_MAX_KEY_BUFF];
|
||||
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;
|
||||
flag=(*keyinfo->bin_search)(info,keyinfo,anc_buff,key, search_key_length,
|
||||
|
|
@ -241,7 +245,7 @@ static int d_search(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
|
|||
DBUG_PRINT("error",("Found wrong key"));
|
||||
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)
|
||||
{
|
||||
|
|
@ -341,14 +345,14 @@ static int d_search(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
|
|||
else
|
||||
{ /* Found key */
|
||||
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,
|
||||
&next_block)))
|
||||
goto err;
|
||||
|
||||
length-= tmp;
|
||||
|
||||
maria_putint(anc_buff,length,nod_flag);
|
||||
_ma_store_page_used(info, anc_buff, length, nod_flag);
|
||||
if (!nod_flag)
|
||||
{ /* On leaf page */
|
||||
if (_ma_write_keypage(info,keyinfo,page,DFLT_INIT_HITS,anc_buff))
|
||||
|
|
@ -378,7 +382,8 @@ static int d_search(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
|
|||
(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;
|
||||
ret_value= _ma_split_page(info,keyinfo,key,anc_buff,lastkey,0) | 2;
|
||||
|
|
@ -387,7 +392,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);
|
||||
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);
|
||||
DBUG_PRINT("exit",("Return: %d",ret_value));
|
||||
|
|
@ -410,7 +415,7 @@ static int del(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
|
|||
uchar *ret_key) /* key before keypos in anc_buff */
|
||||
{
|
||||
int ret_value,length;
|
||||
uint a_length,nod_flag,tmp;
|
||||
uint a_length, nod_flag, used_length, tmp;
|
||||
my_off_t next_page;
|
||||
uchar keybuff[HA_MAX_KEY_BUFF],*endpos,*next_buff,*key_start, *prev_key;
|
||||
MARIA_SHARE *share=info->s;
|
||||
|
|
@ -418,14 +423,16 @@ static int del(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
|
|||
DBUG_ENTER("del");
|
||||
DBUG_PRINT("enter",("leaf_page: %ld keypos: 0x%lx", (long) leaf_page,
|
||||
(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,
|
||||
&tmp)))
|
||||
DBUG_RETURN(-1);
|
||||
|
||||
if ((nod_flag=_ma_test_if_nod(leaf_buff)))
|
||||
if (nod_flag)
|
||||
{
|
||||
next_page= _ma_kpos(nod_flag,endpos);
|
||||
if (!(next_buff= (uchar*) my_alloca((uint) keyinfo->block_length+
|
||||
|
|
@ -435,18 +442,22 @@ static int del(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
|
|||
ret_value= -1;
|
||||
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,
|
||||
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)
|
||||
{
|
||||
ret_value=underflow(info,keyinfo,leaf_buff,next_page,
|
||||
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
|
||||
|
|
@ -467,20 +478,19 @@ static int del(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
|
|||
}
|
||||
|
||||
/* Remove last key from leaf page */
|
||||
|
||||
maria_putint(leaf_buff,key_start-leaf_buff,nod_flag);
|
||||
_ma_store_page_used(info, leaf_buff, key_start-leaf_buff, nod_flag);
|
||||
if (_ma_write_keypage(info,keyinfo,leaf_page,DFLT_INIT_HITS,leaf_buff))
|
||||
goto err;
|
||||
|
||||
/* 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;
|
||||
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))
|
||||
goto err;
|
||||
prev_key=(keypos == anc_buff+2+share->base.key_reflength ?
|
||||
0 : ret_key);
|
||||
prev_key= (keypos == anc_buff + info->s->keypage_header +
|
||||
share->base.key_reflength ? 0 : ret_key);
|
||||
length=(*keyinfo->pack_key)(keyinfo,share->base.key_reflength,
|
||||
keypos == endpos ? (uchar*) 0 : keypos,
|
||||
prev_key, prev_key,
|
||||
|
|
@ -494,11 +504,12 @@ static int del(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
|
|||
if (!(*keyinfo->get_key)(keyinfo,share->base.key_reflength,&keypos,ret_key))
|
||||
goto err;
|
||||
_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) <=
|
||||
(info->quick_mode ? MARIA_MIN_KEYBLOCK_LENGTH :
|
||||
(uint) keyinfo->underflow_block_length));
|
||||
DBUG_RETURN(_ma_get_page_used(info, leaf_buff) <=
|
||||
(info->quick_mode ? MARIA_MIN_KEYBLOCK_LENGTH :
|
||||
(uint) keyinfo->underflow_block_length));
|
||||
err:
|
||||
DBUG_RETURN(-1);
|
||||
} /* del */
|
||||
|
|
@ -524,22 +535,22 @@ static int underflow(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
|
|||
DBUG_ENTER("underflow");
|
||||
DBUG_PRINT("enter",("leaf_page: %ld keypos: 0x%lx",(long) leaf_page,
|
||||
(ulong) keypos));
|
||||
DBUG_DUMP("anc_buff",anc_buff,maria_data_on_page(anc_buff));
|
||||
DBUG_DUMP("leaf_buff",leaf_buff,maria_data_on_page(leaf_buff));
|
||||
DBUG_DUMP("anc_buff", anc_buff, _ma_get_page_used(info, anc_buff));
|
||||
DBUG_DUMP("leaf_buff", leaf_buff, _ma_get_page_used(info, leaf_buff));
|
||||
|
||||
buff=info->buff;
|
||||
info->keyread_buff_used=1;
|
||||
next_keypos=keypos;
|
||||
nod_flag=_ma_test_if_nod(leaf_buff);
|
||||
p_length=nod_flag+2;
|
||||
anc_length= maria_data_on_page(anc_buff);
|
||||
leaf_length= maria_data_on_page(leaf_buff);
|
||||
nod_flag= _ma_test_if_nod(info, leaf_buff);
|
||||
p_length= nod_flag+info->s->keypage_header;
|
||||
anc_length= _ma_get_page_used(info, anc_buff);
|
||||
leaf_length= _ma_get_page_used(info, leaf_buff);
|
||||
key_reflength=share->base.key_reflength;
|
||||
if (info->s->keyinfo+info->lastinx == keyinfo)
|
||||
info->page_changed=1;
|
||||
|
||||
if ((keypos < anc_buff+anc_length && (info->state->records & 1)) ||
|
||||
keypos == anc_buff+2+key_reflength)
|
||||
if ((keypos < anc_buff + anc_length && (info->state->records & 1)) ||
|
||||
keypos == anc_buff + info->s->keypage_header + key_reflength)
|
||||
{ /* Use page right of anc-page */
|
||||
DBUG_PRINT("test",("use right page"));
|
||||
|
||||
|
|
@ -560,14 +571,15 @@ static int underflow(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
|
|||
next_page= _ma_kpos(key_reflength,next_keypos);
|
||||
if (!_ma_fetch_keypage(info,keyinfo,next_page,DFLT_INIT_HITS,buff,0))
|
||||
goto err;
|
||||
buff_length= maria_data_on_page(buff);
|
||||
buff_length= _ma_get_page_used(info, buff);
|
||||
DBUG_DUMP("next",buff,buff_length);
|
||||
|
||||
/* find keys to make a big key-page */
|
||||
bmove(next_keypos-key_reflength, buff+2, key_reflength);
|
||||
if (!_ma_get_last_key(info,keyinfo,anc_buff,anc_key,next_keypos,&length)
|
||||
|| !_ma_get_last_key(info,keyinfo,leaf_buff,leaf_key,
|
||||
leaf_buff+leaf_length,&length))
|
||||
bmove(next_keypos-key_reflength, buff + info->s->keypage_header,
|
||||
key_reflength);
|
||||
if (!_ma_get_last_key(info,keyinfo,anc_buff,anc_key,next_keypos,&length) ||
|
||||
!_ma_get_last_key(info,keyinfo,leaf_buff,leaf_key,
|
||||
leaf_buff+leaf_length,&length))
|
||||
goto err;
|
||||
|
||||
/* merge pages and put parting key from anc_buff between */
|
||||
|
|
@ -582,7 +594,7 @@ static int underflow(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
|
|||
memcpy(buff, leaf_buff,(size_t) leaf_length);
|
||||
(*keyinfo->store_key)(keyinfo,buff+leaf_length,&s_temp);
|
||||
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 */
|
||||
|
||||
|
|
@ -591,9 +603,9 @@ static int underflow(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
|
|||
goto err;
|
||||
|
||||
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 */
|
||||
memcpy(leaf_buff,buff,(size_t) buff_length);
|
||||
if (_ma_dispose(info,keyinfo,next_page,DFLT_INIT_HITS))
|
||||
|
|
@ -604,21 +616,22 @@ static int underflow(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
|
|||
endpos=anc_buff+anc_length;
|
||||
DBUG_PRINT("test",("anc_buff: 0x%lx endpos: 0x%lx",
|
||||
(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))
|
||||
goto err;
|
||||
if (!(half_pos= _ma_find_half_pos(nod_flag, keyinfo, buff, leaf_key,
|
||||
&key_length, &after_key)))
|
||||
if (!(half_pos= _ma_find_half_pos(info, nod_flag, keyinfo, buff,
|
||||
leaf_key, &key_length, &after_key)))
|
||||
goto err;
|
||||
length=(uint) (half_pos-buff);
|
||||
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 */
|
||||
half_pos=after_key;
|
||||
_ma_kpointer(info,leaf_key+key_length,next_page);
|
||||
/* 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,
|
||||
(keypos == endpos ? (uchar*) 0 :
|
||||
keypos),
|
||||
|
|
@ -629,21 +642,23 @@ static int underflow(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
|
|||
else
|
||||
bmove(keypos,keypos-t_length,(uint) (endpos-keypos)+t_length);
|
||||
(*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 */
|
||||
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))
|
||||
goto err;
|
||||
t_length=(int) (*keyinfo->pack_key)(keyinfo, nod_flag, (uchar*) 0,
|
||||
(uchar*) 0, (uchar*) 0,
|
||||
leaf_key, &s_temp);
|
||||
/* 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);
|
||||
(*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))
|
||||
goto err;
|
||||
|
|
@ -662,12 +677,13 @@ static int underflow(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
|
|||
next_page= _ma_kpos(key_reflength,keypos);
|
||||
if (!_ma_fetch_keypage(info,keyinfo,next_page,DFLT_INIT_HITS,buff,0))
|
||||
goto err;
|
||||
buff_length= maria_data_on_page(buff);
|
||||
buff_length= _ma_get_page_used(info, buff);
|
||||
endpos=buff+buff_length;
|
||||
DBUG_DUMP("prev",buff,buff_length);
|
||||
|
||||
/* 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;
|
||||
if (!(*keyinfo->get_key)(keyinfo,key_reflength,&next_keypos,
|
||||
anc_key))
|
||||
|
|
@ -691,7 +707,7 @@ static int underflow(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
|
|||
|
||||
(*keyinfo->store_key)(keyinfo,endpos,&s_temp);
|
||||
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 */
|
||||
if (!(s_length= remove_key(keyinfo,key_reflength,keypos,anc_key,
|
||||
|
|
@ -699,22 +715,22 @@ static int underflow(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
|
|||
goto err;
|
||||
|
||||
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 */
|
||||
if (_ma_dispose(info,keyinfo,leaf_page,DFLT_INIT_HITS))
|
||||
goto err;
|
||||
}
|
||||
else
|
||||
{ /* 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 */
|
||||
else if (!_ma_get_last_key(info,keyinfo,anc_buff,anc_pos=anc_key,keypos,
|
||||
&length))
|
||||
goto err;
|
||||
endpos= _ma_find_half_pos(nod_flag,keyinfo,buff,leaf_key,
|
||||
&key_length, &half_pos);
|
||||
endpos= _ma_find_half_pos(info, nod_flag, keyinfo, buff, leaf_key,
|
||||
&key_length, &half_pos);
|
||||
if (!endpos)
|
||||
goto err;
|
||||
_ma_kpointer(info,leaf_key+key_length,leaf_page);
|
||||
|
|
@ -733,11 +749,13 @@ static int underflow(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
|
|||
else
|
||||
bmove(keypos,keypos-t_length,(uint) (temp_pos-keypos)+t_length);
|
||||
(*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 */
|
||||
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)))
|
||||
goto err;
|
||||
DBUG_DUMP("key_to_leaf",leaf_key,length);
|
||||
|
|
@ -748,14 +766,16 @@ static int underflow(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
|
|||
bmove(leaf_buff+p_length+t_length,half_pos,
|
||||
(size_t) length);
|
||||
(*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))
|
||||
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))
|
||||
goto err;
|
||||
DBUG_RETURN(anc_length <= (uint) keyinfo->block_length/2);
|
||||
DBUG_RETURN(anc_length <= (uint)
|
||||
(keyinfo->block_length - KEYPAGE_CHECKSUM_SIZE)/2);
|
||||
|
||||
err:
|
||||
DBUG_RETURN(-1);
|
||||
|
|
|
|||
|
|
@ -327,9 +327,10 @@ uint _ma_ft_convert_to_ft2(MARIA_HA *info, uint keynr, uchar *key)
|
|||
}
|
||||
|
||||
/* creating pageful of keys */
|
||||
maria_putint(info->buff,length+2,0);
|
||||
memcpy(info->buff+2, key_ptr, length);
|
||||
info->keyread_buff_used=info->page_changed=1; /* info->buff is used */
|
||||
_ma_store_keynr(info, info->buff, keynr);
|
||||
_ma_store_page_used(info, info->buff, length + info->s->keypage_header, 0);
|
||||
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 ||
|
||||
_ma_write_keypage(info,keyinfo,root,DFLT_INIT_HITS,info->buff))
|
||||
DBUG_RETURN(-1);
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@
|
|||
/* short transaction ID type */
|
||||
typedef uint16 SHORT_TRANSACTION_ID;
|
||||
|
||||
struct st_maria_info;
|
||||
struct st_maria_handler;
|
||||
|
||||
/* Changing one of the "SIZE" below will break backward-compatibility! */
|
||||
/* Length of CRC at end of pages */
|
||||
|
|
@ -236,7 +236,7 @@ extern my_bool translog_init(const char *directory, uint32 log_file_max_size,
|
|||
extern my_bool
|
||||
translog_write_record(LSN *lsn, enum translog_record_type type,
|
||||
struct st_transaction *trn,
|
||||
struct st_maria_info *tbl_info,
|
||||
MARIA_HA *tbl_info,
|
||||
translog_size_t rec_len, uint part_no,
|
||||
LEX_STRING *parts_data, uchar *store_share_id,
|
||||
void *hook_arg);
|
||||
|
|
@ -272,7 +272,7 @@ extern my_bool translog_unlock();
|
|||
extern void translog_lock_assert_owner();
|
||||
extern TRANSLOG_ADDRESS translog_get_horizon();
|
||||
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);
|
||||
extern void translog_deassign_id_from_share(struct st_maria_share *share);
|
||||
extern void
|
||||
|
|
@ -307,11 +307,13 @@ struct st_translog_parts
|
|||
};
|
||||
|
||||
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,
|
||||
void *hook_arg);
|
||||
|
||||
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, void *hook_arg);
|
||||
|
||||
typedef uint16(*read_rec_hook) (enum translog_record_type type,
|
||||
|
|
|
|||
|
|
@ -252,7 +252,8 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags)
|
|||
uchar *disk_cache, *disk_pos, *end_pos;
|
||||
MARIA_HA info,*m_info,*old_info;
|
||||
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];
|
||||
ulonglong max_key_file_length, max_data_file_length;
|
||||
File data_file= -1;
|
||||
|
|
@ -273,7 +274,8 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags)
|
|||
{
|
||||
share= &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.pagecache= multi_pagecache_search((uchar*) name_buff,
|
||||
strlen(name_buff),
|
||||
|
|
@ -315,10 +317,11 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags)
|
|||
HA_OPTION_COMPRESS_RECORD | HA_OPTION_READ_ONLY_DATA |
|
||||
HA_OPTION_TEMP_COMPRESS_RECORD | HA_OPTION_CHECKSUM |
|
||||
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));
|
||||
my_errno=HA_ERR_OLD_FILE;
|
||||
my_errno=HA_ERR_NEW_FILE;
|
||||
goto err;
|
||||
}
|
||||
if ((share->options & HA_OPTION_RELIES_ON_SQL_LAYER) &&
|
||||
|
|
@ -442,7 +445,10 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags)
|
|||
|
||||
if (!my_multi_malloc(MY_WME,
|
||||
&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->uniqueinfo,uniques*sizeof(MARIA_UNIQUEDEF),
|
||||
&share->keyparts,
|
||||
|
|
@ -450,6 +456,7 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags)
|
|||
sizeof(HA_KEYSEG),
|
||||
&share->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->unique_file_name,strlen(name_buff)+1,
|
||||
&share->index_file_name,strlen(index_name)+1,
|
||||
|
|
@ -466,7 +473,9 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags)
|
|||
|
||||
*share=share_buff;
|
||||
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,
|
||||
(char*) key_root, sizeof(my_off_t)*keys);
|
||||
strmov(share->unique_file_name, name_buff);
|
||||
|
|
@ -596,6 +605,10 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags)
|
|||
share->base.null_bytes +
|
||||
share->base.pack_bytes +
|
||||
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)
|
||||
{
|
||||
/*
|
||||
|
|
@ -667,6 +680,8 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags)
|
|||
}
|
||||
}
|
||||
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 ||
|
||||
share->data_file_type == COMPRESSED_RECORD))
|
||||
|
|
@ -1096,10 +1111,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->recover_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++)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1136,7 +1154,9 @@ static uchar *_ma_state_info_read(uchar *ptr, MARIA_STATE_INFO *state)
|
|||
state->state.key_empty= mi_sizekorr(ptr); ptr+= 8;
|
||||
state->auto_increment=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;
|
||||
/* Not used (legacy from MyISAM) */
|
||||
state->unique = mi_uint4korr(ptr); ptr+= 4;
|
||||
state->status = mi_uint4korr(ptr); ptr+= 4;
|
||||
state->update_count=mi_uint4korr(ptr); ptr+= 4;
|
||||
|
|
@ -1155,10 +1175,12 @@ static uchar *_ma_state_info_read(uchar *ptr, MARIA_STATE_INFO *state)
|
|||
state->create_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->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++)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
|
@ -1200,6 +1222,8 @@ uint _ma_base_info_write(File file, MARIA_BASE_INFO *base)
|
|||
{
|
||||
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->max_data_file_length); ptr+= 8;
|
||||
mi_sizestore(ptr,base->max_key_file_length); ptr+= 8;
|
||||
|
|
@ -1216,7 +1240,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->max_field_lengths); 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->original_null_bytes); ptr+= 2;
|
||||
mi_int2store(ptr,base->field_offsets); ptr+= 2;
|
||||
|
|
@ -1242,6 +1266,7 @@ uint _ma_base_info_write(File file, 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->max_data_file_length= mi_sizekorr(ptr); ptr+= 8;
|
||||
base->max_key_file_length= mi_sizekorr(ptr); ptr+= 8;
|
||||
|
|
@ -1258,7 +1283,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->max_field_lengths= 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->original_null_bytes= mi_uint2korr(ptr); ptr+= 2;
|
||||
base->field_offsets= mi_uint2korr(ptr); ptr+= 2;
|
||||
|
|
@ -1285,7 +1310,7 @@ static uchar *_ma_base_info_read(uchar *ptr, MARIA_BASE_INFO *base)
|
|||
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 *ptr=buff;
|
||||
|
|
@ -1321,7 +1346,7 @@ uchar *_ma_keydef_read(uchar *ptr, MARIA_KEYDEF *keydef)
|
|||
** 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 *ptr=buff;
|
||||
|
|
@ -1371,7 +1396,7 @@ uchar *_ma_keyseg_read(uchar *ptr, HA_KEYSEG *keyseg)
|
|||
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 *ptr=buff;
|
||||
|
|
@ -1395,12 +1420,12 @@ uchar *_ma_uniquedef_read(uchar *ptr, MARIA_UNIQUEDEF *def)
|
|||
** 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 *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->length); ptr+= 2;
|
||||
mi_int2store(ptr,columndef->fill_length); ptr+= 2;
|
||||
|
|
@ -1408,12 +1433,13 @@ uint _ma_columndef_write(File file, MARIA_COLUMNDEF *columndef)
|
|||
mi_int2store(ptr,columndef->empty_pos); ptr+= 2;
|
||||
(*ptr++)= columndef->null_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;
|
||||
}
|
||||
|
||||
uchar *_ma_columndef_read(uchar *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->length= mi_uint2korr(ptr); ptr+= 2;
|
||||
columndef->fill_length= mi_uint2korr(ptr); ptr+= 2;
|
||||
|
|
@ -1421,9 +1447,36 @@ uchar *_ma_columndef_read(uchar *ptr, MARIA_COLUMNDEF *columndef)
|
|||
columndef->empty_pos= mi_uint2korr(ptr); ptr+= 2;
|
||||
columndef->null_bit= (uint8) *ptr++;
|
||||
columndef->empty_bit= (uint8) *ptr++;
|
||||
ptr+= 4;
|
||||
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
|
||||
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);
|
||||
}
|
||||
info->last_keypage=page;
|
||||
page_size= maria_data_on_page(tmp);
|
||||
if (page_size < 4 || page_size > keyinfo->block_length)
|
||||
#ifdef EXTRA_DEBUG
|
||||
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",
|
||||
(ulong) page, page_size));
|
||||
DBUG_PRINT("error",("page %lu had wrong page length: %u keynr: %u",
|
||||
(ulong) page, page_size,
|
||||
_ma_get_keynr(info, tmp)));
|
||||
DBUG_DUMP("page", (char*) tmp, keyinfo->block_length);
|
||||
info->last_keypage = HA_OFFSET_ERROR;
|
||||
maria_print_error(info->s, HA_ERR_CRASHED);
|
||||
my_errno= HA_ERR_CRASHED;
|
||||
tmp= 0;
|
||||
}
|
||||
#endif
|
||||
DBUG_RETURN(tmp);
|
||||
} /* _ma_fetch_keypage */
|
||||
|
||||
|
|
@ -84,19 +88,27 @@ int _ma_write_keypage(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
|
|||
DBUG_RETURN((-1));
|
||||
}
|
||||
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
|
||||
|
||||
/* Verify that keynr is correct */
|
||||
DBUG_ASSERT(_ma_get_keynr(info, buff) ==
|
||||
(uint) (keyinfo - info->s->keyinfo));
|
||||
|
||||
#ifdef HAVE_purify
|
||||
{
|
||||
/* Clear unitialized part of page to avoid valgrind/purify warnings */
|
||||
uint length= maria_data_on_page(buff);
|
||||
bzero((uchar*) buff+length,keyinfo->block_length-length);
|
||||
uint length= _ma_get_page_used(info, buff);
|
||||
bzero(buff+length, keyinfo->block_length-length);
|
||||
length=keyinfo->block_length;
|
||||
}
|
||||
#endif
|
||||
|
||||
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
|
||||
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)
|
||||
{
|
||||
my_off_t old_link;
|
||||
uchar buff[8];
|
||||
uchar buff[MAX_KEYPAGE_HEADER_SIZE+8];
|
||||
uint offset;
|
||||
pgcache_page_no_t page_no;
|
||||
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;
|
||||
page_no= 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;
|
||||
|
||||
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_PIN_LEFT_UNPINNED,
|
||||
PAGECACHE_WRITE_DELAY, 0,
|
||||
offset, sizeof(buff), 0, 0));
|
||||
offset, info->s->keypage_header+8, 0, 0));
|
||||
} /* _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)
|
||||
{
|
||||
|
|
@ -166,6 +180,7 @@ my_off_t _ma_new(register MARIA_HA *info, MARIA_KEYDEF *keyinfo, int level)
|
|||
}
|
||||
else
|
||||
{
|
||||
/* QQ: Remove this alloc (We don't have to copy the page) */
|
||||
buff= my_alloca(info->s->block_size);
|
||||
DBUG_ASSERT(info->s->pagecache->block_size == keyinfo->block_length &&
|
||||
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))
|
||||
pos= HA_OFFSET_ERROR;
|
||||
else
|
||||
info->s->state.key_del= mi_sizekorr(buff);
|
||||
info->s->state.key_del= mi_sizekorr(buff+info->s->keypage_header);
|
||||
my_afree(buff);
|
||||
}
|
||||
info->s->state.changed|= STATE_NOT_SORTED_PAGES;
|
||||
|
|
|
|||
|
|
@ -40,12 +40,10 @@
|
|||
|
||||
int maria_preload(MARIA_HA *info, ulonglong key_map, my_bool ignore_leaves)
|
||||
{
|
||||
uint i;
|
||||
ulong length, block_length= 0;
|
||||
uchar *buff= NULL;
|
||||
MARIA_SHARE* share= info->s;
|
||||
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 pos= share->base.keystart;
|
||||
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)
|
||||
DBUG_RETURN(0);
|
||||
|
||||
block_length= keyinfo[0].block_length;
|
||||
|
||||
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;
|
||||
|
||||
block_length= share->pagecache->block_size;
|
||||
length= info->preload_buff_size/block_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
|
||||
{
|
||||
uchar *end;
|
||||
/* Read the next block of index file into the preload buffer */
|
||||
if ((my_off_t) length > (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)))
|
||||
goto err;
|
||||
|
||||
if (ignore_leaves)
|
||||
for (end= buff + length ; buff < end ; buff+= block_length)
|
||||
{
|
||||
uchar *end= buff+length;
|
||||
do
|
||||
uint keynr= _ma_get_keynr(info, buff);
|
||||
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,
|
||||
&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+= block_length;
|
||||
DBUG_ASSERT(share->pagecache->block_size == block_length);
|
||||
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;
|
||||
}
|
||||
while ((buff+= block_length) != end);
|
||||
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;
|
||||
pos+= block_length;
|
||||
}
|
||||
}
|
||||
while (pos != key_file_length);
|
||||
|
|
|
|||
|
|
@ -215,7 +215,7 @@ static double _ma_search_pos(register MARIA_HA *info,
|
|||
goto err;
|
||||
flag=(*keyinfo->bin_search)(info, keyinfo, buff, key, key_len, nextflag,
|
||||
&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);
|
||||
|
||||
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,
|
||||
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;
|
||||
|
||||
end= page+maria_data_on_page(page);
|
||||
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;
|
||||
|
||||
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;
|
||||
uchar *page_buf, *k, *last;
|
||||
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;
|
||||
}
|
||||
if (!_ma_fetch_keypage(info, keyinfo, page, DFLT_INIT_HITS, page_buf, 0))
|
||||
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;
|
||||
}
|
||||
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)
|
||||
{
|
||||
/* 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->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,
|
||||
_ma_kpos(nod_flag, k),
|
||||
level + 1)))
|
||||
{
|
||||
case 0: /* found - exit from recursion */
|
||||
*saved_key = k - page_buf;
|
||||
*saved_key= k - page_buf;
|
||||
goto ok;
|
||||
case 1: /* not found - continue searching */
|
||||
info->maria_rtree_recursion_depth = level;
|
||||
info->maria_rtree_recursion_depth= level;
|
||||
break;
|
||||
default: /* error */
|
||||
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,
|
||||
k, info->last_rkey_length, search_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->lastkey_length = k_len + info->s->base.rec_reflength;
|
||||
uchar *after_key= (uchar*) rt_PAGE_NEXT_KEY(k, k_len, nod_flag);
|
||||
info->cur_row.lastpos= _ma_dpos(info, 0, after_key);
|
||||
info->lastkey_length= k_len + info->s->base.rec_reflength;
|
||||
memcpy(info->lastkey, k, info->lastkey_length);
|
||||
info->maria_rtree_recursion_depth = level;
|
||||
*saved_key = last - page_buf;
|
||||
info->maria_rtree_recursion_depth= level;
|
||||
*saved_key= last - page_buf;
|
||||
|
||||
if (after_key < last)
|
||||
{
|
||||
info->int_keypos = info->buff;
|
||||
info->int_maxpos = info->buff + (last - after_key);
|
||||
info->int_keypos= info->buff;
|
||||
info->int_maxpos= info->buff + (last - after_key);
|
||||
memcpy(info->buff, after_key, last - after_key);
|
||||
info->keyread_buff_used = 0;
|
||||
info->keyread_buff_used= 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
info->keyread_buff_used = 1;
|
||||
info->keyread_buff_used= 1;
|
||||
}
|
||||
|
||||
res = 0;
|
||||
res= 0;
|
||||
goto ok;
|
||||
}
|
||||
}
|
||||
}
|
||||
info->cur_row.lastpos = HA_OFFSET_ERROR;
|
||||
my_errno = HA_ERR_KEY_NOT_FOUND;
|
||||
res = 1;
|
||||
info->cur_row.lastpos= HA_OFFSET_ERROR;
|
||||
my_errno= HA_ERR_KEY_NOT_FOUND;
|
||||
res= 1;
|
||||
|
||||
ok:
|
||||
my_afree((uchar*)page_buf);
|
||||
|
|
@ -149,7 +149,7 @@ ok:
|
|||
|
||||
err1:
|
||||
my_afree((uchar*)page_buf);
|
||||
info->cur_row.lastpos = HA_OFFSET_ERROR;
|
||||
info->cur_row.lastpos= HA_OFFSET_ERROR;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
@ -176,9 +176,9 @@ int maria_rtree_find_first(MARIA_HA *info, uint keynr, uchar *key,
|
|||
{
|
||||
my_off_t root;
|
||||
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;
|
||||
return -1;
|
||||
|
|
@ -190,10 +190,10 @@ int maria_rtree_find_first(MARIA_HA *info, uint keynr, uchar *key,
|
|||
(minimum bounding rectangle)
|
||||
*/
|
||||
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->keyread_buff_used = 1;
|
||||
info->maria_rtree_recursion_depth= -1;
|
||||
info->keyread_buff_used= 1;
|
||||
|
||||
nod_cmp_flag= ((search_flag & (MBR_EQUAL | MBR_WITHIN)) ?
|
||||
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;
|
||||
uint nod_cmp_flag;
|
||||
MARIA_KEYDEF *keyinfo = info->s->keyinfo + keynr;
|
||||
MARIA_KEYDEF *keyinfo= info->s->keyinfo + keynr;
|
||||
|
||||
if (info->update & HA_STATE_DELETED)
|
||||
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;
|
||||
}
|
||||
}
|
||||
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;
|
||||
return -1;
|
||||
}
|
||||
|
||||
nod_cmp_flag = ((search_flag & (MBR_EQUAL | MBR_WITHIN)) ?
|
||||
nod_cmp_flag= ((search_flag & (MBR_EQUAL | MBR_WITHIN)) ?
|
||||
MBR_WITHIN : MBR_INTERSECT);
|
||||
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
|
||||
*/
|
||||
|
||||
static int maria_rtree_get_req(MARIA_HA *info, MARIA_KEYDEF *keyinfo, uint key_length,
|
||||
my_off_t page, int level)
|
||||
static int maria_rtree_get_req(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
|
||||
uint key_length, my_off_t page, int level)
|
||||
{
|
||||
uchar *page_buf, *last, *k;
|
||||
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;
|
||||
if (!_ma_fetch_keypage(info, keyinfo, page, DFLT_INIT_HITS, page_buf, 0))
|
||||
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)
|
||||
{
|
||||
k = page_buf + *saved_key;
|
||||
k= page_buf + *saved_key;
|
||||
if (!nod_flag)
|
||||
{
|
||||
/* Only leaf pages contain data references. */
|
||||
/* 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
|
||||
{
|
||||
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)
|
||||
{
|
||||
/* 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)))
|
||||
{
|
||||
case 0: /* found - exit from recursion */
|
||||
*saved_key = k - page_buf;
|
||||
*saved_key= k - page_buf;
|
||||
goto ok;
|
||||
case 1: /* not found - continue searching */
|
||||
info->maria_rtree_recursion_depth = level;
|
||||
info->maria_rtree_recursion_depth= level;
|
||||
break;
|
||||
default:
|
||||
case -1: /* error */
|
||||
|
|
@ -330,33 +330,33 @@ static int maria_rtree_get_req(MARIA_HA *info, MARIA_KEYDEF *keyinfo, uint key_l
|
|||
else
|
||||
{
|
||||
/* this is a leaf */
|
||||
uchar *after_key = rt_PAGE_NEXT_KEY(k, k_len, nod_flag);
|
||||
info->cur_row.lastpos = _ma_dpos(info, 0, after_key);
|
||||
info->lastkey_length = k_len + info->s->base.rec_reflength;
|
||||
uchar *after_key= rt_PAGE_NEXT_KEY(k, k_len, nod_flag);
|
||||
info->cur_row.lastpos= _ma_dpos(info, 0, after_key);
|
||||
info->lastkey_length= k_len + info->s->base.rec_reflength;
|
||||
memcpy(info->lastkey, k, info->lastkey_length);
|
||||
|
||||
info->maria_rtree_recursion_depth = level;
|
||||
*saved_key = k - page_buf;
|
||||
info->maria_rtree_recursion_depth= level;
|
||||
*saved_key= k - page_buf;
|
||||
|
||||
if (after_key < last)
|
||||
{
|
||||
info->int_keypos = (uchar*) saved_key;
|
||||
info->int_keypos= (uchar*) saved_key;
|
||||
memcpy(info->buff, page_buf, keyinfo->block_length);
|
||||
info->int_maxpos = rt_PAGE_END(info->buff);
|
||||
info->keyread_buff_used = 0;
|
||||
info->int_maxpos= rt_PAGE_END(info, info->buff);
|
||||
info->keyread_buff_used= 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
info->keyread_buff_used = 1;
|
||||
info->keyread_buff_used= 1;
|
||||
}
|
||||
|
||||
res = 0;
|
||||
res= 0;
|
||||
goto ok;
|
||||
}
|
||||
}
|
||||
info->cur_row.lastpos = HA_OFFSET_ERROR;
|
||||
my_errno = HA_ERR_KEY_NOT_FOUND;
|
||||
res = 1;
|
||||
info->cur_row.lastpos= HA_OFFSET_ERROR;
|
||||
my_errno= HA_ERR_KEY_NOT_FOUND;
|
||||
res= 1;
|
||||
|
||||
ok:
|
||||
my_afree((uchar*)page_buf);
|
||||
|
|
@ -364,7 +364,7 @@ ok:
|
|||
|
||||
err1:
|
||||
my_afree((uchar*)page_buf);
|
||||
info->cur_row.lastpos = HA_OFFSET_ERROR;
|
||||
info->cur_row.lastpos= HA_OFFSET_ERROR;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
@ -381,16 +381,16 @@ err1:
|
|||
int maria_rtree_get_first(MARIA_HA *info, uint keynr, uint key_length)
|
||||
{
|
||||
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;
|
||||
return -1;
|
||||
}
|
||||
|
||||
info->maria_rtree_recursion_depth = -1;
|
||||
info->keyread_buff_used = 1;
|
||||
info->maria_rtree_recursion_depth= -1;
|
||||
info->keyread_buff_used= 1;
|
||||
|
||||
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)
|
||||
{
|
||||
my_off_t root;
|
||||
MARIA_KEYDEF *keyinfo = info->s->keyinfo + keynr;
|
||||
MARIA_KEYDEF *keyinfo= info->s->keyinfo + keynr;
|
||||
|
||||
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) */
|
||||
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;
|
||||
/* 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->lastkey_length = k_len + info->s->base.rec_reflength;
|
||||
info->cur_row.lastpos= _ma_dpos(info, 0, after_key);
|
||||
info->lastkey_length= 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)
|
||||
{
|
||||
info->keyread_buff_used = 1;
|
||||
info->keyread_buff_used= 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
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;
|
||||
return -1;
|
||||
|
|
@ -455,27 +455,27 @@ static uchar *maria_rtree_pick_key(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
|
|||
uint nod_flag)
|
||||
{
|
||||
double increase;
|
||||
double best_incr = DBL_MAX;
|
||||
double best_incr= DBL_MAX;
|
||||
double perimeter;
|
||||
double best_perimeter;
|
||||
uchar *best_key;
|
||||
uchar *k = rt_PAGE_FIRST_KEY(page_buf, nod_flag);
|
||||
uchar *last = rt_PAGE_END(page_buf);
|
||||
uchar *k= rt_PAGE_FIRST_KEY(page_buf, nod_flag);
|
||||
uchar *last= rt_PAGE_END(info, page_buf);
|
||||
|
||||
LINT_INIT(best_perimeter);
|
||||
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)
|
||||
return NULL;
|
||||
if ((increase < best_incr)||
|
||||
(increase == best_incr && perimeter < best_perimeter))
|
||||
{
|
||||
best_key = k;
|
||||
best_key= k;
|
||||
best_perimeter= perimeter;
|
||||
best_incr = increase;
|
||||
best_incr= increase;
|
||||
}
|
||||
}
|
||||
return best_key;
|
||||
|
|
@ -490,37 +490,37 @@ static uchar *maria_rtree_pick_key(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
|
|||
uint nod_flag)
|
||||
{
|
||||
double increase;
|
||||
double best_incr = DBL_MAX;
|
||||
double best_incr= DBL_MAX;
|
||||
double area;
|
||||
double best_area;
|
||||
uchar *best_key;
|
||||
uchar *k = rt_PAGE_FIRST_KEY(page_buf, nod_flag);
|
||||
uchar *last = rt_PAGE_END(page_buf);
|
||||
uchar *k= rt_PAGE_FIRST_KEY(info, page_buf, nod_flag);
|
||||
uchar *last= rt_PAGE_END(info, page_buf);
|
||||
|
||||
LINT_INIT(best_area);
|
||||
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 */
|
||||
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)
|
||||
return NULL;
|
||||
/* The following should be safe, even if we compare doubles */
|
||||
if (increase < best_incr)
|
||||
{
|
||||
best_key = k;
|
||||
best_area = area;
|
||||
best_incr = increase;
|
||||
best_key= k;
|
||||
best_area= area;
|
||||
best_incr= increase;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The following should be safe, even if we compare doubles */
|
||||
if ((increase == best_incr) && (area < best_area))
|
||||
{
|
||||
best_key = k;
|
||||
best_area = area;
|
||||
best_incr = increase;
|
||||
best_key= k;
|
||||
best_area= area;
|
||||
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 +
|
||||
HA_MAX_KEY_BUFF)))
|
||||
{
|
||||
my_errno = HA_ERR_OUT_OF_MEM;
|
||||
my_errno= HA_ERR_OUT_OF_MEM;
|
||||
DBUG_RETURN(-1); /* purecov: inspected */
|
||||
}
|
||||
if (!_ma_fetch_keypage(info, keyinfo, page, DFLT_INIT_HITS, page_buf, 0))
|
||||
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",
|
||||
(ulong) page, level, ins_level, nod_flag));
|
||||
|
||||
if ((ins_level == -1 && nod_flag) || /* key: go down to leaf */
|
||||
(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)
|
||||
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,
|
||||
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 */
|
||||
{
|
||||
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 */
|
||||
if (maria_rtree_set_key_mbr(info, keyinfo, k, key_length,
|
||||
_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,
|
||||
*new_page))
|
||||
goto err1;
|
||||
res = maria_rtree_add_key(info, keyinfo, new_key, key_length,
|
||||
page_buf, new_page);
|
||||
res= maria_rtree_add_key(info, keyinfo, new_key, key_length,
|
||||
page_buf, new_page);
|
||||
if (_ma_write_keypage(info, keyinfo, page, DFLT_INIT_HITS, page_buf))
|
||||
goto err1;
|
||||
goto ok;
|
||||
|
|
@ -605,7 +605,7 @@ static int maria_rtree_insert_req(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
|
|||
}
|
||||
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);
|
||||
if (_ma_write_keypage(info, keyinfo, page, DFLT_INIT_HITS, page_buf))
|
||||
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)
|
||||
{
|
||||
my_off_t old_root;
|
||||
MARIA_KEYDEF *keyinfo = info->s->keyinfo + keynr;
|
||||
MARIA_KEYDEF *keyinfo= info->s->keyinfo + keynr;
|
||||
int res;
|
||||
my_off_t new_page;
|
||||
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);
|
||||
info->keyread_buff_used = 1;
|
||||
maria_putint(info->buff, 2, 0);
|
||||
res = maria_rtree_add_key(info, keyinfo, key, key_length, info->buff, NULL);
|
||||
info->keyread_buff_used= 1;
|
||||
_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);
|
||||
if (_ma_write_keypage(info, keyinfo, old_root, DFLT_INIT_HITS, info->buff))
|
||||
DBUG_RETURN(1);
|
||||
info->s->state.key_root[keynr] = old_root;
|
||||
info->s->state.key_root[keynr]= old_root;
|
||||
DBUG_RETURN(res);
|
||||
}
|
||||
|
||||
switch ((res = maria_rtree_insert_req(info, keyinfo, key, key_length,
|
||||
old_root, &new_page, ins_level, 0)))
|
||||
switch ((res= maria_rtree_insert_req(info, keyinfo, key, key_length,
|
||||
old_root, &new_page, ins_level, 0)))
|
||||
{
|
||||
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;
|
||||
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"));
|
||||
if (!(new_root_buf= (uchar*) my_alloca((uint)keyinfo->block_length +
|
||||
HA_MAX_KEY_BUFF)))
|
||||
{
|
||||
my_errno = HA_ERR_OUT_OF_MEM;
|
||||
my_errno= HA_ERR_OUT_OF_MEM;
|
||||
DBUG_RETURN(-1); /* purecov: inspected */
|
||||
}
|
||||
|
||||
maria_putint(new_root_buf, 2, nod_flag);
|
||||
if ((new_root = _ma_new(info, keyinfo, DFLT_INIT_HITS)) ==
|
||||
_ma_store_page_used(info, new_root_buf, info->s->keypage_header,
|
||||
nod_flag);
|
||||
if ((new_root= _ma_new(info, keyinfo, DFLT_INIT_HITS)) ==
|
||||
HA_OFFSET_ERROR)
|
||||
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);
|
||||
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,
|
||||
DFLT_INIT_HITS, new_root_buf))
|
||||
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",
|
||||
(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);
|
||||
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)
|
||||
{
|
||||
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))))
|
||||
goto err1;
|
||||
}
|
||||
/* save page to ReinsertList */
|
||||
ReinsertList->pages[ReinsertList->n_pages].offs = page;
|
||||
ReinsertList->pages[ReinsertList->n_pages].level = level;
|
||||
ReinsertList->pages[ReinsertList->n_pages].offs= page;
|
||||
ReinsertList->pages[ReinsertList->n_pages].level= level;
|
||||
ReinsertList->n_pages++;
|
||||
DBUG_RETURN(0);
|
||||
|
||||
|
|
@ -790,28 +792,28 @@ static int maria_rtree_delete_req(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
|
|||
uchar *page_buf, *last, *k;
|
||||
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 */
|
||||
}
|
||||
if (!_ma_fetch_keypage(info, keyinfo, page, DFLT_INIT_HITS, page_buf, 0))
|
||||
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",
|
||||
(ulong) page, level, nod_flag));
|
||||
|
||||
k = rt_PAGE_FIRST_KEY(page_buf, nod_flag);
|
||||
last = rt_PAGE_END(page_buf);
|
||||
k= rt_PAGE_FIRST_KEY(info, page_buf, nod_flag);
|
||||
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)
|
||||
{
|
||||
/* not leaf */
|
||||
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)))
|
||||
{
|
||||
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,
|
||||
DFLT_INIT_HITS, page_buf))
|
||||
goto err1;
|
||||
*page_size = maria_data_on_page(page_buf);
|
||||
*page_size= _ma_get_page_used(info, page_buf);
|
||||
}
|
||||
|
||||
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,
|
||||
DFLT_INIT_HITS, page_buf))
|
||||
goto err1;
|
||||
*page_size = maria_data_on_page(page_buf);
|
||||
res = 0;
|
||||
*page_size= _ma_get_page_used(info, page_buf);
|
||||
res= 0;
|
||||
goto ok;
|
||||
}
|
||||
default: /* error */
|
||||
|
|
@ -883,20 +885,21 @@ static int maria_rtree_delete_req(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
|
|||
else
|
||||
{
|
||||
/* 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);
|
||||
*page_size = maria_data_on_page(page_buf);
|
||||
if (*page_size == 2)
|
||||
*page_size= _ma_get_page_used(info, page_buf);
|
||||
if (*page_size == info->s->keypage_header)
|
||||
{
|
||||
/* last key in the leaf */
|
||||
res = 2;
|
||||
res= 2;
|
||||
if (_ma_dispose(info, keyinfo, page, DFLT_INIT_HITS))
|
||||
goto err1;
|
||||
}
|
||||
else
|
||||
{
|
||||
res = 0;
|
||||
res= 0;
|
||||
if (_ma_write_keypage(info, keyinfo, page, DFLT_INIT_HITS, page_buf))
|
||||
goto err1;
|
||||
}
|
||||
|
|
@ -904,7 +907,7 @@ static int maria_rtree_delete_req(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
|
|||
}
|
||||
}
|
||||
}
|
||||
res = 1;
|
||||
res= 1;
|
||||
|
||||
ok:
|
||||
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;
|
||||
stPageList ReinsertList;
|
||||
my_off_t old_root;
|
||||
MARIA_KEYDEF *keyinfo = info->s->keyinfo + keynr;
|
||||
MARIA_KEYDEF *keyinfo= info->s->keyinfo + keynr;
|
||||
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;
|
||||
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",
|
||||
(ulong) old_root));
|
||||
|
||||
ReinsertList.pages = NULL;
|
||||
ReinsertList.n_pages = 0;
|
||||
ReinsertList.m_pages = 0;
|
||||
ReinsertList.pages= NULL;
|
||||
ReinsertList.n_pages= 0;
|
||||
ReinsertList.m_pages= 0;
|
||||
|
||||
switch (maria_rtree_delete_req(info, keyinfo, key, key_length, old_root,
|
||||
&page_size, &ReinsertList, 0))
|
||||
{
|
||||
case 2: /* empty */
|
||||
{
|
||||
info->s->state.key_root[keynr] = HA_OFFSET_ERROR;
|
||||
info->s->state.key_root[keynr]= HA_OFFSET_ERROR;
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
case 0: /* deleted */
|
||||
{
|
||||
uint nod_flag;
|
||||
ulong i;
|
||||
for (i = 0; i < ReinsertList.n_pages; ++i)
|
||||
for (i= 0; i < ReinsertList.n_pages; ++i)
|
||||
{
|
||||
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;
|
||||
}
|
||||
if (!_ma_fetch_keypage(info, keyinfo, ReinsertList.pages[i].offs,
|
||||
DFLT_INIT_HITS, page_buf, 0))
|
||||
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 "
|
||||
"page: %lu level: %d nod_flag: %u",
|
||||
(ulong) ReinsertList.pages[i].offs,
|
||||
ReinsertList.pages[i].level, nod_flag));
|
||||
|
||||
k = rt_PAGE_FIRST_KEY(page_buf, nod_flag);
|
||||
last = rt_PAGE_END(page_buf);
|
||||
for (; k < last; k = rt_PAGE_NEXT_KEY(k, key_length, nod_flag))
|
||||
k= rt_PAGE_FIRST_KEY(info, page_buf, nod_flag);
|
||||
last= rt_PAGE_END(info, page_buf);
|
||||
for (; k < last; k= rt_PAGE_NEXT_KEY(k, key_length, nod_flag))
|
||||
{
|
||||
int 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));
|
||||
|
||||
/* 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;
|
||||
if (!_ma_fetch_keypage(info, keyinfo, old_root, DFLT_INIT_HITS,
|
||||
info->buff, 0))
|
||||
goto err1;
|
||||
nod_flag = _ma_test_if_nod(info->buff);
|
||||
page_size = maria_data_on_page(info->buff);
|
||||
if (nod_flag && (page_size == 2 + key_length + nod_flag))
|
||||
nod_flag= _ma_test_if_nod(info, info->buff);
|
||||
page_size= _ma_get_page_used(info, info->buff);
|
||||
if (nod_flag && (page_size == info->s->keypage_header + key_length +
|
||||
nod_flag))
|
||||
{
|
||||
my_off_t new_root = _ma_kpos(nod_flag,
|
||||
rt_PAGE_FIRST_KEY(info->buff, nod_flag));
|
||||
my_off_t new_root= _ma_kpos(nod_flag,
|
||||
rt_PAGE_FIRST_KEY(info, info->buff,
|
||||
nod_flag));
|
||||
if (_ma_dispose(info, keyinfo, old_root, DFLT_INIT_HITS))
|
||||
goto err1;
|
||||
info->s->state.key_root[keynr] = new_root;
|
||||
info->s->state.key_root[keynr]= new_root;
|
||||
}
|
||||
info->update= HA_STATE_DELETED;
|
||||
DBUG_RETURN(0);
|
||||
|
|
@ -1031,7 +1036,7 @@ err1:
|
|||
}
|
||||
case 1: /* not found */
|
||||
{
|
||||
my_errno = HA_ERR_KEY_NOT_FOUND;
|
||||
my_errno= HA_ERR_KEY_NOT_FOUND;
|
||||
DBUG_RETURN(-1); /* purecov: inspected */
|
||||
}
|
||||
default:
|
||||
|
|
@ -1051,35 +1056,35 @@ err1:
|
|||
ha_rows maria_rtree_estimate(MARIA_HA *info, uint keynr, uchar *key,
|
||||
uint key_length, uint flag)
|
||||
{
|
||||
MARIA_KEYDEF *keyinfo = info->s->keyinfo + keynr;
|
||||
MARIA_KEYDEF *keyinfo= info->s->keyinfo + keynr;
|
||||
my_off_t root;
|
||||
uint i = 0;
|
||||
uint i= 0;
|
||||
uint nod_flag, k_len;
|
||||
uchar *page_buf, *k, *last;
|
||||
double area = 0;
|
||||
ha_rows res = 0;
|
||||
double area= 0;
|
||||
ha_rows res= 0;
|
||||
|
||||
if (flag & MBR_DISJOINT)
|
||||
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;
|
||||
if (!(page_buf= (uchar*) my_alloca((uint)keyinfo->block_length)))
|
||||
return HA_POS_ERROR;
|
||||
if (!_ma_fetch_keypage(info, keyinfo, root, DFLT_INIT_HITS, page_buf, 0))
|
||||
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);
|
||||
last = rt_PAGE_END(page_buf);
|
||||
k= rt_PAGE_FIRST_KEY(info, page_buf, nod_flag);
|
||||
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)
|
||||
{
|
||||
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 */
|
||||
if (k_area == 0)
|
||||
|
|
@ -1124,9 +1129,9 @@ ha_rows maria_rtree_estimate(MARIA_HA *info, uint keynr, uchar *key,
|
|||
if (nod_flag)
|
||||
{
|
||||
if (i)
|
||||
res = (ha_rows) (area / i * info->state->records);
|
||||
res= (ha_rows) (area / i * info->state->records);
|
||||
else
|
||||
res = HA_POS_ERROR;
|
||||
res= HA_POS_ERROR;
|
||||
}
|
||||
|
||||
my_afree((uchar*)page_buf);
|
||||
|
|
|
|||
|
|
@ -19,12 +19,12 @@
|
|||
|
||||
#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 + \
|
||||
(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,
|
||||
uint key_length);
|
||||
|
|
|
|||
|
|
@ -32,8 +32,8 @@
|
|||
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 page_size = maria_data_on_page(page_buf);
|
||||
uint nod_flag = _ma_test_if_nod(page_buf);
|
||||
uint page_size= _ma_get_page_used(info, page_buf);
|
||||
uint nod_flag= _ma_test_if_nod(info, page_buf);
|
||||
DBUG_ENTER("maria_rtree_add_key");
|
||||
|
||||
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 */
|
||||
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);
|
||||
page_size += key_length + nod_flag;
|
||||
memcpy(rt_PAGE_END(info, page_buf), key - nod_flag,
|
||||
key_length + nod_flag);
|
||||
page_size+= key_length + nod_flag;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -54,11 +55,11 @@ int maria_rtree_add_key(MARIA_HA *info, MARIA_KEYDEF *keyinfo, uchar *key,
|
|||
info->s->base.rec_reflength) <
|
||||
info->state->data_file_length +
|
||||
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);
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
@ -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,
|
||||
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;
|
||||
|
||||
key_start= key - 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 -
|
||||
(key - page_buf));
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -64,10 +64,10 @@
|
|||
#define RT_CMP_KORR(type, korr_func, len, nextflag) \
|
||||
{ \
|
||||
type amin, amax, bmin, bmax; \
|
||||
amin = korr_func(a); \
|
||||
bmin = korr_func(b); \
|
||||
amax = korr_func(a+len); \
|
||||
bmax = korr_func(b+len); \
|
||||
amin= korr_func(a); \
|
||||
bmin= korr_func(b); \
|
||||
amax= korr_func(a+len); \
|
||||
bmax= korr_func(b+len); \
|
||||
RT_CMP(nextflag); \
|
||||
}
|
||||
|
||||
|
|
@ -153,7 +153,7 @@ int maria_rtree_key_cmp(HA_KEYSEG *keyseg, uchar *b, uchar *a, uint key_length,
|
|||
end:
|
||||
if (nextflag & MBR_DATA)
|
||||
{
|
||||
uchar *end = a + keyseg->length;
|
||||
uchar *end= a + keyseg->length;
|
||||
do
|
||||
{
|
||||
if (*a++ != *b++)
|
||||
|
|
@ -166,8 +166,8 @@ end:
|
|||
#define RT_VOL_KORR(type, korr_func, len, cast) \
|
||||
{ \
|
||||
type amin, amax; \
|
||||
amin = korr_func(a); \
|
||||
amax = korr_func(a+len); \
|
||||
amin= korr_func(a); \
|
||||
amax= korr_func(a+len); \
|
||||
res *= (cast(amax) - cast(amin)); \
|
||||
}
|
||||
|
||||
|
|
@ -184,7 +184,7 @@ end:
|
|||
*/
|
||||
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)
|
||||
{
|
||||
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));
|
||||
break;
|
||||
case HA_KEYTYPE_END:
|
||||
key_length = 0;
|
||||
key_length= 0;
|
||||
break;
|
||||
default:
|
||||
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) \
|
||||
{ \
|
||||
type amin, amax; \
|
||||
amin = korr_func(a); \
|
||||
amax = korr_func(a+len); \
|
||||
*res++ = cast(amin); \
|
||||
*res++ = cast(amax); \
|
||||
amin= korr_func(a); \
|
||||
amax= korr_func(a+len); \
|
||||
*res++= cast(amin); \
|
||||
*res++= cast(amax); \
|
||||
}
|
||||
|
||||
#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; \
|
||||
get_func(amin, a); \
|
||||
get_func(amax, a+len); \
|
||||
*res++ = cast(amin); \
|
||||
*res++ = cast(amax); \
|
||||
*res++= cast(amin); \
|
||||
*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));
|
||||
break;
|
||||
case HA_KEYTYPE_END:
|
||||
key_length = 0;
|
||||
key_length= 0;
|
||||
break;
|
||||
default:
|
||||
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) \
|
||||
{ \
|
||||
type amin, amax, bmin, bmax; \
|
||||
amin = korr_func(a); \
|
||||
bmin = korr_func(b); \
|
||||
amax = korr_func(a+len); \
|
||||
bmax = korr_func(b+len); \
|
||||
amin = min(amin, bmin); \
|
||||
amax = max(amax, bmax); \
|
||||
amin= korr_func(a); \
|
||||
bmin= korr_func(b); \
|
||||
amax= korr_func(a+len); \
|
||||
bmax= korr_func(b+len); \
|
||||
amin= min(amin, bmin); \
|
||||
amax= max(amax, bmax); \
|
||||
store_func(c, amin); \
|
||||
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(amax, a+len); \
|
||||
get_func(bmax, b+len); \
|
||||
amin = min(amin, bmin); \
|
||||
amax = max(amax, bmax); \
|
||||
amin= min(amin, bmin); \
|
||||
amax= max(amax, bmax); \
|
||||
store_func(c, amin); \
|
||||
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) \
|
||||
{ \
|
||||
type amin, amax, bmin, bmax; \
|
||||
amin = korr_func(a); \
|
||||
bmin = korr_func(b); \
|
||||
amax = korr_func(a+len); \
|
||||
bmax = korr_func(b+len); \
|
||||
amin = max(amin, bmin); \
|
||||
amax = min(amax, bmax); \
|
||||
amin= korr_func(a); \
|
||||
bmin= korr_func(b); \
|
||||
amax= korr_func(a+len); \
|
||||
bmax= korr_func(b+len); \
|
||||
amin= max(amin, bmin); \
|
||||
amax= min(amax, bmax); \
|
||||
if (amin >= amax) \
|
||||
return 0; \
|
||||
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(amax, a+len); \
|
||||
get_func(bmax, b+len); \
|
||||
amin = max(amin, bmin); \
|
||||
amax = min(amax, bmax); \
|
||||
amin= max(amin, bmin); \
|
||||
amax= min(amax, bmax); \
|
||||
if (amin >= amax) \
|
||||
return 0; \
|
||||
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,
|
||||
uint key_length)
|
||||
{
|
||||
double res = 1;
|
||||
double res= 1;
|
||||
for (; (int) key_length > 0 ; keyseg += 2)
|
||||
{
|
||||
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) \
|
||||
{ \
|
||||
type amin, amax, bmin, bmax; \
|
||||
amin = korr_func(a); \
|
||||
bmin = korr_func(b); \
|
||||
amax = korr_func(a+len); \
|
||||
bmax = korr_func(b+len); \
|
||||
amin= korr_func(a); \
|
||||
bmin= korr_func(b); \
|
||||
amax= korr_func(a+len); \
|
||||
bmax= korr_func(b+len); \
|
||||
a_area *= (((double)amax) - ((double)amin)); \
|
||||
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) \
|
||||
{ \
|
||||
type amin, amax, bmin, bmax; \
|
||||
amin = korr_func(a); \
|
||||
bmin = korr_func(b); \
|
||||
amax = korr_func(a+len); \
|
||||
bmax = korr_func(b+len); \
|
||||
amin= korr_func(a); \
|
||||
bmin= korr_func(b); \
|
||||
amax= korr_func(a+len); \
|
||||
bmax= korr_func(b+len); \
|
||||
a_perim+= (((double)amax) - ((double)amin)); \
|
||||
*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,
|
||||
uint key_length, double *ab_perim)
|
||||
{
|
||||
double a_perim = 0.0;
|
||||
double a_perim= 0.0;
|
||||
|
||||
*ab_perim= 0.0;
|
||||
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) \
|
||||
{ \
|
||||
type amin, amax, bmin, bmax; \
|
||||
amin = korr_func(k + inc); \
|
||||
amax = korr_func(k + inc + len); \
|
||||
k = rt_PAGE_NEXT_KEY(k, k_len, nod_flag); \
|
||||
for (; k < last; k = rt_PAGE_NEXT_KEY(k, k_len, nod_flag)) \
|
||||
amin= korr_func(k + inc); \
|
||||
amax= korr_func(k + inc + len); \
|
||||
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); \
|
||||
bmax = korr_func(k + inc + len); \
|
||||
bmin= korr_func(k + inc); \
|
||||
bmax= korr_func(k + inc + len); \
|
||||
if (amin > bmin) \
|
||||
amin = bmin; \
|
||||
amin= bmin; \
|
||||
if (amax < bmax) \
|
||||
amax = bmax; \
|
||||
amax= bmax; \
|
||||
} \
|
||||
store_func(c, amin); \
|
||||
c += len; \
|
||||
|
|
@ -714,15 +714,15 @@ double maria_rtree_perimeter_increase(HA_KEYSEG *keyseg, uchar* a, uchar* b,
|
|||
type amin, amax, bmin, bmax; \
|
||||
get_func(amin, k + inc); \
|
||||
get_func(amax, k + inc + len); \
|
||||
k = rt_PAGE_NEXT_KEY(k, k_len, nod_flag); \
|
||||
for (; k < last; 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)) \
|
||||
{ \
|
||||
get_func(bmin, k + inc); \
|
||||
get_func(bmax, k + inc + len); \
|
||||
if (amin > bmin) \
|
||||
amin = bmin; \
|
||||
amin= bmin; \
|
||||
if (amax < bmax) \
|
||||
amax = bmax; \
|
||||
amax= bmax; \
|
||||
} \
|
||||
store_func(c, amin); \
|
||||
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,
|
||||
uchar *c, uint key_length)
|
||||
{
|
||||
uint inc = 0;
|
||||
uint k_len = key_length;
|
||||
uint nod_flag = _ma_test_if_nod(page_buf);
|
||||
uint inc= 0;
|
||||
uint k_len= key_length;
|
||||
uint nod_flag= _ma_test_if_nod(info, page_buf);
|
||||
uchar *k;
|
||||
uchar *last = rt_PAGE_END(page_buf);
|
||||
uchar *last= rt_PAGE_END(info, page_buf);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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) {
|
||||
case HA_KEYTYPE_INT8:
|
||||
|
|
|
|||
|
|
@ -32,25 +32,25 @@ typedef struct
|
|||
|
||||
inline static double *reserve_coords(double **d_buffer, int n_dim)
|
||||
{
|
||||
double *coords = *d_buffer;
|
||||
(*d_buffer) += n_dim * 2;
|
||||
double *coords= *d_buffer;
|
||||
(*d_buffer)+= n_dim * 2;
|
||||
return coords;
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
if (a[0] > b[0])
|
||||
a[0] = b[0];
|
||||
a[0]= b[0];
|
||||
|
||||
if (a[1] < b[1])
|
||||
a[1] = b[1];
|
||||
a[1]= b[1];
|
||||
|
||||
a += 2;
|
||||
b += 2;
|
||||
}while (a != end);
|
||||
a+= 2;
|
||||
b+= 2;
|
||||
} 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)
|
||||
{
|
||||
const double *end = a + n_dim * 2;
|
||||
double square = 1.0;
|
||||
const double *end= a + n_dim * 2;
|
||||
double square= 1.0;
|
||||
do
|
||||
{
|
||||
square *=
|
||||
((a[1] < b[1]) ? b[1] : a[1]) - ((a[0] > b[0]) ? b[0] : a[0]);
|
||||
|
||||
a += 2;
|
||||
b += 2;
|
||||
}while (a != end);
|
||||
a+= 2;
|
||||
b+= 2;
|
||||
} while (a != end);
|
||||
|
||||
return square;
|
||||
}
|
||||
|
||||
static double count_square(const double *a, int n_dim)
|
||||
{
|
||||
const double *end = a + n_dim * 2;
|
||||
double square = 1.0;
|
||||
const double *end= a + n_dim * 2;
|
||||
double square= 1.0;
|
||||
do
|
||||
{
|
||||
square *= a[1] - a[0];
|
||||
a += 2;
|
||||
}while (a != end);
|
||||
a+= 2;
|
||||
} while (a != end);
|
||||
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 *cur1;
|
||||
SplitStruct *lim1 = node + (n_entries - 1);
|
||||
SplitStruct *lim1= node + (n_entries - 1);
|
||||
SplitStruct *cur2;
|
||||
SplitStruct *lim2 = node + n_entries;
|
||||
SplitStruct *lim2= node + n_entries;
|
||||
|
||||
double max_d = -DBL_MAX;
|
||||
double max_d= -DBL_MAX;
|
||||
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;
|
||||
if (d > max_d)
|
||||
{
|
||||
max_d = d;
|
||||
*seed_a = cur1;
|
||||
*seed_b = cur2;
|
||||
max_d= d;
|
||||
*seed_a= cur1;
|
||||
*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,
|
||||
SplitStruct **choice, int *n_group, int n_dim)
|
||||
{
|
||||
SplitStruct *cur = node;
|
||||
SplitStruct *end = node + n_entries;
|
||||
SplitStruct *cur= node;
|
||||
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 abs_diff;
|
||||
|
|
@ -141,15 +141,15 @@ static void pick_next(SplitStruct *node, int n_entries, double *g1, double *g2,
|
|||
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);
|
||||
|
||||
abs_diff = fabs(diff);
|
||||
abs_diff= fabs(diff);
|
||||
if (abs_diff > max_diff)
|
||||
{
|
||||
max_diff = abs_diff;
|
||||
*n_group = 1 + (diff > 0);
|
||||
*choice = cur;
|
||||
max_diff= abs_diff;
|
||||
*n_group= 1 + (diff > 0);
|
||||
*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)
|
||||
{
|
||||
SplitStruct *cur = node;
|
||||
SplitStruct *end = node + n_entries;
|
||||
for (; cur<end; ++cur)
|
||||
SplitStruct *cur= node;
|
||||
SplitStruct *end= node + n_entries;
|
||||
|
||||
for (; cur < end; cur++)
|
||||
{
|
||||
if (cur->n_node)
|
||||
{
|
||||
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 *a;
|
||||
SplitStruct *b;
|
||||
double *g1 = reserve_coords(d_buffer, n_dim);
|
||||
double *g2 = reserve_coords(d_buffer, n_dim);
|
||||
double *g1= reserve_coords(d_buffer, n_dim);
|
||||
double *g2= reserve_coords(d_buffer, n_dim);
|
||||
SplitStruct *next;
|
||||
int next_node;
|
||||
int i;
|
||||
SplitStruct *end = node + n_entries;
|
||||
SplitStruct *end= node + n_entries;
|
||||
LINT_INIT(a);
|
||||
LINT_INIT(b);
|
||||
LINT_INIT(next);
|
||||
|
|
@ -197,22 +198,22 @@ static int split_maria_rtree_node(SplitStruct *node, int n_entries,
|
|||
return 1;
|
||||
}
|
||||
|
||||
cur = node;
|
||||
for (; cur<end; ++cur)
|
||||
cur= node;
|
||||
for (; cur < end; cur++)
|
||||
{
|
||||
cur->square = count_square(cur->coords, n_dim);
|
||||
cur->n_node = 0;
|
||||
cur->square= count_square(cur->coords, n_dim);
|
||||
cur->n_node= 0;
|
||||
}
|
||||
|
||||
pick_seeds(node, n_entries, &a, &b, n_dim);
|
||||
a->n_node = 1;
|
||||
b->n_node = 2;
|
||||
a->n_node= 1;
|
||||
b->n_node= 2;
|
||||
|
||||
|
||||
copy_coords(g1, a->coords, n_dim);
|
||||
size1 += key_size;
|
||||
size1+= key_size;
|
||||
copy_coords(g2, b->coords, n_dim);
|
||||
size2 += key_size;
|
||||
size2+= key_size;
|
||||
|
||||
|
||||
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);
|
||||
if (next_node == 1)
|
||||
{
|
||||
size1 += key_size;
|
||||
size1+= key_size;
|
||||
mbr_join(g1, next->coords, n_dim);
|
||||
}
|
||||
else
|
||||
{
|
||||
size2 += key_size;
|
||||
size2+= key_size;
|
||||
mbr_join(g2, next->coords, n_dim);
|
||||
}
|
||||
next->n_node = next_node;
|
||||
next->n_node= next_node;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
@ -262,14 +263,15 @@ int maria_rtree_split_page(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
|
|||
uchar *source_cur, *cur1, *cur2;
|
||||
uchar *new_page;
|
||||
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 :
|
||||
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_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) *
|
||||
(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));
|
||||
|
||||
next_coord = coord_buf;
|
||||
next_coord= coord_buf;
|
||||
|
||||
stop = task + max_keys;
|
||||
source_cur = rt_PAGE_FIRST_KEY(page, nod_flag);
|
||||
stop= task + max_keys;
|
||||
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))
|
||||
{
|
||||
cur->coords = reserve_coords(&next_coord, n_dim);
|
||||
cur->key = source_cur;
|
||||
cur->coords= reserve_coords(&next_coord, n_dim);
|
||||
cur->key= source_cur;
|
||||
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);
|
||||
cur->key = key;
|
||||
cur->key= key;
|
||||
|
||||
old_coord = next_coord;
|
||||
old_coord= next_coord;
|
||||
|
||||
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),
|
||||
2, 2, &next_coord, n_dim))
|
||||
{
|
||||
err_code = 1;
|
||||
err_code= 1;
|
||||
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;
|
||||
goto split_err;
|
||||
}
|
||||
|
||||
stop = task + (max_keys + 1);
|
||||
cur1 = rt_PAGE_FIRST_KEY(page, nod_flag);
|
||||
cur2 = rt_PAGE_FIRST_KEY(new_page, nod_flag);
|
||||
stop= task + (max_keys + 1);
|
||||
cur1= rt_PAGE_FIRST_KEY(info, page, nod_flag);
|
||||
cur2= rt_PAGE_FIRST_KEY(info, new_page, nod_flag);
|
||||
|
||||
n1= n2 = 0;
|
||||
for (cur = task; cur < stop; ++cur)
|
||||
n1= n2= 0;
|
||||
for (cur= task; cur < stop; cur++)
|
||||
{
|
||||
uchar *to;
|
||||
if (cur->n_node == 1)
|
||||
{
|
||||
to = cur1;
|
||||
cur1 = rt_PAGE_NEXT_KEY(cur1, key_length, nod_flag);
|
||||
++n1;
|
||||
to= cur1;
|
||||
cur1= rt_PAGE_NEXT_KEY(cur1, key_length, nod_flag);
|
||||
n1++;
|
||||
}
|
||||
else
|
||||
{
|
||||
to = cur2;
|
||||
cur2 = rt_PAGE_NEXT_KEY(cur2, key_length, nod_flag);
|
||||
++n2;
|
||||
to= cur2;
|
||||
cur2= rt_PAGE_NEXT_KEY(cur2, key_length, nod_flag);
|
||||
n2++;
|
||||
}
|
||||
if (to != cur->key)
|
||||
memcpy(to - nod_flag, cur->key - nod_flag, full_length);
|
||||
}
|
||||
|
||||
maria_putint(page, 2 + n1 * full_length, nod_flag);
|
||||
maria_putint(new_page, 2 + n2 * full_length, nod_flag);
|
||||
_ma_store_page_used(info, page, info->s->keypage_header + n1 * full_length,
|
||||
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)) ==
|
||||
HA_OFFSET_ERROR)
|
||||
|
|
|
|||
|
|
@ -122,7 +122,8 @@ static int run_test(const char *filename)
|
|||
|
||||
/* 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].length=key_length;
|
||||
rec_length+=key_length;
|
||||
|
|
@ -135,7 +136,8 @@ static int run_test(const char *filename)
|
|||
keyinfo[0].flag=0;
|
||||
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].flag=0; /* Things like HA_REVERSE_SORT */
|
||||
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)
|
||||
{
|
||||
if (inx == -1) /* Use last index */
|
||||
inx=info->lastinx;
|
||||
if (inx < 0 || ! maria_is_key_active(info->s->state.key_map, inx))
|
||||
{
|
||||
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;
|
||||
int error,flag;
|
||||
uint nod_flag;
|
||||
uint nod_flag, used_length;
|
||||
uchar *keypos,*maxpos;
|
||||
uchar lastkey[HA_MAX_KEY_BUFF],*buff;
|
||||
DBUG_ENTER("_ma_search");
|
||||
|
|
@ -80,14 +78,14 @@ int _ma_search(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
|
|||
info->keyread_buff,
|
||||
test(!(nextflag & SEARCH_SAVE_BUFF)))))
|
||||
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,
|
||||
&keypos,lastkey, &last_key);
|
||||
if (flag == MARIA_FOUND_WRONG_KEY)
|
||||
DBUG_RETURN(-1);
|
||||
nod_flag=_ma_test_if_nod(buff);
|
||||
maxpos=buff+maria_data_on_page(buff)-1;
|
||||
_ma_get_used_and_nod(info, buff, used_length, nod_flag);
|
||||
maxpos= buff + used_length -1;
|
||||
|
||||
if (flag)
|
||||
{
|
||||
|
|
@ -98,7 +96,7 @@ int _ma_search(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
|
|||
if (flag >0)
|
||||
{
|
||||
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 */
|
||||
}
|
||||
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->last_search_keypage=info->last_keypage;
|
||||
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_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 *buff __attribute__((unused)), my_bool *last_key)
|
||||
{
|
||||
reg4 int start,mid,end,save_end;
|
||||
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");
|
||||
|
||||
LINT_INIT(flag);
|
||||
totlength=keyinfo->keylength+(nod_flag=_ma_test_if_nod(page));
|
||||
start=0; mid=1;
|
||||
save_end=end=(int) ((maria_data_on_page(page)-2-nod_flag)/totlength-1);
|
||||
DBUG_PRINT("test",("page_length: %d end: %d",maria_data_on_page(page),end));
|
||||
page+=2+nod_flag;
|
||||
_ma_get_used_and_nod(info, page, used_length, nod_flag);
|
||||
|
||||
totlength= keyinfo->keylength + nod_flag;
|
||||
start=0;
|
||||
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)
|
||||
{
|
||||
|
|
@ -244,14 +247,16 @@ int _ma_seq_search(MARIA_HA *info, register MARIA_KEYDEF *keyinfo, uchar *page,
|
|||
uchar *buff, my_bool *last_key)
|
||||
{
|
||||
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;
|
||||
DBUG_ENTER("_ma_seq_search");
|
||||
|
||||
LINT_INIT(flag); LINT_INIT(length);
|
||||
end= page+maria_data_on_page(page);
|
||||
nod_flag=_ma_test_if_nod(page);
|
||||
page+=2+nod_flag;
|
||||
LINT_INIT(flag);
|
||||
LINT_INIT(length);
|
||||
|
||||
_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;
|
||||
t_buff[0]=0; /* Avoid bugs */
|
||||
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
|
||||
*/
|
||||
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;
|
||||
int key_len_skip, seg_len_pack, key_len_left;
|
||||
uchar *end;
|
||||
|
|
@ -314,11 +319,11 @@ int _ma_prefix_search(MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
|
|||
LINT_INIT(saved_vseg);
|
||||
|
||||
t_buff[0]=0; /* Avoid bugs */
|
||||
end= page+maria_data_on_page(page);
|
||||
nod_flag=_ma_test_if_nod(page);
|
||||
page+=2+nod_flag;
|
||||
*ret_pos=page;
|
||||
kseg= (uchar*) key;
|
||||
_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;
|
||||
kseg= key;
|
||||
|
||||
get_key_pack_length(kseg_len, length_pack, kseg);
|
||||
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 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++))
|
||||
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 *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;
|
||||
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)))
|
||||
{
|
||||
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
|
||||
{
|
||||
page+=2+nod_flag;
|
||||
page+= info->s->keypage_header + nod_flag;
|
||||
key[0]=0; /* safety */
|
||||
while (page <= keypos)
|
||||
{
|
||||
|
|
@ -1080,8 +1092,13 @@ uchar *_ma_get_key(MARIA_HA *info, MARIA_KEYDEF *keyinfo, uchar *page,
|
|||
} /* _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,
|
||||
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;
|
||||
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)))
|
||||
{
|
||||
*return_key_length=keyinfo->keylength;
|
||||
|
|
@ -1100,7 +1117,7 @@ static my_bool _ma_get_prev_key(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
|
|||
}
|
||||
else
|
||||
{
|
||||
page+=2+nod_flag;
|
||||
page+= info->s->keypage_header + nod_flag;
|
||||
key[0]=0; /* safety */
|
||||
while (page < keypos)
|
||||
{
|
||||
|
|
@ -1117,9 +1134,12 @@ static my_bool _ma_get_prev_key(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
|
|||
} /* _ma_get_key */
|
||||
|
||||
|
||||
/*
|
||||
@brief Get last key from key-page
|
||||
|
||||
/* Get last key from key-page */
|
||||
/* Return pointer to where key starts */
|
||||
@return
|
||||
@retval pointer to where key starts
|
||||
*/
|
||||
|
||||
uchar *_ma_get_last_key(MARIA_HA *info, MARIA_KEYDEF *keyinfo, uchar *page,
|
||||
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,
|
||||
(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)))
|
||||
{
|
||||
lastpos=endpos-keyinfo->keylength-nod_flag;
|
||||
|
|
@ -1140,7 +1160,8 @@ uchar *_ma_get_last_key(MARIA_HA *info, MARIA_KEYDEF *keyinfo, uchar *page,
|
|||
}
|
||||
else
|
||||
{
|
||||
lastpos=(page+=2+nod_flag);
|
||||
page+= info->s->keypage_header + nod_flag;
|
||||
lastpos= page;
|
||||
lastkey[0]=0;
|
||||
while (page < endpos)
|
||||
{
|
||||
|
|
@ -1162,7 +1183,7 @@ uchar *_ma_get_last_key(MARIA_HA *info, MARIA_KEYDEF *keyinfo, uchar *page,
|
|||
} /* _ma_get_last_key */
|
||||
|
||||
|
||||
/* Calculate length of key */
|
||||
/* Calculate length of 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 */
|
||||
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 */
|
||||
{
|
||||
|
|
@ -1300,7 +1321,7 @@ int _ma_search_next(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
|
|||
info->int_keypos, &length);
|
||||
if (!info->int_keypos)
|
||||
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,
|
||||
nextflag | SEARCH_SAVE_BUFF, pos));
|
||||
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
|
||||
{
|
||||
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;
|
||||
DBUG_RETURN(-1);
|
||||
}
|
||||
nod_flag=_ma_test_if_nod(info->keyread_buff);
|
||||
page=info->keyread_buff+2+nod_flag;
|
||||
nod_flag=_ma_test_if_nod(info, info->keyread_buff);
|
||||
page= info->keyread_buff + info->s->keypage_header + nod_flag;
|
||||
} while ((pos= _ma_kpos(nod_flag,page)) != HA_OFFSET_ERROR);
|
||||
|
||||
if (!(info->lastkey_length=(*keyinfo->get_key)(keyinfo,nod_flag,&page,
|
||||
info->lastkey)))
|
||||
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_keytree_version=keyinfo->version;
|
||||
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)
|
||||
{
|
||||
uint nod_flag;
|
||||
uchar *buff,*page;
|
||||
uchar *buff,*end_of_page;
|
||||
DBUG_ENTER("_ma_search_last");
|
||||
|
||||
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;
|
||||
do
|
||||
{
|
||||
uint used_length;
|
||||
if (!_ma_fetch_keypage(info,keyinfo,pos,DFLT_INIT_HITS,buff,0))
|
||||
{
|
||||
info->cur_row.lastpos= HA_OFFSET_ERROR;
|
||||
DBUG_RETURN(-1);
|
||||
}
|
||||
page= buff+maria_data_on_page(buff);
|
||||
nod_flag=_ma_test_if_nod(buff);
|
||||
} while ((pos= _ma_kpos(nod_flag,page)) != HA_OFFSET_ERROR);
|
||||
_ma_get_used_and_nod(info, buff, used_length, nod_flag);
|
||||
end_of_page= buff + used_length;
|
||||
} 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))
|
||||
DBUG_RETURN(-1);
|
||||
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_keytree_version=keyinfo->version;
|
||||
info->last_search_keypage=info->last_keypage;
|
||||
|
|
|
|||
|
|
@ -92,7 +92,7 @@ my_var_write(MARIA_SORT_PARAM *info, IO_CACHE *to_file, uchar *bufs);
|
|||
_ma_create_index_by_sort()
|
||||
info Sort parameters
|
||||
no_messages Set to 1 if no output
|
||||
sortbuff_size Size if sortbuffer to allocate
|
||||
sortbuff_size Size of sortbuffer to allocate
|
||||
|
||||
RESULT
|
||||
0 ok
|
||||
|
|
@ -100,10 +100,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,
|
||||
ulong sortbuff_size)
|
||||
size_t sortbuff_size)
|
||||
{
|
||||
int error,maxbuffer,skr;
|
||||
uint memavl,old_memavl,keys,sort_length;
|
||||
size_t memavl,old_memavl;
|
||||
uint keys,sort_length;
|
||||
DYNAMIC_ARRAY buffpek;
|
||||
ha_rows records;
|
||||
uchar **sort_keys;
|
||||
|
|
@ -313,8 +314,9 @@ pthread_handler_t _ma_thr_find_all_keys(void *arg)
|
|||
{
|
||||
MARIA_SORT_PARAM *sort_param= (MARIA_SORT_PARAM*) arg;
|
||||
int error;
|
||||
uint memavl,old_memavl,keys,sort_length;
|
||||
uint idx, maxbuffer;
|
||||
size_t memavl,old_memavl;
|
||||
uint sort_length;
|
||||
ulong idx, maxbuffer, keys;
|
||||
uchar **sort_keys=0;
|
||||
|
||||
LINT_INIT(keys);
|
||||
|
|
@ -355,19 +357,18 @@ pthread_handler_t _ma_thr_find_all_keys(void *arg)
|
|||
|
||||
while (memavl >= MIN_SORT_MEMORY)
|
||||
{
|
||||
if ((my_off_t) (idx+1)*(sort_length+sizeof(char*)) <=
|
||||
(my_off_t) memavl)
|
||||
if ((my_off_t) (idx+1)*(sort_length+sizeof(char*)) <= (my_off_t) memavl)
|
||||
keys= idx+1;
|
||||
else
|
||||
{
|
||||
uint skr;
|
||||
ulong skr;
|
||||
do
|
||||
{
|
||||
skr= maxbuffer;
|
||||
if (memavl < sizeof(BUFFPEK)*maxbuffer ||
|
||||
(keys=(memavl-sizeof(BUFFPEK)*maxbuffer)/
|
||||
(sort_length+sizeof(char*))) <= 1 ||
|
||||
keys < (uint) maxbuffer)
|
||||
keys < maxbuffer)
|
||||
{
|
||||
_ma_check_print_error(sort_param->sort_info->param,
|
||||
"maria_sort_buffer_size is too small");
|
||||
|
|
@ -403,8 +404,8 @@ pthread_handler_t _ma_thr_find_all_keys(void *arg)
|
|||
}
|
||||
|
||||
if (sort_param->sort_info->param->testflag & T_VERBOSE)
|
||||
printf("Key %d - Allocating buffer for %d keys\n",
|
||||
sort_param->key+1, keys);
|
||||
printf("Key %d - Allocating buffer for %lu keys\n",
|
||||
sort_param->key+1, (ulong) keys);
|
||||
sort_param->sort_keys= sort_keys;
|
||||
|
||||
idx= error= 0;
|
||||
|
|
@ -492,7 +493,7 @@ int _ma_thr_write_keys(MARIA_SORT_PARAM *sort_param)
|
|||
MARIA_SORT_INFO *sort_info=sort_param->sort_info;
|
||||
HA_CHECK *param=sort_info->param;
|
||||
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;
|
||||
uint i;
|
||||
MARIA_HA *info=sort_info->info;
|
||||
|
|
|
|||
|
|
@ -24,10 +24,12 @@
|
|||
#endif
|
||||
|
||||
LIST *maria_open_list=0;
|
||||
uchar NEAR maria_file_magic[]=
|
||||
uchar maria_file_magic[]=
|
||||
{ (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', };
|
||||
/* Unique number for this maria instance */
|
||||
uchar maria_uuid[MY_UUID_SIZE];
|
||||
uint maria_quick_table_bits=9;
|
||||
ulong maria_block_size= MARIA_KEY_BLOCK_LENGTH;
|
||||
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 , == , >= , <= , > , <
|
||||
*/
|
||||
|
||||
uint NEAR maria_read_vec[]=
|
||||
uint maria_read_vec[]=
|
||||
{
|
||||
SEARCH_FIND, SEARCH_FIND | SEARCH_BIGGER, SEARCH_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
|
||||
};
|
||||
|
||||
uint NEAR maria_readnext_vec[]=
|
||||
uint maria_readnext_vec[]=
|
||||
{
|
||||
SEARCH_BIGGER, SEARCH_BIGGER, SEARCH_SMALLER, SEARCH_BIGGER, 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 put_blob_in_record(uchar *blob_pos,char **blob_buffer,
|
||||
ulong *length);
|
||||
static void copy_key(struct st_maria_info *info,uint inx,
|
||||
uchar *record,uchar *key);
|
||||
static void copy_key(MARIA_HA *info, uint inx, uchar *record, uchar *key);
|
||||
|
||||
static int verbose=0,testflag=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)
|
||||
{
|
||||
|
|
@ -311,6 +308,10 @@ int main(int argc, char *argv[])
|
|||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
if (testflag == 2)
|
||||
goto end;
|
||||
|
||||
#ifdef REMOVE_WHEN_WE_HAVE_RESIZE
|
||||
if (pagecacheing)
|
||||
resize_pagecache(maria_pagecache, maria_block_size,
|
||||
|
|
@ -453,7 +454,7 @@ int main(int argc, char *argv[])
|
|||
info.recpos= maria_position(file);
|
||||
int skr=maria_rnext(file,read_record2,0);
|
||||
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 ||
|
||||
info.recpos != maria_position(file))
|
||||
{
|
||||
|
|
@ -877,7 +878,7 @@ int main(int argc, char *argv[])
|
|||
goto err;
|
||||
}
|
||||
opt_delete++;
|
||||
#if 0
|
||||
#if TO_BE_REMOVED
|
||||
/
|
||||
/*
|
||||
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;' `
|
||||
$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`
|
||||
mv $table.MAD $tmp/$table.MAD.good
|
||||
rm $table.MAI
|
||||
mv $table.MAD $tmp/$table-good.MAD
|
||||
mv $table.MAI $tmp/$table-good.MAI
|
||||
apply_log "shouldnotchangelog"
|
||||
cmp $table.MAD $tmp/$table.MAD.good
|
||||
cmp $table.MAD $tmp/$table-good.MAD
|
||||
check_table_is_same
|
||||
echo "testing idempotency"
|
||||
apply_log "shouldnotchangelog"
|
||||
cmp $table.MAD $tmp/$table.MAD.good
|
||||
cmp $table.MAD $tmp/$table-good.MAD
|
||||
check_table_is_same
|
||||
shift
|
||||
done
|
||||
|
|
@ -145,8 +145,8 @@ do
|
|||
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
|
||||
checksum=`$maria_path/maria_chk -dss $table`
|
||||
mv $table.MAD $tmp/$table.MAD.good
|
||||
rm $table.MAI
|
||||
mv $table.MAD $tmp/$table-good.MAD
|
||||
mv $table.MAI $tmp/$table-good.MAI
|
||||
rm maria_log.* maria_log_control
|
||||
echo "TEST WITH $prog $abort_run_args$test_undo (additional aborted work)"
|
||||
$maria_path/$prog $abort_run_args$test_undo
|
||||
|
|
|
|||
|
|
@ -31,36 +31,36 @@ applying log
|
|||
Differences in maria_chk -dvv, recovery not yet perfect !
|
||||
========DIFF START=======
|
||||
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=======
|
||||
testing idempotency
|
||||
applying log
|
||||
Differences in maria_chk -dvv, recovery not yet perfect !
|
||||
========DIFF START=======
|
||||
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=======
|
||||
TEST WITH ma_test2 -s -M -T -c -b
|
||||
applying log
|
||||
Differences in maria_chk -dvv, recovery not yet perfect !
|
||||
========DIFF START=======
|
||||
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=======
|
||||
testing idempotency
|
||||
applying log
|
||||
Differences in maria_chk -dvv, recovery not yet perfect !
|
||||
========DIFF START=======
|
||||
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=======
|
||||
Testing the REDO AND UNDO PHASE
|
||||
TEST WITH ma_test1 -s -M -T -c -N --testflag=1 (commit at end)
|
||||
|
|
@ -182,7 +182,7 @@ Differences in maria_chk -dvv, recovery not yet perfect !
|
|||
11c11
|
||||
< Datafile length: 8192 Keyfile length: 8192
|
||||
---
|
||||
> Datafile length: 90112 Keyfile length: 204800
|
||||
> Datafile length: 114688 Keyfile length: 204800
|
||||
========DIFF END=======
|
||||
testing idempotency
|
||||
applying log
|
||||
|
|
@ -195,7 +195,7 @@ Differences in maria_chk -dvv, recovery not yet perfect !
|
|||
11c11
|
||||
< Datafile length: 8192 Keyfile length: 8192
|
||||
---
|
||||
> Datafile length: 90112 Keyfile length: 204800
|
||||
> Datafile length: 114688 Keyfile length: 204800
|
||||
========DIFF END=======
|
||||
testing applying of CLRs to recreate table
|
||||
applying log
|
||||
|
|
@ -208,7 +208,7 @@ Differences in maria_chk -dvv, recovery not yet perfect !
|
|||
11c11
|
||||
< Datafile length: 8192 Keyfile length: 8192
|
||||
---
|
||||
> Datafile length: 90112 Keyfile length: 8192
|
||||
> Datafile length: 114688 Keyfile length: 8192
|
||||
========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=2 --test-undo=2 (additional aborted work)
|
||||
|
|
@ -329,7 +329,7 @@ Differences in maria_chk -dvv, recovery not yet perfect !
|
|||
11c11
|
||||
< Datafile length: 8192 Keyfile length: 8192
|
||||
---
|
||||
> Datafile length: 90112 Keyfile length: 204800
|
||||
> Datafile length: 114688 Keyfile length: 204800
|
||||
========DIFF END=======
|
||||
testing idempotency
|
||||
applying log
|
||||
|
|
@ -342,7 +342,7 @@ Differences in maria_chk -dvv, recovery not yet perfect !
|
|||
11c11
|
||||
< Datafile length: 8192 Keyfile length: 8192
|
||||
---
|
||||
> Datafile length: 90112 Keyfile length: 204800
|
||||
> Datafile length: 114688 Keyfile length: 204800
|
||||
========DIFF END=======
|
||||
testing applying of CLRs to recreate table
|
||||
applying log
|
||||
|
|
@ -355,7 +355,7 @@ Differences in maria_chk -dvv, recovery not yet perfect !
|
|||
11c11
|
||||
< Datafile length: 8192 Keyfile length: 8192
|
||||
---
|
||||
> Datafile length: 90112 Keyfile length: 8192
|
||||
> Datafile length: 114688 Keyfile length: 8192
|
||||
========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=2 --test-undo=3 (additional aborted work)
|
||||
|
|
@ -476,7 +476,7 @@ Differences in maria_chk -dvv, recovery not yet perfect !
|
|||
11c11
|
||||
< Datafile length: 8192 Keyfile length: 8192
|
||||
---
|
||||
> Datafile length: 90112 Keyfile length: 204800
|
||||
> Datafile length: 114688 Keyfile length: 204800
|
||||
========DIFF END=======
|
||||
testing idempotency
|
||||
applying log
|
||||
|
|
@ -489,7 +489,7 @@ Differences in maria_chk -dvv, recovery not yet perfect !
|
|||
11c11
|
||||
< Datafile length: 8192 Keyfile length: 8192
|
||||
---
|
||||
> Datafile length: 90112 Keyfile length: 204800
|
||||
> Datafile length: 114688 Keyfile length: 204800
|
||||
========DIFF END=======
|
||||
testing applying of CLRs to recreate table
|
||||
applying log
|
||||
|
|
@ -502,7 +502,7 @@ Differences in maria_chk -dvv, recovery not yet perfect !
|
|||
11c11
|
||||
< Datafile length: 8192 Keyfile length: 8192
|
||||
---
|
||||
> Datafile length: 90112 Keyfile length: 8192
|
||||
> Datafile length: 114688 Keyfile length: 8192
|
||||
========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=2 --test-undo=1 (additional aborted work)
|
||||
|
|
@ -623,7 +623,7 @@ Differences in maria_chk -dvv, recovery not yet perfect !
|
|||
11c11
|
||||
< Datafile length: 8192 Keyfile length: 8192
|
||||
---
|
||||
> Datafile length: 81920 Keyfile length: 212992
|
||||
> Datafile length: 114688 Keyfile length: 212992
|
||||
========DIFF END=======
|
||||
testing idempotency
|
||||
applying log
|
||||
|
|
@ -636,7 +636,7 @@ Differences in maria_chk -dvv, recovery not yet perfect !
|
|||
11c11
|
||||
< Datafile length: 8192 Keyfile length: 8192
|
||||
---
|
||||
> Datafile length: 81920 Keyfile length: 212992
|
||||
> Datafile length: 114688 Keyfile length: 212992
|
||||
========DIFF END=======
|
||||
testing applying of CLRs to recreate table
|
||||
applying log
|
||||
|
|
@ -649,7 +649,7 @@ Differences in maria_chk -dvv, recovery not yet perfect !
|
|||
11c11
|
||||
< Datafile length: 8192 Keyfile length: 8192
|
||||
---
|
||||
> Datafile length: 81920 Keyfile length: 8192
|
||||
> Datafile length: 114688 Keyfile length: 8192
|
||||
========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=2 --test-undo=2 (additional aborted work)
|
||||
|
|
@ -770,7 +770,7 @@ Differences in maria_chk -dvv, recovery not yet perfect !
|
|||
11c11
|
||||
< Datafile length: 8192 Keyfile length: 8192
|
||||
---
|
||||
> Datafile length: 81920 Keyfile length: 212992
|
||||
> Datafile length: 114688 Keyfile length: 212992
|
||||
========DIFF END=======
|
||||
testing idempotency
|
||||
applying log
|
||||
|
|
@ -783,7 +783,7 @@ Differences in maria_chk -dvv, recovery not yet perfect !
|
|||
11c11
|
||||
< Datafile length: 8192 Keyfile length: 8192
|
||||
---
|
||||
> Datafile length: 81920 Keyfile length: 212992
|
||||
> Datafile length: 114688 Keyfile length: 212992
|
||||
========DIFF END=======
|
||||
testing applying of CLRs to recreate table
|
||||
applying log
|
||||
|
|
@ -796,7 +796,7 @@ Differences in maria_chk -dvv, recovery not yet perfect !
|
|||
11c11
|
||||
< Datafile length: 8192 Keyfile length: 8192
|
||||
---
|
||||
> Datafile length: 81920 Keyfile length: 8192
|
||||
> Datafile length: 114688 Keyfile length: 8192
|
||||
========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=2 --test-undo=3 (additional aborted work)
|
||||
|
|
@ -917,7 +917,7 @@ Differences in maria_chk -dvv, recovery not yet perfect !
|
|||
11c11
|
||||
< Datafile length: 8192 Keyfile length: 8192
|
||||
---
|
||||
> Datafile length: 81920 Keyfile length: 212992
|
||||
> Datafile length: 114688 Keyfile length: 212992
|
||||
========DIFF END=======
|
||||
testing idempotency
|
||||
applying log
|
||||
|
|
@ -930,7 +930,7 @@ Differences in maria_chk -dvv, recovery not yet perfect !
|
|||
11c11
|
||||
< Datafile length: 8192 Keyfile length: 8192
|
||||
---
|
||||
> Datafile length: 81920 Keyfile length: 212992
|
||||
> Datafile length: 114688 Keyfile length: 212992
|
||||
========DIFF END=======
|
||||
testing applying of CLRs to recreate table
|
||||
applying log
|
||||
|
|
@ -943,5 +943,5 @@ Differences in maria_chk -dvv, recovery not yet perfect !
|
|||
11c11
|
||||
< Datafile length: 8192 Keyfile length: 8192
|
||||
---
|
||||
> Datafile length: 81920 Keyfile length: 8192
|
||||
> Datafile length: 114688 Keyfile length: 8192
|
||||
========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,
|
||||
uchar *curr_buff,uchar *father_buff,
|
||||
uchar *father_keypos,my_off_t father_page);
|
||||
static uchar *_ma_find_last_pos(MARIA_KEYDEF *keyinfo, uchar *page,
|
||||
uchar *key, uint *return_key_length,
|
||||
uchar **after_key);
|
||||
static uchar *_ma_find_last_pos(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
|
||||
uchar *page, uchar *key,
|
||||
uint *return_key_length, uchar **after_key);
|
||||
int _ma_ck_write_tree(register MARIA_HA *info, uint keynr,uchar *key,
|
||||
uint key_length);
|
||||
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)) ==
|
||||
HA_OFFSET_ERROR)
|
||||
goto err2;
|
||||
goto err2;
|
||||
}
|
||||
|
||||
/* Write all keys to indextree */
|
||||
|
|
@ -277,6 +277,7 @@ err:
|
|||
my_errno=save_errno;
|
||||
err2:
|
||||
save_errno=my_errno;
|
||||
DBUG_ASSERT(save_errno);
|
||||
DBUG_PRINT("error", ("got error: %d", save_errno));
|
||||
VOID(_ma_writeinfo(info,WRITEINFO_UPDATE_KEYFILE));
|
||||
allow_break(); /* Allow SIGHUP & SIGINT */
|
||||
|
|
@ -294,10 +295,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));
|
||||
}
|
||||
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 */
|
||||
|
||||
|
||||
|
|
@ -366,12 +364,18 @@ int _ma_enlarge_root(MARIA_HA *info, MARIA_KEYDEF *keyinfo, uchar *key,
|
|||
DBUG_ENTER("_ma_enlarge_root");
|
||||
|
||||
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,
|
||||
(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);
|
||||
info->keyread_buff_used=info->page_changed=1; /* info->buff is used */
|
||||
|
||||
_ma_store_keynr(info, info->buff, (keyinfo - info->s->keyinfo));
|
||||
_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 ||
|
||||
_ma_write_keypage(info,keyinfo,*root,DFLT_INIT_HITS,info->buff))
|
||||
DBUG_RETURN(-1);
|
||||
|
|
@ -379,12 +383,14 @@ int _ma_enlarge_root(MARIA_HA *info, MARIA_KEYDEF *keyinfo, uchar *key,
|
|||
} /* _ma_enlarge_root */
|
||||
|
||||
|
||||
/*
|
||||
Search after a position for a key and store it there
|
||||
Returns -1 = error
|
||||
0 = ok
|
||||
1 = key should be stored in higher tree
|
||||
*/
|
||||
/*
|
||||
Search after a position for a key and store it there
|
||||
|
||||
@return
|
||||
@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,
|
||||
uint comp_flag, uchar *key, uint key_length, my_off_t page,
|
||||
|
|
@ -409,7 +415,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,
|
||||
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)
|
||||
{
|
||||
uint tmp_key_length;
|
||||
|
|
@ -442,7 +448,8 @@ static int w_search(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
|
|||
keyinfo=&info->s->ft2_keyinfo;
|
||||
get_key_full_length_rdonly(off, key);
|
||||
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,
|
||||
&root, comp_flag);
|
||||
_ma_dpointer(info, keypos+HA_FT_WLEN, root);
|
||||
|
|
@ -525,17 +532,17 @@ int _ma_insert(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
|
|||
DBUG_EXECUTE("key", _ma_print_key(DBUG_FILE,keyinfo->seg,key,
|
||||
USE_WHOLE_KEY););
|
||||
|
||||
nod_flag=_ma_test_if_nod(anc_buff);
|
||||
a_length= maria_data_on_page(anc_buff);
|
||||
_ma_get_used_and_nod(info, anc_buff, a_length, nod_flag);
|
||||
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,
|
||||
(key_pos == endpos ? (uchar*) 0 : key_pos),
|
||||
prev_key, prev_key,
|
||||
key,&s_temp);
|
||||
#ifndef DBUG_OFF
|
||||
if (key_pos != anc_buff+2+nod_flag && (keyinfo->flag &
|
||||
(HA_BINARY_PACK_KEY | HA_PACK_KEY)))
|
||||
if (key_pos != anc_buff + info->s->keypage_header + nod_flag &&
|
||||
(keyinfo->flag & (HA_BINARY_PACK_KEY | HA_PACK_KEY)))
|
||||
{
|
||||
DBUG_DUMP("prev_key",(uchar*) key_buff, _ma_keylength(keyinfo,key_buff));
|
||||
}
|
||||
|
|
@ -569,11 +576,11 @@ int _ma_insert(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
|
|||
}
|
||||
(*keyinfo->store_key)(keyinfo,key_pos,&s_temp);
|
||||
a_length+=t_length;
|
||||
maria_putint(anc_buff,a_length,nod_flag);
|
||||
if (a_length <= keyinfo->block_length)
|
||||
_ma_store_page_used(info, anc_buff, a_length, nod_flag);
|
||||
if (a_length <= (uint) keyinfo->block_length - KEYPAGE_CHECKSUM_SIZE)
|
||||
{
|
||||
if (keyinfo->block_length - a_length < 32 &&
|
||||
keyinfo->flag & HA_FULLTEXT && key_pos == endpos &&
|
||||
if (keyinfo->block_length - KEYPAGE_CHECKSUM_SIZE - a_length < 32 &&
|
||||
(keyinfo->flag & HA_FULLTEXT) && key_pos == endpos &&
|
||||
info->s->base.key_reflength <= info->s->base.rec_reflength &&
|
||||
info->s->options & (HA_OPTION_PACK_RECORD | HA_OPTION_COMPRESS_RECORD))
|
||||
{
|
||||
|
|
@ -582,7 +589,7 @@ int _ma_insert(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
|
|||
Let's consider converting.
|
||||
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;
|
||||
/* the very first key on the page is always unpacked */
|
||||
DBUG_ASSERT((*b & 128) == 0);
|
||||
|
|
@ -597,25 +604,28 @@ int _ma_insert(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
|
|||
ha_compare_text(keyinfo->seg->charset, (uchar*) a, alen,
|
||||
(uchar*) b, blen, 0, 0) == 0)
|
||||
{
|
||||
/* yup. converting */
|
||||
/* Yup. converting */
|
||||
info->ft1_to_ft2=(DYNAMIC_ARRAY *)
|
||||
my_malloc(sizeof(DYNAMIC_ARRAY), MYF(MY_WME));
|
||||
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 (!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;
|
||||
for (a=anc_buff+a_length ; b < a ; b+=ft2len+2)
|
||||
insert_dynamic(info->ft1_to_ft2, b);
|
||||
|
||||
/* 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 */
|
||||
}
|
||||
|
|
@ -645,31 +655,33 @@ int _ma_split_page(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
|
|||
MARIA_KEY_PARAM s_temp;
|
||||
DBUG_ENTER("maria_split_page");
|
||||
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)
|
||||
info->page_changed=1; /* Info->buff is used */
|
||||
info->keyread_buff_used=1;
|
||||
nod_flag=_ma_test_if_nod(buff);
|
||||
key_ref_length=2+nod_flag;
|
||||
nod_flag=_ma_test_if_nod(info, buff);
|
||||
key_ref_length= info->s->keypage_header + nod_flag;
|
||||
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
|
||||
key_pos= _ma_find_half_pos(nod_flag,keyinfo,buff,key_buff, &key_length,
|
||||
&after_key);
|
||||
key_pos= _ma_find_half_pos(info, nod_flag, keyinfo, buff, key_buff,
|
||||
&key_length, &after_key);
|
||||
if (!key_pos)
|
||||
DBUG_RETURN(-1);
|
||||
|
||||
length=(uint) (key_pos-buff);
|
||||
a_length= maria_data_on_page(buff);
|
||||
maria_putint(buff,length,nod_flag);
|
||||
a_length= _ma_get_page_used(info, buff);
|
||||
_ma_store_page_used(info, buff, length, nod_flag);
|
||||
|
||||
key_pos=after_key;
|
||||
if (nod_flag)
|
||||
{
|
||||
DBUG_PRINT("test",("Splitting nod"));
|
||||
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 */
|
||||
|
|
@ -688,8 +700,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,
|
||||
(size_t) length);
|
||||
(*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))
|
||||
DBUG_RETURN(-1);
|
||||
DBUG_DUMP("key",(uchar*) key, _ma_keylength(keyinfo,key));
|
||||
|
|
@ -697,25 +715,26 @@ int _ma_split_page(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
|
|||
} /* _ma_split_page */
|
||||
|
||||
|
||||
/*
|
||||
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
|
||||
*/
|
||||
/*
|
||||
Calculate how to much to move to split a page in two
|
||||
|
||||
uchar *_ma_find_half_pos(uint nod_flag, MARIA_KEYDEF *keyinfo, uchar *page,
|
||||
uchar *key, uint *return_key_length,
|
||||
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(MARIA_HA *info, uint nod_flag, MARIA_KEYDEF *keyinfo,
|
||||
uchar *page, uchar *key, uint *return_key_length,
|
||||
uchar **after_key)
|
||||
{
|
||||
uint keys,length,key_ref_length;
|
||||
uchar *end,*lastpos;
|
||||
DBUG_ENTER("_ma_find_half_pos");
|
||||
|
||||
key_ref_length=2+nod_flag;
|
||||
length= maria_data_on_page(page)-key_ref_length;
|
||||
page+=key_ref_length;
|
||||
key_ref_length= info->s->keypage_header + nod_flag;
|
||||
length= _ma_get_page_used(info, page) - key_ref_length;
|
||||
page+= key_ref_length; /* Point to first key */
|
||||
if (!(keyinfo->flag &
|
||||
(HA_PACK_KEY | HA_SPACE_PACK_USED | HA_VAR_LENGTH_KEY |
|
||||
HA_BINARY_PACK_KEY)))
|
||||
|
|
@ -751,7 +770,8 @@ uchar *_ma_find_half_pos(uint nod_flag, MARIA_KEYDEF *keyinfo, uchar *page,
|
|||
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 **after_key)
|
||||
{
|
||||
|
|
@ -760,8 +780,8 @@ static uchar *_ma_find_last_pos(MARIA_KEYDEF *keyinfo, uchar *page,
|
|||
uchar key_buff[HA_MAX_KEY_BUFF];
|
||||
DBUG_ENTER("_ma_find_last_pos");
|
||||
|
||||
key_ref_length=2;
|
||||
length= maria_data_on_page(page)-key_ref_length;
|
||||
key_ref_length= info->s->keypage_header;
|
||||
length= _ma_get_page_used(info, page) - key_ref_length;
|
||||
page+=key_ref_length;
|
||||
if (!(keyinfo->flag &
|
||||
(HA_PACK_KEY | HA_SPACE_PACK_USED | HA_VAR_LENGTH_KEY |
|
||||
|
|
@ -818,15 +838,16 @@ static int _ma_balance_page(register MARIA_HA *info, MARIA_KEYDEF *keyinfo,
|
|||
DBUG_ENTER("_ma_balance_page");
|
||||
|
||||
k_length=keyinfo->keylength;
|
||||
father_length= maria_data_on_page(father_buff);
|
||||
father_keylength=k_length+info->s->base.key_reflength;
|
||||
nod_flag=_ma_test_if_nod(curr_buff);
|
||||
father_length= _ma_get_page_used(info, father_buff);
|
||||
father_keylength= k_length + info->s->base.key_reflength;
|
||||
nod_flag=_ma_test_if_nod(info, curr_buff);
|
||||
curr_keylength=k_length+nod_flag;
|
||||
info->page_changed=1;
|
||||
|
||||
if ((father_key_pos != father_buff+father_length &&
|
||||
(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;
|
||||
next_page= _ma_kpos(info->s->base.key_reflength,
|
||||
|
|
@ -846,42 +867,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))
|
||||
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 */
|
||||
|
||||
left_length= maria_data_on_page(curr_buff);
|
||||
right_length= maria_data_on_page(buff);
|
||||
keys=(left_length+right_length-4-nod_flag*2)/curr_keylength;
|
||||
left_length= _ma_get_page_used(info, curr_buff);
|
||||
right_length= _ma_get_page_used(info, buff);
|
||||
keys= ((left_length+right_length-info->s->keypage_header*2-nod_flag*2)/
|
||||
curr_keylength);
|
||||
|
||||
if ((right ? right_length : left_length) + curr_keylength <=
|
||||
keyinfo->block_length)
|
||||
(uint) keyinfo->block_length - KEYPAGE_CHECKSUM_SIZE)
|
||||
{ /* Merge buffs */
|
||||
new_left_length=2+nod_flag+(keys/2)*curr_keylength;
|
||||
new_right_length=2+nod_flag+((keys+1)/2)*curr_keylength;
|
||||
maria_putint(curr_buff,new_left_length,nod_flag);
|
||||
maria_putint(buff,new_right_length,nod_flag);
|
||||
new_left_length= info->s->keypage_header+nod_flag+(keys/2)*curr_keylength;
|
||||
new_right_length=info->s->keypage_header+nod_flag+(((keys+1)/2)*
|
||||
curr_keylength);
|
||||
_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)
|
||||
{ /* Move keys buff -> leaf */
|
||||
pos=curr_buff+left_length;
|
||||
memcpy((uchar*) pos,(uchar*) father_key_pos, (size_t) k_length);
|
||||
memcpy((uchar*) pos+k_length, (uchar*) buff+2,
|
||||
memcpy(pos,father_key_pos, (size_t) k_length);
|
||||
memcpy(pos+k_length, buff + info->s->keypage_header,
|
||||
(size_t) (length=new_left_length - left_length - k_length));
|
||||
pos=buff+2+length;
|
||||
memcpy((uchar*) father_key_pos,(uchar*) pos,(size_t) k_length);
|
||||
bmove((uchar*) buff+2,(uchar*) pos+k_length,new_right_length);
|
||||
pos= buff + info->s->keypage_header + length;
|
||||
memcpy(father_key_pos, pos, (size_t) k_length);
|
||||
bmove(buff + info->s->keypage_header, pos + k_length, new_right_length);
|
||||
}
|
||||
else
|
||||
{ /* Move keys -> buff */
|
||||
|
||||
bmove_upp((uchar*) buff+new_right_length,(uchar*) buff+right_length,
|
||||
right_length-2);
|
||||
bmove_upp(buff + new_right_length, buff + right_length,
|
||||
right_length - info->s->keypage_header);
|
||||
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;
|
||||
memcpy((uchar*) father_key_pos,(uchar*) pos,(size_t) k_length);
|
||||
memcpy((uchar*) buff+2,(uchar*) pos+k_length,(size_t) length);
|
||||
memcpy(father_key_pos, pos, (size_t) k_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) ||
|
||||
|
|
@ -893,7 +918,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 */
|
||||
|
||||
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 */
|
||||
new_left_length-=curr_keylength;
|
||||
extra_length=nod_flag+left_length+right_length-
|
||||
|
|
@ -902,28 +933,37 @@ static int _ma_balance_page(register MARIA_HA *info, MARIA_KEYDEF *keyinfo,
|
|||
left_length, right_length,
|
||||
new_left_length, new_right_length,
|
||||
extra_length));
|
||||
maria_putint(curr_buff,new_left_length,nod_flag);
|
||||
maria_putint(buff,new_right_length,nod_flag);
|
||||
maria_putint(extra_buff,extra_length+2,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);
|
||||
/* 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 */
|
||||
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 */
|
||||
memcpy(tmp_part_key, pos-k_length,k_length);
|
||||
/* Make place for new keys */
|
||||
bmove_upp((uchar*) buff+new_right_length,(uchar*) pos-k_length,
|
||||
right_length-extra_length-k_length-2);
|
||||
bmove_upp(buff+ new_right_length, pos - k_length,
|
||||
right_length - extra_length - k_length - info->s->keypage_header);
|
||||
/* Copy keys from left page */
|
||||
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));
|
||||
/* 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 */
|
||||
memcpy((uchar*) (right ? key : father_key_pos),pos,(size_t) k_length);
|
||||
memcpy((uchar*) (right ? father_key_pos : key),tmp_part_key, k_length);
|
||||
memcpy((right ? key : father_key_pos),pos,(size_t) 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)
|
||||
goto err;
|
||||
|
|
@ -970,7 +1010,7 @@ static int keys_compare(bulk_insert_param *param, uchar *key1, uchar *key2)
|
|||
{
|
||||
uint not_used[2];
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -830,6 +830,9 @@ static int maria_chk(HA_CHECK *param, char *filename)
|
|||
case HA_ERR_OLD_FILE:
|
||||
_ma_check_print_error(param,"'%s' is a old type of MARIA-table", filename);
|
||||
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:
|
||||
_ma_check_print_error(param,"Couldn't read complete header from '%s'", filename);
|
||||
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)
|
||||
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",
|
||||
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
|
||||
buff[0]=0;
|
||||
if (param->testflag & T_VERBOSE)
|
||||
printf("%11lu %12s %10d",
|
||||
printf("%11.0g %12s %10d",
|
||||
share->state.rec_per_key_part[keyseg_nr++],
|
||||
buff,keyinfo->block_length);
|
||||
VOID(putchar('\n'));
|
||||
|
|
@ -1402,7 +1407,7 @@ static void descript(HA_CHECK *param, register MARIA_HA *info, char *name)
|
|||
printf(" %-6ld%-3d %-21s",
|
||||
(long) keyseg->start+1,keyseg->length,buff);
|
||||
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'));
|
||||
}
|
||||
keyseg++;
|
||||
|
|
@ -1681,7 +1686,7 @@ static int sort_record_index(MARIA_SORT_PARAM *sort_param,MARIA_HA *info,
|
|||
HA_CHECK *param=sort_info->param;
|
||||
DBUG_ENTER("sort_record_index");
|
||||
|
||||
nod_flag=_ma_test_if_nod(buff);
|
||||
nod_flag=_ma_test_if_nod(info, buff);
|
||||
temp_buff=0;
|
||||
|
||||
if (nod_flag)
|
||||
|
|
@ -1692,9 +1697,9 @@ static int sort_record_index(MARIA_SORT_PARAM *sort_param,MARIA_HA *info,
|
|||
DBUG_RETURN(-1);
|
||||
}
|
||||
}
|
||||
used_length= maria_data_on_page(buff);
|
||||
keypos=buff+2+nod_flag;
|
||||
endpos=buff+used_length;
|
||||
used_length= _ma_get_page_used(info, buff);
|
||||
keypos= buff + info->s->keypage_header + nod_flag;
|
||||
endpos= buff + used_length;
|
||||
for ( ;; )
|
||||
{
|
||||
_sanity(__FILE__,__LINE__);
|
||||
|
|
|
|||
|
|
@ -25,13 +25,16 @@
|
|||
#else
|
||||
#include <my_no_pthread.h>
|
||||
#endif
|
||||
|
||||
#include "ma_loghandler.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 MARIA_MAX_TREE_LEVELS 32
|
||||
#define SANITY_CHECKS
|
||||
|
||||
struct st_transaction;
|
||||
|
||||
|
|
@ -79,11 +82,12 @@ typedef struct st_maria_state_info
|
|||
ulong unique; /* Unique number for this process */
|
||||
ulong update_count; /* Updated for each write lock */
|
||||
ulong status;
|
||||
ulong *rec_per_key_part;
|
||||
double *rec_per_key_part;
|
||||
ulong *nulls_per_key_part;
|
||||
ha_checksum checksum; /* Table checksum */
|
||||
my_off_t *key_root; /* Start of key trees */
|
||||
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_used; /* which extra index are in use */
|
||||
|
|
@ -108,18 +112,19 @@ typedef struct st_maria_state_info
|
|||
|
||||
#define MARIA_STATE_INFO_SIZE \
|
||||
(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_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_KEYDEF_SIZE (2+ 5*2)
|
||||
#define MARIA_UNIQUEDEF_SIZE (2+1+1)
|
||||
#define HA_KEYSEG_SIZE (6+ 2*2 + 4*2)
|
||||
#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 */
|
||||
/* 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
|
||||
|
|
@ -171,9 +176,12 @@ typedef struct st_ma_base_info
|
|||
uint default_rec_buff_size;
|
||||
/* Extra number of bytes the row format require in the record buffer */
|
||||
uint extra_rec_buff_size;
|
||||
/* Tuning flags that can be ignored by older Maria versions */
|
||||
uint extra_options;
|
||||
|
||||
/* The following are from the header */
|
||||
uint key_parts, all_key_parts;
|
||||
uchar uuid[MY_UUID_SIZE];
|
||||
/**
|
||||
@brief If false, we disable logging, versioning, transaction etc. Observe
|
||||
difference with MARIA_SHARE::now_transactional
|
||||
|
|
@ -233,6 +241,7 @@ typedef struct st_maria_share
|
|||
MARIA_COLUMNDEF *columndef; /* Pointer to column information */
|
||||
MARIA_PACK pack; /* Data about packed records */
|
||||
MARIA_BLOB *blobs; /* Pointer to blobs */
|
||||
uint16 *column_nr; /* Original column order */
|
||||
char *unique_file_name; /* realpath() of index file */
|
||||
char *data_file_name; /* Resolved path names from symlinks */
|
||||
char *index_file_name;
|
||||
|
|
@ -247,38 +256,38 @@ typedef struct st_maria_share
|
|||
/* Called when the last instance of the table is closed */
|
||||
my_bool (*once_end)(struct st_maria_share *);
|
||||
/* 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 */
|
||||
void (*end)(struct st_maria_info *);
|
||||
void (*end)(MARIA_HA *);
|
||||
/* 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 */
|
||||
my_bool (*scan_init)(struct st_maria_info *);
|
||||
my_bool (*scan_init)(MARIA_HA *);
|
||||
/* 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 */
|
||||
void (*scan_end)(struct st_maria_info *);
|
||||
void (*scan_end)(MARIA_HA *);
|
||||
/* 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) */
|
||||
my_bool (*write_record)(struct st_maria_info *, const uchar *);
|
||||
my_bool (*write_record)(MARIA_HA *, const uchar *);
|
||||
/* Called when write failed */
|
||||
my_bool (*write_record_abort)(struct st_maria_info *);
|
||||
my_bool (*update_record)(struct st_maria_info *, MARIA_RECORD_POS,
|
||||
my_bool (*write_record_abort)(MARIA_HA *);
|
||||
my_bool (*update_record)(MARIA_HA *, MARIA_RECORD_POS,
|
||||
const uchar *, const uchar *);
|
||||
my_bool (*delete_record)(struct st_maria_info *, const uchar *record);
|
||||
my_bool (*compare_record)(struct st_maria_info *, const uchar *);
|
||||
my_bool (*delete_record)(MARIA_HA *, const uchar *record);
|
||||
my_bool (*compare_record)(MARIA_HA *, const uchar *);
|
||||
/* 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
|
||||
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 */
|
||||
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 */
|
||||
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);
|
||||
/* Mapings to read/write the data file */
|
||||
size_t (*file_read)(MARIA_HA *, uchar *, size_t, my_off_t, myf);
|
||||
|
|
@ -293,6 +302,7 @@ typedef struct st_maria_share
|
|||
ulong state_diff_length;
|
||||
uint rec_reflength; /* rec_reflength in use now */
|
||||
uint unique_name_length;
|
||||
uint keypage_header;
|
||||
uint32 ftparsers; /* Number of distinct ftparsers
|
||||
+ 1 */
|
||||
PAGECACHE_FILE kfile; /* Shared keyfile */
|
||||
|
|
@ -396,7 +406,7 @@ typedef struct st_maria_block_scan
|
|||
} MARIA_BLOCK_SCAN;
|
||||
|
||||
|
||||
struct st_maria_info
|
||||
struct st_maria_handler
|
||||
{
|
||||
MARIA_SHARE *s; /* Shared between open:s */
|
||||
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 */
|
||||
uint int_nod_flag; /* -""- */
|
||||
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 */
|
||||
ulong this_unique; /* uniq filenumber or thread */
|
||||
ulong last_unique; /* last unique number */
|
||||
|
|
@ -513,10 +523,32 @@ struct st_maria_info
|
|||
#define READING_NEXT 1
|
||||
#define READING_HEADER 2
|
||||
|
||||
#define maria_data_on_page(x) ((uint) mi_uint2korr(x) & 32767)
|
||||
#define maria_putint(x,y,nod) { uint16 boh=(nod ? (uint16) 32768 : 0) + (uint16) (y);\
|
||||
mi_int2store(x,boh); }
|
||||
#define _ma_test_if_nod(x) (x[0] & 128 ? info->s->base.key_reflength : 0)
|
||||
/* Number of bytes on key pages to indicate used size */
|
||||
#define KEYPAGE_USED_SIZE 2
|
||||
#define KEYPAGE_KEYID_SIZE 1
|
||||
#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; \
|
||||
DBUG_PRINT("error", ("Marked table crashed")); \
|
||||
}while(0)
|
||||
|
|
@ -559,7 +591,7 @@ struct st_maria_info
|
|||
{ 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 MARIA_MIN_BLOCK_LENGTH 20 /* Because of delete-link */
|
||||
|
|
@ -610,8 +642,9 @@ extern pthread_mutex_t THR_LOCK_maria;
|
|||
|
||||
/* Some extern variables */
|
||||
extern LIST *maria_open_list;
|
||||
extern uchar NEAR maria_file_magic[], NEAR maria_pack_file_magic[];
|
||||
extern uint NEAR maria_read_vec[], NEAR maria_readnext_vec[];
|
||||
extern uchar maria_file_magic[], maria_pack_file_magic[];
|
||||
extern uchar maria_uuid[MY_UUID_SIZE];
|
||||
extern uint maria_read_vec[], maria_readnext_vec[];
|
||||
extern uint maria_quick_table_bits;
|
||||
extern const char *maria_data_root;
|
||||
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,
|
||||
uchar *key, uchar *buff, uchar *key_buff,
|
||||
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,
|
||||
uint *return_key_length,
|
||||
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_search(MARIA_HA *info, MARIA_KEYDEF *keyinfo, uchar *key,
|
||||
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,
|
||||
uint comp_flag, uchar **ret_pos, uchar *buff,
|
||||
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_read_dsk(File file, MARIA_STATE_INFO *state);
|
||||
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);
|
||||
uchar *_ma_keyseg_read(uchar *ptr, HA_KEYSEG *keyseg);
|
||||
uint _ma_keydef_write(File file, MARIA_KEYDEF *keydef);
|
||||
my_bool _ma_keydef_write(File file, MARIA_KEYDEF *keydef);
|
||||
uchar *_ma_keydef_read(uchar *ptr, MARIA_KEYDEF *keydef);
|
||||
uint _ma_uniquedef_write(File file, MARIA_UNIQUEDEF *keydef);
|
||||
my_bool _ma_uniquedef_write(File file, MARIA_UNIQUEDEF *keydef);
|
||||
uchar *_ma_uniquedef_read(uchar *ptr, MARIA_UNIQUEDEF *keydef);
|
||||
uint _ma_columndef_write(File file, MARIA_COLUMNDEF *columndef);
|
||||
my_bool _ma_columndef_write(File file, MARIA_COLUMNDEF *columndef);
|
||||
uchar *_ma_columndef_read(uchar *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);
|
||||
ha_checksum _ma_checksum(MARIA_HA *info, const uchar *buf);
|
||||
ha_checksum _ma_static_checksum(MARIA_HA *info, const uchar *buf);
|
||||
|
|
@ -943,7 +979,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_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_initialize_data_file(MARIA_SHARE *share, File dfile);
|
||||
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;
|
||||
HUFF_COUNTS *count,*end_count;
|
||||
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");
|
||||
|
||||
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 */
|
||||
if (mrg->file[0]->s->data_file_type == STATIC_RECORD)
|
||||
calc_checksum= _ma_static_checksum;
|
||||
else
|
||||
calc_checksum= _ma_checksum;
|
||||
else
|
||||
calc_checksum= _ma_checksum;
|
||||
|
||||
mrg_reset(mrg);
|
||||
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;
|
||||
break;
|
||||
case HA_KEYTYPE_ULONG_INT:
|
||||
l_1=mi_sint4korr(key);
|
||||
l_1=mi_uint4korr(key);
|
||||
VOID(fprintf(stream,"%lu",(ulong) l_1));
|
||||
key=end;
|
||||
break;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue