~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/optimizer/sum.cc

  • Committer: Monty Taylor
  • Date: 2009-12-08 22:43:58 UTC
  • mfrom: (1240.1.5 build)
  • mto: (1240.1.6 build)
  • mto: This revision was merged to the branch mainline in revision 1241.
  • Revision ID: mordred@inaugust.com-20091208224358-u1pazjsnn4n932cu
MergedĀ upĀ build.

Show diffs side-by-side

added added

removed removed

Lines of Context:
60
60
namespace drizzled
61
61
{
62
62
 
63
 
static bool find_key_for_maxmin(bool max_fl, 
64
 
                                table_reference_st *ref, 
 
63
static bool find_key_for_maxmin(bool max_fl,
 
64
                                table_reference_st *ref,
65
65
                                Field* field,
66
 
                                COND *cond, 
 
66
                                COND *cond,
67
67
                                uint32_t *range_fl,
68
68
                                uint32_t *key_prefix_length);
69
69
 
70
 
static int reckey_in_range(bool max_fl, 
71
 
                           table_reference_st *ref, 
 
70
static int reckey_in_range(bool max_fl,
 
71
                           table_reference_st *ref,
72
72
                           Field* field,
73
 
                           COND *cond, 
74
 
                           uint32_t range_fl, 
 
73
                           COND *cond,
 
74
                           uint32_t range_fl,
75
75
                           uint32_t prefix_len);
76
76
 
77
77
static int maxmin_in_range(bool max_fl, Field *field, COND *cond);
114
114
  int const_result= 1;
115
115
  bool recalc_const_item= false;
116
116
  uint64_t count= 1;
117
 
  bool is_exact_count= true; 
 
117
  bool is_exact_count= true;
118
118
  bool maybe_exact_count= true;
119
119
  table_map removed_tables= 0;
120
120
  table_map outer_tables= 0;
194
194
    if (item->type() == Item::SUM_FUNC_ITEM)
195
195
    {
196
196
      Item_sum *item_sum= (((Item_sum*) item));
197
 
      switch (item_sum->sum_func()) 
 
197
      switch (item_sum->sum_func())
198
198
      {
199
199
        case Item_sum::COUNT_FUNC:
200
200
          /*
249
249
                 Type of range for the key part for this field will be
250
250
                 returned in range_fl.
251
251
               */
252
 
              if (table->cursor->inited || 
 
252
              if (table->cursor->inited ||
253
253
                  (outer_tables & table->map) ||
254
 
                  ! find_key_for_maxmin(0, 
255
 
                                        &ref, 
256
 
                                        item_field->field, 
 
254
                  ! find_key_for_maxmin(0,
 
255
                                        &ref,
 
256
                                        item_field->field,
257
257
                                        conds,
258
 
                                        &range_fl, 
 
258
                                        &range_fl,
259
259
                                        &prefix_len))
260
260
              {
261
261
                const_result= 0;
336
336
                }
337
337
              }
338
338
              /* Verify that the read tuple indeed matches the search key */
339
 
              if (! error && 
340
 
                  reckey_in_range(0, 
341
 
                                  &ref, 
 
339
              if (! error &&
 
340
                  reckey_in_range(0,
 
341
                                  &ref,
342
342
                                  item_field->field,
343
 
                                  conds, 
344
 
                                  range_fl, 
 
343
                                  conds,
 
344
                                  range_fl,
345
345
                                  prefix_len))
346
346
              {
347
347
                error= HA_ERR_KEY_NOT_FOUND;
417
417
                 Type of range for the key part for this field will be
418
418
                 returned in range_fl.
419
419
               */
420
 
              if (table->cursor->inited || 
 
420
              if (table->cursor->inited ||
421
421
                  (outer_tables & table->map) ||
422
 
                  ! find_key_for_maxmin(1, 
423
 
                                        &ref, 
424
 
                                        item_field->field, 
 
422
                  ! find_key_for_maxmin(1,
 
423
                                        &ref,
 
424
                                        item_field->field,
425
425
                                        conds,
426
 
                                        &range_fl, 
 
426
                                        &range_fl,
427
427
                                        &prefix_len))
428
428
              {
429
429
                const_result= 0;
437
437
              }
438
438
              else
439
439
              {
440
 
                error= table->cursor->index_read_map(table->record[0], 
 
440
                error= table->cursor->index_read_map(table->record[0],
441
441
                                                     key_buff,
442
442
                                                     make_prev_keypart_map(ref.key_parts),
443
443
                                                     range_fl & NEAR_MAX ?
444
444
                                                     HA_READ_BEFORE_KEY :
445
445
                                                     HA_READ_PREFIX_LAST_OR_PREV);
446
446
              }
447
 
              if (! error && 
448
 
                  reckey_in_range(1, 
449
 
                                  &ref, 
 
447
              if (! error &&
 
448
                  reckey_in_range(1,
 
449
                                  &ref,
450
450
                                  item_field->field,
451
 
                                  conds, 
452
 
                                  range_fl, 
 
451
                                  conds,
 
452
                                  range_fl,
453
453
                                  prefix_len))
454
454
              {
455
455
                error= HA_ERR_KEY_NOT_FOUND;
535
535
{
536
536
  Item *item= NULL;
537
537
  inv_order= false;
538
 
  switch (func_item->argument_count()) 
 
538
  switch (func_item->argument_count())
539
539
  {
540
540
  case 0:
541
541
    /* MULT_EQUAL_FUNC */
645
645
  @retval
646
646
    1        We can use index to get MIN/MAX value
647
647
*/
648
 
static bool matching_cond(bool max_fl, 
649
 
                          table_reference_st *ref, 
 
648
static bool matching_cond(bool max_fl,
 
649
                          table_reference_st *ref,
650
650
                          KEY *keyinfo,
651
 
                          KEY_PART_INFO *field_part, 
 
651
                          KEY_PART_INFO *field_part,
652
652
                          COND *cond,
653
 
                          key_part_map *key_part_used, 
 
653
                          key_part_map *key_part_used,
654
654
                          uint32_t *range_fl,
655
655
                          uint32_t *prefix_len)
656
656
{
679
679
    Item *item;
680
680
    while ((item= li++))
681
681
    {
682
 
      if (! matching_cond(max_fl, 
683
 
                          ref, 
684
 
                          keyinfo, 
685
 
                          field_part, 
 
682
      if (! matching_cond(max_fl,
 
683
                          ref,
 
684
                          keyinfo,
 
685
                          field_part,
686
686
                          item,
687
 
                          key_part_used, 
688
 
                          range_fl, 
 
687
                          key_part_used,
 
688
                          range_fl,
689
689
                          prefix_len))
690
690
      {
691
691
        return 0;
705
705
  bool is_null= false;
706
706
  bool between= false;
707
707
 
708
 
  switch (((Item_func*) cond)->functype()) 
 
708
  switch (((Item_func*) cond)->functype())
709
709
  {
710
710
  case Item_func::ISNULL_FUNC:
711
711
    is_null= 1;     /* fall through */
895
895
    1   Can use key to optimize MIN()/MAX().
896
896
    In this case ref, range_fl and prefix_len are updated
897
897
*/
898
 
static bool find_key_for_maxmin(bool max_fl, 
 
898
static bool find_key_for_maxmin(bool max_fl,
899
899
                                table_reference_st *ref,
900
 
                                Field* field, 
 
900
                                Field* field,
901
901
                                COND *cond,
902
 
                                uint32_t *range_fl, 
 
902
                                uint32_t *range_fl,
903
903
                                uint32_t *prefix_len)
904
904
{
905
905
  if (! (field->flags & PART_KEY_FLAG))
954
954
        ref->key_parts= 0;
955
955
        key_part_map key_part_used= 0;
956
956
        *range_fl= NO_MIN_RANGE | NO_MAX_RANGE;
957
 
        if (matching_cond(max_fl, 
958
 
                          ref, 
959
 
                          keyinfo, 
960
 
                          part, 
 
957
        if (matching_cond(max_fl,
 
958
                          ref,
 
959
                          keyinfo,
 
960
                          part,
961
961
                          cond,
962
 
                          &key_part_used, 
963
 
                          range_fl, 
 
962
                          &key_part_used,
 
963
                          range_fl,
964
964
                          prefix_len) &&
965
965
            ! (key_part_to_use & ~key_part_used))
966
966
        {
1021
1021
  @retval
1022
1022
    1        WHERE was not true for the found row
1023
1023
*/
1024
 
static int reckey_in_range(bool max_fl, 
1025
 
                           table_reference_st *ref, 
 
1024
static int reckey_in_range(bool max_fl,
 
1025
                           table_reference_st *ref,
1026
1026
                           Field* field,
1027
 
                           COND *cond, 
1028
 
                           uint32_t range_fl, 
 
1027
                           COND *cond,
 
1028
                           uint32_t range_fl,
1029
1029
                           uint32_t prefix_len)
1030
1030
{
1031
1031
  if (key_cmp_if_same(field->table, ref->key_buff, ref->key, prefix_len))
1074
1074
    return 0;
1075
1075
  }
1076
1076
  bool less_fl= false;
1077
 
  switch (((Item_func*) cond)->functype()) 
 
1077
  switch (((Item_func*) cond)->functype())
1078
1078
  {
1079
1079
  case Item_func::BETWEEN:
1080
1080
    return cond->val_int() == 0;                // Return 1 if WHERE is false