~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/opt_range.h

Merged in latest plugin-slot-reorg.

Show diffs side-by-side

added added

removed removed

Lines of Context:
17
17
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18
18
 */
19
19
 
20
 
 
21
20
/* classes to use when handling where clause */
22
21
 
23
22
#ifndef DRIZZLED_OPT_RANGE_H
24
23
#define DRIZZLED_OPT_RANGE_H
25
24
 
26
 
#ifdef USE_PRAGMA_INTERFACE
27
 
#pragma interface                       /* gcc class implementation */
28
 
#endif
29
 
 
30
 
typedef struct st_key_part {
31
 
  uint16_t           key,part;
 
25
#include <drizzled/field.h>
 
26
#include <drizzled/item/sum.h>
 
27
#include <queue>
 
28
 
 
29
class JOIN;
 
30
typedef class Item COND;
 
31
 
 
32
typedef struct st_handler_buffer HANDLER_BUFFER;
 
33
 
 
34
typedef struct st_key_part
 
35
{
 
36
  uint16_t key;
 
37
  uint16_t part;
32
38
  /* See KEY_PART_INFO for meaning of the next two: */
33
 
  uint16_t           store_length, length;
34
 
  uint8_t            null_bit;
35
 
  /*
 
39
  uint16_t store_length;
 
40
  uint16_t length;
 
41
  uint8_t null_bit;
 
42
  /**
36
43
    Keypart flags (0 when this structure is used by partition pruning code
37
44
    for fake partitioning index description)
38
45
  */
39
46
  uint8_t flag;
40
 
  Field            *field;
41
 
  Field::imagetype image_type;
 
47
  Field *field;
42
48
} KEY_PART;
43
49
 
44
 
 
45
 
class QUICK_RANGE :public Sql_alloc {
46
 
 public:
47
 
  unsigned char *min_key,*max_key;
48
 
  uint16_t min_length,max_length,flag;
49
 
  key_part_map min_keypart_map, // bitmap of used keyparts in min_key
50
 
               max_keypart_map; // bitmap of used keyparts in max_key
 
50
class QUICK_RANGE :public Sql_alloc 
 
51
{
 
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 */
51
60
#ifdef HAVE_purify
52
61
  uint16_t dummy;                                       /* Avoid warnings on 'flag' */
53
62
#endif
54
 
  QUICK_RANGE();                                /* Full range */
55
 
  QUICK_RANGE(const unsigned char *min_key_arg, uint32_t min_length_arg,
 
63
  QUICK_RANGE(); /**< Constructor for a "full range" */
 
64
  QUICK_RANGE(const unsigned char *min_key_arg,
 
65
              uint32_t min_length_arg,
56
66
              key_part_map min_keypart_map_arg,
57
 
              const unsigned char *max_key_arg, uint32_t max_length_arg,
 
67
                    const unsigned char *max_key_arg, 
 
68
              uint32_t max_length_arg,
58
69
              key_part_map max_keypart_map_arg,
59
 
              uint32_t flag_arg)
60
 
    : min_key((unsigned char*) sql_memdup(min_key_arg,min_length_arg+1)),
 
70
                    uint32_t flag_arg)
 
71
    : 
 
72
      min_key((unsigned char*) sql_memdup(min_key_arg,min_length_arg+1)),
61
73
      max_key((unsigned char*) sql_memdup(max_key_arg,max_length_arg+1)),
62
74
      min_length((uint16_t) min_length_arg),
63
75
      max_length((uint16_t) max_length_arg),
71
83
    }
72
84
};
73
85
 
74
 
 
75
 
/*
 
86
/**
76
87
  Quick select interface.
77
88
  This class is a parent for all QUICK_*_SELECT classes.
78
89
 
114
125
    delete quick;
115
126
 
116
127
*/
117
 
 
118
128
class QUICK_SELECT_I
119
129
{
120
130
public:
121
131
  bool sorted;
122
 
  ha_rows records;  /* estimate of # of records to be retrieved */
123
 
  double  read_time; /* time to perform this retrieval          */
124
 
  Table   *head;
125
 
  /*
 
132
  ha_rows records; /**< estimate of # of records to be retrieved */
 
133
  double read_time; /**< time to perform this retrieval */
 
134
  Table *head;
 
135
  /**
126
136
    Index this quick select uses, or MAX_KEY for quick selects
127
137
    that use several indexes
128
138
  */
129
139
  uint32_t index;
130
 
 
131
 
  /*
 
140
  /**
132
141
    Total length of first used_key_parts parts of the key.
133
142
    Applicable if index!= MAX_KEY.
134
143
  */
135
144
  uint32_t max_used_key_length;
136
 
 
137
 
  /*
138
 
    Max. number of (first) key parts this quick select uses for retrieval.
 
145
  /**
 
146
    Maximum number of (first) key parts this quick select uses for retrieval.
139
147
    eg. for "(key1p1=c1 AND key1p2=c2) OR key1p1=c2" used_key_parts == 2.
140
148
    Applicable if index!= MAX_KEY.
141
149
 
142
150
    For QUICK_GROUP_MIN_MAX_SELECT it includes MIN/MAX argument keyparts.
143
151
  */
144
152
  uint32_t used_key_parts;
 
153
  /**
 
154
   * The rowid of last row retrieved by this quick select. This is used only when
 
155
   * doing ROR-index_merge selects
 
156
   */
 
157
  unsigned char *last_rowid;
 
158
 
 
159
  /**
 
160
   * Table record buffer used by this quick select.
 
161
   */
 
162
  unsigned char *record;
145
163
 
146
164
  QUICK_SELECT_I();
147
165
  virtual ~QUICK_SELECT_I(){};
148
166
 
149
 
  /*
150
 
    Do post-constructor initialization.
151
 
    SYNOPSIS
152
 
      init()
153
 
 
154
 
    init() performs initializations that should have been in constructor if
155
 
    it was possible to return errors from constructors. The join optimizer may
156
 
    create and then delete quick selects without retrieving any rows so init()
157
 
    must not contain any IO or CPU intensive code.
158
 
 
159
 
    If init() call fails the only valid action is to delete this quick select,
160
 
    reset() and get_next() must not be called.
161
 
 
162
 
    RETURN
163
 
      0      OK
164
 
      other  Error code
165
 
  */
166
 
  virtual int  init() = 0;
167
 
 
168
 
  /*
169
 
    Initialize quick select for row retrieval.
170
 
    SYNOPSIS
171
 
      reset()
172
 
 
173
 
    reset() should be called when it is certain that row retrieval will be
174
 
    necessary. This call may do heavyweight initialization like buffering first
175
 
    N records etc. If reset() call fails get_next() must not be called.
176
 
    Note that reset() may be called several times if 
177
 
     * the quick select is executed in a subselect
178
 
     * a JOIN buffer is used
179
 
    
180
 
    RETURN
181
 
      0      OK
182
 
      other  Error code
183
 
  */
184
 
  virtual int  reset(void) = 0;
185
 
 
186
 
  virtual int  get_next() = 0;   /* get next record to retrieve */
187
 
 
188
 
  /* Range end should be called when we have looped over the whole index */
 
167
  /**
 
168
   * Do post-constructor initialization.
 
169
   *
 
170
   * @details
 
171
   *
 
172
   * Performs initializations that should have been in constructor if
 
173
   * it was possible to return errors from constructors. The join optimizer may
 
174
   * create and then delete quick selects without retrieving any rows so init()
 
175
   * must not contain any IO or CPU intensive code.
 
176
   *
 
177
   * If init() call fails the only valid action is to delete this quick select,
 
178
   * reset() and get_next() must not be called.
 
179
   *
 
180
   * @retval
 
181
   *  0      OK
 
182
   * @retval
 
183
   *  other  Error code
 
184
  */
 
185
  virtual int init() = 0;
 
186
 
 
187
  /**
 
188
   * Initializes quick select for row retrieval.
 
189
   *
 
190
   * @details
 
191
   *
 
192
   * Should be called when it is certain that row retrieval will be
 
193
   * necessary. This call may do heavyweight initialization like buffering first
 
194
   * N records etc. If reset() call fails get_next() must not be called.
 
195
   * Note that reset() may be called several times if
 
196
   * - the quick select is executed in a subselect
 
197
   * - a JOIN buffer is used
 
198
   *
 
199
   * @retval 
 
200
   *  0      OK
 
201
   * @retval
 
202
   *  other  Error code
 
203
   */
 
204
  virtual int reset(void) = 0;
 
205
  /** Gets next record to retrieve */
 
206
  virtual int get_next() = 0;
 
207
 
 
208
  /** Range end should be called when we have looped over the whole index */
189
209
  virtual void range_end() {}
190
210
 
191
211
  virtual bool reverse_sorted() = 0;
192
 
  virtual bool unique_key_range() { return false; }
 
212
  virtual bool unique_key_range()
 
213
  {
 
214
    return false;
 
215
  }
193
216
 
194
 
  enum {
195
 
    QS_TYPE_RANGE = 0,
196
 
    QS_TYPE_INDEX_MERGE = 1,
197
 
    QS_TYPE_RANGE_DESC = 2,
198
 
    QS_TYPE_ROR_INTERSECT = 4,
199
 
    QS_TYPE_ROR_UNION = 5,
200
 
    QS_TYPE_GROUP_MIN_MAX = 6
 
217
  enum 
 
218
  {
 
219
    QS_TYPE_RANGE= 0,
 
220
    QS_TYPE_INDEX_MERGE= 1,
 
221
    QS_TYPE_RANGE_DESC= 2,
 
222
    QS_TYPE_ROR_INTERSECT= 4,
 
223
    QS_TYPE_ROR_UNION= 5,
 
224
    QS_TYPE_GROUP_MIN_MAX= 6
201
225
  };
202
226
 
203
 
  /* Get type of this quick select - one of the QS_TYPE_* values */
 
227
  /** Returns the type of this quick select - one of the QS_TYPE_* values */
204
228
  virtual int get_type() = 0;
205
229
 
206
 
  /*
207
 
    Initialize this quick select as a merged scan inside a ROR-union or a ROR-
208
 
    intersection scan. The caller must not additionally call init() if this
209
 
    function is called.
210
 
    SYNOPSIS
211
 
      init_ror_merged_scan()
212
 
        reuse_handler  If true, the quick select may use table->handler,
213
 
                       otherwise it must create and use a separate handler
214
 
                       object.
215
 
    RETURN
216
 
      0     Ok
217
 
      other Error
218
 
  */
219
 
  virtual int init_ror_merged_scan(bool reuse_handler __attribute__((unused)))
220
 
  { assert(0); return 1; }
 
230
  /**
 
231
   * Initialize this quick select as a merged scan inside a ROR-union or a ROR-
 
232
   * intersection scan. The caller must not additionally call init() if this
 
233
   * function is called.
 
234
   *
 
235
   * @param If true, the quick select may use table->handler,
 
236
   *        otherwise it must create and use a separate handler
 
237
   *        object.
 
238
   *
 
239
   * @retval
 
240
   *  0     Ok
 
241
   * @retval
 
242
   *  other Error
 
243
   */
 
244
  virtual int init_ror_merged_scan(bool)
 
245
  {
 
246
    assert(0);
 
247
    return 1;
 
248
  }
221
249
 
222
 
  /*
223
 
    Save ROWID of last retrieved row in file->ref. This used in ROR-merging.
224
 
  */
 
250
  /**
 
251
   * Save ROWID of last retrieved row in file->ref. This used in ROR-merging.
 
252
   */
225
253
  virtual void save_last_pos(){};
226
254
 
227
 
  /*
228
 
    Append comma-separated list of keys this quick select uses to key_names;
229
 
    append comma-separated list of corresponding used lengths to used_lengths.
230
 
    This is used by select_describe.
231
 
  */
232
 
  virtual void add_keys_and_lengths(String *key_names,
233
 
                                    String *used_lengths)=0;
234
 
 
235
 
  /*
236
 
    Append text representation of quick select structure (what and how is
237
 
    merged) to str. The result is added to "Extra" field in EXPLAIN output.
238
 
    This function is implemented only by quick selects that merge other quick
239
 
    selects output and/or can produce output suitable for merging.
240
 
  */
241
 
  virtual void add_info_string(String *str __attribute__((unused))) {};
242
 
  /*
243
 
    Return 1 if any index used by this quick select
244
 
    uses field which is marked in passed bitmap.
245
 
  */
246
 
  virtual bool is_keys_used(const MY_BITMAP *fields);
247
 
 
248
 
  /*
249
 
    rowid of last row retrieved by this quick select. This is used only when
250
 
    doing ROR-index_merge selects
251
 
  */
252
 
  unsigned char    *last_rowid;
253
 
 
254
 
  /*
255
 
    Table record buffer used by this quick select.
256
 
  */
257
 
  unsigned char    *record;
 
255
  /**
 
256
   * Append comma-separated list of keys this quick select uses to key_names;
 
257
   * append comma-separated list of corresponding used lengths to used_lengths.
 
258
   * 
 
259
   * @note This is used by select_describe.
 
260
   */
 
261
  virtual void add_keys_and_lengths(String *key_names, String *used_lengths)=0;
 
262
 
 
263
  /**
 
264
   * Append text representation of quick select structure (what and how is
 
265
   * merged) to str. The result is added to "Extra" field in EXPLAIN output.
 
266
   *
 
267
   * @note
 
268
   *
 
269
   * This function is implemented only by quick selects that merge other quick
 
270
   * selects output and/or can produce output suitable for merging.
 
271
   */
 
272
  virtual void add_info_string(String *) 
 
273
  {}
 
274
  
 
275
  /**
 
276
   * Returns true if any index used by this quick select
 
277
   * uses field which is marked in passed bitmap.
 
278
   */
 
279
  virtual bool is_keys_used(const MyBitmap *fields);
258
280
};
259
281
 
260
 
 
261
282
struct st_qsel_param;
262
283
class PARAM;
263
284
class SEL_ARG;
264
285
 
265
 
 
266
 
/*
267
 
  MRR range sequence, array<QUICK_RANGE> implementation: sequence traversal
268
 
  context.
269
 
*/
 
286
/**
 
287
 * MRR range sequence, array<QUICK_RANGE> implementation: sequence traversal
 
288
 * context.
 
289
 */
270
290
typedef struct st_quick_range_seq_ctx
271
291
{
272
292
  QUICK_RANGE **first;
277
297
range_seq_t quick_range_seq_init(void *init_param, uint32_t n_ranges, uint32_t flags);
278
298
uint32_t quick_range_seq_next(range_seq_t rseq, KEY_MULTI_RANGE *range);
279
299
 
280
 
 
281
 
/*
282
 
  Quick select that does a range scan on a single key. The records are
283
 
  returned in key order.
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
 */
285
306
class QUICK_RANGE_SELECT : public QUICK_SELECT_I
286
307
{
287
308
protected:
288
309
  handler *file;
289
 
  DYNAMIC_ARRAY ranges;     /* ordered array of range ptrs */
 
310
  DYNAMIC_ARRAY ranges; /**< ordered array of range ptrs */
290
311
 
291
 
  /* Members to deal with case when this quick select is a ROR-merged scan */
 
312
  /** Members to deal with case when this quick select is a ROR-merged scan */
292
313
  bool in_ror_merged_scan;
293
 
  MY_BITMAP column_bitmap, *save_read_set, *save_write_set;
294
 
  bool free_file;   /* TRUE <=> this->file is "owned" by this quick select */
 
314
  MyBitmap column_bitmap;
 
315
  MyBitmap *save_read_set;
 
316
  MyBitmap *save_write_set;
 
317
  bool free_file; /**< True when this->file is "owned" by this quick select */
295
318
 
296
319
  /* Range pointers to be used when not using MRR interface */
297
 
  QUICK_RANGE **cur_range;  /* current element in ranges  */
 
320
  QUICK_RANGE **cur_range; /**< current element in ranges  */
298
321
  QUICK_RANGE *last_range;
299
 
  
300
 
  /* Members needed to use the MRR interface */
 
322
 
 
323
  /** Members needed to use the MRR interface */
301
324
  QUICK_RANGE_SEQ_CTX qr_traversal_ctx;
302
 
public:
303
 
  uint32_t mrr_flags; /* Flags to be used with MRR interface */
304
 
protected:
305
 
  uint32_t mrr_buf_size; /* copy from thd->variables.read_rnd_buff_size */  
306
 
  HANDLER_BUFFER *mrr_buf_desc; /* the handler buffer */
 
325
  uint32_t mrr_buf_size; /**< copy from session->variables.read_rnd_buff_size */
 
326
  HANDLER_BUFFER *mrr_buf_desc; /**< the handler buffer */
307
327
 
308
 
  /* Info about index we're scanning */
 
328
  /** Info about index we're scanning */
309
329
  KEY_PART *key_parts;
310
330
  KEY_PART_INFO *key_part_info;
311
 
  
312
 
  bool dont_free; /* Used by QUICK_SELECT_DESC */
 
331
 
 
332
  bool dont_free; /**< Used by QUICK_SELECT_DESC */
313
333
 
314
334
  int cmp_next(QUICK_RANGE *range);
315
335
  int cmp_prev(QUICK_RANGE *range);
316
336
  bool row_in_ranges();
317
337
public:
 
338
  uint32_t mrr_flags; /**< Flags to be used with MRR interface */
318
339
  MEM_ROOT alloc;
319
340
 
320
 
  QUICK_RANGE_SELECT(THD *thd, Table *table,uint32_t index_arg,bool no_alloc,
321
 
                     MEM_ROOT *parent_alloc, bool *create_err);
 
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);
322
347
  ~QUICK_RANGE_SELECT();
323
348
 
324
349
  int init();
325
350
  int reset(void);
326
351
  int get_next();
327
352
  void range_end();
328
 
  int get_next_prefix(uint32_t prefix_length, key_part_map keypart_map,
 
353
  int get_next_prefix(uint32_t prefix_length,
 
354
                      key_part_map keypart_map,
329
355
                      unsigned char *cur_prefix);
330
 
  bool reverse_sorted() { return 0; }
 
356
  bool reverse_sorted()
 
357
  {
 
358
    return false;
 
359
  }
331
360
  bool unique_key_range();
332
361
  int init_ror_merged_scan(bool reuse_handler);
333
 
  void save_last_pos()
334
 
  { file->position(record); }
335
 
  int get_type() { return QS_TYPE_RANGE; }
 
362
  void save_last_pos();
 
363
  int get_type()
 
364
  {
 
365
    return QS_TYPE_RANGE;
 
366
  }
336
367
  void add_keys_and_lengths(String *key_names, String *used_lengths);
337
368
  void add_info_string(String *str);
338
369
private:
340
371
  QUICK_RANGE_SELECT(const QUICK_RANGE_SELECT& org) : QUICK_SELECT_I()
341
372
  {
342
373
    memmove(this, &org, sizeof(*this));
343
 
    /* 
 
374
    /*
344
375
      Use default MRR implementation for reverse scans. No table engine
345
376
      currently can do an MRR scan with output in reverse index order.
346
377
    */
347
378
    mrr_buf_desc= NULL;
348
 
    mrr_flags |= HA_MRR_USE_DEFAULT_IMPL;
 
379
    mrr_flags|= HA_MRR_USE_DEFAULT_IMPL;
349
380
    mrr_buf_size= 0;
350
381
  }
351
382
  friend class TRP_ROR_INTERSECT;
352
383
  friend
353
 
  QUICK_RANGE_SELECT *get_quick_select_for_ref(THD *thd, Table *table,
354
 
                                               struct st_table_ref *ref,
 
384
  QUICK_RANGE_SELECT *get_quick_select_for_ref(Session *session, Table *table,
 
385
                                               struct table_reference_st *ref,
355
386
                                               ha_rows records);
356
 
  friend bool get_quick_keys(PARAM *param, QUICK_RANGE_SELECT *quick, 
357
 
                             KEY_PART *key, SEL_ARG *key_tree, 
 
387
  friend bool get_quick_keys(PARAM *param, QUICK_RANGE_SELECT *quick,
 
388
                             KEY_PART *key, SEL_ARG *key_tree,
358
389
                             unsigned char *min_key, uint32_t min_key_flag,
359
390
                             unsigned char *max_key, uint32_t max_key_flag);
360
391
  friend QUICK_RANGE_SELECT *get_quick_select(PARAM*,uint32_t idx,
373
404
                              bool distinct,const char *message);
374
405
};
375
406
 
376
 
 
377
 
/*
 
407
/**
378
408
  QUICK_INDEX_MERGE_SELECT - index_merge access method quick select.
379
409
 
380
410
    QUICK_INDEX_MERGE_SELECT uses
432
462
      retrieve all rows for CPK scan;
433
463
    }
434
464
*/
435
 
 
436
465
class QUICK_INDEX_MERGE_SELECT : public QUICK_SELECT_I
437
466
{
438
467
public:
439
 
  QUICK_INDEX_MERGE_SELECT(THD *thd, Table *table);
 
468
  QUICK_INDEX_MERGE_SELECT(Session *session, Table *table);
440
469
  ~QUICK_INDEX_MERGE_SELECT();
441
470
 
442
 
  int  init();
443
 
  int  reset(void);
444
 
  int  get_next();
445
 
  bool reverse_sorted() { return false; }
446
 
  bool unique_key_range() { return false; }
447
 
  int get_type() { return QS_TYPE_INDEX_MERGE; }
 
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
  }
448
486
  void add_keys_and_lengths(String *key_names, String *used_lengths);
449
487
  void add_info_string(String *str);
450
 
  bool is_keys_used(const MY_BITMAP *fields);
 
488
  bool is_keys_used(const MyBitmap *fields);
451
489
 
452
490
  bool push_quick_back(QUICK_RANGE_SELECT *quick_sel_range);
453
491
 
461
499
  bool  doing_pk_scan;
462
500
 
463
501
  MEM_ROOT alloc;
464
 
  THD *thd;
 
502
  Session *session;
465
503
  int read_keys_and_merge();
466
504
 
467
505
  /* used to get rows collected in Unique */
469
507
};
470
508
 
471
509
 
472
 
/*
 
510
/**
473
511
  Rowid-Ordered Retrieval (ROR) index intersection quick select.
474
512
  This quick select produces intersection of row sequences returned
475
513
  by several QUICK_RANGE_SELECTs it "merges".
486
524
  If one of the merged quick selects is a Clustered PK range scan, it is
487
525
  used only to filter rowid sequence produced by other merged quick selects.
488
526
*/
489
 
 
490
527
class QUICK_ROR_INTERSECT_SELECT : public QUICK_SELECT_I
491
528
{
492
529
public:
493
 
  QUICK_ROR_INTERSECT_SELECT(THD *thd, Table *table,
 
530
  QUICK_ROR_INTERSECT_SELECT(Session *session, Table *table,
494
531
                             bool retrieve_full_rows,
495
532
                             MEM_ROOT *parent_alloc);
496
533
  ~QUICK_ROR_INTERSECT_SELECT();
497
534
 
498
 
  int  init();
499
 
  int  reset(void);
500
 
  int  get_next();
501
 
  bool reverse_sorted() { return false; }
502
 
  bool unique_key_range() { return false; }
503
 
  int get_type() { return QS_TYPE_ROR_INTERSECT; }
 
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
  }
504
550
  void add_keys_and_lengths(String *key_names, String *used_lengths);
505
551
  void add_info_string(String *str);
506
 
  bool is_keys_used(const MY_BITMAP *fields);
 
552
  bool is_keys_used(const MyBitmap *fields);
507
553
  int init_ror_merged_scan(bool reuse_handler);
508
554
  bool push_quick_back(QUICK_RANGE_SELECT *quick_sel_range);
509
555
 
510
 
  /*
511
 
    Range quick selects this intersection consists of, not including
512
 
    cpk_quick.
513
 
  */
 
556
  /**
 
557
   * Range quick selects this intersection consists of, not including
 
558
   * cpk_quick.
 
559
   */
514
560
  List<QUICK_RANGE_SELECT> quick_selects;
515
561
 
516
 
  /*
517
 
    Merged quick select that uses Clustered PK, if there is one. This quick
518
 
    select is not used for row retrieval, it is used for row retrieval.
519
 
  */
 
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
   */
520
566
  QUICK_RANGE_SELECT *cpk_quick;
521
567
 
522
 
  MEM_ROOT alloc; /* Memory pool for this and merged quick selects data. */
523
 
  THD *thd;       /* current thread */
524
 
  bool need_to_fetch_row; /* if true, do retrieve full table records. */
525
 
  /* in top-level quick select, true if merged scans where initialized */
526
 
  bool scans_inited; 
 
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;
527
573
};
528
574
 
529
575
 
530
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
/**
531
584
  Rowid-Ordered Retrieval index union select.
532
585
  This quick select produces union of row sequences returned by several
533
586
  quick select it "merges".
539
592
  ROR-union quick select always retrieves full records.
540
593
 
541
594
*/
542
 
 
543
595
class QUICK_ROR_UNION_SELECT : public QUICK_SELECT_I
544
596
{
545
597
public:
546
 
  QUICK_ROR_UNION_SELECT(THD *thd, Table *table);
 
598
  QUICK_ROR_UNION_SELECT(Session *session, Table *table);
547
599
  ~QUICK_ROR_UNION_SELECT();
548
600
 
549
601
  int  init();
550
602
  int  reset(void);
551
603
  int  get_next();
552
 
  bool reverse_sorted() { return false; }
553
 
  bool unique_key_range() { return false; }
554
 
  int get_type() { return QS_TYPE_ROR_UNION; }
 
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
  }
555
616
  void add_keys_and_lengths(String *key_names, String *used_lengths);
556
617
  void add_info_string(String *str);
557
 
  bool is_keys_used(const MY_BITMAP *fields);
 
618
  bool is_keys_used(const MyBitmap *fields);
558
619
 
559
620
  bool push_quick_back(QUICK_SELECT_I *quick_sel_range);
560
621
 
561
 
  List<QUICK_SELECT_I> quick_selects; /* Merged quick selects */
562
 
 
563
 
  QUEUE queue;    /* Priority queue for merge operation */
564
 
  MEM_ROOT alloc; /* Memory pool for this and merged quick selects data. */
565
 
 
566
 
  THD *thd;             /* current thread */
567
 
  unsigned char *cur_rowid;      /* buffer used in get_next() */
568
 
  unsigned char *prev_rowid;     /* rowid of last row returned by get_next() */
569
 
  bool have_prev_rowid; /* true if prev_rowid has valid data */
570
 
  uint32_t rowid_length;    /* table rowid length */
 
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 */
571
633
private:
572
 
  static int queue_cmp(void *arg, unsigned char *val1, unsigned char *val2);
573
 
  bool scans_inited; 
 
634
  bool scans_inited;
574
635
};
575
636
 
576
 
 
577
 
/*
 
637
/**
578
638
  Index scan for GROUP-BY queries with MIN/MAX aggregate functions.
579
639
 
580
640
  This class provides a specialized index access method for GROUP-BY queries
606
666
  Since one of the requirements is that all select fields are part of the same
607
667
  index, this class produces only index keys, and not complete records.
608
668
*/
609
 
 
610
669
class QUICK_GROUP_MIN_MAX_SELECT : public QUICK_SELECT_I
611
670
{
612
671
private:
613
 
  handler *file;         /* The handler used to get data. */
614
 
  JOIN *join;            /* Descriptor of the current query */
615
 
  KEY  *index_info;      /* The index chosen for data access */
616
 
  unsigned char *record;          /* Buffer where the next record is returned. */
617
 
  unsigned char *tmp_record;      /* Temporary storage for next_min(), next_max(). */
618
 
  unsigned char *group_prefix;    /* Key prefix consisting of the GROUP fields. */
619
 
  uint32_t group_prefix_len; /* Length of the group prefix. */
620
 
  uint32_t group_key_parts;  /* A number of keyparts in the group prefix */
621
 
  unsigned char *last_prefix;     /* Prefix of the last group for detecting EOF. */
622
 
  bool have_min;         /* Specify whether we are computing */
623
 
  bool have_max;         /*   a MIN, a MAX, or both.         */
624
 
  bool seen_first_key;   /* Denotes whether the first key was retrieved.*/
625
 
  KEY_PART_INFO *min_max_arg_part; /* The keypart of the only argument field */
626
 
                                   /* of all MIN/MAX functions.              */
627
 
  uint32_t min_max_arg_len;  /* The length of the MIN/MAX argument field */
628
 
  unsigned char *key_infix;       /* Infix of constants from equality predicates. */
 
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. */
629
687
  uint32_t key_infix_len;
630
 
  DYNAMIC_ARRAY min_max_ranges; /* Array of range ptrs for the MIN/MAX field. */
631
 
  uint32_t real_prefix_len; /* Length of key prefix extended with key_infix. */
632
 
  uint32_t real_key_parts;  /* A number of keyparts in the above value.      */
 
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.      */
633
691
  List<Item_sum> *min_functions;
634
692
  List<Item_sum> *max_functions;
635
693
  List_iterator<Item_sum> *min_functions_it;
639
697
    The following two members are public to allow easy access from
640
698
    TRP_GROUP_MIN_MAX::make_quick()
641
699
  */
642
 
  MEM_ROOT alloc; /* Memory pool for this and quick_prefix_select data. */
643
 
  QUICK_RANGE_SELECT *quick_prefix_select;/* For retrieval of group prefixes. */
 
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. */
644
702
private:
645
 
  int  next_prefix();
646
 
  int  next_min_in_range();
647
 
  int  next_max_in_range();
648
 
  int  next_min();
649
 
  int  next_max();
 
703
  int next_prefix();
 
704
  int next_min_in_range();
 
705
  int next_max_in_range();
 
706
  int next_min();
 
707
  int next_max();
650
708
  void update_min_result();
651
709
  void update_max_result();
652
710
public:
665
723
  int init();
666
724
  int reset();
667
725
  int get_next();
668
 
  bool reverse_sorted() { return false; }
669
 
  bool unique_key_range() { return false; }
670
 
  int get_type() { return QS_TYPE_GROUP_MIN_MAX; }
 
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
  }
671
738
  void add_keys_and_lengths(String *key_names, String *used_lengths);
672
739
};
673
740
 
674
 
 
675
741
class QUICK_SELECT_DESC: public QUICK_RANGE_SELECT
676
742
{
677
743
public:
678
 
  QUICK_SELECT_DESC(QUICK_RANGE_SELECT *q, uint32_t used_key_parts, 
 
744
  QUICK_SELECT_DESC(QUICK_RANGE_SELECT *q, uint32_t used_key_parts,
679
745
                    bool *create_err);
680
746
  int get_next();
681
747
  bool reverse_sorted() { return 1; }
682
748
  int get_type() { return QS_TYPE_RANGE_DESC; }
683
749
private:
684
750
  bool range_reads_after_key(QUICK_RANGE *range);
685
 
#ifdef NOT_USED
686
 
  bool test_if_null_range(QUICK_RANGE *range, uint32_t used_key_parts);
687
 
#endif
688
751
  int reset(void) { rev_it.rewind(); return QUICK_RANGE_SELECT::reset(); }
689
752
  List<QUICK_RANGE> rev_ranges;
690
753
  List_iterator<QUICK_RANGE> rev_it;
691
754
};
692
755
 
693
 
 
 
756
/**
 
757
 * Executor class for SELECT statements.
 
758
 *
 
759
 * @details
 
760
 *
 
761
 * The QUICK_SELECT_I member variable is the implementor
 
762
 * of the SELECT execution.
 
763
 */
694
764
class SQL_SELECT :public Sql_alloc {
695
765
 public:
696
 
  QUICK_SELECT_I *quick;        // If quick-select used
697
 
  COND          *cond;          // where condition
 
766
  QUICK_SELECT_I *quick; /**< If quick-select used */
 
767
  COND *cond; /**< where condition */
698
768
  Table *head;
699
 
  IO_CACHE file;                // Positions to used records
700
 
  ha_rows records;              // Records in use if read from file
701
 
  double read_time;             // Time to read rows
702
 
  key_map quick_keys;           // Possible quick keys
703
 
  key_map needed_reg;           // Possible quick keys after prev tables.
704
 
  table_map const_tables,read_tables;
705
 
  bool  free_cond;
 
769
  IO_CACHE file; /**< Positions to used records */
 
770
  ha_rows records; /**< Records in use if read from file */
 
771
  double read_time; /**< Time to read rows */
 
772
  key_map quick_keys; /**< Possible quick keys */
 
773
  key_map needed_reg; /**< Possible quick keys after prev tables. */
 
774
  table_map const_tables;
 
775
  table_map read_tables;
 
776
  bool free_cond;
706
777
 
707
778
  SQL_SELECT();
708
779
  ~SQL_SELECT();
709
780
  void cleanup();
710
 
  bool check_quick(THD *thd, bool force_quick_range, ha_rows limit)
711
 
  {
712
 
    key_map tmp;
713
 
    tmp.set_all();
714
 
    return test_quick_select(thd, tmp, 0, limit, force_quick_range, false) < 0;
715
 
  }
716
 
  inline bool skip_record() { return cond ? cond->val_int() == 0 : 0; }
717
 
  int test_quick_select(THD *thd, key_map keys, table_map prev_tables,
718
 
                        ha_rows limit, bool force_quick_range, 
 
781
  bool check_quick(Session *session, bool force_quick_range, ha_rows limit);
 
782
  bool skip_record();
 
783
  int test_quick_select(Session *session, key_map keys, table_map prev_tables,
 
784
                        ha_rows limit, bool force_quick_range,
719
785
                        bool ordered_output);
720
786
};
721
787
 
722
 
QUICK_RANGE_SELECT *get_quick_select_for_ref(THD *thd, Table *table,
723
 
                                             struct st_table_ref *ref,
 
788
QUICK_RANGE_SELECT *get_quick_select_for_ref(Session *session, Table *table,
 
789
                                             struct table_reference_st *ref,
724
790
                                             ha_rows records);
725
791
uint32_t get_index_for_order(Table *table, order_st *order, ha_rows limit);
726
792