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));
}
......
This diff is collapsed.
......@@ -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