~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
 *
1999.6.1 by kalebral at gmail
update Copyright strings to a more common format to help with creating the master debian copyright file
4
 *  Copyright (C) 2008-2009 Sun Microsystems, Inc.
1237.13.5 by Padraig O'Sullivan
Split some classes from the range optimizer out in to their own header and implementation files.
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
2173.2.1 by Monty Taylor
Fixes incorrect usage of include
20
#include <config.h>
21
#include <drizzled/session.h>
22
#include <drizzled/records.h>
23
#include <drizzled/util/functors.h>
24
#include <drizzled/optimizer/quick_range_select.h>
25
#include <drizzled/optimizer/quick_index_merge_select.h>
26
#include <drizzled/internal/m_string.h>
2154.2.24 by Brian Aker
Merge in all changes for current_session, etc.
27
#include <drizzled/unique.h>
2198.1.1 by Olaf van der Spek
Remove unnecessary alter* includes
28
#include <drizzled/key.h>
2234.1.3 by Olaf van der Spek
Refactor includes
29
#include <drizzled/table.h>
2241.3.2 by Olaf van der Spek
Refactor Session::variables
30
#include <drizzled/system_variables.h>
1237.13.5 by Padraig O'Sullivan
Split some classes from the range optimizer out in to their own header and implementation files.
31
1237.13.17 by Padraig O'Sullivan
Replaced List with std::vector in the QuickIndexMergeSelect class.
32
#include <vector>
33
34
using namespace std;
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
35
2241.3.2 by Olaf van der Spek
Refactor Session::variables
36
namespace drizzled {
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
37
38
static int refpos_order_cmp(void *arg, const void *a, const void *b)
1237.13.5 by Padraig O'Sullivan
Split some classes from the range optimizer out in to their own header and implementation files.
39
{
40
  Cursor *cursor= (Cursor*)arg;
41
  return cursor->cmp_ref((const unsigned char *) a, (const unsigned char *) b);
42
}
43
44
optimizer::QuickIndexMergeSelect::QuickIndexMergeSelect(Session *session_param,
45
                                                        Table *table)
46
  :
1240.3.1 by Brian Aker
Merge Padraig.
47
    pk_quick_select(NULL),
1237.13.5 by Padraig O'Sullivan
Split some classes from the range optimizer out in to their own header and implementation files.
48
    session(session_param)
49
{
50
  index= MAX_KEY;
51
  head= table;
52
  memset(&read_record, 0, sizeof(read_record));
2318.6.23 by Olaf van der Spek
Refactor
53
  alloc.init(session->variables.range_alloc_block_size);
1237.13.5 by Padraig O'Sullivan
Split some classes from the range optimizer out in to their own header and implementation files.
54
}
55
56
int optimizer::QuickIndexMergeSelect::init()
57
{
58
  return 0;
59
}
60
61
int optimizer::QuickIndexMergeSelect::reset()
62
{
63
  return (read_keys_and_merge());
64
}
65
2318.6.52 by Olaf van der Spek
Refactor
66
void optimizer::QuickIndexMergeSelect::push_quick_back(optimizer::QuickRangeSelect *quick_sel_range)
1237.13.5 by Padraig O'Sullivan
Split some classes from the range optimizer out in to their own header and implementation files.
67
{
68
  /*
69
    Save quick_select that does scan on clustered primary key as it will be
70
    processed separately.
71
  */
72
  if (head->cursor->primary_key_is_clustered() &&
1618 by Brian Aker
This is a rollup set of patches for modifications to TableIdentifier to have
73
      quick_sel_range->index == head->getShare()->getPrimaryKey())
1237.13.5 by Padraig O'Sullivan
Split some classes from the range optimizer out in to their own header and implementation files.
74
  {
75
    pk_quick_select= quick_sel_range;
76
  }
77
  else
78
  {
1237.13.17 by Padraig O'Sullivan
Replaced List with std::vector in the QuickIndexMergeSelect class.
79
    quick_selects.push_back(quick_sel_range);
1237.13.5 by Padraig O'Sullivan
Split some classes from the range optimizer out in to their own header and implementation files.
80
  }
81
}
82
83
optimizer::QuickIndexMergeSelect::~QuickIndexMergeSelect()
84
{
2318.6.52 by Olaf van der Spek
Refactor
85
  BOOST_FOREACH(QuickRangeSelect* it, quick_selects)
86
    it->cursor= NULL;
87
  for_each(quick_selects.begin(), quick_selects.end(), DeletePtr());
1237.13.17 by Padraig O'Sullivan
Replaced List with std::vector in the QuickIndexMergeSelect class.
88
  quick_selects.clear();
1237.13.5 by Padraig O'Sullivan
Split some classes from the range optimizer out in to their own header and implementation files.
89
  delete pk_quick_select;
1487 by Brian Aker
More updates for memory::Root
90
  alloc.free_root(MYF(0));
1237.13.5 by Padraig O'Sullivan
Split some classes from the range optimizer out in to their own header and implementation files.
91
}
92
93
94
int optimizer::QuickIndexMergeSelect::read_keys_and_merge()
95
{
1237.13.17 by Padraig O'Sullivan
Replaced List with std::vector in the QuickIndexMergeSelect class.
96
  vector<optimizer::QuickRangeSelect *>::iterator it= quick_selects.begin();
97
  optimizer::QuickRangeSelect *cur_quick= NULL;
1237.13.5 by Padraig O'Sullivan
Split some classes from the range optimizer out in to their own header and implementation files.
98
  int result;
1237.13.17 by Padraig O'Sullivan
Replaced List with std::vector in the QuickIndexMergeSelect class.
99
  Unique *unique= NULL;
1237.13.5 by Padraig O'Sullivan
Split some classes from the range optimizer out in to their own header and implementation files.
100
  Cursor *cursor= head->cursor;
101
102
  cursor->extra(HA_EXTRA_KEYREAD);
103
  head->prepare_for_position();
104
1237.13.17 by Padraig O'Sullivan
Replaced List with std::vector in the QuickIndexMergeSelect class.
105
  cur_quick= *it;
106
  ++it;
1237.13.5 by Padraig O'Sullivan
Split some classes from the range optimizer out in to their own header and implementation files.
107
  assert(cur_quick != 0);
108
109
  /*
110
    We reuse the same instance of Cursor so we need to call both init and
111
    reset here.
112
  */
113
  if (cur_quick->init() || cur_quick->reset())
114
    return 0;
115
1240.3.1 by Brian Aker
Merge Padraig.
116
  unique= new Unique(refpos_order_cmp,
1237.13.17 by Padraig O'Sullivan
Replaced List with std::vector in the QuickIndexMergeSelect class.
117
                     (void *) cursor,
1237.13.5 by Padraig O'Sullivan
Split some classes from the range optimizer out in to their own header and implementation files.
118
                     cursor->ref_length,
119
                     session->variables.sortbuff_size);
1237.13.17 by Padraig O'Sullivan
Replaced List with std::vector in the QuickIndexMergeSelect class.
120
  if (! unique)
1237.13.5 by Padraig O'Sullivan
Split some classes from the range optimizer out in to their own header and implementation files.
121
    return 0;
122
  for (;;)
123
  {
124
    while ((result= cur_quick->get_next()) == HA_ERR_END_OF_FILE)
125
    {
126
      cur_quick->range_end();
1237.13.17 by Padraig O'Sullivan
Replaced List with std::vector in the QuickIndexMergeSelect class.
127
      if (it == quick_selects.end())
128
      {
129
        break;
130
      }
131
      cur_quick= *it;
132
      ++it;
133
      if (! cur_quick)
1237.13.5 by Padraig O'Sullivan
Split some classes from the range optimizer out in to their own header and implementation files.
134
        break;
135
136
      if (cur_quick->cursor->inited != Cursor::NONE)
1491.1.6 by Jay Pipes
Cursor::ha_index_init() -> Cursor::startIndexScan(). Cursor::ha_index_end() -> Cursor::endIndexScan()
137
        cur_quick->cursor->endIndexScan();
1237.13.5 by Padraig O'Sullivan
Split some classes from the range optimizer out in to their own header and implementation files.
138
      if (cur_quick->init() || cur_quick->reset())
139
        return 0;
140
    }
141
142
    if (result)
143
    {
144
      if (result != HA_ERR_END_OF_FILE)
145
      {
146
        cur_quick->range_end();
147
        return result;
148
      }
149
      break;
150
    }
151
1910.2.8 by Brian Aker
Enapsulate Kill.
152
    if (session->getKilled())
1237.13.5 by Padraig O'Sullivan
Split some classes from the range optimizer out in to their own header and implementation files.
153
      return 0;
154
155
    /* skip row if it will be retrieved by clustered PK scan */
156
    if (pk_quick_select && pk_quick_select->row_in_ranges())
157
      continue;
158
159
    cur_quick->cursor->position(cur_quick->record);
1237.13.17 by Padraig O'Sullivan
Replaced List with std::vector in the QuickIndexMergeSelect class.
160
    result= unique->unique_add((char*) cur_quick->cursor->ref);
1237.13.5 by Padraig O'Sullivan
Split some classes from the range optimizer out in to their own header and implementation files.
161
    if (result)
162
      return 0;
163
164
  }
165
166
  /* ok, all row ids are in Unique */
167
  result= unique->get(head);
168
  delete unique;
169
  doing_pk_scan= false;
170
  /* index_merge currently doesn't support "using index" at all */
171
  cursor->extra(HA_EXTRA_NO_KEYREAD);
172
  /* start table scan */
2049.2.1 by Stewart Smith
doStartTableScan() result not checked.
173
  if ((result= read_record.init_read_record(session, head, (optimizer::SqlSelect*) 0, 1, 1)))
174
  {
175
    head->print_error(result, MYF(0));
176
    return 0;
177
  }
1237.13.5 by Padraig O'Sullivan
Split some classes from the range optimizer out in to their own header and implementation files.
178
  return result;
179
}
180
181
182
int optimizer::QuickIndexMergeSelect::get_next()
183
{
184
  int result;
185
186
  if (doing_pk_scan)
187
    return(pk_quick_select->get_next());
188
189
  if ((result= read_record.read_record(&read_record)) == -1)
190
  {
191
    result= HA_ERR_END_OF_FILE;
1538 by Brian Aker
Code shuffle on ReadRecord
192
    read_record.end_read_record();
1237.13.5 by Padraig O'Sullivan
Split some classes from the range optimizer out in to their own header and implementation files.
193
    /* All rows from Unique have been retrieved, do a clustered PK scan */
194
    if (pk_quick_select)
195
    {
196
      doing_pk_scan= true;
197
      if ((result= pk_quick_select->init()) ||
198
          (result= pk_quick_select->reset()))
199
        return result;
200
      return(pk_quick_select->get_next());
201
    }
202
  }
203
204
  return result;
205
}
206
1802.16.6 by Padraig O'Sullivan
Added temporary conversion of a bitmap to dynamic_bitset in order to remove references to MyBitmap within optimizer code.
207
bool optimizer::QuickIndexMergeSelect::is_keys_used(const boost::dynamic_bitset<>& fields)
1237.13.5 by Padraig O'Sullivan
Split some classes from the range optimizer out in to their own header and implementation files.
208
{
2318.6.64 by Olaf van der Spek
Refactor
209
  BOOST_FOREACH(QuickRangeSelect* it, 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.
210
  {
2318.6.64 by Olaf van der Spek
Refactor
211
    if (is_key_used(head, it->index, fields))
1237.13.5 by Padraig O'Sullivan
Split some classes from the range optimizer out in to their own header and implementation files.
212
      return 1;
213
  }
214
  return 0;
215
}
216
217
2170.4.5 by Stewart Smith
convert explain_plan extra String to std::string. This means that add_info_string() also gets converted to std::string
218
void optimizer::QuickIndexMergeSelect::add_info_string(string *str)
1237.13.5 by Padraig O'Sullivan
Split some classes from the range optimizer out in to their own header and implementation files.
219
{
220
  bool first= true;
2170.4.5 by Stewart Smith
convert explain_plan extra String to std::string. This means that add_info_string() also gets converted to std::string
221
  str->append("sort_union(");
2318.6.64 by Olaf van der Spek
Refactor
222
  BOOST_FOREACH(QuickRangeSelect* it, 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.
223
  {
224
    if (! first)
2170.4.5 by Stewart Smith
convert explain_plan extra String to std::string. This means that add_info_string() also gets converted to std::string
225
      str->append(",");
1237.13.5 by Padraig O'Sullivan
Split some classes from the range optimizer out in to their own header and implementation files.
226
    else
227
      first= false;
2318.6.64 by Olaf van der Spek
Refactor
228
    it->add_info_string(str);
1237.13.5 by Padraig O'Sullivan
Split some classes from the range optimizer out in to their own header and implementation files.
229
  }
230
  if (pk_quick_select)
231
  {
2170.4.5 by Stewart Smith
convert explain_plan extra String to std::string. This means that add_info_string() also gets converted to std::string
232
    str->append(",");
1237.13.5 by Padraig O'Sullivan
Split some classes from the range optimizer out in to their own header and implementation files.
233
    pk_quick_select->add_info_string(str);
234
  }
2170.4.5 by Stewart Smith
convert explain_plan extra String to std::string. This means that add_info_string() also gets converted to std::string
235
  str->append(")");
1237.13.5 by Padraig O'Sullivan
Split some classes from the range optimizer out in to their own header and implementation files.
236
}
237
238
2170.4.3 by Stewart Smith
convert tmp2 in explain_plan to std::string instead of char[] buf and String, consequently also convert add_keys_and_length to deal with std::string for key_names parameter
239
void optimizer::QuickIndexMergeSelect::add_keys_and_lengths(string *key_names,
2170.4.4 by Stewart Smith
tmp3 String to std::string in explain_plan (and used_lengths parameter to add_keys_and_lengths
240
                                                            string *used_lengths)
1237.13.5 by Padraig O'Sullivan
Split some classes from the range optimizer out in to their own header and implementation files.
241
{
242
  char buf[64];
1237.13.17 by Padraig O'Sullivan
Replaced List with std::vector in the QuickIndexMergeSelect class.
243
  uint32_t length= 0;
1237.13.5 by Padraig O'Sullivan
Split some classes from the range optimizer out in to their own header and implementation files.
244
  bool first= true;
245
2318.6.64 by Olaf van der Spek
Refactor
246
  BOOST_FOREACH(QuickRangeSelect* it, 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.
247
  {
248
    if (first)
249
      first= false;
250
    else
251
    {
2170.4.3 by Stewart Smith
convert tmp2 in explain_plan to std::string instead of char[] buf and String, consequently also convert add_keys_and_length to deal with std::string for key_names parameter
252
      key_names->append(",");
2170.4.4 by Stewart Smith
tmp3 String to std::string in explain_plan (and used_lengths parameter to add_keys_and_lengths
253
      used_lengths->append(",");
1237.13.5 by Padraig O'Sullivan
Split some classes from the range optimizer out in to their own header and implementation files.
254
    }
255
2318.6.64 by Olaf van der Spek
Refactor
256
    KeyInfo *key_info= head->key_info + it->index;
1237.13.5 by Padraig O'Sullivan
Split some classes from the range optimizer out in to their own header and implementation files.
257
    key_names->append(key_info->name);
2318.6.64 by Olaf van der Spek
Refactor
258
    length= internal::int64_t2str(it->max_used_key_length, buf, 10) - buf;
1237.13.5 by Padraig O'Sullivan
Split some classes from the range optimizer out in to their own header and implementation files.
259
    used_lengths->append(buf, length);
260
  }
261
  if (pk_quick_select)
262
  {
1535 by Brian Aker
Rename of KEY to KeyInfo
263
    KeyInfo *key_info= head->key_info + pk_quick_select->index;
2170.4.3 by Stewart Smith
convert tmp2 in explain_plan to std::string instead of char[] buf and String, consequently also convert add_keys_and_length to deal with std::string for key_names parameter
264
    key_names->append(",");
1237.13.5 by Padraig O'Sullivan
Split some classes from the range optimizer out in to their own header and implementation files.
265
    key_names->append(key_info->name);
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
266
    length= internal::int64_t2str(pk_quick_select->max_used_key_length, buf, 10) - buf;
2170.4.4 by Stewart Smith
tmp3 String to std::string in explain_plan (and used_lengths parameter to add_keys_and_lengths
267
    used_lengths->append(",");
1237.13.5 by Padraig O'Sullivan
Split some classes from the range optimizer out in to their own header and implementation files.
268
    used_lengths->append(buf, length);
269
  }
270
}
271
272
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
273
} /* namespace drizzled */