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.cc46
1 files changed, 35 insertions, 11 deletions
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 24d2a21147c..11378ac0d11 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -195,7 +195,8 @@ static bool test_if_cheaper_ordering(const JOIN_TAB *tab,
ha_rows select_limit,
int *new_key, int *new_key_direction,
ha_rows *new_select_limit,
- uint *new_used_key_parts= NULL);
+ uint *new_used_key_parts= NULL,
+ uint *saved_best_key_parts= NULL);
static bool test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,
ha_rows select_limit, bool no_changes,
key_map *map);
@@ -592,13 +593,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)
@@ -1152,7 +1161,7 @@ JOIN::optimize()
elements may be lost during further having
condition transformation in JOIN::exec.
*/
- if (having && const_table_map)
+ if (having && const_table_map && !having->with_sum_func)
{
having->update_used_tables();
having= remove_eq_conds(thd, having, &having_value);
@@ -7356,7 +7365,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
@@ -13694,6 +13704,7 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
}
{
uint best_key_parts= 0;
+ uint saved_best_key_parts= 0;
int best_key_direction= 0;
int best_key= -1;
JOIN *join= tab->join;
@@ -13702,7 +13713,8 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
test_if_cheaper_ordering(tab, order, table, usable_keys,
ref_key, select_limit,
&best_key, &best_key_direction,
- &select_limit, &best_key_parts);
+ &select_limit, &best_key_parts,
+ &saved_best_key_parts);
/*
filesort() and join cache are usually faster than reading in
@@ -13781,8 +13793,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);
@@ -17374,6 +17393,8 @@ void JOIN::cache_const_exprs()
@param [out] new_used_key_parts NULL by default, otherwise return number
of new_key prefix columns if success
or undefined if the function fails
+ @param [out] saved_best_key_parts NULL by default, otherwise preserve the
+ value for further use in QUICK_SELECT_DESC
@note
This function takes into account table->quick_condition_rows statistic
@@ -17388,7 +17409,8 @@ test_if_cheaper_ordering(const JOIN_TAB *tab, ORDER *order, TABLE *table,
key_map usable_keys, int ref_key,
ha_rows select_limit,
int *new_key, int *new_key_direction,
- ha_rows *new_select_limit, uint *new_used_key_parts)
+ ha_rows *new_select_limit, uint *new_used_key_parts,
+ uint *saved_best_key_parts)
{
DBUG_ENTER("test_if_cheaper_ordering");
/*
@@ -17567,6 +17589,8 @@ test_if_cheaper_ordering(const JOIN_TAB *tab, ORDER *order, TABLE *table,
{
best_key= nr;
best_key_parts= keyinfo->key_parts;
+ if (saved_best_key_parts)
+ *saved_best_key_parts= used_key_parts;
best_records= quick_records;
is_best_covering= is_covering;
best_key_direction= direction;