~drizzle-trunk/drizzle/development

390.1.2 by Monty Taylor
Fixed copyright headers in drizzled/
1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3
 *
4
 *  Copyright (C) 2008 Sun Microsystems
5
 *
6
 *  This program is free software; you can redistribute it and/or modify
7
 *  it under the terms of the GNU General Public License as published by
8
 *  the Free Software Foundation; version 2 of the License.
9
 *
10
 *  This program is distributed in the hope that it will be useful,
11
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 *  GNU General Public License for more details.
14
 *
15
 *  You should have received a copy of the GNU General Public License
16
 *  along with this program; if not, write to the Free Software
17
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18
 */
1 by brian
clean slate
19
20
21
/* classes to use when handling where clause */
22
327.2.3 by Brian Aker
Refactoring of class Table
23
#ifndef DRIZZLED_OPT_RANGE_H
24
#define DRIZZLED_OPT_RANGE_H
1 by brian
clean slate
25
520.8.3 by Monty Taylor
Moved hash back to mysys.
26
#include <mysys/queues.h>
1 by brian
clean slate
27
28
typedef struct st_key_part {
206 by Brian Aker
Removed final uint dead types.
29
  uint16_t           key,part;
1 by brian
clean slate
30
  /* See KEY_PART_INFO for meaning of the next two: */
206 by Brian Aker
Removed final uint dead types.
31
  uint16_t           store_length, length;
32
  uint8_t            null_bit;
1 by brian
clean slate
33
  /*
34
    Keypart flags (0 when this structure is used by partition pruning code
35
    for fake partitioning index description)
36
  */
206 by Brian Aker
Removed final uint dead types.
37
  uint8_t flag;
1 by brian
clean slate
38
  Field            *field;
39
  Field::imagetype image_type;
40
} KEY_PART;
41
42
43
class QUICK_RANGE :public Sql_alloc {
44
 public:
481 by Brian Aker
Remove all of uchar.
45
  unsigned char *min_key,*max_key;
206 by Brian Aker
Removed final uint dead types.
46
  uint16_t min_length,max_length,flag;
1 by brian
clean slate
47
  key_part_map min_keypart_map, // bitmap of used keyparts in min_key
48
               max_keypart_map; // bitmap of used keyparts in max_key
49
#ifdef HAVE_purify
206 by Brian Aker
Removed final uint dead types.
50
  uint16_t dummy;					/* Avoid warnings on 'flag' */
1 by brian
clean slate
51
#endif
52
  QUICK_RANGE();				/* Full range */
482 by Brian Aker
Remove uint.
53
  QUICK_RANGE(const unsigned char *min_key_arg, uint32_t min_length_arg,
1 by brian
clean slate
54
              key_part_map min_keypart_map_arg,
482 by Brian Aker
Remove uint.
55
	      const unsigned char *max_key_arg, uint32_t max_length_arg,
1 by brian
clean slate
56
              key_part_map max_keypart_map_arg,
482 by Brian Aker
Remove uint.
57
	      uint32_t flag_arg)
481 by Brian Aker
Remove all of uchar.
58
    : min_key((unsigned char*) sql_memdup(min_key_arg,min_length_arg+1)),
59
      max_key((unsigned char*) sql_memdup(max_key_arg,max_length_arg+1)),
206 by Brian Aker
Removed final uint dead types.
60
      min_length((uint16_t) min_length_arg),
61
      max_length((uint16_t) max_length_arg),
62
      flag((uint16_t) flag_arg),
1 by brian
clean slate
63
      min_keypart_map(min_keypart_map_arg),
64
      max_keypart_map(max_keypart_map_arg)
65
    {
66
#ifdef HAVE_purify
67
      dummy=0;
68
#endif
69
    }
70
};
71
72
73
/*
74
  Quick select interface.
160.1.2 by mark
remove FTPARSER and last remains of full text search
75
  This class is a parent for all QUICK_*_SELECT classes.
1 by brian
clean slate
76
77
  The usage scenario is as follows:
78
  1. Create quick select
79
    quick= new QUICK_XXX_SELECT(...);
80
81
  2. Perform lightweight initialization. This can be done in 2 ways:
82
  2.a: Regular initialization
83
    if (quick->init())
84
    {
85
      //the only valid action after failed init() call is delete
86
      delete quick;
87
    }
88
  2.b: Special initialization for quick selects merged by QUICK_ROR_*_SELECT
89
    if (quick->init_ror_merged_scan())
90
      delete quick;
91
92
  3. Perform zero, one, or more scans.
93
    while (...)
94
    {
95
      // initialize quick select for scan. This may allocate
96
      // buffers and/or prefetch rows.
97
      if (quick->reset())
98
      {
99
        //the only valid action after failed reset() call is delete
100
        delete quick;
101
        //abort query
102
      }
103
104
      // perform the scan
105
      do
106
      {
107
        res= quick->get_next();
108
      } while (res && ...)
109
    }
110
111
  4. Delete the select:
112
    delete quick;
113
114
*/
115
116
class QUICK_SELECT_I
117
{
118
public:
119
  bool sorted;
120
  ha_rows records;  /* estimate of # of records to be retrieved */
121
  double  read_time; /* time to perform this retrieval          */
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
122
  Table   *head;
1 by brian
clean slate
123
  /*
124
    Index this quick select uses, or MAX_KEY for quick selects
125
    that use several indexes
126
  */
482 by Brian Aker
Remove uint.
127
  uint32_t index;
1 by brian
clean slate
128
129
  /*
130
    Total length of first used_key_parts parts of the key.
131
    Applicable if index!= MAX_KEY.
132
  */
482 by Brian Aker
Remove uint.
133
  uint32_t max_used_key_length;
1 by brian
clean slate
134
135
  /*
136
    Max. number of (first) key parts this quick select uses for retrieval.
137
    eg. for "(key1p1=c1 AND key1p2=c2) OR key1p1=c2" used_key_parts == 2.
138
    Applicable if index!= MAX_KEY.
139
140
    For QUICK_GROUP_MIN_MAX_SELECT it includes MIN/MAX argument keyparts.
141
  */
482 by Brian Aker
Remove uint.
142
  uint32_t used_key_parts;
1 by brian
clean slate
143
144
  QUICK_SELECT_I();
145
  virtual ~QUICK_SELECT_I(){};
146
147
  /*
148
    Do post-constructor initialization.
149
    SYNOPSIS
150
      init()
151
152
    init() performs initializations that should have been in constructor if
153
    it was possible to return errors from constructors. The join optimizer may
154
    create and then delete quick selects without retrieving any rows so init()
155
    must not contain any IO or CPU intensive code.
156
157
    If init() call fails the only valid action is to delete this quick select,
158
    reset() and get_next() must not be called.
159
160
    RETURN
161
      0      OK
162
      other  Error code
163
  */
164
  virtual int  init() = 0;
165
166
  /*
167
    Initialize quick select for row retrieval.
168
    SYNOPSIS
169
      reset()
170
171
    reset() should be called when it is certain that row retrieval will be
172
    necessary. This call may do heavyweight initialization like buffering first
173
    N records etc. If reset() call fails get_next() must not be called.
174
    Note that reset() may be called several times if 
175
     * the quick select is executed in a subselect
176
     * a JOIN buffer is used
177
    
178
    RETURN
179
      0      OK
180
      other  Error code
181
  */
182
  virtual int  reset(void) = 0;
183
184
  virtual int  get_next() = 0;   /* get next record to retrieve */
185
186
  /* Range end should be called when we have looped over the whole index */
187
  virtual void range_end() {}
188
189
  virtual bool reverse_sorted() = 0;
190
  virtual bool unique_key_range() { return false; }
191
192
  enum {
193
    QS_TYPE_RANGE = 0,
194
    QS_TYPE_INDEX_MERGE = 1,
195
    QS_TYPE_RANGE_DESC = 2,
196
    QS_TYPE_ROR_INTERSECT = 4,
197
    QS_TYPE_ROR_UNION = 5,
198
    QS_TYPE_GROUP_MIN_MAX = 6
199
  };
200
201
  /* Get type of this quick select - one of the QS_TYPE_* values */
202
  virtual int get_type() = 0;
203
204
  /*
205
    Initialize this quick select as a merged scan inside a ROR-union or a ROR-
206
    intersection scan. The caller must not additionally call init() if this
207
    function is called.
208
    SYNOPSIS
209
      init_ror_merged_scan()
210
        reuse_handler  If true, the quick select may use table->handler,
211
                       otherwise it must create and use a separate handler
212
                       object.
213
    RETURN
214
      0     Ok
215
      other Error
216
  */
520.9.3 by mordred
zomg. Solaris actually builds all the way!!!
217
  virtual int init_ror_merged_scan(bool)
51.1.11 by Jay Pipes
Removed/replaced all DBUG_XXX statements, all conditional compilation directives for DBUG_OFF, but kept in the optimizer's custom debugging print code for now.
218
  { assert(0); return 1; }
1 by brian
clean slate
219
220
  /*
221
    Save ROWID of last retrieved row in file->ref. This used in ROR-merging.
222
  */
223
  virtual void save_last_pos(){};
224
225
  /*
226
    Append comma-separated list of keys this quick select uses to key_names;
227
    append comma-separated list of corresponding used lengths to used_lengths.
228
    This is used by select_describe.
229
  */
230
  virtual void add_keys_and_lengths(String *key_names,
231
                                    String *used_lengths)=0;
232
233
  /*
234
    Append text representation of quick select structure (what and how is
235
    merged) to str. The result is added to "Extra" field in EXPLAIN output.
236
    This function is implemented only by quick selects that merge other quick
237
    selects output and/or can produce output suitable for merging.
238
  */
520.9.3 by mordred
zomg. Solaris actually builds all the way!!!
239
  virtual void add_info_string(String *) {};
1 by brian
clean slate
240
  /*
241
    Return 1 if any index used by this quick select
242
    uses field which is marked in passed bitmap.
243
  */
244
  virtual bool is_keys_used(const MY_BITMAP *fields);
245
246
  /*
247
    rowid of last row retrieved by this quick select. This is used only when
248
    doing ROR-index_merge selects
249
  */
481 by Brian Aker
Remove all of uchar.
250
  unsigned char    *last_rowid;
1 by brian
clean slate
251
252
  /*
253
    Table record buffer used by this quick select.
254
  */
481 by Brian Aker
Remove all of uchar.
255
  unsigned char    *record;
1 by brian
clean slate
256
};
257
258
259
struct st_qsel_param;
260
class PARAM;
261
class SEL_ARG;
262
263
264
/*
265
  MRR range sequence, array<QUICK_RANGE> implementation: sequence traversal
266
  context.
267
*/
268
typedef struct st_quick_range_seq_ctx
269
{
270
  QUICK_RANGE **first;
271
  QUICK_RANGE **cur;
272
  QUICK_RANGE **last;
273
} QUICK_RANGE_SEQ_CTX;
274
482 by Brian Aker
Remove uint.
275
range_seq_t quick_range_seq_init(void *init_param, uint32_t n_ranges, uint32_t flags);
276
uint32_t quick_range_seq_next(range_seq_t rseq, KEY_MULTI_RANGE *range);
1 by brian
clean slate
277
278
279
/*
280
  Quick select that does a range scan on a single key. The records are
281
  returned in key order.
282
*/
283
class QUICK_RANGE_SELECT : public QUICK_SELECT_I
284
{
285
protected:
286
  handler *file;
287
  DYNAMIC_ARRAY ranges;     /* ordered array of range ptrs */
288
289
  /* Members to deal with case when this quick select is a ROR-merged scan */
290
  bool in_ror_merged_scan;
291
  MY_BITMAP column_bitmap, *save_read_set, *save_write_set;
292
  bool free_file;   /* TRUE <=> this->file is "owned" by this quick select */
293
294
  /* Range pointers to be used when not using MRR interface */
295
  QUICK_RANGE **cur_range;  /* current element in ranges  */
296
  QUICK_RANGE *last_range;
297
  
298
  /* Members needed to use the MRR interface */
299
  QUICK_RANGE_SEQ_CTX qr_traversal_ctx;
300
public:
482 by Brian Aker
Remove uint.
301
  uint32_t mrr_flags; /* Flags to be used with MRR interface */
1 by brian
clean slate
302
protected:
520.1.22 by Brian Aker
Second pass of thd cleanup
303
  uint32_t mrr_buf_size; /* copy from session->variables.read_rnd_buff_size */  
1 by brian
clean slate
304
  HANDLER_BUFFER *mrr_buf_desc; /* the handler buffer */
305
306
  /* Info about index we're scanning */
307
  KEY_PART *key_parts;
308
  KEY_PART_INFO *key_part_info;
309
  
310
  bool dont_free; /* Used by QUICK_SELECT_DESC */
311
312
  int cmp_next(QUICK_RANGE *range);
313
  int cmp_prev(QUICK_RANGE *range);
314
  bool row_in_ranges();
315
public:
316
  MEM_ROOT alloc;
317
520.1.22 by Brian Aker
Second pass of thd cleanup
318
  QUICK_RANGE_SELECT(Session *session, Table *table,uint32_t index_arg,bool no_alloc,
1 by brian
clean slate
319
                     MEM_ROOT *parent_alloc, bool *create_err);
320
  ~QUICK_RANGE_SELECT();
321
322
  int init();
323
  int reset(void);
324
  int get_next();
325
  void range_end();
482 by Brian Aker
Remove uint.
326
  int get_next_prefix(uint32_t prefix_length, key_part_map keypart_map,
481 by Brian Aker
Remove all of uchar.
327
                      unsigned char *cur_prefix);
1 by brian
clean slate
328
  bool reverse_sorted() { return 0; }
329
  bool unique_key_range();
330
  int init_ror_merged_scan(bool reuse_handler);
331
  void save_last_pos()
332
  { file->position(record); }
333
  int get_type() { return QS_TYPE_RANGE; }
334
  void add_keys_and_lengths(String *key_names, String *used_lengths);
335
  void add_info_string(String *str);
336
private:
337
  /* Used only by QUICK_SELECT_DESC */
338
  QUICK_RANGE_SELECT(const QUICK_RANGE_SELECT& org) : QUICK_SELECT_I()
339
  {
212.6.3 by Mats Kindahl
Removing deprecated functions from code and replacing them with C99 equivalents:
340
    memmove(this, &org, sizeof(*this));
1 by brian
clean slate
341
    /* 
342
      Use default MRR implementation for reverse scans. No table engine
343
      currently can do an MRR scan with output in reverse index order.
344
    */
345
    mrr_buf_desc= NULL;
346
    mrr_flags |= HA_MRR_USE_DEFAULT_IMPL;
347
    mrr_buf_size= 0;
348
  }
349
  friend class TRP_ROR_INTERSECT;
350
  friend
520.1.22 by Brian Aker
Second pass of thd cleanup
351
  QUICK_RANGE_SELECT *get_quick_select_for_ref(Session *session, Table *table,
1 by brian
clean slate
352
                                               struct st_table_ref *ref,
353
                                               ha_rows records);
354
  friend bool get_quick_keys(PARAM *param, QUICK_RANGE_SELECT *quick, 
355
                             KEY_PART *key, SEL_ARG *key_tree, 
482 by Brian Aker
Remove uint.
356
                             unsigned char *min_key, uint32_t min_key_flag,
357
                             unsigned char *max_key, uint32_t max_key_flag);
358
  friend QUICK_RANGE_SELECT *get_quick_select(PARAM*,uint32_t idx,
1 by brian
clean slate
359
                                              SEL_ARG *key_tree,
482 by Brian Aker
Remove uint.
360
                                              uint32_t mrr_flags,
361
                                              uint32_t mrr_buf_size,
1 by brian
clean slate
362
                                              MEM_ROOT *alloc);
363
  friend class QUICK_SELECT_DESC;
364
  friend class QUICK_INDEX_MERGE_SELECT;
365
  friend class QUICK_ROR_INTERSECT_SELECT;
366
  friend class QUICK_GROUP_MIN_MAX_SELECT;
482 by Brian Aker
Remove uint.
367
  friend uint32_t quick_range_seq_next(range_seq_t rseq, KEY_MULTI_RANGE *range);
1 by brian
clean slate
368
  friend range_seq_t quick_range_seq_init(void *init_param,
482 by Brian Aker
Remove uint.
369
                                          uint32_t n_ranges, uint32_t flags);
1 by brian
clean slate
370
  friend void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
371
                              bool distinct,const char *message);
372
};
373
374
375
/*
376
  QUICK_INDEX_MERGE_SELECT - index_merge access method quick select.
377
378
    QUICK_INDEX_MERGE_SELECT uses
379
     * QUICK_RANGE_SELECTs to get rows
380
     * Unique class to remove duplicate rows
381
382
  INDEX MERGE OPTIMIZER
383
    Current implementation doesn't detect all cases where index_merge could
384
    be used, in particular:
385
     * index_merge will never be used if range scan is possible (even if
386
       range scan is more expensive)
387
388
     * index_merge+'using index' is not supported (this the consequence of
389
       the above restriction)
390
391
     * If WHERE part contains complex nested AND and OR conditions, some ways
392
       to retrieve rows using index_merge will not be considered. The choice
393
       of read plan may depend on the order of conjuncts/disjuncts in WHERE
394
       part of the query, see comments near imerge_list_or_list and
395
       SEL_IMERGE::or_sel_tree_with_checks functions for details.
396
397
     * There is no "index_merge_ref" method (but index_merge on non-first
398
       table in join is possible with 'range checked for each record').
399
400
    See comments around SEL_IMERGE class and test_quick_select for more
401
    details.
402
403
  ROW RETRIEVAL ALGORITHM
404
405
    index_merge uses Unique class for duplicates removal.  index_merge takes
406
    advantage of Clustered Primary Key (CPK) if the table has one.
407
    The index_merge algorithm consists of two phases:
408
409
    Phase 1 (implemented in QUICK_INDEX_MERGE_SELECT::prepare_unique):
410
    prepare()
411
    {
412
      activate 'index only';
413
      while(retrieve next row for non-CPK scan)
414
      {
415
        if (there is a CPK scan and row will be retrieved by it)
416
          skip this row;
417
        else
418
          put its rowid into Unique;
419
      }
420
      deactivate 'index only';
421
    }
422
423
    Phase 2 (implemented as sequence of QUICK_INDEX_MERGE_SELECT::get_next
424
    calls):
425
426
    fetch()
427
    {
428
      retrieve all rows from row pointers stored in Unique;
429
      free Unique;
430
      retrieve all rows for CPK scan;
431
    }
432
*/
433
434
class QUICK_INDEX_MERGE_SELECT : public QUICK_SELECT_I
435
{
436
public:
520.1.22 by Brian Aker
Second pass of thd cleanup
437
  QUICK_INDEX_MERGE_SELECT(Session *session, Table *table);
1 by brian
clean slate
438
  ~QUICK_INDEX_MERGE_SELECT();
439
440
  int  init();
441
  int  reset(void);
442
  int  get_next();
443
  bool reverse_sorted() { return false; }
444
  bool unique_key_range() { return false; }
445
  int get_type() { return QS_TYPE_INDEX_MERGE; }
446
  void add_keys_and_lengths(String *key_names, String *used_lengths);
447
  void add_info_string(String *str);
448
  bool is_keys_used(const MY_BITMAP *fields);
449
450
  bool push_quick_back(QUICK_RANGE_SELECT *quick_sel_range);
451
452
  /* range quick selects this index_merge read consists of */
453
  List<QUICK_RANGE_SELECT> quick_selects;
454
455
  /* quick select that uses clustered primary key (NULL if none) */
456
  QUICK_RANGE_SELECT* pk_quick_select;
457
458
  /* true if this select is currently doing a clustered PK scan */
459
  bool  doing_pk_scan;
460
461
  MEM_ROOT alloc;
520.1.22 by Brian Aker
Second pass of thd cleanup
462
  Session *session;
1 by brian
clean slate
463
  int read_keys_and_merge();
464
465
  /* used to get rows collected in Unique */
466
  READ_RECORD read_record;
467
};
468
469
470
/*
471
  Rowid-Ordered Retrieval (ROR) index intersection quick select.
472
  This quick select produces intersection of row sequences returned
473
  by several QUICK_RANGE_SELECTs it "merges".
474
475
  All merged QUICK_RANGE_SELECTs must return rowids in rowid order.
476
  QUICK_ROR_INTERSECT_SELECT will return rows in rowid order, too.
477
478
  All merged quick selects retrieve {rowid, covered_fields} tuples (not full
479
  table records).
480
  QUICK_ROR_INTERSECT_SELECT retrieves full records if it is not being used
481
  by QUICK_ROR_INTERSECT_SELECT and all merged quick selects together don't
482
  cover needed all fields.
483
484
  If one of the merged quick selects is a Clustered PK range scan, it is
485
  used only to filter rowid sequence produced by other merged quick selects.
486
*/
487
488
class QUICK_ROR_INTERSECT_SELECT : public QUICK_SELECT_I
489
{
490
public:
520.1.22 by Brian Aker
Second pass of thd cleanup
491
  QUICK_ROR_INTERSECT_SELECT(Session *session, Table *table,
1 by brian
clean slate
492
                             bool retrieve_full_rows,
493
                             MEM_ROOT *parent_alloc);
494
  ~QUICK_ROR_INTERSECT_SELECT();
495
496
  int  init();
497
  int  reset(void);
498
  int  get_next();
499
  bool reverse_sorted() { return false; }
500
  bool unique_key_range() { return false; }
501
  int get_type() { return QS_TYPE_ROR_INTERSECT; }
502
  void add_keys_and_lengths(String *key_names, String *used_lengths);
503
  void add_info_string(String *str);
504
  bool is_keys_used(const MY_BITMAP *fields);
505
  int init_ror_merged_scan(bool reuse_handler);
506
  bool push_quick_back(QUICK_RANGE_SELECT *quick_sel_range);
507
508
  /*
509
    Range quick selects this intersection consists of, not including
510
    cpk_quick.
511
  */
512
  List<QUICK_RANGE_SELECT> quick_selects;
513
514
  /*
515
    Merged quick select that uses Clustered PK, if there is one. This quick
516
    select is not used for row retrieval, it is used for row retrieval.
517
  */
518
  QUICK_RANGE_SELECT *cpk_quick;
519
520
  MEM_ROOT alloc; /* Memory pool for this and merged quick selects data. */
520.1.22 by Brian Aker
Second pass of thd cleanup
521
  Session *session;       /* current thread */
1 by brian
clean slate
522
  bool need_to_fetch_row; /* if true, do retrieve full table records. */
523
  /* in top-level quick select, true if merged scans where initialized */
524
  bool scans_inited; 
525
};
526
527
528
/*
529
  Rowid-Ordered Retrieval index union select.
530
  This quick select produces union of row sequences returned by several
531
  quick select it "merges".
532
533
  All merged quick selects must return rowids in rowid order.
534
  QUICK_ROR_UNION_SELECT will return rows in rowid order, too.
535
536
  All merged quick selects are set not to retrieve full table records.
537
  ROR-union quick select always retrieves full records.
538
539
*/
540
541
class QUICK_ROR_UNION_SELECT : public QUICK_SELECT_I
542
{
543
public:
520.1.22 by Brian Aker
Second pass of thd cleanup
544
  QUICK_ROR_UNION_SELECT(Session *session, Table *table);
1 by brian
clean slate
545
  ~QUICK_ROR_UNION_SELECT();
546
547
  int  init();
548
  int  reset(void);
549
  int  get_next();
550
  bool reverse_sorted() { return false; }
551
  bool unique_key_range() { return false; }
552
  int get_type() { return QS_TYPE_ROR_UNION; }
553
  void add_keys_and_lengths(String *key_names, String *used_lengths);
554
  void add_info_string(String *str);
555
  bool is_keys_used(const MY_BITMAP *fields);
556
557
  bool push_quick_back(QUICK_SELECT_I *quick_sel_range);
558
559
  List<QUICK_SELECT_I> quick_selects; /* Merged quick selects */
560
561
  QUEUE queue;    /* Priority queue for merge operation */
562
  MEM_ROOT alloc; /* Memory pool for this and merged quick selects data. */
563
520.1.22 by Brian Aker
Second pass of thd cleanup
564
  Session *session;             /* current thread */
481 by Brian Aker
Remove all of uchar.
565
  unsigned char *cur_rowid;      /* buffer used in get_next() */
566
  unsigned char *prev_rowid;     /* rowid of last row returned by get_next() */
1 by brian
clean slate
567
  bool have_prev_rowid; /* true if prev_rowid has valid data */
482 by Brian Aker
Remove uint.
568
  uint32_t rowid_length;    /* table rowid length */
1 by brian
clean slate
569
private:
481 by Brian Aker
Remove all of uchar.
570
  static int queue_cmp(void *arg, unsigned char *val1, unsigned char *val2);
1 by brian
clean slate
571
  bool scans_inited; 
572
};
573
574
575
/*
576
  Index scan for GROUP-BY queries with MIN/MAX aggregate functions.
577
578
  This class provides a specialized index access method for GROUP-BY queries
579
  of the forms:
580
581
       SELECT A_1,...,A_k, [B_1,...,B_m], [MIN(C)], [MAX(C)]
582
         FROM T
583
        WHERE [RNG(A_1,...,A_p ; where p <= k)]
584
         [AND EQ(B_1,...,B_m)]
585
         [AND PC(C)]
586
         [AND PA(A_i1,...,A_iq)]
587
       GROUP BY A_1,...,A_k;
588
589
    or
590
591
       SELECT DISTINCT A_i1,...,A_ik
592
         FROM T
593
        WHERE [RNG(A_1,...,A_p ; where p <= k)]
594
         [AND PA(A_i1,...,A_iq)];
595
596
  where all selected fields are parts of the same index.
597
  The class of queries that can be processed by this quick select is fully
598
  specified in the description of get_best_trp_group_min_max() in opt_range.cc.
599
600
  The get_next() method directly produces result tuples, thus obviating the
601
  need to call end_send_group() because all grouping is already done inside
602
  get_next().
603
604
  Since one of the requirements is that all select fields are part of the same
605
  index, this class produces only index keys, and not complete records.
606
*/
607
608
class QUICK_GROUP_MIN_MAX_SELECT : public QUICK_SELECT_I
609
{
610
private:
611
  handler *file;         /* The handler used to get data. */
612
  JOIN *join;            /* Descriptor of the current query */
613
  KEY  *index_info;      /* The index chosen for data access */
481 by Brian Aker
Remove all of uchar.
614
  unsigned char *record;          /* Buffer where the next record is returned. */
615
  unsigned char *tmp_record;      /* Temporary storage for next_min(), next_max(). */
616
  unsigned char *group_prefix;    /* Key prefix consisting of the GROUP fields. */
482 by Brian Aker
Remove uint.
617
  uint32_t group_prefix_len; /* Length of the group prefix. */
618
  uint32_t group_key_parts;  /* A number of keyparts in the group prefix */
481 by Brian Aker
Remove all of uchar.
619
  unsigned char *last_prefix;     /* Prefix of the last group for detecting EOF. */
1 by brian
clean slate
620
  bool have_min;         /* Specify whether we are computing */
621
  bool have_max;         /*   a MIN, a MAX, or both.         */
622
  bool seen_first_key;   /* Denotes whether the first key was retrieved.*/
623
  KEY_PART_INFO *min_max_arg_part; /* The keypart of the only argument field */
624
                                   /* of all MIN/MAX functions.              */
482 by Brian Aker
Remove uint.
625
  uint32_t min_max_arg_len;  /* The length of the MIN/MAX argument field */
481 by Brian Aker
Remove all of uchar.
626
  unsigned char *key_infix;       /* Infix of constants from equality predicates. */
482 by Brian Aker
Remove uint.
627
  uint32_t key_infix_len;
1 by brian
clean slate
628
  DYNAMIC_ARRAY min_max_ranges; /* Array of range ptrs for the MIN/MAX field. */
482 by Brian Aker
Remove uint.
629
  uint32_t real_prefix_len; /* Length of key prefix extended with key_infix. */
630
  uint32_t real_key_parts;  /* A number of keyparts in the above value.      */
1 by brian
clean slate
631
  List<Item_sum> *min_functions;
632
  List<Item_sum> *max_functions;
633
  List_iterator<Item_sum> *min_functions_it;
634
  List_iterator<Item_sum> *max_functions_it;
635
public:
636
  /*
637
    The following two members are public to allow easy access from
638
    TRP_GROUP_MIN_MAX::make_quick()
639
  */
640
  MEM_ROOT alloc; /* Memory pool for this and quick_prefix_select data. */
641
  QUICK_RANGE_SELECT *quick_prefix_select;/* For retrieval of group prefixes. */
642
private:
643
  int  next_prefix();
644
  int  next_min_in_range();
645
  int  next_max_in_range();
646
  int  next_min();
647
  int  next_max();
648
  void update_min_result();
649
  void update_max_result();
650
public:
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
651
  QUICK_GROUP_MIN_MAX_SELECT(Table *table, JOIN *join, bool have_min,
1 by brian
clean slate
652
                             bool have_max, KEY_PART_INFO *min_max_arg_part,
482 by Brian Aker
Remove uint.
653
                             uint32_t group_prefix_len, uint32_t group_key_parts,
654
                             uint32_t used_key_parts, KEY *index_info, uint
1 by brian
clean slate
655
                             use_index, double read_cost, ha_rows records, uint
481 by Brian Aker
Remove all of uchar.
656
                             key_infix_len, unsigned char *key_infix, MEM_ROOT
1 by brian
clean slate
657
                             *parent_alloc);
658
  ~QUICK_GROUP_MIN_MAX_SELECT();
659
  bool add_range(SEL_ARG *sel_range);
660
  void update_key_stat();
661
  void adjust_prefix_ranges();
662
  bool alloc_buffers();
663
  int init();
664
  int reset();
665
  int get_next();
666
  bool reverse_sorted() { return false; }
667
  bool unique_key_range() { return false; }
668
  int get_type() { return QS_TYPE_GROUP_MIN_MAX; }
669
  void add_keys_and_lengths(String *key_names, String *used_lengths);
670
};
671
672
673
class QUICK_SELECT_DESC: public QUICK_RANGE_SELECT
674
{
675
public:
482 by Brian Aker
Remove uint.
676
  QUICK_SELECT_DESC(QUICK_RANGE_SELECT *q, uint32_t used_key_parts, 
1 by brian
clean slate
677
                    bool *create_err);
678
  int get_next();
679
  bool reverse_sorted() { return 1; }
680
  int get_type() { return QS_TYPE_RANGE_DESC; }
681
private:
682
  bool range_reads_after_key(QUICK_RANGE *range);
683
#ifdef NOT_USED
482 by Brian Aker
Remove uint.
684
  bool test_if_null_range(QUICK_RANGE *range, uint32_t used_key_parts);
1 by brian
clean slate
685
#endif
686
  int reset(void) { rev_it.rewind(); return QUICK_RANGE_SELECT::reset(); }
687
  List<QUICK_RANGE> rev_ranges;
688
  List_iterator<QUICK_RANGE> rev_it;
689
};
690
691
692
class SQL_SELECT :public Sql_alloc {
693
 public:
694
  QUICK_SELECT_I *quick;	// If quick-select used
695
  COND		*cond;		// where condition
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
696
  Table	*head;
1 by brian
clean slate
697
  IO_CACHE file;		// Positions to used records
698
  ha_rows records;		// Records in use if read from file
699
  double read_time;		// Time to read rows
700
  key_map quick_keys;		// Possible quick keys
701
  key_map needed_reg;		// Possible quick keys after prev tables.
702
  table_map const_tables,read_tables;
703
  bool	free_cond;
704
705
  SQL_SELECT();
706
  ~SQL_SELECT();
707
  void cleanup();
520.1.22 by Brian Aker
Second pass of thd cleanup
708
  bool check_quick(Session *session, bool force_quick_range, ha_rows limit)
1 by brian
clean slate
709
  {
710
    key_map tmp;
711
    tmp.set_all();
520.1.22 by Brian Aker
Second pass of thd cleanup
712
    return test_quick_select(session, tmp, 0, limit, force_quick_range, false) < 0;
1 by brian
clean slate
713
  }
714
  inline bool skip_record() { return cond ? cond->val_int() == 0 : 0; }
520.1.22 by Brian Aker
Second pass of thd cleanup
715
  int test_quick_select(Session *session, key_map keys, table_map prev_tables,
1 by brian
clean slate
716
			ha_rows limit, bool force_quick_range, 
717
                        bool ordered_output);
718
};
719
520.1.22 by Brian Aker
Second pass of thd cleanup
720
QUICK_RANGE_SELECT *get_quick_select_for_ref(Session *session, Table *table,
1 by brian
clean slate
721
                                             struct st_table_ref *ref,
722
                                             ha_rows records);
482 by Brian Aker
Remove uint.
723
uint32_t get_index_for_order(Table *table, order_st *order, ha_rows limit);
1 by brian
clean slate
724
725
#endif