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

Merge with MariaDB 5.1.49

Removed references to HA_END_SPACE_KEY (which has been 0 for a long time)
This commit is contained in:
Michael Widenius
2010-08-05 22:56:11 +03:00
820 changed files with 37170 additions and 19216 deletions

View File

@@ -266,15 +266,15 @@ bool handle_select(THD *thd, LEX *lex, select_result *result,
setup_tables_done_option changed for next rexecution
*/
res= mysql_select(thd, &select_lex->ref_pointer_array,
(TABLE_LIST*) select_lex->table_list.first,
select_lex->table_list.first,
select_lex->with_wild, select_lex->item_list,
select_lex->where,
select_lex->order_list.elements +
select_lex->group_list.elements,
(ORDER*) select_lex->order_list.first,
(ORDER*) select_lex->group_list.first,
select_lex->order_list.first,
select_lex->group_list.first,
select_lex->having,
(ORDER*) lex->proc_list.first,
lex->proc_list.first,
select_lex->options | thd->options |
setup_tables_done_option,
result, unit, select_lex);
@@ -574,13 +574,21 @@ JOIN::prepare(Item ***rref_pointer_array,
{
Item *item= *ord->item;
/*
Disregard sort order if there's only "{VAR}CHAR(0) NOT NULL" fields
there. Such fields don't contain any data to sort.
Disregard sort order if there's only
zero length NOT NULL fields (e.g. {VAR}CHAR(0) NOT NULL") or
zero length NOT NULL string functions there.
Such tuples don't contain any data to sort.
*/
if (!real_order &&
(item->type() != Item::FIELD_ITEM ||
((Item_field *) item)->field->maybe_null() ||
((Item_field *) item)->field->sort_length()))
/* Not a zero length NOT NULL field */
((item->type() != Item::FIELD_ITEM ||
((Item_field *) item)->field->maybe_null() ||
((Item_field *) item)->field->sort_length()) &&
/* AND not a zero length NOT NULL string function. */
(item->type() != Item::FUNC_ITEM ||
item->maybe_null ||
item->result_type() != STRING_RESULT ||
item->max_length)))
real_order= TRUE;
if (item->with_sum_func && item->type() != Item::SUM_FUNC_ITEM)
@@ -2717,15 +2725,29 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables_arg, COND *conds,
as well as allow us to catch illegal cross references/
Warshall's algorithm is used to build the transitive closure.
As we use bitmaps to represent the relation the complexity
of the algorithm is O((number of tables)^2).
of the algorithm is O((number of tables)^2).
The classic form of the Warshall's algorithm would look like:
for (i= 0; i < table_count; i++)
{
for (j= 0; j < table_count; j++)
{
for (k= 0; k < table_count; k++)
{
if (bitmap_is_set(stat[j].dependent, i) &&
bitmap_is_set(stat[i].dependent, k))
bitmap_set_bit(stat[j].dependent, k);
}
}
*/
for (i= 0, s= stat ; i < table_count ; i++, s++)
for (s= stat ; s < stat_end ; s++)
{
for (uint j= 0 ; j < table_count ; j++)
table= s->table;
for (JOIN_TAB *t= stat ; t < stat_end ; t++)
{
table= stat[j].table;
if (s->dependent & table->map)
s->dependent |= table->reginfo.join_tab->dependent;
if (t->dependent & table->map)
t->dependent |= table->reginfo.join_tab->dependent;
}
if (outer_join & s->table->map)
s->table->maybe_null= 1;
@@ -2881,8 +2903,7 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables_arg, COND *conds,
!table->fulltext_searched &&
!table->pos_in_table_list->embedding)
{
if ((table->key_info[key].flags & (HA_NOSAME | HA_END_SPACE_KEY))
== HA_NOSAME)
if (table->key_info[key].flags & HA_NOSAME)
{
if (const_ref == eq_part)
{ // Found everything for ref.
@@ -5836,8 +5857,7 @@ static bool create_ref_for_key(JOIN *join, JOIN_TAB *j, KEYUSE *org_keyuse,
DBUG_RETURN(0);
if (j->type == JT_CONST)
j->table->const_table= 1;
else if (((keyinfo->flags & (HA_NOSAME | HA_NULL_PART_KEY |
HA_END_SPACE_KEY)) != HA_NOSAME) ||
else if (((keyinfo->flags & (HA_NOSAME | HA_NULL_PART_KEY)) != HA_NOSAME) ||
keyparts != keyinfo->key_parts || null_ref_key)
{
/* Must read with repeat */
@@ -7279,7 +7299,8 @@ remove_const(JOIN *join,ORDER *first_order, COND *cond,
*simple_order=0; // Must do a temp table to sort
else if (!(order_tables & not_const_tables))
{
if (order->item[0]->with_subselect)
if (order->item[0]->with_subselect &&
!(join->select_lex->options & SELECT_DESCRIBE))
order->item[0]->val_str(&order->item[0]->str_value);
DBUG_PRINT("info",("removing: %s", order->item[0]->full_name()));
continue; // skip const item
@@ -8784,6 +8805,7 @@ simplify_joins(JOIN *join, List<TABLE_LIST> *join_list, COND *conds, bool top)
NESTED_JOIN *nested_join;
TABLE_LIST *prev_table= 0;
List_iterator<TABLE_LIST> li(*join_list);
bool straight_join= test(join->select_options & SELECT_STRAIGHT_JOIN);
DBUG_ENTER("simplify_joins");
/*
@@ -8896,7 +8918,7 @@ simplify_joins(JOIN *join, List<TABLE_LIST> *join_list, COND *conds, bool top)
if (prev_table)
{
/* The order of tables is reverse: prev_table follows table */
if (prev_table->straight)
if (prev_table->straight || straight_join)
prev_table->dep_tables|= used_tables;
if (prev_table->on_expr)
{
@@ -9178,6 +9200,46 @@ static bool check_interleaving_with_nj(JOIN_TAB *next_tab)
/**
Nested joins perspective: Remove the last table from the join order.
The algorithm is the reciprocal of check_interleaving_with_nj(), hence
parent join nest nodes are updated only when the last table in its child
node is removed. The ASCII graphic below will clarify.
%A table nesting such as <tt> t1 x [ ( t2 x t3 ) x ( t4 x t5 ) ] </tt>is
represented by the below join nest tree.
@verbatim
NJ1
_/ / \
_/ / NJ2
_/ / / \
/ / / \
t1 x [ (t2 x t3) x (t4 x t5) ]
@endverbatim
At the point in time when check_interleaving_with_nj() adds the table t5 to
the query execution plan, QEP, it also directs the node named NJ2 to mark
the table as covered. NJ2 does so by incrementing its @c counter
member. Since all of NJ2's tables are now covered by the QEP, the algorithm
proceeds up the tree to NJ1, incrementing its counter as well. All join
nests are now completely covered by the QEP.
restore_prev_nj_state() does the above in reverse. As seen above, the node
NJ1 contains the nodes t2, t3, and NJ2. Its counter being equal to 3 means
that the plan covers t2, t3, and NJ2, @e and that the sub-plan (t4 x t5)
completely covers NJ2. The removal of t5 from the partial plan will first
decrement NJ2's counter to 1. It will then detect that NJ2 went from being
completely to partially covered, and hence the algorithm must continue
upwards to NJ1 and decrement its counter to 2. %A subsequent removal of t4
will however not influence NJ1 since it did not un-cover the last table in
NJ2.
SYNOPSIS
restore_prev_nj_state()
last join table to remove, it is assumed to be the last in current
partial join order.
DESCRIPTION
Remove the last table from the partial join order and update the nested
joins counters and join->cur_embedding_map. It is ok to call this
function for the first table in join order (for which
@@ -9191,19 +9253,20 @@ static void restore_prev_nj_state(JOIN_TAB *last)
{
TABLE_LIST *last_emb= last->table->pos_in_table_list->embedding;
JOIN *join= last->join;
while (last_emb)
for (;last_emb != NULL; last_emb= last_emb->embedding)
{
if (!(--last_emb->nested_join->counter))
join->cur_embedding_map&= ~last_emb->nested_join->nj_map;
else if (last_emb->nested_join->n_tables-1 ==
last_emb->nested_join->counter)
{
join->cur_embedding_map|= last_emb->nested_join->nj_map;
NESTED_JOIN *nest= last_emb->nested_join;
DBUG_ASSERT(nest->counter > 0);
bool was_fully_covered= nest->is_fully_covered();
if (--nest->counter == 0)
join->cur_embedding_map&= ~nest->nj_map;
if (!was_fully_covered)
break;
}
else
break;
last_emb= last_emb->embedding;
join->cur_embedding_map|= nest->nj_map;
}
}
@@ -10337,7 +10400,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
table->null_flags= (uchar*) table->record[0];
share->null_fields= null_count+ hidden_null_count;
share->null_bytes= null_pack_length;
share->null_bytes= share->null_bytes_for_compare= null_pack_length;
}
null_count= (blob_count == 0) ? 1 : 0;
hidden_field_count=param->hidden_field_count;
@@ -10703,7 +10766,7 @@ TABLE *create_virtual_tmp_table(THD *thd, List<Create_field> &field_list)
{
table->null_flags= (uchar*) table->record[0];
share->null_fields= null_count;
share->null_bytes= null_pack_length;
share->null_bytes= share->null_bytes_for_compare= null_pack_length;
}
table->in_use= thd; /* field->reset() may access table->in_use */
@@ -13633,6 +13696,7 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
uint nr;
key_map keys;
uint best_key_parts;
uint saved_best_key_parts= 0;
int best_key_direction;
ha_rows best_records;
double read_time;
@@ -13834,6 +13898,7 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
{
best_key= nr;
best_key_parts= keyinfo->key_parts;
saved_best_key_parts= used_key_parts;
best_records= quick_records;
is_best_covering= is_covering;
best_key_direction= direction;
@@ -13920,8 +13985,15 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
*/
}
}
used_key_parts= best_key_parts;
order_direction= best_key_direction;
/*
saved_best_key_parts is actual number of used keyparts found by the
test_if_order_by_key function. It could differ from keyinfo->key_parts,
thus we have to restore it in case of desc order as it affects
QUICK_SELECT_DESC behaviour.
*/
used_key_parts= (order_direction == -1) ?
saved_best_key_parts : best_key_parts;
}
else
DBUG_RETURN(0);
@@ -17074,15 +17146,15 @@ bool mysql_explain_union(THD *thd, SELECT_LEX_UNIT *unit, select_result *result)
thd->lex->current_select= first;
unit->set_limit(unit->global_parameters);
res= mysql_select(thd, &first->ref_pointer_array,
(TABLE_LIST*) first->table_list.first,
first->table_list.first,
first->with_wild, first->item_list,
first->where,
first->order_list.elements +
first->group_list.elements,
(ORDER*) first->order_list.first,
(ORDER*) first->group_list.first,
first->order_list.first,
first->group_list.first,
first->having,
(ORDER*) thd->lex->proc_list.first,
thd->lex->proc_list.first,
first->options | thd->options | SELECT_DESCRIBE,
result, unit, first);
}
@@ -17392,7 +17464,7 @@ void st_select_lex::print(THD *thd, String *str, enum_query_type query_type)
if (group_list.elements)
{
str->append(STRING_WITH_LEN(" group by "));
print_order(str, (ORDER *) group_list.first, query_type);
print_order(str, group_list.first, query_type);
switch (olap)
{
case CUBE_TYPE:
@@ -17423,7 +17495,7 @@ void st_select_lex::print(THD *thd, String *str, enum_query_type query_type)
if (order_list.elements)
{
str->append(STRING_WITH_LEN(" order by "));
print_order(str, (ORDER *) order_list.first, query_type);
print_order(str, order_list.first, query_type);
}
// limit