54 static bool find_key_for_maxmin(
bool max_fl,
TABLE_REF *ref,
Field* field,
55 Item *cond, uint *range_fl,
56 uint *key_prefix_length);
57 static int reckey_in_range(
bool max_fl,
TABLE_REF *ref,
Field* field,
58 Item *cond, uint range_fl, uint prefix_len);
59 static int maxmin_in_range(
bool max_fl,
Field* field,
Item *cond);
78 static ulonglong get_exact_record_count(
TABLE_LIST *tables)
81 for (
TABLE_LIST *tl= tables; tl; tl= tl->next_leaf)
83 ha_rows tmp= tl->table->file->records();
84 if (tmp == HA_POS_ERROR)
130 if (!(range_fl & NEAR_MIN))
138 HA_READ_KEY_OR_NEXT);
149 DBUG_ASSERT(prefix_len < ref->key_length);
172 (error == HA_ERR_KEY_NOT_FOUND ||
173 key_cmp_if_same(table, ref->
key_buff, ref->
key, prefix_len)))
199 static int get_index_max_value(
TABLE *table,
TABLE_REF *ref, uint range_fl)
204 range_fl & NEAR_MAX ?
206 HA_READ_PREFIX_LAST_OR_PREV) :
242 bool recalc_const_item=
false;
244 bool is_exact_count= TRUE, maybe_exact_count= TRUE;
245 table_map removed_tables= 0, outer_tables= 0, used_tables= 0;
249 DBUG_ENTER(
"opt_sum_query");
251 const table_map where_tables= conds ? conds->used_tables() : 0;
259 if (where_tables & OUTER_REF_TABLE_BIT)
266 for (
TABLE_LIST *tl= tables; tl; tl= tl->next_leaf)
268 if (tl->join_cond() || tl->outer_join_nest())
271 outer_tables|= tl->table->map;
279 if (tl->table->map & where_tables)
283 used_tables|= tl->table->map;
293 bool table_filled= !(tl->schema_table || tl->uses_materialization());
294 if ((tl->table->file->ha_table_flags() & HA_STATS_RECORDS_IS_EXACT) &&
297 error= tl->fetch_number_of_rows();
300 tl->table->file->print_error(error, MYF(ME_FATALERROR));
303 count*= tl->table->file->stats.records;
307 maybe_exact_count&=
test(table_filled &&
308 (tl->table->file->ha_table_flags() &
310 is_exact_count= FALSE;
322 if (item->type() == Item::SUM_FUNC_ITEM)
325 switch (item_sum->sum_func()) {
326 case Item_sum::COUNT_FUNC:
332 if (!conds && !((
Item_sum_count*) item)->get_arg(0)->maybe_null &&
333 !outer_tables && maybe_exact_count)
337 if ((count= get_exact_record_count(tables)) == ULONGLONG_MAX)
357 else if (tables->next_leaf == NULL &&
358 conds && conds->type() == Item::FUNC_ITEM &&
359 ((
Item_func*)conds)->functype() == Item_func::FT_FUNC &&
361 HA_CAN_FULLTEXT_EXT) &&
365 fts_item->init_search(
true);
373 if (const_result == 1) {
375 recalc_const_item=
true;
379 case Item_sum::MIN_FUNC:
380 case Item_sum::MAX_FUNC:
382 int is_max=
test(item_sum->sum_func() == Item_sum::MAX_FUNC);
388 Item *expr=item_sum->get_arg(0);
389 if (expr->real_item()->type() == Item::FIELD_ITEM)
391 uchar key_buff[MAX_KEY_LENGTH];
393 uint range_fl, prefix_len;
397 TABLE *table= item_field->field->table;
407 if (table->file->inited || (outer_tables & table->map) ||
408 !find_key_for_maxmin(is_max, &ref, item_field->field, conds,
409 &range_fl, &prefix_len))
417 table->set_keyread(FALSE);
422 get_index_max_value(table, &ref, range_fl) :
423 get_index_min_value(table, &ref, item_field, range_fl,
427 if (!error && reckey_in_range(is_max, &ref, item_field->field,
428 conds, range_fl, prefix_len))
429 error= HA_ERR_KEY_NOT_FOUND;
430 table->set_keyread(FALSE);
434 if (error == HA_ERR_KEY_NOT_FOUND || error == HA_ERR_END_OF_FILE)
435 DBUG_RETURN(HA_ERR_KEY_NOT_FOUND);
440 removed_tables|= table->map;
442 else if (!expr->const_item() || conds || !is_exact_count)
462 item_sum->set_aggregator(item_sum->has_with_distinct() ?
463 Aggregator::DISTINCT_AGGREGATOR :
464 Aggregator::SIMPLE_AGGREGATOR);
470 if (!count && !outer_tables)
474 item->no_rows_in_result();
478 item_sum->make_const();
479 recalc_const_item= 1;
487 else if (const_result)
489 if (recalc_const_item)
490 item->update_used_tables();
491 if (!item->const_item())
497 DBUG_RETURN(thd->get_stmt_da()->sql_errno());
506 if (removed_tables && used_tables != removed_tables)
508 DBUG_RETURN(const_result);
531 switch (func_item->argument_count()) {
540 if (!(args[1]= item_equal->get_const()))
546 item= func_item->arguments()[0];
547 if (item->type() != Item::FIELD_ITEM)
553 item= func_item->arguments()[0];
554 if (item->type() == Item::FIELD_ITEM)
557 item= func_item->arguments()[1];
558 if (!item->const_item())
562 else if (item->const_item())
565 item= func_item->arguments()[1];
566 if (item->type() != Item::FIELD_ITEM)
576 item= func_item->arguments()[0];
577 if (item->type() == Item::FIELD_ITEM)
580 for (
int i= 1 ;
i <= 2;
i++)
582 item= func_item->arguments()[
i];
583 if (!item->const_item())
651 static bool matching_cond(
bool max_fl,
TABLE_REF *ref,
KEY *keyinfo,
653 key_part_map *key_part_used, uint *range_fl,
656 DBUG_ENTER(
"matching_cond");
659 Field *field= field_part->field;
660 if (!(cond->used_tables() & field->table->map))
665 if (cond->type() == Item::COND_ITEM)
667 if (((
Item_cond*) cond)->functype() == Item_func::COND_OR_FUNC)
675 if (!matching_cond(max_fl, ref, keyinfo, field_part, item,
676 key_part_used, range_fl, prefix_len))
682 if (cond->type() != Item::FUNC_ITEM)
686 bool is_null_safe_eq= FALSE;
692 switch (((
Item_func*) cond)->functype()) {
693 case Item_func::ISNULL_FUNC:
695 case Item_func::EQ_FUNC:
698 case Item_func::EQUAL_FUNC:
699 eq_type= is_null_safe_eq= TRUE;
701 case Item_func::LT_FUNC:
703 case Item_func::LE_FUNC:
706 case Item_func::GT_FUNC:
708 case Item_func::GE_FUNC:
710 case Item_func::BETWEEN:
718 case Item_func::MULT_EQUAL_FUNC:
732 if (!is_null_safe_eq && !is_null &&
733 (args[1]->is_null() || (between && args[2]->is_null())))
742 for (part= keyinfo->key_part; ; key_ptr+= part++->store_length)
745 if (part > field_part)
747 if (part->field->eq(((
Item_field*) args[0])->field))
751 bool is_field_part= part == field_part;
752 if (!(is_field_part || eq_type))
755 key_part_map org_key_part_used= *key_part_used;
756 if (eq_type || between || max_fl == less_fl)
758 uint length= (key_ptr-ref->
key_buff)+part->store_length;
763 ref->
key_parts= (part - keyinfo->key_part) + 1;
765 if (!*prefix_len && part+1 == field_part)
767 if (is_field_part && eq_type)
770 *key_part_used|= (key_part_map) 1 << (part - keyinfo->key_part);
773 if (org_key_part_used == *key_part_used &&
781 (eq_type || *range_fl == 0))
784 if (org_key_part_used != *key_part_used ||
786 (between || eq_type || max_fl == less_fl) && !cond->val_int()))
797 if (is_null || (is_null_safe_eq && args[1]->is_null()))
805 part->field->set_null();
811 Item *value= args[between && max_fl ? 2 : 1];
812 value->save_in_field_no_warnings(part->field,
true);
814 *key_ptr++= (uchar)
test(part->field->is_null());
815 part->field->get_key_image(key_ptr, part->length, Field::itRAW);
819 if (between || eq_type)
820 *range_fl&= ~(NO_MAX_RANGE | NO_MIN_RANGE);
823 *range_fl&= ~(max_fl ? NO_MAX_RANGE : NO_MIN_RANGE);
825 *range_fl|= (max_fl ? NEAR_MAX : NEAR_MIN);
827 *range_fl&= ~(max_fl ? NEAR_MAX : NEAR_MIN);
833 if ((!is_null && !cond->val_int()) ||
834 (is_null && !
test(part->field->is_null())))
837 else if (is_field_part)
838 *range_fl&= ~(max_fl ? NO_MIN_RANGE : NO_MAX_RANGE);
887 static bool find_key_for_maxmin(
bool max_fl,
TABLE_REF *ref,
889 uint *range_fl, uint *prefix_len)
891 if (!(field->flags & PART_KEY_FLAG))
894 DBUG_ENTER(
"find_key_for_maxmin");
896 TABLE *table= field->table;
899 KEY *keyinfo,*keyinfo_end;
900 for (keyinfo= table->key_info, keyinfo_end= keyinfo+table->s->keys ;
901 keyinfo != keyinfo_end;
905 key_part_map key_part_to_use= 0;
910 if (!table->keys_in_use_for_query.is_set(idx))
916 part++, jdx++, key_part_to_use= (key_part_to_use << 1) | 1)
918 if (!(table->file->index_flags(idx, jdx, 0) & HA_READ_ORDER))
922 Field *part_field= table->field[part->fieldnr-1];
923 if ((part_field->flags & BLOB_FLAG) ||
924 part->length < part_field->key_length())
927 if (field->eq(part->field))
932 key_part_map key_part_used= 0;
933 *range_fl= NO_MIN_RANGE | NO_MAX_RANGE;
934 if (matching_cond(max_fl, ref, keyinfo, part, cond,
935 &key_part_used, range_fl, prefix_len) &&
936 !(key_part_to_use & ~key_part_used))
938 if (!max_fl && key_part_used == key_part_to_use && part->null_bit)
959 *range_fl&= ~NO_MIN_RANGE;
960 *range_fl|= NEAR_MIN;
966 if (field->part_of_key.is_set(idx))
967 table->set_keyread(TRUE);
993 static int reckey_in_range(
bool max_fl,
TABLE_REF *ref,
Field* field,
994 Item *cond, uint range_fl, uint prefix_len)
996 if (key_cmp_if_same(field->table, ref->
key_buff, ref->
key, prefix_len))
998 if (!cond || (range_fl & (max_fl ? NO_MIN_RANGE : NO_MAX_RANGE)))
1000 return maxmin_in_range(max_fl, field, cond);
1017 static int maxmin_in_range(
bool max_fl,
Field* field,
Item *cond)
1020 if (cond->type() == Item::COND_ITEM)
1024 while ((item= li++))
1026 if (maxmin_in_range(max_fl, field, item))
1032 if (cond->used_tables() != field->table->map)
1035 switch (((
Item_func*) cond)->functype()) {
1036 case Item_func::BETWEEN:
1037 return cond->val_int() == 0;
1038 case Item_func::LT_FUNC:
1039 case Item_func::LE_FUNC:
1041 case Item_func::GT_FUNC:
1042 case Item_func::GE_FUNC:
1046 if (!item->const_item())
1054 if (max_fl != less_fl)
1055 return cond->val_int() == 0;
1058 case Item_func::EQ_FUNC:
1059 case Item_func::EQUAL_FUNC: