~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/opt_range.cc

  • Committer: Monty Taylor
  • Date: 2008-12-20 23:44:07 UTC
  • mto: (722.2.2 devel)
  • mto: This revision was merged to the branch mainline in revision 727.
  • Revision ID: monty@inaugust.com-20081220234407-585wdrdd1vxqqzam
Removed all the setting of DEFS everywhere. Use configmake.h to get the values
we need.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1017
1017
  *error=0;
1018
1018
 
1019
1019
  if (!conds && !allow_null_cond)
1020
 
    return 0;
 
1020
    return(0);
1021
1021
  if (!(select= new SQL_SELECT))
1022
1022
  {
1023
1023
    *error= 1;                  // out of memory
1024
 
    return 0;           /* purecov: inspected */
 
1024
    return(0);          /* purecov: inspected */
1025
1025
  }
1026
1026
  select->read_tables=read_tables;
1027
1027
  select->const_tables=const_tables;
1190
1190
 
1191
1191
int QUICK_INDEX_MERGE_SELECT::init()
1192
1192
{
1193
 
  return 0;
 
1193
  return(0);
1194
1194
}
1195
1195
 
1196
1196
int QUICK_INDEX_MERGE_SELECT::reset()
1295
1295
  {
1296
1296
    if (init() || reset())
1297
1297
    {
1298
 
      return 0;
 
1298
      return(1);
1299
1299
    }
1300
1300
    head->column_bitmaps_set(&column_bitmap, &column_bitmap);
1301
1301
    goto end;
1305
1305
  if (free_file)
1306
1306
  {
1307
1307
    /* already have own 'handler' object. */
1308
 
    return 0;
 
1308
    return(0);
1309
1309
  }
1310
1310
 
1311
1311
  session= head->in_use;
1357
1357
  bitmap_copy(&column_bitmap, head->read_set);
1358
1358
  head->column_bitmaps_set(&column_bitmap, &column_bitmap);
1359
1359
 
1360
 
  return 0;
 
1360
  return(0);
1361
1361
 
1362
1362
failure:
1363
1363
  head->column_bitmaps_set(save_read_set, save_write_set);
1364
1364
  delete file;
1365
1365
  file= save_file;
1366
 
  return 0;
 
1366
  return(1);
1367
1367
}
1368
1368
 
1369
1369
 
1398
1398
      selects.
1399
1399
    */
1400
1400
    if (quick->init_ror_merged_scan(true))
1401
 
      return 0;
 
1401
      return(1);
1402
1402
    quick->file->extra(HA_EXTRA_KEYREAD_PRESERVE_FIELDS);
1403
1403
  }
1404
1404
  while ((quick= quick_it++))
1405
1405
  {
1406
1406
    if (quick->init_ror_merged_scan(false))
1407
 
      return 0;
 
1407
      return(1);
1408
1408
    quick->file->extra(HA_EXTRA_KEYREAD_PRESERVE_FIELDS);
1409
1409
    /* All merged scans share the same record buffer in intersection. */
1410
1410
    quick->record= head->record[0];
1412
1412
 
1413
1413
  if (need_to_fetch_row && head->file->ha_rnd_init(1))
1414
1414
  {
1415
 
    return 0;
 
1415
    return(1);
1416
1416
  }
1417
 
  return 0;
 
1417
  return(0);
1418
1418
}
1419
1419
 
1420
1420
 
1430
1430
int QUICK_ROR_INTERSECT_SELECT::reset()
1431
1431
{
1432
1432
  if (!scans_inited && init_ror_merged_scan(true))
1433
 
    return 0;
 
1433
    return(1);
1434
1434
  scans_inited= true;
1435
1435
  List_iterator_fast<QUICK_RANGE_SELECT> it(quick_selects);
1436
1436
  QUICK_RANGE_SELECT *quick;
1437
1437
  while ((quick= it++))
1438
1438
    quick->reset();
1439
 
  return 0;
 
1439
  return(0);
1440
1440
}
1441
1441
 
1442
1442
 
1502
1502
                 (void*) this))
1503
1503
  {
1504
1504
    memset(&queue, 0, sizeof(QUEUE));
1505
 
    return 0;
 
1505
    return(1);
1506
1506
  }
1507
1507
 
1508
1508
  if (!(cur_rowid= (unsigned char*) alloc_root(&alloc, 2*head->file->ref_length)))
1509
 
    return 0;
 
1509
    return(1);
1510
1510
  prev_rowid= cur_rowid + head->file->ref_length;
1511
 
  return 0;
 
1511
  return(0);
1512
1512
}
1513
1513
 
1514
1514
 
1552
1552
    while ((quick= it++))
1553
1553
    {
1554
1554
      if (quick->init_ror_merged_scan(false))
1555
 
        return 0;
 
1555
        return(1);
1556
1556
    }
1557
1557
    scans_inited= true;
1558
1558
  }
1565
1565
  while ((quick= it++))
1566
1566
  {
1567
1567
    if (quick->reset())
1568
 
      return 0;
 
1568
      return(1);
1569
1569
    if ((error= quick->get_next()))
1570
1570
    {
1571
1571
      if (error == HA_ERR_END_OF_FILE)
1578
1578
 
1579
1579
  if (head->file->ha_rnd_init(1))
1580
1580
  {
1581
 
    return 0;
 
1581
    return(1);
1582
1582
  }
1583
1583
 
1584
 
  return 0;
 
1584
  return(0);
1585
1585
}
1586
1586
 
1587
1587
 
1954
1954
      quick->records= records;
1955
1955
      quick->read_time= read_cost;
1956
1956
    }
1957
 
    return quick;
 
1957
    return(quick);
1958
1958
  }
1959
1959
};
1960
1960
 
2184
2184
  needed_reg.clear_all();
2185
2185
  quick_keys.clear_all();
2186
2186
  if (keys_to_use.is_clear_all())
2187
 
    return 0;
 
2187
    return(0);
2188
2188
  records= head->file->stats.records;
2189
2189
  if (!records)
2190
2190
    records++;                                  /* purecov: inspected */
2195
2195
  if (limit < records)
2196
2196
    read_time= (double) records + scan_time + 1; // Force to use index
2197
2197
  else if (read_time <= 2.0 && !force_quick_range)
2198
 
    return 0;                           /* No need for quick select */
 
2198
    return(0);                          /* No need for quick select */
2199
2199
 
2200
2200
  keys_to_use.intersect(head->keys_in_use_for_query);
2201
2201
  if (!keys_to_use.is_clear_all())
2207
2207
    PARAM param;
2208
2208
 
2209
2209
    if (check_stack_overrun(session, 2*STACK_MIN_SIZE, NULL))
2210
 
      return 0;                           // Fatal error flag is set
 
2210
      return(0);                           // Fatal error flag is set
2211
2211
 
2212
2212
    /* set up parameter that is passed to all functions */
2213
2213
    param.session= session;
2234
2234
    {
2235
2235
      session->no_errors=0;
2236
2236
      free_root(&alloc,MYF(0));                 // Return memory & allocator
2237
 
      return 0;                         // Can't use range
 
2237
      return(0);                                // Can't use range
2238
2238
    }
2239
2239
    key_parts= param.key_parts;
2240
2240
    session->mem_root= &alloc;
2507
2507
  if (!(range_scans= (TRP_RANGE**)alloc_root(param->mem_root,
2508
2508
                                             sizeof(TRP_RANGE*)*
2509
2509
                                             n_child_scans)))
2510
 
    return NULL;
 
2510
    return(NULL);
2511
2511
  /*
2512
2512
    Collect best 'range' scan for each of disjuncts, and, while doing so,
2513
2513
    analyze possibility of ROR scans. Also calculate some values needed by
2552
2552
      Bail out if it is obvious that both index_merge and ROR-union will be
2553
2553
      more expensive
2554
2554
    */
2555
 
    return NULL;
 
2555
    return(NULL);
2556
2556
  }
2557
2557
  if (all_scans_rors)
2558
2558
  {
2589
2589
  {
2590
2590
    if (!(param->imerge_cost_buff= (uint*)alloc_root(param->mem_root,
2591
2591
                                                     unique_calc_buff_size)))
2592
 
      return NULL;
 
2592
      return(NULL);
2593
2593
    param->imerge_cost_buff_size= unique_calc_buff_size;
2594
2594
  }
2595
2595
 
2761
2761
 
2762
2762
  if (!(ror_scan= (ROR_SCAN_INFO*)alloc_root(param->mem_root,
2763
2763
                                             sizeof(ROR_SCAN_INFO))))
2764
 
    return NULL;
 
2764
    return(NULL);
2765
2765
 
2766
2766
  ror_scan->idx= idx;
2767
2767
  ror_scan->keynr= keynr= param->real_keynr[idx];
2772
2772
 
2773
2773
  if (!(bitmap_buf= (my_bitmap_map*) alloc_root(param->mem_root,
2774
2774
                                                param->fields_bitmap_size)))
2775
 
    return NULL;
 
2775
    return(NULL);
2776
2776
 
2777
2777
  if (bitmap_init(&ror_scan->covered_fields, bitmap_buf,
2778
2778
                  param->table->s->fields, false))
2779
 
    return NULL;
 
2779
    return(NULL);
2780
2780
  bitmap_clear_all(&ror_scan->covered_fields);
2781
2781
 
2782
2782
  KEY_PART_INFO *key_part= param->table->key_info[keynr].key_part;
3124
3124
  if (selectivity_mult == 1.0)
3125
3125
  {
3126
3126
    /* Don't add this scan if it doesn't improve selectivity. */
3127
 
    return false;
 
3127
    return(false);
3128
3128
  }
3129
3129
 
3130
3130
  info->out_rows *= selectivity_mult;
3161
3161
                        is_interrupted, &sweep_cost);
3162
3162
    info->total_cost += sweep_cost.total_cost();
3163
3163
  }
3164
 
  return true;
 
3164
  return(true);
3165
3165
}
3166
3166
 
3167
3167
 
3238
3238
  double min_cost= DBL_MAX;
3239
3239
 
3240
3240
  if ((tree->n_ror_scans < 2) || !param->table->file->stats.records)
3241
 
    return NULL;
 
3241
    return(NULL);
3242
3242
 
3243
3243
  /*
3244
3244
    Step1: Collect ROR-able SEL_ARGs and create ROR_SCAN_INFO for each of
3327
3327
 
3328
3328
  if (intersect_scans_best == intersect_scans)
3329
3329
  {
3330
 
    return NULL;
 
3330
    return(NULL);
3331
3331
  }
3332
3332
 
3333
3333
  print_ror_scans_arr(param->table,
3363
3363
    if (!(trp->first_scan=
3364
3364
           (ROR_SCAN_INFO**)alloc_root(param->mem_root,
3365
3365
                                       sizeof(ROR_SCAN_INFO*)*best_num)))
3366
 
      return NULL;
 
3366
      return(NULL);
3367
3367
    memcpy(trp->first_scan, intersect_scans, best_num*sizeof(ROR_SCAN_INFO*));
3368
3368
    trp->last_scan=  trp->first_scan + best_num;
3369
3369
    trp->is_covering= intersect_best->is_covering;
3441
3441
  if (!covered_fields->bitmap ||
3442
3442
      bitmap_init(covered_fields, covered_fields->bitmap,
3443
3443
                  param->table->s->fields, false))
3444
 
    return 0;
 
3444
    return(0);
3445
3445
  bitmap_clear_all(covered_fields);
3446
3446
 
3447
3447
  double total_cost= 0.0f;
3479
3479
    total_cost += (*ror_scan_mark)->index_read_cost;
3480
3480
    records += (*ror_scan_mark)->records;
3481
3481
    if (total_cost > read_time)
3482
 
      return NULL;
 
3482
      return(NULL);
3483
3483
    /* F=F-covered by first(I) */
3484
3484
    bitmap_union(covered_fields, &(*ror_scan_mark)->covered_fields);
3485
3485
    all_covered= bitmap_is_subset(&param->needed_fields, covered_fields);
3486
3486
  } while ((++ror_scan_mark < ror_scans_end) && !all_covered);
3487
3487
 
3488
3488
  if (!all_covered || (ror_scan_mark - tree->ror_scans) == 1)
3489
 
    return NULL;
 
3489
    return(NULL);
3490
3490
 
3491
3491
  /*
3492
3492
    Ok, [tree->ror_scans .. ror_scan) holds covering index_intersection with
3502
3502
                (TIME_FOR_COMPARE_ROWID * M_LN2);
3503
3503
 
3504
3504
  if (total_cost > read_time)
3505
 
    return NULL;
 
3505
    return(NULL);
3506
3506
 
3507
3507
  TRP_ROR_INTERSECT *trp;
3508
3508
  if (!(trp= new (param->mem_root) TRP_ROR_INTERSECT))
3511
3511
  if (!(trp->first_scan= (ROR_SCAN_INFO**)alloc_root(param->mem_root,
3512
3512
                                                     sizeof(ROR_SCAN_INFO*)*
3513
3513
                                                     best_num)))
3514
 
    return NULL;
 
3514
    return(NULL);
3515
3515
  memcpy(trp->first_scan, tree->ror_scans, best_num*sizeof(ROR_SCAN_INFO*));
3516
3516
  trp->last_scan=  trp->first_scan + best_num;
3517
3517
  trp->is_covering= true;
3674
3674
          quick_intrsect->push_quick_back(quick))
3675
3675
      {
3676
3676
        delete quick_intrsect;
3677
 
        return NULL;
 
3677
        return(NULL);
3678
3678
      }
3679
3679
    }
3680
3680
    if (cpk_scan)
3685
3685
                                    0, alloc)))
3686
3686
      {
3687
3687
        delete quick_intrsect;
3688
 
        return NULL;
 
3688
        return(NULL);
3689
3689
      }
3690
3690
      quick->file= NULL;
3691
3691
      quick_intrsect->cpk_quick= quick;
3712
3712
    {
3713
3713
      if (!(quick= (*scan)->make_quick(param, false, &quick_roru->alloc)) ||
3714
3714
          quick_roru->push_quick_back(quick))
3715
 
        return NULL;
 
3715
        return(NULL);
3716
3716
    }
3717
3717
    quick_roru->records= records;
3718
3718
    quick_roru->read_time= read_cost;
4130
4130
        SEL_TREE *new_tree=get_mm_tree(param,item);
4131
4131
        if (param->session->is_fatal_error ||
4132
4132
            param->alloced_sel_args > SEL_ARG::MAX_SEL_ARGS)
4133
 
          return 0;     // out of memory
 
4133
          return(0);    // out of memory
4134
4134
        tree=tree_and(param,tree,new_tree);
4135
4135
        if (tree && tree->type == SEL_TREE::IMPOSSIBLE)
4136
4136
          break;
4146
4146
        {
4147
4147
          SEL_TREE *new_tree=get_mm_tree(param,item);
4148
4148
          if (!new_tree)
4149
 
            return 0;   // out of memory
 
4149
            return(0);  // out of memory
4150
4150
          tree=tree_or(param,tree,new_tree);
4151
4151
          if (!tree || tree->type == SEL_TREE::ALWAYS)
4152
4152
            break;
4180
4180
    ref_tables= cond->used_tables();
4181
4181
    if ((ref_tables & param->current_table) ||
4182
4182
        (ref_tables & ~(param->prev_tables | param->read_tables)))
4183
 
      return 0;
 
4183
      return(0);
4184
4184
    return(new SEL_TREE(SEL_TREE::MAYBE));
4185
4185
  }
4186
4186
 
4189
4189
      cond_func->functype() == Item_func::IN_FUNC)
4190
4190
    inv= ((Item_func_opt_neg *) cond_func)->negated;
4191
4191
  else if (cond_func->select_optimize() == Item_func::OPTIMIZE_NONE)
4192
 
    return 0;
 
4192
    return(0);
4193
4193
 
4194
4194
  param->cond= cond;
4195
4195
 
4230
4230
  {
4231
4231
    Item_func_in *func=(Item_func_in*) cond_func;
4232
4232
    if (func->key_item()->real_item()->type() != Item::FIELD_ITEM)
4233
 
      return 0;
 
4233
      return(0);
4234
4234
    field_item= (Item_field*) (func->key_item()->real_item());
4235
4235
    ftree= get_full_func_mm_tree(param, cond_func, field_item, NULL, inv);
4236
4236
    break;
4239
4239
  {
4240
4240
    Item_equal *item_equal= (Item_equal *) cond;
4241
4241
    if (!(value= item_equal->get_const()))
4242
 
      return 0;
 
4242
      return(0);
4243
4243
    Item_equal_iterator it(*item_equal);
4244
4244
    ref_tables= value->used_tables();
4245
4245
    while ((field_item= it++))
4270
4270
      value= cond_func->arguments()[0];
4271
4271
    }
4272
4272
    else
4273
 
      return 0;
 
4273
      return(0);
4274
4274
    ftree= get_full_func_mm_tree(param, cond_func, field_item, value, inv);
4275
4275
  }
4276
4276
 
4284
4284
             Item *value, Item_result)
4285
4285
{
4286
4286
  if (field->table != param->table)
4287
 
    return 0;
 
4287
    return(0);
4288
4288
 
4289
4289
  KEY_PART *key_part = param->key_parts;
4290
4290
  KEY_PART *end = param->key_parts_end;
4291
4291
  SEL_TREE *tree=0;
4292
4292
  if (value &&
4293
4293
      value->used_tables() & ~(param->prev_tables | param->read_tables))
4294
 
    return 0;
 
4294
    return(0);
4295
4295
  for (; key_part != end ; key_part++)
4296
4296
  {
4297
4297
    if (field->eq(key_part->field))
4298
4298
    {
4299
4299
      SEL_ARG *sel_arg=0;
4300
4300
      if (!tree && !(tree=new SEL_TREE()))
4301
 
        return 0;                               // OOM
 
4301
        return(0);                              // OOM
4302
4302
      if (!value || !(value->used_tables() & ~param->read_tables))
4303
4303
      {
4304
4304
        sel_arg=get_mm_leaf(param,cond_func,
4315
4315
      {
4316
4316
        // This key may be used later
4317
4317
        if (!(sel_arg= new SEL_ARG(SEL_ARG::MAYBE_KEY)))
4318
 
          return 0;                     // OOM
 
4318
          return(0);                    // OOM
4319
4319
      }
4320
4320
      sel_arg->part=(unsigned char) key_part->part;
4321
4321
      tree->keys[key_part->key]=sel_add(tree->keys[key_part->key],sel_arg);
4767
4767
  common_keys.intersect(tree2->keys_map);
4768
4768
 
4769
4769
  if (common_keys.is_clear_all())
4770
 
    return false;
 
4770
    return(false);
4771
4771
 
4772
4772
  /* trees have a common key, check if they refer to same key part */
4773
4773
  SEL_ARG **key1,**key2;
4779
4779
      key2= tree2->keys + key_no;
4780
4780
      if ((*key1)->part == (*key2)->part)
4781
4781
      {
4782
 
        return true;
 
4782
        return(true);
4783
4783
      }
4784
4784
    }
4785
4785
  }
4786
 
  return false;
 
4786
  return(false);
4787
4787
}
4788
4788
 
4789
4789
 
4866
4866
tree_or(RANGE_OPT_PARAM *param,SEL_TREE *tree1,SEL_TREE *tree2)
4867
4867
{
4868
4868
  if (!tree1 || !tree2)
4869
 
    return 0;
 
4869
    return(0);
4870
4870
  if (tree1->type == SEL_TREE::IMPOSSIBLE || tree2->type == SEL_TREE::ALWAYS)
4871
4871
    return(tree2);
4872
4872
  if (tree2->type == SEL_TREE::IMPOSSIBLE || tree1->type == SEL_TREE::ALWAYS)
4944
4944
        result= tree1;
4945
4945
    }
4946
4946
  }
4947
 
  return result;
 
4947
  return(result);
4948
4948
}
4949
4949
 
4950
4950
 
5555
5555
  }
5556
5556
 
5557
5557
  if (root == &null_element)
5558
 
    return 0;                           // Maybe root later
 
5558
    return(0);                          // Maybe root later
5559
5559
  if (remove_color == BLACK)
5560
5560
    root=rb_delete_fixup(root,nod,fix_par);
5561
5561
#ifdef EXTRA_DEBUG
6393
6393
                    param->table->key_info[param->real_keynr[idx]].key_parts);
6394
6394
    }
6395
6395
  }
6396
 
  return quick;
 
6396
  return(quick);
6397
6397
}
6398
6398
 
6399
6399
 
6755
6755
    reset here.
6756
6756
  */
6757
6757
  if (cur_quick->init() || cur_quick->reset())
6758
 
    return 0;
 
6758
    return(1);
6759
6759
 
6760
6760
  unique= new Unique(refpos_order_cmp, (void *)file,
6761
6761
                     file->ref_length,
6762
6762
                     session->variables.sortbuff_size);
6763
6763
  if (!unique)
6764
 
    return 0;
 
6764
    return(1);
6765
6765
  for (;;)
6766
6766
  {
6767
6767
    while ((result= cur_quick->get_next()) == HA_ERR_END_OF_FILE)
6774
6774
      if (cur_quick->file->inited != handler::NONE)
6775
6775
        cur_quick->file->ha_index_end();
6776
6776
      if (cur_quick->init() || cur_quick->reset())
6777
 
        return 0;
 
6777
        return(1);
6778
6778
    }
6779
6779
 
6780
6780
    if (result)
6782
6782
      if (result != HA_ERR_END_OF_FILE)
6783
6783
      {
6784
6784
        cur_quick->range_end();
6785
 
        return result;
 
6785
        return(result);
6786
6786
      }
6787
6787
      break;
6788
6788
    }
6789
6789
 
6790
6790
    if (session->killed)
6791
 
      return 0;
 
6791
      return(1);
6792
6792
 
6793
6793
    /* skip row if it will be retrieved by clustered PK scan */
6794
6794
    if (pk_quick_select && pk_quick_select->row_in_ranges())
6797
6797
    cur_quick->file->position(cur_quick->record);
6798
6798
    result= unique->unique_add((char*)cur_quick->file->ref);
6799
6799
    if (result)
6800
 
      return 0;
 
6800
      return(1);
6801
6801
 
6802
6802
  }
6803
6803
 
6809
6809
  file->extra(HA_EXTRA_NO_KEYREAD);
6810
6810
  /* start table scan */
6811
6811
  init_read_record(&read_record, session, head, (SQL_SELECT*) 0, 1, 1);
6812
 
  return result;
 
6812
  return(result);
6813
6813
}
6814
6814
 
6815
6815
 
6839
6839
      doing_pk_scan= true;
6840
6840
      if ((result= pk_quick_select->init()) ||
6841
6841
          (result= pk_quick_select->reset()))
6842
 
        return result;
 
6842
        return(result);
6843
6843
      return(pk_quick_select->get_next());
6844
6844
    }
6845
6845
  }
6846
6846
 
6847
 
  return result;
 
6847
  return(result);
6848
6848
}
6849
6849
 
6850
6850
 
7211
7211
    /* Restore bitmaps set on entry */
7212
7212
    head->column_bitmaps_set_no_signal(save_read_set, save_write_set);
7213
7213
  }
7214
 
  return result;
 
7214
  return(result);
7215
7215
}
7216
7216
 
7217
7217
 
7258
7258
      result= file->index_read_map(record, cur_prefix, keypart_map,
7259
7259
                                   HA_READ_AFTER_KEY);
7260
7260
      if (result || (file->compare_key(file->end_range) <= 0))
7261
 
        return result;
 
7261
        return(result);
7262
7262
    }
7263
7263
 
7264
7264
    uint32_t count= ranges.elements - (cur_range - (QUICK_RANGE**) ranges.buffer);
7266
7266
    {
7267
7267
      /* Ranges have already been used up before. None is left for read. */
7268
7268
      last_range= 0;
7269
 
      return HA_ERR_END_OF_FILE;
 
7269
      return(HA_ERR_END_OF_FILE);
7270
7270
    }
7271
7271
    last_range= *(cur_range++);
7272
7272
 
7294
7294
      last_range= 0;                    // Stop searching
7295
7295
 
7296
7296
    if (result != HA_ERR_END_OF_FILE)
7297
 
      return result;
 
7297
      return(result);
7298
7298
    last_range= 0;                      // No matching rows; go to next range
7299
7299
  }
7300
7300
}
7398
7398
      if (!result)
7399
7399
      {
7400
7400
        if (cmp_prev(*rev_it.ref()) == 0)
7401
 
          return 0;
 
7401
          return(0);
7402
7402
      }
7403
7403
      else if (result != HA_ERR_END_OF_FILE)
7404
 
        return result;
 
7404
        return(result);
7405
7405
    }
7406
7406
 
7407
7407
    if (!(last_range= rev_it++))
7408
 
      return HA_ERR_END_OF_FILE;                // All ranges used
 
7408
      return(HA_ERR_END_OF_FILE);               // All ranges used
7409
7409
 
7410
7410
    if (last_range->flag & NO_MAX_RANGE)        // Read last record
7411
7411
    {
7413
7413
      if ((local_error=file->index_last(record)))
7414
7414
        return(local_error);            // Empty table
7415
7415
      if (cmp_prev(last_range) == 0)
7416
 
        return 0;
 
7416
        return(0);
7417
7417
      last_range= 0;                            // No match; go to next range
7418
7418
      continue;
7419
7419
    }
7437
7437
    if (result)
7438
7438
    {
7439
7439
      if (result != HA_ERR_KEY_NOT_FOUND && result != HA_ERR_END_OF_FILE)
7440
 
        return result;
 
7440
        return(result);
7441
7441
      last_range= 0;                            // Not found, to next range
7442
7442
      continue;
7443
7443
    }
7445
7445
    {
7446
7446
      if (last_range->flag == (UNIQUE_RANGE | EQ_RANGE))
7447
7447
        last_range= 0;                          // Stop searching
7448
 
      return 0;                         // Found key is in range
 
7448
      return(0);                                // Found key is in range
7449
7449
    }
7450
7450
    last_range= 0;                              // To next range
7451
7451
  }
7873
7873
 
7874
7874
  /* Perform few 'cheap' tests whether this access method is applicable. */
7875
7875
  if (!join)
7876
 
    return NULL;        /* This is not a select statement. */
 
7876
    return(NULL);        /* This is not a select statement. */
7877
7877
  if ((join->tables != 1) ||  /* The query must reference one table. */
7878
7878
      ((!join->group_list) && /* Neither GROUP BY nor a DISTINCT query. */
7879
7879
       (!join->select_distinct)) ||
7880
7880
      (join->select_lex->olap == ROLLUP_TYPE)) /* Check (B3) for ROLLUP */
7881
 
    return NULL;
 
7881
    return(NULL);
7882
7882
  if (table->s->keys == 0)        /* There are no indexes to use. */
7883
 
    return NULL;
 
7883
    return(NULL);
7884
7884
 
7885
7885
  /* Analyze the query in more detail. */
7886
7886
  List_iterator<Item> select_items_it(join->fields_list);
7887
7887
 
7888
7888
  /* Check (SA1,SA4) and store the only MIN/MAX argument - the C attribute.*/
7889
7889
  if (join->make_sum_func_list(join->all_fields, join->fields_list, 1))
7890
 
    return NULL;
 
7890
    return(NULL);
7891
7891
  if (join->sum_funcs[0])
7892
7892
  {
7893
7893
    Item_sum *min_max_item;
7899
7899
      else if (min_max_item->sum_func() == Item_sum::MAX_FUNC)
7900
7900
        have_max= true;
7901
7901
      else
7902
 
        return NULL;
 
7902
        return(NULL);
7903
7903
 
7904
7904
      /* The argument of MIN/MAX. */
7905
7905
      Item *expr= min_max_item->args[0]->real_item();
7908
7908
        if (! min_max_arg_item)
7909
7909
          min_max_arg_item= (Item_field*) expr;
7910
7910
        else if (! min_max_arg_item->eq(expr, 1))
7911
 
          return NULL;
 
7911
          return(NULL);
7912
7912
      }
7913
7913
      else
7914
 
        return NULL;
 
7914
        return(NULL);
7915
7915
    }
7916
7916
  }
7917
7917
 
7921
7921
    while ((item= select_items_it++))
7922
7922
    {
7923
7923
      if (item->type() != Item::FIELD_ITEM)
7924
 
        return NULL;
 
7924
        return(NULL);
7925
7925
    }
7926
7926
  }
7927
7927
 
7929
7929
  for (tmp_group= join->group_list; tmp_group; tmp_group= tmp_group->next)
7930
7930
  {
7931
7931
    if ((*tmp_group->item)->type() != Item::FIELD_ITEM)
7932
 
      return NULL;
 
7932
      return(NULL);
7933
7933
  }
7934
7934
 
7935
7935
  /*
8215
8215
    cur_group_prefix_len= 0;
8216
8216
  }
8217
8217
  if (!index_info) /* No usable index found. */
8218
 
    return NULL;
 
8218
    return(NULL);
8219
8219
 
8220
8220
  /* Check (SA3) for the where clause. */
8221
8221
  if (join->conds && min_max_arg_item &&
8222
8222
      !check_group_min_max_predicates(join->conds, min_max_arg_item, Field::itRAW))
8223
 
    return NULL;
 
8223
    return(NULL);
8224
8224
 
8225
8225
  /* The query passes all tests, so construct a new TRP object. */
8226
8226
  read_plan= new (param->mem_root)
8234
8234
  if (read_plan)
8235
8235
  {
8236
8236
    if (tree && read_plan->quick_prefix_records == 0)
8237
 
      return NULL;
 
8237
      return(NULL);
8238
8238
 
8239
8239
    read_plan->read_cost= best_read_cost;
8240
8240
    read_plan->records=   best_records;
8241
8241
  }
8242
8242
 
8243
 
  return read_plan;
 
8243
  return(read_plan);
8244
8244
}
8245
8245
 
8246
8246
 
8282
8282
    {
8283
8283
      if (!check_group_min_max_predicates(and_or_arg, min_max_arg_item,
8284
8284
                                         image_type))
8285
 
        return false;
 
8285
        return(false);
8286
8286
    }
8287
 
    return true;
 
8287
    return(true);
8288
8288
  }
8289
8289
 
8290
8290
  /*
8297
8297
    so.
8298
8298
  */
8299
8299
  if (cond_type == Item::SUBSELECT_ITEM)
8300
 
    return false;
 
8300
    return(false);
8301
8301
 
8302
8302
  /* We presume that at this point there are no other Items than functions. */
8303
8303
  assert(cond_type == Item::FUNC_ITEM);
8328
8328
            pred_type != Item_func::ISNOTNULL_FUNC &&
8329
8329
            pred_type != Item_func::EQ_FUNC        &&
8330
8330
            pred_type != Item_func::NE_FUNC)
8331
 
          return false;
 
8331
          return(false);
8332
8332
 
8333
8333
        /* Check that pred compares min_max_arg_item with a constant. */
8334
8334
        Item *args[3];
8336
8336
        bool inv;
8337
8337
        /* Test if this is a comparison of a field and a constant. */
8338
8338
        if (!simple_pred(pred, args, &inv))
8339
 
          return false;
 
8339
          return(false);
8340
8340
 
8341
8341
        /* Check for compatible string comparisons - similar to get_mm_leaf. */
8342
8342
        if (args[0] && args[1] && !args[2] && // this is a binary function
8355
8355
             */
8356
8356
             (args[1]->result_type() != STRING_RESULT &&
8357
8357
              min_max_arg_item->field->cmp_type() != args[1]->result_type())))
8358
 
          return false;
 
8358
          return(false);
8359
8359
      }
8360
8360
    }
8361
8361
    else if (cur_arg->type() == Item::FUNC_ITEM)
8362
8362
    {
8363
8363
      if (!check_group_min_max_predicates(cur_arg, min_max_arg_item,
8364
8364
                                         image_type))
8365
 
        return false;
 
8365
        return(false);
8366
8366
    }
8367
8367
    else if (cur_arg->const_item())
8368
8368
    {
8369
 
      return true;
 
8369
      return(true);
8370
8370
    }
8371
8371
    else
8372
 
      return false;
 
8372
      return(false);
8373
8373
  }
8374
8374
 
8375
 
  return true;
 
8375
  return(true);
8376
8376
}
8377
8377
 
8378
8378
 
8539
8539
    idx++;
8540
8540
  }
8541
8541
  *param_idx= idx;
8542
 
  return range_tree->keys[idx];
 
8542
  return(range_tree->keys[idx]);
8543
8543
}
8544
8544
 
8545
8545
 
8674
8674
 
8675
8675
  *read_cost= io_cost + cpu_cost;
8676
8676
  *records= num_groups;
 
8677
  return;
8677
8678
}
8678
8679
 
8679
8680
 
8711
8712
                                        read_cost, records, key_infix_len,
8712
8713
                                        key_infix, parent_alloc);
8713
8714
  if (!quick)
8714
 
    return NULL;
 
8715
    return(NULL);
8715
8716
 
8716
8717
  if (quick->init())
8717
8718
  {
8718
8719
    delete quick;
8719
 
    return NULL;
 
8720
    return(NULL);
8720
8721
  }
8721
8722
 
8722
8723
  if (range_tree)
8755
8756
        {
8756
8757
          delete quick;
8757
8758
          quick= NULL;
8758
 
          return NULL;
 
8759
          return(NULL);
8759
8760
        }
8760
8761
        min_max_range= min_max_range->next;
8761
8762
      }
8767
8768
  quick->update_key_stat();
8768
8769
  quick->adjust_prefix_ranges();
8769
8770
 
8770
 
  return quick;
 
8771
  return(quick);
8771
8772
}
8772
8773
 
8773
8774
 
8944
8945
  delete min_functions_it;
8945
8946
  delete max_functions_it;
8946
8947
  delete quick_prefix_select;
 
8948
  return;
8947
8949
}
8948
8950
 
8949
8951
 
9120
9122
 
9121
9123
  file->extra(HA_EXTRA_KEYREAD); /* We need only the key attributes */
9122
9124
  if ((result= file->ha_index_init(index,1)))
9123
 
    return result;
 
9125
    return(result);
9124
9126
  if (quick_prefix_select && quick_prefix_select->reset())
9125
 
    return 0;
 
9127
    return(1);
9126
9128
  result= file->index_last(record);
9127
9129
  if (result == HA_ERR_END_OF_FILE)
9128
 
    return 0;
 
9130
    return(0);
9129
9131
  /* Save the prefix of the last group. */
9130
9132
  key_copy(last_prefix, record, index_info, group_prefix_len);
9131
9133
 
9132
 
  return 0;
 
9134
  return(0);
9133
9135
}
9134
9136
 
9135
9137
 
9206
9208
      if (max_res == 0)
9207
9209
        update_max_result();
9208
9210
      /* If a MIN was found, a MAX must have been found as well. */
9209
 
      assert(((have_max && !have_min) ||
9210
 
                  (have_max && have_min && (max_res == 0))));
 
9211
      assert((have_max && !have_min) ||
 
9212
                  (have_max && have_min && (max_res == 0)));
9211
9213
    }
9212
9214
    /*
9213
9215
      If this is just a GROUP BY or DISTINCT without MIN or MAX and there
9236
9238
  else if (result == HA_ERR_KEY_NOT_FOUND)
9237
9239
    result= HA_ERR_END_OF_FILE;
9238
9240
 
9239
 
  return result;
 
9241
  return(result);
9240
9242
}
9241
9243
 
9242
9244
 
9271
9273
  if (min_max_ranges.elements > 0)
9272
9274
  {
9273
9275
    if ((result= next_min_in_range()))
9274
 
      return result;
 
9276
      return(result);
9275
9277
  }
9276
9278
  else
9277
9279
  {
9281
9283
      if ((result= file->index_read_map(record, group_prefix,
9282
9284
                                        make_prev_keypart_map(real_key_parts),
9283
9285
                                        HA_READ_KEY_EXACT)))
9284
 
        return result;
 
9286
        return(result);
9285
9287
    }
9286
9288
 
9287
9289
    /*
9322
9324
    If the MIN attribute is non-nullable, this->record already contains the
9323
9325
    MIN key in the group, so just return.
9324
9326
  */
9325
 
  return result;
 
9327
  return(result);
9326
9328
}
9327
9329
 
9328
9330
 
9353
9355
    result= file->index_read_map(record, group_prefix,
9354
9356
                                 make_prev_keypart_map(real_key_parts),
9355
9357
                                 HA_READ_PREFIX_LAST);
9356
 
  return result;
 
9358
  return(result);
9357
9359
}
9358
9360
 
9359
9361
 
9387
9389
    unsigned char *cur_prefix= seen_first_key ? group_prefix : NULL;
9388
9390
    if ((result= quick_prefix_select->get_next_prefix(group_prefix_len,
9389
9391
                         make_prev_keypart_map(group_key_parts), cur_prefix)))
9390
 
      return result;
 
9392
      return(result);
9391
9393
    seen_first_key= true;
9392
9394
  }
9393
9395
  else
9396
9398
    {
9397
9399
      result= file->index_first(record);
9398
9400
      if (result)
9399
 
        return result;
 
9401
        return(result);
9400
9402
      seen_first_key= true;
9401
9403
    }
9402
9404
    else
9406
9408
                                   make_prev_keypart_map(group_key_parts),
9407
9409
                                   HA_READ_AFTER_KEY);
9408
9410
      if (result)
9409
 
        return result;
 
9411
        return(result);
9410
9412
    }
9411
9413
  }
9412
9414
 
9417
9419
    memcpy(group_prefix + group_prefix_len,
9418
9420
           key_infix, key_infix_len);
9419
9421
 
9420
 
  return 0;
 
9422
  return(0);
9421
9423
}
9422
9424
 
9423
9425
 
9775
9777
  }
9776
9778
  if (!tmp.length())
9777
9779
    tmp.append(STRING_WITH_LEN("(empty)"));
 
9780
 
 
9781
  return;
9778
9782
}
9779
9783
 
9780
9784
 
9793
9797
  }
9794
9798
  if (!tmp.length())
9795
9799
    tmp.append(STRING_WITH_LEN("(empty)"));
 
9800
  return;
9796
9801
}
9797
9802
 
9798
9803
/*****************************************************************************