mirror of
https://github.com/MariaDB/server.git
synced 2025-01-29 02:05:57 +01:00
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
This commit is contained in:
parent
c63e18f43c
commit
3651e3285d
21 changed files with 499 additions and 124 deletions
|
@ -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 @@ public:
|
|||
*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.
|
||||
|
|
Loading…
Add table
Reference in a new issue