Commit 1ad29099 authored by unknown's avatar unknown

Merge of changes in MyISAM since December 16 -> April 1

Fixes bugs:
Bug#28837  MyISAM storage engine error (134) doing delete with self-join
Bug#31277  myisamchk --unpack corrupts table
Bug#4692   DISABLE/ENABLE KEYS waste a space
Bug#31305  myisam tables crash when they are near capacity


BitKeeper/etc/ignore:
  added unittest/tmp/*
mysql-test/r/maria.result:
  Moved missing tests from myisam.test to maria.test
mysql-test/t/maria.test:
  Moved missing tests from myisam.test to maria.test
storage/maria/ha_maria.cc:
  Merge of changes in MyISAM since December 16 -> April 1
  Fixes bug in self join (Bug#28837: MyISAM storage engine error (134) doing delete with self-join)
storage/maria/ha_maria.h:
  Merge of changes in MyISAM since December 16 -> April 1
storage/maria/ma_blockrec.c:
  Merge of changes in MyISAM since December 16 -> April 1
  Fixes bug in self join (Bug#28837: MyISAM storage engine error (134) doing delete with self-join)
  The problem is that we may be using a cached key page with old information. Versioning will fix this
storage/maria/ma_check.c:
  Merge of changes in MyISAM since December 16 -> April 1
  This fixes a problem with pack_reclength not beeing big enough (Bug #31277 myisamchk --unpack corrupts table)
  BUG#4692 - DISABLE/ENABLE KEYS waste a space
storage/maria/ma_delete.c:
  Indentation fixes
storage/maria/ma_dynrec.c:
  Merge of changes in MyISAM since December 16 -> April 1
  Fixes Bug#31305 myisam tables crash when they are near capacity.
  (This uses a simpler fix than in MyISAM by remembering the length of the current row)
storage/maria/ma_ft_boolean_search.c:
  Merge of all changes from myisam/ft_boolean_search.c (This file had not been kept up to date)
storage/maria/ma_open.c:
  Merge of changes in MyISAM since December 16 -> April 1
  Calculate default_rec_buff_size more exact to be sure it's always big enough
storage/maria/ma_packrec.c:
  Merge of changes in MyISAM since December 16 -> April 1
  Update default_rec_buff_size to be big enough to hold one packed row
  Related to Bug#31277 myisamchk --unpack corrupts table
storage/maria/ma_rnext_same.c:
  Indentation fixes
storage/maria/ma_rt_index.c:
  Merge of changes in MyISAM since December 16 -> April 1
storage/maria/ma_rt_mbr.c:
  Merge of changes in MyISAM since December 16 -> April 1
  (Added comment)
storage/maria/ma_search.c:
  Merge of changes in MyISAM since December 16 -> April 1
  (Added comment)
storage/maria/ma_sort.c:
  Merge of changes in MyISAM since December 16 -> April 1
storage/maria/ma_statrec.c:
  Indentation fixes
storage/maria/ma_test2.c:
  Indentation fixes
storage/maria/maria_chk.c:
  Indentation fixes
storage/maria/maria_pack.c:
  Merge of changes in MyISAM since December 16 -> April 1
parent dcfe8c98
......@@ -3078,3 +3078,4 @@ ma_test_recovery.output
test?.MA?
dbug/tests
storage/maria/unittest/tmp/*
unittest/tmp/*
......@@ -1663,6 +1663,88 @@ create table t3 (c1 int) pack_keys=default;
create table t4 (c1 int) pack_keys=2;
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '2' at line 1
drop table t1, t2, t3;
CREATE TABLE t1(a INT, b INT, KEY inx (a), UNIQUE KEY uinx (b));
INSERT INTO t1(a,b) VALUES (1,1),(2,2),(3,3),(4,4),(5,5);
SELECT a FROM t1 FORCE INDEX (inx) WHERE a=1;
a
1
ALTER TABLE t1 DISABLE KEYS;
SELECT a FROM t1 FORCE INDEX (inx) WHERE a=1;
a
1
SELECT a FROM t1 USE INDEX (inx) WHERE a=1;
a
1
SELECT b FROM t1 FORCE INDEX (uinx) WHERE b=1;
b
1
SELECT b FROM t1 USE INDEX (uinx) WHERE b=1;
b
1
SELECT a FROM t1 FORCE INDEX (inx,uinx) WHERE a=1;
a
1
ALTER TABLE t1 ENABLE KEYS;
SELECT a FROM t1 FORCE INDEX (inx) WHERE a=1;
a
1
DROP TABLE t1;
CREATE TABLE t1 (c1 INT, c2 INT, UNIQUE INDEX (c1), INDEX (c2));
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
t1 MARIA 10 Page 0 # # # 8192 # # # # # # #
INSERT INTO t1 VALUES (1,1);
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
t1 MARIA 10 Page 1 # # # 24576 # # # # # # #
ALTER TABLE t1 DISABLE KEYS;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
t1 MARIA 10 Page 1 # # # 24576 # # # # # # #
ALTER TABLE t1 ENABLE KEYS;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
t1 MARIA 10 Page 1 # # # 24576 # # # # # # #
ALTER TABLE t1 DISABLE KEYS;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
t1 MARIA 10 Page 1 # # # 24576 # # # # # # #
ALTER TABLE t1 ENABLE KEYS;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
t1 MARIA 10 Page 1 # # # 24576 # # # # # # #
# Enable keys with parallel repair
SET @@maria_repair_threads=2;
ALTER TABLE t1 DISABLE KEYS;
ALTER TABLE t1 ENABLE KEYS;
SET @@maria_repair_threads=1;
CHECK TABLE t1 EXTENDED;
Table Op Msg_type Msg_text
test.t1 check status OK
DROP TABLE t1;
CREATE TABLE t1 (id int NOT NULL, ref int NOT NULL, INDEX (id));
CREATE TABLE t2 LIKE t1;
INSERT INTO t2 (id, ref) VALUES (1,3), (2,1), (3,2), (4,5), (4,4);
INSERT INTO t1 SELECT * FROM t2;
SELECT * FROM t1 AS a INNER JOIN t1 AS b USING (id) WHERE a.ref < b.ref;
id ref ref
4 4 5
SELECT * FROM t1;
id ref
1 3
2 1
3 2
4 5
4 4
DELETE FROM a USING t1 AS a INNER JOIN t1 AS b USING (id) WHERE a.ref < b.ref;
SELECT * FROM t1;
id ref
1 3
2 1
3 2
4 5
DROP TABLE t1, t2;
End of 5.0 tests
create table t1 (a int not null, key `a` (a) key_block_size=1024);
show create table t1;
Table Create Table
......@@ -2272,3 +2354,12 @@ check table t1 extended;
Table Op Msg_type Msg_text
test.t1 check status OK
drop table t1;
CREATE TABLE t1(a VARCHAR(20), FULLTEXT(a)) transactional=0;
INSERT INTO t1 VALUES('Offside'),('City Of God');
SELECT a FROM t1 WHERE MATCH a AGAINST ('+city of*' IN BOOLEAN MODE);
a
City Of God
SELECT a FROM t1 WHERE MATCH a AGAINST ('+city (of)*' IN BOOLEAN MODE);
a
City Of God
DROP TABLE t1;
......@@ -1035,6 +1035,75 @@ create table t3 (c1 int) pack_keys=default;
create table t4 (c1 int) pack_keys=2;
drop table t1, t2, t3;
#
# Bug#28476: force index on a disabled maria index gives error 124
#
CREATE TABLE t1(a INT, b INT, KEY inx (a), UNIQUE KEY uinx (b));
INSERT INTO t1(a,b) VALUES (1,1),(2,2),(3,3),(4,4),(5,5);
SELECT a FROM t1 FORCE INDEX (inx) WHERE a=1;
ALTER TABLE t1 DISABLE KEYS;
SELECT a FROM t1 FORCE INDEX (inx) WHERE a=1;
SELECT a FROM t1 USE INDEX (inx) WHERE a=1;
SELECT b FROM t1 FORCE INDEX (uinx) WHERE b=1;
SELECT b FROM t1 USE INDEX (uinx) WHERE b=1;
SELECT a FROM t1 FORCE INDEX (inx,uinx) WHERE a=1;
ALTER TABLE t1 ENABLE KEYS;
SELECT a FROM t1 FORCE INDEX (inx) WHERE a=1;
DROP TABLE t1;
#
# Bug#4692 - DISABLE/ENABLE KEYS waste a space
#
CREATE TABLE t1 (c1 INT, c2 INT, UNIQUE INDEX (c1), INDEX (c2));
--replace_column 6 # 7 # 8 # 10 # 11 # 12 # 13 # 14 # 15 # 16 #
SHOW TABLE STATUS LIKE 't1';
INSERT INTO t1 VALUES (1,1);
--replace_column 6 # 7 # 8 # 10 # 11 # 12 # 13 # 14 # 15 # 16 #
SHOW TABLE STATUS LIKE 't1';
ALTER TABLE t1 DISABLE KEYS;
--replace_column 6 # 7 # 8 # 10 # 11 # 12 # 13 # 14 # 15 # 16 #
SHOW TABLE STATUS LIKE 't1';
ALTER TABLE t1 ENABLE KEYS;
--replace_column 6 # 7 # 8 # 10 # 11 # 12 # 13 # 14 # 15 # 16 #
SHOW TABLE STATUS LIKE 't1';
ALTER TABLE t1 DISABLE KEYS;
--replace_column 6 # 7 # 8 # 10 # 11 # 12 # 13 # 14 # 15 # 16 #
SHOW TABLE STATUS LIKE 't1';
ALTER TABLE t1 ENABLE KEYS;
--replace_column 6 # 7 # 8 # 10 # 11 # 12 # 13 # 14 # 15 # 16 #
SHOW TABLE STATUS LIKE 't1';
#--exec ls -log var/master-data/test/t1
#--exec maria_chk -dvv var/master-data/test/t1
#--exec maria_chk -iev var/master-data/test/t1
--echo # Enable keys with parallel repair
SET @@maria_repair_threads=2;
ALTER TABLE t1 DISABLE KEYS;
ALTER TABLE t1 ENABLE KEYS;
SET @@maria_repair_threads=1;
CHECK TABLE t1 EXTENDED;
DROP TABLE t1;
#
# Bug#28837: Maria storage engine error (134) doing delete with self-join
#
CREATE TABLE t1 (id int NOT NULL, ref int NOT NULL, INDEX (id));
CREATE TABLE t2 LIKE t1;
INSERT INTO t2 (id, ref) VALUES (1,3), (2,1), (3,2), (4,5), (4,4);
INSERT INTO t1 SELECT * FROM t2;
SELECT * FROM t1 AS a INNER JOIN t1 AS b USING (id) WHERE a.ref < b.ref;
SELECT * FROM t1;
DELETE FROM a USING t1 AS a INNER JOIN t1 AS b USING (id) WHERE a.ref < b.ref;
SELECT * FROM t1;
DROP TABLE t1, t2;
--echo End of 5.0 tests
#
# Test of key_block_size
#
......@@ -1490,6 +1559,15 @@ delete from t1 where i = 10;
check table t1 extended;
drop table t1;
#
# BUG#29445 - match ... against () never returns
#
CREATE TABLE t1(a VARCHAR(20), FULLTEXT(a)) transactional=0;
INSERT INTO t1 VALUES('Offside'),('City Of God');
SELECT a FROM t1 WHERE MATCH a AGAINST ('+city of*' IN BOOLEAN MODE);
SELECT a FROM t1 WHERE MATCH a AGAINST ('+city (of)*' IN BOOLEAN MODE);
DROP TABLE t1;
# End of 5.1 tests
--disable_result_log
......
......@@ -273,6 +273,10 @@ static void _ma_check_print_msg(HA_CHECK *param, const char *msg_type,
definition for further use in ma_create or for a check for underlying
table conformance in merge engine.
The caller needs to free *recinfo_out after use. Since *recinfo_out
and *keydef_out are allocated with a my_multi_malloc, *keydef_out
is freed automatically when *recinfo_out is freed.
RETURN VALUE
0 OK
# error code
......@@ -1649,9 +1653,9 @@ int ha_maria::enable_indexes(uint mode)
param.testflag &= ~(T_REP_BY_SORT | T_QUICK);
error= (repair(thd, param, 0) != HA_ADMIN_OK);
/*
If the standard repair succeeded, clear all error messages which
might have been set by the first repair. They can still be seen
with SHOW WARNINGS then.
If the standard repair succeeded, clear all error messages which
might have been set by the first repair. They can still be seen
with SHOW WARNINGS then.
*/
if (!error)
thd->clear_error();
......@@ -1974,9 +1978,17 @@ int ha_maria::index_next_same(uchar * buf,
const uchar *key __attribute__ ((unused)),
uint length __attribute__ ((unused)))
{
int error;
DBUG_ASSERT(inited == INDEX);
ha_statistic_increment(&SSV::ha_read_next_count);
int error= maria_rnext_same(file, buf);
/*
TODO: Delete this loop in Maria 1.5 as versioning will ensure this never
happens
*/
do
{
error= maria_rnext_same(file,buf);
} while (error == HA_ERR_RECORD_DELETED);
table->status= error ? STATUS_NOT_FOUND : 0;
return error;
}
......
......@@ -157,6 +157,9 @@ class ha_maria :public handler
*engine_callback,
ulonglong *engine_data);
#endif
MARIA_HA *file_ptr(void)
{
return file;
}
static int implicit_commit(THD *thd);
};
......@@ -4770,8 +4770,8 @@ int _ma_read_block_record(MARIA_HA *info, uchar *record,
if (!(data= get_record_position(buff, block_size, offset, &end_of_data)))
{
DBUG_PRINT("error", ("Wrong directory entry in data block"));
my_errno= HA_ERR_WRONG_IN_RECORD; /* File crashed */
DBUG_RETURN(HA_ERR_WRONG_IN_RECORD);
my_errno= HA_ERR_RECORD_DELETED; /* File crashed */
DBUG_RETURN(HA_ERR_RECORD_DELETED);
}
DBUG_RETURN(_ma_read_block_record2(info, record, data, end_of_data));
}
......
......@@ -489,7 +489,7 @@ int maria_chk_key(HA_CHECK *param, register MARIA_HA *info)
if ((!(param->testflag & T_SILENT)))
printf ("- check data record references index: %d\n",key+1);
if (keyinfo->flag & HA_FULLTEXT)
if (keyinfo->flag & (HA_FULLTEXT | HA_SPATIAL))
full_text_keys++;
if (share->state.key_root[key] == HA_OFFSET_ERROR)
{
......@@ -1914,7 +1914,7 @@ int maria_chk_data_link(HA_CHECK *param, MARIA_HA *info, my_bool extend)
puts("- check record links");
}
if (!(record= (uchar*) my_malloc(share->base.pack_reclength,MYF(0))))
if (!(record= (uchar*) my_malloc(share->base.default_rec_buff_size, MYF(0))))
{
_ma_check_print_error(param,"Not enough memory for record");
DBUG_RETURN(-1);
......@@ -2199,6 +2199,121 @@ static int initialize_variables_for_repair(HA_CHECK *param,
}
/**
@brief Drop all indexes
@param[in] param check parameters
@param[in] info MARIA_HA handle
@param[in] force if to force drop all indexes
@return status
@retval 0 OK
@retval != 0 Error
@note
Once allocated, index blocks remain part of the key file forever.
When indexes are disabled, no block is freed. When enabling indexes,
no block is freed either. The new indexes are create from new
blocks. (Bug #4692)
Before recreating formerly disabled indexes, the unused blocks
must be freed. There are two options to do this:
- Follow the tree of disabled indexes, add all blocks to the
deleted blocks chain. Would require a lot of random I/O.
- Drop all blocks by clearing all index root pointers and all
delete chain pointers and resetting key_file_length to the end
of the index file header. This requires to recreate all indexes,
even those that may still be intact.
The second method is probably faster in most cases.
When disabling indexes, MySQL disables either all indexes or all
non-unique indexes. When MySQL [re-]enables disabled indexes
(T_CREATE_MISSING_KEYS), then we either have "lost" blocks in the
index file, or there are no non-unique indexes. In the latter case,
maria_repair*() would not be called as there would be no disabled
indexes.
If there would be more unique indexes than disabled (non-unique)
indexes, we could do the first method. But this is not implemented
yet. By now we drop and recreate all indexes when repair is called.
However, there is an exception. Sometimes MySQL disables non-unique
indexes when the table is empty (e.g. when copying a table in
mysql_alter_table()). When enabling the non-unique indexes, they
are still empty. So there is no index block that can be lost. This
optimization is implemented in this function.
Note that in normal repair (T_CREATE_MISSING_KEYS not set) we
recreate all enabled indexes unconditonally. We do not change the
key_map. Otherwise we invert the key map temporarily (outside of
this function) and recreate the then "seemingly" enabled indexes.
When we cannot use the optimization, and drop all indexes, we
pretend that all indexes were disabled. By the inversion, we will
then recrate all indexes.
*/
static int maria_drop_all_indexes(HA_CHECK *param, MARIA_HA *info,
my_bool force)
{
MARIA_SHARE *share= info->s;
MARIA_STATE_INFO *state= &share->state;
uint i;
DBUG_ENTER("maria_drop_all_indexes");
/*
If any of the disabled indexes has a key block assigned, we must
drop and recreate all indexes to avoid losing index blocks.
If we want to recreate disabled indexes only _and_ all of these
indexes are empty, we don't need to recreate the existing indexes.
*/
if (!force && (param->testflag & T_CREATE_MISSING_KEYS))
{
DBUG_PRINT("repair", ("creating missing indexes"));
for (i= 0; i < share->base.keys; i++)
{
DBUG_PRINT("repair", ("index #: %u key_root: 0x%lx active: %d",
i, (long) state->key_root[i],
maria_is_key_active(state->key_map, i)));
if ((state->key_root[i] != HA_OFFSET_ERROR) &&
!maria_is_key_active(state->key_map, i))
{
/*
This index has at least one key block and it is disabled.
We would lose its block(s) if would just recreate it.
So we need to drop and recreate all indexes.
*/
DBUG_PRINT("repair", ("nonempty and disabled: recreate all"));
break;
}
}
if (i >= share->base.keys)
goto end;
/*
We do now drop all indexes and declare them disabled. With the
T_CREATE_MISSING_KEYS flag, maria_repair*() will recreate all
disabled indexes and enable them.
*/
maria_clear_all_keys_active(state->key_map);
DBUG_PRINT("repair", ("declared all indexes disabled"));
}
/* Clear index root block pointers. */
for (i= 0; i < share->base.keys; i++)
state->key_root[i]= HA_OFFSET_ERROR;
/* Drop the delete chain. */
share->state.key_del= HA_OFFSET_ERROR;
/* Reset index file length to end of index file header. */
info->state->key_file_length= share->base.keystart;
end:
DBUG_RETURN(0);
}
/*
Recover old table by reading each record and writing all keys
......@@ -2225,7 +2340,6 @@ int maria_repair(HA_CHECK *param, register MARIA_HA *info,
char *name, my_bool rep_quick)
{
int error, got_error;
uint i;
ha_rows start_records,new_header_length;
my_off_t del;
File new_file;
......@@ -2317,9 +2431,9 @@ int maria_repair(HA_CHECK *param, register MARIA_HA *info,
goto err;
}
if (!(sort_param.record= (uchar *) my_malloc((uint)
share->base.pack_reclength,
MYF(0))) ||
if (!(sort_param.record=
(uchar *) my_malloc((uint)
share->base.default_rec_buff_size, MYF(0))) ||
_ma_alloc_buffer(&sort_param.rec_buff, &sort_param.rec_buff_size,
share->base.default_rec_buff_size))
{
......@@ -2337,24 +2451,9 @@ int maria_repair(HA_CHECK *param, register MARIA_HA *info,
info->state->records=info->state->del=share->state.split=0;
info->state->empty=0;
/*
Clear all keys. Note that all key blocks allocated until now remain
"dead" parts of the key file. (Bug #4692)
*/
for (i=0 ; i < share->base.keys ; i++)
share->state.key_root[i]= HA_OFFSET_ERROR;
/* Drop the delete chain. */
share->state.key_del= HA_OFFSET_ERROR;
/*
If requested, activate (enable) all keys in key_map. In this case,
all indexes will be (re-)built.
*/
if (param->testflag & T_CREATE_MISSING_KEYS)
maria_set_all_keys_active(share->state.key_map, share->base.keys);
info->state->key_file_length=share->base.keystart;
maria_drop_all_indexes(param, info, TRUE);
maria_lock_memory(param); /* Everything is alloced */
......@@ -2368,7 +2467,8 @@ int maria_repair(HA_CHECK *param, register MARIA_HA *info,
{
if (my_errno != HA_ERR_FOUND_DUPP_KEY)
goto err;
DBUG_DUMP("record",(uchar*) sort_param.record,share->base.pack_reclength);
DBUG_DUMP("record", (uchar*) sort_param.record,
share->base.default_rec_buff_size);
_ma_check_print_warning(param,
"Duplicate key %2d for record at %10s against new record at %10s",
info->errkey+1,
......@@ -3257,11 +3357,12 @@ int maria_repair_by_sort(HA_CHECK *param, register MARIA_HA *info,
double *rec_per_key_part;
char llbuff[22];
MARIA_SORT_INFO sort_info;
ulonglong key_map= share->state.key_map;
ulonglong key_map;
myf sync_dir= ((share->now_transactional && !share->temporary) ?
MY_SYNC_DIR : 0);
my_bool scan_inited= 0;
DBUG_ENTER("maria_repair_by_sort");
LINT_INIT(key_map);
got_error= 1;
new_file= -1;
......@@ -3338,8 +3439,9 @@ int maria_repair_by_sort(HA_CHECK *param, register MARIA_HA *info,
}
}
if (!(sort_param.record=(uchar*) my_malloc((uint) share->base.pack_reclength,
MYF(0))) ||
if (!(sort_param.record=
(uchar*) my_malloc((size_t) share->base.default_rec_buff_size,
MYF(0))) ||
_ma_alloc_buffer(&sort_param.rec_buff, &sort_param.rec_buff_size,
share->base.default_rec_buff_size))
{
......@@ -3347,16 +3449,14 @@ int maria_repair_by_sort(HA_CHECK *param, register MARIA_HA *info,
goto err;
}
if (!(param->testflag & T_CREATE_MISSING_KEYS))
/* Optionally drop indexes and optionally modify the key_map */
maria_drop_all_indexes(param, info, FALSE);
key_map= share->state.key_map;
if (param->testflag & T_CREATE_MISSING_KEYS)
{
/* Clear the pointers to the given rows */
for (i=0 ; i < share->base.keys ; i++)
share->state.key_root[i]= HA_OFFSET_ERROR;
share->state.key_del= HA_OFFSET_ERROR;
info->state->key_file_length=share->base.keystart;
/* Invert the copied key_map to recreate all disabled indexes. */
key_map= ~key_map;
}
else
key_map= ~key_map; /* Create the missing keys */
param->read_cache.end_of_file= sort_info.filelength;
sort_param.wordlist=NULL;
......@@ -3374,6 +3474,10 @@ int maria_repair_by_sort(HA_CHECK *param, register MARIA_HA *info,
rec_per_key_part+=sort_param.keyinfo->keysegs, sort_param.key++)
{
sort_param.keyinfo=share->keyinfo+sort_param.key;
/*
Skip this index if it is marked disabled in the copied
(and possibly inverted) key_map.
*/
if (! maria_is_key_active(key_map, sort_param.key))
{
/* Remember old statistics for key */
......@@ -3381,6 +3485,8 @@ int maria_repair_by_sort(HA_CHECK *param, register MARIA_HA *info,
(char*) (share->state.rec_per_key_part +
(uint) (rec_per_key_part - param->new_rec_per_key_part)),
sort_param.keyinfo->keysegs*sizeof(*rec_per_key_part));
DBUG_PRINT("repair", ("skipping seemingly disabled index #: %u",
sort_param.key));
continue;
}
......@@ -3492,6 +3598,7 @@ int maria_repair_by_sort(HA_CHECK *param, register MARIA_HA *info,
sort_param.notnull : NULL),
(ulonglong) info->state->records);
maria_set_key_active(share->state.key_map, sort_param.key);
DBUG_PRINT("repair", ("set enabled index #: %u", sort_param.key));
if (_ma_flush_table_files_before_swap(param, info))
goto err;
......@@ -3743,11 +3850,12 @@ int maria_repair_parallel(HA_CHECK *param, register MARIA_HA *info,
IO_CACHE new_data_cache; /* For non-quick repair. */
IO_CACHE_SHARE io_share;
MARIA_SORT_INFO sort_info;
ulonglong key_map=share->state.key_map;
ulonglong key_map;
pthread_attr_t thr_attr;
myf sync_dir= ((share->now_transactional && !share->temporary) ?
MY_SYNC_DIR : 0);
DBUG_ENTER("maria_repair_parallel");
LINT_INIT(key_map);
got_error= 1;
new_file= -1;
......@@ -3768,19 +3876,19 @@ int maria_repair_parallel(HA_CHECK *param, register MARIA_HA *info,
/*
Quick repair (not touching data file, rebuilding indexes):
{
Read cache is (MI_CHECK *param)->read_cache using info->dfile.file.
Read cache is (HA_CHECK *param)->read_cache using info->dfile.file.
}
Non-quick repair (rebuilding data file and indexes):
{
Master thread:
Read cache is (MI_CHECK *param)->read_cache using info->dfile.file.
Write cache is (MI_INFO *info)->rec_cache using new_file.
Read cache is (HA_CHECK *param)->read_cache using info->dfile.file.
Write cache is (MARIA_INFO *info)->rec_cache using new_file.
Slave threads:
Read cache is new_data_cache synced to master rec_cache.
Read cache is new_data_cache synced to master rec_cache.
The final assignment of the filedescriptor for rec_cache is done
after the cache creation.
......@@ -3843,17 +3951,14 @@ int maria_repair_parallel(HA_CHECK *param, register MARIA_HA *info,
info->rec_cache.file=new_file;
}
info->update= (short) (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED);
if (!(param->testflag & T_CREATE_MISSING_KEYS))
/* Optionally drop indexes and optionally modify the key_map. */
maria_drop_all_indexes(param, info, FALSE);
key_map= share->state.key_map;
if (param->testflag & T_CREATE_MISSING_KEYS)
{
/* Clear the pointers to the given rows */
for (i=0 ; i < share->base.keys ; i++)
share->state.key_root[i]= HA_OFFSET_ERROR;
share->state.key_del= HA_OFFSET_ERROR;
info->state->key_file_length=share->base.keystart;
/* Invert the copied key_map to recreate all disabled indexes. */
key_map= ~key_map;
}
else
key_map= ~key_map; /* Create the missing keys */
param->read_cache.end_of_file= sort_info.filelength;
......@@ -3892,6 +3997,10 @@ int maria_repair_parallel(HA_CHECK *param, register MARIA_HA *info,
sort_param[i].key=key;
sort_param[i].keyinfo=share->keyinfo+key;
sort_param[i].seg=sort_param[i].keyinfo->seg;
/*
Skip this index if it is marked disabled in the copied
(and possibly inverted) key_map.
*/
if (! maria_is_key_active(key_map, key))
{
/* Remember old statistics for key */
......@@ -5729,8 +5838,8 @@ void _ma_update_auto_increment_key(HA_CHECK *param, MARIA_HA *info,
We have to use an allocated buffer instead of info->rec_buff as
_ma_put_key_in_record() may use info->rec_buff
*/
if (!(record= (uchar*) my_malloc((uint) share->base.pack_reclength,
MYF(0))))
if (!(record= (uchar*) my_malloc((size_t) share->base.default_rec_buff_size,
MYF(0))))
{
_ma_check_print_error(param,"Not enough memory for extra record");
DBUG_VOID_RETURN;
......
......@@ -81,7 +81,7 @@ int maria_delete(MARIA_HA *info,const uchar *record)
if (maria_is_key_active(share->state.key_map, i))
{
share->keyinfo[i].version++;
if (share->keyinfo[i].flag & HA_FULLTEXT )
if (share->keyinfo[i].flag & HA_FULLTEXT)
{
if (_ma_ft_del(info, i, old_key, record, info->cur_row.lastpos))
goto err;
......
......@@ -329,6 +329,29 @@ static my_bool write_dynamic_record(MARIA_HA *info, const uchar *record,
DBUG_ENTER("write_dynamic_record");
flag=0;
/*
Check if we have enough room for the new record.
First we do simplified check to make usual case faster.
Then we do more precise check for the space left.
Though it still is not absolutely precise, as
we always use MARIA_MAX_DYN_BLOCK_HEADER while it can be
less in the most of the cases.
*/
if (unlikely(info->s->base.max_data_file_length -
info->state->data_file_length <
reclength + MARIA_MAX_DYN_BLOCK_HEADER))
{
if (info->s->base.max_data_file_length - info->state->data_file_length +
info->state->empty - info->state->del * MARIA_MAX_DYN_BLOCK_HEADER <
reclength + MARIA_MAX_DYN_BLOCK_HEADER)
{
my_errno=HA_ERR_RECORD_FILE_FULL;
DBUG_RETURN(1);
}
}
do
{
if (_ma_find_writepos(info,reclength,&filepos,&length))
......@@ -771,6 +794,37 @@ static my_bool update_dynamic_record(MARIA_HA *info, MARIA_RECORD_POS filepos,
DBUG_ENTER("update_dynamic_record");
flag=block_info.second_read=0;
/*
Check if we have enough room for the record.
First we do simplified check to make usual case faster.
Then we do more precise check for the space left.
Though it still is not absolutely precise, as
we always use MARIA_MAX_DYN_BLOCK_HEADER while it can be
less in the most of the cases.
*/
/*
compare with just the reclength as we're going
to get some space from the old replaced record
*/
if (unlikely(info->s->base.max_data_file_length -
info->state->data_file_length < reclength))
{
/* If new record isn't longer, we can go on safely */
if (info->cur_row.total_length < reclength)
{
if (info->s->base.max_data_file_length - info->state->data_file_length +
info->state->empty - info->state->del * MARIA_MAX_DYN_BLOCK_HEADER <
reclength - info->cur_row.total_length + MARIA_MAX_DYN_BLOCK_HEADER)
{
my_errno=HA_ERR_RECORD_FILE_FULL;
goto err;
}
}
}
/* Remember length for updated row if it's updated again */
info->cur_row.total_length= reclength;
while (reclength > 0)
{
if (filepos != info->s->state.dellink)
......@@ -876,6 +930,7 @@ static my_bool update_dynamic_record(MARIA_HA *info, MARIA_RECORD_POS filepos,
if (block_info.next_filepos != HA_OFFSET_ERROR)
if (delete_dynamic_record(info,block_info.next_filepos,1))
goto err;
DBUG_RETURN(0);
err:
DBUG_RETURN(1);
......@@ -1420,6 +1475,7 @@ int _ma_read_dynamic_record(MARIA_HA *info, uchar *buf,
}
if (block_of_record++ == 0) /* First block */
{
info->cur_row.total_length= block_info.rec_len;
if (block_info.rec_len > (uint) info->s->base.max_pack_length)
goto panic;
if (info->s->base.blobs)
......@@ -1752,6 +1808,7 @@ int _ma_read_rnd_dynamic_record(MARIA_HA *info,
}
if (block_of_record == 0) /* First block */
{
info->cur_row.total_length= block_info.rec_len;
if (block_info.rec_len > (uint) share->base.max_pack_length)
goto panic;
info->cur_row.lastpos= filepos;
......
......@@ -23,8 +23,14 @@
inside plus subtree. max_docid could be used by any word in plus
subtree, but it could be updated by plus-word only.
Fulltext "smarter index merge" optimization assumes that rows
it gets are ordered by doc_id. That is not the case when we
search for a word with truncation operator. It may return
rows in random order. Thus we may not use "smarter index merge"
optimization with "trunc-words".
The idea is: there is no need to search for docid smaller than
biggest docid inside current plus subtree.
biggest docid inside current plus subtree or any upper plus subtree.
Examples:
+word1 word2
......@@ -36,6 +42,13 @@
+(word1 -word2) +(+word3 word4)
share same max_docid
max_docid updated by word3
+word1 word2 (+word3 word4 (+word5 word6))
three subexpressions (including the top-level one),
every one has its own max_docid, updated by its plus word.
but for the search word6 uses
max(word1.max_docid, word3.max_docid, word5.max_docid),
while word4 uses, accordingly,
max(word1.max_docid, word3.max_docid).
*/
#define FT_CORE
......@@ -104,14 +117,14 @@ typedef struct st_ftb_word
/* ^^^^^^^^^^^^^^^^^^ FTB_{EXPR,WORD} common section */
my_off_t docid[2]; /* for index search and for scan */
my_off_t key_root;
my_off_t *max_docid;
FTB_EXPR *max_docid_expr;
MARIA_KEYDEF *keyinfo;
struct st_ftb_word *prev;
float weight;
uint ndepth;
uint len;
uchar off;
uchar word[1];
uchar word[1];
} FTB_WORD;
typedef struct st_ft_info
......@@ -208,13 +221,13 @@ static int ftb_query_add_word(MYSQL_FTPARSER_PARAM *param,
for (tmp_expr= ftb_param->ftbe; tmp_expr->up; tmp_expr= tmp_expr->up)
if (! (tmp_expr->flags & FTB_FLAG_YES))
break;
ftbw->max_docid= &tmp_expr->max_docid;
ftbw->max_docid_expr= tmp_expr;
/* fall through */
case FT_TOKEN_STOPWORD:
if (! ftb_param->up_quot) break;
phrase_word= (FT_WORD *)alloc_root(&ftb_param->ftb->mem_root, sizeof(FT_WORD));
tmp_element= (LIST *)alloc_root(&ftb_param->ftb->mem_root, sizeof(LIST));
phrase_word->pos= (uchar *) word;
phrase_word->pos= (uchar*) word;
phrase_word->len= word_len;
tmp_element->data= (void *)phrase_word;
ftb_param->ftbe->phrase= list_add(ftb_param->ftbe->phrase, tmp_element);
......@@ -240,7 +253,7 @@ static int ftb_query_add_word(MYSQL_FTPARSER_PARAM *param,
if (info->yesno > 0) ftbe->up->ythresh++;
ftb_param->ftbe= ftbe;
ftb_param->depth++;
ftb_param->up_quot= (uchar *) info->quot;
ftb_param->up_quot= (uchar*) info->quot;
break;
case FT_TOKEN_RIGHT_PAREN:
if (ftb_param->ftbe->document)
......@@ -275,12 +288,12 @@ static int ftb_parse_query_internal(MYSQL_FTPARSER_PARAM *param,
MYSQL_FTPARSER_BOOLEAN_INFO info;
CHARSET_INFO *cs= ftb_param->ftb->charset;
uchar **start= (uchar**) &query;
char *end= query + len;
uchar *end= (uchar*) query + len;
FT_WORD w;
info.prev= ' ';
info.quot= 0;
while (maria_ft_get_word(cs, start, (uchar *) end, &w, &info))
while (maria_ft_get_word(cs, start, end, &w, &info))
param->mysql_add_word(param, (char *) w.pos, w.len, &info);
return(0);
}
......@@ -308,7 +321,7 @@ static int _ftb_parse_query(FTB *ftb, uchar *query, uint len,
param->mysql_add_word= ftb_query_add_word;
param->mysql_ftparam= (void *)&ftb_param;
param->cs= ftb->charset;
param->doc= (char *) query;
param->doc= (char*) query;
param->length= len;
param->flags= 0;
param->mode= MYSQL_FTPARSER_FULL_BOOLEAN_INFO;
......@@ -329,8 +342,9 @@ static int _ft2_search(FTB *ftb, FTB_WORD *ftbw, my_bool init_search)
int subkeys=1;
my_bool can_go_down;
MARIA_HA *info=ftb->info;
uint off= 0, extra=HA_FT_WLEN+info->s->base.rec_reflength;
uint off, extra=HA_FT_WLEN+info->s->base.rec_reflength;
uchar *lastkey_buf= ftbw->word+ftbw->off;
LINT_INIT(off);
if (ftbw->flags & FTB_FLAG_TRUNC)
lastkey_buf+=ftbw->len;
......@@ -346,11 +360,17 @@ static int _ft2_search(FTB *ftb, FTB_WORD *ftbw, my_bool init_search)
else
{
uint sflag= SEARCH_BIGGER;
if (ftbw->docid[0] < *ftbw->max_docid)
my_off_t max_docid=0;
FTB_EXPR *tmp;
for (tmp= ftbw->max_docid_expr; tmp; tmp= tmp->up)
set_if_bigger(max_docid, tmp->max_docid);
if (ftbw->docid[0] < max_docid)
{
sflag|= SEARCH_SAME;
_ma_dpointer(info, (ftbw->word + ftbw->len + HA_FT_WLEN),
*ftbw->max_docid);
_ma_dpointer(info, (uchar*) (ftbw->word + ftbw->len + HA_FT_WLEN),
max_docid);
}
r= _ma_search(info, ftbw->keyinfo, lastkey_buf,
USE_WHOLE_KEY, sflag, ftbw->key_root);
......@@ -376,7 +396,7 @@ static int _ft2_search(FTB *ftb, FTB_WORD *ftbw, my_bool init_search)
if (!r && !ftbw->off)
{
r= ha_compare_text(ftb->charset,
(uchar*) info->lastkey+1,
info->lastkey+1,
info->lastkey_length-extra-1,
(uchar*) ftbw->word+1,
ftbw->len-1,
......@@ -429,8 +449,8 @@ static int _ft2_search(FTB *ftb, FTB_WORD *ftbw, my_bool init_search)
memcpy(lastkey_buf+off, info->lastkey, info->lastkey_length);
}
ftbw->docid[0]= info->cur_row.lastpos;
if (ftbw->flags & FTB_FLAG_YES)
*ftbw->max_docid= info->cur_row.lastpos;
if (ftbw->flags & FTB_FLAG_YES && !(ftbw->flags & FTB_FLAG_TRUNC))
ftbw->max_docid_expr->max_docid= info->cur_row.lastpos;
return 0;
}
......@@ -473,7 +493,8 @@ static void _ftb_init_index_search(FT_INFO *ftb)
ftbe->up->flags|= FTB_FLAG_TRUNC, ftbe=ftbe->up)
{
if (ftbe->flags & FTB_FLAG_NO || /* 2 */
ftbe->up->ythresh - ftbe->up->yweaks >1) /* 1 */
ftbe->up->ythresh - ftbe->up->yweaks >
(uint) test(ftbe->flags & FTB_FLAG_YES)) /* 1 */
{
FTB_EXPR *top_ftbe=ftbe->up;
ftbw->docid[0]=HA_OFFSET_ERROR;
......@@ -503,8 +524,9 @@ static void _ftb_init_index_search(FT_INFO *ftb)
}
FT_INFO * maria_ft_init_boolean_search(MARIA_HA *info, uint keynr, uchar *query,
uint query_len, CHARSET_INFO *cs)
FT_INFO * maria_ft_init_boolean_search(MARIA_HA *info, uint keynr,
uchar *query,
uint query_len, CHARSET_INFO *cs)
{
FTB *ftb;
FTB_EXPR *ftbe;
......@@ -585,7 +607,7 @@ static int ftb_phrase_add_word(MYSQL_FTPARSER_PARAM *param,
MY_FTB_PHRASE_PARAM *phrase_param= param->mysql_ftparam;
FT_WORD *w= (FT_WORD *)phrase_param->document->data;
LIST *phrase, *document;
w->pos= (uchar *) word;
w->pos= (uchar*) word;
w->len= word_len;
phrase_param->document= phrase_param->document->prev;
if (phrase_param->phrase_length > phrase_param->document_length)
......@@ -600,8 +622,8 @@ static int ftb_phrase_add_word(MYSQL_FTPARSER_PARAM *param,
{
FT_WORD *phrase_word= (FT_WORD *)phrase->data;
FT_WORD *document_word= (FT_WORD *)document->data;
if (my_strnncoll(phrase_param->cs,
(uchar*) phrase_word->pos, phrase_word->len,
if (my_strnncoll(phrase_param->cs, (uchar*) phrase_word->pos,
phrase_word->len,
(uchar*) document_word->pos, document_word->len))
return 0;
}
......@@ -615,11 +637,11 @@ static int ftb_check_phrase_internal(MYSQL_FTPARSER_PARAM *param,
{
FT_WORD word;
MY_FTB_PHRASE_PARAM *phrase_param= param->mysql_ftparam;
const char *docend= document + len;
const uchar *docend= (uchar*) document + len;
while (maria_ft_simple_get_word(phrase_param->cs, (uchar**) &document,
(const uchar *) docend, &word, FALSE))
docend, &word, FALSE))
{
param->mysql_add_word(param, (char *) word.pos, word.len, 0);
param->mysql_add_word(param, (char*) word.pos, word.len, 0);
if (phrase_param->match)
break;
}
......@@ -663,7 +685,7 @@ static int _ftb_check_phrase(FTB *ftb, const uchar *document, uint len,
param->mysql_add_word= ftb_phrase_add_word;
param->mysql_ftparam= (void *)&ftb_param;
param->cs= ftb->charset;
param->doc= (char *)document;
param->doc= (char *) document;
param->length= len;
param->flags= 0;
param->mode= MYSQL_FTPARSER_WITH_STOPWORDS;
......@@ -875,10 +897,10 @@ static int ftb_find_relevance_parse(MYSQL_FTPARSER_PARAM *param,
{
MY_FTB_FIND_PARAM *ftb_param= param->mysql_ftparam;
FT_INFO *ftb= ftb_param->ftb;
char *end= doc + len;
uchar *end= (uchar*) doc + len;
FT_WORD w;
while (maria_ft_simple_get_word(ftb->charset, (uchar**) &doc,
(const uchar *) end, &w, TRUE))
end, &w, TRUE))
param->mysql_add_word(param, (char *) w.pos, w.len, 0);
return(0);
}
......
......@@ -686,23 +686,24 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags)
share->page_type= PAGECACHE_PLAIN_PAGE;
share->now_transactional= share->base.born_transactional;
if (share->data_file_type == DYNAMIC_RECORD)
/* Use pack_reclength as we don't want to modify base.pack_recklength */
if (share->state.header.org_data_file_type == DYNAMIC_RECORD)
{
/* add bits used to pack data to pack_reclength for faster allocation */
/* add bits used to pack data to pack_reclength for faster allocation */
share->base.pack_reclength+= share->base.pack_bytes;
share->base.extra_rec_buff_size=
(ALIGN_SIZE(MARIA_MAX_DYN_BLOCK_HEADER) + MARIA_SPLIT_LENGTH +
MARIA_REC_BUFF_OFFSET);
}
share->base.default_rec_buff_size= (max(share->base.pack_reclength,
share->base.max_key_length) +
share->base.extra_rec_buff_size);
if (share->data_file_type == COMPRESSED_RECORD)
{
/* Need some extra bytes for decode_bytes */
share->base.extra_rec_buff_size= 7;
share->base.extra_rec_buff_size+= 7;
}
share->base.default_rec_buff_size= max(share->base.pack_reclength +
share->base.extra_rec_buff_size,
share->base.max_key_length);
disk_pos_assert(disk_pos + share->base.fields *MARIA_COLUMNDEF_SIZE,
end_pos);
for (i= j= 0 ; i < share->base.fields ; i++)
......
......@@ -200,7 +200,8 @@ static my_bool _ma_read_pack_info(MARIA_SHARE *share, File file,
share->pack.header_length= uint4korr(header+4);
share->min_pack_length=(uint) uint4korr(header+8);
share->max_pack_length=(uint) uint4korr(header+12);
set_if_bigger(share->base.pack_reclength,share->max_pack_length);
set_if_bigger(share->base.default_rec_buff_size,
share->max_pack_length + 7);
elements=uint4korr(header+16);
intervall_length=uint4korr(header+20);
trees=uint2korr(header+24);
......@@ -605,7 +606,7 @@ static void fill_quick_table(uint16 *table, uint bits, uint max_bits,
*/
value|= (max_bits - bits) << 8 | IS_CHAR;
for (end= table + (uint) (((uint) 1 << bits)); table < end; table++)
for (end= table + ((my_ptrdiff_t) 1 << bits); table < end; table++)
{
*table= (uint16) value;
}
......
......@@ -66,8 +66,8 @@ int maria_rnext_same(MARIA_HA *info, uchar *buf)
for (;;)
{
if ((error= _ma_search_next(info,keyinfo,info->lastkey,
info->lastkey_length,SEARCH_BIGGER,
info->s->state.key_root[inx])))
info->lastkey_length,SEARCH_BIGGER,
info->s->state.key_root[inx])))
break;
if (ha_key_cmp(keyinfo->seg, (uchar*) info->lastkey,
(uchar*) info->lastkey2,
......
......@@ -461,15 +461,16 @@ static uchar *maria_rtree_pick_key(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
uint nod_flag)
{
double increase;
double best_incr= DBL_MAX;
double best_incr;
double perimeter;
double best_perimeter;
uchar *best_key;
uchar *best_key= NULL;
uchar *k= rt_PAGE_FIRST_KEY(page_buf, nod_flag);
uchar *last= rt_PAGE_END(info, page_buf);
LINT_INIT(best_perimeter);
LINT_INIT(best_key);
LINT_INIT(best_incr);
for (; k < last; k= rt_PAGE_NEXT_KEY(k, key_length, nod_flag))
{
......@@ -514,22 +515,13 @@ static uchar *maria_rtree_pick_key(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
&area)) == -1.0)
return NULL;
/* The following should be safe, even if we compare doubles */
if (increase < best_incr)
if (!best_key || increase < best_incr ||
((increase == best_incr) && (area < best_area)))
{
best_key= k;
best_area= area;
best_incr= increase;
}
else
{
/* The following should be safe, even if we compare doubles */
if ((increase == best_incr) && (area < best_area))
{
best_key= k;
best_area= area;
best_incr= increase;
}
}
}
return best_key;
}
......
......@@ -526,6 +526,9 @@ double maria_rtree_overlapping_area(HA_KEYSEG *keyseg, uchar* a, uchar* b,
/*
Calculates MBR_AREA(a+b) - MBR_AREA(a)
Note: when 'a' and 'b' objects are far from each other,
the area increase can be really big, so this function
can return 'inf' as a result.
*/
double maria_rtree_area_increase(HA_KEYSEG *keyseg, uchar *a, uchar *b,
......
......@@ -1329,11 +1329,12 @@ int _ma_search_next(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
info->page_changed, info->keyread_buff_used));
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
and the key tree has changed since we used it last time
Note that even if the key tree has changed since last read, we can use
the last read data from the leaf if we haven't used the buffer for
something else.
/*
Force full read if we are at last key or if we are not on a leaf
and the key tree has changed since we used it last time
Note that even if the key tree has changed since last read, we can use
the last read data from the leaf if we haven't used the buffer for
something else.
*/
if (((nextflag & SEARCH_BIGGER) && info->int_keypos >= info->int_maxpos) ||
......
......@@ -569,9 +569,10 @@ int _ma_thr_write_keys(MARIA_SORT_PARAM *sort_param)
if (!mergebuf)
{
length=param->sort_buffer_length;
while (length >= MIN_SORT_MEMORY && !mergebuf)
while (length >= MIN_SORT_MEMORY)
{
mergebuf=my_malloc(length, MYF(0));
if ((mergebuf= my_malloc(length, MYF(0))))
break;
length=length*3/4;
}
if (!mergebuf)
......@@ -909,6 +910,7 @@ merge_buffers(MARIA_SORT_PARAM *info, uint keys, IO_CACHE *from_file,
count=error=0;
maxcount=keys/((uint) (Tb-Fb) +1);
DBUG_ASSERT(maxcount > 0);
LINT_INIT(to_start_filepos);
if (to_file)
to_start_filepos=my_b_tell(to_file);
......
......@@ -62,8 +62,8 @@ my_bool _ma_write_static_record(MARIA_HA *info, const uchar *record)
{
info->rec_cache.seek_not_done=1; /* We have done a seek */
if (info->s->file_write(info, record, info->s->base.reclength,
info->state->data_file_length,
info->s->write_flag))
info->state->data_file_length,
info->s->write_flag))
goto err;
if (info->s->base.pack_reclength != info->s->base.reclength)
{
......
......@@ -39,9 +39,9 @@ static void put_blob_in_record(uchar *blob_pos,char **blob_buffer,
static void copy_key(MARIA_HA *info, uint inx, uchar *record, uchar *key);
static int verbose= 0, testflag= 0, first_key= 0, async_io= 0, pagecacheing= 0;
static int write_cacheing= 0, do_locking= 0, rec_pointer_size= 0, pack_fields= 1;
static int write_cacheing= 0, do_locking= 0, rec_pointer_size= 0;
static int silent= 0, opt_quick_mode= 0, transactional= 0, skip_update= 0;
static int die_in_middle_of_transaction= 0;
static int die_in_middle_of_transaction= 0, pack_fields= 1;
static int pack_seg= HA_SPACE_PACK, pack_type= HA_PACK_KEY, remove_count= -1;
static int create_flag= 0, srand_arg= 0, checkpoint= 0;
static uint use_blob= 0, update_count= 0;
......
......@@ -1674,12 +1674,14 @@ static int maria_sort_records(HA_CHECK *param,
_ma_check_print_error(param,"Not enough memory for key block");
goto err;
}
if (!(sort_param.record=(uchar*) my_malloc((uint) share->base.pack_reclength,
MYF(0))))
if (!(sort_param.record=
(uchar*) my_malloc((uint) share->base.default_rec_buff_size, MYF(0))))
{
_ma_check_print_error(param,"Not enough memory for record");
goto err;
}
fn_format(param->temp_filename,name,"", MARIA_NAME_DEXT,2+4+32);
new_file= my_create(fn_format(param->temp_filename,
param->temp_filename,"",
......
......@@ -3184,7 +3184,7 @@ static void fakebigcodes(HUFF_COUNTS *huff_counts, HUFF_COUNTS *end_count)
cur_sort_p= sort_counts;
while (cur_count_p < end_count_p)
*(cur_sort_p++)= cur_count_p++;
(void) qsort(sort_counts, 256, sizeof(my_off_t*), (qsort_cmp) fakecmp);
(void) my_qsort(sort_counts, 256, sizeof(my_off_t*), (qsort_cmp) fakecmp);
/*
Assign faked counts.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment