1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-27 18:02:13 +03:00

Move USE_PRAGMA_IMPLEMENTATION to proper place

Ensure that 'null_value' is not accessed before val() is called in FIELD() functions
Fixed initialization of key maps. This fixes some problems with keys when you have more than 64 keys
Fixed that ROLLUP don't always create a temporary table. This fix ensures that func_gconcat.test results are now predictable
This commit is contained in:
monty@mysql.com
2005-06-03 23:46:03 +03:00
parent fd17d75923
commit 29fd1f2fd9
47 changed files with 180 additions and 237 deletions

View File

@ -17,13 +17,10 @@
/* mysql_select and join optimization */
#include <my_global.h>
#include "mysql_priv.h"
#ifdef USE_PRAGMA_IMPLEMENTATION
#pragma implementation // gcc: Class implementation
#endif
#include "mysql_priv.h"
#include "sql_select.h"
#include <m_ctype.h>
@ -35,9 +32,6 @@ const char *join_type_str[]={ "UNKNOWN","system","const","eq_ref","ref",
"ref_or_null","unique_subquery","index_subquery"
};
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 *tables,COND *conds,
DYNAMIC_ARRAY *keyuse);
@ -66,7 +60,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,
@ -613,7 +607,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)
@ -681,8 +675,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
@ -694,7 +689,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);
}
@ -1638,8 +1633,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)
{
@ -3452,7 +3447,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=0;
join_tab->ref.key = -1;
@ -3684,7 +3680,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
@ -3697,7 +3693,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
@ -4200,20 +4196,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 ? 0 : 1;
@ -4244,7 +4259,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;
@ -4253,11 +4269,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);
@ -6357,7 +6375,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);
}
@ -7352,12 +7370,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;
@ -8902,6 +8923,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);
}
@ -9415,9 +9438,10 @@ 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
Item_null_result *null_item= rollup.null_items[i];
null_item->result_field= ((Item_field *) item)->result_field;
null_item= rollup.null_items[i];
null_item->result_field= item->get_tmp_table_field();
item= null_item;
break;
}