~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/opt_sum.cc

  • Committer: Eric Herman
  • Date: 2008-12-06 19:42:46 UTC
  • mto: (656.1.6 devel)
  • mto: This revision was merged to the branch mainline in revision 665.
  • Revision ID: eric@mysql.com-20081206194246-5cdexuu81i366eek
removed trailing whitespace with simple script:

for file in $(find . -name "*.c") $(find . -name "*.cc") $(find . -name "*.h"); do ruby -pe 'gsub(/\s+$/, $/)' < $file > $file.out; mv $file.out $file; done;

Show diffs side-by-side

added added

removed removed

Lines of Context:
18
18
  @file
19
19
 
20
20
  Optimising of MIN(), MAX() and COUNT(*) queries without 'group by' clause
21
 
  by replacing the aggregate expression with a constant.  
 
21
  by replacing the aggregate expression with a constant.
22
22
 
23
23
  Given a table with a compound key on columns (a,b,c), the following
24
24
  types of queries are optimised (assuming the table handler supports
41
41
  involved tables and return the answer without any join. Thus, the
42
42
  following query will be replaced with a row of two constants:
43
43
  @verbatim
44
 
  SELECT MAX(b), MIN(d) FROM t1,t2 
 
44
  SELECT MAX(b), MIN(d) FROM t1,t2
45
45
    WHERE a=const AND b<const AND d>const
46
46
  @endverbatim
47
47
  (assuming a index for column d of table t2 is defined)
160
160
      statistics (cheap), compute the total number of rows. If there are
161
161
      no outer table dependencies, this count may be used as the real count.
162
162
      Schema tables are filled after this function is invoked, so we can't
163
 
      get row count 
 
163
      get row count
164
164
    */
165
165
    if (!(tl->table->file->ha_table_flags() & HA_STATS_RECORDS_IS_EXACT) ||
166
166
        tl->schema_table)
237
237
          Item_field *item_field= (Item_field*) (expr->real_item());
238
238
          Table *table= item_field->field->table;
239
239
 
240
 
          /* 
 
240
          /*
241
241
            Look for a partial key that can be used for optimization.
242
242
            If we succeed, ref.key_length will contain the length of
243
 
            this key, while prefix_len will contain the length of 
244
 
            the beginning of this key without field used in MIN(). 
 
243
            this key, while prefix_len will contain the length of
 
244
            the beginning of this key without field used in MIN().
245
245
            Type of range for the key part for this field will be
246
246
            returned in range_fl.
247
247
          */
256
256
 
257
257
          if (!ref.key_length)
258
258
            error= table->file->index_first(table->record[0]);
259
 
          else 
 
259
          else
260
260
          {
261
261
            /*
262
262
              Use index to replace MIN/MAX functions with their values
263
263
              according to the following rules:
264
 
           
 
264
 
265
265
              1) Insert the minimum non-null values where the WHERE clause still
266
266
                 matches, or
267
267
              2) a NULL value if there are only NULL values for key_part_k.
273
273
              nullable column, test if there is an exact match for the key.
274
274
            */
275
275
            if (!(range_fl & NEAR_MIN))
276
 
              /* 
 
276
              /*
277
277
                 Closed interval: Either The MIN argument is non-nullable, or
278
278
                 we have a >= predicate for the MIN argument.
279
279
              */
290
290
                We need to scan the next bigger record first.
291
291
              */
292
292
              error= table->file->index_read_map(table->record[0],
293
 
                                                 ref.key_buff, 
 
293
                                                 ref.key_buff,
294
294
                                                 make_prev_keypart_map(ref.key_parts),
295
295
                                                 HA_READ_AFTER_KEY);
296
 
              /* 
 
296
              /*
297
297
                 If the found record is outside the group formed by the search
298
298
                 prefix, or there is no such record at all, check if all
299
299
                 records in that group have NULL in the MIN argument
323
323
            }
324
324
          }
325
325
          /* Verify that the read tuple indeed matches the search key */
326
 
          if (!error && reckey_in_range(0, &ref, item_field->field, 
 
326
          if (!error && reckey_in_range(0, &ref, item_field->field,
327
327
                                        conds, range_fl, prefix_len))
328
328
            error= HA_ERR_KEY_NOT_FOUND;
329
329
          if (table->key_read)
385
385
          Item_field *item_field= (Item_field*) (expr->real_item());
386
386
          Table *table= item_field->field->table;
387
387
 
388
 
          /* 
 
388
          /*
389
389
            Look for a partial key that can be used for optimization.
390
390
            If we succeed, ref.key_length will contain the length of
391
 
            this key, while prefix_len will contain the length of 
 
391
            this key, while prefix_len will contain the length of
392
392
            the beginning of this key without field used in MAX().
393
393
            Type of range for the key part for this field will be
394
394
            returned in range_fl.
593
593
    1        We can use index to get MIN/MAX value
594
594
*/
595
595
 
596
 
static bool matching_cond(bool max_fl, TABLE_REF *ref, KEY *keyinfo, 
 
596
static bool matching_cond(bool max_fl, TABLE_REF *ref, KEY *keyinfo,
597
597
                          KEY_PART_INFO *field_part, COND *cond,
598
598
                          key_part_map *key_part_used, uint32_t *range_fl,
599
599
                          uint32_t *prefix_len)
627
627
    return 0;                                 // Not operator, can't optimize
628
628
 
629
629
  bool eq_type= 0;                            // =, <=> or IS NULL
630
 
  bool noeq_type= 0;                          // < or >  
631
 
  bool less_fl= 0;                            // < or <= 
 
630
  bool noeq_type= 0;                          // < or >
 
631
  bool less_fl= 0;                            // < or <=
632
632
  bool is_null= 0;
633
633
  bool between= 0;
634
634
 
642
642
  case Item_func::LT_FUNC:
643
643
    noeq_type= 1;   /* fall through */
644
644
  case Item_func::LE_FUNC:
645
 
    less_fl= 1;      
 
645
    less_fl= 1;
646
646
    break;
647
647
  case Item_func::GT_FUNC:
648
648
    noeq_type= 1;   /* fall through */
657
657
  default:
658
658
    return 0;                                        // Can't optimize function
659
659
  }
660
 
  
 
660
 
661
661
  Item *args[3];
662
662
  bool inv;
663
663
 
691
691
    if (ref->key_length < length)
692
692
    {
693
693
    /* Ultimately ref->key_length will contain the length of the search key */
694
 
      ref->key_length= length;      
 
694
      ref->key_length= length;
695
695
      ref->key_parts= (part - keyinfo->key_part) + 1;
696
696
    }
697
 
    if (!*prefix_len && part+1 == field_part)       
 
697
    if (!*prefix_len && part+1 == field_part)
698
698
      *prefix_len= length;
699
699
    if (is_field_part && eq_type)
700
700
      *prefix_len= ref->key_length;
701
 
  
 
701
 
702
702
    *key_part_used|= (key_part_map) 1 << (part - keyinfo->key_part);
703
703
  }
704
704
 
705
705
  if (org_key_part_used != *key_part_used ||
706
 
      (is_field_part && 
 
706
      (is_field_part &&
707
707
       (between || eq_type || max_fl == less_fl) && !cond->val_int()))
708
708
  {
709
709
    /*
710
710
      It's the first predicate for this part or a predicate of the
711
711
      following form  that moves upper/lower bounds for max/min values:
712
712
      - field BETWEEN const AND const
713
 
      - field = const 
 
713
      - field = const
714
714
      - field {<|<=} const, when searching for MAX
715
715
      - field {>|>=} const, when searching for MIN
716
716
    */
724
724
    {
725
725
      store_val_in_field(part->field, args[between && max_fl ? 2 : 1],
726
726
                         CHECK_FIELD_IGNORE);
727
 
      if (part->null_bit) 
 
727
      if (part->null_bit)
728
728
        *key_ptr++= (unsigned char) test(part->field->is_null());
729
729
      part->field->get_key_image(key_ptr, part->length, Field::itRAW);
730
730
    }
750
750
  }
751
751
  else if (is_field_part)
752
752
    *range_fl&= ~(max_fl ? NO_MIN_RANGE : NO_MAX_RANGE);
753
 
  return 1;  
 
753
  return 1;
754
754
}
755
755
 
756
756
 
764
764
     -# for each previous component f_i there is one and only one conjunct
765
765
        of the form: f_i= const_i or const_i= f_i or f_i is null
766
766
     -# references to field occur only in conjucts of the form:
767
 
        field {<|<=|>=|>|=} const or const {<|<=|>=|>|=} field or 
 
767
        field {<|<=|>=|>|=} const or const {<|<=|>=|>|=} field or
768
768
        field BETWEEN const1 AND const2
769
769
     -# all references to the columns from the same table as column field
770
770
        occur only in conjucts mentioned above.
796
796
    In this case ref, range_fl and prefix_len are updated
797
797
*/
798
798
 
799
 
      
 
799
 
800
800
static bool find_key_for_maxmin(bool max_fl, TABLE_REF *ref,
801
801
                                Field* field, COND *cond,
802
802
                                uint32_t *range_fl, uint32_t *prefix_len)
851
851
            /*
852
852
              The query is on this form:
853
853
 
854
 
              SELECT MIN(key_part_k) 
855
 
              FROM t1 
 
854
              SELECT MIN(key_part_k)
 
855
              FROM t1
856
856
              WHERE key_part_1 = const and ... and key_part_k-1 = const
857
857
 
858
858
              If key_part_k is nullable, we want to find the first matching row