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: