~drizzle-trunk/drizzle/development

1237.13.5 by Padraig O'Sullivan
Split some classes from the range optimizer out in to their own header and implementation files.
1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3
 *
4
 *  Copyright (C) 2008-2009 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
 */
19
1237.13.8 by Padraig O'Sullivan
Updated an include guard thanks to a nice catch during code review from Jay. Thanks Jay!
20
#ifndef DRIZZLED_OPTIMIZER_QUICK_INDEX_MERGE_SELECT_H
21
#define DRIZZLED_OPTIMIZER_QUICK_INDEX_MERGE_SELECT_H
1237.13.5 by Padraig O'Sullivan
Split some classes from the range optimizer out in to their own header and implementation files.
22
23
#include "drizzled/optimizer/range.h"
24
1237.13.17 by Padraig O'Sullivan
Replaced List with std::vector in the QuickIndexMergeSelect class.
25
#include <vector>
26
1237.13.5 by Padraig O'Sullivan
Split some classes from the range optimizer out in to their own header and implementation files.
27
namespace drizzled
28
{
29
30
namespace optimizer
31
{
32
33
/**
34
  @class QuickIndexMergeSelect - index_merge access method quick select.
35
36
    QuickIndexMergeSelect uses
37
     * QuickRangeSelects to get rows
38
     * Unique class to remove duplicate rows
39
40
  INDEX MERGE OPTIMIZER
41
    Current implementation doesn't detect all cases where index_merge could
42
    be used, in particular:
43
     * index_merge will never be used if range scan is possible (even if
44
       range scan is more expensive)
45
46
     * index_merge+'using index' is not supported (this the consequence of
47
       the above restriction)
48
49
     * If WHERE part contains complex nested AND and OR conditions, some ways
50
       to retrieve rows using index_merge will not be considered. The choice
51
       of read plan may depend on the order of conjuncts/disjuncts in WHERE
52
       part of the query, see comments near imerge_list_or_list and
53
       SEL_IMERGE::or_sel_tree_with_checks functions for details.
54
55
     * There is no "index_merge_ref" method (but index_merge on non-first
56
       table in join is possible with 'range checked for each record').
57
58
    See comments around SEL_IMERGE class and test_quick_select for more
59
    details.
60
61
  ROW RETRIEVAL ALGORITHM
62
63
    index_merge uses Unique class for duplicates removal.  index_merge takes
64
    advantage of Clustered Primary Key (CPK) if the table has one.
65
    The index_merge algorithm consists of two phases:
66
67
    Phase 1 (implemented in QuickIndexMergeSelect::prepare_unique):
68
    prepare()
69
    {
70
      activate 'index only';
71
      while(retrieve next row for non-CPK scan)
72
      {
73
        if (there is a CPK scan and row will be retrieved by it)
74
          skip this row;
75
        else
76
          put its rowid into Unique;
77
      }
78
      deactivate 'index only';
79
    }
80
81
    Phase 2 (implemented as sequence of QuickIndexMergeSelect::get_next
82
    calls):
83
84
    fetch()
85
    {
86
      retrieve all rows from row pointers stored in Unique;
87
      free Unique;
88
      retrieve all rows for CPK scan;
89
    }
90
*/
91
class QuickIndexMergeSelect : public QuickSelectInterface
92
{
93
public:
94
95
  QuickIndexMergeSelect(Session *session, Table *table);
96
97
  ~QuickIndexMergeSelect();
98
99
  int init();
100
  int reset(void);
101
102
  /**
103
   * Get next row for index_merge.
104
   * NOTES
105
   * The rows are read from
106
   * 1. rowids stored in Unique.
107
   * 2. QuickRangeSelect with clustered primary key (if any).
108
   * The sets of rows retrieved in 1) and 2) are guaranteed to be disjoint.
109
   */
110
  int get_next();
111
1237.13.11 by Padraig O'Sullivan
Split the QUICK_ROR_INTERSECT_SELECT class out into its own header and implementation files.
112
  bool reverse_sorted() const
113
  {
114
    return false;
115
  }
116
117
  bool unique_key_range() const
118
  {
119
    return false;
120
  }
121
122
  int get_type() const
1237.13.5 by Padraig O'Sullivan
Split some classes from the range optimizer out in to their own header and implementation files.
123
  {
124
    return QS_TYPE_INDEX_MERGE;
125
  }
126
127
  void add_keys_and_lengths(String *key_names, String *used_lengths);
128
  void add_info_string(String *str);
129
  bool is_keys_used(const MyBitmap *fields);
130
131
  bool push_quick_back(QuickRangeSelect *quick_sel_range);
132
133
  /* range quick selects this index_merge read consists of */
1237.13.17 by Padraig O'Sullivan
Replaced List with std::vector in the QuickIndexMergeSelect class.
134
  std::vector<QuickRangeSelect *> quick_selects;
1237.13.5 by Padraig O'Sullivan
Split some classes from the range optimizer out in to their own header and implementation files.
135
136
  /* quick select that uses clustered primary key (NULL if none) */
1237.13.15 by Padraig O'Sullivan
Used std::vector instead of List in the QuickRorUnionSelect class.
137
  QuickRangeSelect *pk_quick_select;
1237.13.5 by Padraig O'Sullivan
Split some classes from the range optimizer out in to their own header and implementation files.
138
139
  /* true if this select is currently doing a clustered PK scan */
140
  bool  doing_pk_scan;
141
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
142
  memory::Root alloc;
1237.13.5 by Padraig O'Sullivan
Split some classes from the range optimizer out in to their own header and implementation files.
143
  Session *session;
144
145
  /**
146
   * Perform key scans for all used indexes (except CPK), get rowids and merge
147
   * them into an ordered non-recurrent sequence of rowids.
148
   *
149
   * The merge/duplicate removal is performed using Unique class. We put all
150
   * rowids into Unique, get the sorted sequence and destroy the Unique.
151
   *
152
   * If table has a clustered primary key that covers all rows (true for bdb
153
   * and innodb currently) and one of the index_merge scans is a scan on PK,
154
   * then rows that will be retrieved by PK scan are not put into Unique and
155
   * primary key scan is not performed here, it is performed later separately.
156
   *
157
   * RETURN
158
   * @retval 0     OK
159
   * @retval other error
160
   */
161
  int read_keys_and_merge();
162
163
  /* used to get rows collected in Unique */
164
  READ_RECORD read_record;
165
};
166
167
} /* namespace optimizer */
168
169
} /* namespace drizzled */
170
1237.13.8 by Padraig O'Sullivan
Updated an include guard thanks to a nice catch during code review from Jay. Thanks Jay!
171
#endif /* DRIZZLED_OPTIMIZER_QUICK_INDEX_MERGE_SELECT_H */