mirror of
https://github.com/MariaDB/server.git
synced 2026-05-16 20:07:13 +02:00
merging MyISAM changes into Maria (not done in 5.1->maria merge of
Jul 7th). "maria.test" and "ps_maria.test" still fail; "ma_test_all" starts failing (MyISAM has the same issue see BUG#30094). include/maria.h: merging MyISAM changes into Maria mysys/mf_keycache.c: mi_test_all showed "floating point exception", this was already fixed in the latest 5.1, importing fix. sql/item_xmlfunc.cc: compiler warning (already fixed in latest 5.1) storage/maria/ha_maria.cc: merging MyISAM changes into Maria. See #ifdef ASK_MONTY. storage/maria/ha_maria.h: merging MyISAM changes into Maria storage/maria/ma_cache.c: merging MyISAM changes into Maria storage/maria/ma_check.c: merging MyISAM changes into Maria storage/maria/ma_create.c: merging MyISAM changes into Maria storage/maria/ma_dynrec.c: merging MyISAM changes into Maria storage/maria/ma_extra.c: merging MyISAM changes into Maria storage/maria/ma_ft_boolean_search.c: merging MyISAM changes into Maria storage/maria/ma_ft_nlq_search.c: merging MyISAM changes into Maria storage/maria/ma_info.c: merging MyISAM changes into Maria storage/maria/ma_key.c: merging MyISAM changes into Maria storage/maria/ma_loghandler.c: compiler warning (part->length is size_t) storage/maria/ma_open.c: merging MyISAM changes into Maria storage/maria/ma_preload.c: merging MyISAM changes into Maria storage/maria/ma_range.c: merging MyISAM changes into Maria storage/maria/ma_rkey.c: merging MyISAM changes into Maria storage/maria/ma_rt_index.c: merging MyISAM changes into Maria storage/maria/ma_rt_key.c: merging MyISAM changes into Maria storage/maria/ma_rt_split.c: merging MyISAM changes into Maria storage/maria/ma_search.c: merging MyISAM changes into Maria storage/maria/ma_sort.c: merging MyISAM changes into Maria storage/maria/maria_def.h: merging MyISAM changes into Maria
This commit is contained in:
parent
662002fc8f
commit
a3d2ae4648
25 changed files with 508 additions and 266 deletions
|
|
@ -265,8 +265,8 @@ extern struct st_maria_info *maria_clone(struct st_maria_share *share, int mode)
|
|||
extern int maria_panic(enum ha_panic_function function);
|
||||
extern int maria_rfirst(struct st_maria_info *file, uchar *buf, int inx);
|
||||
extern int maria_rkey(struct st_maria_info *file, uchar *buf, int inx,
|
||||
const uchar *key,
|
||||
uint key_len, enum ha_rkey_function search_flag);
|
||||
const uchar *key, key_part_map keypart_map,
|
||||
enum ha_rkey_function search_flag);
|
||||
extern int maria_rlast(struct st_maria_info *file, uchar *buf, int inx);
|
||||
extern int maria_rnext(struct st_maria_info *file, uchar *buf, int inx);
|
||||
extern int maria_rnext_same(struct st_maria_info *info, uchar *buf);
|
||||
|
|
|
|||
|
|
@ -2522,10 +2522,8 @@ uchar *key_cache_read(KEY_CACHE *keycache,
|
|||
int error=0;
|
||||
uchar *start= buff;
|
||||
DBUG_ENTER("key_cache_read");
|
||||
DBUG_PRINT("enter", ("fd: %u pos: %lu page: %lu length: %u",
|
||||
(uint) file, (ulong) filepos,
|
||||
(ulong) (filepos / keycache->key_cache_block_size),
|
||||
length));
|
||||
DBUG_PRINT("enter", ("fd: %u pos: %lu length: %u",
|
||||
(uint) file, (ulong) filepos, length));
|
||||
|
||||
if (keycache->key_cache_inited)
|
||||
{
|
||||
|
|
@ -2979,10 +2977,10 @@ int key_cache_write(KEY_CACHE *keycache,
|
|||
int error=0;
|
||||
DBUG_ENTER("key_cache_write");
|
||||
DBUG_PRINT("enter",
|
||||
("fd: %u pos: %lu page: %lu length: %u block_length: %u",
|
||||
(uint) file, (ulong) filepos,
|
||||
(ulong) (filepos / keycache->key_cache_block_size),
|
||||
length, block_length));
|
||||
("fd: %u pos: %lu length: %u block_length: %u key_block_length:
|
||||
%u",
|
||||
(uint) file, (ulong) filepos, length, block_length,
|
||||
keycache ? keycache->key_cache_block_size : 0));
|
||||
|
||||
if (!dont_write)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -2767,7 +2767,7 @@ String *Item_xml_str_func::parse_xml(String *raw_xml, String *parsed_xml_buf)
|
|||
if ((rc= my_xml_parse(&p, raw_xml->ptr(), raw_xml->length())) != MY_XML_OK)
|
||||
{
|
||||
char buf[128];
|
||||
my_snprintf(buf, sizeof(buf)-1, "parse error at line %d pos %u: %s",
|
||||
my_snprintf(buf, sizeof(buf)-1, "parse error at line %d pos %lu: %s",
|
||||
my_xml_error_lineno(&p) + 1,
|
||||
my_xml_error_pos(&p) + 1,
|
||||
my_xml_error_string(&p));
|
||||
|
|
|
|||
|
|
@ -114,6 +114,14 @@ static void _ma_check_print_msg(HA_CHECK *param, const char *msg_type,
|
|||
}
|
||||
length= (uint) (strxmov(name, param->db_name, ".", param->table_name,
|
||||
NullS) - name);
|
||||
/*
|
||||
TODO: switch from protocol to push_warning here. The main reason we didn't
|
||||
it yet is parallel repair. Due to following trace:
|
||||
ma_check_print_msg/push_warning/sql_alloc/my_pthread_getspecific_ptr.
|
||||
|
||||
Also we likely need to lock mutex here (in both cases with protocol and
|
||||
push_warning).
|
||||
*/
|
||||
protocol->prepare_for_resend();
|
||||
protocol->store(name, length, system_charset_info);
|
||||
protocol->store(param->op_name, system_charset_info);
|
||||
|
|
@ -353,10 +361,11 @@ int table2maria(TABLE *table_arg, MARIA_KEYDEF **keydef_out,
|
|||
0 - Equal definitions.
|
||||
1 - Different definitions.
|
||||
|
||||
NOTES
|
||||
This is currently not used. In MyISAM the corresponding function
|
||||
(myisam_check_definition()) is used only by MERGE tables
|
||||
(in ha_myisammrg.cc).
|
||||
TODO
|
||||
- compare FULLTEXT keys;
|
||||
- compare SPATIAL keys;
|
||||
- compare FIELD_SKIP_ZERO which is converted to FIELD_NORMAL correctly
|
||||
(should be corretly detected in table2maria).
|
||||
*/
|
||||
int maria_check_definition(MARIA_KEYDEF *t1_keyinfo,
|
||||
MARIA_COLUMNDEF *t1_recinfo,
|
||||
|
|
@ -383,6 +392,28 @@ int maria_check_definition(MARIA_KEYDEF *t1_keyinfo,
|
|||
{
|
||||
HA_KEYSEG *t1_keysegs= t1_keyinfo[i].seg;
|
||||
HA_KEYSEG *t2_keysegs= t2_keyinfo[i].seg;
|
||||
if (t1_keyinfo[i].flag & HA_FULLTEXT && t2_keyinfo[i].flag & HA_FULLTEXT)
|
||||
continue;
|
||||
else if (t1_keyinfo[i].flag & HA_FULLTEXT ||
|
||||
t2_keyinfo[i].flag & HA_FULLTEXT)
|
||||
{
|
||||
DBUG_PRINT("error", ("Key %d has different definition", i));
|
||||
DBUG_PRINT("error", ("t1_fulltext= %d, t2_fulltext=%d",
|
||||
test(t1_keyinfo[i].flag & HA_FULLTEXT),
|
||||
test(t2_keyinfo[i].flag & HA_FULLTEXT)));
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
if (t1_keyinfo[i].flag & HA_SPATIAL && t2_keyinfo[i].flag & HA_SPATIAL)
|
||||
continue;
|
||||
else if (t1_keyinfo[i].flag & HA_SPATIAL ||
|
||||
t2_keyinfo[i].flag & HA_SPATIAL)
|
||||
{
|
||||
DBUG_PRINT("error", ("Key %d has different definition", i));
|
||||
DBUG_PRINT("error", ("t1_spatial= %d, t2_spatial=%d",
|
||||
test(t1_keyinfo[i].flag & HA_SPATIAL),
|
||||
test(t2_keyinfo[i].flag & HA_SPATIAL)));
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
if (t1_keyinfo[i].keysegs != t2_keyinfo[i].keysegs ||
|
||||
t1_keyinfo[i].key_alg != t2_keyinfo[i].key_alg)
|
||||
{
|
||||
|
|
@ -419,7 +450,14 @@ int maria_check_definition(MARIA_KEYDEF *t1_keyinfo,
|
|||
{
|
||||
MARIA_COLUMNDEF *t1_rec= &t1_recinfo[i];
|
||||
MARIA_COLUMNDEF *t2_rec= &t2_recinfo[i];
|
||||
if (t1_rec->type != t2_rec->type ||
|
||||
/*
|
||||
FIELD_SKIP_ZERO can be changed to FIELD_NORMAL in maria_create,
|
||||
see NOTE1 in ma_create.c
|
||||
*/
|
||||
if ((t1_rec->type != t2_rec->type &&
|
||||
!(t1_rec->type == (int) FIELD_SKIP_ZERO &&
|
||||
t1_rec->length == 1 &&
|
||||
t2_rec->type == (int) FIELD_NORMAL)) ||
|
||||
t1_rec->length != t2_rec->length ||
|
||||
t1_rec->null_bit != t2_rec->null_bit)
|
||||
{
|
||||
|
|
@ -602,7 +640,7 @@ int ha_maria::dump(THD * thd, int fd)
|
|||
my_seek(data_fd, 0L, MY_SEEK_SET, MYF(MY_WME));
|
||||
for (; bytes_to_read > 0;)
|
||||
{
|
||||
uint bytes= my_read(data_fd, buf, block_size, MYF(MY_WME));
|
||||
size_t bytes= my_read(data_fd, buf, block_size, MYF(MY_WME));
|
||||
if (bytes == MY_FILE_ERROR)
|
||||
{
|
||||
error= errno;
|
||||
|
|
@ -644,7 +682,8 @@ err:
|
|||
|
||||
bool ha_maria::check_if_locking_is_allowed(uint sql_command,
|
||||
ulong type, TABLE *table,
|
||||
uint count,
|
||||
uint count, uint current,
|
||||
uint *system_count,
|
||||
bool called_by_privileged_thread)
|
||||
{
|
||||
/*
|
||||
|
|
@ -653,10 +692,13 @@ bool ha_maria::check_if_locking_is_allowed(uint sql_command,
|
|||
we have to disallow write-locking of these tables with any other tables.
|
||||
*/
|
||||
if (table->s->system_table &&
|
||||
table->reginfo.lock_type >= TL_WRITE_ALLOW_WRITE && count != 1)
|
||||
table->reginfo.lock_type >= TL_WRITE_ALLOW_WRITE)
|
||||
(*system_count)++;
|
||||
|
||||
/* 'current' is an index, that's why '<=' below. */
|
||||
if (*system_count > 0 && *system_count <= current)
|
||||
{
|
||||
my_error(ER_WRONG_LOCK_OF_SYSTEM_TABLE, MYF(0), table->s->db.str,
|
||||
table->s->table_name.str);
|
||||
my_error(ER_WRONG_LOCK_OF_SYSTEM_TABLE, MYF(0));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
|
@ -676,6 +718,9 @@ bool ha_maria::check_if_locking_is_allowed(uint sql_command,
|
|||
|
||||
int ha_maria::open(const char *name, int mode, uint test_if_locked)
|
||||
{
|
||||
MARIA_KEYDEF *keyinfo;
|
||||
MARIA_COLUMNDEF *recinfo= 0;
|
||||
uint recs;
|
||||
uint i;
|
||||
|
||||
#ifdef NOT_USED
|
||||
|
|
@ -701,6 +746,36 @@ int ha_maria::open(const char *name, int mode, uint test_if_locked)
|
|||
if (!(file= maria_open(name, mode, test_if_locked | HA_OPEN_FROM_SQL_LAYER)))
|
||||
return (my_errno ? my_errno : -1);
|
||||
|
||||
#ifdef ASK_MONTY
|
||||
/*
|
||||
This is a protection for the case of a frm and MAI containing incompatible
|
||||
table definitions (as in BUG#25908). This was merged from MyISAM.
|
||||
But it breaks maria.test and ps_maria.test ("incorrect key file") if the
|
||||
table is BLOCK_RECORD (does it have to do with column reordering done in
|
||||
ma_create.c ?).
|
||||
*/
|
||||
if (!table->s->tmp_table) /* No need to perform a check for tmp table */
|
||||
{
|
||||
if ((my_errno= table2maria(table, &keyinfo, &recinfo, &recs)))
|
||||
{
|
||||
/* purecov: begin inspected */
|
||||
DBUG_PRINT("error", ("Failed to convert TABLE object to Maria "
|
||||
"key and column definition"));
|
||||
goto err;
|
||||
/* purecov: end */
|
||||
}
|
||||
if (maria_check_definition(keyinfo, recinfo, table->s->keys, recs,
|
||||
file->s->keyinfo, file->s->columndef,
|
||||
file->s->base.keys, file->s->base.fields, true))
|
||||
{
|
||||
/* purecov: begin inspected */
|
||||
my_errno= HA_ERR_CRASHED;
|
||||
goto err;
|
||||
/* purecov: end */
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (test_if_locked & (HA_OPEN_IGNORE_IF_LOCKED | HA_OPEN_TMP_TABLE))
|
||||
VOID(maria_extra(file, HA_EXTRA_NO_WAIT_LOCK, 0));
|
||||
|
||||
|
|
@ -731,7 +806,18 @@ int ha_maria::open(const char *name, int mode, uint test_if_locked)
|
|||
(struct st_mysql_ftparser *)plugin_decl(parser)->info;
|
||||
table->key_info[i].block_size= file->s->keyinfo[i].block_length;
|
||||
}
|
||||
return (0);
|
||||
my_errno= 0;
|
||||
goto end;
|
||||
err:
|
||||
this->close();
|
||||
end:
|
||||
/*
|
||||
Both recinfo and keydef are allocated by my_multi_malloc(), thus only
|
||||
recinfo must be freed.
|
||||
*/
|
||||
if (recinfo)
|
||||
my_free((uchar*) recinfo, MYF(0));
|
||||
return my_errno;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -745,7 +831,7 @@ int ha_maria::close(void)
|
|||
|
||||
int ha_maria::write_row(uchar * buf)
|
||||
{
|
||||
statistic_increment(table->in_use->status_var.ha_write_count, &LOCK_status);
|
||||
ha_statistic_increment(&SSV::ha_write_count);
|
||||
|
||||
/* If we have a timestamp column, update it to the current time */
|
||||
if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT)
|
||||
|
|
@ -1064,8 +1150,8 @@ int ha_maria::optimize(THD * thd, HA_CHECK_OPT *check_opt)
|
|||
param.sort_buffer_length= check_opt->sort_buffer_size;
|
||||
if ((error= repair(thd, param, 1)) && param.retry_repair)
|
||||
{
|
||||
sql_print_warning("Warning: Optimize table got errno %d, retrying",
|
||||
my_errno);
|
||||
sql_print_warning("Warning: Optimize table got errno %d on %s.%s, retrying",
|
||||
my_errno, param.db_name, param.table_name);
|
||||
param.testflag &= ~T_REP_BY_SORT;
|
||||
error= repair(thd, param, 1);
|
||||
}
|
||||
|
|
@ -1084,6 +1170,22 @@ int ha_maria::repair(THD *thd, HA_CHECK ¶m, bool do_optimize)
|
|||
ha_rows rows= file->state->records;
|
||||
DBUG_ENTER("ha_maria::repair");
|
||||
|
||||
/*
|
||||
Normally this method is entered with a properly opened table. If the
|
||||
repair fails, it can be repeated with more elaborate options. Under
|
||||
special circumstances it can happen that a repair fails so that it
|
||||
closed the data file and cannot re-open it. In this case file->dfile
|
||||
is set to -1. We must not try another repair without an open data
|
||||
file. (Bug #25289)
|
||||
*/
|
||||
if (file->dfile.file == -1)
|
||||
{
|
||||
sql_print_information("Retrying repair of: '%s' failed. "
|
||||
"Please try REPAIR EXTENDED or maria_chk",
|
||||
table->s->path.str);
|
||||
DBUG_RETURN(HA_ADMIN_FAILED);
|
||||
}
|
||||
|
||||
param.db_name= table->s->db.str;
|
||||
param.table_name= table->alias;
|
||||
param.tmpfile_createflag= O_RDWR | O_TRUNC;
|
||||
|
|
@ -1222,7 +1324,7 @@ int ha_maria::assign_to_keycache(THD * thd, HA_CHECK_OPT *check_opt)
|
|||
PAGECACHE *new_pagecache= check_opt->pagecache;
|
||||
const char *errmsg= 0;
|
||||
int error= HA_ADMIN_OK;
|
||||
ulonglong map= ~(ulonglong) 0;
|
||||
ulonglong map;
|
||||
TABLE_LIST *table_list= table->pos_in_table_list;
|
||||
DBUG_ENTER("ha_maria::assign_to_keycache");
|
||||
|
||||
|
|
@ -1268,9 +1370,10 @@ int ha_maria::preload_keys(THD * thd, HA_CHECK_OPT *check_opt)
|
|||
{
|
||||
int error;
|
||||
const char *errmsg;
|
||||
ulonglong map= ~(ulonglong) 0;
|
||||
ulonglong map;
|
||||
TABLE_LIST *table_list= table->pos_in_table_list;
|
||||
my_bool ignore_leaves= table_list->ignore_leaves;
|
||||
char buf[ERRMSGSIZE+20];
|
||||
|
||||
DBUG_ENTER("ha_maria::preload_keys");
|
||||
|
||||
|
|
@ -1298,7 +1401,6 @@ int ha_maria::preload_keys(THD * thd, HA_CHECK_OPT *check_opt)
|
|||
errmsg= "Failed to allocate buffer";
|
||||
break;
|
||||
default:
|
||||
char buf[ERRMSGSIZE + 20];
|
||||
my_snprintf(buf, ERRMSGSIZE,
|
||||
"Failed to read from index file (errno: %d)", my_errno);
|
||||
errmsg= buf;
|
||||
|
|
@ -1427,13 +1529,13 @@ int ha_maria::enable_indexes(uint mode)
|
|||
T_CREATE_MISSING_KEYS);
|
||||
param.myf_rw &= ~MY_WAIT_IF_FULL;
|
||||
param.sort_buffer_length= thd->variables.maria_sort_buff_size;
|
||||
param.stats_method= (enum_handler_stats_method) thd->variables.
|
||||
maria_stats_method;
|
||||
param.stats_method=
|
||||
(enum_handler_stats_method) thd->variables.maria_stats_method;
|
||||
param.tmpdir= &mysql_tmpdir_list;
|
||||
if ((error= (repair(thd, param, 0) != HA_ADMIN_OK)) && param.retry_repair)
|
||||
{
|
||||
sql_print_warning("Warning: Enabling keys got errno %d, retrying",
|
||||
my_errno);
|
||||
sql_print_warning("Warning: Enabling keys got errno %d on %s.%s, retrying",
|
||||
my_errno, param.db_name, param.table_name);
|
||||
/* Repairing by sort failed. Now try standard repair method. */
|
||||
param.testflag &= ~(T_REP_BY_SORT | T_QUICK);
|
||||
error= (repair(thd, param, 0) != HA_ADMIN_OK);
|
||||
|
|
@ -1442,8 +1544,10 @@ int ha_maria::enable_indexes(uint mode)
|
|||
might have been set by the first repair. They can still be seen
|
||||
with SHOW WARNINGS then.
|
||||
*/
|
||||
#ifndef EMBEDDED_LIBRARY
|
||||
if (!error)
|
||||
thd->clear_error();
|
||||
#endif /* EMBEDDED_LIBRARY */
|
||||
}
|
||||
info(HA_STATUS_CONST);
|
||||
thd->proc_info= save_proc_info;
|
||||
|
|
@ -1607,7 +1711,7 @@ bool ha_maria::is_crashed() const
|
|||
|
||||
int ha_maria::update_row(const uchar * old_data, uchar * new_data)
|
||||
{
|
||||
statistic_increment(table->in_use->status_var.ha_update_count, &LOCK_status);
|
||||
ha_statistic_increment(&SSV::ha_update_count);
|
||||
if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE)
|
||||
table->timestamp_field->set_time();
|
||||
return maria_update(file, old_data, new_data);
|
||||
|
|
@ -1616,41 +1720,41 @@ int ha_maria::update_row(const uchar * old_data, uchar * new_data)
|
|||
|
||||
int ha_maria::delete_row(const uchar * buf)
|
||||
{
|
||||
statistic_increment(table->in_use->status_var.ha_delete_count, &LOCK_status);
|
||||
ha_statistic_increment(&SSV::ha_delete_count);
|
||||
return maria_delete(file, buf);
|
||||
}
|
||||
|
||||
|
||||
int ha_maria::index_read(uchar * buf, const uchar * key,
|
||||
uint key_len, enum ha_rkey_function find_flag)
|
||||
key_part_map keypart_map,
|
||||
enum ha_rkey_function find_flag)
|
||||
{
|
||||
DBUG_ASSERT(inited == INDEX);
|
||||
statistic_increment(table->in_use->status_var.ha_read_key_count,
|
||||
&LOCK_status);
|
||||
int error= maria_rkey(file, buf, active_index, key, key_len, find_flag);
|
||||
ha_statistic_increment(&SSV::ha_read_key_count);
|
||||
int error= maria_rkey(file, buf, active_index, key, keypart_map, find_flag);
|
||||
table->status= error ? STATUS_NOT_FOUND : 0;
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
int ha_maria::index_read_idx(uchar * buf, uint index, const uchar * key,
|
||||
uint key_len, enum ha_rkey_function find_flag)
|
||||
key_part_map keypart_map,
|
||||
enum ha_rkey_function find_flag)
|
||||
{
|
||||
statistic_increment(table->in_use->status_var.ha_read_key_count,
|
||||
&LOCK_status);
|
||||
int error= maria_rkey(file, buf, index, key, key_len, find_flag);
|
||||
ha_statistic_increment(&SSV::ha_read_key_count);
|
||||
int error= maria_rkey(file, buf, index, key, keypart_map, find_flag);
|
||||
table->status= error ? STATUS_NOT_FOUND : 0;
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
int ha_maria::index_read_last(uchar * buf, const uchar * key, uint key_len)
|
||||
int ha_maria::index_read_last(uchar * buf, const uchar * key,
|
||||
key_part_map keypart_map)
|
||||
{
|
||||
DBUG_ENTER("ha_maria::index_read_last");
|
||||
DBUG_ASSERT(inited == INDEX);
|
||||
statistic_increment(table->in_use->status_var.ha_read_key_count,
|
||||
&LOCK_status);
|
||||
int error= maria_rkey(file, buf, active_index, key, key_len,
|
||||
ha_statistic_increment(&SSV::ha_read_key_count);
|
||||
int error= maria_rkey(file, buf, active_index, key, keypart_map,
|
||||
HA_READ_PREFIX_LAST);
|
||||
table->status= error ? STATUS_NOT_FOUND : 0;
|
||||
DBUG_RETURN(error);
|
||||
|
|
@ -1660,8 +1764,7 @@ int ha_maria::index_read_last(uchar * buf, const uchar * key, uint key_len)
|
|||
int ha_maria::index_next(uchar * buf)
|
||||
{
|
||||
DBUG_ASSERT(inited == INDEX);
|
||||
statistic_increment(table->in_use->status_var.ha_read_next_count,
|
||||
&LOCK_status);
|
||||
ha_statistic_increment(&SSV::ha_read_next_count);
|
||||
int error= maria_rnext(file, buf, active_index);
|
||||
table->status= error ? STATUS_NOT_FOUND : 0;
|
||||
return error;
|
||||
|
|
@ -1671,8 +1774,7 @@ int ha_maria::index_next(uchar * buf)
|
|||
int ha_maria::index_prev(uchar * buf)
|
||||
{
|
||||
DBUG_ASSERT(inited == INDEX);
|
||||
statistic_increment(table->in_use->status_var.ha_read_prev_count,
|
||||
&LOCK_status);
|
||||
ha_statistic_increment(&SSV::ha_read_prev_count);
|
||||
int error= maria_rprev(file, buf, active_index);
|
||||
table->status= error ? STATUS_NOT_FOUND : 0;
|
||||
return error;
|
||||
|
|
@ -1682,8 +1784,7 @@ int ha_maria::index_prev(uchar * buf)
|
|||
int ha_maria::index_first(uchar * buf)
|
||||
{
|
||||
DBUG_ASSERT(inited == INDEX);
|
||||
statistic_increment(table->in_use->status_var.ha_read_first_count,
|
||||
&LOCK_status);
|
||||
ha_statistic_increment(&SSV::ha_read_first_count);
|
||||
int error= maria_rfirst(file, buf, active_index);
|
||||
table->status= error ? STATUS_NOT_FOUND : 0;
|
||||
return error;
|
||||
|
|
@ -1693,8 +1794,7 @@ int ha_maria::index_first(uchar * buf)
|
|||
int ha_maria::index_last(uchar * buf)
|
||||
{
|
||||
DBUG_ASSERT(inited == INDEX);
|
||||
statistic_increment(table->in_use->status_var.ha_read_last_count,
|
||||
&LOCK_status);
|
||||
ha_statistic_increment(&SSV::ha_read_last_count);
|
||||
int error= maria_rlast(file, buf, active_index);
|
||||
table->status= error ? STATUS_NOT_FOUND : 0;
|
||||
return error;
|
||||
|
|
@ -1706,8 +1806,7 @@ int ha_maria::index_next_same(uchar * buf,
|
|||
uint length __attribute__ ((unused)))
|
||||
{
|
||||
DBUG_ASSERT(inited == INDEX);
|
||||
statistic_increment(table->in_use->status_var.ha_read_next_count,
|
||||
&LOCK_status);
|
||||
ha_statistic_increment(&SSV::ha_read_next_count);
|
||||
int error= maria_rnext_same(file, buf);
|
||||
table->status= error ? STATUS_NOT_FOUND : 0;
|
||||
return error;
|
||||
|
|
@ -1732,8 +1831,7 @@ int ha_maria::rnd_end()
|
|||
|
||||
int ha_maria::rnd_next(uchar *buf)
|
||||
{
|
||||
statistic_increment(table->in_use->status_var.ha_read_rnd_next_count,
|
||||
&LOCK_status);
|
||||
ha_statistic_increment(&SSV::ha_read_rnd_next_count);
|
||||
int error= maria_scan(file, buf);
|
||||
table->status= error ? STATUS_NOT_FOUND : 0;
|
||||
return error;
|
||||
|
|
@ -1748,8 +1846,7 @@ int ha_maria::restart_rnd_next(uchar *buf, uchar *pos)
|
|||
|
||||
int ha_maria::rnd_pos(uchar * buf, uchar *pos)
|
||||
{
|
||||
statistic_increment(table->in_use->status_var.ha_read_rnd_count,
|
||||
&LOCK_status);
|
||||
ha_statistic_increment(&SSV::ha_read_rnd_count);
|
||||
int error= maria_rrnd(file, buf, my_get_ptr(pos, ref_length));
|
||||
table->status= error ? STATUS_NOT_FOUND : 0;
|
||||
return error;
|
||||
|
|
@ -2111,7 +2208,8 @@ void ha_maria::get_auto_increment(ulonglong offset, ulonglong increment,
|
|||
table->key_info + table->s->next_number_index,
|
||||
table->s->next_number_key_offset);
|
||||
error= maria_rkey(file, table->record[1], (int) table->s->next_number_index,
|
||||
key, table->s->next_number_key_offset, HA_READ_PREFIX_LAST);
|
||||
key, make_prev_keypart_map(table->s->next_number_keypart),
|
||||
HA_READ_PREFIX_LAST);
|
||||
if (error)
|
||||
nr= 1;
|
||||
else
|
||||
|
|
|
|||
|
|
@ -68,18 +68,21 @@ public:
|
|||
|
||||
virtual bool check_if_locking_is_allowed(uint sql_command,
|
||||
ulong type, TABLE * table,
|
||||
uint count,
|
||||
uint count, uint current,
|
||||
uint *system_count,
|
||||
bool called_by_logger_thread);
|
||||
int open(const char *name, int mode, uint test_if_locked);
|
||||
int close(void);
|
||||
int write_row(uchar * buf);
|
||||
int update_row(const uchar * old_data, uchar * new_data);
|
||||
int delete_row(const uchar * buf);
|
||||
int index_read(uchar * buf, const uchar * key,
|
||||
uint key_len, enum ha_rkey_function find_flag);
|
||||
int index_read(uchar * buf, const uchar * key, key_part_map keypart_map,
|
||||
enum ha_rkey_function find_flag);
|
||||
int index_read_idx(uchar * buf, uint idx, const uchar * key,
|
||||
uint key_len, enum ha_rkey_function find_flag);
|
||||
int index_read_last(uchar * buf, const uchar * key, uint key_len);
|
||||
key_part_map keypart_map,
|
||||
enum ha_rkey_function find_flag);
|
||||
int index_read_last(uchar * buf, const uchar * key,
|
||||
key_part_map keypart_map);
|
||||
int index_next(uchar * buf);
|
||||
int index_prev(uchar * buf);
|
||||
int index_first(uchar * buf);
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ int _ma_read_cache(IO_CACHE *info, uchar *buff, my_off_t pos, uint length,
|
|||
{
|
||||
uint read_length,in_buff_length;
|
||||
my_off_t offset;
|
||||
char *in_buff_pos;
|
||||
uchar *in_buff_pos;
|
||||
DBUG_ENTER("_ma_read_cache");
|
||||
|
||||
if (pos < info->pos_in_file)
|
||||
|
|
@ -61,7 +61,7 @@ int _ma_read_cache(IO_CACHE *info, uchar *buff, my_off_t pos, uint length,
|
|||
(my_off_t) (info->read_end - info->request_pos))
|
||||
{
|
||||
in_buff_pos=info->request_pos+(uint) offset;
|
||||
in_buff_length= min(length,(uint) ((char*)(info->read_end)-in_buff_pos));
|
||||
in_buff_length= min(length,(size_t) (info->read_end-in_buff_pos));
|
||||
memcpy(buff,info->request_pos+(uint) offset,(size_t) in_buff_length);
|
||||
if (!(length-=in_buff_length))
|
||||
DBUG_RETURN(0);
|
||||
|
|
|
|||
|
|
@ -344,7 +344,7 @@ int maria_chk_size(HA_CHECK *param, register MARIA_HA *info)
|
|||
flush_pagecache_blocks(info->s->pagecache,
|
||||
&info->s->kfile, FLUSH_FORCE_WRITE);
|
||||
|
||||
size= my_seek(info->s->kfile.file, 0L, MY_SEEK_END, MYF(0));
|
||||
size= my_seek(info->s->kfile.file, 0L, MY_SEEK_END, MYF(MY_THREADSAFE));
|
||||
if ((skr=(my_off_t) info->state->key_file_length) != size)
|
||||
{
|
||||
/* Don't give error if file generated by mariapack */
|
||||
|
|
@ -539,7 +539,7 @@ int maria_chk_key(HA_CHECK *param, register MARIA_HA *info)
|
|||
maria_extra(info,HA_EXTRA_KEYREAD,0);
|
||||
bzero(info->lastkey,keyinfo->seg->length);
|
||||
if (!maria_rkey(info, info->rec_buff, key, (const uchar*) info->lastkey,
|
||||
keyinfo->seg->length, HA_READ_KEY_EXACT))
|
||||
(key_part_map)1, HA_READ_KEY_EXACT))
|
||||
{
|
||||
/* Don't count this as a real warning, as maria_chk can't correct it */
|
||||
uint save=param->warning_printed;
|
||||
|
|
@ -603,7 +603,8 @@ static int chk_index_down(HA_CHECK *param, MARIA_HA *info,
|
|||
{
|
||||
/* purecov: begin tested */
|
||||
/* Give it a chance to fit in the real file size. */
|
||||
my_off_t max_length= my_seek(info->s->kfile.file, 0L, MY_SEEK_END, MYF(0));
|
||||
my_off_t max_length= my_seek(info->s->kfile.file, 0L, MY_SEEK_END,
|
||||
MYF(MY_THREADSAFE));
|
||||
_ma_check_print_error(param, "Invalid key block position: %s "
|
||||
"key block size: %u file_length: %s",
|
||||
llstr(page, llbuff), keyinfo->block_length,
|
||||
|
|
@ -4772,10 +4773,11 @@ int maria_test_if_almost_full(MARIA_HA *info)
|
|||
{
|
||||
if (info->s->options & HA_OPTION_COMPRESS_RECORD)
|
||||
return 0;
|
||||
return (my_seek(info->s->kfile.file, 0L, MY_SEEK_END, MYF(0))/10*9 >
|
||||
(my_off_t) (info->s->base.max_key_file_length) ||
|
||||
my_seek(info->dfile.file, 0L, MY_SEEK_END, MYF(0)) / 10 * 9 >
|
||||
(my_off_t) info->s->base.max_data_file_length);
|
||||
return my_seek(info->s->kfile.file, 0L, MY_SEEK_END,
|
||||
MYF(MY_THREADSAFE))/10*9 >
|
||||
(my_off_t) info->s->base.max_key_file_length ||
|
||||
my_seek(info->dfile.file, 0L, MY_SEEK_END, MYF(0)) / 10 * 9 >
|
||||
(my_off_t) info->s->base.max_data_file_length;
|
||||
}
|
||||
|
||||
/* Recreate table with bigger more alloced record-data */
|
||||
|
|
|
|||
|
|
@ -239,6 +239,10 @@ int maria_create(const char *name, enum data_file_type datafile_type,
|
|||
column--;
|
||||
if (column->type == (int) FIELD_SKIP_ZERO && column->length == 1)
|
||||
{
|
||||
/*
|
||||
NOTE1: here we change a field type FIELD_SKIP_ZERO ->
|
||||
FIELD_NORMAL
|
||||
*/
|
||||
column->type=(int) FIELD_NORMAL;
|
||||
column->empty_pos= 0;
|
||||
column->empty_bit= 0;
|
||||
|
|
@ -701,6 +705,10 @@ int maria_create(const char *name, enum data_file_type datafile_type,
|
|||
|
||||
pthread_mutex_lock(&THR_LOCK_maria);
|
||||
|
||||
/*
|
||||
NOTE: For test_if_reopen() we need a real path name. Hence we need
|
||||
MY_RETURN_REAL_PATH for every fn_format(filename, ...).
|
||||
*/
|
||||
if (ci->index_file_name)
|
||||
{
|
||||
char *iext= strrchr(ci->index_file_name, '.');
|
||||
|
|
@ -712,13 +720,14 @@ int maria_create(const char *name, enum data_file_type datafile_type,
|
|||
if ((path= strrchr(ci->index_file_name, FN_LIBCHAR)))
|
||||
*path= '\0';
|
||||
fn_format(filename, name, ci->index_file_name, MARIA_NAME_IEXT,
|
||||
MY_REPLACE_DIR | MY_UNPACK_FILENAME | MY_APPEND_EXT);
|
||||
MY_REPLACE_DIR | MY_UNPACK_FILENAME |
|
||||
MY_RETURN_REAL_PATH | MY_APPEND_EXT);
|
||||
}
|
||||
else
|
||||
{
|
||||
fn_format(filename, ci->index_file_name, "", MARIA_NAME_IEXT,
|
||||
MY_UNPACK_FILENAME | (have_iext ? MY_REPLACE_EXT :
|
||||
MY_APPEND_EXT));
|
||||
MY_UNPACK_FILENAME | MY_RETURN_REAL_PATH |
|
||||
(have_iext ? MY_REPLACE_EXT : MY_APPEND_EXT));
|
||||
}
|
||||
fn_format(linkname, name, "", MARIA_NAME_IEXT,
|
||||
MY_UNPACK_FILENAME|MY_APPEND_EXT);
|
||||
|
|
@ -734,10 +743,11 @@ int maria_create(const char *name, enum data_file_type datafile_type,
|
|||
}
|
||||
else
|
||||
{
|
||||
char *iext= strrchr(name, '.');
|
||||
int have_iext= iext && !strcmp(iext, MARIA_NAME_IEXT);
|
||||
fn_format(filename, name, "", MARIA_NAME_IEXT,
|
||||
(MY_UNPACK_FILENAME |
|
||||
(flags & HA_DONT_TOUCH_DATA) ? MY_RETURN_REAL_PATH : 0) |
|
||||
MY_APPEND_EXT);
|
||||
MY_UNPACK_FILENAME | MY_RETURN_REAL_PATH |
|
||||
(have_iext ? MY_REPLACE_EXT : MY_APPEND_EXT));
|
||||
linkname_ptr= NullS;
|
||||
/*
|
||||
Replace the current file.
|
||||
|
|
@ -752,6 +762,10 @@ int maria_create(const char *name, enum data_file_type datafile_type,
|
|||
A TRUNCATE command checks for the table in the cache only and could
|
||||
be fooled to believe, the table is not open.
|
||||
Pull the emergency brake in this situation. (Bug #8306)
|
||||
|
||||
|
||||
NOTE: The filename is compared against unique_file_name of every
|
||||
open table. Hence we need a real path here.
|
||||
*/
|
||||
if (_ma_test_if_reopen(filename))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -887,7 +887,7 @@ uint _ma_rec_pack(MARIA_HA *info, register uchar *to,
|
|||
register const uchar *from)
|
||||
{
|
||||
uint length,new_length,flag,bit,i;
|
||||
char *pos,*end,*startpos,*packpos;
|
||||
uchar *pos,*end,*startpos,*packpos;
|
||||
enum en_fieldtype type;
|
||||
reg3 MARIA_COLUMNDEF *column;
|
||||
MARIA_BLOB *blob;
|
||||
|
|
@ -941,7 +941,7 @@ uint _ma_rec_pack(MARIA_HA *info, register uchar *to,
|
|||
pos= (uchar*) from; end= (uchar*) from + length;
|
||||
if (type == FIELD_SKIP_ENDSPACE)
|
||||
{ /* Pack trailing spaces */
|
||||
while (end > (char*) from && *(end-1) == ' ')
|
||||
while (end > from && *(end-1) == ' ')
|
||||
end--;
|
||||
}
|
||||
else
|
||||
|
|
@ -1007,8 +1007,8 @@ uint _ma_rec_pack(MARIA_HA *info, register uchar *to,
|
|||
*packpos= (char) (uchar) flag;
|
||||
if (info->s->calc_checksum)
|
||||
*to++= (uchar) info->cur_row.checksum;
|
||||
DBUG_PRINT("exit",("packed length: %d",(int) ((char*)to-startpos)));
|
||||
DBUG_RETURN((uint) ((char*)to-startpos));
|
||||
DBUG_PRINT("exit",("packed length: %d",(int) (to-startpos)));
|
||||
DBUG_RETURN((uint) (to-startpos));
|
||||
} /* _ma_rec_pack */
|
||||
|
||||
|
||||
|
|
@ -1018,12 +1018,12 @@ uint _ma_rec_pack(MARIA_HA *info, register uchar *to,
|
|||
Returns 0 if record is ok.
|
||||
*/
|
||||
|
||||
my_bool _ma_rec_check(MARIA_HA *info,const char *record, uchar *rec_buff,
|
||||
my_bool _ma_rec_check(MARIA_HA *info,const uchar *record, uchar *rec_buff,
|
||||
ulong packed_length, my_bool with_checksum,
|
||||
ha_checksum checksum)
|
||||
{
|
||||
uint length,new_length,flag,bit,i;
|
||||
char *pos,*end,*packpos,*to;
|
||||
uchar *pos,*end,*packpos,*to;
|
||||
enum en_fieldtype type;
|
||||
reg3 MARIA_COLUMNDEF *column;
|
||||
DBUG_ENTER("_ma_rec_check");
|
||||
|
|
@ -1123,7 +1123,7 @@ my_bool _ma_rec_check(MARIA_HA *info,const char *record, uchar *rec_buff,
|
|||
else
|
||||
to+= length;
|
||||
}
|
||||
if (packed_length != (uint) (to - (char*) rec_buff) +
|
||||
if (packed_length != (uint) (to - rec_buff) +
|
||||
test(info->s->calc_checksum) || (bit != 1 && (flag & ~(bit - 1))))
|
||||
goto err;
|
||||
if (with_checksum && ((uchar) checksum != (uchar) *to))
|
||||
|
|
|
|||
|
|
@ -379,11 +379,13 @@ int maria_extra(MARIA_HA *info, enum ha_extra_function function,
|
|||
break; /* Not supported */
|
||||
pthread_mutex_lock(&share->intern_lock);
|
||||
/*
|
||||
Memory map the data file if it is not already mapped and if there
|
||||
are no other threads using this table. intern_lock prevents other
|
||||
threads from starting to use the table while we are mapping it.
|
||||
Memory map the data file if it is not already mapped. It is safe
|
||||
to memory map a file while other threads are using file I/O on it.
|
||||
Assigning a new address to a function pointer is an atomic
|
||||
operation. intern_lock prevents that two or more mappings are done
|
||||
at the same time.
|
||||
*/
|
||||
if (!share->file_map && (share->tot_locks == 1))
|
||||
if (!share->file_map)
|
||||
{
|
||||
if (_ma_dynmap_file(info, share->state.state.data_file_length))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -286,8 +286,8 @@ static int ftb_parse_query_internal(MYSQL_FTPARSER_PARAM *param,
|
|||
}
|
||||
|
||||
|
||||
static void _ftb_parse_query(FTB *ftb, uchar *query, uint len,
|
||||
struct st_mysql_ftparser *parser)
|
||||
static int _ftb_parse_query(FTB *ftb, uchar *query, uint len,
|
||||
struct st_mysql_ftparser *parser)
|
||||
{
|
||||
MYSQL_FTPARSER_PARAM *param;
|
||||
MY_FTB_PARAM ftb_param;
|
||||
|
|
@ -295,9 +295,9 @@ static void _ftb_parse_query(FTB *ftb, uchar *query, uint len,
|
|||
DBUG_ASSERT(parser);
|
||||
|
||||
if (ftb->state != UNINITIALIZED)
|
||||
DBUG_VOID_RETURN;
|
||||
DBUG_RETURN(0);
|
||||
if (! (param= maria_ftparser_call_initializer(ftb->info, ftb->keynr, 0)))
|
||||
DBUG_VOID_RETURN;
|
||||
DBUG_RETURN(1);
|
||||
|
||||
ftb_param.ftb= ftb;
|
||||
ftb_param.depth= 0;
|
||||
|
|
@ -312,8 +312,7 @@ static void _ftb_parse_query(FTB *ftb, uchar *query, uint len,
|
|||
param->length= len;
|
||||
param->flags= 0;
|
||||
param->mode= MYSQL_FTPARSER_FULL_BOOLEAN_INFO;
|
||||
parser->parse(param);
|
||||
DBUG_VOID_RETURN;
|
||||
DBUG_RETURN(parser->parse(param));
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -537,9 +536,10 @@ FT_INFO * maria_ft_init_boolean_search(MARIA_HA *info, uint keynr, uchar *query,
|
|||
ftbe->phrase= NULL;
|
||||
ftbe->document= 0;
|
||||
ftb->root=ftbe;
|
||||
_ftb_parse_query(ftb, query, query_len, keynr == NO_SUCH_KEY ?
|
||||
&ft_default_parser :
|
||||
info->s->keyinfo[keynr].parser);
|
||||
if (unlikely(_ftb_parse_query(ftb, query, query_len,
|
||||
keynr == NO_SUCH_KEY ? &ft_default_parser :
|
||||
info->s->keyinfo[keynr].parser)))
|
||||
goto err;
|
||||
/*
|
||||
Hack: instead of init_queue, we'll use reinit queue to be able
|
||||
to alloc queue with alloc_root()
|
||||
|
|
@ -621,7 +621,7 @@ static int ftb_check_phrase_internal(MYSQL_FTPARSER_PARAM *param,
|
|||
{
|
||||
param->mysql_add_word(param, word.pos, word.len, 0);
|
||||
if (phrase_param->match)
|
||||
return 1;
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -639,6 +639,7 @@ static int ftb_check_phrase_internal(MYSQL_FTPARSER_PARAM *param,
|
|||
|
||||
RETURN VALUE
|
||||
1 is returned if phrase found, 0 else.
|
||||
-1 is returned if error occurs.
|
||||
*/
|
||||
|
||||
static int _ftb_check_phrase(FTB *ftb, const uchar *document, uint len,
|
||||
|
|
@ -666,12 +667,13 @@ static int _ftb_check_phrase(FTB *ftb, const uchar *document, uint len,
|
|||
param->length= len;
|
||||
param->flags= 0;
|
||||
param->mode= MYSQL_FTPARSER_WITH_STOPWORDS;
|
||||
parser->parse(param);
|
||||
if (unlikely(parser->parse(param)))
|
||||
return -1;
|
||||
DBUG_RETURN(ftb_param.match ? 1 : 0);
|
||||
}
|
||||
|
||||
|
||||
static void _ftb_climb_the_tree(FTB *ftb, FTB_WORD *ftbw, FT_SEG_ITERATOR *ftsi_orig)
|
||||
static int _ftb_climb_the_tree(FTB *ftb, FTB_WORD *ftbw, FT_SEG_ITERATOR *ftsi_orig)
|
||||
{
|
||||
FT_SEG_ITERATOR ftsi;
|
||||
FTB_EXPR *ftbe;
|
||||
|
|
@ -703,17 +705,19 @@ static void _ftb_climb_the_tree(FTB *ftb, FTB_WORD *ftbw, FT_SEG_ITERATOR *ftsi_
|
|||
weight=ftbe->cur_weight*ftbe->weight;
|
||||
if (mode && ftbe->phrase)
|
||||
{
|
||||
int not_found=1;
|
||||
int found= 0;
|
||||
|
||||
memcpy(&ftsi, ftsi_orig, sizeof(ftsi));
|
||||
while (_ma_ft_segiterator(&ftsi) && not_found)
|
||||
while (_ma_ft_segiterator(&ftsi) && !found)
|
||||
{
|
||||
if (!ftsi.pos)
|
||||
continue;
|
||||
not_found = ! _ftb_check_phrase(ftb, ftsi.pos, ftsi.len,
|
||||
ftbe, parser);
|
||||
found= _ftb_check_phrase(ftb, ftsi.pos, ftsi.len, ftbe, parser);
|
||||
if (unlikely(found < 0))
|
||||
return 1;
|
||||
}
|
||||
if (not_found) break;
|
||||
if (!found)
|
||||
break;
|
||||
} /* ftbe->quot */
|
||||
}
|
||||
else
|
||||
|
|
@ -745,6 +749,7 @@ static void _ftb_climb_the_tree(FTB *ftb, FTB_WORD *ftbw, FT_SEG_ITERATOR *ftsi_
|
|||
weight*= ftbe->weight;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -777,7 +782,11 @@ int maria_ft_boolean_read_next(FT_INFO *ftb, char *record)
|
|||
{
|
||||
while (curdoc == (ftbw=(FTB_WORD *)queue_top(& ftb->queue))->docid[0])
|
||||
{
|
||||
_ftb_climb_the_tree(ftb, ftbw, 0);
|
||||
if (unlikely(_ftb_climb_the_tree(ftb, ftbw, 0)))
|
||||
{
|
||||
my_errno= HA_ERR_OUT_OF_MEM;
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* update queue */
|
||||
_ft2_search(ftb, ftbw, 0);
|
||||
|
|
@ -853,7 +862,8 @@ static int ftb_find_relevance_add_word(MYSQL_FTPARSER_PARAM *param,
|
|||
if (ftbw->docid[1] == ftb->info->cur_row.lastpos)
|
||||
continue;
|
||||
ftbw->docid[1]= ftb->info->cur_row.lastpos;
|
||||
_ftb_climb_the_tree(ftb, ftbw, ftb_param->ftsi);
|
||||
if (unlikely(_ftb_climb_the_tree(ftb, ftbw, ftb_param->ftsi)))
|
||||
return 1;
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
|
@ -926,7 +936,8 @@ float maria_ft_boolean_find_relevance(FT_INFO *ftb, uchar *record, uint length)
|
|||
continue;
|
||||
param->doc= (uchar *)ftsi.pos;
|
||||
param->length= ftsi.len;
|
||||
parser->parse(param);
|
||||
if (unlikely(parser->parse(param)))
|
||||
return 0;
|
||||
}
|
||||
ftbe=ftb->root;
|
||||
if (ftbe->docid[1]==docid && ftbe->cur_weight>0 &&
|
||||
|
|
|
|||
|
|
@ -258,8 +258,12 @@ FT_INFO *maria_ft_init_nlq_search(MARIA_HA *info, uint keynr, uchar *query,
|
|||
{
|
||||
info->update|= HA_STATE_AKTIV;
|
||||
ftparser_param->flags= MYSQL_FTFLAGS_NEED_COPY;
|
||||
_ma_ft_parse(&wtree, info, keynr, record, ftparser_param,
|
||||
&wtree.mem_root);
|
||||
if (unlikely(_ma_ft_parse(&wtree, info, keynr, record, ftparser_param,
|
||||
&wtree.mem_root)))
|
||||
{
|
||||
delete_queue(&best);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
}
|
||||
delete_queue(&best);
|
||||
|
|
|
|||
|
|
@ -57,9 +57,9 @@ int maria_status(MARIA_HA *info, register MARIA_INFO *x, uint flag)
|
|||
|
||||
x->keys = share->state.header.keys;
|
||||
x->check_time = share->state.check_time;
|
||||
x->mean_reclength = info->state->records ?
|
||||
(ulong) ((info->state->data_file_length-info->state->empty)/
|
||||
info->state->records) : (ulong) share->min_pack_length;
|
||||
x->mean_reclength = x->records ?
|
||||
(ulong) ((x->data_file_length - x->delete_length) /x ->records) :
|
||||
(ulong) share->min_pack_length;
|
||||
}
|
||||
if (flag & HA_STATUS_ERRKEY)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -206,7 +206,7 @@ uint _ma_make_key(register MARIA_HA *info, uint keynr, uchar *key,
|
|||
uint keynr key number
|
||||
key Store packed key here
|
||||
old Not packed key
|
||||
k_length Length of 'old' to use
|
||||
keypart_map bitmap of used keyparts
|
||||
last_used_keyseg out parameter. May be NULL
|
||||
|
||||
RETURN
|
||||
|
|
@ -216,34 +216,37 @@ uint _ma_make_key(register MARIA_HA *info, uint keynr, uchar *key,
|
|||
*/
|
||||
|
||||
uint _ma_pack_key(register MARIA_HA *info, uint keynr, uchar *key,
|
||||
const uchar *old, uint k_length, HA_KEYSEG **last_used_keyseg)
|
||||
const uchar *old, key_part_map keypart_map,
|
||||
HA_KEYSEG **last_used_keyseg)
|
||||
{
|
||||
uchar *start_key=key;
|
||||
HA_KEYSEG *keyseg;
|
||||
my_bool is_ft= info->s->keyinfo[keynr].flag & HA_FULLTEXT;
|
||||
DBUG_ENTER("_ma_pack_key");
|
||||
|
||||
for (keyseg=info->s->keyinfo[keynr].seg ;
|
||||
keyseg->type && (int) k_length > 0;
|
||||
old+=keyseg->length, keyseg++)
|
||||
/* "one part" rtree key is 2*SPDIMS part key in Maria */
|
||||
if (info->s->keyinfo[keynr].key_alg == HA_KEY_ALG_RTREE)
|
||||
keypart_map= (((key_part_map)1) << (2*SPDIMS)) - 1;
|
||||
|
||||
/* only key prefixes are supported */
|
||||
DBUG_ASSERT(((keypart_map+1) & keypart_map) == 0);
|
||||
|
||||
for (keyseg=info->s->keyinfo[keynr].seg ; keyseg->type && keypart_map;
|
||||
old+= keyseg->length, keyseg++)
|
||||
{
|
||||
enum ha_base_keytype type=(enum ha_base_keytype) keyseg->type;
|
||||
uint length=min((uint) keyseg->length,(uint) k_length);
|
||||
enum ha_base_keytype type= (enum ha_base_keytype) keyseg->type;
|
||||
uint length= keyseg->length;
|
||||
uint char_length;
|
||||
const uchar *pos;
|
||||
CHARSET_INFO *cs=keyseg->charset;
|
||||
|
||||
keypart_map>>= 1;
|
||||
if (keyseg->null_bit)
|
||||
{
|
||||
k_length--;
|
||||
if (!(*key++= (char) 1-*old++)) /* Copy null marker */
|
||||
{
|
||||
k_length-=length;
|
||||
if (keyseg->flag & (HA_VAR_LENGTH_PART | HA_BLOB_PART))
|
||||
{
|
||||
k_length-=2; /* Skip length */
|
||||
old+= 2;
|
||||
}
|
||||
continue; /* Found NULL */
|
||||
}
|
||||
}
|
||||
|
|
@ -253,17 +256,16 @@ uint _ma_pack_key(register MARIA_HA *info, uint keynr, uchar *key,
|
|||
if (keyseg->flag & HA_SPACE_PACK)
|
||||
{
|
||||
const uchar *end= pos + length;
|
||||
if (type != HA_KEYTYPE_NUM)
|
||||
{
|
||||
while (end > pos && end[-1] == ' ')
|
||||
end--;
|
||||
}
|
||||
else
|
||||
if (type == HA_KEYTYPE_NUM)
|
||||
{
|
||||
while (pos < end && pos[0] == ' ')
|
||||
pos++;
|
||||
}
|
||||
k_length-=length;
|
||||
else if (type != HA_KEYTYPE_BINARY)
|
||||
{
|
||||
while (end > pos && end[-1] == ' ')
|
||||
end--;
|
||||
}
|
||||
length=(uint) (end-pos);
|
||||
FIX_LENGTH(cs, pos, length, char_length);
|
||||
store_key_length_inc(key,char_length);
|
||||
|
|
@ -275,7 +277,6 @@ uint _ma_pack_key(register MARIA_HA *info, uint keynr, uchar *key,
|
|||
{
|
||||
/* Length of key-part used with maria_rkey() always 2 */
|
||||
uint tmp_length=uint2korr(pos);
|
||||
k_length-= 2+length;
|
||||
pos+=2;
|
||||
set_if_smaller(length,tmp_length); /* Safety */
|
||||
FIX_LENGTH(cs, pos, length, char_length);
|
||||
|
|
@ -288,11 +289,8 @@ uint _ma_pack_key(register MARIA_HA *info, uint keynr, uchar *key,
|
|||
else if (keyseg->flag & HA_SWAP_KEY)
|
||||
{ /* Numerical column */
|
||||
pos+=length;
|
||||
k_length-=length;
|
||||
while (length--)
|
||||
{
|
||||
*key++ = *--pos;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
FIX_LENGTH(cs, pos, length, char_length);
|
||||
|
|
@ -300,30 +298,10 @@ uint _ma_pack_key(register MARIA_HA *info, uint keynr, uchar *key,
|
|||
if (length > char_length)
|
||||
cs->cset->fill(cs, (char*) key+char_length, length-char_length, ' ');
|
||||
key+= length;
|
||||
k_length-=length;
|
||||
}
|
||||
if (last_used_keyseg)
|
||||
*last_used_keyseg= keyseg;
|
||||
|
||||
#ifdef NOT_USED
|
||||
if (keyseg->type)
|
||||
{
|
||||
/* Part-key ; fill with ASCII 0 for easier searching */
|
||||
length= (uint) -k_length; /* unused part of last key */
|
||||
do
|
||||
{
|
||||
if (keyseg->flag & HA_NULL_PART)
|
||||
length++;
|
||||
if (keyseg->flag & HA_SPACE_PACK)
|
||||
length+=2;
|
||||
else
|
||||
length+= keyseg->length;
|
||||
keyseg++;
|
||||
} while (keyseg->type);
|
||||
bzero(key,length);
|
||||
key+=length;
|
||||
}
|
||||
#endif
|
||||
DBUG_PRINT("exit", ("length: %u", (uint) (key-start_key)));
|
||||
DBUG_RETURN((uint) (key-start_key));
|
||||
} /* _ma_pack_key */
|
||||
|
|
|
|||
|
|
@ -3553,8 +3553,8 @@ static my_bool translog_relative_LSN_encode(struct st_translog_parts *parts,
|
|||
COMPRESSED_LSN_MAX_STORE_SIZE)) -
|
||||
dst_ptr);
|
||||
parts->record_length-= (economy= lsns_len - part->length);
|
||||
DBUG_PRINT("info", ("new length of LSNs: %u economy: %d",
|
||||
part->length, economy));
|
||||
DBUG_PRINT("info", ("new length of LSNs: %lu economy: %d",
|
||||
(ulong)part->length, economy));
|
||||
parts->total_record_length-= economy;
|
||||
part->str= (char*)dst_ptr;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -392,7 +392,7 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags)
|
|||
|
||||
key_parts+=fulltext_keys*FT_SEGS;
|
||||
if (share->base.max_key_length > maria_max_key_length() ||
|
||||
keys > MARIA_MAX_KEY || key_parts >= MARIA_MAX_KEY * HA_MAX_KEY_SEG)
|
||||
keys > MARIA_MAX_KEY || key_parts > MARIA_MAX_KEY * HA_MAX_KEY_SEG)
|
||||
{
|
||||
DBUG_PRINT("error",("Wrong key info: Max_key_length: %d keys: %d key_parts: %d", share->base.max_key_length, keys, key_parts));
|
||||
my_errno=HA_ERR_UNSUPPORTED;
|
||||
|
|
@ -667,22 +667,6 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags)
|
|||
_ma_setup_functions(share);
|
||||
if ((*share->once_init)(share, info.dfile.file))
|
||||
goto err;
|
||||
if (open_flags & HA_OPEN_MMAP)
|
||||
{
|
||||
info.s= share;
|
||||
if (_ma_dynmap_file(&info, share->state.state.data_file_length))
|
||||
{
|
||||
/* purecov: begin inspected */
|
||||
/* Ignore if mmap fails. Use file I/O instead. */
|
||||
DBUG_PRINT("warning", ("mmap failed: errno: %d", errno));
|
||||
/* purecov: end */
|
||||
}
|
||||
else
|
||||
{
|
||||
share->file_read= _ma_mmap_pread;
|
||||
share->file_write= _ma_mmap_pwrite;
|
||||
}
|
||||
}
|
||||
share->is_log_table= FALSE;
|
||||
if (open_flags & HA_OPEN_TMP_TABLE)
|
||||
share->options|= HA_OPTION_TMP_TABLE;
|
||||
|
|
@ -721,6 +705,14 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags)
|
|||
}
|
||||
}
|
||||
#endif
|
||||
/*
|
||||
Memory mapping can only be requested after initializing intern_lock.
|
||||
*/
|
||||
if (open_flags & HA_OPEN_MMAP)
|
||||
{
|
||||
info.s= share;
|
||||
maria_extra(&info, HA_EXTRA_MMAP, 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -1022,10 +1014,10 @@ uint _ma_state_info_write(File file, MARIA_STATE_INFO *state, uint pWrite)
|
|||
}
|
||||
|
||||
if (pWrite & 1)
|
||||
DBUG_RETURN(my_pwrite(file,(char*) buff, (uint) (ptr-buff), 0L,
|
||||
MYF(MY_NABP | MY_THREADSAFE)));
|
||||
DBUG_RETURN(my_write(file, (char*) buff, (uint) (ptr-buff),
|
||||
MYF(MY_NABP)));
|
||||
DBUG_RETURN(my_pwrite(file, buff, (size_t) (ptr-buff), 0L,
|
||||
MYF(MY_NABP | MY_THREADSAFE)) != 0);
|
||||
DBUG_RETURN(my_write(file, buff, (size_t) (ptr-buff),
|
||||
MYF(MY_NABP)) != 0);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1089,10 +1081,10 @@ uint _ma_state_info_read_dsk(File file, MARIA_STATE_INFO *state, my_bool pRead)
|
|||
if (pRead)
|
||||
{
|
||||
if (my_pread(file, buff, state->state_length,0L, MYF(MY_NABP)))
|
||||
return (MY_FILE_ERROR);
|
||||
return 1;
|
||||
}
|
||||
else if (my_read(file, buff, state->state_length,MYF(MY_NABP)))
|
||||
return (MY_FILE_ERROR);
|
||||
return 1;
|
||||
_ma_state_info_read(buff, state);
|
||||
}
|
||||
return 0;
|
||||
|
|
@ -1143,7 +1135,7 @@ uint _ma_base_info_write(File file, MARIA_BASE_INFO *base)
|
|||
*ptr++= base->extra_alloc_procent;
|
||||
bzero(ptr,16); ptr+= 16; /* extra */
|
||||
DBUG_ASSERT((ptr - buff) == MARIA_BASE_INFO_SIZE);
|
||||
return my_write(file,(char*) buff, (uint) (ptr-buff), MYF(MY_NABP));
|
||||
return my_write(file, buff, (size_t) (ptr-buff), MYF(MY_NABP)) != 0;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1204,7 +1196,7 @@ uint _ma_keydef_write(File file, MARIA_KEYDEF *keydef)
|
|||
mi_int2store(ptr,keydef->keylength); ptr+= 2;
|
||||
mi_int2store(ptr,keydef->minlength); ptr+= 2;
|
||||
mi_int2store(ptr,keydef->maxlength); ptr+= 2;
|
||||
return my_write(file,(char*) buff, (uint) (ptr-buff), MYF(MY_NABP));
|
||||
return my_write(file, buff, (size_t) (ptr-buff), MYF(MY_NABP)) != 0;
|
||||
}
|
||||
|
||||
char *_ma_keydef_read(char *ptr, MARIA_KEYDEF *keydef)
|
||||
|
|
@ -1247,7 +1239,7 @@ int _ma_keyseg_write(File file, const HA_KEYSEG *keyseg)
|
|||
mi_int4store(ptr, pos);
|
||||
ptr+=4;
|
||||
|
||||
return my_write(file,(char*) buff, (uint) (ptr-buff), MYF(MY_NABP));
|
||||
return my_write(file, buff, (size_t) (ptr-buff), MYF(MY_NABP)) != 0;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1287,7 +1279,7 @@ uint _ma_uniquedef_write(File file, MARIA_UNIQUEDEF *def)
|
|||
*ptr++= (uchar) def->key;
|
||||
*ptr++ = (uchar) def->null_are_equal;
|
||||
|
||||
return my_write(file,(char*) buff, (uint) (ptr-buff), MYF(MY_NABP));
|
||||
return my_write(file, buff, (size_t) (ptr-buff), MYF(MY_NABP)) != 0;
|
||||
}
|
||||
|
||||
char *_ma_uniquedef_read(char *ptr, MARIA_UNIQUEDEF *def)
|
||||
|
|
@ -1315,7 +1307,7 @@ uint _ma_columndef_write(File file, MARIA_COLUMNDEF *columndef)
|
|||
mi_int2store(ptr,columndef->empty_pos); ptr+= 2;
|
||||
(*ptr++)= columndef->null_bit;
|
||||
(*ptr++)= columndef->empty_bit;
|
||||
return my_write(file,(char*) buff, (uint) (ptr-buff), MYF(MY_NABP));
|
||||
return my_write(file, buff, (size_t) (ptr-buff), MYF(MY_NABP)) != 0;
|
||||
}
|
||||
|
||||
char *_ma_columndef_read(char *ptr, MARIA_COLUMNDEF *columndef)
|
||||
|
|
|
|||
|
|
@ -55,12 +55,17 @@ int maria_preload(MARIA_HA *info, ulonglong key_map, my_bool ignore_leaves)
|
|||
|
||||
block_length= keyinfo[0].block_length;
|
||||
|
||||
/* Check whether all indexes use the same block size */
|
||||
for (i= 1 ; i < keys ; i++)
|
||||
if (ignore_leaves)
|
||||
{
|
||||
if (keyinfo[i].block_length != block_length)
|
||||
DBUG_RETURN(my_errno= HA_ERR_NON_UNIQUE_BLOCK_SIZE);
|
||||
/* Check whether all indexes use the same block size */
|
||||
for (i= 1 ; i < keys ; i++)
|
||||
{
|
||||
if (keyinfo[i].block_length != block_length)
|
||||
DBUG_RETURN(my_errno= HA_ERR_NON_UNIQUE_BLOCK_SIZE);
|
||||
}
|
||||
}
|
||||
else
|
||||
block_length= share->pagecache->block_size;
|
||||
|
||||
length= info->preload_buff_size/block_length * block_length;
|
||||
set_if_bigger(length, block_length);
|
||||
|
|
|
|||
|
|
@ -21,12 +21,11 @@
|
|||
#include "maria_def.h"
|
||||
#include "ma_rt_index.h"
|
||||
|
||||
static ha_rows _ma_record_pos(MARIA_HA *info,const uchar *key,uint key_len,
|
||||
enum ha_rkey_function search_flag);
|
||||
static double _ma_search_pos(MARIA_HA *info,MARIA_KEYDEF *keyinfo, uchar *key,
|
||||
uint key_len,uint nextflag, my_off_t pos);
|
||||
static uint _ma_keynr(MARIA_HA *info, MARIA_KEYDEF *keyinfo, uchar *page,
|
||||
uchar *keypos, uint *ret_max_key);
|
||||
static ha_rows _ma_record_pos(MARIA_HA *,const uchar *, key_part_map,
|
||||
enum ha_rkey_function);
|
||||
static double _ma_search_pos(MARIA_HA *, MARIA_KEYDEF *, uchar *,
|
||||
uint, uint, my_off_t);
|
||||
static uint _ma_keynr(MARIA_HA *, MARIA_KEYDEF *, uchar *, uchar *, uint *);
|
||||
|
||||
|
||||
/**
|
||||
|
|
@ -84,7 +83,7 @@ ha_rows maria_records_in_range(MARIA_HA *info, int inx, key_range *min_key,
|
|||
}
|
||||
key_buff= info->lastkey+info->s->base.max_key_length;
|
||||
start_key_len= _ma_pack_key(info,inx, key_buff,
|
||||
min_key->key, min_key->length,
|
||||
min_key->key, min_key->keypart_map,
|
||||
(HA_KEYSEG**) 0);
|
||||
res= maria_rtree_estimate(info, inx, key_buff, start_key_len,
|
||||
maria_read_vec[min_key->flag]);
|
||||
|
|
@ -95,13 +94,13 @@ ha_rows maria_records_in_range(MARIA_HA *info, int inx, key_range *min_key,
|
|||
case HA_KEY_ALG_BTREE:
|
||||
default:
|
||||
start_pos= (min_key ?
|
||||
_ma_record_pos(info, min_key->key, min_key->length,
|
||||
_ma_record_pos(info, min_key->key, min_key->keypart_map,
|
||||
min_key->flag) :
|
||||
(ha_rows) 0);
|
||||
end_pos= (max_key ?
|
||||
_ma_record_pos(info, max_key->key, max_key->length,
|
||||
_ma_record_pos(info, max_key->key, max_key->keypart_map,
|
||||
max_key->flag) :
|
||||
info->state->records+ (ha_rows) 1);
|
||||
info->state->records + (ha_rows) 1);
|
||||
res= (end_pos < start_pos ? (ha_rows) 0 :
|
||||
(end_pos == start_pos ? (ha_rows) 1 : end_pos-start_pos));
|
||||
if (start_pos == HA_POS_ERROR || end_pos == HA_POS_ERROR)
|
||||
|
|
@ -126,20 +125,22 @@ ha_rows maria_records_in_range(MARIA_HA *info, int inx, key_range *min_key,
|
|||
|
||||
/* Find relative position (in records) for key in index-tree */
|
||||
|
||||
static ha_rows _ma_record_pos(MARIA_HA *info, const uchar *key, uint key_len,
|
||||
static ha_rows _ma_record_pos(MARIA_HA *info, const uchar *key,
|
||||
key_part_map keypart_map,
|
||||
enum ha_rkey_function search_flag)
|
||||
{
|
||||
uint inx=(uint) info->lastinx, nextflag;
|
||||
uint inx=(uint) info->lastinx, nextflag, key_len;
|
||||
MARIA_KEYDEF *keyinfo=info->s->keyinfo+inx;
|
||||
uchar *key_buff;
|
||||
double pos;
|
||||
DBUG_ENTER("_ma_record_pos");
|
||||
DBUG_PRINT("enter",("search_flag: %d",search_flag));
|
||||
DBUG_ASSERT(keypart_map);
|
||||
|
||||
if (key_len == 0)
|
||||
key_len= USE_WHOLE_KEY;
|
||||
key_buff=info->lastkey+info->s->base.max_key_length;
|
||||
key_len= _ma_pack_key(info, inx, key_buff, key, key_len,
|
||||
key_len= _ma_pack_key(info, inx, key_buff, key, keypart_map,
|
||||
(HA_KEYSEG**) 0);
|
||||
DBUG_EXECUTE("key", _ma_print_key(DBUG_FILE, keyinfo->seg,
|
||||
key_buff, key_len););
|
||||
|
|
@ -147,8 +148,42 @@ static ha_rows _ma_record_pos(MARIA_HA *info, const uchar *key, uint key_len,
|
|||
if (!(nextflag & (SEARCH_FIND | SEARCH_NO_FIND | SEARCH_LAST)))
|
||||
key_len=USE_WHOLE_KEY;
|
||||
|
||||
/*
|
||||
my_handler.c:mi_compare_text() has a flag 'skip_end_space'.
|
||||
This is set in my_handler.c:ha_key_cmp() in dependence on the
|
||||
compare flags 'nextflag' and the column type.
|
||||
|
||||
TEXT columns are of type HA_KEYTYPE_VARTEXT. In this case the
|
||||
condition is skip_end_space= ((nextflag & (SEARCH_FIND |
|
||||
SEARCH_UPDATE)) == SEARCH_FIND).
|
||||
|
||||
SEARCH_FIND is used for an exact key search. The combination
|
||||
SEARCH_FIND | SEARCH_UPDATE is used in write/update/delete
|
||||
operations with a comment like "Not real duplicates", whatever this
|
||||
means. From the condition above we can see that 'skip_end_space' is
|
||||
always false for these operations. The result is that trailing space
|
||||
counts in key comparison and hence, emtpy strings ('', string length
|
||||
zero, but not NULL) compare less that strings starting with control
|
||||
characters and these in turn compare less than strings starting with
|
||||
blanks.
|
||||
|
||||
When estimating the number of records in a key range, we request an
|
||||
exact search for the minimum key. This translates into a plain
|
||||
SEARCH_FIND flag. Using this alone would lead to a 'skip_end_space'
|
||||
compare. Empty strings would be expected above control characters.
|
||||
Their keys would not be found because they are located below control
|
||||
characters.
|
||||
|
||||
This is the reason that we add the SEARCH_UPDATE flag here. It makes
|
||||
the key estimation compare in the same way like key write operations
|
||||
do. Olny so we will find the keys where they have been inserted.
|
||||
|
||||
Adding the flag unconditionally does not hurt as it is used in the
|
||||
above mentioned condition only. So it can safely be used together
|
||||
with other flags.
|
||||
*/
|
||||
pos= _ma_search_pos(info,keyinfo, key_buff, key_len,
|
||||
nextflag | SEARCH_SAVE_BUFF,
|
||||
nextflag | SEARCH_SAVE_BUFF | SEARCH_UPDATE,
|
||||
info->s->state.key_root[inx]);
|
||||
if (pos >= 0.0)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@
|
|||
/* Ordinary search_flag is 0 ; Give error if no record with key */
|
||||
|
||||
int maria_rkey(MARIA_HA *info, uchar *buf, int inx, const uchar *key,
|
||||
uint key_len, enum ha_rkey_function search_flag)
|
||||
key_part_map keypart_map, enum ha_rkey_function search_flag)
|
||||
{
|
||||
uchar *key_buff;
|
||||
MARIA_SHARE *share=info->s;
|
||||
|
|
@ -47,20 +47,21 @@ int maria_rkey(MARIA_HA *info, uchar *buf, int inx, const uchar *key,
|
|||
key is already packed!; This happens when we are using a MERGE TABLE
|
||||
*/
|
||||
key_buff= info->lastkey+info->s->base.max_key_length;
|
||||
pack_key_length= key_len;
|
||||
bmove(key_buff,key,key_len);
|
||||
last_used_keyseg= 0;
|
||||
pack_key_length= keypart_map;
|
||||
bmove(key_buff, key, pack_key_length);
|
||||
last_used_keyseg= info->s->keyinfo[inx].seg + info->last_used_keyseg;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (key_len == 0)
|
||||
key_len=USE_WHOLE_KEY;
|
||||
DBUG_ASSERT(keypart_map);
|
||||
/* Save the packed key for later use in the second buffer of lastkey. */
|
||||
key_buff=info->lastkey+info->s->base.max_key_length;
|
||||
pack_key_length= _ma_pack_key(info,(uint) inx, key_buff, key,
|
||||
key_len, &last_used_keyseg);
|
||||
keypart_map, &last_used_keyseg);
|
||||
/* Save packed_key_length for use by the MERGE engine. */
|
||||
info->pack_key_length= pack_key_length;
|
||||
info->last_used_keyseg= (uint16) (last_used_keyseg -
|
||||
info->s->keyinfo[inx].seg);
|
||||
DBUG_EXECUTE("key", _ma_print_key(DBUG_FILE, keyinfo->seg,
|
||||
key_buff, pack_key_length););
|
||||
}
|
||||
|
|
|
|||
|
|
@ -187,6 +187,7 @@ int maria_rtree_find_first(MARIA_HA *info, uint keynr, uchar *key,
|
|||
/*
|
||||
Save searched key, include data pointer.
|
||||
The data pointer is required if the search_flag contains MBR_DATA.
|
||||
(minimum bounding rectangle)
|
||||
*/
|
||||
memcpy(info->first_mbr_key, key, keyinfo->keylength);
|
||||
info->last_rkey_length = key_length;
|
||||
|
|
@ -546,16 +547,19 @@ static int maria_rtree_insert_req(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
|
|||
uint nod_flag;
|
||||
int res;
|
||||
uchar *page_buf, *k;
|
||||
DBUG_ENTER("maria_rtree_insert_req");
|
||||
|
||||
if (!(page_buf= (uchar*) my_alloca((uint)keyinfo->block_length +
|
||||
HA_MAX_KEY_BUFF)))
|
||||
{
|
||||
my_errno = HA_ERR_OUT_OF_MEM;
|
||||
return -1;
|
||||
DBUG_RETURN(-1); /* purecov: inspected */
|
||||
}
|
||||
if (!_ma_fetch_keypage(info, keyinfo, page, DFLT_INIT_HITS, page_buf, 0))
|
||||
goto err1;
|
||||
nod_flag = _ma_test_if_nod(page_buf);
|
||||
DBUG_PRINT("rtree", ("page: %lu level: %d ins_level: %d nod_flag: %u",
|
||||
(ulong) page, level, ins_level, nod_flag));
|
||||
|
||||
if ((ins_level == -1 && nod_flag) || /* key: go down to leaf */
|
||||
(ins_level > -1 && ins_level > level)) /* branch: go down to ins_level */
|
||||
|
|
@ -609,11 +613,11 @@ static int maria_rtree_insert_req(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
|
|||
|
||||
ok:
|
||||
my_afree(page_buf);
|
||||
return res;
|
||||
DBUG_RETURN(res);
|
||||
|
||||
err1:
|
||||
my_afree(page_buf);
|
||||
return -1;
|
||||
DBUG_RETURN(-1); /* purecov: inspected */
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -633,18 +637,19 @@ static int maria_rtree_insert_level(MARIA_HA *info, uint keynr, uchar *key,
|
|||
MARIA_KEYDEF *keyinfo = info->s->keyinfo + keynr;
|
||||
int res;
|
||||
my_off_t new_page;
|
||||
DBUG_ENTER("maria_rtree_insert_level");
|
||||
|
||||
if ((old_root = info->s->state.key_root[keynr]) == HA_OFFSET_ERROR)
|
||||
{
|
||||
if ((old_root = _ma_new(info, keyinfo, DFLT_INIT_HITS)) == HA_OFFSET_ERROR)
|
||||
return -1;
|
||||
DBUG_RETURN(-1);
|
||||
info->keyread_buff_used = 1;
|
||||
maria_putint(info->buff, 2, 0);
|
||||
res = maria_rtree_add_key(info, keyinfo, key, key_length, info->buff, NULL);
|
||||
if (_ma_write_keypage(info, keyinfo, old_root, DFLT_INIT_HITS, info->buff))
|
||||
return 1;
|
||||
DBUG_RETURN(1);
|
||||
info->s->state.key_root[keynr] = old_root;
|
||||
return res;
|
||||
DBUG_RETURN(res);
|
||||
}
|
||||
|
||||
switch ((res = maria_rtree_insert_req(info, keyinfo, key, key_length,
|
||||
|
|
@ -660,11 +665,12 @@ static int maria_rtree_insert_level(MARIA_HA *info, uint keynr, uchar *key,
|
|||
my_off_t new_root;
|
||||
uint nod_flag = info->s->base.key_reflength;
|
||||
|
||||
DBUG_PRINT("rtree", ("root was split, grow a new root"));
|
||||
if (!(new_root_buf= (uchar*) my_alloca((uint)keyinfo->block_length +
|
||||
HA_MAX_KEY_BUFF)))
|
||||
{
|
||||
my_errno = HA_ERR_OUT_OF_MEM;
|
||||
return -1;
|
||||
DBUG_RETURN(-1); /* purecov: inspected */
|
||||
}
|
||||
|
||||
maria_putint(new_root_buf, 2, nod_flag);
|
||||
|
|
@ -694,12 +700,15 @@ static int maria_rtree_insert_level(MARIA_HA *info, uint keynr, uchar *key,
|
|||
DFLT_INIT_HITS, new_root_buf))
|
||||
goto err1;
|
||||
info->s->state.key_root[keynr] = new_root;
|
||||
DBUG_PRINT("rtree", ("new root page: %lu level: %d nod_flag: %u",
|
||||
(ulong) new_root, 0,
|
||||
_ma_test_if_nod(new_root_buf)));
|
||||
|
||||
my_afree((uchar*)new_root_buf);
|
||||
break;
|
||||
err1:
|
||||
my_afree((uchar*)new_root_buf);
|
||||
return -1;
|
||||
DBUG_RETURN(-1); /* purecov: inspected */
|
||||
}
|
||||
default:
|
||||
case -1: /* error */
|
||||
|
|
@ -707,7 +716,7 @@ err1:
|
|||
break;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
DBUG_RETURN(res);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -721,9 +730,10 @@ err1:
|
|||
|
||||
int maria_rtree_insert(MARIA_HA *info, uint keynr, uchar *key, uint key_length)
|
||||
{
|
||||
return (!key_length ||
|
||||
(maria_rtree_insert_level(info, keynr, key, key_length, -1) == -1)) ?
|
||||
-1 : 0;
|
||||
DBUG_ENTER("maria_rtree_insert");
|
||||
DBUG_RETURN((!key_length ||
|
||||
(maria_rtree_insert_level(info, keynr, key, key_length, -1) == -1)) ?
|
||||
-1 : 0);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -738,6 +748,8 @@ int maria_rtree_insert(MARIA_HA *info, uint keynr, uchar *key, uint key_length)
|
|||
static int maria_rtree_fill_reinsert_list(stPageList *ReinsertList, my_off_t page,
|
||||
int level)
|
||||
{
|
||||
DBUG_ENTER("maria_rtree_fill_reinsert_list");
|
||||
DBUG_PRINT("rtree", ("page: %lu level: %d", (ulong) page, level));
|
||||
if (ReinsertList->n_pages == ReinsertList->m_pages)
|
||||
{
|
||||
ReinsertList->m_pages += REINSERT_BUFFER_INC;
|
||||
|
|
@ -749,10 +761,10 @@ static int maria_rtree_fill_reinsert_list(stPageList *ReinsertList, my_off_t pag
|
|||
ReinsertList->pages[ReinsertList->n_pages].offs = page;
|
||||
ReinsertList->pages[ReinsertList->n_pages].level = level;
|
||||
ReinsertList->n_pages++;
|
||||
return 0;
|
||||
DBUG_RETURN(0);
|
||||
|
||||
err1:
|
||||
return -1;
|
||||
DBUG_RETURN(-1); /* purecov: inspected */
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -776,15 +788,18 @@ static int maria_rtree_delete_req(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
|
|||
uint nod_flag;
|
||||
int res;
|
||||
uchar *page_buf, *last, *k;
|
||||
DBUG_ENTER("maria_rtree_delete_req");
|
||||
|
||||
if (!(page_buf = (uchar*) my_alloca((uint)keyinfo->block_length)))
|
||||
{
|
||||
my_errno = HA_ERR_OUT_OF_MEM;
|
||||
return -1;
|
||||
DBUG_RETURN(-1); /* purecov: inspected */
|
||||
}
|
||||
if (!_ma_fetch_keypage(info, keyinfo, page, DFLT_INIT_HITS, page_buf, 0))
|
||||
goto err1;
|
||||
nod_flag = _ma_test_if_nod(page_buf);
|
||||
DBUG_PRINT("rtree", ("page: %lu level: %d nod_flag: %u",
|
||||
(ulong) page, level, nod_flag));
|
||||
|
||||
k = rt_PAGE_FIRST_KEY(page_buf, nod_flag);
|
||||
last = rt_PAGE_END(page_buf);
|
||||
|
|
@ -806,6 +821,7 @@ static int maria_rtree_delete_req(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
|
|||
rt_PAGE_MIN_SIZE(keyinfo->block_length))
|
||||
{
|
||||
/* OK */
|
||||
/* Calculate a new key value (MBR) for the shrinked block. */
|
||||
if (maria_rtree_set_key_mbr(info, keyinfo, k, key_length,
|
||||
_ma_kpos(nod_flag, k)))
|
||||
goto err1;
|
||||
|
|
@ -815,11 +831,24 @@ static int maria_rtree_delete_req(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
|
|||
}
|
||||
else
|
||||
{
|
||||
/* too small: delete key & add it descendant to reinsert list */
|
||||
/*
|
||||
Too small: delete key & add it descendant to reinsert list.
|
||||
Store position and level of the block so that it can be
|
||||
accessed later for inserting the remaining keys.
|
||||
*/
|
||||
DBUG_PRINT("rtree", ("too small. move block to reinsert list"));
|
||||
if (maria_rtree_fill_reinsert_list(ReinsertList,
|
||||
_ma_kpos(nod_flag, k),
|
||||
level + 1))
|
||||
goto err1;
|
||||
/*
|
||||
Delete the key that references the block. This makes the
|
||||
block disappear from the index. Hence we need to insert
|
||||
its remaining keys later. Note: if the block is a branch
|
||||
block, we do not only remove this block, but the whole
|
||||
subtree. So we need to re-insert its keys on the same
|
||||
level later to reintegrate the subtrees.
|
||||
*/
|
||||
maria_rtree_delete_key(info, page_buf, k, key_length, nod_flag);
|
||||
if (_ma_write_keypage(info, keyinfo, page,
|
||||
DFLT_INIT_HITS, page_buf))
|
||||
|
|
@ -879,11 +908,11 @@ static int maria_rtree_delete_req(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
|
|||
|
||||
ok:
|
||||
my_afree((uchar*)page_buf);
|
||||
return res;
|
||||
DBUG_RETURN(res);
|
||||
|
||||
err1:
|
||||
my_afree((uchar*)page_buf);
|
||||
return -1;
|
||||
DBUG_RETURN(-1); /* purecov: inspected */
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -901,12 +930,15 @@ int maria_rtree_delete(MARIA_HA *info, uint keynr, uchar *key, uint key_length)
|
|||
stPageList ReinsertList;
|
||||
my_off_t old_root;
|
||||
MARIA_KEYDEF *keyinfo = info->s->keyinfo + keynr;
|
||||
DBUG_ENTER("maria_rtree_delete");
|
||||
|
||||
if ((old_root = info->s->state.key_root[keynr]) == HA_OFFSET_ERROR)
|
||||
{
|
||||
my_errno= HA_ERR_END_OF_FILE;
|
||||
return -1;
|
||||
DBUG_RETURN(-1); /* purecov: inspected */
|
||||
}
|
||||
DBUG_PRINT("rtree", ("starting deletion at root page: %lu",
|
||||
(ulong) old_root));
|
||||
|
||||
ReinsertList.pages = NULL;
|
||||
ReinsertList.n_pages = 0;
|
||||
|
|
@ -915,12 +947,12 @@ int maria_rtree_delete(MARIA_HA *info, uint keynr, uchar *key, uint key_length)
|
|||
switch (maria_rtree_delete_req(info, keyinfo, key, key_length, old_root,
|
||||
&page_size, &ReinsertList, 0))
|
||||
{
|
||||
case 2:
|
||||
case 2: /* empty */
|
||||
{
|
||||
info->s->state.key_root[keynr] = HA_OFFSET_ERROR;
|
||||
return 0;
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
case 0:
|
||||
case 0: /* deleted */
|
||||
{
|
||||
uint nod_flag;
|
||||
ulong i;
|
||||
|
|
@ -937,16 +969,35 @@ int maria_rtree_delete(MARIA_HA *info, uint keynr, uchar *key, uint key_length)
|
|||
DFLT_INIT_HITS, page_buf, 0))
|
||||
goto err1;
|
||||
nod_flag = _ma_test_if_nod(page_buf);
|
||||
DBUG_PRINT("rtree", ("reinserting keys from "
|
||||
"page: %lu level: %d nod_flag: %u",
|
||||
(ulong) ReinsertList.pages[i].offs,
|
||||
ReinsertList.pages[i].level, nod_flag));
|
||||
|
||||
k = rt_PAGE_FIRST_KEY(page_buf, nod_flag);
|
||||
last = rt_PAGE_END(page_buf);
|
||||
for (; k < last; k = rt_PAGE_NEXT_KEY(k, key_length, nod_flag))
|
||||
{
|
||||
if (maria_rtree_insert_level(info, keynr, k, key_length,
|
||||
ReinsertList.pages[i].level) == -1)
|
||||
int res;
|
||||
if ((res=
|
||||
maria_rtree_insert_level(info, keynr, k, key_length,
|
||||
ReinsertList.pages[i].level)) == -1)
|
||||
{
|
||||
my_afree(page_buf);
|
||||
goto err1;
|
||||
}
|
||||
if (res)
|
||||
{
|
||||
ulong j;
|
||||
DBUG_PRINT("rtree", ("root has been split, adjust levels"));
|
||||
for (j= i; j < ReinsertList.n_pages; j++)
|
||||
{
|
||||
ReinsertList.pages[j].level++;
|
||||
DBUG_PRINT("rtree", ("keys from page: %lu now level: %d",
|
||||
(ulong) ReinsertList.pages[i].offs,
|
||||
ReinsertList.pages[i].level));
|
||||
}
|
||||
}
|
||||
}
|
||||
my_afree(page_buf);
|
||||
if (_ma_dispose(info, keyinfo, ReinsertList.pages[i].offs,
|
||||
|
|
@ -973,19 +1024,19 @@ int maria_rtree_delete(MARIA_HA *info, uint keynr, uchar *key, uint key_length)
|
|||
info->s->state.key_root[keynr] = new_root;
|
||||
}
|
||||
info->update= HA_STATE_DELETED;
|
||||
return 0;
|
||||
DBUG_RETURN(0);
|
||||
|
||||
err1:
|
||||
return -1;
|
||||
DBUG_RETURN(-1); /* purecov: inspected */
|
||||
}
|
||||
case 1: /* not found */
|
||||
{
|
||||
my_errno = HA_ERR_KEY_NOT_FOUND;
|
||||
return -1;
|
||||
DBUG_RETURN(-1); /* purecov: inspected */
|
||||
}
|
||||
default:
|
||||
case -1: /* error */
|
||||
return -1;
|
||||
DBUG_RETURN(-1); /* purecov: inspected */
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ int maria_rtree_add_key(MARIA_HA *info, MARIA_KEYDEF *keyinfo, uchar *key,
|
|||
{
|
||||
uint page_size = maria_data_on_page(page_buf);
|
||||
uint nod_flag = _ma_test_if_nod(page_buf);
|
||||
DBUG_ENTER("maria_rtree_add_key");
|
||||
|
||||
if (page_size + key_length + info->s->base.rec_reflength <=
|
||||
keyinfo->block_length)
|
||||
|
|
@ -42,22 +43,27 @@ int maria_rtree_add_key(MARIA_HA *info, MARIA_KEYDEF *keyinfo, uchar *key,
|
|||
if (nod_flag)
|
||||
{
|
||||
/* save key */
|
||||
DBUG_ASSERT(_ma_kpos(nod_flag, key) < info->state->key_file_length);
|
||||
memcpy(rt_PAGE_END(page_buf), key - nod_flag, key_length + nod_flag);
|
||||
page_size += key_length + nod_flag;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* save key */
|
||||
DBUG_ASSERT(_ma_dpos(info, nod_flag, key + key_length +
|
||||
info->s->base.rec_reflength) <
|
||||
info->state->data_file_length +
|
||||
info->s->base.pack_reclength);
|
||||
memcpy(rt_PAGE_END(page_buf), key, key_length +
|
||||
info->s->base.rec_reflength);
|
||||
page_size += key_length + info->s->base.rec_reflength;
|
||||
}
|
||||
maria_putint(page_buf, page_size, nod_flag);
|
||||
return 0;
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
return (maria_rtree_split_page(info, keyinfo, page_buf, key, key_length,
|
||||
new_page) ? -1 : 1);
|
||||
DBUG_RETURN(maria_rtree_split_page(info, keyinfo, page_buf, key, key_length,
|
||||
new_page) ? -1 : 1);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -91,11 +97,13 @@ int maria_rtree_delete_key(MARIA_HA *info, uchar *page_buf, uchar *key,
|
|||
int maria_rtree_set_key_mbr(MARIA_HA *info, MARIA_KEYDEF *keyinfo, uchar *key,
|
||||
uint key_length, my_off_t child_page)
|
||||
{
|
||||
DBUG_ENTER("maria_rtree_set_key_mbr");
|
||||
if (!_ma_fetch_keypage(info, keyinfo, child_page,
|
||||
DFLT_INIT_HITS, info->buff, 0))
|
||||
return -1;
|
||||
DBUG_RETURN(-1);
|
||||
|
||||
return maria_rtree_page_mbr(info, keyinfo->seg, info->buff, key, key_length);
|
||||
DBUG_RETURN(maria_rtree_page_mbr(info, keyinfo->seg,
|
||||
info->buff, key, key_length));
|
||||
}
|
||||
|
||||
#endif /*HAVE_RTREE_KEYS*/
|
||||
|
|
|
|||
|
|
@ -266,13 +266,15 @@ int maria_rtree_split_page(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
|
|||
uint full_length= key_length + (nod_flag ? nod_flag :
|
||||
info->s->base.rec_reflength);
|
||||
int max_keys= (maria_data_on_page(page)-2) / (full_length);
|
||||
DBUG_ENTER("maria_rtree_split_page");
|
||||
DBUG_PRINT("rtree", ("splitting block"));
|
||||
|
||||
n_dim = keyinfo->keysegs / 2;
|
||||
|
||||
if (!(coord_buf= (double*) my_alloca(n_dim * 2 * sizeof(double) *
|
||||
(max_keys + 1 + 4) +
|
||||
sizeof(SplitStruct) * (max_keys + 1))))
|
||||
return -1;
|
||||
DBUG_RETURN(-1); /* purecov: inspected */
|
||||
|
||||
task= (SplitStruct *)(coord_buf + n_dim * 2 * (max_keys + 1 + 4));
|
||||
|
||||
|
|
@ -343,12 +345,18 @@ int maria_rtree_split_page(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
|
|||
else
|
||||
err_code= _ma_write_keypage(info, keyinfo, *new_page_offs,
|
||||
DFLT_INIT_HITS, new_page);
|
||||
DBUG_PRINT("rtree", ("split new block: %lu", (ulong) *new_page_offs));
|
||||
|
||||
my_afree((uchar*)new_page);
|
||||
|
||||
split_err:
|
||||
/**
|
||||
@todo the cast below is useless (coord_buf is uchar*); at the moment we
|
||||
changed all "byte" to "uchar", some casts became useless and should be
|
||||
removed.
|
||||
*/
|
||||
my_afree((uchar*) coord_buf);
|
||||
return err_code;
|
||||
DBUG_RETURN(err_code);
|
||||
}
|
||||
|
||||
#endif /*HAVE_RTREE_KEYS*/
|
||||
|
|
|
|||
|
|
@ -927,11 +927,16 @@ uint _ma_get_binary_pack_key(register MARIA_KEYDEF *keyinfo, uint nod_flag,
|
|||
/*
|
||||
Keys are compressed the following way:
|
||||
|
||||
prefix length Packed length of prefix for the prev key. (1 or 3 bytes)
|
||||
prefix length Packed length of prefix common with prev key. (1 or 3 bytes)
|
||||
for each key segment:
|
||||
[is null] Null indicator if can be null (1 byte, zero means null)
|
||||
[length] Packed length if varlength (1 or 3 bytes)
|
||||
key segment 'length' bytes of key segment value
|
||||
pointer Reference to the data file (last_keyseg->length).
|
||||
|
||||
get_key_length() is a macro. It gets the prefix length from 'page'
|
||||
and puts it into 'length'. It increments 'page' by 1 or 3, depending
|
||||
on the packed length of the prefix length.
|
||||
*/
|
||||
get_key_length(length,page);
|
||||
if (length)
|
||||
|
|
@ -946,34 +951,44 @@ uint _ma_get_binary_pack_key(register MARIA_KEYDEF *keyinfo, uint nod_flag,
|
|||
my_errno=HA_ERR_CRASHED;
|
||||
DBUG_RETURN(0); /* Wrong key */
|
||||
}
|
||||
from=key; from_end=key+length;
|
||||
/* Key is packed against prev key, take prefix from prev key. */
|
||||
from= key;
|
||||
from_end= key + length;
|
||||
}
|
||||
else
|
||||
{
|
||||
from=page; from_end=page_end; /* Not packed key */
|
||||
/* Key is not packed against prev key, take all from page buffer. */
|
||||
from= page;
|
||||
from_end= page_end;
|
||||
}
|
||||
|
||||
/*
|
||||
The trouble is that key is split in two parts:
|
||||
The first part is in from ...from_end-1.
|
||||
The second part starts at page
|
||||
The trouble is that key can be split in two parts:
|
||||
The first part (prefix) is in from .. from_end - 1.
|
||||
The second part starts at page.
|
||||
The split can be at every byte position. So we need to check for
|
||||
the end of the first part before using every byte.
|
||||
*/
|
||||
for (keyseg=keyinfo->seg ; keyseg->type ;keyseg++)
|
||||
{
|
||||
if (keyseg->flag & HA_NULL_PART)
|
||||
{
|
||||
/* If prefix is used up, switch to rest. */
|
||||
if (from == from_end) { from=page; from_end=page_end; }
|
||||
if (!(*key++ = *from++))
|
||||
continue; /* Null part */
|
||||
}
|
||||
if (keyseg->flag & (HA_VAR_LENGTH_PART | HA_BLOB_PART | HA_SPACE_PACK))
|
||||
{
|
||||
/* Get length of dynamic length key part */
|
||||
/* If prefix is used up, switch to rest. */
|
||||
if (from == from_end) { from=page; from_end=page_end; }
|
||||
/* Get length of dynamic length key part */
|
||||
if ((length= (uint) (uchar) (*key++ = *from++)) == 255)
|
||||
{
|
||||
/* If prefix is used up, switch to rest. */
|
||||
if (from == from_end) { from=page; from_end=page_end; }
|
||||
length= ((uint) (uchar) ((*key++ = *from++))) << 8;
|
||||
/* If prefix is used up, switch to rest. */
|
||||
if (from == from_end) { from=page; from_end=page_end; }
|
||||
length+= (uint) (uchar) ((*key++ = *from++));
|
||||
}
|
||||
|
|
@ -994,14 +1009,26 @@ uint _ma_get_binary_pack_key(register MARIA_KEYDEF *keyinfo, uint nod_flag,
|
|||
key+=length;
|
||||
from+=length;
|
||||
}
|
||||
/*
|
||||
Last segment (type == 0) contains length of data pointer.
|
||||
If we have mixed key blocks with data pointer and key block pointer,
|
||||
we have to copy both.
|
||||
*/
|
||||
length=keyseg->length+nod_flag;
|
||||
if ((tmp=(uint) (from_end-from)) <= length)
|
||||
{
|
||||
/* Remaining length is less or equal max possible length. */
|
||||
memcpy(key+tmp,page,length-tmp); /* Get last part of key */
|
||||
*page_pos= page+length-tmp;
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
Remaining length is greater than max possible length.
|
||||
This can happen only if we switched to the new key bytes already.
|
||||
'page_end' is calculated with MI_MAX_KEY_BUFF. So it can be far
|
||||
behind the real end of the key.
|
||||
*/
|
||||
if (from_end != page_end)
|
||||
{
|
||||
DBUG_PRINT("error",("Error when unpacking key"));
|
||||
|
|
@ -1009,6 +1036,7 @@ uint _ma_get_binary_pack_key(register MARIA_KEYDEF *keyinfo, uint nod_flag,
|
|||
my_errno=HA_ERR_CRASHED;
|
||||
DBUG_RETURN(0); /* Error */
|
||||
}
|
||||
/* Copy data pointer and, if appropriate, key block pointer. */
|
||||
memcpy((uchar*) key,(uchar*) from,(size_t) length);
|
||||
*page_pos= from+length;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -138,8 +138,9 @@ int _ma_create_index_by_sort(MARIA_SORT_PARAM *info, my_bool no_messages,
|
|||
|
||||
while (memavl >= MIN_SORT_MEMORY)
|
||||
{
|
||||
if ((my_off_t) (records+1)*(sort_length+sizeof(char*)) <=
|
||||
(my_off_t) memavl)
|
||||
if ((records < UINT_MAX32) &&
|
||||
((my_off_t) (records + 1) *
|
||||
(sort_length + sizeof(char*)) <= (my_off_t) memavl))
|
||||
keys= records+1;
|
||||
else
|
||||
do
|
||||
|
|
@ -151,7 +152,7 @@ int _ma_create_index_by_sort(MARIA_SORT_PARAM *info, my_bool no_messages,
|
|||
keys < (uint) maxbuffer)
|
||||
{
|
||||
_ma_check_print_error(info->sort_info->param,
|
||||
"sort_buffer_size is to small");
|
||||
"maria_sort_buffer_size is too small");
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
|
@ -175,7 +176,8 @@ int _ma_create_index_by_sort(MARIA_SORT_PARAM *info, my_bool no_messages,
|
|||
}
|
||||
if (memavl < MIN_SORT_MEMORY)
|
||||
{
|
||||
_ma_check_print_error(info->sort_info->param,"Sort buffer to small"); /* purecov: tested */
|
||||
_ma_check_print_error(info->sort_info->param, "Maria sort buffer"
|
||||
" too small"); /* purecov: tested */
|
||||
goto err; /* purecov: tested */
|
||||
}
|
||||
(*info->lock_in_memory)(info->sort_info->param);/* Everything is allocated */
|
||||
|
|
@ -369,7 +371,7 @@ pthread_handler_t _ma_thr_find_all_keys(void *arg)
|
|||
keys < (uint) maxbuffer)
|
||||
{
|
||||
_ma_check_print_error(sort_param->sort_info->param,
|
||||
"sort_buffer_size is to small");
|
||||
"maria_sort_buffer_size is too small");
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
|
@ -397,7 +399,7 @@ pthread_handler_t _ma_thr_find_all_keys(void *arg)
|
|||
if (memavl < MIN_SORT_MEMORY)
|
||||
{
|
||||
_ma_check_print_error(sort_param->sort_info->param,
|
||||
"Sort buffer too small");
|
||||
"Maria sort buffer too small");
|
||||
goto err; /* purecov: tested */
|
||||
}
|
||||
|
||||
|
|
@ -775,7 +777,7 @@ static int NEAR_F merge_many_buff(MARIA_SORT_PARAM *info, uint keys,
|
|||
{
|
||||
if (merge_buffers(info,keys,from_file,to_file,sort_keys,lastbuff++,
|
||||
buffpek+i,buffpek+i+MERGEBUFF-1))
|
||||
break; /* purecov: inspected */
|
||||
goto cleanup;
|
||||
}
|
||||
if (merge_buffers(info,keys,from_file,to_file,sort_keys,lastbuff++,
|
||||
buffpek+i,buffpek+ *maxbuffer))
|
||||
|
|
@ -785,6 +787,7 @@ static int NEAR_F merge_many_buff(MARIA_SORT_PARAM *info, uint keys,
|
|||
temp=from_file; from_file=to_file; to_file=temp;
|
||||
*maxbuffer= (int) (lastbuff-buffpek)-1;
|
||||
}
|
||||
cleanup:
|
||||
close_cached_file(to_file); /* This holds old result */
|
||||
if (to_file == t_file)
|
||||
*t_file=t_file2; /* Copy result file */
|
||||
|
|
|
|||
|
|
@ -442,6 +442,7 @@ struct st_maria_info
|
|||
enum ha_rkey_function last_key_func; /* CONTAIN, OVERLAP, etc */
|
||||
uint save_lastkey_length;
|
||||
uint pack_key_length; /* For MARIAMRG */
|
||||
uint16 last_used_keyseg; /* For MARIAMRG */
|
||||
int errkey; /* Got last error on this key */
|
||||
int lock_type; /* How database was locked */
|
||||
int tmp_lock_type; /* When locked by readinfo */
|
||||
|
|
@ -749,7 +750,7 @@ extern my_off_t _ma_new(MARIA_HA *info, MARIA_KEYDEF *keyinfo, int level);
|
|||
extern uint _ma_make_key(MARIA_HA *info, uint keynr, uchar *key,
|
||||
const uchar *record, MARIA_RECORD_POS filepos);
|
||||
extern uint _ma_pack_key(MARIA_HA *info, uint keynr, uchar *key,
|
||||
const uchar *old, uint key_length,
|
||||
const uchar *old, key_part_map keypart_map,
|
||||
HA_KEYSEG ** last_used_keyseg);
|
||||
extern int _ma_read_key_record(MARIA_HA *info, uchar *buf, MARIA_RECORD_POS);
|
||||
extern int _ma_read_cache(IO_CACHE *info, uchar *buff, MARIA_RECORD_POS pos,
|
||||
|
|
@ -760,7 +761,7 @@ extern my_bool _ma_alloc_buffer(uchar **old_addr, size_t *old_size,
|
|||
size_t new_size);
|
||||
extern ulong _ma_rec_unpack(MARIA_HA *info, uchar *to, uchar *from,
|
||||
ulong reclength);
|
||||
extern my_bool _ma_rec_check(MARIA_HA *info, const char *record,
|
||||
extern my_bool _ma_rec_check(MARIA_HA *info, const uchar *record,
|
||||
uchar *packpos, ulong packed_length,
|
||||
my_bool with_checkum, ha_checksum checksum);
|
||||
extern int _ma_write_part_record(MARIA_HA *info, my_off_t filepos,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue