mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
Merge with 4.1
This commit is contained in:
@ -17,8 +17,6 @@
|
||||
|
||||
/* mysql_select and join optimization */
|
||||
|
||||
#include <my_global.h>
|
||||
|
||||
#ifdef USE_PRAGMA_IMPLEMENTATION
|
||||
#pragma implementation // gcc: Class implementation
|
||||
#endif
|
||||
@ -36,9 +34,6 @@ const char *join_type_str[]={ "UNKNOWN","system","const","eq_ref","ref",
|
||||
"index_merge"
|
||||
};
|
||||
|
||||
const key_map key_map_empty(0);
|
||||
const key_map key_map_full(~(uint)0);
|
||||
|
||||
static void optimize_keyuse(JOIN *join, DYNAMIC_ARRAY *keyuse_array);
|
||||
static bool make_join_statistics(JOIN *join, TABLE_LIST *leaves, COND *conds,
|
||||
DYNAMIC_ARRAY *keyuse);
|
||||
@ -88,7 +83,7 @@ static bool only_eq_ref_tables(JOIN *join, ORDER *order, table_map tables);
|
||||
static void update_depend_map(JOIN *join);
|
||||
static void update_depend_map(JOIN *join, ORDER *order);
|
||||
static ORDER *remove_const(JOIN *join,ORDER *first_order,COND *cond,
|
||||
bool *simple_order);
|
||||
bool change_list, bool *simple_order);
|
||||
static int return_zero_rows(JOIN *join, select_result *res,TABLE_LIST *tables,
|
||||
List<Item> &fields, bool send_row,
|
||||
uint select_options, const char *info,
|
||||
@ -749,7 +744,7 @@ JOIN::optimize()
|
||||
/* Optimize distinct away if possible */
|
||||
{
|
||||
ORDER *org_order= order;
|
||||
order=remove_const(this, order,conds,&simple_order);
|
||||
order=remove_const(this, order,conds,1, &simple_order);
|
||||
/*
|
||||
If we are using ORDER BY NULL or ORDER BY const_expression,
|
||||
return result in any order (even if we are using a GROUP BY)
|
||||
@ -817,8 +812,9 @@ JOIN::optimize()
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
simple_group= 0;
|
||||
if (rollup.state == ROLLUP::STATE_NONE)
|
||||
group_list= remove_const(this, group_list, conds, &simple_group);
|
||||
group_list= remove_const(this, group_list, conds,
|
||||
rollup.state == ROLLUP::STATE_NONE,
|
||||
&simple_group);
|
||||
if (!group_list && group)
|
||||
{
|
||||
order=0; // The output has only one row
|
||||
@ -830,7 +826,7 @@ JOIN::optimize()
|
||||
if (procedure && procedure->group)
|
||||
{
|
||||
group_list= procedure->group= remove_const(this, procedure->group, conds,
|
||||
&simple_group);
|
||||
1, &simple_group);
|
||||
calc_group_buffer(this, group_list);
|
||||
}
|
||||
|
||||
@ -2088,8 +2084,8 @@ static ha_rows get_quick_record_count(THD *thd, SQL_SELECT *select,
|
||||
{
|
||||
select->head=table;
|
||||
table->reginfo.impossible_range=0;
|
||||
if ((error=select->test_quick_select(thd, *(key_map *)keys,(table_map) 0,
|
||||
limit)) == 1)
|
||||
if ((error= select->test_quick_select(thd, *(key_map *)keys,(table_map) 0,
|
||||
limit, 0)) == 1)
|
||||
DBUG_RETURN(select->quick->records);
|
||||
if (error == -1)
|
||||
{
|
||||
@ -5091,7 +5087,8 @@ make_simple_join(JOIN *join,TABLE *tmp_table)
|
||||
join_tab->select_cond=0;
|
||||
join_tab->quick=0;
|
||||
join_tab->type= JT_ALL; /* Map through all records */
|
||||
join_tab->keys.init(~(uint)0); /* test everything in quick */
|
||||
join_tab->keys.init();
|
||||
join_tab->keys.set_all(); /* test everything in quick */
|
||||
join_tab->info=0;
|
||||
join_tab->on_expr_ref=0;
|
||||
join_tab->last_inner= 0;
|
||||
@ -5540,7 +5537,7 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
|
||||
(join->select_options &
|
||||
OPTION_FOUND_ROWS ?
|
||||
HA_POS_ERROR :
|
||||
join->unit->select_limit_cnt)) < 0)
|
||||
join->unit->select_limit_cnt), 0) < 0)
|
||||
{
|
||||
/*
|
||||
Before reporting "Impossible WHERE" for the whole query
|
||||
@ -5553,7 +5550,7 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
|
||||
(join->select_options &
|
||||
OPTION_FOUND_ROWS ?
|
||||
HA_POS_ERROR :
|
||||
join->unit->select_limit_cnt)) < 0)
|
||||
join->unit->select_limit_cnt),0) < 0)
|
||||
DBUG_RETURN(1); // Impossible WHERE
|
||||
}
|
||||
else
|
||||
@ -6122,20 +6119,39 @@ static void update_depend_map(JOIN *join, ORDER *order)
|
||||
|
||||
|
||||
/*
|
||||
simple_order is set to 1 if sort_order only uses fields from head table
|
||||
and the head table is not a LEFT JOIN table
|
||||
Remove all constants and check if ORDER only contains simple expressions
|
||||
|
||||
SYNOPSIS
|
||||
remove_const()
|
||||
join Join handler
|
||||
first_order List of SORT or GROUP order
|
||||
cond WHERE statement
|
||||
change_list Set to 1 if we should remove things from list
|
||||
If this is not set, then only simple_order is
|
||||
calculated
|
||||
simple_order Set to 1 if we are only using simple expressions
|
||||
|
||||
RETURN
|
||||
Returns new sort order
|
||||
|
||||
simple_order is set to 1 if sort_order only uses fields from head table
|
||||
and the head table is not a LEFT JOIN table
|
||||
|
||||
*/
|
||||
|
||||
static ORDER *
|
||||
remove_const(JOIN *join,ORDER *first_order, COND *cond, bool *simple_order)
|
||||
remove_const(JOIN *join,ORDER *first_order, COND *cond,
|
||||
bool change_list, bool *simple_order)
|
||||
{
|
||||
if (join->tables == join->const_tables)
|
||||
return 0; // No need to sort
|
||||
DBUG_ENTER("remove_const");
|
||||
return change_list ? 0 : first_order; // No need to sort
|
||||
|
||||
ORDER *order,**prev_ptr;
|
||||
table_map first_table= join->join_tab[join->const_tables].table->map;
|
||||
table_map not_const_tables= ~join->const_table_map;
|
||||
table_map ref;
|
||||
DBUG_ENTER("remove_const");
|
||||
|
||||
prev_ptr= &first_order;
|
||||
*simple_order= *join->join_tab[join->const_tables].on_expr_ref ? 0 : 1;
|
||||
|
||||
@ -6166,7 +6182,8 @@ remove_const(JOIN *join,ORDER *first_order, COND *cond, bool *simple_order)
|
||||
}
|
||||
if ((ref=order_tables & (not_const_tables ^ first_table)))
|
||||
{
|
||||
if (!(order_tables & first_table) && only_eq_ref_tables(join,first_order,ref))
|
||||
if (!(order_tables & first_table) &&
|
||||
only_eq_ref_tables(join,first_order, ref))
|
||||
{
|
||||
DBUG_PRINT("info",("removing: %s", order->item[0]->full_name()));
|
||||
continue;
|
||||
@ -6175,11 +6192,13 @@ remove_const(JOIN *join,ORDER *first_order, COND *cond, bool *simple_order)
|
||||
}
|
||||
}
|
||||
}
|
||||
*prev_ptr= order; // use this entry
|
||||
if (change_list)
|
||||
*prev_ptr= order; // use this entry
|
||||
prev_ptr= &order->next;
|
||||
}
|
||||
*prev_ptr=0;
|
||||
if (!first_order) // Nothing to sort/group
|
||||
if (change_list)
|
||||
*prev_ptr=0;
|
||||
if (prev_ptr == &first_order) // Nothing to sort/group
|
||||
*simple_order=1;
|
||||
DBUG_PRINT("exit",("simple_order: %d",(int) *simple_order));
|
||||
DBUG_RETURN(first_order);
|
||||
@ -9829,7 +9848,7 @@ test_if_quick_select(JOIN_TAB *tab)
|
||||
delete tab->select->quick;
|
||||
tab->select->quick=0;
|
||||
return tab->select->test_quick_select(tab->join->thd, tab->keys,
|
||||
(table_map) 0, HA_POS_ERROR);
|
||||
(table_map) 0, HA_POS_ERROR, 0);
|
||||
}
|
||||
|
||||
|
||||
@ -10865,12 +10884,15 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
|
||||
parameres are set correctly by the range optimizer.
|
||||
*/
|
||||
key_map new_ref_key_map;
|
||||
new_ref_key_map.clear_all(); /* Force the creation of quick select */
|
||||
new_ref_key_map.set_bit(new_ref_key); /* only for new_ref_key. */
|
||||
new_ref_key_map.clear_all(); // Force the creation of quick select
|
||||
new_ref_key_map.set_bit(new_ref_key); // only for new_ref_key.
|
||||
|
||||
if (select->test_quick_select(tab->join->thd, new_ref_key_map, 0,
|
||||
(tab->join->select_options & OPTION_FOUND_ROWS) ?
|
||||
HA_POS_ERROR : tab->join->unit->select_limit_cnt) <= 0)
|
||||
(tab->join->select_options &
|
||||
OPTION_FOUND_ROWS) ?
|
||||
HA_POS_ERROR :
|
||||
tab->join->unit->select_limit_cnt,0) <=
|
||||
0)
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
ref_key= new_ref_key;
|
||||
@ -12528,6 +12550,8 @@ bool JOIN::make_sum_func_list(List<Item> &field_list, List<Item> &send_fields,
|
||||
for (uint i=0 ; i <= send_group_parts ;i++)
|
||||
sum_funcs_end[i]= func;
|
||||
}
|
||||
else if (rollup.state == ROLLUP::STATE_READY)
|
||||
DBUG_RETURN(FALSE); // Don't put end marker
|
||||
*func=0; // End marker
|
||||
DBUG_RETURN(FALSE);
|
||||
}
|
||||
@ -13070,12 +13094,12 @@ bool JOIN::rollup_make_fields(List<Item> &fields_arg, List<Item> &sel_fields,
|
||||
This is an element that is used by the GROUP BY and should be
|
||||
set to NULL in this level
|
||||
*/
|
||||
Item_null_result *null_item;
|
||||
item->maybe_null= 1; // Value will be null sometimes
|
||||
null_item= rollup.null_items[i];
|
||||
DBUG_ASSERT(null_item->result_field == 0 ||
|
||||
null_item->result_field ==
|
||||
((Item_field *) item)->result_field);
|
||||
null_item->result_field= ((Item_field *) item)->result_field;
|
||||
null_item->result_field == item->get_tmp_table_field());
|
||||
null_item->result_field= item->get_tmp_table_field();
|
||||
item= null_item;
|
||||
break;
|
||||
}
|
||||
|
Reference in New Issue
Block a user