~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/opt_range.h

  • Committer: Brian Aker
  • Date: 2009-08-17 01:44:23 UTC
  • mto: This revision was merged to the branch mainline in revision 1118.
  • Revision ID: brian@gaz-20090817014423-jxi2qonsumm8mndf
Remove SQL level reference for DELAY (just now done correctly by default in
engine).

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
2
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3
3
 *
4
 
 *  Copyright (C) 2008-2009 Sun Microsystems, Inc.
 
4
 *  Copyright (C) 2008 Sun Microsystems
5
5
 *
6
6
 *  This program is free software; you can redistribute it and/or modify
7
7
 *  it under the terms of the GNU General Public License as published by
19
19
 
20
20
/* classes to use when handling where clause */
21
21
 
22
 
#ifndef DRIZZLED_OPTIMIZER_RANGE_H
23
 
#define DRIZZLED_OPTIMIZER_RANGE_H
 
22
#ifndef DRIZZLED_OPT_RANGE_H
 
23
#define DRIZZLED_OPT_RANGE_H
24
24
 
25
25
#include <drizzled/field.h>
26
26
#include <drizzled/item/sum.h>
27
 
#include <drizzled/table_reference.h>
28
 
 
29
27
#include <queue>
30
28
 
31
 
#include <boost/dynamic_bitset.hpp>
32
 
 
33
 
namespace drizzled
34
 
{
35
 
 
36
 
class Join;
37
 
class RorIntersectReadPlan; 
 
29
class JOIN;
38
30
typedef class Item COND;
39
31
 
40
 
namespace internal
41
 
{
42
 
typedef struct st_io_cache IO_CACHE;
43
 
}
 
32
typedef struct st_handler_buffer HANDLER_BUFFER;
44
33
 
45
34
typedef struct st_key_part
46
35
{
47
36
  uint16_t key;
48
37
  uint16_t part;
49
 
  /* See KeyPartInfo for meaning of the next two: */
 
38
  /* See KEY_PART_INFO for meaning of the next two: */
50
39
  uint16_t store_length;
51
40
  uint16_t length;
52
41
  uint8_t null_bit;
58
47
  Field *field;
59
48
} KEY_PART;
60
49
 
61
 
 
62
 
namespace optimizer
 
50
class QUICK_RANGE :public Sql_alloc 
63
51
{
64
 
 
65
 
class Parameter;
66
 
class SEL_ARG;
 
52
public:
 
53
  unsigned char *min_key;
 
54
  unsigned char *max_key;
 
55
  uint16_t min_length;
 
56
  uint16_t max_length;
 
57
  uint16_t flag;
 
58
  key_part_map min_keypart_map; /**< bitmap of used keyparts in min_key */
 
59
  key_part_map max_keypart_map; /**< bitmap of used keyparts in max_key */
 
60
#ifdef HAVE_purify
 
61
  uint16_t dummy;                                       /* Avoid warnings on 'flag' */
 
62
#endif
 
63
  QUICK_RANGE(); /**< Constructor for a "full range" */
 
64
  QUICK_RANGE(const unsigned char *min_key_arg,
 
65
              uint32_t min_length_arg,
 
66
              key_part_map min_keypart_map_arg,
 
67
                    const unsigned char *max_key_arg, 
 
68
              uint32_t max_length_arg,
 
69
              key_part_map max_keypart_map_arg,
 
70
                    uint32_t flag_arg)
 
71
    : 
 
72
      min_key((unsigned char*) sql_memdup(min_key_arg,min_length_arg+1)),
 
73
      max_key((unsigned char*) sql_memdup(max_key_arg,max_length_arg+1)),
 
74
      min_length((uint16_t) min_length_arg),
 
75
      max_length((uint16_t) max_length_arg),
 
76
      flag((uint16_t) flag_arg),
 
77
      min_keypart_map(min_keypart_map_arg),
 
78
      max_keypart_map(max_keypart_map_arg)
 
79
    {
 
80
#ifdef HAVE_purify
 
81
      dummy=0;
 
82
#endif
 
83
    }
 
84
};
67
85
 
68
86
/**
69
87
  Quick select interface.
107
125
    delete quick;
108
126
 
109
127
*/
110
 
class QuickSelectInterface
 
128
class QUICK_SELECT_I
111
129
{
112
130
public:
113
131
  bool sorted;
143
161
   */
144
162
  unsigned char *record;
145
163
 
146
 
  QuickSelectInterface();
147
 
  virtual ~QuickSelectInterface(){};
 
164
  QUICK_SELECT_I();
 
165
  virtual ~QUICK_SELECT_I(){};
148
166
 
149
167
  /**
150
168
   * Do post-constructor initialization.
190
208
  /** Range end should be called when we have looped over the whole index */
191
209
  virtual void range_end() {}
192
210
 
193
 
  virtual bool reverse_sorted() const = 0;
194
 
 
195
 
  virtual bool unique_key_range() const
 
211
  virtual bool reverse_sorted() = 0;
 
212
  virtual bool unique_key_range()
196
213
  {
197
214
    return false;
198
215
  }
208
225
  };
209
226
 
210
227
  /** Returns the type of this quick select - one of the QS_TYPE_* values */
211
 
  virtual int get_type() const = 0;
 
228
  virtual int get_type() = 0;
212
229
 
213
230
  /**
214
231
   * Initialize this quick select as a merged scan inside a ROR-union or a ROR-
215
232
   * intersection scan. The caller must not additionally call init() if this
216
233
   * function is called.
217
234
   *
218
 
   * @param If true, the quick select may use table->Cursor,
219
 
   *        otherwise it must create and use a separate Cursor
 
235
   * @param If true, the quick select may use table->handler,
 
236
   *        otherwise it must create and use a separate handler
220
237
   *        object.
221
238
   *
222
239
   * @retval
239
256
   * Append comma-separated list of keys this quick select uses to key_names;
240
257
   * append comma-separated list of corresponding used lengths to used_lengths.
241
258
   * 
242
 
   * @note This is used by during explain plan.
 
259
   * @note This is used by select_describe.
243
260
   */
244
261
  virtual void add_keys_and_lengths(String *key_names, String *used_lengths)=0;
245
262
 
259
276
   * Returns true if any index used by this quick select
260
277
   * uses field which is marked in passed bitmap.
261
278
   */
262
 
  virtual bool is_keys_used(const boost::dynamic_bitset<>& fields);
 
279
  virtual bool is_keys_used(const MY_BITMAP *fields);
263
280
};
264
281
 
265
282
struct st_qsel_param;
266
 
class QuickRange;
267
 
class QuickRangeSelect;
 
283
class PARAM;
 
284
class SEL_ARG;
268
285
 
269
286
/**
270
 
 * MRR range sequence, array<QuickRange> implementation: sequence traversal
 
287
 * MRR range sequence, array<QUICK_RANGE> implementation: sequence traversal
271
288
 * context.
272
289
 */
273
290
typedef struct st_quick_range_seq_ctx
274
291
{
275
 
  QuickRange **first;
276
 
  QuickRange **cur;
277
 
  QuickRange **last;
278
 
} QuickRangeSequenceContext;
 
292
  QUICK_RANGE **first;
 
293
  QUICK_RANGE **cur;
 
294
  QUICK_RANGE **last;
 
295
} QUICK_RANGE_SEQ_CTX;
279
296
 
280
297
range_seq_t quick_range_seq_init(void *init_param, uint32_t n_ranges, uint32_t flags);
281
 
 
282
298
uint32_t quick_range_seq_next(range_seq_t rseq, KEY_MULTI_RANGE *range);
283
299
 
284
300
/**
 
301
 * Quick select that does a range scan on a single key. 
 
302
 *
 
303
 * The records are returned in key order.
 
304
 * 
 
305
 */
 
306
class QUICK_RANGE_SELECT : public QUICK_SELECT_I
 
307
{
 
308
protected:
 
309
  handler *file;
 
310
  DYNAMIC_ARRAY ranges; /**< ordered array of range ptrs */
 
311
 
 
312
  /** Members to deal with case when this quick select is a ROR-merged scan */
 
313
  bool in_ror_merged_scan;
 
314
  MY_BITMAP column_bitmap;
 
315
  MY_BITMAP *save_read_set;
 
316
  MY_BITMAP *save_write_set;
 
317
  bool free_file; /**< True when this->file is "owned" by this quick select */
 
318
 
 
319
  /* Range pointers to be used when not using MRR interface */
 
320
  QUICK_RANGE **cur_range; /**< current element in ranges  */
 
321
  QUICK_RANGE *last_range;
 
322
 
 
323
  /** Members needed to use the MRR interface */
 
324
  QUICK_RANGE_SEQ_CTX qr_traversal_ctx;
 
325
  uint32_t mrr_buf_size; /**< copy from session->variables.read_rnd_buff_size */
 
326
  HANDLER_BUFFER *mrr_buf_desc; /**< the handler buffer */
 
327
 
 
328
  /** Info about index we're scanning */
 
329
  KEY_PART *key_parts;
 
330
  KEY_PART_INFO *key_part_info;
 
331
 
 
332
  bool dont_free; /**< Used by QUICK_SELECT_DESC */
 
333
 
 
334
  int cmp_next(QUICK_RANGE *range);
 
335
  int cmp_prev(QUICK_RANGE *range);
 
336
  bool row_in_ranges();
 
337
public:
 
338
  uint32_t mrr_flags; /**< Flags to be used with MRR interface */
 
339
  MEM_ROOT alloc;
 
340
 
 
341
  QUICK_RANGE_SELECT(Session *session,
 
342
                     Table *table,
 
343
                     uint32_t index_arg,
 
344
                     bool no_alloc,
 
345
                     MEM_ROOT *parent_alloc,
 
346
                     bool *create_err);
 
347
  ~QUICK_RANGE_SELECT();
 
348
 
 
349
  int init();
 
350
  int reset(void);
 
351
  int get_next();
 
352
  void range_end();
 
353
  int get_next_prefix(uint32_t prefix_length,
 
354
                      key_part_map keypart_map,
 
355
                      unsigned char *cur_prefix);
 
356
  bool reverse_sorted()
 
357
  {
 
358
    return false;
 
359
  }
 
360
  bool unique_key_range();
 
361
  int init_ror_merged_scan(bool reuse_handler);
 
362
  void save_last_pos();
 
363
  int get_type()
 
364
  {
 
365
    return QS_TYPE_RANGE;
 
366
  }
 
367
  void add_keys_and_lengths(String *key_names, String *used_lengths);
 
368
  void add_info_string(String *str);
 
369
private:
 
370
  /* Used only by QUICK_SELECT_DESC */
 
371
  QUICK_RANGE_SELECT(const QUICK_RANGE_SELECT& org) : QUICK_SELECT_I()
 
372
  {
 
373
    memmove(this, &org, sizeof(*this));
 
374
    /*
 
375
      Use default MRR implementation for reverse scans. No table engine
 
376
      currently can do an MRR scan with output in reverse index order.
 
377
    */
 
378
    mrr_buf_desc= NULL;
 
379
    mrr_flags|= HA_MRR_USE_DEFAULT_IMPL;
 
380
    mrr_buf_size= 0;
 
381
  }
 
382
  friend class TRP_ROR_INTERSECT;
 
383
  friend
 
384
  QUICK_RANGE_SELECT *get_quick_select_for_ref(Session *session, Table *table,
 
385
                                               struct table_reference_st *ref,
 
386
                                               ha_rows records);
 
387
  friend bool get_quick_keys(PARAM *param, QUICK_RANGE_SELECT *quick,
 
388
                             KEY_PART *key, SEL_ARG *key_tree,
 
389
                             unsigned char *min_key, uint32_t min_key_flag,
 
390
                             unsigned char *max_key, uint32_t max_key_flag);
 
391
  friend QUICK_RANGE_SELECT *get_quick_select(PARAM*,uint32_t idx,
 
392
                                              SEL_ARG *key_tree,
 
393
                                              uint32_t mrr_flags,
 
394
                                              uint32_t mrr_buf_size,
 
395
                                              MEM_ROOT *alloc);
 
396
  friend class QUICK_SELECT_DESC;
 
397
  friend class QUICK_INDEX_MERGE_SELECT;
 
398
  friend class QUICK_ROR_INTERSECT_SELECT;
 
399
  friend class QUICK_GROUP_MIN_MAX_SELECT;
 
400
  friend uint32_t quick_range_seq_next(range_seq_t rseq, KEY_MULTI_RANGE *range);
 
401
  friend range_seq_t quick_range_seq_init(void *init_param,
 
402
                                          uint32_t n_ranges, uint32_t flags);
 
403
  friend void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
 
404
                              bool distinct,const char *message);
 
405
};
 
406
 
 
407
/**
 
408
  QUICK_INDEX_MERGE_SELECT - index_merge access method quick select.
 
409
 
 
410
    QUICK_INDEX_MERGE_SELECT uses
 
411
     * QUICK_RANGE_SELECTs to get rows
 
412
     * Unique class to remove duplicate rows
 
413
 
 
414
  INDEX MERGE OPTIMIZER
 
415
    Current implementation doesn't detect all cases where index_merge could
 
416
    be used, in particular:
 
417
     * index_merge will never be used if range scan is possible (even if
 
418
       range scan is more expensive)
 
419
 
 
420
     * index_merge+'using index' is not supported (this the consequence of
 
421
       the above restriction)
 
422
 
 
423
     * If WHERE part contains complex nested AND and OR conditions, some ways
 
424
       to retrieve rows using index_merge will not be considered. The choice
 
425
       of read plan may depend on the order of conjuncts/disjuncts in WHERE
 
426
       part of the query, see comments near imerge_list_or_list and
 
427
       SEL_IMERGE::or_sel_tree_with_checks functions for details.
 
428
 
 
429
     * There is no "index_merge_ref" method (but index_merge on non-first
 
430
       table in join is possible with 'range checked for each record').
 
431
 
 
432
    See comments around SEL_IMERGE class and test_quick_select for more
 
433
    details.
 
434
 
 
435
  ROW RETRIEVAL ALGORITHM
 
436
 
 
437
    index_merge uses Unique class for duplicates removal.  index_merge takes
 
438
    advantage of Clustered Primary Key (CPK) if the table has one.
 
439
    The index_merge algorithm consists of two phases:
 
440
 
 
441
    Phase 1 (implemented in QUICK_INDEX_MERGE_SELECT::prepare_unique):
 
442
    prepare()
 
443
    {
 
444
      activate 'index only';
 
445
      while(retrieve next row for non-CPK scan)
 
446
      {
 
447
        if (there is a CPK scan and row will be retrieved by it)
 
448
          skip this row;
 
449
        else
 
450
          put its rowid into Unique;
 
451
      }
 
452
      deactivate 'index only';
 
453
    }
 
454
 
 
455
    Phase 2 (implemented as sequence of QUICK_INDEX_MERGE_SELECT::get_next
 
456
    calls):
 
457
 
 
458
    fetch()
 
459
    {
 
460
      retrieve all rows from row pointers stored in Unique;
 
461
      free Unique;
 
462
      retrieve all rows for CPK scan;
 
463
    }
 
464
*/
 
465
class QUICK_INDEX_MERGE_SELECT : public QUICK_SELECT_I
 
466
{
 
467
public:
 
468
  QUICK_INDEX_MERGE_SELECT(Session *session, Table *table);
 
469
  ~QUICK_INDEX_MERGE_SELECT();
 
470
 
 
471
  int init();
 
472
  int reset(void);
 
473
  int get_next();
 
474
  bool reverse_sorted()
 
475
  {
 
476
    return false;
 
477
  }
 
478
  bool unique_key_range()
 
479
  {
 
480
    return false;
 
481
  }
 
482
  int get_type()
 
483
  {
 
484
    return QS_TYPE_INDEX_MERGE;
 
485
  }
 
486
  void add_keys_and_lengths(String *key_names, String *used_lengths);
 
487
  void add_info_string(String *str);
 
488
  bool is_keys_used(const MY_BITMAP *fields);
 
489
 
 
490
  bool push_quick_back(QUICK_RANGE_SELECT *quick_sel_range);
 
491
 
 
492
  /* range quick selects this index_merge read consists of */
 
493
  List<QUICK_RANGE_SELECT> quick_selects;
 
494
 
 
495
  /* quick select that uses clustered primary key (NULL if none) */
 
496
  QUICK_RANGE_SELECT* pk_quick_select;
 
497
 
 
498
  /* true if this select is currently doing a clustered PK scan */
 
499
  bool  doing_pk_scan;
 
500
 
 
501
  MEM_ROOT alloc;
 
502
  Session *session;
 
503
  int read_keys_and_merge();
 
504
 
 
505
  /* used to get rows collected in Unique */
 
506
  READ_RECORD read_record;
 
507
};
 
508
 
 
509
 
 
510
/**
 
511
  Rowid-Ordered Retrieval (ROR) index intersection quick select.
 
512
  This quick select produces intersection of row sequences returned
 
513
  by several QUICK_RANGE_SELECTs it "merges".
 
514
 
 
515
  All merged QUICK_RANGE_SELECTs must return rowids in rowid order.
 
516
  QUICK_ROR_INTERSECT_SELECT will return rows in rowid order, too.
 
517
 
 
518
  All merged quick selects retrieve {rowid, covered_fields} tuples (not full
 
519
  table records).
 
520
  QUICK_ROR_INTERSECT_SELECT retrieves full records if it is not being used
 
521
  by QUICK_ROR_INTERSECT_SELECT and all merged quick selects together don't
 
522
  cover needed all fields.
 
523
 
 
524
  If one of the merged quick selects is a Clustered PK range scan, it is
 
525
  used only to filter rowid sequence produced by other merged quick selects.
 
526
*/
 
527
class QUICK_ROR_INTERSECT_SELECT : public QUICK_SELECT_I
 
528
{
 
529
public:
 
530
  QUICK_ROR_INTERSECT_SELECT(Session *session, Table *table,
 
531
                             bool retrieve_full_rows,
 
532
                             MEM_ROOT *parent_alloc);
 
533
  ~QUICK_ROR_INTERSECT_SELECT();
 
534
 
 
535
  int init();
 
536
  int reset(void);
 
537
  int get_next();
 
538
  bool reverse_sorted()
 
539
  {
 
540
    return false;
 
541
  }
 
542
  bool unique_key_range()
 
543
  {
 
544
    return false;
 
545
  }
 
546
  int get_type()
 
547
  {
 
548
    return QS_TYPE_ROR_INTERSECT;
 
549
  }
 
550
  void add_keys_and_lengths(String *key_names, String *used_lengths);
 
551
  void add_info_string(String *str);
 
552
  bool is_keys_used(const MY_BITMAP *fields);
 
553
  int init_ror_merged_scan(bool reuse_handler);
 
554
  bool push_quick_back(QUICK_RANGE_SELECT *quick_sel_range);
 
555
 
 
556
  /**
 
557
   * Range quick selects this intersection consists of, not including
 
558
   * cpk_quick.
 
559
   */
 
560
  List<QUICK_RANGE_SELECT> quick_selects;
 
561
 
 
562
  /**
 
563
   * Merged quick select that uses Clustered PK, if there is one. This quick
 
564
   * select is not used for row retrieval, it is used for row retrieval.
 
565
   */
 
566
  QUICK_RANGE_SELECT *cpk_quick;
 
567
 
 
568
  MEM_ROOT alloc; /**< Memory pool for this and merged quick selects data. */
 
569
  Session *session; /**< Pointer to the current session */
 
570
  bool need_to_fetch_row; /**< if true, do retrieve full table records. */
 
571
  /** in top-level quick select, true if merged scans where initialized */
 
572
  bool scans_inited;
 
573
};
 
574
 
 
575
 
 
576
/*
 
577
 * This function object is defined in drizzled/opt_range.cc
 
578
 * We need this here for the priority_queue definition in the
 
579
 * QUICK_ROR_UNION_SELECT class.
 
580
 */
 
581
class compare_functor;
 
582
 
 
583
/**
 
584
  Rowid-Ordered Retrieval index union select.
 
585
  This quick select produces union of row sequences returned by several
 
586
  quick select it "merges".
 
587
 
 
588
  All merged quick selects must return rowids in rowid order.
 
589
  QUICK_ROR_UNION_SELECT will return rows in rowid order, too.
 
590
 
 
591
  All merged quick selects are set not to retrieve full table records.
 
592
  ROR-union quick select always retrieves full records.
 
593
 
 
594
*/
 
595
class QUICK_ROR_UNION_SELECT : public QUICK_SELECT_I
 
596
{
 
597
public:
 
598
  QUICK_ROR_UNION_SELECT(Session *session, Table *table);
 
599
  ~QUICK_ROR_UNION_SELECT();
 
600
 
 
601
  int  init();
 
602
  int  reset(void);
 
603
  int  get_next();
 
604
  bool reverse_sorted()
 
605
  {
 
606
    return false;
 
607
  }
 
608
  bool unique_key_range()
 
609
  {
 
610
    return false;
 
611
  }
 
612
  int get_type()
 
613
  {
 
614
    return QS_TYPE_ROR_UNION;
 
615
  }
 
616
  void add_keys_and_lengths(String *key_names, String *used_lengths);
 
617
  void add_info_string(String *str);
 
618
  bool is_keys_used(const MY_BITMAP *fields);
 
619
 
 
620
  bool push_quick_back(QUICK_SELECT_I *quick_sel_range);
 
621
 
 
622
  List<QUICK_SELECT_I> quick_selects; /**< Merged quick selects */
 
623
 
 
624
  /** Priority queue for merge operation */
 
625
  std::priority_queue<QUICK_SELECT_I *, std::vector<QUICK_SELECT_I *>, compare_functor > *queue;
 
626
  MEM_ROOT alloc; /**< Memory pool for this and merged quick selects data. */
 
627
 
 
628
  Session *session; /**< current thread */
 
629
  unsigned char *cur_rowid; /**< buffer used in get_next() */
 
630
  unsigned char *prev_rowid; /**< rowid of last row returned by get_next() */
 
631
  bool have_prev_rowid; /**< true if prev_rowid has valid data */
 
632
  uint32_t rowid_length; /**< table rowid length */
 
633
private:
 
634
  bool scans_inited;
 
635
};
 
636
 
 
637
/**
 
638
  Index scan for GROUP-BY queries with MIN/MAX aggregate functions.
 
639
 
 
640
  This class provides a specialized index access method for GROUP-BY queries
 
641
  of the forms:
 
642
 
 
643
       SELECT A_1,...,A_k, [B_1,...,B_m], [MIN(C)], [MAX(C)]
 
644
         FROM T
 
645
        WHERE [RNG(A_1,...,A_p ; where p <= k)]
 
646
         [AND EQ(B_1,...,B_m)]
 
647
         [AND PC(C)]
 
648
         [AND PA(A_i1,...,A_iq)]
 
649
       GROUP BY A_1,...,A_k;
 
650
 
 
651
    or
 
652
 
 
653
       SELECT DISTINCT A_i1,...,A_ik
 
654
         FROM T
 
655
        WHERE [RNG(A_1,...,A_p ; where p <= k)]
 
656
         [AND PA(A_i1,...,A_iq)];
 
657
 
 
658
  where all selected fields are parts of the same index.
 
659
  The class of queries that can be processed by this quick select is fully
 
660
  specified in the description of get_best_trp_group_min_max() in opt_range.cc.
 
661
 
 
662
  The get_next() method directly produces result tuples, thus obviating the
 
663
  need to call end_send_group() because all grouping is already done inside
 
664
  get_next().
 
665
 
 
666
  Since one of the requirements is that all select fields are part of the same
 
667
  index, this class produces only index keys, and not complete records.
 
668
*/
 
669
class QUICK_GROUP_MIN_MAX_SELECT : public QUICK_SELECT_I
 
670
{
 
671
private:
 
672
  handler *file; /**< The handler used to get data. */
 
673
  JOIN *join; /**< Descriptor of the current query */
 
674
  KEY *index_info; /**< The index chosen for data access */
 
675
  unsigned char *record; /**< Buffer where the next record is returned. */
 
676
  unsigned char *tmp_record; /**< Temporary storage for next_min(), next_max(). */
 
677
  unsigned char *group_prefix; /**< Key prefix consisting of the GROUP fields. */
 
678
  uint32_t group_prefix_len; /**< Length of the group prefix. */
 
679
  uint32_t group_key_parts; /**< A number of keyparts in the group prefix */
 
680
  unsigned char *last_prefix; /**< Prefix of the last group for detecting EOF. */
 
681
  bool have_min; /**< Specify whether we are computing */
 
682
  bool have_max; /**< a MIN, a MAX, or both. */
 
683
  bool seen_first_key; /**< Denotes whether the first key was retrieved.*/
 
684
  KEY_PART_INFO *min_max_arg_part; /** The keypart of the only argument field of all MIN/MAX functions. */
 
685
  uint32_t min_max_arg_len; /**< The length of the MIN/MAX argument field */
 
686
  unsigned char *key_infix; /**< Infix of constants from equality predicates. */
 
687
  uint32_t key_infix_len;
 
688
  DYNAMIC_ARRAY min_max_ranges; /**< Array of range ptrs for the MIN/MAX field. */
 
689
  uint32_t real_prefix_len; /**< Length of key prefix extended with key_infix. */
 
690
  uint32_t real_key_parts;  /**< A number of keyparts in the above value.      */
 
691
  List<Item_sum> *min_functions;
 
692
  List<Item_sum> *max_functions;
 
693
  List_iterator<Item_sum> *min_functions_it;
 
694
  List_iterator<Item_sum> *max_functions_it;
 
695
public:
 
696
  /*
 
697
    The following two members are public to allow easy access from
 
698
    TRP_GROUP_MIN_MAX::make_quick()
 
699
  */
 
700
  MEM_ROOT alloc; /**< Memory pool for this and quick_prefix_select data. */
 
701
  QUICK_RANGE_SELECT *quick_prefix_select; /**< For retrieval of group prefixes. */
 
702
private:
 
703
  int next_prefix();
 
704
  int next_min_in_range();
 
705
  int next_max_in_range();
 
706
  int next_min();
 
707
  int next_max();
 
708
  void update_min_result();
 
709
  void update_max_result();
 
710
public:
 
711
  QUICK_GROUP_MIN_MAX_SELECT(Table *table, JOIN *join, bool have_min,
 
712
                             bool have_max, KEY_PART_INFO *min_max_arg_part,
 
713
                             uint32_t group_prefix_len, uint32_t group_key_parts,
 
714
                             uint32_t used_key_parts, KEY *index_info, uint
 
715
                             use_index, double read_cost, ha_rows records, uint
 
716
                             key_infix_len, unsigned char *key_infix, MEM_ROOT
 
717
                             *parent_alloc);
 
718
  ~QUICK_GROUP_MIN_MAX_SELECT();
 
719
  bool add_range(SEL_ARG *sel_range);
 
720
  void update_key_stat();
 
721
  void adjust_prefix_ranges();
 
722
  bool alloc_buffers();
 
723
  int init();
 
724
  int reset();
 
725
  int get_next();
 
726
  bool reverse_sorted()
 
727
  {
 
728
    return false;
 
729
  }
 
730
  bool unique_key_range()
 
731
  {
 
732
    return false;
 
733
  }
 
734
  int get_type()
 
735
  {
 
736
    return QS_TYPE_GROUP_MIN_MAX;
 
737
  }
 
738
  void add_keys_and_lengths(String *key_names, String *used_lengths);
 
739
};
 
740
 
 
741
class QUICK_SELECT_DESC: public QUICK_RANGE_SELECT
 
742
{
 
743
public:
 
744
  QUICK_SELECT_DESC(QUICK_RANGE_SELECT *q, uint32_t used_key_parts,
 
745
                    bool *create_err);
 
746
  int get_next();
 
747
  bool reverse_sorted() { return 1; }
 
748
  int get_type() { return QS_TYPE_RANGE_DESC; }
 
749
private:
 
750
  bool range_reads_after_key(QUICK_RANGE *range);
 
751
  int reset(void) { rev_it.rewind(); return QUICK_RANGE_SELECT::reset(); }
 
752
  List<QUICK_RANGE> rev_ranges;
 
753
  List_iterator<QUICK_RANGE> rev_it;
 
754
};
 
755
 
 
756
/**
285
757
 * Executor class for SELECT statements.
286
758
 *
287
759
 * @details
288
760
 *
289
 
 * The QuickSelectInterface member variable is the implementor
 
761
 * The QUICK_SELECT_I member variable is the implementor
290
762
 * of the SELECT execution.
291
763
 */
292
 
class SqlSelect : public memory::SqlAlloc 
293
 
{
 
764
class SQL_SELECT :public Sql_alloc {
294
765
 public:
295
 
  QuickSelectInterface *quick; /**< If quick-select used */
 
766
  QUICK_SELECT_I *quick; /**< If quick-select used */
296
767
  COND *cond; /**< where condition */
297
768
  Table *head;
298
 
  internal::IO_CACHE *file; /**< Positions to used records */
 
769
  IO_CACHE file; /**< Positions to used records */
299
770
  ha_rows records; /**< Records in use if read from file */
300
771
  double read_time; /**< Time to read rows */
301
772
  key_map quick_keys; /**< Possible quick keys */
304
775
  table_map read_tables;
305
776
  bool free_cond;
306
777
 
307
 
  SqlSelect();
308
 
  ~SqlSelect();
 
778
  SQL_SELECT();
 
779
  ~SQL_SELECT();
309
780
  void cleanup();
310
781
  bool check_quick(Session *session, bool force_quick_range, ha_rows limit);
311
782
  bool skip_record();
314
785
                        bool ordered_output);
315
786
};
316
787
 
317
 
QuickRangeSelect *get_quick_select_for_ref(Session *session, 
318
 
                                           Table *table,
319
 
                                           table_reference_st *ref,
320
 
                                           ha_rows records);
321
 
 
322
 
/*
323
 
  Create a QuickRangeSelect from given key and SEL_ARG tree for that key.
324
 
 
325
 
  SYNOPSIS
326
 
    get_quick_select()
327
 
      param
328
 
      idx            Index of used key in param->key.
329
 
      key_tree       SEL_ARG tree for the used key
330
 
      mrr_flags      MRR parameter for quick select
331
 
      mrr_buf_size   MRR parameter for quick select
332
 
      parent_alloc   If not NULL, use it to allocate memory for
333
 
                     quick select data. Otherwise use quick->alloc.
334
 
  NOTES
335
 
    The caller must call QUICK_SELECT::init for returned quick select.
336
 
 
337
 
    CAUTION! This function may change session->mem_root to a memory::Root which will be
338
 
    deallocated when the returned quick select is deleted.
339
 
 
340
 
  RETURN
341
 
    NULL on error
342
 
    otherwise created quick select
343
 
*/
344
 
QuickRangeSelect *get_quick_select(Parameter *param,
345
 
                                   uint32_t index,
346
 
                                   SEL_ARG *key_tree, 
347
 
                                   uint32_t mrr_flags,
348
 
                                   uint32_t mrr_buf_size, 
349
 
                                   memory::Root *alloc);
350
 
 
351
 
uint32_t get_index_for_order(Table *table, Order *order, ha_rows limit);
352
 
 
353
 
SqlSelect *make_select(Table *head, 
354
 
                       table_map const_tables,
355
 
                       table_map read_tables, 
356
 
                       COND *conds,
357
 
                       bool allow_null_cond,
358
 
                       int *error);
359
 
 
360
 
bool get_quick_keys(Parameter *param, 
361
 
                    QuickRangeSelect *quick,
362
 
                    KEY_PART *key,
363
 
                    SEL_ARG *key_tree, 
364
 
                    unsigned char *min_key,
365
 
                    uint32_t min_key_flag,
366
 
                    unsigned char *max_key,
367
 
                    uint32_t max_key_flag);
368
 
 
369
 
} /* namespace optimizer */
370
 
 
371
 
} /* namespace drizzled */
372
 
 
373
 
#endif /* DRIZZLED_OPTIMIZER_RANGE_H */
 
788
QUICK_RANGE_SELECT *get_quick_select_for_ref(Session *session, Table *table,
 
789
                                             struct table_reference_st *ref,
 
790
                                             ha_rows records);
 
791
uint32_t get_index_for_order(Table *table, order_st *order, ha_rows limit);
 
792
 
 
793
#endif