1
0
mirror of https://github.com/MariaDB/server.git synced 2026-01-06 05:22:24 +03:00

Merge of 5.1-main into 5.1-maria. There were no changes to storage/myisam, mysys/mf_keycache.c, mysql-test/t/*myisam*

since previous merge. MARIA_PAGECACHE_READS in maria-preload.test are down a little bit (5%), which must be a good
side-effect of some sql/ change.
This commit is contained in:
Guilhem Bichot
2008-12-10 10:02:25 +01:00
608 changed files with 210523 additions and 6061 deletions

View File

@@ -31,11 +31,16 @@
#include "mysql_priv.h"
#include "sql_select.h"
#include "sql_cursor.h"
#include <m_ctype.h>
#include <my_bit.h>
#include <hash.h>
#include <ft_global.h>
#if defined(WITH_MARIA_STORAGE_ENGINE) && defined(USE_MARIA_FOR_TMP_TABLES)
#include "../storage/maria/ha_maria.h"
#define TMP_ENGINE_HTON maria_hton
#else
#define TMP_ENGINE_HTON myisam_hton
#endif
const char *join_type_str[]={ "UNKNOWN","system","const","eq_ref","ref",
"MAYBE_REF","ALL","range","index","fulltext",
@@ -120,8 +125,13 @@ static COND *optimize_cond(JOIN *join, COND *conds,
Item::cond_result *cond_value);
static bool const_expression_in_where(COND *conds,Item *item, Item **comp_item);
static bool open_tmp_table(TABLE *table);
static bool create_myisam_tmp_table(TABLE *table,TMP_TABLE_PARAM *param,
ulonglong options);
static bool create_internal_tmp_table(TABLE *,TMP_TABLE_PARAM *, ulonglong);
static bool create_internal_tmp_table_from_heap2(THD *thd, TABLE *table,
TMP_TABLE_PARAM *param,
int error,
bool ignore_last_dupp,
handlerton *hton,
const char *proc_info);
static int do_select(JOIN *join,List<Item> *fields,TABLE *tmp_table,
Procedure *proc);
@@ -1800,7 +1810,10 @@ JOIN::exec()
curr_join->having= curr_join->tmp_having= 0; // Allready done
/* Change sum_fields reference to calculated fields in tmp_table */
curr_join->all_fields= *curr_all_fields;
#ifdef HAVE_purify
if (curr_join != this)
#endif
curr_join->all_fields= *curr_all_fields;
if (!items1)
{
items1= items0 + all_fields.elements;
@@ -1819,8 +1832,13 @@ JOIN::exec()
fields_list.elements, all_fields))
DBUG_VOID_RETURN;
}
curr_join->tmp_all_fields1= tmp_all_fields1;
curr_join->tmp_fields_list1= tmp_fields_list1;
#ifdef HAVE_purify
if (curr_join != this)
#endif
{
curr_join->tmp_all_fields1= tmp_all_fields1;
curr_join->tmp_fields_list1= tmp_fields_list1;
}
curr_join->items1= items1;
}
curr_all_fields= &tmp_all_fields1;
@@ -2024,8 +2042,13 @@ JOIN::exec()
tmp_table_param.save_copy_field= curr_join->tmp_table_param.copy_field;
tmp_table_param.save_copy_field_end=
curr_join->tmp_table_param.copy_field_end;
curr_join->tmp_all_fields3= tmp_all_fields3;
curr_join->tmp_fields_list3= tmp_fields_list3;
#ifdef HAVE_purify
if (curr_join != this)
#endif
{
curr_join->tmp_all_fields3= tmp_all_fields3;
curr_join->tmp_fields_list3= tmp_fields_list3;
}
}
else
{
@@ -3534,16 +3557,16 @@ add_ft_keys(DYNAMIC_ARRAY *keyuse_array,
Item_func *arg0=(Item_func *)(func->arguments()[0]),
*arg1=(Item_func *)(func->arguments()[1]);
if (arg1->const_item() &&
((functype == Item_func::GE_FUNC && arg1->val_real() > 0) ||
(functype == Item_func::GT_FUNC && arg1->val_real() >=0)) &&
arg0->type() == Item::FUNC_ITEM &&
arg0->functype() == Item_func::FT_FUNC)
arg0->functype() == Item_func::FT_FUNC &&
((functype == Item_func::GE_FUNC && arg1->val_real() > 0) ||
(functype == Item_func::GT_FUNC && arg1->val_real() >=0)))
cond_func=(Item_func_match *) arg0;
else if (arg0->const_item() &&
((functype == Item_func::LE_FUNC && arg0->val_real() > 0) ||
(functype == Item_func::LT_FUNC && arg0->val_real() >=0)) &&
arg1->type() == Item::FUNC_ITEM &&
arg1->functype() == Item_func::FT_FUNC)
arg1->functype() == Item_func::FT_FUNC &&
((functype == Item_func::LE_FUNC && arg0->val_real() > 0) ||
(functype == Item_func::LT_FUNC && arg0->val_real() >=0)))
cond_func=(Item_func_match *) arg1;
}
}
@@ -9648,7 +9671,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
KEY *keyinfo;
KEY_PART_INFO *key_part_info;
Item **copy_func;
MI_COLUMNDEF *recinfo;
ENGINE_COLUMNDEF *recinfo;
uint total_uneven_bit_length= 0;
bool force_copy_fields= param->force_copy_fields;
/* Treat sum functions as normal ones when loose index scan is used. */
@@ -9676,11 +9699,10 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
/*
No need to change table name to lower case as we are only creating
MyISAM or HEAP tables here
MyISAM, Maria or HEAP tables here
*/
fn_format(path, path, mysql_tmpdir, "", MY_REPLACE_EXT|MY_UNPACK_FILENAME);
if (group)
{
if (!param->quick_group)
@@ -9772,7 +9794,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
init_tmp_table_share(thd, share, "", 0, tmpname, tmpname);
share->blob_field= blob_field;
share->blob_ptr_size= portable_sizeof_char_ptr;
share->db_low_byte_first=1; // True for HEAP and MyISAM
share->db_low_byte_first=1; // True for HEAP, MyISAM and Maria
share->table_charset= param->table_charset;
share->primary_key= MAX_KEY; // Indicate no primary key
share->keys_for_keyread.init();
@@ -9904,6 +9926,12 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
*blob_field++= fieldnr;
blob_count++;
}
if (new_field->real_type() == MYSQL_TYPE_STRING ||
new_field->real_type() == MYSQL_TYPE_VARCHAR)
{
string_count++;
string_total_length+= new_field->pack_length();
}
if (item->marker == 4 && item->maybe_null)
{
group_null_items++;
@@ -9940,7 +9968,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
(select_options & (OPTION_BIG_TABLES | SELECT_SMALL_RESULT)) ==
OPTION_BIG_TABLES || (select_options & TMP_TABLE_FORCE_MYISAM))
{
share->db_plugin= ha_lock_engine(0, myisam_hton);
share->db_plugin= ha_lock_engine(0, TMP_ENGINE_HTON);
table->file= get_new_handler(share, &table->mem_root,
share->db_type());
if (group &&
@@ -9957,7 +9985,6 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
if (!table->file)
goto err;
if (!using_unique_constraint)
reclength+= group_null_items; // null flag is stored separately
@@ -10093,13 +10120,16 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
/* Make entry for create table */
recinfo->length=length;
if (field->flags & BLOB_FLAG)
recinfo->type= (int) FIELD_BLOB;
recinfo->type= FIELD_BLOB;
else if (use_packed_rows &&
field->real_type() == MYSQL_TYPE_STRING &&
length >= MIN_STRING_LENGTH_TO_PACK_ROWS)
recinfo->type=FIELD_SKIP_ENDSPACE;
recinfo->type= FIELD_SKIP_ENDSPACE;
else if (field->real_type() == MYSQL_TYPE_VARCHAR)
recinfo->type= FIELD_VARCHAR;
else
recinfo->type=FIELD_NORMAL;
recinfo->type= FIELD_NORMAL;
if (!--hidden_field_count)
null_count=(null_count+7) & ~7; // move to next byte
@@ -10262,9 +10292,9 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
if (thd->is_fatal_error) // If end of memory
goto err; /* purecov: inspected */
share->db_record_offset= 1;
if (share->db_type() == myisam_hton)
if (share->db_type() == TMP_ENGINE_HTON)
{
if (create_myisam_tmp_table(table,param,select_options))
if (create_internal_tmp_table(table,param,select_options))
goto err;
}
if (open_tmp_table(table))
@@ -10426,15 +10456,149 @@ static bool open_tmp_table(TABLE *table)
}
static bool create_myisam_tmp_table(TABLE *table,TMP_TABLE_PARAM *param,
ulonglong options)
#if defined(WITH_MARIA_STORAGE_ENGINE) && defined(USE_MARIA_FOR_TMP_TABLES)
/* Create internal Maria temporary table */
static bool create_internal_tmp_table(TABLE *table,TMP_TABLE_PARAM *param,
ulonglong options)
{
int error;
MARIA_KEYDEF keydef;
MARIA_UNIQUEDEF uniquedef;
KEY *keyinfo=param->keyinfo;
TABLE_SHARE *share= table->s;
MARIA_CREATE_INFO create_info;
DBUG_ENTER("create_internal_tmp_table");
if (share->keys)
{ // Get keys for ni_create
bool using_unique_constraint=0;
HA_KEYSEG *seg= (HA_KEYSEG*) alloc_root(&table->mem_root,
sizeof(*seg) * keyinfo->key_parts);
if (!seg)
goto err;
bzero(seg, sizeof(*seg) * keyinfo->key_parts);
if (keyinfo->key_length >= table->file->max_key_length() ||
keyinfo->key_parts > table->file->max_key_parts() ||
share->uniques)
{
/* Can't create a key; Make a unique constraint instead of a key */
share->keys= 0;
share->uniques= 1;
using_unique_constraint=1;
bzero((char*) &uniquedef,sizeof(uniquedef));
uniquedef.keysegs=keyinfo->key_parts;
uniquedef.seg=seg;
uniquedef.null_are_equal=1;
/* Create extra column for hash value */
bzero((uchar*) param->recinfo,sizeof(*param->recinfo));
param->recinfo->type= FIELD_CHECK;
param->recinfo->length= MARIA_UNIQUE_HASH_LENGTH;
param->recinfo++;
share->reclength+= MARIA_UNIQUE_HASH_LENGTH;
}
else
{
/* Create an unique key */
bzero((char*) &keydef,sizeof(keydef));
keydef.flag=HA_NOSAME | HA_BINARY_PACK_KEY | HA_PACK_KEY;
keydef.keysegs= keyinfo->key_parts;
keydef.seg= seg;
}
for (uint i=0; i < keyinfo->key_parts ; i++,seg++)
{
Field *field=keyinfo->key_part[i].field;
seg->flag= 0;
seg->language= field->charset()->number;
seg->length= keyinfo->key_part[i].length;
seg->start= keyinfo->key_part[i].offset;
if (field->flags & BLOB_FLAG)
{
seg->type=
((keyinfo->key_part[i].key_type & FIELDFLAG_BINARY) ?
HA_KEYTYPE_VARBINARY2 : HA_KEYTYPE_VARTEXT2);
seg->bit_start= (uint8)(field->pack_length() - share->blob_ptr_size);
seg->flag= HA_BLOB_PART;
seg->length=0; // Whole blob in unique constraint
}
else
{
seg->type= keyinfo->key_part[i].type;
/* Tell handler if it can do suffic space compression */
if (field->real_type() == MYSQL_TYPE_STRING &&
keyinfo->key_part[i].length > 4)
seg->flag|= HA_SPACE_PACK;
}
if (!(field->flags & NOT_NULL_FLAG))
{
seg->null_bit= field->null_bit;
seg->null_pos= (uint) (field->null_ptr - (uchar*) table->record[0]);
/*
We are using a GROUP BY on something that contains NULL
In this case we have to tell Maria that two NULL should
on INSERT be regarded at the same value
*/
if (!using_unique_constraint)
keydef.flag|= HA_NULL_ARE_EQUAL;
}
}
}
bzero((char*) &create_info,sizeof(create_info));
if ((options & (OPTION_BIG_TABLES | SELECT_SMALL_RESULT)) ==
OPTION_BIG_TABLES)
create_info.data_file_length= ~(ulonglong) 0;
if ((error= maria_create(share->table_name.str,
share->reclength < 64 &&
!share->blob_fields ? STATIC_RECORD :
BLOCK_RECORD,
share->keys, &keydef,
(uint) (param->recinfo-param->start_recinfo),
param->start_recinfo,
share->uniques, &uniquedef,
&create_info,
HA_CREATE_TMP_TABLE)))
{
table->file->print_error(error,MYF(0)); /* purecov: inspected */
table->db_stat=0;
goto err;
}
status_var_increment(table->in_use->status_var.created_tmp_disk_tables);
share->db_record_offset= 1;
DBUG_RETURN(0);
err:
DBUG_RETURN(1);
}
bool create_internal_tmp_table_from_heap(THD *thd, TABLE *table,
TMP_TABLE_PARAM *param,
int error,
bool ignore_last_dupp_key_error)
{
return create_internal_tmp_table_from_heap2(thd, table, param, error,
ignore_last_dupp_key_error,
maria_hton,
"converting HEAP to Maria");
}
#else
/* Create internal MyISAM temporary table */
static bool create_internal_tmp_table(TABLE *table,TMP_TABLE_PARAM *param,
ulonglong options)
{
int error;
MI_KEYDEF keydef;
MI_UNIQUEDEF uniquedef;
KEY *keyinfo=param->keyinfo;
TABLE_SHARE *share= table->s;
DBUG_ENTER("create_myisam_tmp_table");
DBUG_ENTER("create_internal_tmp_table");
if (share->keys)
{ // Get keys for ni_create
@@ -10537,55 +10701,43 @@ static bool create_myisam_tmp_table(TABLE *table,TMP_TABLE_PARAM *param,
}
void
free_tmp_table(THD *thd, TABLE *entry)
{
MEM_ROOT own_root= entry->mem_root;
const char *save_proc_info;
DBUG_ENTER("free_tmp_table");
DBUG_PRINT("enter",("table: %s",entry->alias));
save_proc_info=thd->proc_info;
thd_proc_info(thd, "removing tmp table");
if (entry->file)
{
if (entry->db_stat)
entry->file->ha_drop_table(entry->s->table_name.str);
else
entry->file->ha_delete_table(entry->s->table_name.str);
delete entry->file;
}
/* free blobs */
for (Field **ptr=entry->field ; *ptr ; ptr++)
(*ptr)->free();
free_io_cache(entry);
if (entry->temp_pool_slot != MY_BIT_NONE)
bitmap_lock_clear_bit(&temp_pool, entry->temp_pool_slot);
plugin_unlock(0, entry->s->db_plugin);
free_root(&own_root, MYF(0)); /* the table is allocated in its own root */
thd_proc_info(thd, save_proc_info);
DBUG_VOID_RETURN;
}
/**
If a HEAP table gets full, create a MyISAM table and copy all rows
to this.
If a HEAP table gets full, create a MyISAM table and copy all rows to this
*/
bool create_myisam_from_heap(THD *thd, TABLE *table, TMP_TABLE_PARAM *param,
int error, bool ignore_last_dupp_key_error)
bool create_internal_tmp_table_from_heap(THD *thd, TABLE *table,
TMP_TABLE_PARAM *param,
int error,
bool ignore_last_dupp_key_error)
{
return create_internal_tmp_table_from_heap2(thd, table, param, error,
ignore_last_dupp_key_error,
myisam_hton,
"converting HEAP to MyISAM");
}
#endif /* WITH_MARIA_STORAGE_ENGINE */
/*
If a HEAP table gets full, create a internal table in MyISAM or Maria
and copy all rows to this
*/
static bool
create_internal_tmp_table_from_heap2(THD *thd, TABLE *table,
TMP_TABLE_PARAM *param,
int error,
bool ignore_last_dupp_key_error,
handlerton *hton,
const char *proc_info)
{
TABLE new_table;
TABLE_SHARE share;
const char *save_proc_info;
int write_err;
DBUG_ENTER("create_myisam_from_heap");
DBUG_ENTER("create_internal_tmp_table_from_heap2");
if (table->s->db_type() != heap_hton ||
error != HA_ERR_RECORD_FILE_FULL)
@@ -10596,15 +10748,15 @@ bool create_myisam_from_heap(THD *thd, TABLE *table, TMP_TABLE_PARAM *param,
new_table= *table;
share= *table->s;
new_table.s= &share;
new_table.s->db_plugin= ha_lock_engine(thd, myisam_hton);
new_table.s->db_plugin= ha_lock_engine(thd, hton);
if (!(new_table.file= get_new_handler(&share, &new_table.mem_root,
new_table.s->db_type())))
DBUG_RETURN(1); // End of memory
save_proc_info=thd->proc_info;
thd_proc_info(thd, "converting HEAP to MyISAM");
thd_proc_info(thd, proc_info);
if (create_myisam_tmp_table(&new_table, param,
if (create_internal_tmp_table(&new_table, param,
thd->lex->select_lex.options | thd->options))
goto err2;
if (open_tmp_table(&new_table))
@@ -10667,7 +10819,7 @@ bool create_myisam_from_heap(THD *thd, TABLE *table, TMP_TABLE_PARAM *param,
table->use_all_columns();
if (save_proc_info)
thd_proc_info(thd, (!strcmp(save_proc_info,"Copying to tmp table") ?
"Copying to tmp table on disk" : save_proc_info));
"Copying to tmp table on disk" : save_proc_info));
DBUG_RETURN(0);
err:
@@ -10685,6 +10837,43 @@ bool create_myisam_from_heap(THD *thd, TABLE *table, TMP_TABLE_PARAM *param,
}
void
free_tmp_table(THD *thd, TABLE *entry)
{
MEM_ROOT own_root= entry->mem_root;
const char *save_proc_info;
DBUG_ENTER("free_tmp_table");
DBUG_PRINT("enter",("table: %s",entry->alias));
save_proc_info=thd->proc_info;
thd_proc_info(thd, "removing tmp table");
if (entry->file)
{
if (entry->db_stat)
entry->file->ha_drop_table(entry->s->table_name.str);
else
entry->file->ha_delete_table(entry->s->table_name.str);
delete entry->file;
}
/* free blobs */
for (Field **ptr=entry->field ; *ptr ; ptr++)
(*ptr)->free();
free_io_cache(entry);
if (entry->temp_pool_slot != MY_BIT_NONE)
bitmap_lock_clear_bit(&temp_pool, entry->temp_pool_slot);
plugin_unlock(0, entry->s->db_plugin);
free_root(&own_root, MYF(0)); /* the table is allocated in its own root */
thd_proc_info(thd, save_proc_info);
DBUG_VOID_RETURN;
}
/**
@details
Rows produced by a join sweep may end up in a temporary table or be sent
@@ -12143,7 +12332,7 @@ end_write(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
{
if (!table->file->is_fatal_error(error, HA_CHECK_DUP))
goto end;
if (create_myisam_from_heap(join->thd, table, &join->tmp_table_param,
if (create_internal_tmp_table_from_heap(join->thd, table, &join->tmp_table_param,
error,1))
DBUG_RETURN(NESTED_LOOP_ERROR); // Not a table_is_full error
table->s->uniques=0; // To ensure rows are the same
@@ -12227,7 +12416,7 @@ end_update(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
copy_funcs(join->tmp_table_param.items_to_copy);
if ((error=table->file->ha_write_row(table->record[0])))
{
if (create_myisam_from_heap(join->thd, table, &join->tmp_table_param,
if (create_internal_tmp_table_from_heap(join->thd, table, &join->tmp_table_param,
error, 0))
DBUG_RETURN(NESTED_LOOP_ERROR); // Not a table_is_full error
/* Change method to update rows */
@@ -12322,7 +12511,7 @@ end_write_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
if (!join->having || join->having->val_int())
{
int error= table->file->ha_write_row(table->record[0]);
if (error && create_myisam_from_heap(join->thd, table,
if (error && create_internal_tmp_table_from_heap(join->thd, table,
&join->tmp_table_param,
error, 0))
DBUG_RETURN(NESTED_LOOP_ERROR);
@@ -13638,13 +13827,14 @@ static int remove_dup_with_compare(THD *thd, TABLE *table, Field **first_field,
else if (!found)
{
found=1;
file->position(record); // Remember position
if ((error= file->remember_rnd_pos()))
goto err;
}
}
if (!found)
break; // End of file
/* Restart search on next row */
error=file->restart_rnd_next(record,file->ref);
/* Restart search on saved row */
error=file->restart_rnd_next(record);
}
file->extra(HA_EXTRA_NO_CACHE);
@@ -15783,7 +15973,7 @@ int JOIN::rollup_write_data(uint idx, TABLE *table_arg)
copy_sum_funcs(sum_funcs_end[i+1], sum_funcs_end[i]);
if ((write_error= table_arg->file->ha_write_row(table_arg->record[0])))
{
if (create_myisam_from_heap(thd, table_arg, &tmp_table_param,
if (create_internal_tmp_table_from_heap(thd, table_arg, &tmp_table_param,
write_error, 0))
return 1;
}