mirror of
https://github.com/MariaDB/server.git
synced 2025-08-08 11:22:35 +03:00
Fixes after review of guilhem of block record patch
Short overview: Changed a lot of variable, functions, defines and struct elements to use more readable names More comments (mostly function and structure slot comments) Other things: Changed 'USE_WHOLE_KEY' to a big number to not interfer with long keys Ensure that tail block are at least of size 'MIN_TAIL_SIZE' Allow longer keys and key parts than before (don't limit Maria interface by HA_MAX_KEY_LENGTH) Use ma_chsize() to write initial bitmap page Added checking if using file with wrong block_size Added issing types to type_names[] (for maria_chk -d) Added maria_max_key_length() include/maria.h: Changed maria_portable_size_char_ptr to portable_size_char_ptr and moved it to my_handler.h Removed not used variable maria_delay_rec_write. More comments include/my_handler.h: Added portable_sizeof_char_ptr include/myisam.h: Changed mi_portable_size_char_ptr to portable_size_char_ptr and moved it to my_handler.h mysql-test/r/maria.result: Fix results when we now have a longer key length mysql-test/t/maria.test: More tests mysys/my_pread.c: Code cleanup sql/net_serv.cc: Changed warning to note (as in main 5.1 tree) to avoid not critical failing tests sql/sql_select.cc: Use portable_sizeof_char_ptr storage/maria/ha_maria.cc: Added max_supported_key_length(), as this is not a trival function anymore storage/maria/ha_maria.h: Moved max_supported_key_length(), as this is not a trival function anymore storage/maria/ma_bitmap.c: Lots of new comments Added maria_bitmap_marker[] to mark 2 last bytes of each bitmap (for corruption detection) Trivial code changes (based on review comments) storage/maria/ma_blockrec.c: More code comments Renamed _block_row() functions to _block_record() Trivial code changes, based on review comments Moved Code from maria_close() to _ma_end_block_record() Some function renames to make things more understandable DIR_ENTRY_OFFSET -> DIR_COUNT_OFFSET keybuff_used -> keyread_buff_used ma_recordpos_to_offset -> ma_recordpos_to_dir_entry Changed some 'rec' named variables to 'column'. Ensure that tail block are at least of size 'MIN_TAIL_SIZE' storage/maria/ma_blockrec.h: More comments DIRCOUNT_SIZE -> DIR_COUNT_SIZE Added define for maira_bitmap_marker[] ma_recordpos_to_offset -> ma_recordpos_to_dir_entry xxx_block_row() -> xxx_block_record() Made _ma_read_bitmap_page() static storage/maria/ma_check.c: More comments ma_recordpos_to_offset() -> ma_recordpos_to_dir_entry() DIR_ENTRY_OFFSET -> DIR_COUNT_OFFSET rec variables -> column variables recdef -> columndef storage/maria/ma_checksum.c: rec -> column Avoid an 'if' in _ma_checksum() for the common case storage/maria/ma_close.c: Moved resetting of info->dfile to ma_end_once_block_record() storage/maria/ma_create.c: Some variable changes to make things more readable: recinfo -> columndef rec -> column rec_end -> end_column record_type -> datafile_type ma_recinfo_write() -> ma_columndef_write() Fixed wrong setting of 'data_file_length'; Now max_rows should be calculated correctly New check if too long key. Use ma_chsize() to write bitmap page. storage/maria/ma_delete.c: keybuff_used -> keyread_buff_used storage/maria/ma_dynrec.c: rec -> columndef rec_length -> column_length maria_portable_sizeof_char_ptr -> portable_sizeof_char_ptr Better comment for _ma_read_rnd_dynamic_record() storage/maria/ma_ft_eval.c: maria_portable_sizeof_char_ptr -> portable_sizeof_char_ptr storage/maria/ma_ft_test1.c: maria_portable_sizeof_char_ptr -> portable_sizeof_char_ptr storage/maria/ma_ft_update.c: keybuff_used -> keyread_buff_used storage/maria/ma_info.c: More comments storage/maria/ma_open.c: Added checking if using file with wrong block_size New checking of max_key_length rec -> columndef _ma_recinfo_write -> _ma_columndef_write Don't change block_size (as this is checked in ma_create()) More comments storage/maria/ma_packrec.c: Trivial code changes rec -> columndef maria_portable_sizeof_char_ptr -> portable_sizeof_char_ptr storage/maria/ma_page.c: keybuff_used -> keyread_buff_used storage/maria/ma_rkey.c: Removed not needded empty line storage/maria/ma_rrnd.c: Removed not used variable storage/maria/ma_rt_index.c: keybuff_used -> keyread_buff_used storage/maria/ma_search.c: keybuff_used -> keyread_buff_used Trivial code changes storage/maria/ma_sp_test.c: maria_portable_sizeof_char_ptr -> portable_sizeof_char_ptr storage/maria/ma_test1.c: maria_portable_sizeof_char_ptr -> portable_sizeof_char_ptr storage/maria/ma_test2.c: maria_portable_sizeof_char_ptr -> portable_sizeof_char_ptr storage/maria/ma_update.c: Updated comment storage/maria/ma_write.c: keybuff_used -> keyread_buff_used storage/maria/maria_chk.c: Added missing types to type_names[] Removed not used variable rec -> columndef Replaced some numbers with define flags storage/maria/maria_def.h: More comments Added 'MARIA_INDEX_MIN_OVERHEAD_SIZE' rec -> columndef keybuff_used -> keyread_buff_used _ma_recinfo_write -> _ma_culumndef_write _ma_recinfo_read -> _ma_columndef_read Changed 'USE_WHOLE_KEY' to a big number to not interfer with long keys Added maria_max_key_length() storage/maria/maria_pack.c: Updated message strings rec -> columndef maria_portable_sizeof_char_ptr -> portable_sizeof_char_ptr More comments storage/myisam/ft_eval.c: mi_portable_sizeof_char_ptr -> portable_sizeof_char_ptr storage/myisam/ft_test1.c: mi_portable_sizeof_char_ptr -> portable_sizeof_char_ptr storage/myisam/mi_checksum.c: mi_portable_sizeof_char_ptr -> portable_sizeof_char_ptr storage/myisam/mi_create.c: mi_portable_sizeof_char_ptr -> portable_sizeof_char_ptr storage/myisam/mi_dynrec.c: mi_portable_sizeof_char_ptr -> portable_sizeof_char_ptr storage/myisam/mi_open.c: mi_portable_sizeof_char_ptr -> portable_sizeof_char_ptr storage/myisam/mi_packrec.c: mi_portable_sizeof_char_ptr -> portable_sizeof_char_ptr storage/myisam/mi_rkey.c: Unlock mutex also in case of error storage/myisam/mi_test1.c: mi_portable_sizeof_char_ptr -> portable_sizeof_char_ptr storage/myisam/mi_test2.c: mi_portable_sizeof_char_ptr -> portable_sizeof_char_ptr storage/myisam/myisampack.c: mi_portable_sizeof_char_ptr -> portable_sizeof_char_ptr storage/myisam/sp_test.c: mi_portable_sizeof_char_ptr -> portable_sizeof_char_ptr support-files/magic: Fixed typo
This commit is contained in:
@@ -54,8 +54,6 @@ extern "C" {
|
|||||||
#define MARIA_KEY_BLOCK_LENGTH 8192 /* default key block length */
|
#define MARIA_KEY_BLOCK_LENGTH 8192 /* default key block length */
|
||||||
#define MARIA_MIN_KEY_BLOCK_LENGTH 1024 /* Min key block length */
|
#define MARIA_MIN_KEY_BLOCK_LENGTH 1024 /* Min key block length */
|
||||||
#define MARIA_MAX_KEY_BLOCK_LENGTH 32768
|
#define MARIA_MAX_KEY_BLOCK_LENGTH 32768
|
||||||
#define maria_portable_sizeof_char_ptr 8
|
|
||||||
#define MARIA_MAX_KEY_LENGTH 1000 /* Max length in bytes */
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
In the following macros '_keyno_' is 0 .. keys-1.
|
In the following macros '_keyno_' is 0 .. keys-1.
|
||||||
@@ -150,6 +148,7 @@ typedef struct st_maria_create_info
|
|||||||
ulonglong auto_increment;
|
ulonglong auto_increment;
|
||||||
ulonglong data_file_length;
|
ulonglong data_file_length;
|
||||||
ulonglong key_file_length;
|
ulonglong key_file_length;
|
||||||
|
/* Size of null bitmap at start of row */
|
||||||
uint null_bytes;
|
uint null_bytes;
|
||||||
uint old_options;
|
uint old_options;
|
||||||
enum data_file_type org_data_file_type;
|
enum data_file_type org_data_file_type;
|
||||||
@@ -226,11 +225,13 @@ typedef struct st_maria_columndef /* column information */
|
|||||||
uint64 offset; /* Offset to position in row */
|
uint64 offset; /* Offset to position in row */
|
||||||
enum en_fieldtype type;
|
enum en_fieldtype type;
|
||||||
uint16 length; /* length of field */
|
uint16 length; /* length of field */
|
||||||
|
/* Intern variable (size of total storage area for the row) */
|
||||||
uint16 fill_length;
|
uint16 fill_length;
|
||||||
uint16 null_pos; /* Position for null marker */
|
uint16 null_pos; /* Position for null marker */
|
||||||
uint16 empty_pos; /* Position for empty marker */
|
uint16 empty_pos; /* Position for empty marker */
|
||||||
uint8 null_bit; /* If column may be NULL */
|
uint8 null_bit; /* If column may be NULL */
|
||||||
uint8 empty_bit; /* If column may be empty */
|
/* Intern. Set if column should be zero packed (part of empty_bits) */
|
||||||
|
uint8 empty_bit;
|
||||||
|
|
||||||
#ifndef NOT_PACKED_DATABASES
|
#ifndef NOT_PACKED_DATABASES
|
||||||
void(*unpack)(struct st_maria_columndef *rec,
|
void(*unpack)(struct st_maria_columndef *rec,
|
||||||
@@ -246,7 +247,7 @@ typedef struct st_maria_columndef /* column information */
|
|||||||
extern ulong maria_block_size;
|
extern ulong maria_block_size;
|
||||||
extern ulong maria_concurrent_insert;
|
extern ulong maria_concurrent_insert;
|
||||||
extern my_bool maria_flush, maria_single_user;
|
extern my_bool maria_flush, maria_single_user;
|
||||||
extern my_bool maria_delay_key_write, maria_delay_rec_write;
|
extern my_bool maria_delay_key_write;
|
||||||
extern my_off_t maria_max_temp_length;
|
extern my_off_t maria_max_temp_length;
|
||||||
extern ulong maria_bulk_insert_tree_size, maria_data_pointer_size;
|
extern ulong maria_bulk_insert_tree_size, maria_data_pointer_size;
|
||||||
extern KEY_CACHE maria_key_cache_var, *maria_key_cache;
|
extern KEY_CACHE maria_key_cache_var, *maria_key_cache;
|
||||||
|
@@ -111,4 +111,11 @@ extern int ha_key_cmp(register HA_KEYSEG *keyseg, register uchar *a,
|
|||||||
|
|
||||||
extern HA_KEYSEG *ha_find_null(HA_KEYSEG *keyseg, uchar *a);
|
extern HA_KEYSEG *ha_find_null(HA_KEYSEG *keyseg, uchar *a);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Inside an in-memory data record, memory pointers to pieces of the
|
||||||
|
record (like BLOBs) are stored in their native byte order and in
|
||||||
|
this amount of bytes.
|
||||||
|
*/
|
||||||
|
#define portable_sizeof_char_ptr 8
|
||||||
|
|
||||||
#endif /* _my_handler_h */
|
#endif /* _my_handler_h */
|
||||||
|
@@ -55,8 +55,6 @@ extern "C" {
|
|||||||
#define MI_MIN_KEY_BLOCK_LENGTH 1024 /* Min key block length */
|
#define MI_MIN_KEY_BLOCK_LENGTH 1024 /* Min key block length */
|
||||||
#define MI_MAX_KEY_BLOCK_LENGTH 16384
|
#define MI_MAX_KEY_BLOCK_LENGTH 16384
|
||||||
|
|
||||||
#define mi_portable_sizeof_char_ptr 8
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
In the following macros '_keyno_' is 0 .. keys-1.
|
In the following macros '_keyno_' is 0 .. keys-1.
|
||||||
If there can be more keys than bits in the key_map, the highest bit
|
If there can be more keys than bits in the key_map, the highest bit
|
||||||
|
@@ -325,10 +325,14 @@ Table Op Msg_type Msg_text
|
|||||||
test.t1 check status OK
|
test.t1 check status OK
|
||||||
drop table t1;
|
drop table t1;
|
||||||
CREATE TABLE t1 (a varchar(255), b varchar(255), c varchar(255), d varchar(255), e varchar(255), KEY t1 (a, b, c, d, e));
|
CREATE TABLE t1 (a varchar(255), b varchar(255), c varchar(255), d varchar(255), e varchar(255), KEY t1 (a, b, c, d, e));
|
||||||
ERROR 42000: Specified key was too long; max key length is 1000 bytes
|
ERROR 42000: Specified key was too long; max key length is 1112 bytes
|
||||||
|
CREATE TABLE t1 (a varchar(32000), unique key(a));
|
||||||
|
ERROR 42000: Specified key was too long; max key length is 1112 bytes
|
||||||
|
CREATE TABLE t1 (a varchar(1), b varchar(1), key (a,b,a,b,a,b,a,b,a,b,a,b,a,b,a,b,a,b,a,b,a,b,a,b,a,b,a,b,a,b,a,b,a,b,a,b));
|
||||||
|
ERROR 42000: Too many key parts specified; max 16 parts allowed
|
||||||
CREATE TABLE t1 (a varchar(255), b varchar(255), c varchar(255), d varchar(255), e varchar(255));
|
CREATE TABLE t1 (a varchar(255), b varchar(255), c varchar(255), d varchar(255), e varchar(255));
|
||||||
ALTER TABLE t1 ADD INDEX t1 (a, b, c, d, e);
|
ALTER TABLE t1 ADD INDEX t1 (a, b, c, d, e);
|
||||||
ERROR 42000: Specified key was too long; max key length is 1000 bytes
|
ERROR 42000: Specified key was too long; max key length is 1112 bytes
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
CREATE TABLE t1 (a int not null, b int, c int, key(b), key(c), key(a,b), key(c,a));
|
CREATE TABLE t1 (a int not null, b int, c int, key(b), key(c), key(a,b), key(c,a));
|
||||||
INSERT into t1 values (0, null, 0), (0, null, 1), (0, null, 2), (0, null,3), (1,1,4);
|
INSERT into t1 values (0, null, 0), (0, null, 1), (0, null, 2), (0, null,3), (1,1,4);
|
||||||
@@ -1476,7 +1480,7 @@ a b
|
|||||||
drop table t1;
|
drop table t1;
|
||||||
create table t1 (v varchar(65530), key(v));
|
create table t1 (v varchar(65530), key(v));
|
||||||
Warnings:
|
Warnings:
|
||||||
Warning 1071 Specified key was too long; max key length is 1000 bytes
|
Warning 1071 Specified key was too long; max key length is 1112 bytes
|
||||||
drop table if exists t1;
|
drop table if exists t1;
|
||||||
create table t1 (v varchar(65536));
|
create table t1 (v varchar(65536));
|
||||||
Warnings:
|
Warnings:
|
||||||
@@ -1607,34 +1611,34 @@ t1 CREATE TABLE `t1` (
|
|||||||
drop table t1;
|
drop table t1;
|
||||||
create table t1 (a varchar(2048), key `a` (a));
|
create table t1 (a varchar(2048), key `a` (a));
|
||||||
Warnings:
|
Warnings:
|
||||||
Warning 1071 Specified key was too long; max key length is 1000 bytes
|
Warning 1071 Specified key was too long; max key length is 1112 bytes
|
||||||
show create table t1;
|
show create table t1;
|
||||||
Table Create Table
|
Table Create Table
|
||||||
t1 CREATE TABLE `t1` (
|
t1 CREATE TABLE `t1` (
|
||||||
`a` varchar(2048) DEFAULT NULL,
|
`a` varchar(2048) DEFAULT NULL,
|
||||||
KEY `a` (`a`(1000))
|
KEY `a` (`a`(1112))
|
||||||
) ENGINE=MARIA DEFAULT CHARSET=latin1
|
) ENGINE=MARIA DEFAULT CHARSET=latin1
|
||||||
drop table t1;
|
drop table t1;
|
||||||
create table t1 (a varchar(2048), key `a` (a) key_block_size=1024);
|
create table t1 (a varchar(2048), key `a` (a) key_block_size=1024);
|
||||||
Warnings:
|
Warnings:
|
||||||
Warning 1071 Specified key was too long; max key length is 1000 bytes
|
Warning 1071 Specified key was too long; max key length is 1112 bytes
|
||||||
show create table t1;
|
show create table t1;
|
||||||
Table Create Table
|
Table Create Table
|
||||||
t1 CREATE TABLE `t1` (
|
t1 CREATE TABLE `t1` (
|
||||||
`a` varchar(2048) DEFAULT NULL,
|
`a` varchar(2048) DEFAULT NULL,
|
||||||
KEY `a` (`a`(1000)) KEY_BLOCK_SIZE=8192
|
KEY `a` (`a`(1112)) KEY_BLOCK_SIZE=8192
|
||||||
) ENGINE=MARIA DEFAULT CHARSET=latin1
|
) ENGINE=MARIA DEFAULT CHARSET=latin1
|
||||||
drop table t1;
|
drop table t1;
|
||||||
create table t1 (a int not null, b varchar(2048), key (a), key(b)) key_block_size=1024;
|
create table t1 (a int not null, b varchar(2048), key (a), key(b)) key_block_size=1024;
|
||||||
Warnings:
|
Warnings:
|
||||||
Warning 1071 Specified key was too long; max key length is 1000 bytes
|
Warning 1071 Specified key was too long; max key length is 1112 bytes
|
||||||
show create table t1;
|
show create table t1;
|
||||||
Table Create Table
|
Table Create Table
|
||||||
t1 CREATE TABLE `t1` (
|
t1 CREATE TABLE `t1` (
|
||||||
`a` int(11) NOT NULL,
|
`a` int(11) NOT NULL,
|
||||||
`b` varchar(2048) DEFAULT NULL,
|
`b` varchar(2048) DEFAULT NULL,
|
||||||
KEY `a` (`a`) KEY_BLOCK_SIZE=8192,
|
KEY `a` (`a`) KEY_BLOCK_SIZE=8192,
|
||||||
KEY `b` (`b`(1000)) KEY_BLOCK_SIZE=8192
|
KEY `b` (`b`(1112)) KEY_BLOCK_SIZE=8192
|
||||||
) ENGINE=MARIA DEFAULT CHARSET=latin1 KEY_BLOCK_SIZE=1024
|
) ENGINE=MARIA DEFAULT CHARSET=latin1 KEY_BLOCK_SIZE=1024
|
||||||
alter table t1 key_block_size=2048;
|
alter table t1 key_block_size=2048;
|
||||||
show create table t1;
|
show create table t1;
|
||||||
@@ -1643,7 +1647,7 @@ t1 CREATE TABLE `t1` (
|
|||||||
`a` int(11) NOT NULL,
|
`a` int(11) NOT NULL,
|
||||||
`b` varchar(2048) DEFAULT NULL,
|
`b` varchar(2048) DEFAULT NULL,
|
||||||
KEY `a` (`a`) KEY_BLOCK_SIZE=8192,
|
KEY `a` (`a`) KEY_BLOCK_SIZE=8192,
|
||||||
KEY `b` (`b`(1000)) KEY_BLOCK_SIZE=8192
|
KEY `b` (`b`(1112)) KEY_BLOCK_SIZE=8192
|
||||||
) ENGINE=MARIA DEFAULT CHARSET=latin1 KEY_BLOCK_SIZE=2048
|
) ENGINE=MARIA DEFAULT CHARSET=latin1 KEY_BLOCK_SIZE=2048
|
||||||
alter table t1 add c int, add key (c);
|
alter table t1 add c int, add key (c);
|
||||||
show create table t1;
|
show create table t1;
|
||||||
@@ -1653,7 +1657,7 @@ t1 CREATE TABLE `t1` (
|
|||||||
`b` varchar(2048) DEFAULT NULL,
|
`b` varchar(2048) DEFAULT NULL,
|
||||||
`c` int(11) DEFAULT NULL,
|
`c` int(11) DEFAULT NULL,
|
||||||
KEY `a` (`a`) KEY_BLOCK_SIZE=8192,
|
KEY `a` (`a`) KEY_BLOCK_SIZE=8192,
|
||||||
KEY `b` (`b`(1000)) KEY_BLOCK_SIZE=8192,
|
KEY `b` (`b`(1112)) KEY_BLOCK_SIZE=8192,
|
||||||
KEY `c` (`c`) KEY_BLOCK_SIZE=8192
|
KEY `c` (`c`) KEY_BLOCK_SIZE=8192
|
||||||
) ENGINE=MARIA DEFAULT CHARSET=latin1 KEY_BLOCK_SIZE=2048
|
) ENGINE=MARIA DEFAULT CHARSET=latin1 KEY_BLOCK_SIZE=2048
|
||||||
alter table t1 key_block_size=0;
|
alter table t1 key_block_size=0;
|
||||||
@@ -1666,33 +1670,33 @@ t1 CREATE TABLE `t1` (
|
|||||||
`c` int(11) DEFAULT NULL,
|
`c` int(11) DEFAULT NULL,
|
||||||
`d` int(11) DEFAULT NULL,
|
`d` int(11) DEFAULT NULL,
|
||||||
KEY `a` (`a`) KEY_BLOCK_SIZE=8192,
|
KEY `a` (`a`) KEY_BLOCK_SIZE=8192,
|
||||||
KEY `b` (`b`(1000)) KEY_BLOCK_SIZE=8192,
|
KEY `b` (`b`(1112)) KEY_BLOCK_SIZE=8192,
|
||||||
KEY `c` (`c`) KEY_BLOCK_SIZE=8192,
|
KEY `c` (`c`) KEY_BLOCK_SIZE=8192,
|
||||||
KEY `d` (`d`)
|
KEY `d` (`d`)
|
||||||
) ENGINE=MARIA DEFAULT CHARSET=latin1
|
) ENGINE=MARIA DEFAULT CHARSET=latin1
|
||||||
drop table t1;
|
drop table t1;
|
||||||
create table t1 (a int not null, b varchar(2048), key (a), key(b)) key_block_size=8192;
|
create table t1 (a int not null, b varchar(2048), key (a), key(b)) key_block_size=8192;
|
||||||
Warnings:
|
Warnings:
|
||||||
Warning 1071 Specified key was too long; max key length is 1000 bytes
|
Warning 1071 Specified key was too long; max key length is 1112 bytes
|
||||||
show create table t1;
|
show create table t1;
|
||||||
Table Create Table
|
Table Create Table
|
||||||
t1 CREATE TABLE `t1` (
|
t1 CREATE TABLE `t1` (
|
||||||
`a` int(11) NOT NULL,
|
`a` int(11) NOT NULL,
|
||||||
`b` varchar(2048) DEFAULT NULL,
|
`b` varchar(2048) DEFAULT NULL,
|
||||||
KEY `a` (`a`),
|
KEY `a` (`a`),
|
||||||
KEY `b` (`b`(1000))
|
KEY `b` (`b`(1112))
|
||||||
) ENGINE=MARIA DEFAULT CHARSET=latin1 KEY_BLOCK_SIZE=8192
|
) ENGINE=MARIA DEFAULT CHARSET=latin1 KEY_BLOCK_SIZE=8192
|
||||||
drop table t1;
|
drop table t1;
|
||||||
create table t1 (a int not null, b varchar(2048), key (a) key_block_size=1024, key(b)) key_block_size=8192;
|
create table t1 (a int not null, b varchar(2048), key (a) key_block_size=1024, key(b)) key_block_size=8192;
|
||||||
Warnings:
|
Warnings:
|
||||||
Warning 1071 Specified key was too long; max key length is 1000 bytes
|
Warning 1071 Specified key was too long; max key length is 1112 bytes
|
||||||
show create table t1;
|
show create table t1;
|
||||||
Table Create Table
|
Table Create Table
|
||||||
t1 CREATE TABLE `t1` (
|
t1 CREATE TABLE `t1` (
|
||||||
`a` int(11) NOT NULL,
|
`a` int(11) NOT NULL,
|
||||||
`b` varchar(2048) DEFAULT NULL,
|
`b` varchar(2048) DEFAULT NULL,
|
||||||
KEY `a` (`a`),
|
KEY `a` (`a`),
|
||||||
KEY `b` (`b`(1000))
|
KEY `b` (`b`(1112))
|
||||||
) ENGINE=MARIA DEFAULT CHARSET=latin1 KEY_BLOCK_SIZE=8192
|
) ENGINE=MARIA DEFAULT CHARSET=latin1 KEY_BLOCK_SIZE=8192
|
||||||
drop table t1;
|
drop table t1;
|
||||||
create table t1 (a int not null, b int, key (a) key_block_size=1024, key(b) key_block_size=8192) key_block_size=16384;
|
create table t1 (a int not null, b int, key (a) key_block_size=1024, key(b) key_block_size=8192) key_block_size=16384;
|
||||||
@@ -1715,12 +1719,12 @@ t1 CREATE TABLE `t1` (
|
|||||||
drop table t1;
|
drop table t1;
|
||||||
create table t1 (a varchar(2048), key `a` (a) key_block_size=1000000000000000000);
|
create table t1 (a varchar(2048), key `a` (a) key_block_size=1000000000000000000);
|
||||||
Warnings:
|
Warnings:
|
||||||
Warning 1071 Specified key was too long; max key length is 1000 bytes
|
Warning 1071 Specified key was too long; max key length is 1112 bytes
|
||||||
show create table t1;
|
show create table t1;
|
||||||
Table Create Table
|
Table Create Table
|
||||||
t1 CREATE TABLE `t1` (
|
t1 CREATE TABLE `t1` (
|
||||||
`a` varchar(2048) DEFAULT NULL,
|
`a` varchar(2048) DEFAULT NULL,
|
||||||
KEY `a` (`a`(1000)) KEY_BLOCK_SIZE=8192
|
KEY `a` (`a`(1112)) KEY_BLOCK_SIZE=8192
|
||||||
) ENGINE=MARIA DEFAULT CHARSET=latin1
|
) ENGINE=MARIA DEFAULT CHARSET=latin1
|
||||||
drop table t1;
|
drop table t1;
|
||||||
create table t1 (a int not null, key `a` (a) key_block_size=1025);
|
create table t1 (a int not null, key `a` (a) key_block_size=1025);
|
||||||
|
@@ -345,6 +345,10 @@ drop table t1;
|
|||||||
|
|
||||||
--error 1071
|
--error 1071
|
||||||
CREATE TABLE t1 (a varchar(255), b varchar(255), c varchar(255), d varchar(255), e varchar(255), KEY t1 (a, b, c, d, e));
|
CREATE TABLE t1 (a varchar(255), b varchar(255), c varchar(255), d varchar(255), e varchar(255), KEY t1 (a, b, c, d, e));
|
||||||
|
--error 1071
|
||||||
|
CREATE TABLE t1 (a varchar(32000), unique key(a));
|
||||||
|
--error 1070
|
||||||
|
CREATE TABLE t1 (a varchar(1), b varchar(1), key (a,b,a,b,a,b,a,b,a,b,a,b,a,b,a,b,a,b,a,b,a,b,a,b,a,b,a,b,a,b,a,b,a,b,a,b));
|
||||||
CREATE TABLE t1 (a varchar(255), b varchar(255), c varchar(255), d varchar(255), e varchar(255));
|
CREATE TABLE t1 (a varchar(255), b varchar(255), c varchar(255), d varchar(255), e varchar(255));
|
||||||
--error 1071
|
--error 1071
|
||||||
ALTER TABLE t1 ADD INDEX t1 (a, b, c, d, e);
|
ALTER TABLE t1 ADD INDEX t1 (a, b, c, d, e);
|
||||||
|
@@ -87,11 +87,9 @@ uint my_pread(File Filedes, byte *Buffer, uint Count, my_off_t offset,
|
|||||||
my_error(EE_READ, MYF(ME_BELL+ME_WAITTANG),
|
my_error(EE_READ, MYF(ME_BELL+ME_WAITTANG),
|
||||||
my_filename(Filedes),my_errno);
|
my_filename(Filedes),my_errno);
|
||||||
else if (MyFlags & (MY_NABP | MY_FNABP))
|
else if (MyFlags & (MY_NABP | MY_FNABP))
|
||||||
{
|
|
||||||
my_error(EE_EOFERR, MYF(ME_BELL+ME_WAITTANG),
|
my_error(EE_EOFERR, MYF(ME_BELL+ME_WAITTANG),
|
||||||
my_filename(Filedes),my_errno);
|
my_filename(Filedes),my_errno);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if ((int) readbytes == -1 || (MyFlags & (MY_FNABP | MY_NABP)))
|
if ((int) readbytes == -1 || (MyFlags & (MY_FNABP | MY_NABP)))
|
||||||
DBUG_RETURN(MY_FILE_ERROR); /* Return with error */
|
DBUG_RETURN(MY_FILE_ERROR); /* Return with error */
|
||||||
}
|
}
|
||||||
|
@@ -298,8 +298,8 @@ void net_clear(NET *net, my_bool clear_buffer)
|
|||||||
{
|
{
|
||||||
DBUG_PRINT("info",("skipped %d bytes from file: %s",
|
DBUG_PRINT("info",("skipped %d bytes from file: %s",
|
||||||
count, vio_description(net->vio)));
|
count, vio_description(net->vio)));
|
||||||
#if defined(EXTRA_DEBUG) && (MYSQL_VERSION_ID < 51000)
|
#if defined(EXTRA_DEBUG) && (MYSQL_VERSION_ID < 50100)
|
||||||
fprintf(stderr,"Error: net_clear() skipped %d bytes from file: %s\n",
|
fprintf(stderr,"Note: net_clear() skipped %d bytes from file: %s\n",
|
||||||
count, vio_description(net->vio));
|
count, vio_description(net->vio));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@@ -9301,7 +9301,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
|
|||||||
table->s= share;
|
table->s= share;
|
||||||
init_tmp_table_share(share, "", 0, tmpname, tmpname);
|
init_tmp_table_share(share, "", 0, tmpname, tmpname);
|
||||||
share->blob_field= blob_field;
|
share->blob_field= blob_field;
|
||||||
share->blob_ptr_size= mi_portable_sizeof_char_ptr;
|
share->blob_ptr_size= portable_sizeof_char_ptr;
|
||||||
share->db_low_byte_first=1; // True for HEAP and MyISAM
|
share->db_low_byte_first=1; // True for HEAP and MyISAM
|
||||||
share->table_charset= param->table_charset;
|
share->table_charset= param->table_charset;
|
||||||
share->primary_key= MAX_KEY; // Indicate no primary key
|
share->primary_key= MAX_KEY; // Indicate no primary key
|
||||||
@@ -9856,7 +9856,7 @@ TABLE *create_virtual_tmp_table(THD *thd, List<create_field> &field_list)
|
|||||||
table->s= share;
|
table->s= share;
|
||||||
share->blob_field= blob_field;
|
share->blob_field= blob_field;
|
||||||
share->fields= field_count;
|
share->fields= field_count;
|
||||||
share->blob_ptr_size= mi_portable_sizeof_char_ptr;
|
share->blob_ptr_size= portable_sizeof_char_ptr;
|
||||||
setup_tmp_table_column_bitmaps(table, bitmaps);
|
setup_tmp_table_column_bitmaps(table, bitmaps);
|
||||||
|
|
||||||
/* Create all fields and calculate the total length of record */
|
/* Create all fields and calculate the total length of record */
|
||||||
|
@@ -28,6 +28,7 @@
|
|||||||
|
|
||||||
#include "maria_def.h"
|
#include "maria_def.h"
|
||||||
#include "ma_rt_index.h"
|
#include "ma_rt_index.h"
|
||||||
|
#include "ma_blockrec.h"
|
||||||
|
|
||||||
ulong maria_recover_options= HA_RECOVER_NONE;
|
ulong maria_recover_options= HA_RECOVER_NONE;
|
||||||
|
|
||||||
@@ -108,7 +109,6 @@ static void _ma_check_print_msg(HA_CHECK *param, const char *msg_type,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Convert TABLE object to Maria key and column definition
|
Convert TABLE object to Maria key and column definition
|
||||||
|
|
||||||
@@ -512,6 +512,26 @@ double ha_maria::scan_time()
|
|||||||
return handler::scan_time();
|
return handler::scan_time();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
We need to be able to store at least two keys on an index page as the
|
||||||
|
splitting algorithms depends on this. (With only one key on a page
|
||||||
|
we also can't use any compression, which may make the index file much
|
||||||
|
larger)
|
||||||
|
We use HA_MAX_KEY_BUFF as this is a stack restriction imposed by the
|
||||||
|
handler interface.
|
||||||
|
|
||||||
|
We also need to reserve place for a record pointer (8) and 3 bytes
|
||||||
|
per key segment to store the length of the segment + possible null bytes.
|
||||||
|
These extra bytes are required here so that maria_create() will surely
|
||||||
|
accept any keys created which the returned key data storage length.
|
||||||
|
*/
|
||||||
|
|
||||||
|
uint ha_maria::max_supported_key_length() const
|
||||||
|
{
|
||||||
|
uint tmp= (maria_max_key_length() - 8 - HA_MAX_KEY_SEG*3);
|
||||||
|
return min(HA_MAX_KEY_BUFF, tmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef HAVE_REPLICATION
|
#ifdef HAVE_REPLICATION
|
||||||
int ha_maria::net_read_dump(NET * net)
|
int ha_maria::net_read_dump(NET * net)
|
||||||
|
@@ -59,10 +59,9 @@ public:
|
|||||||
}
|
}
|
||||||
uint max_supported_keys() const
|
uint max_supported_keys() const
|
||||||
{ return MARIA_MAX_KEY; }
|
{ return MARIA_MAX_KEY; }
|
||||||
uint max_supported_key_length() const
|
uint max_supported_key_length() const;
|
||||||
{ return HA_MAX_KEY_LENGTH; }
|
|
||||||
uint max_supported_key_part_length() const
|
uint max_supported_key_part_length() const
|
||||||
{ return HA_MAX_KEY_LENGTH; }
|
{ return max_supported_key_length(); }
|
||||||
enum row_type get_row_type() const;
|
enum row_type get_row_type() const;
|
||||||
uint checksum() const;
|
uint checksum() const;
|
||||||
virtual double scan_time();
|
virtual double scan_time();
|
||||||
|
@@ -30,7 +30,7 @@
|
|||||||
2 bits are used to indicate:
|
2 bits are used to indicate:
|
||||||
|
|
||||||
0 Empty
|
0 Empty
|
||||||
1 50-75 % full (at least room for 2 records)
|
1 0-75 % full (at least room for 2 records)
|
||||||
2 75-100 % full (at least room for one record)
|
2 75-100 % full (at least room for one record)
|
||||||
3 100 % full (no more room for records)
|
3 100 % full (no more room for records)
|
||||||
|
|
||||||
@@ -106,7 +106,6 @@
|
|||||||
put on disk even if they are not in the page cache).
|
put on disk even if they are not in the page cache).
|
||||||
- When explicitely requested (for example on backup or after recvoery,
|
- When explicitely requested (for example on backup or after recvoery,
|
||||||
to simplify things)
|
to simplify things)
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "maria_def.h"
|
#include "maria_def.h"
|
||||||
@@ -118,6 +117,15 @@
|
|||||||
#define FULL_HEAD_PAGE 4
|
#define FULL_HEAD_PAGE 4
|
||||||
#define FULL_TAIL_PAGE 7
|
#define FULL_TAIL_PAGE 7
|
||||||
|
|
||||||
|
uchar maria_bitmap_marker[2]= {(uchar) 'b',(uchar) 'm'};
|
||||||
|
|
||||||
|
static my_bool _ma_read_bitmap_page(MARIA_SHARE *share,
|
||||||
|
MARIA_FILE_BITMAP *bitmap,
|
||||||
|
ulonglong page);
|
||||||
|
|
||||||
|
|
||||||
|
/* Write bitmap page to key cache */
|
||||||
|
|
||||||
static inline my_bool write_changed_bitmap(MARIA_SHARE *share,
|
static inline my_bool write_changed_bitmap(MARIA_SHARE *share,
|
||||||
MARIA_FILE_BITMAP *bitmap)
|
MARIA_FILE_BITMAP *bitmap)
|
||||||
{
|
{
|
||||||
@@ -128,7 +136,19 @@ static inline my_bool write_changed_bitmap(MARIA_SHARE *share,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Initialize bitmap. This is called the first time a file is opened
|
Initialize bitmap variables in share
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
_ma_bitmap_init()
|
||||||
|
share Share handler
|
||||||
|
file data file handler
|
||||||
|
|
||||||
|
NOTES
|
||||||
|
This is called the first time a file is opened.
|
||||||
|
|
||||||
|
RETURN
|
||||||
|
0 ok
|
||||||
|
1 error
|
||||||
*/
|
*/
|
||||||
|
|
||||||
my_bool _ma_bitmap_init(MARIA_SHARE *share, File file)
|
my_bool _ma_bitmap_init(MARIA_SHARE *share, File file)
|
||||||
@@ -175,20 +195,21 @@ my_bool _ma_bitmap_init(MARIA_SHARE *share, File file)
|
|||||||
Start by reading first page (assume table scan)
|
Start by reading first page (assume table scan)
|
||||||
Later code is simpler if it can assume we always have an active bitmap.
|
Later code is simpler if it can assume we always have an active bitmap.
|
||||||
*/
|
*/
|
||||||
if (_ma_read_bitmap_page(share, bitmap, (ulonglong) 0))
|
return _ma_read_bitmap_page(share, bitmap, (ulonglong) 0);
|
||||||
return(1);
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Free data allocated by _ma_bitmap_init
|
Free data allocated by _ma_bitmap_init
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
_ma_bitmap_end()
|
||||||
|
share Share handler
|
||||||
*/
|
*/
|
||||||
|
|
||||||
my_bool _ma_bitmap_end(MARIA_SHARE *share)
|
my_bool _ma_bitmap_end(MARIA_SHARE *share)
|
||||||
{
|
{
|
||||||
my_bool res= 0;
|
my_bool res= _ma_flush_bitmap(share);
|
||||||
_ma_flush_bitmap(share);
|
|
||||||
pthread_mutex_destroy(&share->bitmap.bitmap_lock);
|
pthread_mutex_destroy(&share->bitmap.bitmap_lock);
|
||||||
my_free((byte*) share->bitmap.map, MYF(MY_ALLOW_ZERO_PTR));
|
my_free((byte*) share->bitmap.map, MYF(MY_ALLOW_ZERO_PTR));
|
||||||
share->bitmap.map= 0;
|
share->bitmap.map= 0;
|
||||||
@@ -198,6 +219,20 @@ my_bool _ma_bitmap_end(MARIA_SHARE *share)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
Flush bitmap to disk
|
Flush bitmap to disk
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
_ma_flush_bitmap()
|
||||||
|
share Share handler
|
||||||
|
|
||||||
|
NOTES
|
||||||
|
In the future, _ma_flush_bitmap() will be called to flush changes don't
|
||||||
|
by this thread (ie, checking the changed flag is ok). The reason we
|
||||||
|
check it again in the mutex is that if someone else did a flush at the
|
||||||
|
same time, we don't have to do the write.
|
||||||
|
|
||||||
|
RETURN
|
||||||
|
0 ok
|
||||||
|
1 error
|
||||||
*/
|
*/
|
||||||
|
|
||||||
my_bool _ma_flush_bitmap(MARIA_SHARE *share)
|
my_bool _ma_flush_bitmap(MARIA_SHARE *share)
|
||||||
@@ -217,12 +252,24 @@ my_bool _ma_flush_bitmap(MARIA_SHARE *share)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Intialize bitmap in memory to a zero bitmap
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
_ma_bitmap_delete_all()
|
||||||
|
share Share handler
|
||||||
|
|
||||||
|
NOTES
|
||||||
|
This is called on ma_delete_all (truncate data file).
|
||||||
|
*/
|
||||||
|
|
||||||
void _ma_bitmap_delete_all(MARIA_SHARE *share)
|
void _ma_bitmap_delete_all(MARIA_SHARE *share)
|
||||||
{
|
{
|
||||||
MARIA_FILE_BITMAP *bitmap= &share->bitmap;
|
MARIA_FILE_BITMAP *bitmap= &share->bitmap;
|
||||||
if (bitmap->map) /* Not in create */
|
if (bitmap->map) /* Not in create */
|
||||||
{
|
{
|
||||||
bzero(bitmap->map, share->block_size);
|
bzero(bitmap->map, share->block_size);
|
||||||
|
memcpy(bitmap->map + share->block_size - 2, maria_bitmap_marker, 2);
|
||||||
bitmap->changed= 0;
|
bitmap->changed= 0;
|
||||||
bitmap->page= 0;
|
bitmap->page= 0;
|
||||||
bitmap->used_size= bitmap->total_size;
|
bitmap->used_size= bitmap->total_size;
|
||||||
@@ -256,7 +303,15 @@ static uint size_to_head_pattern(MARIA_FILE_BITMAP *bitmap, uint size)
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Return bitmap pattern for block where there is size bytes free
|
Return bitmap pattern for head block where there is size bytes free
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
_ma_free_size_to_head_pattern()
|
||||||
|
bitmap Bitmap
|
||||||
|
size Requested size
|
||||||
|
|
||||||
|
RETURN
|
||||||
|
0-4 (Possible bitmap patterns for head block)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
uint _ma_free_size_to_head_pattern(MARIA_FILE_BITMAP *bitmap, uint size)
|
uint _ma_free_size_to_head_pattern(MARIA_FILE_BITMAP *bitmap, uint size)
|
||||||
@@ -294,6 +349,18 @@ static uint size_to_tail_pattern(MARIA_FILE_BITMAP *bitmap, uint size)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Return bitmap pattern for tail block where there is size bytes free
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
free_size_to_tail_pattern()
|
||||||
|
bitmap Bitmap
|
||||||
|
size Requested size
|
||||||
|
|
||||||
|
RETURN
|
||||||
|
0, 5, 6, 7 For a description of the bitmap sizes, see the header
|
||||||
|
*/
|
||||||
|
|
||||||
static uint free_size_to_tail_pattern(MARIA_FILE_BITMAP *bitmap, uint size)
|
static uint free_size_to_tail_pattern(MARIA_FILE_BITMAP *bitmap, uint size)
|
||||||
{
|
{
|
||||||
if (size >= bitmap->sizes[0])
|
if (size >= bitmap->sizes[0])
|
||||||
@@ -310,7 +377,7 @@ static uint free_size_to_tail_pattern(MARIA_FILE_BITMAP *bitmap, uint size)
|
|||||||
Return size guranteed to be available on a page
|
Return size guranteed to be available on a page
|
||||||
|
|
||||||
SYNOPSIS
|
SYNOPSIS
|
||||||
pattern_to_head_size
|
pattern_to_head_size()
|
||||||
bitmap Bitmap
|
bitmap Bitmap
|
||||||
pattern Pattern (0-7)
|
pattern Pattern (0-7)
|
||||||
|
|
||||||
@@ -327,6 +394,15 @@ static inline uint pattern_to_size(MARIA_FILE_BITMAP *bitmap, uint pattern)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
Print bitmap for debugging
|
Print bitmap for debugging
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
_ma_print_bitmap()
|
||||||
|
bitmap Bitmap to print
|
||||||
|
|
||||||
|
IMPLEMENTATION
|
||||||
|
Prints all changed bits since last call to _ma_print_bitmap().
|
||||||
|
This is done by having a copy of the last bitmap in
|
||||||
|
bitmap->map+bitmap->block_size.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef DBUG_OFF
|
#ifndef DBUG_OFF
|
||||||
@@ -348,12 +424,18 @@ static void _ma_print_bitmap(MARIA_FILE_BITMAP *bitmap)
|
|||||||
(ulong) bitmap->page);
|
(ulong) bitmap->page);
|
||||||
|
|
||||||
page= (ulong) bitmap->page+1;
|
page= (ulong) bitmap->page+1;
|
||||||
for (pos= bitmap->map, org_pos= bitmap->map+bitmap->block_size ; pos < end ;
|
for (pos= bitmap->map, org_pos= bitmap->map + bitmap->block_size ;
|
||||||
|
pos < end ;
|
||||||
pos+= 6, org_pos+= 6)
|
pos+= 6, org_pos+= 6)
|
||||||
{
|
{
|
||||||
ulonglong bits= uint6korr(pos); /* 6 bytes = 6*8/3= 16 patterns */
|
ulonglong bits= uint6korr(pos); /* 6 bytes = 6*8/3= 16 patterns */
|
||||||
ulonglong org_bits= uint6korr(org_pos);
|
ulonglong org_bits= uint6korr(org_pos);
|
||||||
uint i;
|
uint i;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Test if there is any changes in the next 16 bitmaps (to not have to
|
||||||
|
loop through all bits if we know they are the same)
|
||||||
|
*/
|
||||||
if (bits != org_bits)
|
if (bits != org_bits)
|
||||||
{
|
{
|
||||||
for (i= 0; i < 16 ; i++, bits>>= 3, org_bits>>= 3)
|
for (i= 0; i < 16 ; i++, bits>>= 3, org_bits>>= 3)
|
||||||
@@ -394,7 +476,8 @@ static void _ma_print_bitmap(MARIA_FILE_BITMAP *bitmap)
|
|||||||
1 error (Error writing old bitmap or reading bitmap page)
|
1 error (Error writing old bitmap or reading bitmap page)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
my_bool _ma_read_bitmap_page(MARIA_SHARE *share, MARIA_FILE_BITMAP *bitmap,
|
static my_bool _ma_read_bitmap_page(MARIA_SHARE *share,
|
||||||
|
MARIA_FILE_BITMAP *bitmap,
|
||||||
ulonglong page)
|
ulonglong page)
|
||||||
{
|
{
|
||||||
my_off_t position= page * bitmap->block_size;
|
my_off_t position= page * bitmap->block_size;
|
||||||
@@ -407,6 +490,7 @@ my_bool _ma_read_bitmap_page(MARIA_SHARE *share, MARIA_FILE_BITMAP *bitmap,
|
|||||||
{
|
{
|
||||||
share->state.state.data_file_length= position + bitmap->block_size;
|
share->state.state.data_file_length= position + bitmap->block_size;
|
||||||
bzero(bitmap->map, bitmap->block_size);
|
bzero(bitmap->map, bitmap->block_size);
|
||||||
|
memcpy(bitmap->map + share->block_size - 2, maria_bitmap_marker, 2);
|
||||||
bitmap->used_size= 0;
|
bitmap->used_size= 0;
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
@@ -465,6 +549,10 @@ static my_bool _ma_change_bitmap_page(MARIA_HA *info,
|
|||||||
move_to_next_bitmap()
|
move_to_next_bitmap()
|
||||||
bitmap Bitmap handle
|
bitmap Bitmap handle
|
||||||
|
|
||||||
|
NOTES
|
||||||
|
The found bitmap may be full, so calling function may need to call this
|
||||||
|
repeatedly until it finds enough space.
|
||||||
|
|
||||||
TODO
|
TODO
|
||||||
Add cache of bitmaps to not read something that is not usable
|
Add cache of bitmaps to not read something that is not usable
|
||||||
|
|
||||||
@@ -505,7 +593,12 @@ static my_bool move_to_next_bitmap(MARIA_HA *info, MARIA_FILE_BITMAP *bitmap)
|
|||||||
best_data Pointer to best 6 byte aligned area in bitmap->map
|
best_data Pointer to best 6 byte aligned area in bitmap->map
|
||||||
best_pos Which bit in *best_data the area starts
|
best_pos Which bit in *best_data the area starts
|
||||||
0 = first bit pattern, 1 second bit pattern etc
|
0 = first bit pattern, 1 second bit pattern etc
|
||||||
|
best_bits The original value of the bits at best_pos
|
||||||
fill_pattern Bitmap pattern to store in best_data[best_pos]
|
fill_pattern Bitmap pattern to store in best_data[best_pos]
|
||||||
|
|
||||||
|
NOTES
|
||||||
|
We mark all pages to be 'TAIL's, which means that
|
||||||
|
block->page_count is really a row position inside the page.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void fill_block(MARIA_FILE_BITMAP *bitmap,
|
static void fill_block(MARIA_FILE_BITMAP *bitmap,
|
||||||
@@ -523,7 +616,7 @@ static void fill_block(MARIA_FILE_BITMAP *bitmap,
|
|||||||
block->empty_space= pattern_to_size(bitmap, best_bits);
|
block->empty_space= pattern_to_size(bitmap, best_bits);
|
||||||
block->sub_blocks= 1;
|
block->sub_blocks= 1;
|
||||||
block->org_bitmap_value= best_bits;
|
block->org_bitmap_value= best_bits;
|
||||||
block->used= BLOCKUSED_TAIL;
|
block->used= BLOCKUSED_TAIL; /* See _ma_bitmap_release_unused() */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Mark place used by reading/writing 2 bytes at a time to handle
|
Mark place used by reading/writing 2 bytes at a time to handle
|
||||||
@@ -533,6 +626,8 @@ static void fill_block(MARIA_FILE_BITMAP *bitmap,
|
|||||||
data= best_data+ best_pos / 8;
|
data= best_data+ best_pos / 8;
|
||||||
offset= best_pos & 7;
|
offset= best_pos & 7;
|
||||||
tmp= uint2korr(data);
|
tmp= uint2korr(data);
|
||||||
|
|
||||||
|
/* we turn off the 3 bits and replace them with fill_pattern */
|
||||||
tmp= (tmp & ~(7 << offset)) | (fill_pattern << offset);
|
tmp= (tmp & ~(7 << offset)) | (fill_pattern << offset);
|
||||||
int2store(data, tmp);
|
int2store(data, tmp);
|
||||||
bitmap->changed= 1;
|
bitmap->changed= 1;
|
||||||
@@ -546,9 +641,14 @@ static void fill_block(MARIA_FILE_BITMAP *bitmap,
|
|||||||
SYNOPSIS
|
SYNOPSIS
|
||||||
allocate_head()
|
allocate_head()
|
||||||
bitmap bitmap
|
bitmap bitmap
|
||||||
size Size of block we need to find
|
size Size of data region we need to store
|
||||||
block Store found information here
|
block Store found information here
|
||||||
|
|
||||||
|
IMPLEMENTATION
|
||||||
|
Find the best-fit page to put a region of 'size'
|
||||||
|
This is defined as the first page of the set of pages
|
||||||
|
with the smallest free space that can hold 'size'.
|
||||||
|
|
||||||
RETURN
|
RETURN
|
||||||
0 ok (block is updated)
|
0 ok (block is updated)
|
||||||
1 error (no space in bitmap; block is not touched)
|
1 error (no space in bitmap; block is not touched)
|
||||||
@@ -586,9 +686,10 @@ static my_bool allocate_head(MARIA_FILE_BITMAP *bitmap, uint size,
|
|||||||
uint pattern= bits & 7;
|
uint pattern= bits & 7;
|
||||||
if (pattern <= min_bits)
|
if (pattern <= min_bits)
|
||||||
{
|
{
|
||||||
|
/* There is enough space here */
|
||||||
if (pattern == min_bits)
|
if (pattern == min_bits)
|
||||||
{
|
{
|
||||||
/* Found perfect match */
|
/* There is exactly enough space here, return this page */
|
||||||
best_bits= min_bits;
|
best_bits= min_bits;
|
||||||
best_data= data;
|
best_data= data;
|
||||||
best_pos= i;
|
best_pos= i;
|
||||||
@@ -596,6 +697,11 @@ static my_bool allocate_head(MARIA_FILE_BITMAP *bitmap, uint size,
|
|||||||
}
|
}
|
||||||
if ((int) pattern > (int) best_bits)
|
if ((int) pattern > (int) best_bits)
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
There is more than enough space here and it's better than what
|
||||||
|
we have found so far. Remember it, as we will choose it if we
|
||||||
|
don't find anything in this bitmap page.
|
||||||
|
*/
|
||||||
best_bits= pattern;
|
best_bits= pattern;
|
||||||
best_data= data;
|
best_data= data;
|
||||||
best_pos= i;
|
best_pos= i;
|
||||||
@@ -603,10 +709,10 @@ static my_bool allocate_head(MARIA_FILE_BITMAP *bitmap, uint size,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!best_data)
|
if (!best_data) /* Found no place */
|
||||||
{
|
{
|
||||||
if (bitmap->used_size == bitmap->total_size)
|
if (bitmap->used_size == bitmap->total_size)
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1); /* No space in bitmap */
|
||||||
/* Allocate data at end of bitmap */
|
/* Allocate data at end of bitmap */
|
||||||
bitmap->used_size+= 6;
|
bitmap->used_size+= 6;
|
||||||
best_data= data;
|
best_data= data;
|
||||||
@@ -655,7 +761,12 @@ static my_bool allocate_tail(MARIA_FILE_BITMAP *bitmap, uint size,
|
|||||||
/*
|
/*
|
||||||
Skip common patterns
|
Skip common patterns
|
||||||
We can skip empty pages (if we already found a match) or
|
We can skip empty pages (if we already found a match) or
|
||||||
the following patterns: 1-4 or 7
|
the following patterns: 1-4 (head pages, not suitable for tail) or
|
||||||
|
7 (full tail page). See 'Dynamic size records' comment at start of file.
|
||||||
|
|
||||||
|
At the moment we only skip full tail pages (ie, all bits are
|
||||||
|
set) as this is easy to detect with one simple test and is a
|
||||||
|
quite common case if we have blobs.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if ((!bits && best_data) || bits == LL(0xffffffffffff))
|
if ((!bits && best_data) || bits == LL(0xffffffffffff))
|
||||||
@@ -888,6 +999,13 @@ static ulong allocate_full_pages(MARIA_FILE_BITMAP *bitmap,
|
|||||||
/*
|
/*
|
||||||
Find right bitmap and position for head block
|
Find right bitmap and position for head block
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
find_head()
|
||||||
|
info Maria handler
|
||||||
|
length Size of data region we need store
|
||||||
|
position Position in bitmap_blocks where to store the
|
||||||
|
information for the head block.
|
||||||
|
|
||||||
RETURN
|
RETURN
|
||||||
0 ok
|
0 ok
|
||||||
1 error
|
1 error
|
||||||
@@ -897,7 +1015,10 @@ static my_bool find_head(MARIA_HA *info, uint length, uint position)
|
|||||||
{
|
{
|
||||||
MARIA_FILE_BITMAP *bitmap= &info->s->bitmap;
|
MARIA_FILE_BITMAP *bitmap= &info->s->bitmap;
|
||||||
MARIA_BITMAP_BLOCK *block;
|
MARIA_BITMAP_BLOCK *block;
|
||||||
/* There is always place for head blocks in bitmap_blocks */
|
/*
|
||||||
|
There is always place for the head block in bitmap_blocks as these are
|
||||||
|
preallocated at _ma_init_block_record().
|
||||||
|
*/
|
||||||
block= dynamic_element(&info->bitmap_blocks, position, MARIA_BITMAP_BLOCK *);
|
block= dynamic_element(&info->bitmap_blocks, position, MARIA_BITMAP_BLOCK *);
|
||||||
|
|
||||||
while (allocate_head(bitmap, length, block))
|
while (allocate_head(bitmap, length, block))
|
||||||
@@ -910,6 +1031,13 @@ static my_bool find_head(MARIA_HA *info, uint length, uint position)
|
|||||||
/*
|
/*
|
||||||
Find right bitmap and position for tail
|
Find right bitmap and position for tail
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
find_tail()
|
||||||
|
info Maria handler
|
||||||
|
length Size of data region we need store
|
||||||
|
position Position in bitmap_blocks where to store the
|
||||||
|
information for the head block.
|
||||||
|
|
||||||
RETURN
|
RETURN
|
||||||
0 ok
|
0 ok
|
||||||
1 error
|
1 error
|
||||||
@@ -936,8 +1064,15 @@ static my_bool find_tail(MARIA_HA *info, uint length, uint position)
|
|||||||
/*
|
/*
|
||||||
Find right bitmap and position for full blocks in one extent
|
Find right bitmap and position for full blocks in one extent
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
find_mid()
|
||||||
|
info Maria handler.
|
||||||
|
pages How many pages to allocate.
|
||||||
|
position Position in bitmap_blocks where to store the
|
||||||
|
information for the head block.
|
||||||
NOTES
|
NOTES
|
||||||
This is used to allocate the main extent after the 'head' block
|
This is used to allocate the main extent after the 'head' block
|
||||||
|
(Ie, the middle part of the head-middle-tail entry)
|
||||||
|
|
||||||
RETURN
|
RETURN
|
||||||
0 ok
|
0 ok
|
||||||
@@ -962,6 +1097,11 @@ static my_bool find_mid(MARIA_HA *info, ulong pages, uint position)
|
|||||||
/*
|
/*
|
||||||
Find right bitmap and position for putting a blob
|
Find right bitmap and position for putting a blob
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
find_blob()
|
||||||
|
info Maria handler.
|
||||||
|
length Length of the blob
|
||||||
|
|
||||||
NOTES
|
NOTES
|
||||||
The extents are stored last in info->bitmap_blocks
|
The extents are stored last in info->bitmap_blocks
|
||||||
|
|
||||||
@@ -1023,6 +1163,19 @@ static my_bool find_blob(MARIA_HA *info, ulong length)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Find pages to put ALL blobs
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
allocate_blobs()
|
||||||
|
info Maria handler
|
||||||
|
row Information of what is in the row (from calc_record_size())
|
||||||
|
|
||||||
|
RETURN
|
||||||
|
0 ok
|
||||||
|
1 error
|
||||||
|
*/
|
||||||
|
|
||||||
static my_bool allocate_blobs(MARIA_HA *info, MARIA_ROW *row)
|
static my_bool allocate_blobs(MARIA_HA *info, MARIA_ROW *row)
|
||||||
{
|
{
|
||||||
ulong *length, *end;
|
ulong *length, *end;
|
||||||
@@ -1045,6 +1198,23 @@ static my_bool allocate_blobs(MARIA_HA *info, MARIA_ROW *row)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Store in the bitmap the new size for a head page
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
use_head()
|
||||||
|
info Maria handler
|
||||||
|
page Page number to update
|
||||||
|
(Note that caller guarantees this is in the active
|
||||||
|
bitmap)
|
||||||
|
size How much free space is left on the page
|
||||||
|
block_position In which info->bitmap_block we have the
|
||||||
|
information about the head block.
|
||||||
|
|
||||||
|
NOTES
|
||||||
|
This is used on update where we are updating an existing head page
|
||||||
|
*/
|
||||||
|
|
||||||
static void use_head(MARIA_HA *info, ulonglong page, uint size,
|
static void use_head(MARIA_HA *info, ulonglong page, uint size,
|
||||||
uint block_position)
|
uint block_position)
|
||||||
{
|
{
|
||||||
@@ -1078,7 +1248,18 @@ static void use_head(MARIA_HA *info, ulonglong page, uint size,
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Find out where to split the row;
|
Find out where to split the row (ie, what goes in head, middle, tail etc)
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
find_where_to_split_row()
|
||||||
|
share Maria share
|
||||||
|
row Information of what is in the row (from calc_record_size())
|
||||||
|
extents_length Number of bytes needed to store all extents
|
||||||
|
split_size Free size on the page (The head length must be less
|
||||||
|
than this)
|
||||||
|
|
||||||
|
RETURN
|
||||||
|
row_length for the head block.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static uint find_where_to_split_row(MARIA_SHARE *share, MARIA_ROW *row,
|
static uint find_where_to_split_row(MARIA_SHARE *share, MARIA_ROW *row,
|
||||||
@@ -1108,6 +1289,21 @@ static uint find_where_to_split_row(MARIA_SHARE *share, MARIA_ROW *row,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Find where to write the middle parts of the row and the tail
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
write_rest_of_head()
|
||||||
|
info Maria handler
|
||||||
|
position Position in bitmap_blocks. Is 0 for rows that needs
|
||||||
|
full blocks (ie, has a head, middle part and optional tail)
|
||||||
|
rest_length How much left of the head block to write.
|
||||||
|
|
||||||
|
RETURN
|
||||||
|
0 ok
|
||||||
|
1 error
|
||||||
|
*/
|
||||||
|
|
||||||
static my_bool write_rest_of_head(MARIA_HA *info, uint position,
|
static my_bool write_rest_of_head(MARIA_HA *info, uint position,
|
||||||
ulong rest_length)
|
ulong rest_length)
|
||||||
{
|
{
|
||||||
@@ -1349,6 +1545,23 @@ abort:
|
|||||||
Clear and reset bits
|
Clear and reset bits
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
|
/*
|
||||||
|
Set fill pattern for a page
|
||||||
|
|
||||||
|
set_page_bits()
|
||||||
|
info Maria handler
|
||||||
|
bitmap Bitmap handler
|
||||||
|
page Adress to page
|
||||||
|
fill_pattern Pattern (not size) for page
|
||||||
|
|
||||||
|
NOTES
|
||||||
|
Page may not be part of active bitmap
|
||||||
|
|
||||||
|
RETURN
|
||||||
|
0 ok
|
||||||
|
1 error
|
||||||
|
*/
|
||||||
|
|
||||||
static my_bool set_page_bits(MARIA_HA *info, MARIA_FILE_BITMAP *bitmap,
|
static my_bool set_page_bits(MARIA_HA *info, MARIA_FILE_BITMAP *bitmap,
|
||||||
ulonglong page, uint fill_pattern)
|
ulonglong page, uint fill_pattern)
|
||||||
{
|
{
|
||||||
@@ -1390,7 +1603,6 @@ static my_bool set_page_bits(MARIA_HA *info, MARIA_FILE_BITMAP *bitmap,
|
|||||||
Get bitmap pattern for a given page
|
Get bitmap pattern for a given page
|
||||||
|
|
||||||
SYNOPSIS
|
SYNOPSIS
|
||||||
|
|
||||||
get_page_bits()
|
get_page_bits()
|
||||||
info Maria handler
|
info Maria handler
|
||||||
bitmap Bitmap handler
|
bitmap Bitmap handler
|
||||||
@@ -1432,7 +1644,7 @@ static uint get_page_bits(MARIA_HA *info, MARIA_FILE_BITMAP *bitmap,
|
|||||||
Mark all pages in a region as free
|
Mark all pages in a region as free
|
||||||
|
|
||||||
SYNOPSIS
|
SYNOPSIS
|
||||||
reset_full_page_bits()
|
_ma_reset_full_page_bits()
|
||||||
info Maria handler
|
info Maria handler
|
||||||
bitmap Bitmap handler
|
bitmap Bitmap handler
|
||||||
page Start page
|
page Start page
|
||||||
@@ -1579,6 +1791,11 @@ my_bool _ma_bitmap_release_unused(MARIA_HA *info, MARIA_BITMAP_BLOCKS *blocks)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
bits= block->org_bitmap_value;
|
bits= block->org_bitmap_value;
|
||||||
|
|
||||||
|
/*
|
||||||
|
The page has all bits set; The following test is an optimization
|
||||||
|
to not set the bits to the same value as before.
|
||||||
|
*/
|
||||||
if (bits != FULL_TAIL_PAGE &&
|
if (bits != FULL_TAIL_PAGE &&
|
||||||
set_page_bits(info, bitmap, block->page, bits))
|
set_page_bits(info, bitmap, block->page, bits))
|
||||||
goto err;
|
goto err;
|
||||||
@@ -1638,8 +1855,22 @@ my_bool _ma_bitmap_free_full_pages(MARIA_HA *info, const byte *extents,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Mark in the bitmap how much free space there is on a page
|
||||||
|
|
||||||
my_bool _ma_bitmap_set(MARIA_HA *info, ulonglong pos, my_bool head,
|
SYNOPSIS
|
||||||
|
_ma_bitmap_set()
|
||||||
|
info Mari handler
|
||||||
|
page Adress to page
|
||||||
|
head 1 if page is a head page, 0 if tail page
|
||||||
|
empty_space How much empty space there is on page
|
||||||
|
|
||||||
|
RETURN
|
||||||
|
0 ok
|
||||||
|
1 error
|
||||||
|
*/
|
||||||
|
|
||||||
|
my_bool _ma_bitmap_set(MARIA_HA *info, ulonglong page, my_bool head,
|
||||||
uint empty_space)
|
uint empty_space)
|
||||||
{
|
{
|
||||||
MARIA_FILE_BITMAP *bitmap= &info->s->bitmap;
|
MARIA_FILE_BITMAP *bitmap= &info->s->bitmap;
|
||||||
@@ -1651,7 +1882,7 @@ my_bool _ma_bitmap_set(MARIA_HA *info, ulonglong pos, my_bool head,
|
|||||||
bits= (head ?
|
bits= (head ?
|
||||||
_ma_free_size_to_head_pattern(bitmap, empty_space) :
|
_ma_free_size_to_head_pattern(bitmap, empty_space) :
|
||||||
free_size_to_tail_pattern(bitmap, empty_space));
|
free_size_to_tail_pattern(bitmap, empty_space));
|
||||||
res= set_page_bits(info, bitmap, pos, bits);
|
res= set_page_bits(info, bitmap, page, bits);
|
||||||
pthread_mutex_unlock(&info->s->bitmap.bitmap_lock);
|
pthread_mutex_unlock(&info->s->bitmap.bitmap_lock);
|
||||||
DBUG_RETURN(res);
|
DBUG_RETURN(res);
|
||||||
}
|
}
|
||||||
@@ -1663,6 +1894,15 @@ my_bool _ma_bitmap_set(MARIA_HA *info, ulonglong pos, my_bool head,
|
|||||||
NOTES
|
NOTES
|
||||||
Used in maria_chk
|
Used in maria_chk
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
_ma_check_bitmap_data()
|
||||||
|
info Maria handler
|
||||||
|
page_type What kind of page this is
|
||||||
|
page Adress to page
|
||||||
|
empty_space Empty space on page
|
||||||
|
bitmap_pattern Store here the pattern that was in the bitmap for the
|
||||||
|
page. This is always updated.
|
||||||
|
|
||||||
RETURN
|
RETURN
|
||||||
0 ok
|
0 ok
|
||||||
1 error
|
1 error
|
||||||
@@ -1694,7 +1934,15 @@ my_bool _ma_check_bitmap_data(MARIA_HA *info,
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Check that bitmap pattern is correct for a page
|
Check if the page type matches the one that we have in the bitmap
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
_ma_check_if_right_bitmap_type()
|
||||||
|
info Maria handler
|
||||||
|
page_type What kind of page this is
|
||||||
|
page Adress to page
|
||||||
|
bitmap_pattern Store here the pattern that was in the bitmap for the
|
||||||
|
page. This is always updated.
|
||||||
|
|
||||||
NOTES
|
NOTES
|
||||||
Used in maria_chk
|
Used in maria_chk
|
||||||
|
@@ -16,16 +16,19 @@
|
|||||||
/*
|
/*
|
||||||
Storage of records in block
|
Storage of records in block
|
||||||
|
|
||||||
Maria will have a LSN at start of each page (including the bitmap page)
|
Some clarifactions about the abbrev used:
|
||||||
Maria will for each row have the additional information:
|
|
||||||
|
|
||||||
TRANSID Transaction ID that last updated row (6 bytes)
|
NULL fields -> Fields that may have contain a NULL value.
|
||||||
VER_PTR Version pointer that points on the UNDO entry that
|
Not null fields -> Fields that may not contain a NULL value.
|
||||||
contains last version of the row versions (7 bytes)
|
Critical fields -> Fields that can't be null and can't be dropped without
|
||||||
|
causing a table reorganization.
|
||||||
|
|
||||||
|
|
||||||
|
Maria will have a LSN at start of each page (excluding the bitmap pages)
|
||||||
|
|
||||||
The different page types that are in a data file are:
|
The different page types that are in a data file are:
|
||||||
|
|
||||||
Bitmap pages Map of free pages in the next extent (8129 page size
|
Bitmap pages Map of free pages in the next extent (8192 page size
|
||||||
gives us 256M of mapped pages / bitmap)
|
gives us 256M of mapped pages / bitmap)
|
||||||
Head page Start of rows are stored on this page.
|
Head page Start of rows are stored on this page.
|
||||||
A rowid always points to a head page
|
A rowid always points to a head page
|
||||||
@@ -43,9 +46,9 @@
|
|||||||
Structure of data and tail page:
|
Structure of data and tail page:
|
||||||
|
|
||||||
The page has a row directory at end of page to allow us to do deletes
|
The page has a row directory at end of page to allow us to do deletes
|
||||||
without having to reorganize the page. It also allows us to store some
|
without having to reorganize the page. It also allows us to later store
|
||||||
extra bytes after each row to allow them to grow without having to move
|
some more bytes after each row to allow them to grow without having to move
|
||||||
around other rows
|
around other rows.
|
||||||
|
|
||||||
Page header:
|
Page header:
|
||||||
|
|
||||||
@@ -59,7 +62,7 @@
|
|||||||
|
|
||||||
Row data
|
Row data
|
||||||
|
|
||||||
Row directory of NO entires, that consist of the following for each row
|
Row directory of NO entries, that consist of the following for each row
|
||||||
(in reverse order; ie, first record is stored last):
|
(in reverse order; ie, first record is stored last):
|
||||||
|
|
||||||
Position 2 bytes Position of row on page
|
Position 2 bytes Position of row on page
|
||||||
@@ -69,7 +72,8 @@
|
|||||||
upmost bit of the length could be used for some states of the row (in
|
upmost bit of the length could be used for some states of the row (in
|
||||||
other words, we should try to keep these reserved)
|
other words, we should try to keep these reserved)
|
||||||
|
|
||||||
eof flag 1 byte Reserved for full page read testing
|
eof flag 1 byte Reserved for full page read testing. (Ie, did the
|
||||||
|
previous write get the whole block on disk.
|
||||||
|
|
||||||
----------------
|
----------------
|
||||||
|
|
||||||
@@ -105,19 +109,27 @@
|
|||||||
Total length of length array 1-3 byte Only used if we have
|
Total length of length array 1-3 byte Only used if we have
|
||||||
char/varchar/blob fields.
|
char/varchar/blob fields.
|
||||||
Row checksum 1 byte Only if table created with checksums
|
Row checksum 1 byte Only if table created with checksums
|
||||||
Null_bits .. One bit for each NULL field
|
Null_bits .. One bit for each NULL field (a field that may
|
||||||
Empty_bits .. One bit for each NOT NULL field. This bit is
|
have the value NULL)
|
||||||
0 if the value is 0 or empty string.
|
Empty_bits .. One bit for each field that may be 'empty'.
|
||||||
|
(Both for null and not null fields).
|
||||||
|
This bit is 1 if the value for the field is
|
||||||
|
0 or empty string.
|
||||||
|
|
||||||
field_offsets 2 byte/offset
|
field_offsets 2 byte/offset
|
||||||
For each 32 field, there is one offset that
|
For each 32'th field, there is one offset
|
||||||
points to where the field information starts
|
that points to where the field information
|
||||||
in the block. This is to provide fast access
|
starts in the block. This is to provide
|
||||||
to later field in the row when we only need
|
fast access to later field in the row
|
||||||
to return a small set of fields.
|
when we only need to return a small
|
||||||
|
set of fields.
|
||||||
|
TODO: Implement this.
|
||||||
|
|
||||||
Things marked above as 'optional' will only be present if the corresponding
|
Things marked above as 'optional' will only be present if the
|
||||||
bit is set in 'Flag' field.
|
corresponding bit is set in 'Flag' field. Flag gives us a way to
|
||||||
|
get more space on a page when doing page compaction as we don't need
|
||||||
|
to store TRANSID that have committed before the smallest running
|
||||||
|
transaction we have in memory.
|
||||||
|
|
||||||
Data in the following order:
|
Data in the following order:
|
||||||
(Field order is precalculated when table is created)
|
(Field order is precalculated when table is created)
|
||||||
@@ -176,11 +188,6 @@
|
|||||||
Nulls_extended_exists 3
|
Nulls_extended_exists 3
|
||||||
Row is split 7 This means that 'Number_of_row_extents' exists
|
Row is split 7 This means that 'Number_of_row_extents' exists
|
||||||
|
|
||||||
|
|
||||||
This would be a way to get more space on a page when doing page
|
|
||||||
compaction as we don't need to store TRANSID that have committed
|
|
||||||
before the smallest running transaction we have in memory.
|
|
||||||
|
|
||||||
Nulls_extended is the number of new DEFAULT NULL fields in the row
|
Nulls_extended is the number of new DEFAULT NULL fields in the row
|
||||||
compared to the number of DEFAULT NULL fields when the first version
|
compared to the number of DEFAULT NULL fields when the first version
|
||||||
of the table was created. If Nulls_extended doesn't exist in the row,
|
of the table was created. If Nulls_extended doesn't exist in the row,
|
||||||
@@ -198,8 +205,10 @@
|
|||||||
fields. When storing a row, we will mark a dropped field either with a
|
fields. When storing a row, we will mark a dropped field either with a
|
||||||
null in the null bit map or in the empty_bits and not store any data
|
null in the null bit map or in the empty_bits and not store any data
|
||||||
for it.
|
for it.
|
||||||
|
TODO: Add code for handling dropped fields.
|
||||||
|
|
||||||
One ROW_EXTENT is coded as:
|
|
||||||
|
A ROW EXTENT is range of pages. One ROW_EXTENT is coded as:
|
||||||
|
|
||||||
START_PAGE 5 bytes
|
START_PAGE 5 bytes
|
||||||
PAGE_COUNT 2 bytes. High bit is used to indicate tail page/
|
PAGE_COUNT 2 bytes. High bit is used to indicate tail page/
|
||||||
@@ -248,14 +257,36 @@
|
|||||||
#include "maria_def.h"
|
#include "maria_def.h"
|
||||||
#include "ma_blockrec.h"
|
#include "ma_blockrec.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
Struct for having a cursor over a set of extent.
|
||||||
|
This is used to loop over all extents for a row when reading
|
||||||
|
the row data. It's also used to store the tail positions for
|
||||||
|
a read row to be used by a later update/delete command.
|
||||||
|
*/
|
||||||
|
|
||||||
typedef struct st_maria_extent_cursor
|
typedef struct st_maria_extent_cursor
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
Pointer to packed byte array of extents for the row.
|
||||||
|
Format is described above in the header
|
||||||
|
*/
|
||||||
byte *extent;
|
byte *extent;
|
||||||
byte *data_start; /* For error checking */
|
/* Where data starts on page; Only for debugging */
|
||||||
|
byte *data_start;
|
||||||
|
/* Position to all tails in the row. Updated when reading a row */
|
||||||
MARIA_RECORD_POS *tail_positions;
|
MARIA_RECORD_POS *tail_positions;
|
||||||
|
/* Current page */
|
||||||
my_off_t page;
|
my_off_t page;
|
||||||
uint extent_count, page_count;
|
/* How many pages in the page region */
|
||||||
uint tail; /* <> 0 if current extent is a tail page */
|
uint page_count;
|
||||||
|
/* Total number of extents (ie, entries in the 'extent' slot) */
|
||||||
|
uint extent_count;
|
||||||
|
/* <> 0 if current extent is a tail page; Set while using cursor */
|
||||||
|
uint tail;
|
||||||
|
/*
|
||||||
|
<> 1 if we are working on the first extent (ie, the one that is store in
|
||||||
|
the row header, not an extent that is stored as part of the row data).
|
||||||
|
*/
|
||||||
my_bool first_extent;
|
my_bool first_extent;
|
||||||
} MARIA_EXTENT_CURSOR;
|
} MARIA_EXTENT_CURSOR;
|
||||||
|
|
||||||
@@ -327,38 +358,47 @@ void _ma_init_block_record_data(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
my_bool _ma_once_init_block_row(MARIA_SHARE *share, File data_file)
|
my_bool _ma_once_init_block_record(MARIA_SHARE *share, File data_file)
|
||||||
{
|
{
|
||||||
|
|
||||||
share->base.max_data_file_length=
|
share->base.max_data_file_length=
|
||||||
(((ulonglong) 1 << ((share->base.rec_reflength-1)*8))-1) *
|
(((ulonglong) 1 << ((share->base.rec_reflength-1)*8))-1) *
|
||||||
share->block_size;
|
share->block_size;
|
||||||
#if SIZEOF_OFF_T == 4
|
#if SIZEOF_OFF_T == 4
|
||||||
set_if_smaller(max_data_file_length, INT_MAX32);
|
set_if_smaller(share->base.max_data_file_length, INT_MAX32);
|
||||||
#endif
|
#endif
|
||||||
return _ma_bitmap_init(share, data_file);
|
return _ma_bitmap_init(share, data_file);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
my_bool _ma_once_end_block_row(MARIA_SHARE *share)
|
my_bool _ma_once_end_block_record(MARIA_SHARE *share)
|
||||||
{
|
{
|
||||||
int res= _ma_bitmap_end(share);
|
int res= _ma_bitmap_end(share);
|
||||||
|
if (share->bitmap.file >= 0)
|
||||||
|
{
|
||||||
if (flush_key_blocks(share->key_cache, share->bitmap.file,
|
if (flush_key_blocks(share->key_cache, share->bitmap.file,
|
||||||
share->temporary ? FLUSH_IGNORE_CHANGED :
|
share->temporary ? FLUSH_IGNORE_CHANGED :
|
||||||
FLUSH_RELEASE))
|
FLUSH_RELEASE))
|
||||||
res= 1;
|
res= 1;
|
||||||
if (share->bitmap.file >= 0 && my_close(share->bitmap.file, MYF(MY_WME)))
|
if (my_close(share->bitmap.file, MYF(MY_WME)))
|
||||||
res= 1;
|
res= 1;
|
||||||
|
/*
|
||||||
|
Trivial assignment to guard against multiple invocations
|
||||||
|
(May happen if file are closed but we want to keep the maria object
|
||||||
|
around a bit longer)
|
||||||
|
*/
|
||||||
|
share->bitmap.file= -1;
|
||||||
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Init info->cur_row structure */
|
/* Init info->cur_row structure */
|
||||||
|
|
||||||
my_bool _ma_init_block_row(MARIA_HA *info)
|
my_bool _ma_init_block_record(MARIA_HA *info)
|
||||||
{
|
{
|
||||||
MARIA_ROW *row= &info->cur_row, *new_row= &info->new_row;
|
MARIA_ROW *row= &info->cur_row, *new_row= &info->new_row;
|
||||||
DBUG_ENTER("_ma_init_block_row");
|
DBUG_ENTER("_ma_init_block_record");
|
||||||
|
|
||||||
if (!my_multi_malloc(MY_WME,
|
if (!my_multi_malloc(MY_WME,
|
||||||
&row->empty_bits_buffer, info->s->base.pack_bytes,
|
&row->empty_bits_buffer, info->s->base.pack_bytes,
|
||||||
@@ -398,12 +438,18 @@ my_bool _ma_init_block_row(MARIA_HA *info)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void _ma_end_block_row(MARIA_HA *info)
|
void _ma_end_block_record(MARIA_HA *info)
|
||||||
{
|
{
|
||||||
DBUG_ENTER("_ma_end_block_row");
|
DBUG_ENTER("_ma_end_block_record");
|
||||||
my_free((gptr) info->cur_row.empty_bits_buffer, MYF(MY_ALLOW_ZERO_PTR));
|
my_free((gptr) info->cur_row.empty_bits_buffer, MYF(MY_ALLOW_ZERO_PTR));
|
||||||
delete_dynamic(&info->bitmap_blocks);
|
delete_dynamic(&info->bitmap_blocks);
|
||||||
my_free((gptr) info->cur_row.extents, MYF(MY_ALLOW_ZERO_PTR));
|
my_free((gptr) info->cur_row.extents, MYF(MY_ALLOW_ZERO_PTR));
|
||||||
|
/*
|
||||||
|
The data file is closed, when needed, in ma_once_end_block_record().
|
||||||
|
The following protects us from doing an extra, not allowed, close
|
||||||
|
in maria_close()
|
||||||
|
*/
|
||||||
|
info->dfile= -1;
|
||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -412,7 +458,19 @@ void _ma_end_block_row(MARIA_HA *info)
|
|||||||
Helper functions
|
Helper functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
static inline uint empty_pos_after_row(byte *dir)
|
/*
|
||||||
|
Return the next used byte on the page after a directory entry.
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
start_of_next_entry()
|
||||||
|
dir Directory entry to be used
|
||||||
|
|
||||||
|
RETURN
|
||||||
|
# Position in page where next entry starts.
|
||||||
|
Everything between the '*dir' and this are free to be used.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static inline uint start_of_next_entry(byte *dir)
|
||||||
{
|
{
|
||||||
byte *prev;
|
byte *prev;
|
||||||
/*
|
/*
|
||||||
@@ -427,6 +485,18 @@ static inline uint empty_pos_after_row(byte *dir)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Check that a region is all zero
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
check_if_zero()
|
||||||
|
pos Start of memory to check
|
||||||
|
length length of memory region
|
||||||
|
|
||||||
|
NOTES
|
||||||
|
Used mainly to detect rows with wrong extent information
|
||||||
|
*/
|
||||||
|
|
||||||
static my_bool check_if_zero(byte *pos, uint length)
|
static my_bool check_if_zero(byte *pos, uint length)
|
||||||
{
|
{
|
||||||
byte *end;
|
byte *end;
|
||||||
@@ -438,7 +508,7 @@ static my_bool check_if_zero(byte *pos, uint length)
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Find free postion in directory
|
Find free position in directory
|
||||||
|
|
||||||
SYNOPSIS
|
SYNOPSIS
|
||||||
find_free_position()
|
find_free_position()
|
||||||
@@ -450,7 +520,7 @@ static my_bool check_if_zero(byte *pos, uint length)
|
|||||||
all empty space, including the found block.
|
all empty space, including the found block.
|
||||||
|
|
||||||
NOTES
|
NOTES
|
||||||
If there is a free directory entry (entry with postion == 0),
|
If there is a free directory entry (entry with position == 0),
|
||||||
then use it and change it to be the size of the empty block
|
then use it and change it to be the size of the empty block
|
||||||
after the previous entry. This guarantees that all row entries
|
after the previous entry. This guarantees that all row entries
|
||||||
are stored on disk in inverse directory order, which makes life easier for
|
are stored on disk in inverse directory order, which makes life easier for
|
||||||
@@ -473,7 +543,7 @@ static my_bool check_if_zero(byte *pos, uint length)
|
|||||||
static byte *find_free_position(byte *buff, uint block_size, uint *res_rownr,
|
static byte *find_free_position(byte *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_ENTRY_OFFSET];
|
uint max_entry= (uint) ((uchar*) buff)[DIR_COUNT_OFFSET];
|
||||||
uint entry, length, first_pos;
|
uint entry, length, first_pos;
|
||||||
byte *dir, *end;
|
byte *dir, *end;
|
||||||
DBUG_ENTER("find_free_position");
|
DBUG_ENTER("find_free_position");
|
||||||
@@ -482,22 +552,23 @@ static byte *find_free_position(byte *buff, uint block_size, uint *res_rownr,
|
|||||||
dir= (buff + block_size - DIR_ENTRY_SIZE * max_entry - PAGE_SUFFIX_SIZE);
|
dir= (buff + block_size - DIR_ENTRY_SIZE * max_entry - PAGE_SUFFIX_SIZE);
|
||||||
end= buff + block_size - PAGE_SUFFIX_SIZE - DIR_ENTRY_SIZE;
|
end= buff + block_size - PAGE_SUFFIX_SIZE - DIR_ENTRY_SIZE;
|
||||||
|
|
||||||
first_pos= PAGE_HEADER_SIZE;
|
|
||||||
*empty_space= uint2korr(buff + EMPTY_SPACE_OFFSET);
|
*empty_space= uint2korr(buff + EMPTY_SPACE_OFFSET);
|
||||||
|
|
||||||
/* Search after first empty position */
|
/* Search after first empty position */
|
||||||
|
first_pos= PAGE_HEADER_SIZE;
|
||||||
for (entry= 0 ; dir <= end ; end-= DIR_ENTRY_SIZE, entry++)
|
for (entry= 0 ; dir <= end ; end-= DIR_ENTRY_SIZE, entry++)
|
||||||
{
|
{
|
||||||
if (end[0] == 0 && end[1] == 0) /* Found not used entry */
|
uint tmp= uint2korr(end);
|
||||||
|
if (!tmp) /* Found not used entry */
|
||||||
{
|
{
|
||||||
length= empty_pos_after_row(end) - first_pos;
|
length= start_of_next_entry(end) - first_pos;
|
||||||
int2store(end, first_pos); /* Update dir entry */
|
int2store(end, first_pos); /* Update dir entry */
|
||||||
int2store(end + 2, length);
|
int2store(end + 2, length);
|
||||||
*res_rownr= entry;
|
*res_rownr= entry;
|
||||||
*res_length= length;
|
*res_length= length;
|
||||||
DBUG_RETURN(end);
|
DBUG_RETURN(end);
|
||||||
}
|
}
|
||||||
first_pos= uint2korr(end) + uint2korr(end + 2);
|
first_pos= tmp + uint2korr(end + 2);
|
||||||
}
|
}
|
||||||
/* No empty places in dir; create a new one */
|
/* No empty places in dir; create a new one */
|
||||||
dir= end;
|
dir= end;
|
||||||
@@ -513,7 +584,7 @@ static byte *find_free_position(byte *buff, uint block_size, uint *res_rownr,
|
|||||||
uint2korr(end + DIR_ENTRY_SIZE+ 2));
|
uint2korr(end + DIR_ENTRY_SIZE+ 2));
|
||||||
*empty_space= uint2korr(buff + EMPTY_SPACE_OFFSET);
|
*empty_space= uint2korr(buff + EMPTY_SPACE_OFFSET);
|
||||||
}
|
}
|
||||||
buff[DIR_ENTRY_OFFSET]= (byte) (uchar) max_entry+1;
|
buff[DIR_COUNT_OFFSET]= (byte) (uchar) max_entry+1;
|
||||||
length= (uint) (dir - buff - first_pos);
|
length= (uint) (dir - buff - first_pos);
|
||||||
DBUG_ASSERT(length <= *empty_space - DIR_ENTRY_SIZE);
|
DBUG_ASSERT(length <= *empty_space - DIR_ENTRY_SIZE);
|
||||||
int2store(dir, first_pos);
|
int2store(dir, first_pos);
|
||||||
@@ -551,7 +622,7 @@ static void calc_record_size(MARIA_HA *info, const byte *record,
|
|||||||
{
|
{
|
||||||
MARIA_SHARE *share= info->s;
|
MARIA_SHARE *share= info->s;
|
||||||
byte *field_length_data;
|
byte *field_length_data;
|
||||||
MARIA_COLUMNDEF *rec, *end_field;
|
MARIA_COLUMNDEF *column, *end_column;
|
||||||
uint *null_field_lengths= row->null_field_lengths;
|
uint *null_field_lengths= row->null_field_lengths;
|
||||||
ulong *blob_lengths= row->blob_lengths;
|
ulong *blob_lengths= row->blob_lengths;
|
||||||
|
|
||||||
@@ -562,56 +633,56 @@ static void calc_record_size(MARIA_HA *info, const byte *record,
|
|||||||
bzero(row->empty_bits_buffer, share->base.pack_bytes);
|
bzero(row->empty_bits_buffer, share->base.pack_bytes);
|
||||||
row->empty_bits= row->empty_bits_buffer;
|
row->empty_bits= row->empty_bits_buffer;
|
||||||
field_length_data= row->field_lengths;
|
field_length_data= row->field_lengths;
|
||||||
for (rec= share->rec + share->base.fixed_not_null_fields,
|
for (column= share->columndef + share->base.fixed_not_null_fields,
|
||||||
end_field= share->rec + share->base.fields;
|
end_column= share->columndef + share->base.fields;
|
||||||
rec < end_field; rec++, null_field_lengths++)
|
column < end_column; column++, null_field_lengths++)
|
||||||
{
|
{
|
||||||
if ((record[rec->null_pos] & rec->null_bit))
|
if ((record[column->null_pos] & column->null_bit))
|
||||||
{
|
{
|
||||||
if (rec->type != FIELD_BLOB)
|
if (column->type != FIELD_BLOB)
|
||||||
*null_field_lengths= 0;
|
*null_field_lengths= 0;
|
||||||
else
|
else
|
||||||
*blob_lengths++= 0;
|
*blob_lengths++= 0;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
switch ((enum en_fieldtype) rec->type) {
|
switch ((enum en_fieldtype) column->type) {
|
||||||
case FIELD_CHECK:
|
case FIELD_CHECK:
|
||||||
case FIELD_NORMAL: /* Fixed length field */
|
case FIELD_NORMAL: /* Fixed length field */
|
||||||
case FIELD_ZERO:
|
case FIELD_ZERO:
|
||||||
DBUG_ASSERT(rec->empty_bit == 0);
|
DBUG_ASSERT(column->empty_bit == 0);
|
||||||
/* fall through */
|
/* fall through */
|
||||||
case FIELD_SKIP_PRESPACE: /* Not packed */
|
case FIELD_SKIP_PRESPACE: /* Not packed */
|
||||||
row->normal_length+= rec->length;
|
row->normal_length+= column->length;
|
||||||
*null_field_lengths= rec->length;
|
*null_field_lengths= column->length;
|
||||||
break;
|
break;
|
||||||
case FIELD_SKIP_ZERO: /* Fixed length field */
|
case FIELD_SKIP_ZERO: /* Fixed length field */
|
||||||
if (memcmp(record+ rec->offset, maria_zero_string,
|
if (memcmp(record+ column->offset, maria_zero_string,
|
||||||
rec->length) == 0)
|
column->length) == 0)
|
||||||
{
|
{
|
||||||
row->empty_bits[rec->empty_pos] |= rec->empty_bit;
|
row->empty_bits[column->empty_pos] |= column->empty_bit;
|
||||||
*null_field_lengths= 0;
|
*null_field_lengths= 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
row->normal_length+= rec->length;
|
row->normal_length+= column->length;
|
||||||
*null_field_lengths= rec->length;
|
*null_field_lengths= column->length;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case FIELD_SKIP_ENDSPACE: /* CHAR */
|
case FIELD_SKIP_ENDSPACE: /* CHAR */
|
||||||
{
|
{
|
||||||
const char *pos, *end;
|
const char *pos, *end;
|
||||||
for (pos= record + rec->offset, end= pos + rec->length;
|
for (pos= record + column->offset, end= pos + column->length;
|
||||||
end > pos && end[-1] == ' '; end--)
|
end > pos && end[-1] == ' '; end--)
|
||||||
;
|
;
|
||||||
if (pos == end) /* If empty string */
|
if (pos == end) /* If empty string */
|
||||||
{
|
{
|
||||||
row->empty_bits[rec->empty_pos]|= rec->empty_bit;
|
row->empty_bits[column->empty_pos]|= column->empty_bit;
|
||||||
*null_field_lengths= 0;
|
*null_field_lengths= 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
uint length= (end - pos);
|
uint length= (end - pos);
|
||||||
if (rec->length <= 255)
|
if (column->length <= 255)
|
||||||
*field_length_data++= (byte) (uchar) length;
|
*field_length_data++= (byte) (uchar) length;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -626,11 +697,11 @@ static void calc_record_size(MARIA_HA *info, const byte *record,
|
|||||||
case FIELD_VARCHAR:
|
case FIELD_VARCHAR:
|
||||||
{
|
{
|
||||||
uint length, field_length_data_length;
|
uint length, field_length_data_length;
|
||||||
const byte *field_pos= record + rec->offset;
|
const byte *field_pos= record + column->offset;
|
||||||
/* 256 is correct as this includes the length byte */
|
/* 256 is correct as this includes the length byte */
|
||||||
|
|
||||||
field_length_data[0]= field_pos[0];
|
field_length_data[0]= field_pos[0];
|
||||||
if (rec->length <= 256)
|
if (column->length <= 256)
|
||||||
{
|
{
|
||||||
length= (uint) (uchar) *field_pos;
|
length= (uint) (uchar) *field_pos;
|
||||||
field_length_data_length= 1;
|
field_length_data_length= 1;
|
||||||
@@ -644,7 +715,7 @@ static void calc_record_size(MARIA_HA *info, const byte *record,
|
|||||||
*null_field_lengths= length;
|
*null_field_lengths= length;
|
||||||
if (!length)
|
if (!length)
|
||||||
{
|
{
|
||||||
row->empty_bits[rec->empty_pos]|= rec->empty_bit;
|
row->empty_bits[column->empty_pos]|= column->empty_bit;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
row->varchar_length+= length;
|
row->varchar_length+= length;
|
||||||
@@ -654,13 +725,13 @@ static void calc_record_size(MARIA_HA *info, const byte *record,
|
|||||||
}
|
}
|
||||||
case FIELD_BLOB:
|
case FIELD_BLOB:
|
||||||
{
|
{
|
||||||
const byte *field_pos= record + rec->offset;
|
const byte *field_pos= record + column->offset;
|
||||||
uint size_length= rec->length - maria_portable_sizeof_char_ptr;
|
uint size_length= column->length - portable_sizeof_char_ptr;
|
||||||
ulong blob_length= _ma_calc_blob_length(size_length, field_pos);
|
ulong blob_length= _ma_calc_blob_length(size_length, field_pos);
|
||||||
|
|
||||||
*blob_lengths++= blob_length;
|
*blob_lengths++= blob_length;
|
||||||
if (!blob_length)
|
if (!blob_length)
|
||||||
row->empty_bits[rec->empty_pos]|= rec->empty_bit;
|
row->empty_bits[column->empty_pos]|= column->empty_bit;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
row->blob_length+= blob_length;
|
row->blob_length+= blob_length;
|
||||||
@@ -709,7 +780,7 @@ static void calc_record_size(MARIA_HA *info, const byte *record,
|
|||||||
static void compact_page(byte *buff, uint block_size, uint rownr,
|
static void compact_page(byte *buff, uint block_size, uint rownr,
|
||||||
my_bool extend_block)
|
my_bool extend_block)
|
||||||
{
|
{
|
||||||
uint max_entry= (uint) ((uchar *) buff)[DIR_ENTRY_OFFSET];
|
uint max_entry= (uint) ((uchar *) buff)[DIR_COUNT_OFFSET];
|
||||||
uint page_pos, next_free_pos, start_of_found_block, diff, end_of_found_block;
|
uint page_pos, next_free_pos, start_of_found_block, diff, end_of_found_block;
|
||||||
byte *dir, *end;
|
byte *dir, *end;
|
||||||
DBUG_ENTER("compact_page");
|
DBUG_ENTER("compact_page");
|
||||||
@@ -875,7 +946,7 @@ static my_bool get_head_or_tail_page(MARIA_HA *info,
|
|||||||
bzero(buff+ PAGE_HEADER_SIZE, block_size - PAGE_HEADER_SIZE);
|
bzero(buff+ PAGE_HEADER_SIZE, block_size - PAGE_HEADER_SIZE);
|
||||||
|
|
||||||
buff[PAGE_TYPE_OFFSET]= (byte) page_type;
|
buff[PAGE_TYPE_OFFSET]= (byte) page_type;
|
||||||
buff[DIR_ENTRY_OFFSET]= 1;
|
buff[DIR_COUNT_OFFSET]= 1;
|
||||||
res->buff= buff;
|
res->buff= buff;
|
||||||
res->empty_space= res->length= (block_size - PAGE_OVERHEAD_SIZE);
|
res->empty_space= res->length= (block_size - PAGE_OVERHEAD_SIZE);
|
||||||
res->data= (buff + PAGE_HEADER_SIZE);
|
res->data= (buff + PAGE_HEADER_SIZE);
|
||||||
@@ -956,12 +1027,18 @@ static my_bool write_tail(MARIA_HA *info,
|
|||||||
DBUG_PRINT("enter", ("page: %lu length: %u",
|
DBUG_PRINT("enter", ("page: %lu length: %u",
|
||||||
(ulong) block->page, length));
|
(ulong) block->page, length));
|
||||||
|
|
||||||
info->keybuff_used= 1;
|
info->keyread_buff_used= 1;
|
||||||
if (get_head_or_tail_page(info, block, info->keyread_buff, length,
|
if (get_head_or_tail_page(info, block, info->keyread_buff, length,
|
||||||
TAIL_PAGE, &row_pos))
|
TAIL_PAGE, &row_pos))
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
|
|
||||||
memcpy(row_pos.data, row_part, length);
|
memcpy(row_pos.data, row_part, length);
|
||||||
|
/*
|
||||||
|
Don't allocate smaller block than MIN_TAIL_SIZE (we want to give rows
|
||||||
|
some place to grow in the future)
|
||||||
|
*/
|
||||||
|
if (length < MIN_TAIL_SIZE)
|
||||||
|
length= MIN_TAIL_SIZE;
|
||||||
int2store(row_pos.dir + 2, length);
|
int2store(row_pos.dir + 2, length);
|
||||||
empty_space= row_pos.empty_space - length;
|
empty_space= row_pos.empty_space - length;
|
||||||
int2store(row_pos.buff + EMPTY_SPACE_OFFSET, empty_space);
|
int2store(row_pos.buff + EMPTY_SPACE_OFFSET, empty_space);
|
||||||
@@ -969,10 +1046,10 @@ static my_bool write_tail(MARIA_HA *info,
|
|||||||
/*
|
/*
|
||||||
If there is less directory entries free than number of possible tails
|
If there is less directory entries free than number of possible tails
|
||||||
we can write for a row, we mark the page full to ensure that we don't
|
we can write for a row, we mark the page full to ensure that we don't
|
||||||
during _ma_bitmap_find_place() allocate more entires on the tail page
|
during _ma_bitmap_find_place() allocate more entries on the tail page
|
||||||
than it can hold
|
than it can hold
|
||||||
*/
|
*/
|
||||||
block->empty_space= ((uint) ((uchar*) row_pos.buff)[DIR_ENTRY_OFFSET] <=
|
block->empty_space= ((uint) ((uchar*) row_pos.buff)[DIR_COUNT_OFFSET] <=
|
||||||
MAX_ROWS_PER_PAGE - 1 - info->s->base.blobs ?
|
MAX_ROWS_PER_PAGE - 1 - info->s->base.blobs ?
|
||||||
empty_space : 0);
|
empty_space : 0);
|
||||||
block->used= BLOCKUSED_USED | BLOCKUSED_TAIL;
|
block->used= BLOCKUSED_USED | BLOCKUSED_TAIL;
|
||||||
@@ -1015,7 +1092,7 @@ static my_bool write_full_pages(MARIA_HA *info,
|
|||||||
(ulong) length, (ulong) block->page,
|
(ulong) length, (ulong) block->page,
|
||||||
(ulong) block->page_count));
|
(ulong) block->page_count));
|
||||||
|
|
||||||
info->keybuff_used= 1;
|
info->keyread_buff_used= 1;
|
||||||
page= block->page;
|
page= block->page;
|
||||||
page_count= block->page_count;
|
page_count= block->page_count;
|
||||||
|
|
||||||
@@ -1134,7 +1211,7 @@ static my_bool write_block_record(MARIA_HA *info, const byte *record,
|
|||||||
byte *page_buff;
|
byte *page_buff;
|
||||||
MARIA_BITMAP_BLOCK *block, *head_block;
|
MARIA_BITMAP_BLOCK *block, *head_block;
|
||||||
MARIA_SHARE *share;
|
MARIA_SHARE *share;
|
||||||
MARIA_COLUMNDEF *rec, *end_field;
|
MARIA_COLUMNDEF *column, *end_column;
|
||||||
uint block_size, flag;
|
uint block_size, flag;
|
||||||
ulong *blob_lengths;
|
ulong *blob_lengths;
|
||||||
my_off_t position;
|
my_off_t position;
|
||||||
@@ -1219,16 +1296,17 @@ static my_bool write_block_record(MARIA_HA *info, const byte *record,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Copy fields that has fixed lengths (primary key etc) */
|
/* Copy fields that has fixed lengths (primary key etc) */
|
||||||
for (rec= share->rec, end_field= rec + share->base.fixed_not_null_fields;
|
for (column= share->columndef,
|
||||||
rec < end_field; rec++)
|
end_column= column + share->base.fixed_not_null_fields;
|
||||||
|
column < end_column; column++)
|
||||||
{
|
{
|
||||||
if (!tmp_data_used && tmp_data + rec->length > end_of_data)
|
if (!tmp_data_used && tmp_data + column->length > end_of_data)
|
||||||
{
|
{
|
||||||
tmp_data_used= tmp_data;
|
tmp_data_used= tmp_data;
|
||||||
tmp_data= info->rec_buff;
|
tmp_data= info->rec_buff;
|
||||||
}
|
}
|
||||||
memcpy(tmp_data, record + rec->offset, rec->length);
|
memcpy(tmp_data, record + column->offset, column->length);
|
||||||
tmp_data+= rec->length;
|
tmp_data+= column->length;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Copy length of data for variable length fields */
|
/* Copy length of data for variable length fields */
|
||||||
@@ -1242,26 +1320,26 @@ static my_bool write_block_record(MARIA_HA *info, const byte *record,
|
|||||||
tmp_data+= row->field_lengths_length;
|
tmp_data+= row->field_lengths_length;
|
||||||
|
|
||||||
/* Copy variable length fields and fields with null/zero */
|
/* Copy variable length fields and fields with null/zero */
|
||||||
for (end_field= share->rec + share->base.fields - share->base.blobs;
|
for (end_column= share->columndef + share->base.fields - share->base.blobs;
|
||||||
rec < end_field ;
|
column < end_column ;
|
||||||
rec++)
|
column++)
|
||||||
{
|
{
|
||||||
const byte *field_pos;
|
const byte *field_pos;
|
||||||
ulong length;
|
ulong length;
|
||||||
if ((record[rec->null_pos] & rec->null_bit) ||
|
if ((record[column->null_pos] & column->null_bit) ||
|
||||||
(row->empty_bits[rec->empty_pos] & rec->empty_bit))
|
(row->empty_bits[column->empty_pos] & column->empty_bit))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
field_pos= record + rec->offset;
|
field_pos= record + column->offset;
|
||||||
switch ((enum en_fieldtype) rec->type) {
|
switch ((enum en_fieldtype) column->type) {
|
||||||
case FIELD_NORMAL: /* Fixed length field */
|
case FIELD_NORMAL: /* Fixed length field */
|
||||||
case FIELD_SKIP_PRESPACE:
|
case FIELD_SKIP_PRESPACE:
|
||||||
case FIELD_SKIP_ZERO: /* Fixed length field */
|
case FIELD_SKIP_ZERO: /* Fixed length field */
|
||||||
length= rec->length;
|
length= column->length;
|
||||||
break;
|
break;
|
||||||
case FIELD_SKIP_ENDSPACE: /* CHAR */
|
case FIELD_SKIP_ENDSPACE: /* CHAR */
|
||||||
/* Char that is space filled */
|
/* Char that is space filled */
|
||||||
if (rec->length <= 255)
|
if (column->length <= 255)
|
||||||
length= (uint) (uchar) *field_length_data++;
|
length= (uint) (uchar) *field_length_data++;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -1270,7 +1348,7 @@ static my_bool write_block_record(MARIA_HA *info, const byte *record,
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case FIELD_VARCHAR:
|
case FIELD_VARCHAR:
|
||||||
if (rec->length <= 256)
|
if (column->length <= 256)
|
||||||
{
|
{
|
||||||
length= (uint) (uchar) *field_length_data++;
|
length= (uint) (uchar) *field_length_data++;
|
||||||
field_pos++; /* Skip length byte */
|
field_pos++; /* Skip length byte */
|
||||||
@@ -1298,21 +1376,21 @@ static my_bool write_block_record(MARIA_HA *info, const byte *record,
|
|||||||
|
|
||||||
block= head_block + head_block->sub_blocks; /* Point to first blob data */
|
block= head_block + head_block->sub_blocks; /* Point to first blob data */
|
||||||
|
|
||||||
end_field= rec + share->base.blobs;
|
end_column= column + share->base.blobs;
|
||||||
blob_lengths= row->blob_lengths;
|
blob_lengths= row->blob_lengths;
|
||||||
if (!tmp_data_used)
|
if (!tmp_data_used)
|
||||||
{
|
{
|
||||||
/* Still room on page; Copy as many blobs we can into this page */
|
/* Still room on page; Copy as many blobs we can into this page */
|
||||||
data= tmp_data;
|
data= tmp_data;
|
||||||
for (; rec < end_field && *blob_lengths < (ulong) (end_of_data - data);
|
for (; column < end_column && *blob_lengths < (ulong) (end_of_data - data);
|
||||||
rec++, blob_lengths++)
|
column++, blob_lengths++)
|
||||||
{
|
{
|
||||||
byte *tmp_pos;
|
byte *tmp_pos;
|
||||||
uint length;
|
uint length;
|
||||||
if (!*blob_lengths) /* Null or "" */
|
if (!*blob_lengths) /* Null or "" */
|
||||||
continue;
|
continue;
|
||||||
length= rec->length - maria_portable_sizeof_char_ptr;
|
length= column->length - portable_sizeof_char_ptr;
|
||||||
memcpy_fixed((byte*) &tmp_pos, record + rec->offset + length,
|
memcpy_fixed((byte*) &tmp_pos, record + column->offset + length,
|
||||||
sizeof(char*));
|
sizeof(char*));
|
||||||
memcpy(data, tmp_pos, *blob_lengths);
|
memcpy(data, tmp_pos, *blob_lengths);
|
||||||
data+= *blob_lengths;
|
data+= *blob_lengths;
|
||||||
@@ -1342,7 +1420,7 @@ static my_bool write_block_record(MARIA_HA *info, const byte *record,
|
|||||||
int2store(page_buff + EMPTY_SPACE_OFFSET, row_pos->empty_space);
|
int2store(page_buff + EMPTY_SPACE_OFFSET, row_pos->empty_space);
|
||||||
/* Mark in bitmaps how the current page was actually used */
|
/* Mark in bitmaps how the current page was actually used */
|
||||||
head_block->empty_space= row_pos->empty_space;
|
head_block->empty_space= row_pos->empty_space;
|
||||||
if (page_buff[DIR_ENTRY_OFFSET] == (char) MAX_ROWS_PER_PAGE)
|
if (page_buff[DIR_COUNT_OFFSET] == (char) MAX_ROWS_PER_PAGE)
|
||||||
head_block->empty_space= 0; /* Page is full */
|
head_block->empty_space= 0; /* Page is full */
|
||||||
head_block->used= BLOCKUSED_USED;
|
head_block->used= BLOCKUSED_USED;
|
||||||
}
|
}
|
||||||
@@ -1362,14 +1440,14 @@ static my_bool write_block_record(MARIA_HA *info, const byte *record,
|
|||||||
|
|
||||||
if (row_extents_in_use)
|
if (row_extents_in_use)
|
||||||
{
|
{
|
||||||
if (rec != end_field) /* If blob fields */
|
if (column != end_column) /* If blob fields */
|
||||||
{
|
{
|
||||||
MARIA_COLUMNDEF *save_rec= rec;
|
MARIA_COLUMNDEF *save_column= column;
|
||||||
MARIA_BITMAP_BLOCK *save_block= block;
|
MARIA_BITMAP_BLOCK *save_block= block;
|
||||||
MARIA_BITMAP_BLOCK *end_block;
|
MARIA_BITMAP_BLOCK *end_block;
|
||||||
ulong *save_blob_lengths= blob_lengths;
|
ulong *save_blob_lengths= blob_lengths;
|
||||||
|
|
||||||
for (; rec < end_field; rec++, blob_lengths++)
|
for (; column < end_column; column++, blob_lengths++)
|
||||||
{
|
{
|
||||||
byte *blob_pos;
|
byte *blob_pos;
|
||||||
if (!*blob_lengths) /* Null or "" */
|
if (!*blob_lengths) /* Null or "" */
|
||||||
@@ -1377,8 +1455,8 @@ static my_bool write_block_record(MARIA_HA *info, const byte *record,
|
|||||||
if (block[block->sub_blocks - 1].used & BLOCKUSED_TAIL)
|
if (block[block->sub_blocks - 1].used & BLOCKUSED_TAIL)
|
||||||
{
|
{
|
||||||
uint length;
|
uint length;
|
||||||
length= rec->length - maria_portable_sizeof_char_ptr;
|
length= column->length - portable_sizeof_char_ptr;
|
||||||
memcpy_fixed((byte *) &blob_pos, record + rec->offset + length,
|
memcpy_fixed((byte *) &blob_pos, record + column->offset + length,
|
||||||
sizeof(char*));
|
sizeof(char*));
|
||||||
length= *blob_lengths % FULL_PAGE_SIZE(block_size); /* tail size */
|
length= *blob_lengths % FULL_PAGE_SIZE(block_size); /* tail size */
|
||||||
if (write_tail(info, block + block->sub_blocks-1,
|
if (write_tail(info, block + block->sub_blocks-1,
|
||||||
@@ -1395,7 +1473,7 @@ static my_bool write_block_record(MARIA_HA *info, const byte *record,
|
|||||||
block->used|= BLOCKUSED_USED;
|
block->used|= BLOCKUSED_USED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
rec= save_rec;
|
column= save_column;
|
||||||
block= save_block;
|
block= save_block;
|
||||||
blob_lengths= save_blob_lengths;
|
blob_lengths= save_blob_lengths;
|
||||||
}
|
}
|
||||||
@@ -1593,15 +1671,15 @@ static my_bool write_block_record(MARIA_HA *info, const byte *record,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Write rest of blobs (data, but no tails as they are already written) */
|
/* Write rest of blobs (data, but no tails as they are already written) */
|
||||||
for (; rec < end_field; rec++, blob_lengths++)
|
for (; column < end_column; column++, blob_lengths++)
|
||||||
{
|
{
|
||||||
byte *blob_pos;
|
byte *blob_pos;
|
||||||
uint length;
|
uint length;
|
||||||
ulong blob_length;
|
ulong blob_length;
|
||||||
if (!*blob_lengths) /* Null or "" */
|
if (!*blob_lengths) /* Null or "" */
|
||||||
continue;
|
continue;
|
||||||
length= rec->length - maria_portable_sizeof_char_ptr;
|
length= column->length - portable_sizeof_char_ptr;
|
||||||
memcpy_fixed((byte*) &blob_pos, record + rec->offset + length,
|
memcpy_fixed((byte*) &blob_pos, record + column->offset + length,
|
||||||
sizeof(char*));
|
sizeof(char*));
|
||||||
/* remove tail part */
|
/* remove tail part */
|
||||||
blob_length= *blob_lengths;
|
blob_length= *blob_lengths;
|
||||||
@@ -1705,7 +1783,7 @@ my_bool _ma_write_abort_block_record(MARIA_HA *info)
|
|||||||
|
|
||||||
if (delete_head_or_tail(info,
|
if (delete_head_or_tail(info,
|
||||||
ma_recordpos_to_page(info->cur_row.lastpos),
|
ma_recordpos_to_page(info->cur_row.lastpos),
|
||||||
ma_recordpos_to_offset(info->cur_row.lastpos), 1))
|
ma_recordpos_to_dir_entry(info->cur_row.lastpos), 1))
|
||||||
res= 1;
|
res= 1;
|
||||||
for (block= blocks->block + 1, end= block + blocks->count - 1; block < end;
|
for (block= blocks->block + 1, end= block + blocks->count - 1; block < end;
|
||||||
block++)
|
block++)
|
||||||
@@ -1764,7 +1842,7 @@ my_bool _ma_update_block_record(MARIA_HA *info, MARIA_RECORD_POS record_pos,
|
|||||||
info->buff, block_size, block_size, 0)))
|
info->buff, block_size, block_size, 0)))
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
org_empty_size= uint2korr(buff + EMPTY_SPACE_OFFSET);
|
org_empty_size= uint2korr(buff + EMPTY_SPACE_OFFSET);
|
||||||
rownr= ma_recordpos_to_offset(record_pos);
|
rownr= ma_recordpos_to_dir_entry(record_pos);
|
||||||
dir= (buff + block_size - DIR_ENTRY_SIZE * rownr -
|
dir= (buff + block_size - DIR_ENTRY_SIZE * rownr -
|
||||||
DIR_ENTRY_SIZE - PAGE_SUFFIX_SIZE);
|
DIR_ENTRY_SIZE - PAGE_SUFFIX_SIZE);
|
||||||
|
|
||||||
@@ -1785,8 +1863,8 @@ my_bool _ma_update_block_record(MARIA_HA *info, MARIA_RECORD_POS record_pos,
|
|||||||
if (new_row->total_length > length)
|
if (new_row->total_length > length)
|
||||||
{
|
{
|
||||||
/* See if there is empty space after */
|
/* See if there is empty space after */
|
||||||
if (rownr != (uint) ((uchar *) buff)[DIR_ENTRY_OFFSET] - 1)
|
if (rownr != (uint) ((uchar *) buff)[DIR_COUNT_OFFSET] - 1)
|
||||||
empty= empty_pos_after_row(dir) - (offset + length);
|
empty= start_of_next_entry(dir) - (offset + length);
|
||||||
if (new_row->total_length > length + empty)
|
if (new_row->total_length > length + empty)
|
||||||
{
|
{
|
||||||
compact_page(buff, info->s->block_size, rownr, 1);
|
compact_page(buff, info->s->block_size, rownr, 1);
|
||||||
@@ -1876,14 +1954,14 @@ static my_bool delete_head_or_tail(MARIA_HA *info,
|
|||||||
my_off_t position;
|
my_off_t position;
|
||||||
DBUG_ENTER("delete_head_or_tail");
|
DBUG_ENTER("delete_head_or_tail");
|
||||||
|
|
||||||
info->keybuff_used= 1;
|
info->keyread_buff_used= 1;
|
||||||
if (!(buff= key_cache_read(share->key_cache,
|
if (!(buff= key_cache_read(share->key_cache,
|
||||||
info->dfile, page * block_size, 0,
|
info->dfile, page * block_size, 0,
|
||||||
info->keyread_buff,
|
info->keyread_buff,
|
||||||
block_size, block_size, 0)))
|
block_size, block_size, 0)))
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
|
|
||||||
number_of_records= (uint) ((uchar *) buff)[DIR_ENTRY_OFFSET];
|
number_of_records= (uint) ((uchar *) buff)[DIR_COUNT_OFFSET];
|
||||||
#ifdef SANITY_CHECKS
|
#ifdef SANITY_CHECKS
|
||||||
if (record_number >= number_of_records ||
|
if (record_number >= number_of_records ||
|
||||||
record_number > ((block_size - LSN_SIZE - PAGE_TYPE_SIZE - 1 -
|
record_number > ((block_size - LSN_SIZE - PAGE_TYPE_SIZE - 1 -
|
||||||
@@ -1911,7 +1989,7 @@ static my_bool delete_head_or_tail(MARIA_HA *info,
|
|||||||
dir+= DIR_ENTRY_SIZE;
|
dir+= DIR_ENTRY_SIZE;
|
||||||
empty_space+= DIR_ENTRY_SIZE;
|
empty_space+= DIR_ENTRY_SIZE;
|
||||||
} while (dir < end && dir[0] == 0 && dir[1] == 0);
|
} while (dir < end && dir[0] == 0 && dir[1] == 0);
|
||||||
buff[DIR_ENTRY_OFFSET]= (byte) (uchar) number_of_records;
|
buff[DIR_COUNT_OFFSET]= (byte) (uchar) number_of_records;
|
||||||
}
|
}
|
||||||
empty_space+= length;
|
empty_space+= length;
|
||||||
if (number_of_records != 0)
|
if (number_of_records != 0)
|
||||||
@@ -1957,7 +2035,7 @@ static my_bool delete_tails(MARIA_HA *info, MARIA_RECORD_POS *tails)
|
|||||||
{
|
{
|
||||||
if (delete_head_or_tail(info,
|
if (delete_head_or_tail(info,
|
||||||
ma_recordpos_to_page(*tails),
|
ma_recordpos_to_page(*tails),
|
||||||
ma_recordpos_to_offset(*tails), 0))
|
ma_recordpos_to_dir_entry(*tails), 0))
|
||||||
res= 1;
|
res= 1;
|
||||||
}
|
}
|
||||||
DBUG_RETURN(res);
|
DBUG_RETURN(res);
|
||||||
@@ -1978,7 +2056,7 @@ my_bool _ma_delete_block_record(MARIA_HA *info)
|
|||||||
DBUG_ENTER("_ma_delete_block_record");
|
DBUG_ENTER("_ma_delete_block_record");
|
||||||
if (delete_head_or_tail(info,
|
if (delete_head_or_tail(info,
|
||||||
ma_recordpos_to_page(info->cur_row.lastpos),
|
ma_recordpos_to_page(info->cur_row.lastpos),
|
||||||
ma_recordpos_to_offset(info->cur_row.lastpos),
|
ma_recordpos_to_dir_entry(info->cur_row.lastpos),
|
||||||
1) ||
|
1) ||
|
||||||
delete_tails(info, info->cur_row.tail_positions))
|
delete_tails(info, info->cur_row.tail_positions))
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
@@ -2011,7 +2089,7 @@ my_bool _ma_delete_block_record(MARIA_HA *info)
|
|||||||
static byte *get_record_position(byte *buff, uint block_size,
|
static byte *get_record_position(byte *buff, uint block_size,
|
||||||
uint record_number, byte **end_of_data)
|
uint record_number, byte **end_of_data)
|
||||||
{
|
{
|
||||||
uint number_of_records= (uint) ((uchar *) buff)[DIR_ENTRY_OFFSET];
|
uint number_of_records= (uint) ((uchar *) buff)[DIR_COUNT_OFFSET];
|
||||||
byte *dir;
|
byte *dir;
|
||||||
byte *data;
|
byte *data;
|
||||||
uint offset, length;
|
uint offset, length;
|
||||||
@@ -2254,7 +2332,7 @@ int _ma_read_block_record2(MARIA_HA *info, byte *record,
|
|||||||
uint flag, null_bytes, cur_null_bytes, row_extents, field_lengths;
|
uint flag, null_bytes, cur_null_bytes, row_extents, field_lengths;
|
||||||
my_bool found_blob= 0;
|
my_bool found_blob= 0;
|
||||||
MARIA_EXTENT_CURSOR extent;
|
MARIA_EXTENT_CURSOR extent;
|
||||||
MARIA_COLUMNDEF *rec, *end_field;
|
MARIA_COLUMNDEF *column, *end_column;
|
||||||
DBUG_ENTER("_ma_read_block_record2");
|
DBUG_ENTER("_ma_read_block_record2");
|
||||||
|
|
||||||
LINT_INIT(field_lengths);
|
LINT_INIT(field_lengths);
|
||||||
@@ -2347,15 +2425,16 @@ int _ma_read_block_record2(MARIA_HA *info, byte *record,
|
|||||||
Data now points to start of fixed length field data that can't be null
|
Data now points to start of fixed length field data that can't be null
|
||||||
or 'empty'. Note that these fields can't be split over blocks
|
or 'empty'. Note that these fields can't be split over blocks
|
||||||
*/
|
*/
|
||||||
for (rec= share->rec, end_field= rec + share->base.fixed_not_null_fields;
|
for (column= share->columndef,
|
||||||
rec < end_field; rec++)
|
end_column= column + share->base.fixed_not_null_fields;
|
||||||
|
column < end_column; column++)
|
||||||
{
|
{
|
||||||
uint rec_length= rec->length;
|
uint column_length= column->length;
|
||||||
if (data >= end_of_data &&
|
if (data >= end_of_data &&
|
||||||
!(data= read_next_extent(info, &extent, &end_of_data)))
|
!(data= read_next_extent(info, &extent, &end_of_data)))
|
||||||
goto err;
|
goto err;
|
||||||
memcpy(record + rec->offset, data, rec_length);
|
memcpy(record + column->offset, data, column_length);
|
||||||
data+= rec_length;
|
data+= column_length;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read array of field lengths. This may be stored in several extents */
|
/* Read array of field lengths. This may be stored in several extents */
|
||||||
@@ -2368,18 +2447,19 @@ int _ma_read_block_record2(MARIA_HA *info, byte *record,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Read variable length data. Each of these may be split over many extents */
|
/* Read variable length data. Each of these may be split over many extents */
|
||||||
for (end_field= share->rec + share->base.fields; rec < end_field; rec++)
|
for (end_column= share->columndef + share->base.fields;
|
||||||
|
column < end_column; column++)
|
||||||
{
|
{
|
||||||
enum en_fieldtype type= (enum en_fieldtype) rec->type;
|
enum en_fieldtype type= (enum en_fieldtype) column->type;
|
||||||
byte *field_pos= record + rec->offset;
|
byte *field_pos= record + column->offset;
|
||||||
/* First check if field is present in record */
|
/* First check if field is present in record */
|
||||||
if ((record[rec->null_pos] & rec->null_bit) ||
|
if ((record[column->null_pos] & column->null_bit) ||
|
||||||
(info->cur_row.empty_bits[rec->empty_pos] & rec->empty_bit))
|
(info->cur_row.empty_bits[column->empty_pos] & column->empty_bit))
|
||||||
{
|
{
|
||||||
if (type == FIELD_SKIP_ENDSPACE)
|
if (type == FIELD_SKIP_ENDSPACE)
|
||||||
bfill(record + rec->offset, rec->length, ' ');
|
bfill(record + column->offset, column->length, ' ');
|
||||||
else
|
else
|
||||||
bzero(record + rec->offset, rec->fill_length);
|
bzero(record + column->offset, column->fill_length);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
switch (type) {
|
switch (type) {
|
||||||
@@ -2389,14 +2469,14 @@ int _ma_read_block_record2(MARIA_HA *info, byte *record,
|
|||||||
if (data >= end_of_data &&
|
if (data >= end_of_data &&
|
||||||
!(data= read_next_extent(info, &extent, &end_of_data)))
|
!(data= read_next_extent(info, &extent, &end_of_data)))
|
||||||
goto err;
|
goto err;
|
||||||
memcpy(field_pos, data, rec->length);
|
memcpy(field_pos, data, column->length);
|
||||||
data+= rec->length;
|
data+= column->length;
|
||||||
break;
|
break;
|
||||||
case FIELD_SKIP_ENDSPACE: /* CHAR */
|
case FIELD_SKIP_ENDSPACE: /* CHAR */
|
||||||
{
|
{
|
||||||
/* Char that is space filled */
|
/* Char that is space filled */
|
||||||
uint length;
|
uint length;
|
||||||
if (rec->length <= 255)
|
if (column->length <= 255)
|
||||||
length= (uint) (uchar) *field_length_data++;
|
length= (uint) (uchar) *field_length_data++;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -2404,19 +2484,19 @@ int _ma_read_block_record2(MARIA_HA *info, byte *record,
|
|||||||
field_length_data+= 2;
|
field_length_data+= 2;
|
||||||
}
|
}
|
||||||
#ifdef SANITY_CHECKS
|
#ifdef SANITY_CHECKS
|
||||||
if (length > rec->length)
|
if (length > column->length)
|
||||||
goto err;
|
goto err;
|
||||||
#endif
|
#endif
|
||||||
if (read_long_data(info, field_pos, length, &extent, &data,
|
if (read_long_data(info, field_pos, length, &extent, &data,
|
||||||
&end_of_data))
|
&end_of_data))
|
||||||
DBUG_RETURN(my_errno);
|
DBUG_RETURN(my_errno);
|
||||||
bfill(field_pos + length, rec->length - length, ' ');
|
bfill(field_pos + length, column->length - length, ' ');
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case FIELD_VARCHAR:
|
case FIELD_VARCHAR:
|
||||||
{
|
{
|
||||||
ulong length;
|
ulong length;
|
||||||
if (rec->length <= 256)
|
if (column->length <= 256)
|
||||||
{
|
{
|
||||||
length= (uint) (uchar) (*field_pos++= *field_length_data++);
|
length= (uint) (uchar) (*field_pos++= *field_length_data++);
|
||||||
}
|
}
|
||||||
@@ -2435,7 +2515,7 @@ int _ma_read_block_record2(MARIA_HA *info, byte *record,
|
|||||||
}
|
}
|
||||||
case FIELD_BLOB:
|
case FIELD_BLOB:
|
||||||
{
|
{
|
||||||
uint size_length= rec->length - maria_portable_sizeof_char_ptr;
|
uint size_length= column->length - portable_sizeof_char_ptr;
|
||||||
ulong blob_length= _ma_calc_blob_length(size_length, field_length_data);
|
ulong blob_length= _ma_calc_blob_length(size_length, field_length_data);
|
||||||
|
|
||||||
if (!found_blob)
|
if (!found_blob)
|
||||||
@@ -2443,17 +2523,17 @@ int _ma_read_block_record2(MARIA_HA *info, byte *record,
|
|||||||
/* Calculate total length for all blobs */
|
/* Calculate total length for all blobs */
|
||||||
ulong blob_lengths= 0;
|
ulong blob_lengths= 0;
|
||||||
byte *length_data= field_length_data;
|
byte *length_data= field_length_data;
|
||||||
MARIA_COLUMNDEF *blob_field= rec;
|
MARIA_COLUMNDEF *blob_field= column;
|
||||||
|
|
||||||
found_blob= 1;
|
found_blob= 1;
|
||||||
for (; blob_field < end_field; blob_field++)
|
for (; blob_field < end_column; blob_field++)
|
||||||
{
|
{
|
||||||
uint size_length;
|
uint size_length;
|
||||||
if ((record[blob_field->null_pos] & blob_field->null_bit) ||
|
if ((record[blob_field->null_pos] & blob_field->null_bit) ||
|
||||||
(info->cur_row.empty_bits[blob_field->empty_pos] &
|
(info->cur_row.empty_bits[blob_field->empty_pos] &
|
||||||
blob_field->empty_bit))
|
blob_field->empty_bit))
|
||||||
continue;
|
continue;
|
||||||
size_length= blob_field->length - maria_portable_sizeof_char_ptr;
|
size_length= blob_field->length - portable_sizeof_char_ptr;
|
||||||
blob_lengths+= _ma_calc_blob_length(size_length, length_data);
|
blob_lengths+= _ma_calc_blob_length(size_length, length_data);
|
||||||
length_data+= size_length;
|
length_data+= size_length;
|
||||||
}
|
}
|
||||||
@@ -2547,7 +2627,7 @@ int _ma_read_block_record(MARIA_HA *info, byte *record,
|
|||||||
|
|
||||||
info->cur_row.lastpos= record_pos;
|
info->cur_row.lastpos= record_pos;
|
||||||
page= ma_recordpos_to_page(record_pos) * block_size;
|
page= ma_recordpos_to_page(record_pos) * block_size;
|
||||||
offset= ma_recordpos_to_offset(record_pos);
|
offset= ma_recordpos_to_dir_entry(record_pos);
|
||||||
|
|
||||||
if (!(buff= key_cache_read(info->s->key_cache,
|
if (!(buff= key_cache_read(info->s->key_cache,
|
||||||
info->dfile, page, 0, info->buff,
|
info->dfile, page, 0, info->buff,
|
||||||
@@ -2754,7 +2834,7 @@ restart_bitmap_scan:
|
|||||||
if (((info->scan.page_buff[PAGE_TYPE_OFFSET] & PAGE_TYPE_MASK) !=
|
if (((info->scan.page_buff[PAGE_TYPE_OFFSET] & PAGE_TYPE_MASK) !=
|
||||||
HEAD_PAGE) ||
|
HEAD_PAGE) ||
|
||||||
(info->scan.number_of_rows=
|
(info->scan.number_of_rows=
|
||||||
(uint) (uchar) info->scan.page_buff[DIR_ENTRY_OFFSET]) == 0)
|
(uint) (uchar) info->scan.page_buff[DIR_COUNT_OFFSET]) == 0)
|
||||||
{
|
{
|
||||||
DBUG_PRINT("error", ("Wrong page header"));
|
DBUG_PRINT("error", ("Wrong page header"));
|
||||||
DBUG_RETURN((my_errno= HA_ERR_WRONG_IN_RECORD));
|
DBUG_RETURN((my_errno= HA_ERR_WRONG_IN_RECORD));
|
||||||
@@ -2818,7 +2898,7 @@ my_bool _ma_compare_block_record(MARIA_HA *info __attribute__ ((unused)),
|
|||||||
|
|
||||||
static void _ma_print_directory(byte *buff, uint block_size)
|
static void _ma_print_directory(byte *buff, uint block_size)
|
||||||
{
|
{
|
||||||
uint max_entry= (uint) ((uchar *) buff)[DIR_ENTRY_OFFSET], row= 0;
|
uint max_entry= (uint) ((uchar *) buff)[DIR_COUNT_OFFSET], row= 0;
|
||||||
uint end_of_prev_row= PAGE_HEADER_SIZE;
|
uint end_of_prev_row= PAGE_HEADER_SIZE;
|
||||||
byte *dir, *end;
|
byte *dir, *end;
|
||||||
|
|
||||||
|
@@ -18,11 +18,11 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#define LSN_SIZE 7
|
#define LSN_SIZE 7
|
||||||
#define DIRCOUNT_SIZE 1 /* Stores number of rows on page */
|
#define DIR_COUNT_SIZE 1 /* Stores number of rows on page */
|
||||||
#define EMPTY_SPACE_SIZE 2 /* Stores empty space on page */
|
#define EMPTY_SPACE_SIZE 2 /* Stores empty space on page */
|
||||||
#define PAGE_TYPE_SIZE 1
|
#define PAGE_TYPE_SIZE 1
|
||||||
#define PAGE_SUFFIX_SIZE 0 /* Bytes for page suffix */
|
#define PAGE_SUFFIX_SIZE 0 /* Bytes for page suffix */
|
||||||
#define PAGE_HEADER_SIZE (LSN_SIZE + DIRCOUNT_SIZE + EMPTY_SPACE_SIZE +\
|
#define PAGE_HEADER_SIZE (LSN_SIZE + DIR_COUNT_SIZE + EMPTY_SPACE_SIZE +\
|
||||||
PAGE_TYPE_SIZE)
|
PAGE_TYPE_SIZE)
|
||||||
#define PAGE_OVERHEAD_SIZE (PAGE_HEADER_SIZE + DIR_ENTRY_SIZE + \
|
#define PAGE_OVERHEAD_SIZE (PAGE_HEADER_SIZE + DIR_ENTRY_SIZE + \
|
||||||
PAGE_SUFFIX_SIZE)
|
PAGE_SUFFIX_SIZE)
|
||||||
@@ -34,14 +34,18 @@
|
|||||||
#define ROW_EXTENT_COUNT_SIZE 2
|
#define ROW_EXTENT_COUNT_SIZE 2
|
||||||
#define ROW_EXTENT_SIZE (ROW_EXTENT_PAGE_SIZE + ROW_EXTENT_COUNT_SIZE)
|
#define ROW_EXTENT_SIZE (ROW_EXTENT_PAGE_SIZE + ROW_EXTENT_COUNT_SIZE)
|
||||||
#define TAIL_BIT 0x8000 /* Bit in page_count to signify tail */
|
#define TAIL_BIT 0x8000 /* Bit in page_count to signify tail */
|
||||||
|
/* Number of extents reserved MARIA_BITMAP_BLOCKS to store head part */
|
||||||
#define ELEMENTS_RESERVED_FOR_MAIN_PART 4
|
#define ELEMENTS_RESERVED_FOR_MAIN_PART 4
|
||||||
|
/* Fields before 'row->null_field_lengths' used by find_where_to_split_row */
|
||||||
#define EXTRA_LENGTH_FIELDS 3
|
#define EXTRA_LENGTH_FIELDS 3
|
||||||
|
|
||||||
|
/* Size for the different parts in the row header (and head page) */
|
||||||
|
|
||||||
#define FLAG_SIZE 1
|
#define FLAG_SIZE 1
|
||||||
#define TRANSID_SIZE 6
|
#define TRANSID_SIZE 6
|
||||||
#define VERPTR_SIZE 7
|
#define VERPTR_SIZE 7
|
||||||
#define DIR_ENTRY_SIZE 4
|
#define DIR_ENTRY_SIZE 4
|
||||||
#define FIELD_OFFSET_SIZE 2
|
#define FIELD_OFFSET_SIZE 2 /* size of pointers to field starts */
|
||||||
|
|
||||||
/* Minimum header size needed for a new row */
|
/* Minimum header size needed for a new row */
|
||||||
#define BASE_ROW_HEADER_SIZE FLAG_SIZE
|
#define BASE_ROW_HEADER_SIZE FLAG_SIZE
|
||||||
@@ -51,8 +55,8 @@
|
|||||||
enum en_page_type { UNALLOCATED_PAGE, HEAD_PAGE, TAIL_PAGE, BLOB_PAGE, MAX_PAGE_TYPE };
|
enum en_page_type { UNALLOCATED_PAGE, HEAD_PAGE, TAIL_PAGE, BLOB_PAGE, MAX_PAGE_TYPE };
|
||||||
|
|
||||||
#define PAGE_TYPE_OFFSET LSN_SIZE
|
#define PAGE_TYPE_OFFSET LSN_SIZE
|
||||||
#define DIR_ENTRY_OFFSET LSN_SIZE+PAGE_TYPE_SIZE
|
#define DIR_COUNT_OFFSET LSN_SIZE+PAGE_TYPE_SIZE
|
||||||
#define EMPTY_SPACE_OFFSET (DIR_ENTRY_OFFSET + DIRCOUNT_SIZE)
|
#define EMPTY_SPACE_OFFSET (DIR_COUNT_OFFSET + DIR_COUNT_SIZE)
|
||||||
|
|
||||||
#define PAGE_CAN_BE_COMPACTED 128 /* Bit in PAGE_TYPE */
|
#define PAGE_CAN_BE_COMPACTED 128 /* Bit in PAGE_TYPE */
|
||||||
|
|
||||||
@@ -64,10 +68,15 @@ enum en_page_type { UNALLOCATED_PAGE, HEAD_PAGE, TAIL_PAGE, BLOB_PAGE, MAX_PAGE_
|
|||||||
#define ROW_FLAG_EXTENTS 128
|
#define ROW_FLAG_EXTENTS 128
|
||||||
#define ROW_FLAG_ALL (1+2+4+8+128)
|
#define ROW_FLAG_ALL (1+2+4+8+128)
|
||||||
|
|
||||||
/* Variables that affects how data pages are utilized */
|
/******** Variables that affects how data pages are utilized ********/
|
||||||
|
|
||||||
|
/* Minium size of tail segment */
|
||||||
#define MIN_TAIL_SIZE 32
|
#define MIN_TAIL_SIZE 32
|
||||||
|
|
||||||
/* Fixed part of Max possible header size; See table in ma_blockrec.c */
|
/*
|
||||||
|
Fixed length part of Max possible header size; See row data structure
|
||||||
|
table in ma_blockrec.c.
|
||||||
|
*/
|
||||||
#define MAX_FIXED_HEADER_SIZE (FLAG_SIZE + 3 + ROW_EXTENT_SIZE + 3)
|
#define MAX_FIXED_HEADER_SIZE (FLAG_SIZE + 3 + ROW_EXTENT_SIZE + 3)
|
||||||
#define TRANS_MAX_FIXED_HEADER_SIZE (MAX_FIXED_HEADER_SIZE + \
|
#define TRANS_MAX_FIXED_HEADER_SIZE (MAX_FIXED_HEADER_SIZE + \
|
||||||
TRANSID_SIZE + VERPTR_SIZE + \
|
TRANSID_SIZE + VERPTR_SIZE + \
|
||||||
@@ -77,21 +86,30 @@ enum en_page_type { UNALLOCATED_PAGE, HEAD_PAGE, TAIL_PAGE, BLOB_PAGE, MAX_PAGE_
|
|||||||
#define MAX_ROWS_PER_PAGE 255
|
#define MAX_ROWS_PER_PAGE 255
|
||||||
|
|
||||||
/* Bits for MARIA_BITMAP_BLOCKS->used */
|
/* Bits for MARIA_BITMAP_BLOCKS->used */
|
||||||
|
/* We stored data on disk in the block */
|
||||||
#define BLOCKUSED_USED 1
|
#define BLOCKUSED_USED 1
|
||||||
|
/* Bitmap on disk is block->org_bitmap_value ; Happens only on update */
|
||||||
#define BLOCKUSED_USE_ORG_BITMAP 2
|
#define BLOCKUSED_USE_ORG_BITMAP 2
|
||||||
|
/* We stored tail data on disk for the block */
|
||||||
#define BLOCKUSED_TAIL 4
|
#define BLOCKUSED_TAIL 4
|
||||||
|
|
||||||
/* defines that affects allocation (density) of data */
|
/******* defines that affects allocation (density) of data *******/
|
||||||
|
|
||||||
/* If we fill up a block to 75 %, don't create a new tail page for it */
|
/*
|
||||||
|
If the tail part (from the main block or a blob) uses more than 75 % of
|
||||||
|
the size of page, store the tail on a full page instead of a shared
|
||||||
|
tail page.
|
||||||
|
*/
|
||||||
#define MAX_TAIL_SIZE(block_size) ((block_size) *3 / 4)
|
#define MAX_TAIL_SIZE(block_size) ((block_size) *3 / 4)
|
||||||
|
|
||||||
|
extern uchar maria_bitmap_marker[2];
|
||||||
|
|
||||||
/* Functions to convert MARIA_RECORD_POS to/from page:offset */
|
/* Functions to convert MARIA_RECORD_POS to/from page:offset */
|
||||||
|
|
||||||
static inline MARIA_RECORD_POS ma_recordpos(ulonglong page, uint offset)
|
static inline MARIA_RECORD_POS ma_recordpos(ulonglong page, uint dir_entry)
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(offset <= 255);
|
DBUG_ASSERT(dir_entry <= 255);
|
||||||
return (MARIA_RECORD_POS) ((page << 8) | offset);
|
return (MARIA_RECORD_POS) ((page << 8) | dir_entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline my_off_t ma_recordpos_to_page(MARIA_RECORD_POS record_pos)
|
static inline my_off_t ma_recordpos_to_page(MARIA_RECORD_POS record_pos)
|
||||||
@@ -99,17 +117,17 @@ static inline my_off_t ma_recordpos_to_page(MARIA_RECORD_POS record_pos)
|
|||||||
return record_pos >> 8;
|
return record_pos >> 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline my_off_t ma_recordpos_to_offset(MARIA_RECORD_POS record_pos)
|
static inline my_off_t ma_recordpos_to_dir_entry(MARIA_RECORD_POS record_pos)
|
||||||
{
|
{
|
||||||
return record_pos & 255;
|
return record_pos & 255;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ma_blockrec.c */
|
/* ma_blockrec.c */
|
||||||
void _ma_init_block_record_data(void);
|
void _ma_init_block_record_data(void);
|
||||||
my_bool _ma_once_init_block_row(MARIA_SHARE *share, File dfile);
|
my_bool _ma_once_init_block_record(MARIA_SHARE *share, File dfile);
|
||||||
my_bool _ma_once_end_block_row(MARIA_SHARE *share);
|
my_bool _ma_once_end_block_record(MARIA_SHARE *share);
|
||||||
my_bool _ma_init_block_row(MARIA_HA *info);
|
my_bool _ma_init_block_record(MARIA_HA *info);
|
||||||
void _ma_end_block_row(MARIA_HA *info);
|
void _ma_end_block_record(MARIA_HA *info);
|
||||||
|
|
||||||
my_bool _ma_update_block_record(MARIA_HA *info, MARIA_RECORD_POS pos,
|
my_bool _ma_update_block_record(MARIA_HA *info, MARIA_RECORD_POS pos,
|
||||||
const byte *record);
|
const byte *record);
|
||||||
@@ -136,8 +154,6 @@ my_bool _ma_compare_block_record(register MARIA_HA *info,
|
|||||||
my_bool _ma_bitmap_init(MARIA_SHARE *share, File file);
|
my_bool _ma_bitmap_init(MARIA_SHARE *share, File file);
|
||||||
my_bool _ma_bitmap_end(MARIA_SHARE *share);
|
my_bool _ma_bitmap_end(MARIA_SHARE *share);
|
||||||
my_bool _ma_flush_bitmap(MARIA_SHARE *share);
|
my_bool _ma_flush_bitmap(MARIA_SHARE *share);
|
||||||
my_bool _ma_read_bitmap_page(MARIA_SHARE *share, MARIA_FILE_BITMAP *bitmap,
|
|
||||||
ulonglong page);
|
|
||||||
my_bool _ma_bitmap_find_place(MARIA_HA *info, MARIA_ROW *row,
|
my_bool _ma_bitmap_find_place(MARIA_HA *info, MARIA_ROW *row,
|
||||||
MARIA_BITMAP_BLOCKS *result_blocks);
|
MARIA_BITMAP_BLOCKS *result_blocks);
|
||||||
my_bool _ma_bitmap_release_unused(MARIA_HA *info, MARIA_BITMAP_BLOCKS *blocks);
|
my_bool _ma_bitmap_release_unused(MARIA_HA *info, MARIA_BITMAP_BLOCKS *blocks);
|
||||||
|
@@ -941,7 +941,7 @@ static void record_pos_to_txt(MARIA_HA *info, my_off_t recpos,
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
my_off_t page= ma_recordpos_to_page(recpos);
|
my_off_t page= ma_recordpos_to_page(recpos);
|
||||||
uint row= ma_recordpos_to_offset(recpos);
|
uint row= ma_recordpos_to_dir_entry(recpos);
|
||||||
char *end= longlong10_to_str(page, buff, 10);
|
char *end= longlong10_to_str(page, buff, 10);
|
||||||
*(end++)= ':';
|
*(end++)= ':';
|
||||||
longlong10_to_str(row, end, 10);
|
longlong10_to_str(row, end, 10);
|
||||||
@@ -1370,6 +1370,9 @@ end:
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
Check if layout on a page is ok
|
Check if layout on a page is ok
|
||||||
|
|
||||||
|
NOTES
|
||||||
|
This is for rows-in-block format.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int check_page_layout(HA_CHECK *param, MARIA_HA *info,
|
static int check_page_layout(HA_CHECK *param, MARIA_HA *info,
|
||||||
@@ -1442,6 +1445,8 @@ static int check_page_layout(HA_CHECK *param, MARIA_HA *info,
|
|||||||
Check all rows on head page
|
Check all rows on head page
|
||||||
|
|
||||||
NOTES
|
NOTES
|
||||||
|
This is for rows-in-block format.
|
||||||
|
|
||||||
Before this, we have already called check_page_layout(), so
|
Before this, we have already called check_page_layout(), so
|
||||||
we know the block is logicaly correct (even if the rows may not be that)
|
we know the block is logicaly correct (even if the rows may not be that)
|
||||||
|
|
||||||
@@ -1548,6 +1553,9 @@ static my_bool check_head_page(HA_CHECK *param, MARIA_HA *info, byte *record,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Check if rows-in-block data file is consistent
|
||||||
|
*/
|
||||||
|
|
||||||
static int check_block_record(HA_CHECK *param, MARIA_HA *info, int extend,
|
static int check_block_record(HA_CHECK *param, MARIA_HA *info, int extend,
|
||||||
byte *record)
|
byte *record)
|
||||||
@@ -1638,7 +1646,7 @@ static int check_block_record(HA_CHECK *param, MARIA_HA *info, int extend,
|
|||||||
DBUG_ASSERT(0);
|
DBUG_ASSERT(0);
|
||||||
break;
|
break;
|
||||||
case HEAD_PAGE:
|
case HEAD_PAGE:
|
||||||
row_count= ((uchar*) page_buff)[DIR_ENTRY_OFFSET];
|
row_count= ((uchar*) page_buff)[DIR_COUNT_OFFSET];
|
||||||
empty_space= uint2korr(page_buff + EMPTY_SPACE_OFFSET);
|
empty_space= uint2korr(page_buff + EMPTY_SPACE_OFFSET);
|
||||||
param->used+= (PAGE_HEADER_SIZE + PAGE_SUFFIX_SIZE +
|
param->used+= (PAGE_HEADER_SIZE + PAGE_SUFFIX_SIZE +
|
||||||
row_count * DIR_ENTRY_SIZE);
|
row_count * DIR_ENTRY_SIZE);
|
||||||
@@ -1647,7 +1655,7 @@ static int check_block_record(HA_CHECK *param, MARIA_HA *info, int extend,
|
|||||||
full_dir= row_count == MAX_ROWS_PER_PAGE;
|
full_dir= row_count == MAX_ROWS_PER_PAGE;
|
||||||
break;
|
break;
|
||||||
case TAIL_PAGE:
|
case TAIL_PAGE:
|
||||||
row_count= ((uchar*) page_buff)[DIR_ENTRY_OFFSET];
|
row_count= ((uchar*) page_buff)[DIR_COUNT_OFFSET];
|
||||||
empty_space= uint2korr(page_buff + EMPTY_SPACE_OFFSET);
|
empty_space= uint2korr(page_buff + EMPTY_SPACE_OFFSET);
|
||||||
param->used+= (PAGE_HEADER_SIZE + PAGE_SUFFIX_SIZE +
|
param->used+= (PAGE_HEADER_SIZE + PAGE_SUFFIX_SIZE +
|
||||||
row_count * DIR_ENTRY_SIZE);
|
row_count * DIR_ENTRY_SIZE);
|
||||||
@@ -4581,7 +4589,7 @@ int maria_recreate_table(HA_CHECK *param, MARIA_HA **org_info, char *filename)
|
|||||||
MARIA_SHARE share;
|
MARIA_SHARE share;
|
||||||
MARIA_KEYDEF *keyinfo,*key,*key_end;
|
MARIA_KEYDEF *keyinfo,*key,*key_end;
|
||||||
HA_KEYSEG *keysegs,*keyseg;
|
HA_KEYSEG *keysegs,*keyseg;
|
||||||
MARIA_COLUMNDEF *recdef,*rec,*end;
|
MARIA_COLUMNDEF *columndef,*column,*end;
|
||||||
MARIA_UNIQUEDEF *uniquedef,*u_ptr,*u_end;
|
MARIA_UNIQUEDEF *uniquedef,*u_ptr,*u_end;
|
||||||
MARIA_STATUS_INFO status_info;
|
MARIA_STATUS_INFO status_info;
|
||||||
uint unpack,key_parts;
|
uint unpack,key_parts;
|
||||||
@@ -4610,7 +4618,7 @@ int maria_recreate_table(HA_CHECK *param, MARIA_HA **org_info, char *filename)
|
|||||||
my_afree((gptr) keyinfo);
|
my_afree((gptr) keyinfo);
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
}
|
}
|
||||||
if (!(recdef=(MARIA_COLUMNDEF*)
|
if (!(columndef=(MARIA_COLUMNDEF*)
|
||||||
my_alloca(sizeof(MARIA_COLUMNDEF)*(share.base.fields+1))))
|
my_alloca(sizeof(MARIA_COLUMNDEF)*(share.base.fields+1))))
|
||||||
{
|
{
|
||||||
my_afree((gptr) keyinfo);
|
my_afree((gptr) keyinfo);
|
||||||
@@ -4620,22 +4628,24 @@ int maria_recreate_table(HA_CHECK *param, MARIA_HA **org_info, char *filename)
|
|||||||
if (!(uniquedef=(MARIA_UNIQUEDEF*)
|
if (!(uniquedef=(MARIA_UNIQUEDEF*)
|
||||||
my_alloca(sizeof(MARIA_UNIQUEDEF)*(share.state.header.uniques+1))))
|
my_alloca(sizeof(MARIA_UNIQUEDEF)*(share.state.header.uniques+1))))
|
||||||
{
|
{
|
||||||
my_afree((gptr) recdef);
|
my_afree((gptr) columndef);
|
||||||
my_afree((gptr) keyinfo);
|
my_afree((gptr) keyinfo);
|
||||||
my_afree((gptr) keysegs);
|
my_afree((gptr) keysegs);
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Copy the column definitions */
|
/* Copy the column definitions */
|
||||||
memcpy((byte*) recdef,(byte*) share.rec,
|
memcpy((byte*) columndef,(byte*) share.columndef,
|
||||||
(size_t) (sizeof(MARIA_COLUMNDEF)*(share.base.fields+1)));
|
(size_t) (sizeof(MARIA_COLUMNDEF)*(share.base.fields+1)));
|
||||||
for (rec=recdef,end=recdef+share.base.fields; rec != end ; rec++)
|
for (column=columndef, end= columndef+share.base.fields;
|
||||||
|
column != end ;
|
||||||
|
column++)
|
||||||
{
|
{
|
||||||
if (unpack && !(share.options & HA_OPTION_PACK_RECORD) &&
|
if (unpack && !(share.options & HA_OPTION_PACK_RECORD) &&
|
||||||
rec->type != FIELD_BLOB &&
|
column->type != FIELD_BLOB &&
|
||||||
rec->type != FIELD_VARCHAR &&
|
column->type != FIELD_VARCHAR &&
|
||||||
rec->type != FIELD_CHECK)
|
column->type != FIELD_CHECK)
|
||||||
rec->type=(int) FIELD_NORMAL;
|
column->type=(int) FIELD_NORMAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Change the new key to point at the saved key segments */
|
/* Change the new key to point at the saved key segments */
|
||||||
@@ -4710,7 +4720,7 @@ int maria_recreate_table(HA_CHECK *param, MARIA_HA **org_info, char *filename)
|
|||||||
*/
|
*/
|
||||||
if (maria_create(filename, share.data_file_type,
|
if (maria_create(filename, share.data_file_type,
|
||||||
share.base.keys - share.state.header.uniques,
|
share.base.keys - share.state.header.uniques,
|
||||||
keyinfo, share.base.fields, recdef,
|
keyinfo, share.base.fields, columndef,
|
||||||
share.state.header.uniques, uniquedef,
|
share.state.header.uniques, uniquedef,
|
||||||
&create_info,
|
&create_info,
|
||||||
HA_DONT_TOUCH_DATA))
|
HA_DONT_TOUCH_DATA))
|
||||||
@@ -4751,7 +4761,7 @@ int maria_recreate_table(HA_CHECK *param, MARIA_HA **org_info, char *filename)
|
|||||||
end:
|
end:
|
||||||
my_afree((gptr) uniquedef);
|
my_afree((gptr) uniquedef);
|
||||||
my_afree((gptr) keyinfo);
|
my_afree((gptr) keyinfo);
|
||||||
my_afree((gptr) recdef);
|
my_afree((gptr) columndef);
|
||||||
my_afree((gptr) keysegs);
|
my_afree((gptr) keysegs);
|
||||||
DBUG_RETURN(error);
|
DBUG_RETURN(error);
|
||||||
}
|
}
|
||||||
|
@@ -20,29 +20,32 @@
|
|||||||
ha_checksum _ma_checksum(MARIA_HA *info, const byte *record)
|
ha_checksum _ma_checksum(MARIA_HA *info, const byte *record)
|
||||||
{
|
{
|
||||||
ha_checksum crc=0;
|
ha_checksum crc=0;
|
||||||
MARIA_COLUMNDEF *rec= info->s->rec, *rec_end= rec+ info->s->base.fields;
|
MARIA_COLUMNDEF *column= info->s->columndef;
|
||||||
|
MARIA_COLUMNDEF *column_end= column+ info->s->base.fields;
|
||||||
|
|
||||||
if (info->s->base.null_bytes)
|
if (info->s->base.null_bytes)
|
||||||
crc= my_checksum(crc, record, info->s->base.null_bytes);
|
crc= my_checksum(crc, record, info->s->base.null_bytes);
|
||||||
|
|
||||||
for ( ; rec != rec_end ; rec++)
|
for ( ; column != column_end ; column++)
|
||||||
{
|
{
|
||||||
const byte *pos= record + rec->offset;
|
const byte *pos= record + column->offset;
|
||||||
ulong length;
|
ulong length;
|
||||||
|
|
||||||
switch (rec->type) {
|
switch (column->type) {
|
||||||
case FIELD_BLOB:
|
case FIELD_BLOB:
|
||||||
{
|
{
|
||||||
length= _ma_calc_blob_length(rec->length-
|
uint blob_size_length= column->length- portable_sizeof_char_ptr;
|
||||||
maria_portable_sizeof_char_ptr,
|
length= _ma_calc_blob_length(blob_size_length, pos);
|
||||||
pos);
|
if (length)
|
||||||
memcpy((char*) &pos, pos+rec->length- maria_portable_sizeof_char_ptr,
|
{
|
||||||
sizeof(char*));
|
memcpy((char*) &pos, pos + blob_size_length, sizeof(char*));
|
||||||
break;
|
crc= my_checksum(crc, pos, length);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
case FIELD_VARCHAR:
|
case FIELD_VARCHAR:
|
||||||
{
|
{
|
||||||
uint pack_length= HA_VARCHAR_PACKLENGTH(rec->length-1);
|
uint pack_length= HA_VARCHAR_PACKLENGTH(column->length-1);
|
||||||
if (pack_length == 1)
|
if (pack_length == 1)
|
||||||
length= (ulong) *(uchar*) pos;
|
length= (ulong) *(uchar*) pos;
|
||||||
else
|
else
|
||||||
@@ -51,10 +54,10 @@ ha_checksum _ma_checksum(MARIA_HA *info, const byte *record)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
length= rec->length;
|
length= column->length;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
crc= my_checksum(crc, pos ? pos : "", length);
|
crc= my_checksum(crc, pos, length);
|
||||||
}
|
}
|
||||||
return crc;
|
return crc;
|
||||||
}
|
}
|
||||||
|
@@ -69,10 +69,8 @@ int maria_close(register MARIA_HA *info)
|
|||||||
pthread_mutex_unlock(&share->intern_lock);
|
pthread_mutex_unlock(&share->intern_lock);
|
||||||
|
|
||||||
my_free(info->rec_buff, MYF(MY_ALLOW_ZERO_PTR));
|
my_free(info->rec_buff, MYF(MY_ALLOW_ZERO_PTR));
|
||||||
(share->end)(info);
|
(*share->end)(info);
|
||||||
|
|
||||||
if (info->s->data_file_type == BLOCK_RECORD)
|
|
||||||
info->dfile= -1; /* Closed in ma_end_once_block_row */
|
|
||||||
if (flag)
|
if (flag)
|
||||||
{
|
{
|
||||||
if (share->kfile >= 0)
|
if (share->kfile >= 0)
|
||||||
|
@@ -35,9 +35,9 @@ static int compare_columns(MARIA_COLUMNDEF **a, MARIA_COLUMNDEF **b);
|
|||||||
Old options is used when recreating database, from maria_chk
|
Old options is used when recreating database, from maria_chk
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int maria_create(const char *name, enum data_file_type record_type,
|
int maria_create(const char *name, enum data_file_type datafile_type,
|
||||||
uint keys,MARIA_KEYDEF *keydefs,
|
uint keys,MARIA_KEYDEF *keydefs,
|
||||||
uint columns, MARIA_COLUMNDEF *recinfo,
|
uint columns, MARIA_COLUMNDEF *columndef,
|
||||||
uint uniques, MARIA_UNIQUEDEF *uniquedefs,
|
uint uniques, MARIA_UNIQUEDEF *uniquedefs,
|
||||||
MARIA_CREATE_INFO *ci,uint flags)
|
MARIA_CREATE_INFO *ci,uint flags)
|
||||||
{
|
{
|
||||||
@@ -55,12 +55,12 @@ int maria_create(const char *name, enum data_file_type record_type,
|
|||||||
ulong pack_reclength;
|
ulong pack_reclength;
|
||||||
ulonglong tot_length,max_rows, tmp;
|
ulonglong tot_length,max_rows, tmp;
|
||||||
enum en_fieldtype type;
|
enum en_fieldtype type;
|
||||||
enum data_file_type org_record_type= record_type;
|
enum data_file_type org_datafile_type= datafile_type;
|
||||||
MARIA_SHARE share;
|
MARIA_SHARE share;
|
||||||
MARIA_KEYDEF *keydef,tmp_keydef;
|
MARIA_KEYDEF *keydef,tmp_keydef;
|
||||||
MARIA_UNIQUEDEF *uniquedef;
|
MARIA_UNIQUEDEF *uniquedef;
|
||||||
HA_KEYSEG *keyseg,tmp_keyseg;
|
HA_KEYSEG *keyseg,tmp_keyseg;
|
||||||
MARIA_COLUMNDEF *rec, *rec_end;
|
MARIA_COLUMNDEF *column, *end_column;
|
||||||
ulong *rec_per_key_part;
|
ulong *rec_per_key_part;
|
||||||
my_off_t key_root[HA_MAX_POSSIBLE_KEY];
|
my_off_t key_root[HA_MAX_POSSIBLE_KEY];
|
||||||
MARIA_CREATE_INFO tmp_create_info;
|
MARIA_CREATE_INFO tmp_create_info;
|
||||||
@@ -70,6 +70,7 @@ int maria_create(const char *name, enum data_file_type record_type,
|
|||||||
DBUG_PRINT("enter", ("keys: %u columns: %u uniques: %u flags: %u",
|
DBUG_PRINT("enter", ("keys: %u columns: %u uniques: %u flags: %u",
|
||||||
keys, columns, uniques, flags));
|
keys, columns, uniques, flags));
|
||||||
|
|
||||||
|
DBUG_ASSERT(maria_block_size && maria_block_size % IO_SIZE == 0);
|
||||||
LINT_INIT(dfile);
|
LINT_INIT(dfile);
|
||||||
LINT_INIT(file);
|
LINT_INIT(file);
|
||||||
|
|
||||||
@@ -89,7 +90,7 @@ int maria_create(const char *name, enum data_file_type record_type,
|
|||||||
|
|
||||||
if (flags & HA_DONT_TOUCH_DATA)
|
if (flags & HA_DONT_TOUCH_DATA)
|
||||||
{
|
{
|
||||||
org_record_type= ci->org_data_file_type;
|
org_datafile_type= ci->org_data_file_type;
|
||||||
if (!(ci->old_options & HA_OPTION_TEMP_COMPRESS_RECORD))
|
if (!(ci->old_options & HA_OPTION_TEMP_COMPRESS_RECORD))
|
||||||
options=ci->old_options &
|
options=ci->old_options &
|
||||||
(HA_OPTION_COMPRESS_RECORD | HA_OPTION_PACK_RECORD |
|
(HA_OPTION_COMPRESS_RECORD | HA_OPTION_PACK_RECORD |
|
||||||
@@ -117,83 +118,85 @@ int maria_create(const char *name, enum data_file_type record_type,
|
|||||||
pack_reclength= max_field_lengths= 0;
|
pack_reclength= max_field_lengths= 0;
|
||||||
reclength= min_pack_length= ci->null_bytes;
|
reclength= min_pack_length= ci->null_bytes;
|
||||||
|
|
||||||
for (rec= recinfo, rec_end= rec + columns ; rec != rec_end ; rec++)
|
for (column= columndef, end_column= column + columns ;
|
||||||
|
column != end_column ;
|
||||||
|
column++)
|
||||||
{
|
{
|
||||||
/* Fill in not used struct parts */
|
/* Fill in not used struct parts */
|
||||||
rec->offset= reclength;
|
column->offset= reclength;
|
||||||
rec->empty_pos= 0;
|
column->empty_pos= 0;
|
||||||
rec->empty_bit= 0;
|
column->empty_bit= 0;
|
||||||
rec->fill_length= rec->length;
|
column->fill_length= column->length;
|
||||||
|
|
||||||
reclength+= rec->length;
|
reclength+= column->length;
|
||||||
type= rec->type;
|
type= column->type;
|
||||||
if (type == FIELD_SKIP_PRESPACE && record_type == BLOCK_RECORD)
|
if (type == FIELD_SKIP_PRESPACE && datafile_type == BLOCK_RECORD)
|
||||||
type= FIELD_NORMAL; /* SKIP_PRESPACE not supported */
|
type= FIELD_NORMAL; /* SKIP_PRESPACE not supported */
|
||||||
|
|
||||||
if (type != FIELD_NORMAL && type != FIELD_CHECK)
|
if (type != FIELD_NORMAL && type != FIELD_CHECK)
|
||||||
{
|
{
|
||||||
rec->empty_pos= packed/8;
|
column->empty_pos= packed/8;
|
||||||
rec->empty_bit= (1 << (packed & 7));
|
column->empty_bit= (1 << (packed & 7));
|
||||||
if (type == FIELD_BLOB)
|
if (type == FIELD_BLOB)
|
||||||
{
|
{
|
||||||
packed++;
|
packed++;
|
||||||
share.base.blobs++;
|
share.base.blobs++;
|
||||||
if (pack_reclength != INT_MAX32)
|
if (pack_reclength != INT_MAX32)
|
||||||
{
|
{
|
||||||
if (rec->length == 4+maria_portable_sizeof_char_ptr)
|
if (column->length == 4+portable_sizeof_char_ptr)
|
||||||
pack_reclength= INT_MAX32;
|
pack_reclength= INT_MAX32;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Add max possible blob length */
|
/* Add max possible blob length */
|
||||||
pack_reclength+= (1 << ((rec->length-
|
pack_reclength+= (1 << ((column->length-
|
||||||
maria_portable_sizeof_char_ptr)*8));
|
portable_sizeof_char_ptr)*8));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
max_field_lengths+= (rec->length - maria_portable_sizeof_char_ptr);
|
max_field_lengths+= (column->length - portable_sizeof_char_ptr);
|
||||||
}
|
}
|
||||||
else if (type == FIELD_SKIP_PRESPACE ||
|
else if (type == FIELD_SKIP_PRESPACE ||
|
||||||
type == FIELD_SKIP_ENDSPACE)
|
type == FIELD_SKIP_ENDSPACE)
|
||||||
{
|
{
|
||||||
max_field_lengths+= rec->length > 255 ? 2 : 1;
|
max_field_lengths+= column->length > 255 ? 2 : 1;
|
||||||
if (record_type != BLOCK_RECORD)
|
if (datafile_type != BLOCK_RECORD)
|
||||||
min_pack_length++;
|
min_pack_length++;
|
||||||
packed++;
|
packed++;
|
||||||
}
|
}
|
||||||
else if (type == FIELD_VARCHAR)
|
else if (type == FIELD_VARCHAR)
|
||||||
{
|
{
|
||||||
varchar_length+= rec->length-1; /* Used for min_pack_length */
|
varchar_length+= column->length-1; /* Used for min_pack_length */
|
||||||
pack_reclength++;
|
pack_reclength++;
|
||||||
if (record_type != BLOCK_RECORD)
|
if (datafile_type != BLOCK_RECORD)
|
||||||
min_pack_length++;
|
min_pack_length++;
|
||||||
max_field_lengths++;
|
max_field_lengths++;
|
||||||
packed++;
|
packed++;
|
||||||
rec->fill_length= 1;
|
column->fill_length= 1;
|
||||||
/* We must test for 257 as length includes pack-length */
|
/* We must test for 257 as length includes pack-length */
|
||||||
if (test(rec->length >= 257))
|
if (test(column->length >= 257))
|
||||||
{
|
{
|
||||||
long_varchar_count++;
|
long_varchar_count++;
|
||||||
max_field_lengths++;
|
max_field_lengths++;
|
||||||
rec->fill_length= 2;
|
column->fill_length= 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (type == FIELD_SKIP_ZERO)
|
else if (type == FIELD_SKIP_ZERO)
|
||||||
packed++;
|
packed++;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (record_type != BLOCK_RECORD || !rec->null_bit)
|
if (datafile_type != BLOCK_RECORD || !column->null_bit)
|
||||||
min_pack_length+= rec->length;
|
min_pack_length+= column->length;
|
||||||
rec->empty_pos= 0;
|
column->empty_pos= 0;
|
||||||
rec->empty_bit= 0;
|
column->empty_bit= 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else /* FIELD_NORMAL */
|
else /* FIELD_NORMAL */
|
||||||
{
|
{
|
||||||
if (record_type != BLOCK_RECORD || !rec->null_bit)
|
if (datafile_type != BLOCK_RECORD || !column->null_bit)
|
||||||
min_pack_length+= rec->length;
|
min_pack_length+= column->length;
|
||||||
if (!rec->null_bit)
|
if (!column->null_bit)
|
||||||
{
|
{
|
||||||
share.base.fixed_not_null_fields++;
|
share.base.fixed_not_null_fields++;
|
||||||
share.base.fixed_not_null_fields_length+= rec->length;
|
share.base.fixed_not_null_fields_length+= column->length;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -203,14 +206,14 @@ int maria_create(const char *name, enum data_file_type record_type,
|
|||||||
Not optimal packing, try to remove a 1 byte length zero-field as
|
Not optimal packing, try to remove a 1 byte length zero-field as
|
||||||
this will get same record length, but smaller pack overhead
|
this will get same record length, but smaller pack overhead
|
||||||
*/
|
*/
|
||||||
while (rec != recinfo)
|
while (column != columndef)
|
||||||
{
|
{
|
||||||
rec--;
|
column--;
|
||||||
if (rec->type == (int) FIELD_SKIP_ZERO && rec->length == 1)
|
if (column->type == (int) FIELD_SKIP_ZERO && column->length == 1)
|
||||||
{
|
{
|
||||||
rec->type=(int) FIELD_NORMAL;
|
column->type=(int) FIELD_NORMAL;
|
||||||
rec->empty_pos= 0;
|
column->empty_pos= 0;
|
||||||
rec->empty_bit= 0;
|
column->empty_bit= 0;
|
||||||
packed--;
|
packed--;
|
||||||
min_pack_length++;
|
min_pack_length++;
|
||||||
break;
|
break;
|
||||||
@@ -226,12 +229,12 @@ int maria_create(const char *name, enum data_file_type record_type,
|
|||||||
if (pack_reclength != INT_MAX32)
|
if (pack_reclength != INT_MAX32)
|
||||||
pack_reclength+= max_field_lengths + long_varchar_count;
|
pack_reclength+= max_field_lengths + long_varchar_count;
|
||||||
|
|
||||||
if (packed && record_type == STATIC_RECORD)
|
if (packed && datafile_type == STATIC_RECORD)
|
||||||
record_type= BLOCK_RECORD;
|
datafile_type= BLOCK_RECORD;
|
||||||
if (record_type == DYNAMIC_RECORD)
|
if (datafile_type == DYNAMIC_RECORD)
|
||||||
options|= HA_OPTION_PACK_RECORD; /* Must use packed records */
|
options|= HA_OPTION_PACK_RECORD; /* Must use packed records */
|
||||||
|
|
||||||
if (record_type == STATIC_RECORD)
|
if (datafile_type == STATIC_RECORD)
|
||||||
{
|
{
|
||||||
/* We can't use checksum with static length rows */
|
/* We can't use checksum with static length rows */
|
||||||
flags&= ~HA_CREATE_CHECKSUM;
|
flags&= ~HA_CREATE_CHECKSUM;
|
||||||
@@ -275,22 +278,22 @@ int maria_create(const char *name, enum data_file_type record_type,
|
|||||||
}
|
}
|
||||||
else if (!ci->max_rows)
|
else if (!ci->max_rows)
|
||||||
{
|
{
|
||||||
if (record_type == BLOCK_RECORD)
|
if (datafile_type == BLOCK_RECORD)
|
||||||
{
|
{
|
||||||
uint rows_per_page= ((maria_block_size - PAGE_OVERHEAD_SIZE) /
|
uint rows_per_page= ((maria_block_size - PAGE_OVERHEAD_SIZE) /
|
||||||
(min_pack_length + extra_header_size +
|
(min_pack_length + extra_header_size +
|
||||||
DIR_ENTRY_SIZE));
|
DIR_ENTRY_SIZE));
|
||||||
ulonglong data_file_length= ci->data_file_length;
|
ulonglong data_file_length= ci->data_file_length;
|
||||||
if (data_file_length)
|
if (!data_file_length)
|
||||||
data_file_length= ((((ulonglong) 1 << ((BLOCK_RECORD_POINTER_SIZE-1) *
|
data_file_length= ((((ulonglong) 1 << ((BLOCK_RECORD_POINTER_SIZE-1) *
|
||||||
8)) -1));
|
8)) -1));
|
||||||
if (rows_per_page > 0)
|
if (rows_per_page > 0)
|
||||||
{
|
{
|
||||||
set_if_smaller(rows_per_page, MAX_ROWS_PER_PAGE);
|
set_if_smaller(rows_per_page, MAX_ROWS_PER_PAGE);
|
||||||
ci->max_rows= ci->data_file_length / maria_block_size * rows_per_page;
|
ci->max_rows= data_file_length / maria_block_size * rows_per_page;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
ci->max_rows= ci->data_file_length / (min_pack_length +
|
ci->max_rows= data_file_length / (min_pack_length +
|
||||||
extra_header_size +
|
extra_header_size +
|
||||||
DIR_ENTRY_SIZE);
|
DIR_ENTRY_SIZE);
|
||||||
}
|
}
|
||||||
@@ -301,7 +304,7 @@ int maria_create(const char *name, enum data_file_type record_type,
|
|||||||
3 : 0)));
|
3 : 0)));
|
||||||
}
|
}
|
||||||
max_rows= (ulonglong) ci->max_rows;
|
max_rows= (ulonglong) ci->max_rows;
|
||||||
if (record_type == BLOCK_RECORD)
|
if (datafile_type == BLOCK_RECORD)
|
||||||
{
|
{
|
||||||
/* The + 1 is for record position withing page */
|
/* The + 1 is for record position withing page */
|
||||||
pointer= maria_get_pointer_length((ci->data_file_length /
|
pointer= maria_get_pointer_length((ci->data_file_length /
|
||||||
@@ -314,7 +317,7 @@ int maria_create(const char *name, enum data_file_type record_type,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (record_type != STATIC_RECORD)
|
if (datafile_type != STATIC_RECORD)
|
||||||
pointer= maria_get_pointer_length(ci->data_file_length,
|
pointer= maria_get_pointer_length(ci->data_file_length,
|
||||||
maria_data_pointer_size);
|
maria_data_pointer_size);
|
||||||
else
|
else
|
||||||
@@ -324,7 +327,7 @@ int maria_create(const char *name, enum data_file_type record_type,
|
|||||||
}
|
}
|
||||||
|
|
||||||
real_reclength=reclength;
|
real_reclength=reclength;
|
||||||
if (record_type == STATIC_RECORD)
|
if (datafile_type == STATIC_RECORD)
|
||||||
{
|
{
|
||||||
if (reclength <= pointer)
|
if (reclength <= pointer)
|
||||||
reclength=pointer+1; /* reserve place for delete link */
|
reclength=pointer+1; /* reserve place for delete link */
|
||||||
@@ -533,7 +536,12 @@ int maria_create(const char *name, enum data_file_type record_type,
|
|||||||
key_segs)
|
key_segs)
|
||||||
share.state.rec_per_key_part[key_segs-1]=1L;
|
share.state.rec_per_key_part[key_segs-1]=1L;
|
||||||
length+=key_length;
|
length+=key_length;
|
||||||
if (length >= HA_MAX_KEY_BUFF)
|
/*
|
||||||
|
A key can't be longer than than half a index block (as we have
|
||||||
|
to be able to put at least 2 keys on an index block for the key
|
||||||
|
algorithms to work).
|
||||||
|
*/
|
||||||
|
if (length > maria_max_key_length())
|
||||||
{
|
{
|
||||||
my_errno=HA_WRONG_CREATE_OPTION;
|
my_errno=HA_WRONG_CREATE_OPTION;
|
||||||
goto err_no_lock;
|
goto err_no_lock;
|
||||||
@@ -592,8 +600,8 @@ int maria_create(const char *name, enum data_file_type record_type,
|
|||||||
mi_int2store(share.state.header.state_info_length,MARIA_STATE_INFO_SIZE);
|
mi_int2store(share.state.header.state_info_length,MARIA_STATE_INFO_SIZE);
|
||||||
mi_int2store(share.state.header.base_info_length,MARIA_BASE_INFO_SIZE);
|
mi_int2store(share.state.header.base_info_length,MARIA_BASE_INFO_SIZE);
|
||||||
mi_int2store(share.state.header.base_pos,base_pos);
|
mi_int2store(share.state.header.base_pos,base_pos);
|
||||||
share.state.header.data_file_type= record_type;
|
share.state.header.data_file_type= datafile_type;
|
||||||
share.state.header.org_data_file_type= org_record_type;
|
share.state.header.org_data_file_type= org_datafile_type;
|
||||||
share.state.header.language= (ci->language ?
|
share.state.header.language= (ci->language ?
|
||||||
ci->language : default_charset_info->number);
|
ci->language : default_charset_info->number);
|
||||||
|
|
||||||
@@ -653,7 +661,7 @@ int maria_create(const char *name, enum data_file_type record_type,
|
|||||||
share.base.max_data_file_length= (my_off_t) ci->data_file_length;
|
share.base.max_data_file_length= (my_off_t) ci->data_file_length;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (record_type == BLOCK_RECORD)
|
if (datafile_type == BLOCK_RECORD)
|
||||||
share.base.min_block_length= share.base.min_row_length;
|
share.base.min_block_length= share.base.min_row_length;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -869,7 +877,7 @@ int maria_create(const char *name, enum data_file_type record_type,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
DBUG_PRINT("info", ("write field definitions"));
|
DBUG_PRINT("info", ("write field definitions"));
|
||||||
if (record_type == BLOCK_RECORD)
|
if (datafile_type == BLOCK_RECORD)
|
||||||
{
|
{
|
||||||
/* Store columns in a more efficent order */
|
/* Store columns in a more efficent order */
|
||||||
MARIA_COLUMNDEF **col_order, **pos;
|
MARIA_COLUMNDEF **col_order, **pos;
|
||||||
@@ -877,13 +885,15 @@ int maria_create(const char *name, enum data_file_type record_type,
|
|||||||
sizeof(MARIA_COLUMNDEF*),
|
sizeof(MARIA_COLUMNDEF*),
|
||||||
MYF(MY_WME))))
|
MYF(MY_WME))))
|
||||||
goto err;
|
goto err;
|
||||||
for (rec= recinfo, pos= col_order ; rec != rec_end ; rec++, pos++)
|
for (column= columndef, pos= col_order ;
|
||||||
*pos= rec;
|
column != end_column ;
|
||||||
|
column++, pos++)
|
||||||
|
*pos= column;
|
||||||
qsort(col_order, share.base.fields, sizeof(*col_order),
|
qsort(col_order, share.base.fields, sizeof(*col_order),
|
||||||
(qsort_cmp) compare_columns);
|
(qsort_cmp) compare_columns);
|
||||||
for (i=0 ; i < share.base.fields ; i++)
|
for (i=0 ; i < share.base.fields ; i++)
|
||||||
{
|
{
|
||||||
if (_ma_recinfo_write(file, col_order[i]))
|
if (_ma_columndef_write(file, col_order[i]))
|
||||||
{
|
{
|
||||||
my_free((gptr) col_order, MYF(0));
|
my_free((gptr) col_order, MYF(0));
|
||||||
goto err;
|
goto err;
|
||||||
@@ -894,7 +904,7 @@ int maria_create(const char *name, enum data_file_type record_type,
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (i=0 ; i < share.base.fields ; i++)
|
for (i=0 ; i < share.base.fields ; i++)
|
||||||
if (_ma_recinfo_write(file, &recinfo[i]))
|
if (_ma_columndef_write(file, &columndef[i]))
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1026,9 +1036,9 @@ static int compare_columns(MARIA_COLUMNDEF **a_ptr, MARIA_COLUMNDEF **b_ptr)
|
|||||||
MARIA_COLUMNDEF *a= *a_ptr, *b= *b_ptr;
|
MARIA_COLUMNDEF *a= *a_ptr, *b= *b_ptr;
|
||||||
enum en_fieldtype a_type, b_type;
|
enum en_fieldtype a_type, b_type;
|
||||||
|
|
||||||
a_type= (a->type == FIELD_NORMAL || a->type == FIELD_CHECK ?
|
a_type= ((a->type == FIELD_NORMAL || a->type == FIELD_CHECK) ?
|
||||||
FIELD_NORMAL : a->type);
|
FIELD_NORMAL : a->type);
|
||||||
b_type= (b->type == FIELD_NORMAL || b->type == FIELD_CHECK ?
|
b_type= ((b->type == FIELD_NORMAL || b->type == FIELD_CHECK) ?
|
||||||
FIELD_NORMAL : b->type);
|
FIELD_NORMAL : b->type);
|
||||||
|
|
||||||
if (a_type == FIELD_NORMAL && !a->null_bit)
|
if (a_type == FIELD_NORMAL && !a->null_bit)
|
||||||
@@ -1059,14 +1069,7 @@ int _ma_initialize_data_file(File dfile, MARIA_SHARE *share)
|
|||||||
{
|
{
|
||||||
if (share->data_file_type == BLOCK_RECORD)
|
if (share->data_file_type == BLOCK_RECORD)
|
||||||
{
|
{
|
||||||
/* Write one bitmap page */
|
if (my_chsize(dfile, maria_block_size, 0, MYF(MY_WME)))
|
||||||
byte buff[IO_SIZE];
|
|
||||||
uint i;
|
|
||||||
bzero((char*) buff, sizeof(buff));
|
|
||||||
if (my_seek(dfile, 0, SEEK_SET, 0))
|
|
||||||
return 1;
|
|
||||||
for (i= 0 ; i < maria_block_size ; i+= IO_SIZE)
|
|
||||||
if (my_write(dfile, buff, sizeof(buff), MYF(MY_NABP)))
|
|
||||||
return 1;
|
return 1;
|
||||||
share->state.state.data_file_length= maria_block_size;
|
share->state.state.data_file_length= maria_block_size;
|
||||||
_ma_bitmap_delete_all(share);
|
_ma_bitmap_delete_all(share);
|
||||||
|
@@ -525,7 +525,7 @@ static int underflow(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
|
|||||||
DBUG_DUMP("leaf_buff",leaf_buff,maria_getint(leaf_buff));
|
DBUG_DUMP("leaf_buff",leaf_buff,maria_getint(leaf_buff));
|
||||||
|
|
||||||
buff=info->buff;
|
buff=info->buff;
|
||||||
info->keybuff_used=1;
|
info->keyread_buff_used=1;
|
||||||
next_keypos=keypos;
|
next_keypos=keypos;
|
||||||
nod_flag=_ma_test_if_nod(leaf_buff);
|
nod_flag=_ma_test_if_nod(leaf_buff);
|
||||||
p_length=nod_flag+2;
|
p_length=nod_flag+2;
|
||||||
|
@@ -883,7 +883,7 @@ uint _ma_rec_pack(MARIA_HA *info, register byte *to, register const byte *from)
|
|||||||
uint length,new_length,flag,bit,i;
|
uint length,new_length,flag,bit,i;
|
||||||
char *pos,*end,*startpos,*packpos;
|
char *pos,*end,*startpos,*packpos;
|
||||||
enum en_fieldtype type;
|
enum en_fieldtype type;
|
||||||
reg3 MARIA_COLUMNDEF *rec;
|
reg3 MARIA_COLUMNDEF *column;
|
||||||
MARIA_BLOB *blob;
|
MARIA_BLOB *blob;
|
||||||
DBUG_ENTER("_ma_rec_pack");
|
DBUG_ENTER("_ma_rec_pack");
|
||||||
|
|
||||||
@@ -892,7 +892,7 @@ uint _ma_rec_pack(MARIA_HA *info, register byte *to, register const byte *from)
|
|||||||
startpos= packpos=to;
|
startpos= packpos=to;
|
||||||
to+= info->s->base.pack_bytes;
|
to+= info->s->base.pack_bytes;
|
||||||
blob= info->blobs;
|
blob= info->blobs;
|
||||||
rec= info->s->rec;
|
column= info->s->columndef;
|
||||||
if (info->s->base.null_bytes)
|
if (info->s->base.null_bytes)
|
||||||
{
|
{
|
||||||
memcpy(to, from, info->s->base.null_bytes);
|
memcpy(to, from, info->s->base.null_bytes);
|
||||||
@@ -900,10 +900,10 @@ uint _ma_rec_pack(MARIA_HA *info, register byte *to, register const byte *from)
|
|||||||
to+= info->s->base.null_bytes;
|
to+= info->s->base.null_bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i=info->s->base.fields ; i-- > 0; from+= length,rec++)
|
for (i=info->s->base.fields ; i-- > 0; from+= length, column++)
|
||||||
{
|
{
|
||||||
length=(uint) rec->length;
|
length=(uint) column->length;
|
||||||
if ((type = (enum en_fieldtype) rec->type) != FIELD_NORMAL)
|
if ((type = (enum en_fieldtype) column->type) != FIELD_NORMAL)
|
||||||
{
|
{
|
||||||
if (type == FIELD_BLOB)
|
if (type == FIELD_BLOB)
|
||||||
{
|
{
|
||||||
@@ -912,7 +912,7 @@ uint _ma_rec_pack(MARIA_HA *info, register byte *to, register const byte *from)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
char *temp_pos;
|
char *temp_pos;
|
||||||
size_t tmp_length=length-maria_portable_sizeof_char_ptr;
|
size_t tmp_length=length-portable_sizeof_char_ptr;
|
||||||
memcpy((byte*) to,from,tmp_length);
|
memcpy((byte*) to,from,tmp_length);
|
||||||
memcpy_fixed(&temp_pos,from+tmp_length,sizeof(char*));
|
memcpy_fixed(&temp_pos,from+tmp_length,sizeof(char*));
|
||||||
memcpy(to+tmp_length,temp_pos,(size_t) blob->length);
|
memcpy(to+tmp_length,temp_pos,(size_t) blob->length);
|
||||||
@@ -944,10 +944,10 @@ uint _ma_rec_pack(MARIA_HA *info, register byte *to, register const byte *from)
|
|||||||
pos++;
|
pos++;
|
||||||
}
|
}
|
||||||
new_length=(uint) (end-pos);
|
new_length=(uint) (end-pos);
|
||||||
if (new_length +1 + test(rec->length > 255 && new_length > 127)
|
if (new_length +1 + test(column->length > 255 && new_length > 127)
|
||||||
< length)
|
< length)
|
||||||
{
|
{
|
||||||
if (rec->length > 255 && new_length > 127)
|
if (column->length > 255 && new_length > 127)
|
||||||
{
|
{
|
||||||
to[0]=(char) ((new_length & 127)+128);
|
to[0]=(char) ((new_length & 127)+128);
|
||||||
to[1]=(char) (new_length >> 7);
|
to[1]=(char) (new_length >> 7);
|
||||||
@@ -965,7 +965,7 @@ uint _ma_rec_pack(MARIA_HA *info, register byte *to, register const byte *from)
|
|||||||
}
|
}
|
||||||
else if (type == FIELD_VARCHAR)
|
else if (type == FIELD_VARCHAR)
|
||||||
{
|
{
|
||||||
uint pack_length= HA_VARCHAR_PACKLENGTH(rec->length -1);
|
uint pack_length= HA_VARCHAR_PACKLENGTH(column->length -1);
|
||||||
uint tmp_length;
|
uint tmp_length;
|
||||||
if (pack_length == 1)
|
if (pack_length == 1)
|
||||||
{
|
{
|
||||||
@@ -1018,28 +1018,28 @@ my_bool _ma_rec_check(MARIA_HA *info,const char *record, byte *rec_buff,
|
|||||||
uint length,new_length,flag,bit,i;
|
uint length,new_length,flag,bit,i;
|
||||||
char *pos,*end,*packpos,*to;
|
char *pos,*end,*packpos,*to;
|
||||||
enum en_fieldtype type;
|
enum en_fieldtype type;
|
||||||
reg3 MARIA_COLUMNDEF *rec;
|
reg3 MARIA_COLUMNDEF *column;
|
||||||
DBUG_ENTER("_ma_rec_check");
|
DBUG_ENTER("_ma_rec_check");
|
||||||
|
|
||||||
packpos=rec_buff; to= rec_buff+info->s->base.pack_bytes;
|
packpos=rec_buff; to= rec_buff+info->s->base.pack_bytes;
|
||||||
rec=info->s->rec;
|
column= info->s->columndef;
|
||||||
flag= *packpos; bit=1;
|
flag= *packpos; bit=1;
|
||||||
record+= info->s->base.null_bytes;
|
record+= info->s->base.null_bytes;
|
||||||
to+= info->s->base.null_bytes;
|
to+= info->s->base.null_bytes;
|
||||||
|
|
||||||
for (i=info->s->base.fields ; i-- > 0; record+= length, rec++)
|
for (i=info->s->base.fields ; i-- > 0; record+= length, column++)
|
||||||
{
|
{
|
||||||
length=(uint) rec->length;
|
length=(uint) column->length;
|
||||||
if ((type = (enum en_fieldtype) rec->type) != FIELD_NORMAL)
|
if ((type = (enum en_fieldtype) column->type) != FIELD_NORMAL)
|
||||||
{
|
{
|
||||||
if (type == FIELD_BLOB)
|
if (type == FIELD_BLOB)
|
||||||
{
|
{
|
||||||
uint blob_length=
|
uint blob_length=
|
||||||
_ma_calc_blob_length(length-maria_portable_sizeof_char_ptr,record);
|
_ma_calc_blob_length(length-portable_sizeof_char_ptr,record);
|
||||||
if (!blob_length && !(flag & bit))
|
if (!blob_length && !(flag & bit))
|
||||||
goto err;
|
goto err;
|
||||||
if (blob_length)
|
if (blob_length)
|
||||||
to+=length - maria_portable_sizeof_char_ptr+ blob_length;
|
to+=length - portable_sizeof_char_ptr+ blob_length;
|
||||||
}
|
}
|
||||||
else if (type == FIELD_SKIP_ZERO)
|
else if (type == FIELD_SKIP_ZERO)
|
||||||
{
|
{
|
||||||
@@ -1066,12 +1066,12 @@ my_bool _ma_rec_check(MARIA_HA *info,const char *record, byte *rec_buff,
|
|||||||
pos++;
|
pos++;
|
||||||
}
|
}
|
||||||
new_length=(uint) (end-pos);
|
new_length=(uint) (end-pos);
|
||||||
if (new_length +1 + test(rec->length > 255 && new_length > 127)
|
if (new_length +1 + test(column->length > 255 && new_length > 127)
|
||||||
< length)
|
< length)
|
||||||
{
|
{
|
||||||
if (!(flag & bit))
|
if (!(flag & bit))
|
||||||
goto err;
|
goto err;
|
||||||
if (rec->length > 255 && new_length > 127)
|
if (column->length > 255 && new_length > 127)
|
||||||
{
|
{
|
||||||
if (to[0] != (char) ((new_length & 127)+128) ||
|
if (to[0] != (char) ((new_length & 127)+128) ||
|
||||||
to[1] != (char) (new_length >> 7))
|
to[1] != (char) (new_length >> 7))
|
||||||
@@ -1087,7 +1087,7 @@ my_bool _ma_rec_check(MARIA_HA *info,const char *record, byte *rec_buff,
|
|||||||
}
|
}
|
||||||
else if (type == FIELD_VARCHAR)
|
else if (type == FIELD_VARCHAR)
|
||||||
{
|
{
|
||||||
uint pack_length= HA_VARCHAR_PACKLENGTH(rec->length -1);
|
uint pack_length= HA_VARCHAR_PACKLENGTH(column->length -1);
|
||||||
uint tmp_length;
|
uint tmp_length;
|
||||||
if (pack_length == 1)
|
if (pack_length == 1)
|
||||||
{
|
{
|
||||||
@@ -1139,10 +1139,10 @@ err:
|
|||||||
ulong _ma_rec_unpack(register MARIA_HA *info, register byte *to, byte *from,
|
ulong _ma_rec_unpack(register MARIA_HA *info, register byte *to, byte *from,
|
||||||
ulong found_length)
|
ulong found_length)
|
||||||
{
|
{
|
||||||
uint flag,bit,length,rec_length,min_pack_length;
|
uint flag,bit,length,min_pack_length, column_length;
|
||||||
enum en_fieldtype type;
|
enum en_fieldtype type;
|
||||||
byte *from_end,*to_end,*packpos;
|
byte *from_end,*to_end,*packpos;
|
||||||
reg3 MARIA_COLUMNDEF *rec,*end_field;
|
reg3 MARIA_COLUMNDEF *column, *end_column;
|
||||||
DBUG_ENTER("_ma_rec_unpack");
|
DBUG_ENTER("_ma_rec_unpack");
|
||||||
|
|
||||||
to_end=to + info->s->base.reclength;
|
to_end=to + info->s->base.reclength;
|
||||||
@@ -1161,27 +1161,27 @@ ulong _ma_rec_unpack(register MARIA_HA *info, register byte *to, byte *from,
|
|||||||
min_pack_length-= length;
|
min_pack_length-= length;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (rec=info->s->rec , end_field=rec+info->s->base.fields ;
|
for (column= info->s->columndef, end_column= column + info->s->base.fields;
|
||||||
rec < end_field ; to+= rec_length, rec++)
|
column < end_column ; to+= column_length, column++)
|
||||||
{
|
{
|
||||||
rec_length=rec->length;
|
column_length= column->length;
|
||||||
if ((type = (enum en_fieldtype) rec->type) != FIELD_NORMAL &&
|
if ((type = (enum en_fieldtype) column->type) != FIELD_NORMAL &&
|
||||||
(type != FIELD_CHECK))
|
(type != FIELD_CHECK))
|
||||||
{
|
{
|
||||||
if (type == FIELD_VARCHAR)
|
if (type == FIELD_VARCHAR)
|
||||||
{
|
{
|
||||||
uint pack_length= HA_VARCHAR_PACKLENGTH(rec_length-1);
|
uint pack_length= HA_VARCHAR_PACKLENGTH(column_length-1);
|
||||||
if (pack_length == 1)
|
if (pack_length == 1)
|
||||||
{
|
{
|
||||||
length= (uint) *(uchar*) from;
|
length= (uint) *(uchar*) from;
|
||||||
if (length > rec_length-1)
|
if (length > column_length-1)
|
||||||
goto err;
|
goto err;
|
||||||
*to= *from++;
|
*to= *from++;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
get_key_length(length, from);
|
get_key_length(length, from);
|
||||||
if (length > rec_length-2)
|
if (length > column_length-2)
|
||||||
goto err;
|
goto err;
|
||||||
int2store(to,length);
|
int2store(to,length);
|
||||||
}
|
}
|
||||||
@@ -1195,11 +1195,11 @@ ulong _ma_rec_unpack(register MARIA_HA *info, register byte *to, byte *from,
|
|||||||
if (flag & bit)
|
if (flag & bit)
|
||||||
{
|
{
|
||||||
if (type == FIELD_BLOB || type == FIELD_SKIP_ZERO)
|
if (type == FIELD_BLOB || type == FIELD_SKIP_ZERO)
|
||||||
bzero((byte*) to,rec_length);
|
bzero((byte*) to,column_length);
|
||||||
else if (type == FIELD_SKIP_ENDSPACE ||
|
else if (type == FIELD_SKIP_ENDSPACE ||
|
||||||
type == FIELD_SKIP_PRESPACE)
|
type == FIELD_SKIP_PRESPACE)
|
||||||
{
|
{
|
||||||
if (rec->length > 255 && *from & 128)
|
if (column->length > 255 && *from & 128)
|
||||||
{
|
{
|
||||||
if (from + 1 >= from_end)
|
if (from + 1 >= from_end)
|
||||||
goto err;
|
goto err;
|
||||||
@@ -1212,25 +1212,25 @@ ulong _ma_rec_unpack(register MARIA_HA *info, register byte *to, byte *from,
|
|||||||
length= (uchar) *from++;
|
length= (uchar) *from++;
|
||||||
}
|
}
|
||||||
min_pack_length--;
|
min_pack_length--;
|
||||||
if (length >= rec_length ||
|
if (length >= column_length ||
|
||||||
min_pack_length + length > (uint) (from_end - from))
|
min_pack_length + length > (uint) (from_end - from))
|
||||||
goto err;
|
goto err;
|
||||||
if (type == FIELD_SKIP_ENDSPACE)
|
if (type == FIELD_SKIP_ENDSPACE)
|
||||||
{
|
{
|
||||||
memcpy(to,(byte*) from,(size_t) length);
|
memcpy(to,(byte*) from,(size_t) length);
|
||||||
bfill((byte*) to+length,rec_length-length,' ');
|
bfill((byte*) to+length,column_length-length,' ');
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
bfill((byte*) to,rec_length-length,' ');
|
bfill((byte*) to,column_length-length,' ');
|
||||||
memcpy(to+rec_length-length,(byte*) from,(size_t) length);
|
memcpy(to+column_length-length,(byte*) from,(size_t) length);
|
||||||
}
|
}
|
||||||
from+=length;
|
from+=length;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (type == FIELD_BLOB)
|
else if (type == FIELD_BLOB)
|
||||||
{
|
{
|
||||||
uint size_length=rec_length- maria_portable_sizeof_char_ptr;
|
uint size_length=column_length- portable_sizeof_char_ptr;
|
||||||
ulong blob_length= _ma_calc_blob_length(size_length,from);
|
ulong blob_length= _ma_calc_blob_length(size_length,from);
|
||||||
ulong from_left= (ulong) (from_end - from);
|
ulong from_left= (ulong) (from_end - from);
|
||||||
if (from_left < size_length ||
|
if (from_left < size_length ||
|
||||||
@@ -1246,9 +1246,9 @@ ulong _ma_rec_unpack(register MARIA_HA *info, register byte *to, byte *from,
|
|||||||
{
|
{
|
||||||
if (type == FIELD_SKIP_ENDSPACE || type == FIELD_SKIP_PRESPACE)
|
if (type == FIELD_SKIP_ENDSPACE || type == FIELD_SKIP_PRESPACE)
|
||||||
min_pack_length--;
|
min_pack_length--;
|
||||||
if (min_pack_length + rec_length > (uint) (from_end - from))
|
if (min_pack_length + column_length > (uint) (from_end - from))
|
||||||
goto err;
|
goto err;
|
||||||
memcpy(to,(byte*) from,(size_t) rec_length); from+=rec_length;
|
memcpy(to,(byte*) from,(size_t) column_length); from+=column_length;
|
||||||
}
|
}
|
||||||
if ((bit= bit << 1) >= 256)
|
if ((bit= bit << 1) >= 256)
|
||||||
{
|
{
|
||||||
@@ -1259,9 +1259,9 @@ ulong _ma_rec_unpack(register MARIA_HA *info, register byte *to, byte *from,
|
|||||||
{
|
{
|
||||||
if (min_pack_length > (uint) (from_end - from))
|
if (min_pack_length > (uint) (from_end - from))
|
||||||
goto err;
|
goto err;
|
||||||
min_pack_length-=rec_length;
|
min_pack_length-=column_length;
|
||||||
memcpy(to, (byte*) from, (size_t) rec_length);
|
memcpy(to, (byte*) from, (size_t) column_length);
|
||||||
from+=rec_length;
|
from+=column_length;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (info->s->calc_checksum)
|
if (info->s->calc_checksum)
|
||||||
@@ -1620,7 +1620,7 @@ err:
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Read record from datafile.
|
Read next record from datafile during table scan.
|
||||||
|
|
||||||
SYNOPSIS
|
SYNOPSIS
|
||||||
_ma_read_rnd_dynamic_record()
|
_ma_read_rnd_dynamic_record()
|
||||||
@@ -1631,22 +1631,17 @@ err:
|
|||||||
record is found.
|
record is found.
|
||||||
|
|
||||||
NOTE
|
NOTE
|
||||||
|
This is identical to _ma_read_dynamic_record(), except the following
|
||||||
|
cases:
|
||||||
|
|
||||||
If a write buffer is active, it needs to be flushed if its contents
|
- If there is no active row at 'filepos', continue scanning for
|
||||||
intersects with the record to read. We always check if the position
|
an active row. (This is becasue the previous
|
||||||
of the first byte of the write buffer is lower than the position
|
_ma_read_rnd_dynamic_record() call stored the next block position
|
||||||
past the last byte to read. In theory this is also true if the write
|
in filepos, but this position may not be a start block for a row
|
||||||
buffer is completely below the read segment. That is, if there is no
|
- We may have READ_CACHING enabled, in which case we use the cache
|
||||||
intersection. But this case is unusual. We flush anyway. Only if the
|
to read rows.
|
||||||
first byte in the write buffer is above the last byte to read, we do
|
|
||||||
not flush.
|
|
||||||
|
|
||||||
A dynamic record may need several reads. So this check must be done
|
For other comments, check _ma_read_dynamic_record()
|
||||||
before every read. Reading a dynamic record starts with reading the
|
|
||||||
block header. If the record does not fit into the free space of the
|
|
||||||
header, the block may be longer than the header. In this case a
|
|
||||||
second read is necessary. These one or two reads repeat for every
|
|
||||||
part of the record.
|
|
||||||
|
|
||||||
RETURN
|
RETURN
|
||||||
0 OK
|
0 OK
|
||||||
|
@@ -49,7 +49,7 @@ int main(int argc, char *argv[])
|
|||||||
recinfo[0].type=FIELD_SKIP_ENDSPACE;
|
recinfo[0].type=FIELD_SKIP_ENDSPACE;
|
||||||
recinfo[0].length=docid_length;
|
recinfo[0].length=docid_length;
|
||||||
recinfo[1].type=FIELD_BLOB;
|
recinfo[1].type=FIELD_BLOB;
|
||||||
recinfo[1].length= 4+maria_portable_sizeof_char_ptr;
|
recinfo[1].length= 4+portable_sizeof_char_ptr;
|
||||||
|
|
||||||
/* Define a key over the first column */
|
/* Define a key over the first column */
|
||||||
keyinfo[0].seg=keyseg;
|
keyinfo[0].seg=keyseg;
|
||||||
|
@@ -76,12 +76,12 @@ static int run_test(const char *filename)
|
|||||||
|
|
||||||
/* First define 2 columns */
|
/* First define 2 columns */
|
||||||
recinfo[0].type=extra_field;
|
recinfo[0].type=extra_field;
|
||||||
recinfo[0].length= (extra_field == FIELD_BLOB ? 4 + maria_portable_sizeof_char_ptr :
|
recinfo[0].length= (extra_field == FIELD_BLOB ? 4 + portable_sizeof_char_ptr :
|
||||||
extra_length);
|
extra_length);
|
||||||
if (extra_field == FIELD_VARCHAR)
|
if (extra_field == FIELD_VARCHAR)
|
||||||
recinfo[0].length+= HA_VARCHAR_PACKLENGTH(extra_length);
|
recinfo[0].length+= HA_VARCHAR_PACKLENGTH(extra_length);
|
||||||
recinfo[1].type=key_field;
|
recinfo[1].type=key_field;
|
||||||
recinfo[1].length= (key_field == FIELD_BLOB ? 4+maria_portable_sizeof_char_ptr :
|
recinfo[1].length= (key_field == FIELD_BLOB ? 4+portable_sizeof_char_ptr :
|
||||||
key_length);
|
key_length);
|
||||||
if (key_field == FIELD_VARCHAR)
|
if (key_field == FIELD_VARCHAR)
|
||||||
recinfo[1].length+= HA_VARCHAR_PACKLENGTH(key_length);
|
recinfo[1].length+= HA_VARCHAR_PACKLENGTH(key_length);
|
||||||
|
@@ -329,7 +329,7 @@ uint _ma_ft_convert_to_ft2(MARIA_HA *info, uint keynr, byte *key)
|
|||||||
/* creating pageful of keys */
|
/* creating pageful of keys */
|
||||||
maria_putint(info->buff,length+2,0);
|
maria_putint(info->buff,length+2,0);
|
||||||
memcpy(info->buff+2, key_ptr, length);
|
memcpy(info->buff+2, key_ptr, length);
|
||||||
info->keybuff_used=info->page_changed=1; /* info->buff is used */
|
info->keyread_buff_used=info->page_changed=1; /* info->buff is used */
|
||||||
if ((root= _ma_new(info,keyinfo,DFLT_INIT_HITS)) == HA_OFFSET_ERROR ||
|
if ((root= _ma_new(info,keyinfo,DFLT_INIT_HITS)) == HA_OFFSET_ERROR ||
|
||||||
_ma_write_keypage(info,keyinfo,root,DFLT_INIT_HITS,info->buff))
|
_ma_write_keypage(info,keyinfo,root,DFLT_INIT_HITS,info->buff))
|
||||||
DBUG_RETURN(-1);
|
DBUG_RETURN(-1);
|
||||||
|
@@ -126,11 +126,15 @@ void _ma_report_error(int errcode, const char *file_name)
|
|||||||
|
|
||||||
if ((length= strlen(file_name)) > 64)
|
if ((length= strlen(file_name)) > 64)
|
||||||
{
|
{
|
||||||
|
/* we first remove the directory */
|
||||||
uint dir_length= dirname_length(file_name);
|
uint dir_length= dirname_length(file_name);
|
||||||
file_name+= dir_length;
|
file_name+= dir_length;
|
||||||
if ((length-= dir_length) > 64)
|
if ((length-= dir_length) > 64)
|
||||||
|
{
|
||||||
|
/* still too long, chop start of table name */
|
||||||
file_name+= length - 64;
|
file_name+= length - 64;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
my_error(errcode, MYF(ME_NOREFRESH), file_name);
|
my_error(errcode, MYF(ME_NOREFRESH), file_name);
|
||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
}
|
}
|
||||||
|
@@ -232,13 +232,21 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags)
|
|||||||
}
|
}
|
||||||
|
|
||||||
key_parts+=fulltext_keys*FT_SEGS;
|
key_parts+=fulltext_keys*FT_SEGS;
|
||||||
if (share->base.max_key_length > HA_MAX_KEY_BUFF || keys > MARIA_MAX_KEY ||
|
if (share->base.max_key_length > maria_max_key_length() ||
|
||||||
key_parts >= MARIA_MAX_KEY * HA_MAX_KEY_SEG)
|
keys > MARIA_MAX_KEY || key_parts >= MARIA_MAX_KEY * HA_MAX_KEY_SEG)
|
||||||
{
|
{
|
||||||
DBUG_PRINT("error",("Wrong key info: Max_key_length: %d keys: %d key_parts: %d", share->base.max_key_length, keys, key_parts));
|
DBUG_PRINT("error",("Wrong key info: Max_key_length: %d keys: %d key_parts: %d", share->base.max_key_length, keys, key_parts));
|
||||||
my_errno=HA_ERR_UNSUPPORTED;
|
my_errno=HA_ERR_UNSUPPORTED;
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
if (share->base.block_size != maria_block_size)
|
||||||
|
{
|
||||||
|
DBUG_PRINT("error", ("Wrong block size %u; Expected %u",
|
||||||
|
(uint) share->base.block_size,
|
||||||
|
(uint) maria_block_size));
|
||||||
|
my_errno=HA_ERR_UNSUPPORTED;
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
/* Correct max_file_length based on length of sizeof(off_t) */
|
/* Correct max_file_length based on length of sizeof(off_t) */
|
||||||
max_data_file_length=
|
max_data_file_length=
|
||||||
@@ -268,7 +276,7 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags)
|
|||||||
&share->keyparts,
|
&share->keyparts,
|
||||||
(key_parts+unique_key_parts+keys+uniques) *
|
(key_parts+unique_key_parts+keys+uniques) *
|
||||||
sizeof(HA_KEYSEG),
|
sizeof(HA_KEYSEG),
|
||||||
&share->rec,
|
&share->columndef,
|
||||||
(share->base.fields+1)*sizeof(MARIA_COLUMNDEF),
|
(share->base.fields+1)*sizeof(MARIA_COLUMNDEF),
|
||||||
&share->blobs,sizeof(MARIA_BLOB)*share->base.blobs,
|
&share->blobs,sizeof(MARIA_BLOB)*share->base.blobs,
|
||||||
&share->unique_file_name,strlen(name_buff)+1,
|
&share->unique_file_name,strlen(name_buff)+1,
|
||||||
@@ -304,7 +312,6 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags)
|
|||||||
end_pos);
|
end_pos);
|
||||||
if (share->keyinfo[i].key_alg == HA_KEY_ALG_RTREE)
|
if (share->keyinfo[i].key_alg == HA_KEY_ALG_RTREE)
|
||||||
have_rtree=1;
|
have_rtree=1;
|
||||||
set_if_smaller(share->block_size,share->keyinfo[i].block_length);
|
|
||||||
share->keyinfo[i].seg=pos;
|
share->keyinfo[i].seg=pos;
|
||||||
for (j=0 ; j < share->keyinfo[i].keysegs; j++,pos++)
|
for (j=0 ; j < share->keyinfo[i].keysegs; j++,pos++)
|
||||||
{
|
{
|
||||||
@@ -430,18 +437,18 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags)
|
|||||||
end_pos);
|
end_pos);
|
||||||
for (i= j= 0 ; i < share->base.fields ; i++)
|
for (i= j= 0 ; i < share->base.fields ; i++)
|
||||||
{
|
{
|
||||||
disk_pos=_ma_recinfo_read(disk_pos,&share->rec[i]);
|
disk_pos=_ma_columndef_read(disk_pos,&share->columndef[i]);
|
||||||
share->rec[i].pack_type=0;
|
share->columndef[i].pack_type=0;
|
||||||
share->rec[i].huff_tree=0;
|
share->columndef[i].huff_tree=0;
|
||||||
if (share->rec[i].type == (int) FIELD_BLOB)
|
if (share->columndef[i].type == (int) FIELD_BLOB)
|
||||||
{
|
{
|
||||||
share->blobs[j].pack_length=
|
share->blobs[j].pack_length=
|
||||||
share->rec[i].length-maria_portable_sizeof_char_ptr;;
|
share->columndef[i].length-portable_sizeof_char_ptr;;
|
||||||
share->blobs[j].offset= share->rec[i].offset;
|
share->blobs[j].offset= share->columndef[i].offset;
|
||||||
j++;
|
j++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
share->rec[i].type=(int) FIELD_LAST; /* End marker */
|
share->columndef[i].type=(int) FIELD_LAST; /* End marker */
|
||||||
#ifdef ASKMONTY
|
#ifdef ASKMONTY
|
||||||
/*
|
/*
|
||||||
This code was added to mi_open.c in this cset:
|
This code was added to mi_open.c in this cset:
|
||||||
@@ -718,8 +725,8 @@ void _ma_setup_functions(register MARIA_SHARE *share)
|
|||||||
share->once_end= maria_once_end_dummy;
|
share->once_end= maria_once_end_dummy;
|
||||||
share->init= maria_scan_init_dummy;
|
share->init= maria_scan_init_dummy;
|
||||||
share->end= maria_scan_end_dummy;
|
share->end= maria_scan_end_dummy;
|
||||||
share->scan_init= maria_scan_init_dummy;
|
share->scan_init= maria_scan_init_dummy;/* Compat. dummy function */
|
||||||
share->scan_end= maria_scan_end_dummy;
|
share->scan_end= maria_scan_end_dummy;/* Compat. dummy function */
|
||||||
share->write_record_init= _ma_write_init_default;
|
share->write_record_init= _ma_write_init_default;
|
||||||
share->write_record_abort= _ma_write_abort_default;
|
share->write_record_abort= _ma_write_abort_default;
|
||||||
|
|
||||||
@@ -729,7 +736,10 @@ void _ma_setup_functions(register MARIA_SHARE *share)
|
|||||||
share->scan= _ma_read_rnd_pack_record;
|
share->scan= _ma_read_rnd_pack_record;
|
||||||
share->once_init= _ma_once_init_pack_row;
|
share->once_init= _ma_once_init_pack_row;
|
||||||
share->once_end= _ma_once_end_pack_row;
|
share->once_end= _ma_once_end_pack_row;
|
||||||
/* Calculate checksum according how the original row was stored */
|
/*
|
||||||
|
Calculate checksum according to data in the original, not compressed,
|
||||||
|
row.
|
||||||
|
*/
|
||||||
if (share->state.header.org_data_file_type == STATIC_RECORD)
|
if (share->state.header.org_data_file_type == STATIC_RECORD)
|
||||||
share->calc_checksum= _ma_static_checksum;
|
share->calc_checksum= _ma_static_checksum;
|
||||||
else
|
else
|
||||||
@@ -767,10 +777,10 @@ void _ma_setup_functions(register MARIA_SHARE *share)
|
|||||||
share->calc_checksum= share->calc_write_checksum= _ma_static_checksum;
|
share->calc_checksum= share->calc_write_checksum= _ma_static_checksum;
|
||||||
break;
|
break;
|
||||||
case BLOCK_RECORD:
|
case BLOCK_RECORD:
|
||||||
share->once_init= _ma_once_init_block_row;
|
share->once_init= _ma_once_init_block_record;
|
||||||
share->once_end= _ma_once_end_block_row;
|
share->once_end= _ma_once_end_block_record;
|
||||||
share->init= _ma_init_block_row;
|
share->init= _ma_init_block_record;
|
||||||
share->end= _ma_end_block_row;
|
share->end= _ma_end_block_record;
|
||||||
share->write_record_init= _ma_write_init_block_record;
|
share->write_record_init= _ma_write_init_block_record;
|
||||||
share->write_record_abort= _ma_write_abort_block_record;
|
share->write_record_abort= _ma_write_abort_block_record;
|
||||||
share->scan_init= _ma_scan_init_block_record;
|
share->scan_init= _ma_scan_init_block_record;
|
||||||
@@ -783,6 +793,10 @@ void _ma_setup_functions(register MARIA_SHARE *share)
|
|||||||
share->write_record= _ma_write_block_record;
|
share->write_record= _ma_write_block_record;
|
||||||
share->compare_unique= _ma_cmp_block_unique;
|
share->compare_unique= _ma_cmp_block_unique;
|
||||||
share->calc_checksum= _ma_checksum;
|
share->calc_checksum= _ma_checksum;
|
||||||
|
/*
|
||||||
|
write_block_record() will calculate the checksum; Tell maria_write()
|
||||||
|
that it doesn't have to do this.
|
||||||
|
*/
|
||||||
share->calc_write_checksum= 0;
|
share->calc_write_checksum= 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1187,32 +1201,32 @@ char *_ma_uniquedef_read(char *ptr, MARIA_UNIQUEDEF *def)
|
|||||||
** MARIA_COLUMNDEF
|
** MARIA_COLUMNDEF
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
uint _ma_recinfo_write(File file, MARIA_COLUMNDEF *recinfo)
|
uint _ma_columndef_write(File file, MARIA_COLUMNDEF *columndef)
|
||||||
{
|
{
|
||||||
uchar buff[MARIA_COLUMNDEF_SIZE];
|
uchar buff[MARIA_COLUMNDEF_SIZE];
|
||||||
uchar *ptr=buff;
|
uchar *ptr=buff;
|
||||||
|
|
||||||
mi_int6store(ptr,recinfo->offset); ptr+= 6;
|
mi_int6store(ptr,columndef->offset); ptr+= 6;
|
||||||
mi_int2store(ptr,recinfo->type); ptr+= 2;
|
mi_int2store(ptr,columndef->type); ptr+= 2;
|
||||||
mi_int2store(ptr,recinfo->length); ptr+= 2;
|
mi_int2store(ptr,columndef->length); ptr+= 2;
|
||||||
mi_int2store(ptr,recinfo->fill_length); ptr+= 2;
|
mi_int2store(ptr,columndef->fill_length); ptr+= 2;
|
||||||
mi_int2store(ptr,recinfo->null_pos); ptr+= 2;
|
mi_int2store(ptr,columndef->null_pos); ptr+= 2;
|
||||||
mi_int2store(ptr,recinfo->empty_pos); ptr+= 2;
|
mi_int2store(ptr,columndef->empty_pos); ptr+= 2;
|
||||||
(*ptr++)= recinfo->null_bit;
|
(*ptr++)= columndef->null_bit;
|
||||||
(*ptr++)= recinfo->empty_bit;
|
(*ptr++)= columndef->empty_bit;
|
||||||
return my_write(file,(char*) buff, (uint) (ptr-buff), MYF(MY_NABP));
|
return my_write(file,(char*) buff, (uint) (ptr-buff), MYF(MY_NABP));
|
||||||
}
|
}
|
||||||
|
|
||||||
char *_ma_recinfo_read(char *ptr, MARIA_COLUMNDEF *recinfo)
|
char *_ma_columndef_read(char *ptr, MARIA_COLUMNDEF *columndef)
|
||||||
{
|
{
|
||||||
recinfo->offset= mi_uint6korr(ptr); ptr+= 6;
|
columndef->offset= mi_uint6korr(ptr); ptr+= 6;
|
||||||
recinfo->type= mi_sint2korr(ptr); ptr+= 2;
|
columndef->type= mi_sint2korr(ptr); ptr+= 2;
|
||||||
recinfo->length= mi_uint2korr(ptr); ptr+= 2;
|
columndef->length= mi_uint2korr(ptr); ptr+= 2;
|
||||||
recinfo->fill_length= mi_uint2korr(ptr); ptr+= 2;
|
columndef->fill_length= mi_uint2korr(ptr); ptr+= 2;
|
||||||
recinfo->null_pos= mi_uint2korr(ptr); ptr+= 2;
|
columndef->null_pos= mi_uint2korr(ptr); ptr+= 2;
|
||||||
recinfo->empty_pos= mi_uint2korr(ptr); ptr+= 2;
|
columndef->empty_pos= mi_uint2korr(ptr); ptr+= 2;
|
||||||
recinfo->null_bit= (uint8) *ptr++;
|
columndef->null_bit= (uint8) *ptr++;
|
||||||
recinfo->empty_bit= (uint8) *ptr++;
|
columndef->empty_bit= (uint8) *ptr++;
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -142,15 +142,14 @@ static maria_bit_type mask[]=
|
|||||||
my_bool _ma_once_init_pack_row(MARIA_SHARE *share, File dfile)
|
my_bool _ma_once_init_pack_row(MARIA_SHARE *share, File dfile)
|
||||||
{
|
{
|
||||||
share->options|= HA_OPTION_READ_ONLY_DATA;
|
share->options|= HA_OPTION_READ_ONLY_DATA;
|
||||||
if (_ma_read_pack_info(share, dfile,
|
return (_ma_read_pack_info(share, dfile,
|
||||||
(pbool)
|
(pbool)
|
||||||
test(!(share->options &
|
test(!(share->options &
|
||||||
(HA_OPTION_PACK_RECORD |
|
(HA_OPTION_PACK_RECORD |
|
||||||
HA_OPTION_TEMP_COMPRESS_RECORD)))))
|
HA_OPTION_TEMP_COMPRESS_RECORD)))));
|
||||||
return 1;
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
my_bool _ma_once_end_pack_row(MARIA_SHARE *share)
|
my_bool _ma_once_end_pack_row(MARIA_SHARE *share)
|
||||||
{
|
{
|
||||||
if (share->decode_trees)
|
if (share->decode_trees)
|
||||||
@@ -262,15 +261,16 @@ static my_bool _ma_read_pack_info(MARIA_SHARE *share, File file,
|
|||||||
/* Read new info for each field */
|
/* Read new info for each field */
|
||||||
for (i=0 ; i < share->base.fields ; i++)
|
for (i=0 ; i < share->base.fields ; i++)
|
||||||
{
|
{
|
||||||
share->rec[i].base_type=(enum en_fieldtype) get_bits(&bit_buff,5);
|
share->columndef[i].base_type=(enum en_fieldtype) get_bits(&bit_buff,5);
|
||||||
share->rec[i].pack_type=(uint) get_bits(&bit_buff,6);
|
share->columndef[i].pack_type=(uint) get_bits(&bit_buff,6);
|
||||||
share->rec[i].space_length_bits=get_bits(&bit_buff,5);
|
share->columndef[i].space_length_bits=get_bits(&bit_buff,5);
|
||||||
share->rec[i].huff_tree=share->decode_trees+(uint) get_bits(&bit_buff,
|
share->columndef[i].huff_tree=share->decode_trees+(uint) get_bits(&bit_buff,
|
||||||
huff_tree_bits);
|
huff_tree_bits);
|
||||||
share->rec[i].unpack= get_unpack_function(share->rec+i);
|
share->columndef[i].unpack= get_unpack_function(share->columndef + i);
|
||||||
DBUG_PRINT("info", ("col: %2u type: %2u pack: %u slbits: %2u",
|
DBUG_PRINT("info", ("col: %2u type: %2u pack: %u slbits: %2u",
|
||||||
i, share->rec[i].base_type, share->rec[i].pack_type,
|
i, share->columndef[i].base_type,
|
||||||
share->rec[i].space_length_bits));
|
share->columndef[i].pack_type,
|
||||||
|
share->columndef[i].space_length_bits));
|
||||||
}
|
}
|
||||||
skip_to_next_byte(&bit_buff);
|
skip_to_next_byte(&bit_buff);
|
||||||
/*
|
/*
|
||||||
@@ -776,7 +776,7 @@ int _ma_pack_rec_unpack(register MARIA_HA *info, MARIA_BIT_BUFF *bit_buff,
|
|||||||
reclength-= info->s->base.null_bytes;
|
reclength-= info->s->base.null_bytes;
|
||||||
}
|
}
|
||||||
init_bit_buffer(bit_buff, (uchar*) from, reclength);
|
init_bit_buffer(bit_buff, (uchar*) from, reclength);
|
||||||
for (current_field=share->rec, end=current_field+share->base.fields ;
|
for (current_field=share->columndef, end=current_field+share->base.fields ;
|
||||||
current_field < end ;
|
current_field < end ;
|
||||||
current_field++,to=end_field)
|
current_field++,to=end_field)
|
||||||
{
|
{
|
||||||
@@ -1080,7 +1080,7 @@ static void uf_blob(MARIA_COLUMNDEF *rec, MARIA_BIT_BUFF *bit_buff,
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
ulong length=get_bits(bit_buff,rec->space_length_bits);
|
ulong length=get_bits(bit_buff,rec->space_length_bits);
|
||||||
uint pack_length=(uint) (end-to)-maria_portable_sizeof_char_ptr;
|
uint pack_length=(uint) (end-to)-portable_sizeof_char_ptr;
|
||||||
if (bit_buff->blob_pos+length > bit_buff->blob_end)
|
if (bit_buff->blob_pos+length > bit_buff->blob_end)
|
||||||
{
|
{
|
||||||
bit_buff->error=1;
|
bit_buff->error=1;
|
||||||
|
@@ -32,7 +32,7 @@ byte *_ma_fetch_keypage(register MARIA_HA *info, MARIA_KEYDEF *keyinfo,
|
|||||||
info->s->block_size, info->s->block_size,
|
info->s->block_size, info->s->block_size,
|
||||||
return_buffer);
|
return_buffer);
|
||||||
if (tmp == info->buff)
|
if (tmp == info->buff)
|
||||||
info->keybuff_used=1;
|
info->keyread_buff_used=1;
|
||||||
else if (!tmp)
|
else if (!tmp)
|
||||||
{
|
{
|
||||||
DBUG_PRINT("error",("Got errno: %d from key_cache_read",my_errno));
|
DBUG_PRINT("error",("Got errno: %d from key_cache_read",my_errno));
|
||||||
|
@@ -150,7 +150,6 @@ int maria_rkey(MARIA_HA *info, byte *buf, int inx, const byte *key,
|
|||||||
else
|
else
|
||||||
info->last_rkey_length= pack_key_length;
|
info->last_rkey_length= pack_key_length;
|
||||||
|
|
||||||
|
|
||||||
/* Check if we don't want to have record back, only error message */
|
/* Check if we don't want to have record back, only error message */
|
||||||
if (!buf)
|
if (!buf)
|
||||||
{
|
{
|
||||||
|
@@ -36,7 +36,6 @@ int maria_rrnd(MARIA_HA *info, byte *buf, MARIA_RECORD_POS filepos)
|
|||||||
#ifdef NOT_USED
|
#ifdef NOT_USED
|
||||||
if (filepos == HA_OFFSET_ERROR)
|
if (filepos == HA_OFFSET_ERROR)
|
||||||
{
|
{
|
||||||
skip_deleted_blocks=1;
|
|
||||||
if (info->cur_row.lastpos == HA_OFFSET_ERROR) /* First read ? */
|
if (info->cur_row.lastpos == HA_OFFSET_ERROR) /* First read ? */
|
||||||
filepos= info->s->pack.header_length; /* Read first record */
|
filepos= info->s->pack.header_length; /* Read first record */
|
||||||
else
|
else
|
||||||
|
@@ -127,11 +127,11 @@ static int maria_rtree_find_req(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
|
|||||||
info->int_keypos = info->buff;
|
info->int_keypos = info->buff;
|
||||||
info->int_maxpos = info->buff + (last - after_key);
|
info->int_maxpos = info->buff + (last - after_key);
|
||||||
memcpy(info->buff, after_key, last - after_key);
|
memcpy(info->buff, after_key, last - after_key);
|
||||||
info->keybuff_used = 0;
|
info->keyread_buff_used = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
info->keybuff_used = 1;
|
info->keyread_buff_used = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
res = 0;
|
res = 0;
|
||||||
@@ -192,7 +192,7 @@ int maria_rtree_find_first(MARIA_HA *info, uint keynr, byte *key,
|
|||||||
info->last_rkey_length = key_length;
|
info->last_rkey_length = key_length;
|
||||||
|
|
||||||
info->maria_rtree_recursion_depth = -1;
|
info->maria_rtree_recursion_depth = -1;
|
||||||
info->keybuff_used = 1;
|
info->keyread_buff_used = 1;
|
||||||
|
|
||||||
nod_cmp_flag= ((search_flag & (MBR_EQUAL | MBR_WITHIN)) ?
|
nod_cmp_flag= ((search_flag & (MBR_EQUAL | MBR_WITHIN)) ?
|
||||||
MBR_WITHIN : MBR_INTERSECT);
|
MBR_WITHIN : MBR_INTERSECT);
|
||||||
@@ -227,7 +227,7 @@ int maria_rtree_find_next(MARIA_HA *info, uint keynr, uint search_flag)
|
|||||||
info->lastkey_length,
|
info->lastkey_length,
|
||||||
search_flag);
|
search_flag);
|
||||||
|
|
||||||
if (!info->keybuff_used)
|
if (!info->keyread_buff_used)
|
||||||
{
|
{
|
||||||
byte *key= info->int_keypos;
|
byte *key= info->int_keypos;
|
||||||
|
|
||||||
@@ -245,7 +245,7 @@ int maria_rtree_find_next(MARIA_HA *info, uint keynr, uint search_flag)
|
|||||||
if (after_key < info->int_maxpos)
|
if (after_key < info->int_maxpos)
|
||||||
info->int_keypos= after_key;
|
info->int_keypos= after_key;
|
||||||
else
|
else
|
||||||
info->keybuff_used= 1;
|
info->keyread_buff_used= 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
key+= keyinfo->keylength;
|
key+= keyinfo->keylength;
|
||||||
@@ -342,11 +342,11 @@ static int maria_rtree_get_req(MARIA_HA *info, MARIA_KEYDEF *keyinfo, uint key_l
|
|||||||
info->int_keypos = (byte*) saved_key;
|
info->int_keypos = (byte*) saved_key;
|
||||||
memcpy(info->buff, page_buf, keyinfo->block_length);
|
memcpy(info->buff, page_buf, keyinfo->block_length);
|
||||||
info->int_maxpos = rt_PAGE_END(info->buff);
|
info->int_maxpos = rt_PAGE_END(info->buff);
|
||||||
info->keybuff_used = 0;
|
info->keyread_buff_used = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
info->keybuff_used = 1;
|
info->keyread_buff_used = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
res = 0;
|
res = 0;
|
||||||
@@ -389,7 +389,7 @@ int maria_rtree_get_first(MARIA_HA *info, uint keynr, uint key_length)
|
|||||||
}
|
}
|
||||||
|
|
||||||
info->maria_rtree_recursion_depth = -1;
|
info->maria_rtree_recursion_depth = -1;
|
||||||
info->keybuff_used = 1;
|
info->keyread_buff_used = 1;
|
||||||
|
|
||||||
return maria_rtree_get_req(info, &keyinfo[keynr], key_length, root, 0);
|
return maria_rtree_get_req(info, &keyinfo[keynr], key_length, root, 0);
|
||||||
}
|
}
|
||||||
@@ -409,7 +409,7 @@ int maria_rtree_get_next(MARIA_HA *info, uint keynr, uint key_length)
|
|||||||
my_off_t root;
|
my_off_t root;
|
||||||
MARIA_KEYDEF *keyinfo = info->s->keyinfo + keynr;
|
MARIA_KEYDEF *keyinfo = info->s->keyinfo + keynr;
|
||||||
|
|
||||||
if (!info->keybuff_used)
|
if (!info->keyread_buff_used)
|
||||||
{
|
{
|
||||||
uint k_len = keyinfo->keylength - info->s->base.rec_reflength;
|
uint k_len = keyinfo->keylength - info->s->base.rec_reflength;
|
||||||
/* rt_PAGE_NEXT_KEY(info->int_keypos) */
|
/* rt_PAGE_NEXT_KEY(info->int_keypos) */
|
||||||
@@ -425,7 +425,7 @@ int maria_rtree_get_next(MARIA_HA *info, uint keynr, uint key_length)
|
|||||||
*(int*)info->int_keypos = key - info->buff;
|
*(int*)info->int_keypos = key - info->buff;
|
||||||
if (after_key >= info->int_maxpos)
|
if (after_key >= info->int_maxpos)
|
||||||
{
|
{
|
||||||
info->keybuff_used = 1;
|
info->keyread_buff_used = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -638,7 +638,7 @@ static int maria_rtree_insert_level(MARIA_HA *info, uint keynr, byte *key,
|
|||||||
{
|
{
|
||||||
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)
|
||||||
return -1;
|
return -1;
|
||||||
info->keybuff_used = 1;
|
info->keyread_buff_used = 1;
|
||||||
maria_putint(info->buff, 2, 0);
|
maria_putint(info->buff, 2, 0);
|
||||||
res = maria_rtree_add_key(info, keyinfo, key, key_length, info->buff, NULL);
|
res = maria_rtree_add_key(info, keyinfo, key, key_length, info->buff, NULL);
|
||||||
if (_ma_write_keypage(info, keyinfo, old_root, DFLT_INIT_HITS, info->buff))
|
if (_ma_write_keypage(info, keyinfo, old_root, DFLT_INIT_HITS, info->buff))
|
||||||
|
@@ -157,7 +157,7 @@ int _ma_search(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
|
|||||||
info->int_keytree_version=keyinfo->version;
|
info->int_keytree_version=keyinfo->version;
|
||||||
info->last_search_keypage=info->last_keypage;
|
info->last_search_keypage=info->last_keypage;
|
||||||
info->page_changed=0;
|
info->page_changed=0;
|
||||||
info->keybuff_used= (info->keyread_buff != buff); /* If we have to reread */
|
info->keyread_buff_used= (info->keyread_buff != buff); /* If we have to reread */
|
||||||
|
|
||||||
DBUG_PRINT("exit",("found key at %lu",(ulong) info->cur_row.lastpos));
|
DBUG_PRINT("exit",("found key at %lu",(ulong) info->cur_row.lastpos));
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
@@ -618,7 +618,7 @@ void _ma_kpointer(register MARIA_HA *info, register byte *buff, my_off_t pos)
|
|||||||
case 4: mi_int4store(buff,pos); break;
|
case 4: mi_int4store(buff,pos); break;
|
||||||
case 3: mi_int3store(buff,pos); break;
|
case 3: mi_int3store(buff,pos); break;
|
||||||
case 2: mi_int2store(buff,(uint) pos); break;
|
case 2: mi_int2store(buff,(uint) pos); break;
|
||||||
case 1: buff[0]= (char) (uchar) pos; break;
|
case 1: buff[0]= (byte) pos; break;
|
||||||
default: abort(); /* impossible */
|
default: abort(); /* impossible */
|
||||||
}
|
}
|
||||||
} /* _ma_kpointer */
|
} /* _ma_kpointer */
|
||||||
@@ -1219,10 +1219,10 @@ int _ma_search_next(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
|
|||||||
uint nod_flag;
|
uint nod_flag;
|
||||||
byte lastkey[HA_MAX_KEY_BUFF];
|
byte lastkey[HA_MAX_KEY_BUFF];
|
||||||
DBUG_ENTER("_ma_search_next");
|
DBUG_ENTER("_ma_search_next");
|
||||||
DBUG_PRINT("enter",("nextflag: %u lastpos: %lu int_keypos: %lu page_changed %d keybuff_used: %d",
|
DBUG_PRINT("enter",("nextflag: %u lastpos: %lu int_keypos: %lu page_changed %d keyread_buff_used: %d",
|
||||||
nextflag, (ulong) info->cur_row.lastpos,
|
nextflag, (ulong) info->cur_row.lastpos,
|
||||||
(ulong) info->int_keypos,
|
(ulong) info->int_keypos,
|
||||||
info->page_changed, info->keybuff_used));
|
info->page_changed, info->keyread_buff_used));
|
||||||
DBUG_EXECUTE("key", _ma_print_key(DBUG_FILE,keyinfo->seg,key,key_length););
|
DBUG_EXECUTE("key", _ma_print_key(DBUG_FILE,keyinfo->seg,key,key_length););
|
||||||
|
|
||||||
/* Force full read if we are at last key or if we are not on a leaf
|
/* Force full read if we are at last key or if we are not on a leaf
|
||||||
@@ -1235,16 +1235,16 @@ int _ma_search_next(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
|
|||||||
if (((nextflag & SEARCH_BIGGER) && info->int_keypos >= info->int_maxpos) ||
|
if (((nextflag & SEARCH_BIGGER) && info->int_keypos >= info->int_maxpos) ||
|
||||||
info->page_changed ||
|
info->page_changed ||
|
||||||
(info->int_keytree_version != keyinfo->version &&
|
(info->int_keytree_version != keyinfo->version &&
|
||||||
(info->int_nod_flag || info->keybuff_used)))
|
(info->int_nod_flag || info->keyread_buff_used)))
|
||||||
DBUG_RETURN(_ma_search(info,keyinfo,key, USE_WHOLE_KEY,
|
DBUG_RETURN(_ma_search(info,keyinfo,key, USE_WHOLE_KEY,
|
||||||
nextflag | SEARCH_SAVE_BUFF, pos));
|
nextflag | SEARCH_SAVE_BUFF, pos));
|
||||||
|
|
||||||
if (info->keybuff_used)
|
if (info->keyread_buff_used)
|
||||||
{
|
{
|
||||||
if (!_ma_fetch_keypage(info,keyinfo,info->last_search_keypage,
|
if (!_ma_fetch_keypage(info,keyinfo,info->last_search_keypage,
|
||||||
DFLT_INIT_HITS,info->keyread_buff,0))
|
DFLT_INIT_HITS,info->keyread_buff,0))
|
||||||
DBUG_RETURN(-1);
|
DBUG_RETURN(-1);
|
||||||
info->keybuff_used=0;
|
info->keyread_buff_used=0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Last used buffer is in info->keyread_buff */
|
/* Last used buffer is in info->keyread_buff */
|
||||||
@@ -1328,7 +1328,7 @@ int _ma_search_first(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
|
|||||||
info->int_nod_flag=nod_flag;
|
info->int_nod_flag=nod_flag;
|
||||||
info->int_keytree_version=keyinfo->version;
|
info->int_keytree_version=keyinfo->version;
|
||||||
info->last_search_keypage=info->last_keypage;
|
info->last_search_keypage=info->last_keypage;
|
||||||
info->page_changed=info->keybuff_used=0;
|
info->page_changed=info->keyread_buff_used=0;
|
||||||
info->cur_row.lastpos= _ma_dpos(info,0,info->lastkey+info->lastkey_length);
|
info->cur_row.lastpos= _ma_dpos(info,0,info->lastkey+info->lastkey_length);
|
||||||
|
|
||||||
DBUG_PRINT("exit",("found key at %lu", (ulong) info->cur_row.lastpos));
|
DBUG_PRINT("exit",("found key at %lu", (ulong) info->cur_row.lastpos));
|
||||||
@@ -1373,7 +1373,7 @@ int _ma_search_last(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
|
|||||||
info->int_nod_flag=nod_flag;
|
info->int_nod_flag=nod_flag;
|
||||||
info->int_keytree_version=keyinfo->version;
|
info->int_keytree_version=keyinfo->version;
|
||||||
info->last_search_keypage=info->last_keypage;
|
info->last_search_keypage=info->last_keypage;
|
||||||
info->page_changed=info->keybuff_used=0;
|
info->page_changed=info->keyread_buff_used=0;
|
||||||
|
|
||||||
DBUG_PRINT("exit",("found key at %lu",(ulong) info->cur_row.lastpos));
|
DBUG_PRINT("exit",("found key at %lu",(ulong) info->cur_row.lastpos));
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
|
@@ -80,7 +80,7 @@ int run_test(const char *filename)
|
|||||||
/* Define spatial column */
|
/* Define spatial column */
|
||||||
|
|
||||||
recinfo[1].type=FIELD_BLOB;
|
recinfo[1].type=FIELD_BLOB;
|
||||||
recinfo[1].length=4 + maria_portable_sizeof_char_ptr;
|
recinfo[1].length=4 + portable_sizeof_char_ptr;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@@ -73,12 +73,12 @@ static int run_test(const char *filename)
|
|||||||
/* First define 2 columns */
|
/* First define 2 columns */
|
||||||
create_info.null_bytes= 1;
|
create_info.null_bytes= 1;
|
||||||
recinfo[0].type= key_field;
|
recinfo[0].type= key_field;
|
||||||
recinfo[0].length= (key_field == FIELD_BLOB ? 4+maria_portable_sizeof_char_ptr :
|
recinfo[0].length= (key_field == FIELD_BLOB ? 4+portable_sizeof_char_ptr :
|
||||||
key_length);
|
key_length);
|
||||||
if (key_field == FIELD_VARCHAR)
|
if (key_field == FIELD_VARCHAR)
|
||||||
recinfo[0].length+= HA_VARCHAR_PACKLENGTH(key_length);
|
recinfo[0].length+= HA_VARCHAR_PACKLENGTH(key_length);
|
||||||
recinfo[1].type=extra_field;
|
recinfo[1].type=extra_field;
|
||||||
recinfo[1].length= (extra_field == FIELD_BLOB ? 4 + maria_portable_sizeof_char_ptr : 24);
|
recinfo[1].length= (extra_field == FIELD_BLOB ? 4 + portable_sizeof_char_ptr : 24);
|
||||||
if (extra_field == FIELD_VARCHAR)
|
if (extra_field == FIELD_VARCHAR)
|
||||||
recinfo[1].length+= HA_VARCHAR_PACKLENGTH(recinfo[1].length);
|
recinfo[1].length+= HA_VARCHAR_PACKLENGTH(recinfo[1].length);
|
||||||
if (opt_unique)
|
if (opt_unique)
|
||||||
|
@@ -191,7 +191,7 @@ int main(int argc, char *argv[])
|
|||||||
if (use_blob)
|
if (use_blob)
|
||||||
{
|
{
|
||||||
recinfo[6].type=FIELD_BLOB;
|
recinfo[6].type=FIELD_BLOB;
|
||||||
recinfo[6].length=4+maria_portable_sizeof_char_ptr;
|
recinfo[6].length=4+portable_sizeof_char_ptr;
|
||||||
recinfo[6].null_bit=0;
|
recinfo[6].null_bit=0;
|
||||||
recinfo[6].null_pos=0;
|
recinfo[6].null_pos=0;
|
||||||
}
|
}
|
||||||
|
@@ -177,7 +177,7 @@ int maria_update(register MARIA_HA *info, const byte *oldrec, byte *newrec)
|
|||||||
info->state->checksum+= (info->cur_row.checksum - old_checksum);
|
info->state->checksum+= (info->cur_row.checksum - old_checksum);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
We can't yet have HA_STATE_ACTIVE here, as block_record dosn't support
|
We can't yet have HA_STATE_AKTIV here, as block_record dosn't support
|
||||||
it
|
it
|
||||||
*/
|
*/
|
||||||
info->update= (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED | key_changed);
|
info->update= (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED | key_changed);
|
||||||
|
@@ -356,7 +356,7 @@ int _ma_enlarge_root(MARIA_HA *info, MARIA_KEYDEF *keyinfo, byte *key,
|
|||||||
(byte*) 0, (byte*) 0, key,&s_temp);
|
(byte*) 0, (byte*) 0, key,&s_temp);
|
||||||
maria_putint(info->buff,t_length+2+nod_flag,nod_flag);
|
maria_putint(info->buff,t_length+2+nod_flag,nod_flag);
|
||||||
(*keyinfo->store_key)(keyinfo,info->buff+2+nod_flag,&s_temp);
|
(*keyinfo->store_key)(keyinfo,info->buff+2+nod_flag,&s_temp);
|
||||||
info->keybuff_used=info->page_changed=1; /* info->buff is used */
|
info->keyread_buff_used=info->page_changed=1; /* info->buff is used */
|
||||||
if ((*root= _ma_new(info,keyinfo,DFLT_INIT_HITS)) == HA_OFFSET_ERROR ||
|
if ((*root= _ma_new(info,keyinfo,DFLT_INIT_HITS)) == HA_OFFSET_ERROR ||
|
||||||
_ma_write_keypage(info,keyinfo,*root,DFLT_INIT_HITS,info->buff))
|
_ma_write_keypage(info,keyinfo,*root,DFLT_INIT_HITS,info->buff))
|
||||||
DBUG_RETURN(-1);
|
DBUG_RETURN(-1);
|
||||||
@@ -634,7 +634,7 @@ int _ma_split_page(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
|
|||||||
|
|
||||||
if (info->s->keyinfo+info->lastinx == keyinfo)
|
if (info->s->keyinfo+info->lastinx == keyinfo)
|
||||||
info->page_changed=1; /* Info->buff is used */
|
info->page_changed=1; /* Info->buff is used */
|
||||||
info->keybuff_used=1;
|
info->keyread_buff_used=1;
|
||||||
nod_flag=_ma_test_if_nod(buff);
|
nod_flag=_ma_test_if_nod(buff);
|
||||||
key_ref_length=2+nod_flag;
|
key_ref_length=2+nod_flag;
|
||||||
if (insert_last_key)
|
if (insert_last_key)
|
||||||
|
@@ -50,8 +50,8 @@ static const char *type_names[]=
|
|||||||
"impossible","char","binary", "short", "long", "float",
|
"impossible","char","binary", "short", "long", "float",
|
||||||
"double","number","unsigned short",
|
"double","number","unsigned short",
|
||||||
"unsigned long","longlong","ulonglong","int24",
|
"unsigned long","longlong","ulonglong","int24",
|
||||||
"uint24","int8","varchar", "varbin","?",
|
"uint24","int8","varchar", "varbin", "varchar2", "varbin2", "bit",
|
||||||
"?"
|
"?","?"
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char *prefix_packed_txt="packed ",
|
static const char *prefix_packed_txt="packed ",
|
||||||
@@ -1224,7 +1224,7 @@ end2:
|
|||||||
|
|
||||||
static void descript(HA_CHECK *param, register MARIA_HA *info, my_string name)
|
static void descript(HA_CHECK *param, register MARIA_HA *info, my_string name)
|
||||||
{
|
{
|
||||||
uint key,keyseg_nr,field,start;
|
uint key,keyseg_nr,field;
|
||||||
reg3 MARIA_KEYDEF *keyinfo;
|
reg3 MARIA_KEYDEF *keyinfo;
|
||||||
reg2 HA_KEYSEG *keyseg;
|
reg2 HA_KEYSEG *keyseg;
|
||||||
reg4 const char *text;
|
reg4 const char *text;
|
||||||
@@ -1430,43 +1430,42 @@ static void descript(HA_CHECK *param, register MARIA_HA *info, my_string name)
|
|||||||
for (field=0 ; field < share->base.fields ; field++)
|
for (field=0 ; field < share->base.fields ; field++)
|
||||||
{
|
{
|
||||||
if (share->options & HA_OPTION_COMPRESS_RECORD)
|
if (share->options & HA_OPTION_COMPRESS_RECORD)
|
||||||
type=share->rec[field].base_type;
|
type=share->columndef[field].base_type;
|
||||||
else
|
else
|
||||||
type=(enum en_fieldtype) share->rec[field].type;
|
type=(enum en_fieldtype) share->columndef[field].type;
|
||||||
end=strmov(buff,field_pack[type]);
|
end=strmov(buff,field_pack[type]);
|
||||||
if (share->options & HA_OPTION_COMPRESS_RECORD)
|
if (share->options & HA_OPTION_COMPRESS_RECORD)
|
||||||
{
|
{
|
||||||
if (share->rec[field].pack_type & PACK_TYPE_SELECTED)
|
if (share->columndef[field].pack_type & PACK_TYPE_SELECTED)
|
||||||
end=strmov(end,", not_always");
|
end=strmov(end,", not_always");
|
||||||
if (share->rec[field].pack_type & PACK_TYPE_SPACE_FIELDS)
|
if (share->columndef[field].pack_type & PACK_TYPE_SPACE_FIELDS)
|
||||||
end=strmov(end,", no empty");
|
end=strmov(end,", no empty");
|
||||||
if (share->rec[field].pack_type & PACK_TYPE_ZERO_FILL)
|
if (share->columndef[field].pack_type & PACK_TYPE_ZERO_FILL)
|
||||||
{
|
{
|
||||||
sprintf(end,", zerofill(%d)",share->rec[field].space_length_bits);
|
sprintf(end,", zerofill(%d)",share->columndef[field].space_length_bits);
|
||||||
end=strend(end);
|
end=strend(end);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (buff[0] == ',')
|
if (buff[0] == ',')
|
||||||
strmov(buff,buff+2);
|
strmov(buff,buff+2);
|
||||||
int10_to_str((long) share->rec[field].length,length,10);
|
int10_to_str((long) share->columndef[field].length,length,10);
|
||||||
null_bit[0]=null_pos[0]=0;
|
null_bit[0]=null_pos[0]=0;
|
||||||
if (share->rec[field].null_bit)
|
if (share->columndef[field].null_bit)
|
||||||
{
|
{
|
||||||
sprintf(null_bit,"%d",share->rec[field].null_bit);
|
sprintf(null_bit,"%d",share->columndef[field].null_bit);
|
||||||
sprintf(null_pos,"%d",share->rec[field].null_pos+1);
|
sprintf(null_pos,"%d",share->columndef[field].null_pos+1);
|
||||||
}
|
}
|
||||||
printf("%-6d%-6u%-7s%-8s%-8s%-35s",field+1,
|
printf("%-6d%-6u%-7s%-8s%-8s%-35s",field+1,
|
||||||
(uint) share->rec[field].offset+1,
|
(uint) share->columndef[field].offset+1,
|
||||||
length, null_pos, null_bit, buff);
|
length, null_pos, null_bit, buff);
|
||||||
if (share->options & HA_OPTION_COMPRESS_RECORD)
|
if (share->options & HA_OPTION_COMPRESS_RECORD)
|
||||||
{
|
{
|
||||||
if (share->rec[field].huff_tree)
|
if (share->columndef[field].huff_tree)
|
||||||
printf("%3d %2d",
|
printf("%3d %2d",
|
||||||
(uint) (share->rec[field].huff_tree-share->decode_trees)+1,
|
(uint) (share->columndef[field].huff_tree-share->decode_trees)+1,
|
||||||
share->rec[field].huff_tree->quick_table_bits);
|
share->columndef[field].huff_tree->quick_table_bits);
|
||||||
}
|
}
|
||||||
VOID(putchar('\n'));
|
VOID(putchar('\n'));
|
||||||
start+=share->rec[field].length;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
@@ -1556,7 +1555,8 @@ static int maria_sort_records(HA_CHECK *param,
|
|||||||
fn_format(param->temp_filename,name,"", MARIA_NAME_DEXT,2+4+32);
|
fn_format(param->temp_filename,name,"", MARIA_NAME_DEXT,2+4+32);
|
||||||
new_file= my_create(fn_format(param->temp_filename,
|
new_file= my_create(fn_format(param->temp_filename,
|
||||||
param->temp_filename,"",
|
param->temp_filename,"",
|
||||||
DATA_TMP_EXT,2+4),
|
DATA_TMP_EXT,
|
||||||
|
MY_REPLACE_EXT | MY_UNPACK_FILENAME),
|
||||||
0, param->tmpfile_createflag,
|
0, param->tmpfile_createflag,
|
||||||
MYF(0));
|
MYF(0));
|
||||||
if (new_file < 0)
|
if (new_file < 0)
|
||||||
|
@@ -60,7 +60,8 @@ typedef struct st_maria_state_info
|
|||||||
uchar language; /* Language for indexes */
|
uchar language; /* Language for indexes */
|
||||||
uchar fulltext_keys;
|
uchar fulltext_keys;
|
||||||
uchar data_file_type;
|
uchar data_file_type;
|
||||||
uchar org_data_file_type; /* Used by mariapack to store dft */
|
/* Used by mariapack to store the original data_file_type */
|
||||||
|
uchar org_data_file_type;
|
||||||
} header;
|
} header;
|
||||||
|
|
||||||
MARIA_STATUS_INFO state;
|
MARIA_STATUS_INFO state;
|
||||||
@@ -75,7 +76,7 @@ typedef struct st_maria_state_info
|
|||||||
ulong *rec_per_key_part;
|
ulong *rec_per_key_part;
|
||||||
ha_checksum checksum; /* Table checksum */
|
ha_checksum checksum; /* Table checksum */
|
||||||
my_off_t *key_root; /* Start of key trees */
|
my_off_t *key_root; /* Start of key trees */
|
||||||
my_off_t key_del; /* delete links for 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 rec_per_key_rows; /* Rows when calculating rec_per_key */
|
||||||
|
|
||||||
ulong sec_index_changed; /* Updated when new sec_index */
|
ulong sec_index_changed; /* Updated when new sec_index */
|
||||||
@@ -107,6 +108,13 @@ typedef struct st_maria_state_info
|
|||||||
#define MARIA_COLUMNDEF_SIZE (6+2+2+2+2+2+1+1)
|
#define MARIA_COLUMNDEF_SIZE (6+2+2+2+2+2+1+1)
|
||||||
#define MARIA_BASE_INFO_SIZE (5*8 + 6*4 + 11*2 + 6 + 5*2 + 1 + 16)
|
#define MARIA_BASE_INFO_SIZE (5*8 + 6*4 + 11*2 + 6 + 5*2 + 1 + 16)
|
||||||
#define MARIA_INDEX_BLOCK_MARGIN 16 /* Safety margin for .MYI tables */
|
#define MARIA_INDEX_BLOCK_MARGIN 16 /* Safety margin for .MYI tables */
|
||||||
|
/* Internal management bytes needed to store 2 keys on an index page */
|
||||||
|
#define MARIA_INDEX_MIN_OVERHEAD_SIZE (4 + (TRANSID_SIZE+1) * 2)
|
||||||
|
|
||||||
|
/*
|
||||||
|
Basic information of the Maria table. This is stored on disk
|
||||||
|
and not changed (unless we do DLL changes).
|
||||||
|
*/
|
||||||
|
|
||||||
typedef struct st_ma_base_info
|
typedef struct st_ma_base_info
|
||||||
{
|
{
|
||||||
@@ -127,7 +135,9 @@ typedef struct st_ma_base_info
|
|||||||
uint max_field_lengths;
|
uint max_field_lengths;
|
||||||
uint pack_fields; /* packed fields in table */
|
uint pack_fields; /* packed fields in table */
|
||||||
uint varlength_fields; /* char/varchar/blobs */
|
uint varlength_fields; /* char/varchar/blobs */
|
||||||
uint rec_reflength; /* = 2-8 */
|
/* Number of bytes in the index used to refer to a row (2-8) */
|
||||||
|
uint rec_reflength;
|
||||||
|
/* Number of bytes in the index used to refer to another index page (2-8) */
|
||||||
uint key_reflength; /* = 2-8 */
|
uint key_reflength; /* = 2-8 */
|
||||||
uint keys; /* same as in state.header */
|
uint keys; /* same as in state.header */
|
||||||
uint auto_key; /* Which key-1 is a auto key */
|
uint auto_key; /* Which key-1 is a auto key */
|
||||||
@@ -144,14 +154,17 @@ typedef struct st_ma_base_info
|
|||||||
uint extra_alloc_bytes;
|
uint extra_alloc_bytes;
|
||||||
uint extra_alloc_procent;
|
uint extra_alloc_procent;
|
||||||
uint is_nulls_extended; /* 1 if new null bytes */
|
uint is_nulls_extended; /* 1 if new null bytes */
|
||||||
uint min_row_length;
|
uint min_row_length; /* Min possible length of a row */
|
||||||
uint default_row_flag; /* 0 or ROW_FLAG_NULLS_EXTENDED */
|
uint default_row_flag; /* 0 or ROW_FLAG_NULLS_EXTENDED */
|
||||||
uint block_size;
|
uint block_size;
|
||||||
|
/* Size of initial record buffer */
|
||||||
uint default_rec_buff_size;
|
uint default_rec_buff_size;
|
||||||
|
/* Extra number of bytes the row format require in the record buffer */
|
||||||
uint extra_rec_buff_size;
|
uint extra_rec_buff_size;
|
||||||
|
|
||||||
/* The following are from the header */
|
/* The following are from the header */
|
||||||
uint key_parts, all_key_parts;
|
uint key_parts, all_key_parts;
|
||||||
|
/* If false, we disable logging, versioning etc */
|
||||||
my_bool transactional;
|
my_bool transactional;
|
||||||
} MARIA_BASE_INFO;
|
} MARIA_BASE_INFO;
|
||||||
|
|
||||||
@@ -177,8 +190,8 @@ typedef struct st_maria_file_bitmap
|
|||||||
{
|
{
|
||||||
uchar *map;
|
uchar *map;
|
||||||
ulonglong page; /* Page number for current bitmap */
|
ulonglong page; /* Page number for current bitmap */
|
||||||
uint used_size; /* Size of bitmap that is not 0 */
|
uint used_size; /* Size of bitmap head that is not 0 */
|
||||||
File file;
|
File file; /* Datafile, where bitmap is stored */
|
||||||
|
|
||||||
my_bool changed;
|
my_bool changed;
|
||||||
|
|
||||||
@@ -204,8 +217,7 @@ typedef struct st_maria_share
|
|||||||
MARIA_KEYDEF *keyinfo; /* Key definitions */
|
MARIA_KEYDEF *keyinfo; /* Key definitions */
|
||||||
MARIA_UNIQUEDEF *uniqueinfo; /* unique definitions */
|
MARIA_UNIQUEDEF *uniqueinfo; /* unique definitions */
|
||||||
HA_KEYSEG *keyparts; /* key part info */
|
HA_KEYSEG *keyparts; /* key part info */
|
||||||
MARIA_COLUMNDEF *rec; /* Pointer to field information
|
MARIA_COLUMNDEF *columndef; /* Pointer to column information */
|
||||||
*/
|
|
||||||
MARIA_PACK pack; /* Data about packed records */
|
MARIA_PACK pack; /* Data about packed records */
|
||||||
MARIA_BLOB *blobs; /* Pointer to blobs */
|
MARIA_BLOB *blobs; /* Pointer to blobs */
|
||||||
char *unique_file_name; /* realpath() of index file */
|
char *unique_file_name; /* realpath() of index file */
|
||||||
@@ -216,25 +228,43 @@ typedef struct st_maria_share
|
|||||||
KEY_CACHE *key_cache; /* ref to the current key cache */
|
KEY_CACHE *key_cache; /* ref to the current key cache */
|
||||||
MARIA_DECODE_TREE *decode_trees;
|
MARIA_DECODE_TREE *decode_trees;
|
||||||
uint16 *decode_tables;
|
uint16 *decode_tables;
|
||||||
|
/* Called the first time the table instance is opened */
|
||||||
my_bool (*once_init)(struct st_maria_share *, File);
|
my_bool (*once_init)(struct st_maria_share *, File);
|
||||||
|
/* Called when the last instance of the table is closed */
|
||||||
my_bool (*once_end)(struct st_maria_share *);
|
my_bool (*once_end)(struct st_maria_share *);
|
||||||
|
/* Is called for every open of the table */
|
||||||
my_bool (*init)(struct st_maria_info *);
|
my_bool (*init)(struct st_maria_info *);
|
||||||
|
/* Is called for every close of the table */
|
||||||
void (*end)(struct st_maria_info *);
|
void (*end)(struct st_maria_info *);
|
||||||
|
/* Called when we want to read a record from a specific position */
|
||||||
int (*read_record)(struct st_maria_info *, byte *, MARIA_RECORD_POS);
|
int (*read_record)(struct st_maria_info *, byte *, MARIA_RECORD_POS);
|
||||||
|
/* Initialize a scan */
|
||||||
my_bool (*scan_init)(struct st_maria_info *);
|
my_bool (*scan_init)(struct st_maria_info *);
|
||||||
|
/* Read next record while scanning */
|
||||||
int (*scan)(struct st_maria_info *, byte *, MARIA_RECORD_POS, my_bool);
|
int (*scan)(struct st_maria_info *, byte *, MARIA_RECORD_POS, my_bool);
|
||||||
|
/* End scan */
|
||||||
void (*scan_end)(struct st_maria_info *);
|
void (*scan_end)(struct st_maria_info *);
|
||||||
|
/* Pre-write of row (some handlers may do the actual write here) */
|
||||||
MARIA_RECORD_POS (*write_record_init)(struct st_maria_info *, const byte *);
|
MARIA_RECORD_POS (*write_record_init)(struct st_maria_info *, const byte *);
|
||||||
|
/* Write record (or accept write_record_init) */
|
||||||
my_bool (*write_record)(struct st_maria_info *, const byte *);
|
my_bool (*write_record)(struct st_maria_info *, const byte *);
|
||||||
|
/* Called when write failed */
|
||||||
my_bool (*write_record_abort)(struct st_maria_info *);
|
my_bool (*write_record_abort)(struct st_maria_info *);
|
||||||
my_bool (*update_record)(struct st_maria_info *, MARIA_RECORD_POS,
|
my_bool (*update_record)(struct st_maria_info *, MARIA_RECORD_POS,
|
||||||
const byte *);
|
const byte *);
|
||||||
my_bool (*delete_record)(struct st_maria_info *);
|
my_bool (*delete_record)(struct st_maria_info *);
|
||||||
my_bool (*compare_record)(struct st_maria_info *, const byte *);
|
my_bool (*compare_record)(struct st_maria_info *, const byte *);
|
||||||
|
/* calculate checksum for a row */
|
||||||
ha_checksum(*calc_checksum)(struct st_maria_info *, const byte *);
|
ha_checksum(*calc_checksum)(struct st_maria_info *, const byte *);
|
||||||
|
/*
|
||||||
|
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 byte *);
|
ha_checksum(*calc_write_checksum) (struct st_maria_info *, const byte *);
|
||||||
|
/* Compare a row in memory with a row on disk */
|
||||||
my_bool (*compare_unique)(struct st_maria_info *, MARIA_UNIQUEDEF *,
|
my_bool (*compare_unique)(struct st_maria_info *, MARIA_UNIQUEDEF *,
|
||||||
const byte *record, MARIA_RECORD_POS pos);
|
const byte *record, MARIA_RECORD_POS pos);
|
||||||
|
/* Mapings to read/write the data file */
|
||||||
uint (*file_read)(MARIA_HA *, byte *, uint, my_off_t, myf);
|
uint (*file_read)(MARIA_HA *, byte *, uint, my_off_t, myf);
|
||||||
uint (*file_write)(MARIA_HA *, byte *, uint, my_off_t, myf);
|
uint (*file_write)(MARIA_HA *, byte *, uint, my_off_t, myf);
|
||||||
invalidator_by_filename invalidator; /* query cache invalidator */
|
invalidator_by_filename invalidator; /* query cache invalidator */
|
||||||
@@ -255,6 +285,7 @@ typedef struct st_maria_share
|
|||||||
uint reopen; /* How many times reopened */
|
uint reopen; /* How many times reopened */
|
||||||
uint w_locks, r_locks, tot_locks; /* Number of read/write locks */
|
uint w_locks, r_locks, tot_locks; /* Number of read/write locks */
|
||||||
uint block_size; /* block_size of keyfile & data file*/
|
uint block_size; /* block_size of keyfile & data file*/
|
||||||
|
/* Fixed length part of a packed row in BLOCK_RECORD format */
|
||||||
uint base_length;
|
uint base_length;
|
||||||
myf write_flag;
|
myf write_flag;
|
||||||
enum data_file_type data_file_type;
|
enum data_file_type data_file_type;
|
||||||
@@ -342,7 +373,8 @@ struct st_maria_info
|
|||||||
{
|
{
|
||||||
MARIA_SHARE *s; /* Shared between open:s */
|
MARIA_SHARE *s; /* Shared between open:s */
|
||||||
MARIA_STATUS_INFO *state, save_state;
|
MARIA_STATUS_INFO *state, save_state;
|
||||||
MARIA_ROW cur_row, new_row;
|
MARIA_ROW cur_row; /* The active row that we just read */
|
||||||
|
MARIA_ROW new_row; /* Storage for a row during update */
|
||||||
MARIA_BLOCK_SCAN scan;
|
MARIA_BLOCK_SCAN scan;
|
||||||
MARIA_BLOB *blobs; /* Pointer to blobs */
|
MARIA_BLOB *blobs; /* Pointer to blobs */
|
||||||
MARIA_BIT_BUFF bit_buff;
|
MARIA_BIT_BUFF bit_buff;
|
||||||
@@ -404,8 +436,8 @@ struct st_maria_info
|
|||||||
my_bool quick_mode;
|
my_bool quick_mode;
|
||||||
/* If info->keyread_buff can't be used for rnext */
|
/* If info->keyread_buff can't be used for rnext */
|
||||||
my_bool page_changed;
|
my_bool page_changed;
|
||||||
/* If info->keyread_buff has to be reread for rnext */
|
/* If info->keyread_buff has to be re-read for rnext */
|
||||||
my_bool keybuff_used;
|
my_bool keyread_buff_used;
|
||||||
my_bool once_flags; /* For MARIA_MRG */
|
my_bool once_flags; /* For MARIA_MRG */
|
||||||
#ifdef __WIN__
|
#ifdef __WIN__
|
||||||
my_bool owned_by_merge; /* This Maria table is part of a merge union */
|
my_bool owned_by_merge; /* This Maria table is part of a merge union */
|
||||||
@@ -419,7 +451,7 @@ struct st_maria_info
|
|||||||
|
|
||||||
/* Some defines used by maria-functions */
|
/* Some defines used by maria-functions */
|
||||||
|
|
||||||
#define USE_WHOLE_KEY HA_MAX_KEY_BUFF*2 /* Use whole key in _search() */
|
#define USE_WHOLE_KEY 65535 /* Use whole key in _search() */
|
||||||
#define F_EXTRA_LCK -1
|
#define F_EXTRA_LCK -1
|
||||||
|
|
||||||
/* bits in opt_flag */
|
/* bits in opt_flag */
|
||||||
@@ -489,6 +521,7 @@ struct st_maria_info
|
|||||||
{ length=mi_uint2korr((key)+1)+3; } \
|
{ length=mi_uint2korr((key)+1)+3; } \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define maria_max_key_length() ((maria_block_size - MARIA_INDEX_MIN_OVERHEAD_SIZE)/2)
|
||||||
#define get_pack_length(length) ((length) >= 255 ? 3 : 1)
|
#define get_pack_length(length) ((length) >= 255 ? 3 : 1)
|
||||||
|
|
||||||
#define MARIA_MIN_BLOCK_LENGTH 20 /* Because of delete-link */
|
#define MARIA_MIN_BLOCK_LENGTH 20 /* Because of delete-link */
|
||||||
@@ -720,7 +753,11 @@ extern int _ma_ft_update(MARIA_HA *info, uint keynr, byte *keybuf,
|
|||||||
const byte *oldrec, const byte *newrec,
|
const byte *oldrec, const byte *newrec,
|
||||||
my_off_t pos);
|
my_off_t pos);
|
||||||
|
|
||||||
/* Parameter to _ma_get_block_info */
|
/*
|
||||||
|
Parameter to _ma_get_block_info
|
||||||
|
The dynamic row header is read into this struct. For an explanation of
|
||||||
|
the fields, look at the function _ma_get_block_info().
|
||||||
|
*/
|
||||||
|
|
||||||
typedef struct st_maria_block_info
|
typedef struct st_maria_block_info
|
||||||
{
|
{
|
||||||
@@ -736,6 +773,7 @@ typedef struct st_maria_block_info
|
|||||||
uint offset;
|
uint offset;
|
||||||
} MARIA_BLOCK_INFO;
|
} MARIA_BLOCK_INFO;
|
||||||
|
|
||||||
|
|
||||||
/* bits in return from _ma_get_block_info */
|
/* bits in return from _ma_get_block_info */
|
||||||
|
|
||||||
#define BLOCK_FIRST 1
|
#define BLOCK_FIRST 1
|
||||||
@@ -800,8 +838,8 @@ uint _ma_keydef_write(File file, MARIA_KEYDEF *keydef);
|
|||||||
char *_ma_keydef_read(char *ptr, MARIA_KEYDEF *keydef);
|
char *_ma_keydef_read(char *ptr, MARIA_KEYDEF *keydef);
|
||||||
uint _ma_uniquedef_write(File file, MARIA_UNIQUEDEF *keydef);
|
uint _ma_uniquedef_write(File file, MARIA_UNIQUEDEF *keydef);
|
||||||
char *_ma_uniquedef_read(char *ptr, MARIA_UNIQUEDEF *keydef);
|
char *_ma_uniquedef_read(char *ptr, MARIA_UNIQUEDEF *keydef);
|
||||||
uint _ma_recinfo_write(File file, MARIA_COLUMNDEF *recinfo);
|
uint _ma_columndef_write(File file, MARIA_COLUMNDEF *columndef);
|
||||||
char *_ma_recinfo_read(char *ptr, MARIA_COLUMNDEF *recinfo);
|
char *_ma_columndef_read(char *ptr, MARIA_COLUMNDEF *columndef);
|
||||||
ulong _ma_calc_total_blob_length(MARIA_HA *info, const byte *record);
|
ulong _ma_calc_total_blob_length(MARIA_HA *info, const byte *record);
|
||||||
ha_checksum _ma_checksum(MARIA_HA *info, const byte *buf);
|
ha_checksum _ma_checksum(MARIA_HA *info, const byte *buf);
|
||||||
ha_checksum _ma_static_checksum(MARIA_HA *info, const byte *buf);
|
ha_checksum _ma_static_checksum(MARIA_HA *info, const byte *buf);
|
||||||
|
@@ -307,9 +307,10 @@ static void usage(void)
|
|||||||
puts("and you are welcome to modify and redistribute it under the GPL license\n");
|
puts("and you are welcome to modify and redistribute it under the GPL license\n");
|
||||||
|
|
||||||
puts("Pack a MARIA-table to take much less space.");
|
puts("Pack a MARIA-table to take much less space.");
|
||||||
puts("Keys are not updated, you must run maria_chk -rq on the datafile");
|
puts("Keys are not updated, you must run maria_chk -rq on the index (.MAI) file");
|
||||||
puts("afterwards to update the keys.");
|
puts("afterwards to update the keys.");
|
||||||
puts("You should give the .MYI file as the filename argument.");
|
puts("You should give the .MAI file as the filename argument.");
|
||||||
|
puts("To unpack a packed table, run maria_chk -u on the table");
|
||||||
|
|
||||||
VOID(printf("\nUsage: %s [OPTIONS] filename...\n", my_progname));
|
VOID(printf("\nUsage: %s [OPTIONS] filename...\n", my_progname));
|
||||||
my_print_help(my_long_options);
|
my_print_help(my_long_options);
|
||||||
@@ -462,9 +463,9 @@ static bool open_isam_files(PACK_MRG_INFO *mrg,char **names,uint count)
|
|||||||
if (mrg->file[j]->s->base.reclength != mrg->file[j+1]->s->base.reclength ||
|
if (mrg->file[j]->s->base.reclength != mrg->file[j+1]->s->base.reclength ||
|
||||||
mrg->file[j]->s->base.fields != mrg->file[j+1]->s->base.fields)
|
mrg->file[j]->s->base.fields != mrg->file[j+1]->s->base.fields)
|
||||||
goto diff_file;
|
goto diff_file;
|
||||||
m1=mrg->file[j]->s->rec;
|
m1=mrg->file[j]->s->columndef;
|
||||||
end=m1+mrg->file[j]->s->base.fields;
|
end=m1+mrg->file[j]->s->base.fields;
|
||||||
m2=mrg->file[j+1]->s->rec;
|
m2=mrg->file[j+1]->s->columndef;
|
||||||
for ( ; m1 != end ; m1++,m2++)
|
for ( ; m1 != end ; m1++,m2++)
|
||||||
{
|
{
|
||||||
if (m1->type != m2->type || m1->length != m2->length)
|
if (m1->type != m2->type || m1->length != m2->length)
|
||||||
@@ -773,8 +774,8 @@ static HUFF_COUNTS *init_huff_count(MARIA_HA *info,my_off_t records)
|
|||||||
for (i=0 ; i < info->s->base.fields ; i++)
|
for (i=0 ; i < info->s->base.fields ; i++)
|
||||||
{
|
{
|
||||||
enum en_fieldtype type;
|
enum en_fieldtype type;
|
||||||
count[i].field_length=info->s->rec[i].length;
|
count[i].field_length=info->s->columndef[i].length;
|
||||||
type= count[i].field_type= (enum en_fieldtype) info->s->rec[i].type;
|
type= count[i].field_type= (enum en_fieldtype) info->s->columndef[i].type;
|
||||||
if (type == FIELD_INTERVALL ||
|
if (type == FIELD_INTERVALL ||
|
||||||
type == FIELD_CONSTANT ||
|
type == FIELD_CONSTANT ||
|
||||||
type == FIELD_ZERO)
|
type == FIELD_ZERO)
|
||||||
@@ -1003,7 +1004,7 @@ static int get_statistic(PACK_MRG_INFO *mrg,HUFF_COUNTS *huff_counts)
|
|||||||
/* Calculate pos, end_pos, and max_length for variable length fields. */
|
/* Calculate pos, end_pos, and max_length for variable length fields. */
|
||||||
if (count->field_type == FIELD_BLOB)
|
if (count->field_type == FIELD_BLOB)
|
||||||
{
|
{
|
||||||
uint field_length=count->field_length -maria_portable_sizeof_char_ptr;
|
uint field_length=count->field_length -portable_sizeof_char_ptr;
|
||||||
ulong blob_length= _ma_calc_blob_length(field_length, start_pos);
|
ulong blob_length= _ma_calc_blob_length(field_length, start_pos);
|
||||||
memcpy_fixed((char*) &pos, start_pos+field_length,sizeof(char*));
|
memcpy_fixed((char*) &pos, start_pos+field_length,sizeof(char*));
|
||||||
end_pos=pos+blob_length;
|
end_pos=pos+blob_length;
|
||||||
@@ -2656,7 +2657,7 @@ static int compress_isam_file(PACK_MRG_INFO *mrg, HUFF_COUNTS *huff_counts)
|
|||||||
case FIELD_BLOB:
|
case FIELD_BLOB:
|
||||||
{
|
{
|
||||||
ulong blob_length= _ma_calc_blob_length(field_length-
|
ulong blob_length= _ma_calc_blob_length(field_length-
|
||||||
maria_portable_sizeof_char_ptr,
|
portable_sizeof_char_ptr,
|
||||||
start_pos);
|
start_pos);
|
||||||
/* Empty blobs are encoded with a single 1 bit. */
|
/* Empty blobs are encoded with a single 1 bit. */
|
||||||
if (!blob_length)
|
if (!blob_length)
|
||||||
@@ -2673,7 +2674,7 @@ static int compress_isam_file(PACK_MRG_INFO *mrg, HUFF_COUNTS *huff_counts)
|
|||||||
DBUG_PRINT("fields", ("FIELD_BLOB %lu bytes, bits: %2u",
|
DBUG_PRINT("fields", ("FIELD_BLOB %lu bytes, bits: %2u",
|
||||||
blob_length, count->length_bits));
|
blob_length, count->length_bits));
|
||||||
write_bits(blob_length,count->length_bits);
|
write_bits(blob_length,count->length_bits);
|
||||||
memcpy_fixed(&blob,end_pos-maria_portable_sizeof_char_ptr,
|
memcpy_fixed(&blob,end_pos-portable_sizeof_char_ptr,
|
||||||
sizeof(char*));
|
sizeof(char*));
|
||||||
blob_end=blob+blob_length;
|
blob_end=blob+blob_length;
|
||||||
/* Encode the blob bytes. */
|
/* Encode the blob bytes. */
|
||||||
@@ -2952,6 +2953,7 @@ static int save_state(MARIA_HA *isam_file,PACK_MRG_INFO *mrg,
|
|||||||
|
|
||||||
options|= HA_OPTION_COMPRESS_RECORD | HA_OPTION_READ_ONLY_DATA;
|
options|= HA_OPTION_COMPRESS_RECORD | HA_OPTION_READ_ONLY_DATA;
|
||||||
mi_int2store(share->state.header.options,options);
|
mi_int2store(share->state.header.options,options);
|
||||||
|
/* Save the original file type of we have to undo the packing later */
|
||||||
share->state.header.org_data_file_type= share->state.header.data_file_type;
|
share->state.header.org_data_file_type= share->state.header.data_file_type;
|
||||||
share->state.header.data_file_type= COMPRESSED_RECORD;
|
share->state.header.data_file_type= COMPRESSED_RECORD;
|
||||||
|
|
||||||
|
@@ -48,7 +48,7 @@ int main(int argc, char *argv[])
|
|||||||
recinfo[0].type=FIELD_SKIP_ENDSPACE;
|
recinfo[0].type=FIELD_SKIP_ENDSPACE;
|
||||||
recinfo[0].length=docid_length;
|
recinfo[0].length=docid_length;
|
||||||
recinfo[1].type=FIELD_BLOB;
|
recinfo[1].type=FIELD_BLOB;
|
||||||
recinfo[1].length= 4+mi_portable_sizeof_char_ptr;
|
recinfo[1].length= 4+portable_sizeof_char_ptr;
|
||||||
|
|
||||||
/* Define a key over the first column */
|
/* Define a key over the first column */
|
||||||
keyinfo[0].seg=keyseg;
|
keyinfo[0].seg=keyseg;
|
||||||
|
@@ -75,12 +75,12 @@ static int run_test(const char *filename)
|
|||||||
|
|
||||||
/* First define 2 columns */
|
/* First define 2 columns */
|
||||||
recinfo[0].type=extra_field;
|
recinfo[0].type=extra_field;
|
||||||
recinfo[0].length= (extra_field == FIELD_BLOB ? 4 + mi_portable_sizeof_char_ptr :
|
recinfo[0].length= (extra_field == FIELD_BLOB ? 4 + portable_sizeof_char_ptr :
|
||||||
extra_length);
|
extra_length);
|
||||||
if (extra_field == FIELD_VARCHAR)
|
if (extra_field == FIELD_VARCHAR)
|
||||||
recinfo[0].length+= HA_VARCHAR_PACKLENGTH(extra_length);
|
recinfo[0].length+= HA_VARCHAR_PACKLENGTH(extra_length);
|
||||||
recinfo[1].type=key_field;
|
recinfo[1].type=key_field;
|
||||||
recinfo[1].length= (key_field == FIELD_BLOB ? 4+mi_portable_sizeof_char_ptr :
|
recinfo[1].length= (key_field == FIELD_BLOB ? 4+portable_sizeof_char_ptr :
|
||||||
key_length);
|
key_length);
|
||||||
if (key_field == FIELD_VARCHAR)
|
if (key_field == FIELD_VARCHAR)
|
||||||
recinfo[1].length+= HA_VARCHAR_PACKLENGTH(key_length);
|
recinfo[1].length+= HA_VARCHAR_PACKLENGTH(key_length);
|
||||||
|
@@ -31,9 +31,9 @@ ha_checksum mi_checksum(MI_INFO *info, const byte *buf)
|
|||||||
case FIELD_BLOB:
|
case FIELD_BLOB:
|
||||||
{
|
{
|
||||||
length=_mi_calc_blob_length(rec->length-
|
length=_mi_calc_blob_length(rec->length-
|
||||||
mi_portable_sizeof_char_ptr,
|
portable_sizeof_char_ptr,
|
||||||
buf);
|
buf);
|
||||||
memcpy((char*) &pos, buf+rec->length- mi_portable_sizeof_char_ptr,
|
memcpy((char*) &pos, buf+rec->length- portable_sizeof_char_ptr,
|
||||||
sizeof(char*));
|
sizeof(char*));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@@ -117,10 +117,10 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
|
|||||||
share.base.blobs++;
|
share.base.blobs++;
|
||||||
if (pack_reclength != INT_MAX32)
|
if (pack_reclength != INT_MAX32)
|
||||||
{
|
{
|
||||||
if (rec->length == 4+mi_portable_sizeof_char_ptr)
|
if (rec->length == 4+portable_sizeof_char_ptr)
|
||||||
pack_reclength= INT_MAX32;
|
pack_reclength= INT_MAX32;
|
||||||
else
|
else
|
||||||
pack_reclength+=(1 << ((rec->length-mi_portable_sizeof_char_ptr)*8)); /* Max blob length */
|
pack_reclength+=(1 << ((rec->length-portable_sizeof_char_ptr)*8)); /* Max blob length */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (type == FIELD_SKIP_PRESPACE ||
|
else if (type == FIELD_SKIP_PRESPACE ||
|
||||||
|
@@ -900,7 +900,7 @@ uint _mi_rec_pack(MI_INFO *info, register byte *to, register const byte *from)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
char *temp_pos;
|
char *temp_pos;
|
||||||
size_t tmp_length=length-mi_portable_sizeof_char_ptr;
|
size_t tmp_length=length-portable_sizeof_char_ptr;
|
||||||
memcpy((byte*) to,from,tmp_length);
|
memcpy((byte*) to,from,tmp_length);
|
||||||
memcpy_fixed(&temp_pos,from+tmp_length,sizeof(char*));
|
memcpy_fixed(&temp_pos,from+tmp_length,sizeof(char*));
|
||||||
memcpy(to+tmp_length,temp_pos,(size_t) blob->length);
|
memcpy(to+tmp_length,temp_pos,(size_t) blob->length);
|
||||||
@@ -1021,11 +1021,11 @@ my_bool _mi_rec_check(MI_INFO *info,const char *record, byte *rec_buff,
|
|||||||
if (type == FIELD_BLOB)
|
if (type == FIELD_BLOB)
|
||||||
{
|
{
|
||||||
uint blob_length=
|
uint blob_length=
|
||||||
_mi_calc_blob_length(length-mi_portable_sizeof_char_ptr,record);
|
_mi_calc_blob_length(length-portable_sizeof_char_ptr,record);
|
||||||
if (!blob_length && !(flag & bit))
|
if (!blob_length && !(flag & bit))
|
||||||
goto err;
|
goto err;
|
||||||
if (blob_length)
|
if (blob_length)
|
||||||
to+=length - mi_portable_sizeof_char_ptr+ blob_length;
|
to+=length - portable_sizeof_char_ptr+ blob_length;
|
||||||
}
|
}
|
||||||
else if (type == FIELD_SKIP_ZERO)
|
else if (type == FIELD_SKIP_ZERO)
|
||||||
{
|
{
|
||||||
@@ -1208,7 +1208,7 @@ ulong _mi_rec_unpack(register MI_INFO *info, register byte *to, byte *from,
|
|||||||
}
|
}
|
||||||
else if (type == FIELD_BLOB)
|
else if (type == FIELD_BLOB)
|
||||||
{
|
{
|
||||||
uint size_length=rec_length- mi_portable_sizeof_char_ptr;
|
uint size_length=rec_length- portable_sizeof_char_ptr;
|
||||||
ulong blob_length=_mi_calc_blob_length(size_length,from);
|
ulong blob_length=_mi_calc_blob_length(size_length,from);
|
||||||
ulong from_left= (ulong) (from_end - from);
|
ulong from_left= (ulong) (from_end - from);
|
||||||
if (from_left < size_length ||
|
if (from_left < size_length ||
|
||||||
|
@@ -453,7 +453,7 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
|
|||||||
if (share->rec[i].type == (int) FIELD_BLOB)
|
if (share->rec[i].type == (int) FIELD_BLOB)
|
||||||
{
|
{
|
||||||
share->blobs[j].pack_length=
|
share->blobs[j].pack_length=
|
||||||
share->rec[i].length-mi_portable_sizeof_char_ptr;;
|
share->rec[i].length-portable_sizeof_char_ptr;;
|
||||||
share->blobs[j].offset=offset;
|
share->blobs[j].offset=offset;
|
||||||
j++;
|
j++;
|
||||||
}
|
}
|
||||||
|
@@ -1036,7 +1036,7 @@ static void uf_blob(MI_COLUMNDEF *rec, MI_BIT_BUFF *bit_buff,
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
ulong length=get_bits(bit_buff,rec->space_length_bits);
|
ulong length=get_bits(bit_buff,rec->space_length_bits);
|
||||||
uint pack_length=(uint) (end-to)-mi_portable_sizeof_char_ptr;
|
uint pack_length=(uint) (end-to)-portable_sizeof_char_ptr;
|
||||||
if (bit_buff->blob_pos+length > bit_buff->blob_end)
|
if (bit_buff->blob_pos+length > bit_buff->blob_end)
|
||||||
{
|
{
|
||||||
bit_buff->error=1;
|
bit_buff->error=1;
|
||||||
|
@@ -83,6 +83,8 @@ int mi_rkey(MI_INFO *info, byte *buf, int inx, const byte *key, uint key_len,
|
|||||||
{
|
{
|
||||||
mi_print_error(info->s, HA_ERR_CRASHED);
|
mi_print_error(info->s, HA_ERR_CRASHED);
|
||||||
my_errno=HA_ERR_CRASHED;
|
my_errno=HA_ERR_CRASHED;
|
||||||
|
if (share->concurrent_insert)
|
||||||
|
rw_unlock(&share->key_root_lock[inx]);
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@@ -71,12 +71,12 @@ static int run_test(const char *filename)
|
|||||||
/* First define 2 columns */
|
/* First define 2 columns */
|
||||||
recinfo[0].type=FIELD_NORMAL; recinfo[0].length=1; /* For NULL bits */
|
recinfo[0].type=FIELD_NORMAL; recinfo[0].length=1; /* For NULL bits */
|
||||||
recinfo[1].type=key_field;
|
recinfo[1].type=key_field;
|
||||||
recinfo[1].length= (key_field == FIELD_BLOB ? 4+mi_portable_sizeof_char_ptr :
|
recinfo[1].length= (key_field == FIELD_BLOB ? 4+portable_sizeof_char_ptr :
|
||||||
key_length);
|
key_length);
|
||||||
if (key_field == FIELD_VARCHAR)
|
if (key_field == FIELD_VARCHAR)
|
||||||
recinfo[1].length+= HA_VARCHAR_PACKLENGTH(key_length);;
|
recinfo[1].length+= HA_VARCHAR_PACKLENGTH(key_length);;
|
||||||
recinfo[2].type=extra_field;
|
recinfo[2].type=extra_field;
|
||||||
recinfo[2].length= (extra_field == FIELD_BLOB ? 4 + mi_portable_sizeof_char_ptr : 24);
|
recinfo[2].length= (extra_field == FIELD_BLOB ? 4 + portable_sizeof_char_ptr : 24);
|
||||||
if (extra_field == FIELD_VARCHAR)
|
if (extra_field == FIELD_VARCHAR)
|
||||||
recinfo[2].length+= HA_VARCHAR_PACKLENGTH(recinfo[2].length);
|
recinfo[2].length+= HA_VARCHAR_PACKLENGTH(recinfo[2].length);
|
||||||
if (opt_unique)
|
if (opt_unique)
|
||||||
|
@@ -188,7 +188,7 @@ int main(int argc, char *argv[])
|
|||||||
if (use_blob)
|
if (use_blob)
|
||||||
{
|
{
|
||||||
recinfo[6].type=FIELD_BLOB;
|
recinfo[6].type=FIELD_BLOB;
|
||||||
recinfo[6].length=4+mi_portable_sizeof_char_ptr;
|
recinfo[6].length=4+portable_sizeof_char_ptr;
|
||||||
recinfo[6].null_bit=0;
|
recinfo[6].null_bit=0;
|
||||||
recinfo[6].null_pos=0;
|
recinfo[6].null_pos=0;
|
||||||
}
|
}
|
||||||
|
@@ -305,7 +305,7 @@ static void usage(void)
|
|||||||
puts("and you are welcome to modify and redistribute it under the GPL license\n");
|
puts("and you are welcome to modify and redistribute it under the GPL license\n");
|
||||||
|
|
||||||
puts("Pack a MyISAM-table to take much less space.");
|
puts("Pack a MyISAM-table to take much less space.");
|
||||||
puts("Keys are not updated, you must run myisamchk -rq on the datafile");
|
puts("Keys are not updated, you must run myisamchk -rq on the index (.MYI) file");
|
||||||
puts("afterwards to update the keys.");
|
puts("afterwards to update the keys.");
|
||||||
puts("You should give the .MYI file as the filename argument.");
|
puts("You should give the .MYI file as the filename argument.");
|
||||||
|
|
||||||
@@ -1008,7 +1008,7 @@ static int get_statistic(PACK_MRG_INFO *mrg,HUFF_COUNTS *huff_counts)
|
|||||||
/* Calculate pos, end_pos, and max_length for variable length fields. */
|
/* Calculate pos, end_pos, and max_length for variable length fields. */
|
||||||
if (count->field_type == FIELD_BLOB)
|
if (count->field_type == FIELD_BLOB)
|
||||||
{
|
{
|
||||||
uint field_length=count->field_length -mi_portable_sizeof_char_ptr;
|
uint field_length=count->field_length -portable_sizeof_char_ptr;
|
||||||
ulong blob_length= _mi_calc_blob_length(field_length, start_pos);
|
ulong blob_length= _mi_calc_blob_length(field_length, start_pos);
|
||||||
memcpy_fixed((char*) &pos, start_pos+field_length,sizeof(char*));
|
memcpy_fixed((char*) &pos, start_pos+field_length,sizeof(char*));
|
||||||
end_pos=pos+blob_length;
|
end_pos=pos+blob_length;
|
||||||
@@ -2650,7 +2650,7 @@ static int compress_isam_file(PACK_MRG_INFO *mrg, HUFF_COUNTS *huff_counts)
|
|||||||
case FIELD_BLOB:
|
case FIELD_BLOB:
|
||||||
{
|
{
|
||||||
ulong blob_length=_mi_calc_blob_length(field_length-
|
ulong blob_length=_mi_calc_blob_length(field_length-
|
||||||
mi_portable_sizeof_char_ptr,
|
portable_sizeof_char_ptr,
|
||||||
start_pos);
|
start_pos);
|
||||||
/* Empty blobs are encoded with a single 1 bit. */
|
/* Empty blobs are encoded with a single 1 bit. */
|
||||||
if (!blob_length)
|
if (!blob_length)
|
||||||
@@ -2667,7 +2667,7 @@ static int compress_isam_file(PACK_MRG_INFO *mrg, HUFF_COUNTS *huff_counts)
|
|||||||
DBUG_PRINT("fields", ("FIELD_BLOB %lu bytes, bits: %2u",
|
DBUG_PRINT("fields", ("FIELD_BLOB %lu bytes, bits: %2u",
|
||||||
blob_length, count->length_bits));
|
blob_length, count->length_bits));
|
||||||
write_bits(blob_length,count->length_bits);
|
write_bits(blob_length,count->length_bits);
|
||||||
memcpy_fixed(&blob,end_pos-mi_portable_sizeof_char_ptr,
|
memcpy_fixed(&blob,end_pos-portable_sizeof_char_ptr,
|
||||||
sizeof(char*));
|
sizeof(char*));
|
||||||
blob_end=blob+blob_length;
|
blob_end=blob+blob_length;
|
||||||
/* Encode the blob bytes. */
|
/* Encode the blob bytes. */
|
||||||
|
@@ -79,7 +79,7 @@ int run_test(const char *filename)
|
|||||||
/* Define spatial column */
|
/* Define spatial column */
|
||||||
|
|
||||||
recinfo[1].type=FIELD_BLOB;
|
recinfo[1].type=FIELD_BLOB;
|
||||||
recinfo[1].length=4 + mi_portable_sizeof_char_ptr;
|
recinfo[1].length=4 + portable_sizeof_char_ptr;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@@ -4,9 +4,9 @@
|
|||||||
#
|
#
|
||||||
0 beshort 0xfe01 MySQL table definition file
|
0 beshort 0xfe01 MySQL table definition file
|
||||||
>2 byte x Version %d
|
>2 byte x Version %d
|
||||||
0 belong&0xffffff00 0xfefe0700 MySQL MISAM index file
|
0 belong&0xffffff00 0xfefe0700 MySQL MyISAM index file
|
||||||
>3 byte x Version %d
|
>3 byte x Version %d
|
||||||
0 belong&0xffffff00 0xfefe0800 MySQL MISAM compressed data file
|
0 belong&0xffffff00 0xfefe0800 MySQL MyISAM compressed data file
|
||||||
>3 byte x Version %d
|
>3 byte x Version %d
|
||||||
0 belong&0xffffff00 0xfefe0900 MySQL Maria index file
|
0 belong&0xffffff00 0xfefe0900 MySQL Maria index file
|
||||||
>3 byte x Version %d
|
>3 byte x Version %d
|
||||||
|
Reference in New Issue
Block a user