1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-30 16:24:05 +03:00

Merge 5.0.80 release and 5.0 community. Version left at 5.0.80.

This commit is contained in:
Chad MILLER
2009-04-14 13:20:13 -04:00
397 changed files with 11101 additions and 8316 deletions

View File

@ -78,7 +78,6 @@ static store_key *get_store_key(THD *thd,
KEYUSE *keyuse, table_map used_tables,
KEY_PART_INFO *key_part, char *key_buff,
uint maybe_null);
static bool make_simple_join(JOIN *join,TABLE *tmp_table);
static void make_outerjoin_info(JOIN *join);
static bool make_join_select(JOIN *join,SQL_SELECT *select,COND *item);
static void make_join_readinfo(JOIN *join, ulonglong options);
@ -100,7 +99,7 @@ static COND* substitute_for_best_equal_field(COND *cond,
void *table_join_idx);
static COND *simplify_joins(JOIN *join, List<TABLE_LIST> *join_list,
COND *conds, bool top);
static bool check_interleaving_with_nj(JOIN_TAB *last, JOIN_TAB *next);
static bool check_interleaving_with_nj(JOIN_TAB *next);
static void restore_prev_nj_state(JOIN_TAB *last);
static void reset_nj_counters(List<TABLE_LIST> *join_list);
static uint build_bitmap_for_nested_joins(List<TABLE_LIST> *join_list,
@ -1619,8 +1618,13 @@ JOIN::exec()
We have to test for 'conds' here as the WHERE may not be constant
even if we don't have any tables for prepared statements or if
conds uses something like 'rand()'.
If the HAVING clause is either impossible or always true, then
JOIN::having is set to NULL by optimize_cond.
In this case JOIN::exec must check for JOIN::having_value, in the
same way it checks for JOIN::cond_value.
*/
if (cond_value != Item::COND_FALSE &&
having_value != Item::COND_FALSE &&
(!conds || conds->val_int()) &&
(!having || having->val_int()))
{
@ -1815,7 +1819,7 @@ JOIN::exec()
/* Free first data from old join */
curr_join->join_free();
if (make_simple_join(curr_join, curr_tmp_table))
if (curr_join->make_simple_join(this, curr_tmp_table))
DBUG_VOID_RETURN;
calc_group_buffer(curr_join, group_list);
count_field_types(select_lex, &curr_join->tmp_table_param,
@ -1935,7 +1939,7 @@ JOIN::exec()
curr_join->select_distinct=0;
}
curr_tmp_table->reginfo.lock_type= TL_UNLOCK;
if (make_simple_join(curr_join, curr_tmp_table))
if (curr_join->make_simple_join(this, curr_tmp_table))
DBUG_VOID_RETURN;
calc_group_buffer(curr_join, curr_join->group_list);
count_field_types(select_lex, &curr_join->tmp_table_param,
@ -2381,11 +2385,12 @@ typedef struct st_sargable_param
*/
static bool
make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds,
make_join_statistics(JOIN *join, TABLE_LIST *tables_arg, COND *conds,
DYNAMIC_ARRAY *keyuse_array)
{
int error;
TABLE *table;
TABLE_LIST *tables= tables_arg;
uint i,table_count,const_count,key;
table_map found_const_table_map, all_table_map, found_ref, refs;
key_map const_ref, eq_part;
@ -2423,10 +2428,10 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds,
table_vector[i]=s->table=table=tables->table;
table->pos_in_table_list= tables;
error= table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
if(error)
if (error)
{
table->file->print_error(error, MYF(0));
DBUG_RETURN(1);
table->file->print_error(error, MYF(0));
goto error;
}
table->quick_keys.clear_all();
table->reginfo.join_tab=s;
@ -2511,7 +2516,7 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds,
{
join->tables=0; // Don't use join->table
my_message(ER_WRONG_OUTER_JOIN, ER(ER_WRONG_OUTER_JOIN), MYF(0));
DBUG_RETURN(1);
goto error;
}
s->key_dependent= s->dependent;
}
@ -2521,7 +2526,7 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds,
if (update_ref_and_keys(join->thd, keyuse_array, stat, join->tables,
conds, join->cond_equal,
~outer_join, join->select_lex, &sargables))
DBUG_RETURN(1);
goto error;
/* Read tables with 0 or 1 rows (system tables) */
join->const_table_map= 0;
@ -2537,7 +2542,7 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds,
if ((tmp=join_read_const_table(s, p_pos)))
{
if (tmp > 0)
DBUG_RETURN(1); // Fatal error
goto error; // Fatal error
}
else
found_const_table_map|= s->table->map;
@ -2609,7 +2614,7 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds,
if ((tmp= join_read_const_table(s, join->positions+const_count-1)))
{
if (tmp > 0)
DBUG_RETURN(1); // Fatal error
goto error; // Fatal error
}
else
found_const_table_map|= table->map;
@ -2658,12 +2663,12 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds,
set_position(join,const_count++,s,start_keyuse);
if (create_ref_for_key(join, s, start_keyuse,
found_const_table_map))
DBUG_RETURN(1);
goto error;
if ((tmp=join_read_const_table(s,
join->positions+const_count-1)))
{
if (tmp > 0)
DBUG_RETURN(1); // Fatal error
goto error; // Fatal error
}
else
found_const_table_map|= table->map;
@ -2740,7 +2745,7 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds,
*s->on_expr_ref ? *s->on_expr_ref : conds,
1, &error);
if (!select)
DBUG_RETURN(1);
goto error;
records= get_quick_record_count(join->thd, select, s->table,
&s->const_keys, join->row_limit);
s->quick=select->quick;
@ -2786,7 +2791,7 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds,
{
optimize_keyuse(join, keyuse_array);
if (choose_plan(join, all_table_map & ~join->const_table_map))
DBUG_RETURN(TRUE);
goto error;
}
else
{
@ -2796,6 +2801,17 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds,
}
/* Generate an execution plan from the found optimal join order. */
DBUG_RETURN(join->thd->killed || get_best_combination(join));
error:
/*
Need to clean up join_tab from TABLEs in case of error.
They won't get cleaned up by JOIN::cleanup() because JOIN::join_tab
may not be assigned yet by this function (which is building join_tab).
Dangling TABLE::reginfo.join_tab may cause part_of_refkey to choke.
*/
for (tables= tables_arg; tables; tables= tables->next_leaf)
tables->table->reginfo.join_tab= NULL;
DBUG_RETURN (1);
}
@ -4730,6 +4746,18 @@ greedy_search(JOIN *join,
*/
join->positions[idx]= best_pos;
/*
Update the interleaving state after extending the current partial plan
with a new table.
We are doing this here because best_extension_by_limited_search reverts
the interleaving state to the one of the non-extended partial plan
on exit.
*/
IF_DBUG(bool is_interleave_error= )
check_interleaving_with_nj (best_table);
/* This has been already checked by best_extension_by_limited_search */
DBUG_ASSERT(!is_interleave_error);
/* find the position of 'best_table' in 'join->best_ref' */
best_idx= idx;
JOIN_TAB *pos= join->best_ref[best_idx];
@ -4747,7 +4775,7 @@ greedy_search(JOIN *join,
--size_remain;
++idx;
DBUG_EXECUTE("opt", print_plan(join, join->tables,
DBUG_EXECUTE("opt", print_plan(join, idx,
record_count, read_time, read_time,
"extended"););
} while (TRUE);
@ -4898,7 +4926,7 @@ best_extension_by_limited_search(JOIN *join,
table_map real_table_bit= s->table->map;
if ((remaining_tables & real_table_bit) &&
!(remaining_tables & s->dependent) &&
(!idx || !check_interleaving_with_nj(join->positions[idx-1].table, s)))
(!idx || !check_interleaving_with_nj(s)))
{
double current_record_count, current_read_time;
@ -5043,7 +5071,7 @@ find_best(JOIN *join,table_map rest_tables,uint idx,double record_count,
{
table_map real_table_bit=s->table->map;
if ((rest_tables & real_table_bit) && !(rest_tables & s->dependent) &&
(!idx|| !check_interleaving_with_nj(join->positions[idx-1].table, s)))
(!idx|| !check_interleaving_with_nj(s)))
{
double records, best;
best_access_path(join, s, thd, rest_tables, idx, record_count,
@ -5426,48 +5454,42 @@ store_val_in_field(Field *field, Item *item, enum_check_fields check_flag)
}
static bool
make_simple_join(JOIN *join,TABLE *tmp_table)
/**
@details Initialize a JOIN as a query execution plan
that accesses a single table via a table scan.
@param parent contains JOIN_TAB and TABLE object buffers for this join
@param tmp_table temporary table
@retval FALSE success
@retval TRUE error occurred
*/
bool
JOIN::make_simple_join(JOIN *parent, TABLE *tmp_table)
{
TABLE **tableptr;
JOIN_TAB *join_tab;
DBUG_ENTER("make_simple_join");
DBUG_ENTER("JOIN::make_simple_join");
/*
Reuse TABLE * and JOIN_TAB if already allocated by a previous call
to this function through JOIN::exec (may happen for sub-queries).
*/
if (!join->table_reexec)
{
if (!(join->table_reexec= (TABLE**) join->thd->alloc(sizeof(TABLE*))))
DBUG_RETURN(TRUE); /* purecov: inspected */
if (join->tmp_join)
join->tmp_join->table_reexec= join->table_reexec;
}
if (!join->join_tab_reexec)
{
if (!(join->join_tab_reexec=
(JOIN_TAB*) join->thd->alloc(sizeof(JOIN_TAB))))
DBUG_RETURN(TRUE); /* purecov: inspected */
if (join->tmp_join)
join->tmp_join->join_tab_reexec= join->join_tab_reexec;
}
tableptr= join->table_reexec;
join_tab= join->join_tab_reexec;
if (!parent->join_tab_reexec &&
!(parent->join_tab_reexec= (JOIN_TAB*) thd->alloc(sizeof(JOIN_TAB))))
DBUG_RETURN(TRUE); /* purecov: inspected */
join->join_tab=join_tab;
join->table=tableptr; tableptr[0]=tmp_table;
join->tables=1;
join->const_tables=0;
join->const_table_map=0;
join->tmp_table_param.field_count= join->tmp_table_param.sum_func_count=
join->tmp_table_param.func_count=0;
join->tmp_table_param.copy_field=join->tmp_table_param.copy_field_end=0;
join->first_record=join->sort_and_group=0;
join->send_records=(ha_rows) 0;
join->group=0;
join->row_limit=join->unit->select_limit_cnt;
join->do_send_rows = (join->row_limit) ? 1 : 0;
join_tab= parent->join_tab_reexec;
table= &parent->table_reexec[0]; parent->table_reexec[0]= tmp_table;
tables= 1;
const_tables= 0;
const_table_map= 0;
tmp_table_param.field_count= tmp_table_param.sum_func_count=
tmp_table_param.func_count= 0;
tmp_table_param.copy_field= tmp_table_param.copy_field_end=0;
first_record= sort_and_group=0;
send_records= (ha_rows) 0;
group= 0;
row_limit= unit->select_limit_cnt;
do_send_rows= row_limit ? 1 : 0;
join_tab->cache.buff=0; /* No caching */
join_tab->table=tmp_table;
@ -5484,7 +5506,7 @@ make_simple_join(JOIN *join,TABLE *tmp_table)
join_tab->ref.key = -1;
join_tab->not_used_in_distinct=0;
join_tab->read_first_record= join_init_read_record;
join_tab->join=join;
join_tab->join= this;
join_tab->ref.key_parts= 0;
bzero((char*) &join_tab->read_record,sizeof(join_tab->read_record));
tmp_table->status=0;
@ -7607,7 +7629,7 @@ static int compare_fields_by_table_order(Item_field *field1,
if (outer_ref)
return cmp;
JOIN_TAB **idx= (JOIN_TAB **) table_join_idx;
cmp= idx[field2->field->table->tablenr]-idx[field1->field->table->tablenr];
cmp= (uint) (idx[field2->field->table->tablenr] - idx[field1->field->table->tablenr]);
return cmp < 0 ? -1 : (cmp ? 1 : 0);
}
@ -8415,9 +8437,6 @@ static void reset_nj_counters(List<TABLE_LIST> *join_list)
SYNOPSIS
check_interleaving_with_nj()
join Join being processed
last_tab Last table in current partial join order (this function is
not called for empty partial join orders)
next_tab Table we're going to extend the current partial join with
DESCRIPTION
@ -8502,10 +8521,10 @@ static void reset_nj_counters(List<TABLE_LIST> *join_list)
TRUE Requested join order extension not allowed.
*/
static bool check_interleaving_with_nj(JOIN_TAB *last_tab, JOIN_TAB *next_tab)
static bool check_interleaving_with_nj(JOIN_TAB *next_tab)
{
TABLE_LIST *next_emb= next_tab->table->pos_in_table_list->embedding;
JOIN *join= last_tab->join;
JOIN *join= next_tab->join;
if (join->cur_embedding_map & ~next_tab->embedding_map)
{
@ -9637,7 +9656,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
table->s->default_values= table->record[1]+alloc_length;
}
copy_func[0]=0; // End marker
param->func_count= copy_func - param->items_to_copy;
param->func_count= (uint) (copy_func - param->items_to_copy);
recinfo=param->start_recinfo;
null_flags=(uchar*) table->record[0];
@ -15210,10 +15229,10 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
item_list.push_back(new Item_int((int32)
join->select_lex->select_number));
item_list.push_back(new Item_string(join->select_lex->type,
strlen(join->select_lex->type), cs));
(uint) strlen(join->select_lex->type), cs));
for (uint i=0 ; i < 7; i++)
item_list.push_back(item_null);
item_list.push_back(new Item_string(message,strlen(message),cs));
item_list.push_back(new Item_string(message,(uint) strlen(message),cs));
if (result->send_data(item_list))
join->error= 1;
}
@ -15232,7 +15251,7 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
item_list.push_back(new Item_null);
/* select_type */
item_list.push_back(new Item_string(join->select_lex->type,
strlen(join->select_lex->type),
(uint) strlen(join->select_lex->type),
cs));
/* table */
{
@ -15259,7 +15278,7 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
}
/* type */
item_list.push_back(new Item_string(join_type_str[JT_ALL],
strlen(join_type_str[JT_ALL]),
(uint) strlen(join_type_str[JT_ALL]),
cs));
/* possible_keys */
item_list.push_back(item_null);
@ -15308,7 +15327,7 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
join->select_lex->select_number));
/* select_type */
item_list.push_back(new Item_string(join->select_lex->type,
strlen(join->select_lex->type),
(uint) strlen(join->select_lex->type),
cs));
if (tab->type == JT_ALL && tab->select && tab->select->quick)
{
@ -15333,12 +15352,12 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
{
TABLE_LIST *real_table= table->pos_in_table_list;
item_list.push_back(new Item_string(real_table->alias,
strlen(real_table->alias),
(uint) strlen(real_table->alias),
cs));
}
/* type */
item_list.push_back(new Item_string(join_type_str[tab->type],
strlen(join_type_str[tab->type]),
(uint) strlen(join_type_str[tab->type]),
cs));
/* Build "possible_keys" value and add it to item_list */
if (!tab->keys.is_clear_all())
@ -15351,7 +15370,7 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
if (tmp1.length())
tmp1.append(',');
tmp1.append(table->key_info[j].name,
strlen(table->key_info[j].name),
(uint) strlen(table->key_info[j].name),
system_charset_info);
}
}
@ -15367,17 +15386,17 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
KEY *key_info=table->key_info+ tab->ref.key;
register uint length;
item_list.push_back(new Item_string(key_info->name,
strlen(key_info->name),
(uint) strlen(key_info->name),
system_charset_info));
length= longlong2str(tab->ref.key_length, keylen_str_buf, 10) -
keylen_str_buf;
length= (uint) (longlong2str(tab->ref.key_length, keylen_str_buf, 10) -
keylen_str_buf);
item_list.push_back(new Item_string(keylen_str_buf, length,
system_charset_info));
for (store_key **ref=tab->ref.key_copy ; *ref ; ref++)
{
if (tmp2.length())
tmp2.append(',');
tmp2.append((*ref)->name(), strlen((*ref)->name()),
tmp2.append((*ref)->name(), (uint) strlen((*ref)->name()),
system_charset_info);
}
item_list.push_back(new Item_string(tmp2.ptr(),tmp2.length(),cs));
@ -15387,9 +15406,9 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
KEY *key_info=table->key_info+ tab->index;
register uint length;
item_list.push_back(new Item_string(key_info->name,
strlen(key_info->name),cs));
length= longlong2str(key_info->key_length, keylen_str_buf, 10) -
keylen_str_buf;
(uint) strlen(key_info->name),cs));
length= (uint) (longlong2str(key_info->key_length, keylen_str_buf, 10) -
keylen_str_buf);
item_list.push_back(new Item_string(keylen_str_buf,
length,
system_charset_info));
@ -15422,7 +15441,7 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
key_read=1;
if (tab->info)
item_list.push_back(new Item_string(tab->info,strlen(tab->info),cs));
item_list.push_back(new Item_string(tab->info,(uint) strlen(tab->info),cs));
else if (tab->packed_info & TAB_INFO_HAVE_VALUE)
{
if (tab->packed_info & TAB_INFO_USING_INDEX)
@ -15746,7 +15765,7 @@ void TABLE_LIST::print(THD *thd, String *str)
if (schema_table)
{
append_identifier(thd, str, schema_table_name,
strlen(schema_table_name));
(uint) strlen(schema_table_name));
cmp_name= schema_table_name;
}
else
@ -15771,7 +15790,7 @@ void TABLE_LIST::print(THD *thd, String *str)
}
}
append_identifier(thd, str, t_alias, strlen(t_alias));
append_identifier(thd, str, t_alias, (uint) strlen(t_alias));
}
if (use_index)