1
0
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:
monty@mysql.com
2005-06-07 00:31:53 +03:00
67 changed files with 416 additions and 302 deletions

View File

@ -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;
}