~posulliv/drizzle/memcached_applier

« back to all changes in this revision

Viewing changes to drizzled/opt_range.cc

Merged trunk and resolved conflicts.

Show diffs side-by-side

added added

removed removed

Lines of Context:
2269
2269
 
2270
2270
      param.key[param.keys]=key_parts;
2271
2271
      key_part_info= key_info->key_part;
2272
 
      for (uint32_t part=0 ; part < key_info->key_parts ;
2273
 
           part++, key_parts++, key_part_info++)
 
2272
      for (uint32_t part=0;
 
2273
           part < key_info->key_parts;
 
2274
           part++, key_parts++, key_part_info++)
2274
2275
      {
2275
 
        key_parts->key=          param.keys;
2276
 
        key_parts->part=         part;
2277
 
        key_parts->length=       key_part_info->length;
2278
 
        key_parts->store_length= key_part_info->store_length;
2279
 
        key_parts->field=        key_part_info->field;
2280
 
        key_parts->null_bit=     key_part_info->null_bit;
2281
 
        key_parts->image_type =  Field::itRAW;
 
2276
        key_parts->key= param.keys;
 
2277
        key_parts->part= part;
 
2278
        key_parts->length= key_part_info->length;
 
2279
        key_parts->store_length= key_part_info->store_length;
 
2280
        key_parts->field= key_part_info->field;
 
2281
        key_parts->null_bit= key_part_info->null_bit;
2282
2282
        /* Only HA_PART_KEY_SEG is used */
2283
 
        key_parts->flag=         (uint8_t) key_part_info->key_part_flag;
 
2283
        key_parts->flag= (uint8_t) key_part_info->key_part_flag;
2284
2284
      }
2285
2285
      param.real_keynr[param.keys++]=idx;
2286
2286
    }
4398
4398
  */
4399
4399
  if (field->result_type() == STRING_RESULT &&
4400
4400
      value->result_type() == STRING_RESULT &&
4401
 
      key_part->image_type == Field::itRAW &&
4402
4401
      ((Field_str*)field)->charset() != conf_func->compare_collation() &&
4403
4402
      !(conf_func->compare_collation()->state & MY_CS_BINSORT))
4404
4403
    goto end;
4470
4469
      max_str[0]= min_str[0]=0;
4471
4470
 
4472
4471
    field_length-= maybe_null;
 
4472
    int escape_code=
 
4473
      make_escape_code(field->charset(),
 
4474
                       ((Item_func_like*)(param->cond))->escape);
4473
4475
    like_error= my_like_range(field->charset(),
4474
4476
                              res->ptr(), res->length(),
4475
 
                              ((Item_func_like*)(param->cond))->escape,
 
4477
                              escape_code,
4476
4478
                              wild_one, wild_many,
4477
4479
                              field_length,
4478
4480
                              (char*) min_str+offset, (char*) max_str+offset,
4681
4683
    goto end;
4682
4684
  if (maybe_null)
4683
4685
    *str= (unsigned char) field->is_real_null();        // Set to 1 if null
4684
 
  field->get_key_image(str+maybe_null, key_part->length,
4685
 
                       key_part->image_type);
 
4686
  field->get_key_image(str+maybe_null, key_part->length);
4686
4687
  if (!(tree= new (alloc) SEL_ARG(field, str, str)))
4687
4688
    goto end;                                   // out of memory
4688
4689
 
7821
7822
                       KEY_PART_INFO *last_part, Session *session,
7822
7823
                       unsigned char *key_infix, uint32_t *key_infix_len,
7823
7824
                       KEY_PART_INFO **first_non_infix_part);
7824
 
static bool
7825
 
check_group_min_max_predicates(COND *cond, Item_field *min_max_arg_item,
7826
 
                               Field::imagetype image_type);
 
7825
static bool check_group_min_max_predicates(COND *cond, Item_field *min_max_arg_item);
7827
7826
 
7828
7827
static void
7829
7828
cost_group_min_max(Table* table, KEY *index_info, uint32_t used_key_parts,
8072
8071
  SEL_ARG *cur_index_tree= NULL;
8073
8072
  ha_rows cur_quick_prefix_records= 0;
8074
8073
  uint32_t cur_param_idx=MAX_KEY;
8075
 
  key_map cur_used_key_parts;
 
8074
  key_map used_key_parts_map;
 
8075
  uint32_t cur_key_infix_len= 0;
 
8076
  unsigned char cur_key_infix[MAX_KEY_LENGTH];
 
8077
  uint32_t cur_used_key_parts= 0;
8076
8078
  uint32_t pk= param->table->s->primary_key;
8077
8079
 
8078
8080
  for (uint32_t cur_index= 0 ; cur_index_info != cur_index_info_end ;
8147
8149
    else if (join->select_distinct)
8148
8150
    {
8149
8151
      select_items_it.rewind();
8150
 
      cur_used_key_parts.reset();
 
8152
      used_key_parts_map.reset();
8151
8153
      uint32_t max_key_part= 0;
8152
8154
      while ((item= select_items_it++))
8153
8155
      {
8158
8160
          Check if this attribute was already present in the select list.
8159
8161
          If it was present, then its corresponding key part was alredy used.
8160
8162
        */
8161
 
        if (cur_used_key_parts.test(key_part_nr))
 
8163
        if (used_key_parts_map.test(key_part_nr))
8162
8164
          continue;
8163
8165
        if (key_part_nr < 1 || key_part_nr > join->fields_list.elements)
8164
8166
          goto next_index;
8165
8167
        cur_part= cur_index_info->key_part + key_part_nr - 1;
8166
8168
        cur_group_prefix_len+= cur_part->store_length;
8167
 
        cur_used_key_parts.set(key_part_nr);
 
8169
        used_key_parts_map.set(key_part_nr);
8168
8170
        ++cur_group_key_parts;
8169
8171
        max_key_part= cmax(max_key_part,key_part_nr);
8170
8172
      }
8177
8179
      key_map all_parts, cur_parts;
8178
8180
      for (uint32_t pos= 0; pos < max_key_part; pos++)
8179
8181
        all_parts.set(pos);
8180
 
      cur_parts= cur_used_key_parts >> 1;
 
8182
      cur_parts= used_key_parts_map >> 1;
8181
8183
      if (all_parts != cur_parts)
8182
8184
        goto next_index;
8183
8185
    }
8227
8229
                                                        &dummy);
8228
8230
        if (!get_constant_key_infix(cur_index_info, index_range_tree,
8229
8231
                                    first_non_group_part, min_max_arg_part,
8230
 
                                    last_part, session, key_infix, &key_infix_len,
 
8232
                                    last_part, session, cur_key_infix, 
 
8233
                                    &cur_key_infix_len,
8231
8234
                                    &first_non_infix_part))
8232
8235
          goto next_index;
8233
8236
      }
8281
8284
    }
8282
8285
 
8283
8286
    /* If we got to this point, cur_index_info passes the test. */
8284
 
    key_infix_parts= key_infix_len ?
 
8287
    key_infix_parts= cur_key_infix_len ?
8285
8288
                     (first_non_infix_part - first_non_group_part) : 0;
8286
 
    used_key_parts= cur_group_key_parts + key_infix_parts;
 
8289
    cur_used_key_parts= cur_group_key_parts + key_infix_parts;
8287
8290
 
8288
8291
    /* Compute the cost of using this index. */
8289
8292
    if (tree)
8301
8304
                                                   &mrr_flags, &mrr_bufsize,
8302
8305
                                                   &dummy_cost);
8303
8306
    }
8304
 
    cost_group_min_max(table, cur_index_info, used_key_parts,
 
8307
    cost_group_min_max(table, cur_index_info, cur_used_key_parts,
8305
8308
                       cur_group_key_parts, tree, cur_index_tree,
8306
8309
                       cur_quick_prefix_records, have_min, have_max,
8307
8310
                       &cur_read_cost, &cur_records);
8322
8325
      best_param_idx= cur_param_idx;
8323
8326
      group_key_parts= cur_group_key_parts;
8324
8327
      group_prefix_len= cur_group_prefix_len;
 
8328
      key_infix_len= cur_key_infix_len;
 
8329
      if (key_infix_len)
 
8330
        memcpy (key_infix, cur_key_infix, sizeof (key_infix));
 
8331
      used_key_parts= cur_used_key_parts;
8325
8332
    }
8326
8333
 
8327
8334
  next_index:
8328
8335
    cur_group_key_parts= 0;
8329
8336
    cur_group_prefix_len= 0;
 
8337
    cur_key_infix_len= 0;
8330
8338
  }
8331
8339
  if (!index_info) /* No usable index found. */
8332
8340
    return NULL;
8333
8341
 
8334
8342
  /* Check (SA3) for the where clause. */
8335
8343
  if (join->conds && min_max_arg_item &&
8336
 
      !check_group_min_max_predicates(join->conds, min_max_arg_item, Field::itRAW))
 
8344
      ! check_group_min_max_predicates(join->conds, min_max_arg_item))
8337
8345
    return NULL;
8338
8346
 
8339
8347
  /* The query passes all tests, so construct a new TRP object. */
8379
8387
    true  if cond passes the test
8380
8388
    false o/w
8381
8389
*/
8382
 
 
8383
 
static bool
8384
 
check_group_min_max_predicates(COND *cond, Item_field *min_max_arg_item,
8385
 
                               Field::imagetype image_type)
 
8390
static bool check_group_min_max_predicates(COND *cond, Item_field *min_max_arg_item)
8386
8391
{
8387
8392
  assert(cond && min_max_arg_item);
8388
8393
 
8394
8399
    Item *and_or_arg;
8395
8400
    while ((and_or_arg= li++))
8396
8401
    {
8397
 
      if (!check_group_min_max_predicates(and_or_arg, min_max_arg_item,
8398
 
                                         image_type))
 
8402
      if (!check_group_min_max_predicates(and_or_arg, min_max_arg_item))
8399
8403
        return false;
8400
8404
    }
8401
8405
    return true;
8459
8463
              Don't use an index when comparing strings of different collations.
8460
8464
            */
8461
8465
            ((args[1]->result_type() == STRING_RESULT &&
8462
 
              image_type == Field::itRAW &&
8463
8466
              ((Field_str*) min_max_arg_item->field)->charset() !=
8464
8467
              pred->compare_collation())
8465
8468
             ||
8474
8477
    }
8475
8478
    else if (cur_arg->type() == Item::FUNC_ITEM)
8476
8479
    {
8477
 
      if (!check_group_min_max_predicates(cur_arg, min_max_arg_item,
8478
 
                                         image_type))
 
8480
      if (! check_group_min_max_predicates(cur_arg, min_max_arg_item))
8479
8481
        return false;
8480
8482
    }
8481
8483
    else if (cur_arg->const_item())