summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--client/mysqladmin.cc4
-rw-r--r--include/maria.h75
-rw-r--r--include/my_base.h50
-rw-r--r--include/my_sys.h12
-rw-r--r--include/myisamchk.h5
-rw-r--r--include/mysql_com.h12
-rw-r--r--libmysql/Makefile.shared2
-rw-r--r--mysql-test/r/maria.result56
-rw-r--r--mysql-test/t/maria.test25
-rw-r--r--mysys/Makefile.am1
-rw-r--r--mysys/my_rnd.c55
-rw-r--r--mysys/my_uuid.c169
-rw-r--r--server-tools/instance-manager/listener.cc6
-rw-r--r--server-tools/instance-manager/mysql_connection.cc9
-rw-r--r--server-tools/instance-manager/mysql_connection.h3
-rw-r--r--sql/handler.h2
-rw-r--r--sql/item_func.cc4
-rw-r--r--sql/item_func.h2
-rw-r--r--sql/item_strfunc.cc8
-rw-r--r--sql/lex.h4
-rw-r--r--sql/mysql_priv.h2
-rw-r--r--sql/mysqld.cc4
-rw-r--r--sql/password.c42
-rw-r--r--sql/sql_class.cc2
-rw-r--r--sql/sql_class.h2
-rw-r--r--sql/sql_crypt.cc2
-rw-r--r--sql/sql_crypt.h2
-rw-r--r--sql/sql_show.cc24
-rw-r--r--sql/sql_table.cc5
-rw-r--r--sql/sql_yacc.yy23
-rw-r--r--sql/table.cc6
-rw-r--r--sql/table.h1
-rw-r--r--storage/maria/ha_maria.cc90
-rw-r--r--storage/maria/ma_bitmap.c49
-rw-r--r--storage/maria/ma_blockrec.c286
-rw-r--r--storage/maria/ma_blockrec.h26
-rw-r--r--storage/maria/ma_check.c178
-rw-r--r--storage/maria/ma_checksum.c25
-rw-r--r--storage/maria/ma_create.c52
-rw-r--r--storage/maria/ma_dbug.c2
-rw-r--r--storage/maria/ma_delete.c166
-rw-r--r--storage/maria/ma_ft_update.c7
-rw-r--r--storage/maria/ma_loghandler.h12
-rw-r--r--storage/maria/ma_open.c99
-rw-r--r--storage/maria/ma_page.c39
-rw-r--r--storage/maria/ma_preload.c66
-rw-r--r--storage/maria/ma_range.c12
-rw-r--r--storage/maria/ma_rt_index.c343
-rw-r--r--storage/maria/ma_rt_index.h6
-rw-r--r--storage/maria/ma_rt_key.c21
-rw-r--r--storage/maria/ma_rt_mbr.c120
-rw-r--r--storage/maria/ma_rt_split.c167
-rw-r--r--storage/maria/ma_rt_test.c6
-rw-r--r--storage/maria/ma_search.c129
-rw-r--r--storage/maria/ma_sort.c25
-rw-r--r--storage/maria/ma_static.c10
-rw-r--r--storage/maria/ma_test2.c13
-rwxr-xr-xstorage/maria/ma_test_recovery12
-rw-r--r--storage/maria/ma_test_recovery.expected52
-rw-r--r--storage/maria/ma_write.c232
-rw-r--r--storage/maria/maria_chk.c17
-rw-r--r--storage/maria/maria_def.h116
-rw-r--r--storage/maria/maria_pack.c6
-rw-r--r--storage/myisam/mi_dbug.c2
64 files changed, 1870 insertions, 1135 deletions
diff --git a/client/mysqladmin.cc b/client/mysqladmin.cc
index f6ff44c7d56..5948f4de828 100644
--- a/client/mysqladmin.cc
+++ b/client/mysqladmin.cc
@@ -515,7 +515,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--)
{
@@ -827,7 +827,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)
{
diff --git a/include/maria.h b/include/maria.h
index 1d7778f7c3d..49259915d16 100644
--- a/include/maria.h
+++ b/include/maria.h
@@ -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,
diff --git a/include/my_base.h b/include/my_base.h
index 2ab1123ce76..f69d0dce977 100644
--- a/include/my_base.h
+++ b/include/my_base.h
@@ -293,6 +293,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 */
@@ -302,6 +303,7 @@ enum ha_base_keytype {
#define HA_PACK_RECORD 2 /* Request packed record format */
#define HA_CREATE_TMP_TABLE 4
#define HA_CREATE_CHECKSUM 8
+#define HA_CREATE_PAGE_CHECKSUM 16
#define HA_CREATE_DELAY_KEY_WRITE 64
#define HA_CREATE_RELIES_ON_SQL_LAYER 128
@@ -348,12 +350,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 */
@@ -374,7 +379,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
@@ -389,28 +394,33 @@ enum ha_base_keytype {
#define HA_ERR_NO_SUCH_TABLE 155 /* The table does not exist in engine */
#define HA_ERR_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 */
-
-#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. */
+/* 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 */
+
+/* Number of different errors */
#define HA_ERR_ERRORS (HA_ERR_LAST - HA_ERR_FIRST + 1)
/* Other constants */
diff --git a/include/my_sys.h b/include/my_sys.h
index ca44f9ed39b..65a8c9fdeda 100644
--- a/include/my_sys.h
+++ b/include/my_sys.h
@@ -902,6 +902,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);
diff --git a/include/myisamchk.h b/include/myisamchk.h
index 78350b60bb0..30b986a835a 100644
--- a/include/myisamchk.h
+++ b/include/myisamchk.h
@@ -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;
diff --git a/include/mysql_com.h b/include/mysql_com.h
index ae57e84a696..f05cf8e1068 100644
--- a/include/mysql_com.h
+++ b/include/mysql_com.h
@@ -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
}
@@ -417,10 +413,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);
diff --git a/libmysql/Makefile.shared b/libmysql/Makefile.shared
index 70b67cee28e..118f4d2dde5 100644
--- a/libmysql/Makefile.shared
+++ b/libmysql/Makefile.shared
@@ -68,7 +68,7 @@ mysysobjects1 = my_init.lo my_static.lo my_malloc.lo my_realloc.lo \
mf_iocache2.lo my_seek.lo my_sleep.lo \
my_pread.lo mf_cache.lo md5.lo sha1.lo \
my_getopt.lo my_gethostbyname.lo my_port.lo \
- my_rename.lo my_chsize.lo my_sync.lo
+ my_rename.lo my_chsize.lo my_sync.lo my_rnd.lo
sqlobjects = net.lo
sql_cmn_objects = pack.lo client.lo my_time.lo
diff --git a/mysql-test/r/maria.result b/mysql-test/r/maria.result
index 8c1cb5f3a2f..8a029ef5d16 100644
--- a/mysql-test/r/maria.result
+++ b/mysql-test/r/maria.result
@@ -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
diff --git a/mysql-test/t/maria.test b/mysql-test/t/maria.test
index a98e2a8acf4..06e5a4d5b45 100644
--- a/mysql-test/t/maria.test
+++ b/mysql-test/t/maria.test
@@ -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;
diff --git a/mysys/Makefile.am b/mysys/Makefile.am
index 3d3047b3a9c..3c9cd9ac6dd 100644
--- a/mysys/Makefile.am
+++ b/mysys/Makefile.am
@@ -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 \
diff --git a/mysys/my_rnd.c b/mysys/my_rnd.c
new file mode 100644
index 00000000000..e1aca222954
--- /dev/null
+++ b/mysys/my_rnd.c
@@ -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);
+}
diff --git a/mysys/my_uuid.c b/mysys/my_uuid.c
new file mode 100644
index 00000000000..3c3cd8836fc
--- /dev/null
+++ b/mysys/my_uuid.c
@@ -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));
+}
diff --git a/server-tools/instance-manager/listener.cc b/server-tools/instance-manager/listener.cc
index e68ba2fe8ce..ce0f6fb5d2e 100644
--- a/server-tools/instance-manager/listener.cc
+++ b/server-tools/instance-manager/listener.cc
@@ -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>
diff --git a/server-tools/instance-manager/mysql_connection.cc b/server-tools/instance-manager/mysql_connection.cc
index bf08f963aa3..de611878bb4 100644
--- a/server-tools/instance-manager/mysql_connection.cc
+++ b/server-tools/instance-manager/mysql_connection.cc
@@ -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 */
diff --git a/server-tools/instance-manager/mysql_connection.h b/server-tools/instance-manager/mysql_connection.h
index 56bbf76e146..933dd820372 100644
--- a/server-tools/instance-manager/mysql_connection.h
+++ b/server-tools/instance-manager/mysql_connection.h
@@ -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;
diff --git a/sql/handler.h b/sql/handler.h
index feb551670a3..c498dd6e7af 100644
--- a/sql/handler.h
+++ b/sql/handler.h
@@ -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"
@@ -786,6 +787,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;
diff --git a/sql/item_func.cc b/sql/item_func.cc
index 5a41aa3e9da..557f01e2c65 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -2132,7 +2132,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));
}
@@ -2152,7 +2152,7 @@ bool Item_func_rand::fix_fields(THD *thd,Item **ref)
No need to send a Rand log event if seed was given eg: RAND(seed),
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;
diff --git a/sql/item_func.h b/sql/item_func.h
index 347a4a1f084..f02b35d2e80 100644
--- a/sql/item_func.h
+++ b/sql/item_func.h
@@ -664,7 +664,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() {}
diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc
index a376504512f..ca43bd6011a 100644
--- a/sql/item_strfunc.cc
+++ b/sql/item_strfunc.cc
@@ -3303,7 +3303,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";
@@ -3351,9 +3351,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 */
@@ -3364,7 +3364,7 @@ String *Item_func_uuid::val_str(String *str)
*--s=_dig_vec_lower[mac[i] & 15];
*--s=_dig_vec_lower[mac[i] >> 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();
}
diff --git a/sql/lex.h b/sql/lex.h
index 5f24b06cf05..aab2182b097 100644
--- a/sql/lex.h
+++ b/sql/lex.h
@@ -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)},
diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h
index 683a6553632..b52bdf90a69 100644
--- a/sql/mysql_priv.h
+++ b/sql/mysql_priv.h
@@ -1810,7 +1810,7 @@ extern SHOW_VAR status_vars[];
extern struct system_variables global_system_variables;
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[];
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 2b47be2cddc..4b802c83eb6 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -610,7 +610,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;
@@ -3239,7 +3239,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
diff --git a/sql/password.c b/sql/password.c
index 1ff67888ea4..43430f37f96 100644
--- a/sql/password.c
+++ b/sql/password.c
@@ -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. */
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index 53651f92001..d83b3f51ce0 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -446,7 +446,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);
diff --git a/sql/sql_class.h b/sql/sql_class.h
index 0a518e860e5..8d55d06c3ec 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -993,7 +993,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 */
diff --git a/sql/sql_crypt.cc b/sql/sql_crypt.cc
index ebd424f00f0..53babf517c1 100644
--- a/sql/sql_crypt.cc
+++ b/sql/sql_crypt.cc
@@ -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;
diff --git a/sql/sql_crypt.h b/sql/sql_crypt.h
index f3db9adde25..7d803245b0b 100644
--- a/sql/sql_crypt.h
+++ b/sql/sql_crypt.h
@@ -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);
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index 8906c5654c7..1c1b86d11a7 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -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);
@@ -1153,6 +1156,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;
@@ -1337,19 +1342,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)
{
@@ -3001,8 +3012,12 @@ static int get_schema_tables_record(THD *thd, struct st_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)
@@ -3015,6 +3030,9 @@ static int get_schema_tables_record(THD *thd, struct st_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);
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 22b1d7701e7..98b64551de7 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -7082,10 +7082,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))
{
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index 8def8a43249..e6b0aeb6430 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -470,6 +470,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;
@@ -858,6 +859,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 */
@@ -993,6 +995,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
@@ -1126,6 +1129,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
@@ -4335,6 +4340,12 @@ create_table_option:
Lex->create_info.used_fields|= HA_CREATE_USED_PACK_KEYS;
}
| CHECKSUM_SYM opt_equal ulong_num { Lex->create_info.table_options|= $3 ? HA_OPTION_CHECKSUM : HA_OPTION_NO_CHECKSUM; Lex->create_info.used_fields|= HA_CREATE_USED_CHECKSUM; }
+ | TABLE_CHECKSUM_SYM opt_equal ulong_num { Lex->create_info.table_options|= $3 ? HA_OPTION_CHECKSUM : HA_OPTION_NO_CHECKSUM; Lex->create_info.used_fields|= HA_CREATE_USED_CHECKSUM; }
+ | PAGE_CHECKSUM_SYM opt_equal choice
+ {
+ Lex->create_info.used_fields|= HA_CREATE_USED_PAGE_CHECKSUM;
+ Lex->create_info.page_checksum= $3;
+ }
| DELAY_KEY_WRITE_SYM opt_equal ulong_num { Lex->create_info.table_options|= $3 ? HA_OPTION_DELAY_KEY_WRITE : HA_OPTION_NO_DELAY_KEY_WRITE; Lex->create_info.used_fields|= HA_CREATE_USED_DELAY_KEY_WRITE; }
| ROW_FORMAT_SYM opt_equal row_types { Lex->create_info.row_type= $3; Lex->create_info.used_fields|= HA_CREATE_USED_ROW_FORMAT; }
| UNION_SYM opt_equal '(' table_list ')'
@@ -4366,11 +4377,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;
}
;
@@ -8000,6 +8010,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 */
@@ -10046,6 +10061,7 @@ keyword_sp:
| ONE_SYM {}
| PACK_KEYS_SYM {}
| PAGE_SYM {}
+ | PAGE_CHECKSUM_SYM {}
| PARTIAL {}
| PARTITIONING_SYM {}
| PARTITIONS_SYM {}
@@ -10108,6 +10124,7 @@ keyword_sp:
| SUBPARTITIONS_SYM {}
| SUPER_SYM {}
| SUSPEND_SYM {}
+ | TABLE_CHECKSUM_SYM {}
| TABLES {}
| TABLESPACE {}
| TEMPORARY {}
diff --git a/sql/table.cc b/sql/table.cc
index e8add38640c..abdb635f899 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -655,7 +655,8 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
if (!head[32]) // New frm file in 3.23
{
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;
@@ -2373,7 +2374,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;
diff --git a/sql/table.h b/sql/table.h
index 47b2cbd3075..cd3d12614fb 100644
--- a/sql/table.h
+++ b/sql/table.h
@@ -204,6 +204,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 */
diff --git a/storage/maria/ha_maria.cc b/storage/maria/ha_maria.cc
index 678b88063db..6cecb95cac9 100644
--- a/storage/maria/ha_maria.cc
+++ b/storage/maria/ha_maria.cc
@@ -372,8 +372,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,
@@ -725,9 +726,6 @@ bool ha_maria::check_if_locking_is_allowed(uint sql_command,
int ha_maria::open(const char *name, int mode, uint test_if_locked)
{
- MARIA_KEYDEF *keyinfo;
- MARIA_COLUMNDEF *recinfo= 0;
- uint recs;
uint i;
#ifdef NOT_USED
@@ -753,39 +751,6 @@ int ha_maria::open(const char *name, int mode, uint test_if_locked)
if (!(file= maria_open(name, mode, test_if_locked | HA_OPEN_FROM_SQL_LAYER)))
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));
@@ -817,16 +782,6 @@ int ha_maria::open(const char *name, int mode, uint test_if_locked)
table->key_info[i].block_size= file->s->keyinfo[i].block_length;
}
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;
}
@@ -1918,9 +1873,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);
@@ -2112,6 +2070,10 @@ void ha_maria::update_create_info(HA_CREATE_INFO *create_info)
}
create_info->data_file_name= data_file_name;
create_info->index_file_name= index_file_name;
+ /* We need to restore the row type as Maria can change it */
+ if (create_info->row_type != ROW_TYPE_DEFAULT &&
+ !(create_info->used_fields & HA_CREATE_USED_ROW_FORMAT))
+ create_info->row_type= get_row_type();
}
@@ -2161,7 +2123,16 @@ int ha_maria::create(const char *name, register TABLE *table_arg,
break;
}
}
+ /* 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));
@@ -2175,18 +2146,13 @@ 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
*/
-#endif
create_info.transactional= (row_type == BLOCK_RECORD &&
ha_create_info->transactional != HA_CHOICE_NO);
@@ -2198,6 +2164,8 @@ int ha_maria::create(const char *name, register TABLE *table_arg,
create_flags|= HA_CREATE_CHECKSUM;
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=
diff --git a/storage/maria/ma_bitmap.c b/storage/maria/ma_bitmap.c
index 684f5e16ffa..5bda329ceab 100644
--- a/storage/maria/ma_bitmap.c
+++ b/storage/maria/ma_bitmap.c
@@ -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
@@ -452,10 +455,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 ;
@@ -541,14 +540,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);
@@ -1425,6 +1440,7 @@ static my_bool write_rest_of_head(MARIA_HA *info, uint position,
row->space_on_head_page contains minimum number of bytes we
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,
@@ -2065,9 +2081,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;
diff --git a/storage/maria/ma_blockrec.c b/storage/maria/ma_blockrec.c
index 3ec18d229c2..1e2cda8e8e1 100644
--- a/storage/maria/ma_blockrec.c
+++ b/storage/maria/ma_blockrec.c
@@ -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>
@@ -599,17 +605,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.
@@ -646,7 +677,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 */
}
}
@@ -824,60 +861,76 @@ static uint empty_space_on_page(uchar *buff, uint block_size)
buff[EMPTY_SPACE_OFFSET] is NOT updated but left up to the caller
+ 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;
@@ -1082,8 +1135,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)
@@ -1172,7 +1225,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
@@ -1202,22 +1255,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;
}
@@ -1269,7 +1331,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);
@@ -1302,8 +1364,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)
@@ -1407,7 +1468,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;
@@ -1509,6 +1570,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,
@@ -2330,7 +2394,7 @@ static my_bool write_block_record(MARIA_HA *info,
(uint) (log_array_pos - log_array),
log_array, log_data);
if (log_array != tmp_log_array)
- my_free((uchar*) log_array, MYF(0));
+ my_free(log_array, MYF(0));
if (error)
goto disk_err;
}
@@ -2510,6 +2574,7 @@ static my_bool allocate_and_write_block_record(MARIA_HA *info,
if (_ma_bitmap_find_place(info, row, blocks))
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,
@@ -2710,8 +2775,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)
{
@@ -2820,9 +2884,9 @@ my_bool _ma_update_block_record(MARIA_HA *info, MARIA_RECORD_POS record_pos,
static int delete_dir_entry(uchar *buff, uint block_size, uint record_number,
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
@@ -2838,33 +2902,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;
@@ -3118,7 +3223,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;
@@ -3135,8 +3240,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
@@ -3258,7 +3362,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);
}
@@ -4079,8 +4183,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");
@@ -4634,7 +4738,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;
@@ -4643,7 +4747,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,
@@ -4664,25 +4767,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)
@@ -4698,7 +4803,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)
@@ -4916,6 +5021,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,
diff --git a/storage/maria/ma_blockrec.h b/storage/maria/ma_blockrec.h
index 30dffe1c0c0..f9adc6a830e 100644
--- a/storage/maria/ma_blockrec.h
+++ b/storage/maria/ma_blockrec.h
@@ -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);
diff --git a/storage/maria/ma_check.c b/storage/maria/ma_check.c
index fa1c812daf7..79b267b6bd5 100644
--- a/storage/maria/ma_check.c
+++ b/storage/maria/ma_check.c
@@ -264,7 +264,8 @@ static int check_k_link(HA_CHECK *param, register MARIA_HA *info,
{
uint block_size= info->s->block_size;
ha_rows records;
- char llbuff[21], llbuff2[21], *buff;
+ char llbuff[21], llbuff2[21];
+ uchar *buff;
DBUG_ENTER("check_k_link");
records= (ha_rows) (info->state->key_file_length / block_size);
@@ -313,7 +314,11 @@ static int check_k_link(HA_CHECK *param, register MARIA_HA *info,
DBUG_RETURN(1);
/* 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;
}
@@ -418,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];
@@ -444,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++)
{
@@ -454,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;
}
@@ -627,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 */
@@ -742,7 +747,7 @@ int maria_collect_stats_nonulls_next(HA_KEYSEG *keyseg, ulonglong *notnull,
}
- /* Check if index is ok */
+/* Check if index is ok */
static int chk_index(HA_CHECK *param, MARIA_HA *info, MARIA_KEYDEF *keyinfo,
my_off_t page, uchar *buff, ha_rows *keys,
@@ -755,7 +760,7 @@ static int chk_index(HA_CHECK *param, MARIA_HA *info, MARIA_KEYDEF *keyinfo,
char llbuff[22];
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)
@@ -771,16 +776,22 @@ static int chk_index(HA_CHECK *param, MARIA_HA *info, MARIA_KEYDEF *keyinfo,
comp_flag=SEARCH_FIND | SEARCH_UPDATE; /* Not real duplicates */
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",
@@ -1388,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.
@@ -1399,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;
@@ -1417,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,
@@ -1454,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)));
}
@@ -1665,7 +1731,7 @@ static int check_block_record(HA_CHECK *param, MARIA_HA *info, int extend,
if (page_type == UNALLOCATED_PAGE || page_type >= MAX_PAGE_TYPE)
{
_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;
@@ -1831,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)
@@ -2424,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,
@@ -2620,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)
@@ -2666,7 +2732,7 @@ static int sort_one_index(HA_CHECK *param, MARIA_HA *info,
}
/* Fill block with zero and write it to the new index file */
- 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)))
@@ -2775,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;
@@ -2912,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++)
{
@@ -2924,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;
}
@@ -2990,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;
@@ -3004,9 +3070,11 @@ int maria_repair_by_sort(HA_CHECK *param, register MARIA_HA *info,
sort_info.max_records= (ha_rows) info->state->records;
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)
@@ -3200,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. */
@@ -3377,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;
@@ -3392,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;
@@ -4656,12 +4724,14 @@ static int sort_insert_key(MARIA_SORT_PARAM *sort_param,
_ma_check_print_error(param,"To many key-block-levels; Try increasing sort_key_blocks");
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)
@@ -4672,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)
{
@@ -4681,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;
@@ -4698,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))
@@ -4792,7 +4862,7 @@ int _ma_flush_pending_blocks(MARIA_SORT_PARAM *sort_param)
for (key_block=sort_info->key_block ; key_block->inited ; key_block++)
{
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;
@@ -5079,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;
}
}
@@ -5246,13 +5316,14 @@ void _ma_update_auto_increment_key(HA_CHECK *param, MARIA_HA *info,
IGNORE_NULLS n/a tuples that don't have NULLs
*/
-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];
@@ -5271,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;
}
}
diff --git a/storage/maria/ma_checksum.c b/storage/maria/ma_checksum.c
index 9076b3ebb86..b48eae1c27d 100644
--- a/storage/maria/ma_checksum.c
+++ b/storage/maria/ma_checksum.c
@@ -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:
{
diff --git a/storage/maria/ma_create.c b/storage/maria/ma_create.c
index ba1d9a13b42..db31d62fb8e 100644
--- a/storage/maria/ma_create.c
+++ b/storage/maria/ma_create.c
@@ -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);
@@ -900,6 +918,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));
@@ -911,9 +930,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;
diff --git a/storage/maria/ma_dbug.c b/storage/maria/ma_dbug.c
index a23e7248029..5996e42a101 100644
--- a/storage/maria/ma_dbug.c
+++ b/storage/maria/ma_dbug.c
@@ -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;
diff --git a/storage/maria/ma_delete.c b/storage/maria/ma_delete.c
index 56da6fd3ed3..b7c036c3f30 100644
--- a/storage/maria/ma_delete.c
+++ b/storage/maria/ma_delete.c
@@ -176,8 +176,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)
@@ -187,11 +187,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))
@@ -209,13 +212,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,
@@ -228,7 +232,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,
@@ -238,7 +242,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)
{
@@ -338,14 +342,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))
@@ -375,7 +379,8 @@ static int d_search(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
(uchar*) 0,(uchar*) 0,(my_off_t) 0,(my_bool) 0);
}
}
- 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;
@@ -384,7 +389,7 @@ static int d_search(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
ret_value|= _ma_write_keypage(info,keyinfo,page,DFLT_INIT_HITS,anc_buff);
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));
@@ -407,7 +412,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;
@@ -415,14 +420,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+
@@ -432,18 +439,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
@@ -464,20 +475,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,
@@ -491,11 +501,12 @@ static int del(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
if (!(*keyinfo->get_key)(keyinfo,share->base.key_reflength,&keypos,ret_key))
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 */
@@ -521,22 +532,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"));
@@ -557,14 +568,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 */
@@ -579,7 +591,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 */
@@ -588,9 +600,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))
@@ -601,21 +613,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),
@@ -626,21 +639,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;
@@ -659,12 +674,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))
@@ -688,7 +704,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,
@@ -696,22 +712,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);
@@ -730,11 +746,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);
@@ -745,14 +763,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);
diff --git a/storage/maria/ma_ft_update.c b/storage/maria/ma_ft_update.c
index f36147ccde2..ce173993b6d 100644
--- a/storage/maria/ma_ft_update.c
+++ b/storage/maria/ma_ft_update.c
@@ -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);
diff --git a/storage/maria/ma_loghandler.h b/storage/maria/ma_loghandler.h
index b13984d88ef..7e8c87caaa4 100644
--- a/storage/maria/ma_loghandler.h
+++ b/storage/maria/ma_loghandler.h
@@ -46,7 +46,7 @@
/* short transaction ID type */
typedef uint16 SHORT_TRANSACTION_ID;
-struct st_maria_info;
+struct st_maria_handler;
/* Length of CRC at end of pages */
#define CRC_LENGTH 4
@@ -228,7 +228,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);
@@ -263,7 +263,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
@@ -298,11 +298,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,
struct st_translog_parts *parts);
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,
struct st_translog_parts *parts);
diff --git a/storage/maria/ma_open.c b/storage/maria/ma_open.c
index 6852d5b4a6d..4a15d6e338a 100644
--- a/storage/maria/ma_open.c
+++ b/storage/maria/ma_open.c
@@ -81,8 +81,8 @@ MARIA_HA *_ma_test_if_reopen(const char *filename)
share Share of already open table
mode Mode of table (O_RDONLY | O_RDWR)
data_file Filedescriptor of data file to use < 0 if one should open
- open it.
-
+ open it.
+
RETURN
# Maria handler
0 Error
@@ -252,7 +252,8 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags)
char *disk_cache, *disk_pos, *end_pos;
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(name_buff, strlen(name_buff),
maria_pagecache);
@@ -314,10 +316,11 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags)
HA_OPTION_COMPRESS_RECORD | HA_OPTION_READ_ONLY_DATA |
HA_OPTION_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) &&
@@ -441,7 +444,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,
@@ -449,6 +455,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,
@@ -465,7 +472,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);
@@ -595,6 +604,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)
{
/*
@@ -666,6 +679,8 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags)
}
}
share->columndef[i].type=(int) FIELD_LAST; /* End marker */
+ 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))
@@ -693,7 +708,7 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags)
if ((*share->once_init)(share, info.dfile.file))
goto err;
share->is_log_table= FALSE;
- if (open_flags & HA_OPEN_TMP_TABLE)
+ if (open_flags & HA_OPEN_TMP_TABLE)
share->options|= HA_OPTION_TMP_TABLE;
if (open_flags & HA_OPEN_DELAY_KEY_WRITE)
share->options|= HA_OPTION_DELAY_KEY_WRITE;
@@ -771,7 +786,7 @@ err:
VOID(my_close(data_file, MYF(0)));
if (old_info)
break; /* Don't remove open table */
- (*share->once_end)(share);
+ (*share->once_end)(share);
/* fall through */
case 4:
my_free((uchar*) share,MYF(0));
@@ -914,7 +929,7 @@ void _ma_setup_functions(register MARIA_SHARE *share)
share->file_read= _ma_nommap_pread;
share->file_write= _ma_nommap_pwrite;
share->calc_check_checksum= share->calc_checksum;
-
+
if (!(share->options & HA_OPTION_CHECKSUM) &&
share->data_file_type != COMPRESSED_RECORD)
share->calc_checksum= share->calc_write_checksum= 0;
@@ -1095,10 +1110,13 @@ uint _ma_state_info_write_sub(File file, MARIA_STATE_INFO *state, uint pWrite)
mi_int8store(ptr,(ulonglong) state->create_time); ptr+= 8;
mi_int8store(ptr,(ulonglong) state->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;
}
}
@@ -1135,7 +1153,9 @@ static uchar *_ma_state_info_read(uchar *ptr, MARIA_STATE_INFO *state)
state->state.key_empty= mi_sizekorr(ptr); ptr+= 8;
state->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;
@@ -1154,10 +1174,12 @@ static uchar *_ma_state_info_read(uchar *ptr, MARIA_STATE_INFO *state)
state->create_time = (time_t) mi_sizekorr(ptr); ptr+= 8;
state->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;
}
@@ -1199,6 +1221,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;
@@ -1215,7 +1239,7 @@ uint _ma_base_info_write(File file, MARIA_BASE_INFO *base)
mi_int2store(ptr,base->fixed_not_null_fields_length); ptr+= 2;
mi_int2store(ptr,base->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;
@@ -1241,6 +1265,7 @@ uint _ma_base_info_write(File file, MARIA_BASE_INFO *base)
static uchar *_ma_base_info_read(uchar *ptr, MARIA_BASE_INFO *base)
{
+ 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;
@@ -1257,7 +1282,7 @@ static uchar *_ma_base_info_read(uchar *ptr, MARIA_BASE_INFO *base)
base->fixed_not_null_fields_length= mi_uint2korr(ptr);ptr+= 2;
base->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;
@@ -1284,7 +1309,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;
@@ -1320,7 +1345,7 @@ char *_ma_keydef_read(char *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;
@@ -1370,7 +1395,7 @@ char *_ma_keyseg_read(char *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;
@@ -1394,12 +1419,12 @@ char *_ma_uniquedef_read(char *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;
@@ -1407,12 +1432,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;
}
char *_ma_columndef_read(char *ptr, MARIA_COLUMNDEF *columndef)
{
- columndef->offset= mi_uint6korr(ptr); ptr+= 6;
+ columndef->offset= mi_uint2korr(ptr); ptr+= 2;
columndef->type= mi_sint2korr(ptr); ptr+= 2;
columndef->length= mi_uint2korr(ptr); ptr+= 2;
columndef->fill_length= mi_uint2korr(ptr); ptr+= 2;
@@ -1420,9 +1446,36 @@ char *_ma_columndef_read(char *ptr, MARIA_COLUMNDEF *columndef)
columndef->empty_pos= mi_uint2korr(ptr); ptr+= 2;
columndef->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
diff --git a/storage/maria/ma_page.c b/storage/maria/ma_page.c
index f749414474f..484d9230725 100644
--- a/storage/maria/ma_page.c
+++ b/storage/maria/ma_page.c
@@ -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;
- char buff[8];
+ char 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= 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);
}
info->s->state.changed|= STATE_NOT_SORTED_PAGES;
DBUG_PRINT("exit",("Pos: %ld",(long) pos));
diff --git a/storage/maria/ma_preload.c b/storage/maria/ma_preload.c
index 138bb94f7d0..b3a0b97a58f 100644
--- a/storage/maria/ma_preload.c
+++ b/storage/maria/ma_preload.c
@@ -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);
diff --git a/storage/maria/ma_range.c b/storage/maria/ma_range.c
index 02616d8ac5c..8ef6dc87c0c 100644
--- a/storage/maria/ma_range.c
+++ b/storage/maria/ma_range.c
@@ -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)))
{
diff --git a/storage/maria/ma_rt_index.c b/storage/maria/ma_rt_index.c
index 4980233fc11..2530ae86a5c 100644
--- a/storage/maria/ma_rt_index.c
+++ b/storage/maria/ma_rt_index.c
@@ -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);
diff --git a/storage/maria/ma_rt_index.h b/storage/maria/ma_rt_index.h
index fe2f62b662c..af2fcabaa44 100644
--- a/storage/maria/ma_rt_index.h
+++ b/storage/maria/ma_rt_index.h
@@ -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);
diff --git a/storage/maria/ma_rt_key.c b/storage/maria/ma_rt_key.c
index b74d5d06690..c71d7d7d8eb 100644
--- a/storage/maria/ma_rt_key.c
+++ b/storage/maria/ma_rt_key.c
@@ -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;
}
diff --git a/storage/maria/ma_rt_mbr.c b/storage/maria/ma_rt_mbr.c
index a224cefac12..4f17ce6d074 100644
--- a/storage/maria/ma_rt_mbr.c
+++ b/storage/maria/ma_rt_mbr.c
@@ -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:
diff --git a/storage/maria/ma_rt_split.c b/storage/maria/ma_rt_split.c
index a91eaa47bea..d3381ecf1ad 100644
--- a/storage/maria/ma_rt_split.c
+++ b/storage/maria/ma_rt_split.c
@@ -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)
diff --git a/storage/maria/ma_rt_test.c b/storage/maria/ma_rt_test.c
index 4360e81c550..e41ebdce500 100644
--- a/storage/maria/ma_rt_test.c
+++ b/storage/maria/ma_rt_test.c
@@ -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;
diff --git a/storage/maria/ma_search.c b/storage/maria/ma_search.c
index 8cb3e56e646..a41346f2460 100644
--- a/storage/maria/ma_search.c
+++ b/storage/maria/ma_search.c
@@ -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;
diff --git a/storage/maria/ma_sort.c b/storage/maria/ma_sort.c
index 2851a3a09dd..68564b44312 100644
--- a/storage/maria/ma_sort.c
+++ b/storage/maria/ma_sort.c
@@ -93,7 +93,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
@@ -101,10 +101,11 @@ my_var_write(MARIA_SORT_PARAM *info, IO_CACHE *to_file, uchar *bufs);
*/
int _ma_create_index_by_sort(MARIA_SORT_PARAM *info, my_bool no_messages,
- 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;
@@ -314,8 +315,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);
@@ -356,19 +358,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");
@@ -404,8 +405,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;
@@ -493,7 +494,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;
diff --git a/storage/maria/ma_static.c b/storage/maria/ma_static.c
index 41b202491a7..fe1335c39fe 100644
--- a/storage/maria/ma_static.c
+++ b/storage/maria/ma_static.c
@@ -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
diff --git a/storage/maria/ma_test2.c b/storage/maria/ma_test2.c
index 935be09850c..72d2c8e9777 100644
--- a/storage/maria/ma_test2.c
+++ b/storage/maria/ma_test2.c
@@ -42,8 +42,7 @@ static uint rnd(uint max_value);
static void fix_length(uchar *record,uint length);
static void put_blob_in_record(char *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))
{
@@ -872,7 +873,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.
diff --git a/storage/maria/ma_test_recovery b/storage/maria/ma_test_recovery
index 7c45af1e206..728994a5086 100755
--- a/storage/maria/ma_test_recovery
+++ b/storage/maria/ma_test_recovery
@@ -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
diff --git a/storage/maria/ma_test_recovery.expected b/storage/maria/ma_test_recovery.expected
index 926943b11b3..e776ea9d73c 100644
--- a/storage/maria/ma_test_recovery.expected
+++ b/storage/maria/ma_test_recovery.expected
@@ -39,36 +39,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)
@@ -218,7 +218,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
@@ -231,7 +231,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
@@ -244,7 +244,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)
@@ -393,7 +393,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
@@ -406,7 +406,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
@@ -419,7 +419,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)
@@ -568,7 +568,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
@@ -581,7 +581,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
@@ -594,7 +594,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)
@@ -743,7 +743,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
@@ -756,7 +756,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
@@ -769,7 +769,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)
@@ -918,7 +918,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
@@ -931,7 +931,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
@@ -944,7 +944,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)
@@ -1093,7 +1093,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
@@ -1106,7 +1106,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
@@ -1119,5 +1119,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=======
diff --git a/storage/maria/ma_write.c b/storage/maria/ma_write.c
index b034d71ef9d..4a0854dd785 100644
--- a/storage/maria/ma_write.c
+++ b/storage/maria/ma_write.c
@@ -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 */
@@ -280,6 +280,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 */
@@ -297,10 +298,7 @@ int _ma_ck_write(MARIA_HA *info, uint keynr, uchar *key, uint key_length)
{
DBUG_RETURN(_ma_ck_write_tree(info, keynr, key, key_length));
}
- 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 */
@@ -369,12 +367,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);
@@ -382,12 +386,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,
@@ -412,7 +418,7 @@ static int w_search(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
flag=(*keyinfo->bin_search)(info,keyinfo,temp_buff,key,search_key_length,
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;
@@ -445,7 +451,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);
@@ -528,17 +535,17 @@ int _ma_insert(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
DBUG_EXECUTE("key", _ma_print_key(DBUG_FILE,keyinfo->seg,key,
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));
}
@@ -572,11 +579,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))
{
@@ -585,7 +592,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);
@@ -600,25 +607,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, (char*) 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 */
}
@@ -648,31 +658,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 */
@@ -691,8 +703,14 @@ int _ma_split_page(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
memcpy((uchar*) info->buff+key_ref_length+t_length,(uchar*) key_pos,
(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));
@@ -700,25 +718,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
+
+ Returns pointer to start of key.
+ key will contain the key.
+ return_key_length will contain the length of key
+ after_key will contain the position to where the next key starts
+*/
-uchar *_ma_find_half_pos(uint nod_flag, MARIA_KEYDEF *keyinfo, uchar *page,
- uchar *key, uint *return_key_length,
+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)))
@@ -754,7 +773,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)
{
@@ -763,8 +783,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 |
@@ -821,15 +841,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,
@@ -849,42 +870,46 @@ static int _ma_balance_page(register MARIA_HA *info, MARIA_KEYDEF *keyinfo,
if (!_ma_fetch_keypage(info,keyinfo,next_page,DFLT_INIT_HITS,info->buff,0))
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) ||
@@ -896,7 +921,13 @@ static int _ma_balance_page(register MARIA_HA *info, MARIA_KEYDEF *keyinfo,
/* curr_buff[] and buff[] are full, lets split and make new nod */
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-
@@ -905,28 +936,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;
@@ -973,7 +1013,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);
}
diff --git a/storage/maria/maria_chk.c b/storage/maria/maria_chk.c
index e6ac0dcfc50..dc483ff547f 100644
--- a/storage/maria/maria_chk.c
+++ b/storage/maria/maria_chk.c
@@ -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__);
diff --git a/storage/maria/maria_def.h b/storage/maria/maria_def.h
index bac83db4f51..42cf3f48cf5 100644
--- a/storage/maria/maria_def.h
+++ b/storage/maria/maria_def.h
@@ -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 */
uint (*file_read)(MARIA_HA *, uchar *, uint, 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);
char *_ma_keyseg_read(char *ptr, HA_KEYSEG *keyseg);
-uint _ma_keydef_write(File file, MARIA_KEYDEF *keydef);
+my_bool _ma_keydef_write(File file, MARIA_KEYDEF *keydef);
char *_ma_keydef_read(char *ptr, MARIA_KEYDEF *keydef);
-uint _ma_uniquedef_write(File file, MARIA_UNIQUEDEF *keydef);
+my_bool _ma_uniquedef_write(File file, MARIA_UNIQUEDEF *keydef);
char *_ma_uniquedef_read(char *ptr, MARIA_UNIQUEDEF *keydef);
-uint _ma_columndef_write(File file, MARIA_COLUMNDEF *columndef);
+my_bool _ma_columndef_write(File file, MARIA_COLUMNDEF *columndef);
char *_ma_columndef_read(char *ptr, MARIA_COLUMNDEF *columndef);
+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);
@@ -940,7 +976,7 @@ int _ma_flush_table_files_after_repair(HA_CHECK *param, MARIA_HA *info);
int _ma_sort_write_record(MARIA_SORT_PARAM *sort_param);
int _ma_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,
diff --git a/storage/maria/maria_pack.c b/storage/maria/maria_pack.c
index 83f88fcb0dc..79c85b8be29 100644
--- a/storage/maria/maria_pack.c
+++ b/storage/maria/maria_pack.c
@@ -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)
diff --git a/storage/myisam/mi_dbug.c b/storage/myisam/mi_dbug.c
index 0808a7e85dd..659abdce131 100644
--- a/storage/myisam/mi_dbug.c
+++ b/storage/myisam/mi_dbug.c
@@ -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;