~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/opt_sum.cc

Removing global errbuff and cleaning up two remaining instances that referenced it.

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)
49
49
 
50
50
#include <drizzled/server_includes.h>
51
51
#include <drizzled/sql_select.h>
 
52
#include <drizzled/item/sum.h>
 
53
#include <drizzled/item/cmpfunc.h>
52
54
 
53
55
static bool find_key_for_maxmin(bool max_fl, TABLE_REF *ref, Field* field,
54
56
                                COND *cond, uint32_t *range_fl,
158
160
      statistics (cheap), compute the total number of rows. If there are
159
161
      no outer table dependencies, this count may be used as the real count.
160
162
      Schema tables are filled after this function is invoked, so we can't
161
 
      get row count 
 
163
      get row count
162
164
    */
163
165
    if (!(tl->table->file->ha_table_flags() & HA_STATS_RECORDS_IS_EXACT) ||
164
166
        tl->schema_table)
211
213
            }
212
214
            is_exact_count= 1;                  // count is now exact
213
215
          }
214
 
          ((Item_sum_count*) item)->make_const((int64_t) count);
 
216
          ((Item_sum_count*) item)->make_const_count((int64_t) count);
215
217
          recalc_const_item= 1;
216
218
        }
217
219
        else
235
237
          Item_field *item_field= (Item_field*) (expr->real_item());
236
238
          Table *table= item_field->field->table;
237
239
 
238
 
          /* 
 
240
          /*
239
241
            Look for a partial key that can be used for optimization.
240
242
            If we succeed, ref.key_length will contain the length of
241
 
            this key, while prefix_len will contain the length of 
242
 
            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().
243
245
            Type of range for the key part for this field will be
244
246
            returned in range_fl.
245
247
          */
250
252
            const_result= 0;
251
253
            break;
252
254
          }
253
 
          error= table->file->ha_index_init((uint) ref.key, 1);
 
255
          error= table->file->ha_index_init((uint32_t) ref.key, 1);
254
256
 
255
257
          if (!ref.key_length)
256
258
            error= table->file->index_first(table->record[0]);
257
 
          else 
 
259
          else
258
260
          {
259
261
            /*
260
262
              Use index to replace MIN/MAX functions with their values
261
263
              according to the following rules:
262
 
           
 
264
 
263
265
              1) Insert the minimum non-null values where the WHERE clause still
264
266
                 matches, or
265
267
              2) a NULL value if there are only NULL values for key_part_k.
271
273
              nullable column, test if there is an exact match for the key.
272
274
            */
273
275
            if (!(range_fl & NEAR_MIN))
274
 
              /* 
 
276
              /*
275
277
                 Closed interval: Either The MIN argument is non-nullable, or
276
278
                 we have a >= predicate for the MIN argument.
277
279
              */
288
290
                We need to scan the next bigger record first.
289
291
              */
290
292
              error= table->file->index_read_map(table->record[0],
291
 
                                                 ref.key_buff, 
 
293
                                                 ref.key_buff,
292
294
                                                 make_prev_keypart_map(ref.key_parts),
293
295
                                                 HA_READ_AFTER_KEY);
294
 
              /* 
 
296
              /*
295
297
                 If the found record is outside the group formed by the search
296
298
                 prefix, or there is no such record at all, check if all
297
299
                 records in that group have NULL in the MIN argument
321
323
            }
322
324
          }
323
325
          /* Verify that the read tuple indeed matches the search key */
324
 
          if (!error && reckey_in_range(0, &ref, item_field->field, 
 
326
          if (!error && reckey_in_range(0, &ref, item_field->field,
325
327
                                        conds, range_fl, prefix_len))
326
328
            error= HA_ERR_KEY_NOT_FOUND;
327
329
          if (table->key_read)
383
385
          Item_field *item_field= (Item_field*) (expr->real_item());
384
386
          Table *table= item_field->field->table;
385
387
 
386
 
          /* 
 
388
          /*
387
389
            Look for a partial key that can be used for optimization.
388
390
            If we succeed, ref.key_length will contain the length of
389
 
            this key, while prefix_len will contain the length of 
 
391
            this key, while prefix_len will contain the length of
390
392
            the beginning of this key without field used in MAX().
391
393
            Type of range for the key part for this field will be
392
394
            returned in range_fl.
398
400
            const_result= 0;
399
401
            break;
400
402
          }
401
 
          error= table->file->ha_index_init((uint) ref.key, 1);
 
403
          error= table->file->ha_index_init((uint32_t) ref.key, 1);
402
404
 
403
405
          if (!ref.key_length)
404
406
            error= table->file->index_last(table->record[0]);
591
593
    1        We can use index to get MIN/MAX value
592
594
*/
593
595
 
594
 
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,
595
597
                          KEY_PART_INFO *field_part, COND *cond,
596
598
                          key_part_map *key_part_used, uint32_t *range_fl,
597
599
                          uint32_t *prefix_len)
625
627
    return 0;                                 // Not operator, can't optimize
626
628
 
627
629
  bool eq_type= 0;                            // =, <=> or IS NULL
628
 
  bool noeq_type= 0;                          // < or >  
629
 
  bool less_fl= 0;                            // < or <= 
 
630
  bool noeq_type= 0;                          // < or >
 
631
  bool less_fl= 0;                            // < or <=
630
632
  bool is_null= 0;
631
633
  bool between= 0;
632
634
 
640
642
  case Item_func::LT_FUNC:
641
643
    noeq_type= 1;   /* fall through */
642
644
  case Item_func::LE_FUNC:
643
 
    less_fl= 1;      
 
645
    less_fl= 1;
644
646
    break;
645
647
  case Item_func::GT_FUNC:
646
648
    noeq_type= 1;   /* fall through */
655
657
  default:
656
658
    return 0;                                        // Can't optimize function
657
659
  }
658
 
  
 
660
 
659
661
  Item *args[3];
660
662
  bool inv;
661
663
 
689
691
    if (ref->key_length < length)
690
692
    {
691
693
    /* Ultimately ref->key_length will contain the length of the search key */
692
 
      ref->key_length= length;      
 
694
      ref->key_length= length;
693
695
      ref->key_parts= (part - keyinfo->key_part) + 1;
694
696
    }
695
 
    if (!*prefix_len && part+1 == field_part)       
 
697
    if (!*prefix_len && part+1 == field_part)
696
698
      *prefix_len= length;
697
699
    if (is_field_part && eq_type)
698
700
      *prefix_len= ref->key_length;
699
 
  
 
701
 
700
702
    *key_part_used|= (key_part_map) 1 << (part - keyinfo->key_part);
701
703
  }
702
704
 
703
705
  if (org_key_part_used != *key_part_used ||
704
 
      (is_field_part && 
 
706
      (is_field_part &&
705
707
       (between || eq_type || max_fl == less_fl) && !cond->val_int()))
706
708
  {
707
709
    /*
708
710
      It's the first predicate for this part or a predicate of the
709
711
      following form  that moves upper/lower bounds for max/min values:
710
712
      - field BETWEEN const AND const
711
 
      - field = const 
 
713
      - field = const
712
714
      - field {<|<=} const, when searching for MAX
713
715
      - field {>|>=} const, when searching for MIN
714
716
    */
722
724
    {
723
725
      store_val_in_field(part->field, args[between && max_fl ? 2 : 1],
724
726
                         CHECK_FIELD_IGNORE);
725
 
      if (part->null_bit) 
 
727
      if (part->null_bit)
726
728
        *key_ptr++= (unsigned char) test(part->field->is_null());
727
729
      part->field->get_key_image(key_ptr, part->length, Field::itRAW);
728
730
    }
748
750
  }
749
751
  else if (is_field_part)
750
752
    *range_fl&= ~(max_fl ? NO_MIN_RANGE : NO_MAX_RANGE);
751
 
  return 1;  
 
753
  return 1;
752
754
}
753
755
 
754
756
 
762
764
     -# for each previous component f_i there is one and only one conjunct
763
765
        of the form: f_i= const_i or const_i= f_i or f_i is null
764
766
     -# references to field occur only in conjucts of the form:
765
 
        field {<|<=|>=|>|=} const or const {<|<=|>=|>|=} field or 
 
767
        field {<|<=|>=|>|=} const or const {<|<=|>=|>|=} field or
766
768
        field BETWEEN const1 AND const2
767
769
     -# all references to the columns from the same table as column field
768
770
        occur only in conjucts mentioned above.
794
796
    In this case ref, range_fl and prefix_len are updated
795
797
*/
796
798
 
797
 
      
 
799
 
798
800
static bool find_key_for_maxmin(bool max_fl, TABLE_REF *ref,
799
801
                                Field* field, COND *cond,
800
802
                                uint32_t *range_fl, uint32_t *prefix_len)
849
851
            /*
850
852
              The query is on this form:
851
853
 
852
 
              SELECT MIN(key_part_k) 
853
 
              FROM t1 
 
854
              SELECT MIN(key_part_k)
 
855
              FROM t1
854
856
              WHERE key_part_1 = const and ... and key_part_k-1 = const
855
857
 
856
858
              If key_part_k is nullable, we want to find the first matching row