summaryrefslogtreecommitdiff
path: root/sql/sql_select.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/sql_select.cc')
-rw-r--r--sql/sql_select.cc88
1 files changed, 56 insertions, 32 deletions
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 2f1761387ae..e6702faa4e3 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -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;
}