~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));
1253.1.6 by Monty Taylor
Moved mem_root functions into drizzled::memory:: namespace.
53
  memory::init_sql_alloc(&alloc, session->variables.range_alloc_block_size, 0);
1237.13.5 by Padraig O'Sullivan
Split some classes from the range optimizer out in to their own header and implementation files.
54
  return;
55
}
56
57
int optimizer::QuickIndexMergeSelect::init()
58
{
59
  return 0;
60
}
61
62
int optimizer::QuickIndexMergeSelect::reset()
63
{
64
  return (read_keys_and_merge());
65
}
66
67
bool
68
optimizer::QuickIndexMergeSelect::push_quick_back(optimizer::QuickRangeSelect *quick_sel_range)
69
{
70
  /*
71
    Save quick_select that does scan on clustered primary key as it will be
72
    processed separately.
73
  */
74
  if (head->cursor->primary_key_is_clustered() &&
1618 by Brian Aker
This is a rollup set of patches for modifications to TableIdentifier to have
75
      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.
76
  {
77
    pk_quick_select= quick_sel_range;
78
  }
79
  else
80
  {
1237.13.17 by Padraig O'Sullivan
Replaced List with std::vector in the QuickIndexMergeSelect class.
81
    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.
82
  }
1237.13.17 by Padraig O'Sullivan
Replaced List with std::vector in the QuickIndexMergeSelect class.
83
  return false;
1237.13.5 by Padraig O'Sullivan
Split some classes from the range optimizer out in to their own header and implementation files.
84
}
85
86
optimizer::QuickIndexMergeSelect::~QuickIndexMergeSelect()
87
{
1237.13.17 by Padraig O'Sullivan
Replaced List with std::vector in the QuickIndexMergeSelect class.
88
  for (vector<optimizer::QuickRangeSelect *>::iterator it= quick_selects.begin();
89
       it != quick_selects.end();
90
       ++it)
1237.13.5 by Padraig O'Sullivan
Split some classes from the range optimizer out in to their own header and implementation files.
91
  {
1237.13.17 by Padraig O'Sullivan
Replaced List with std::vector in the QuickIndexMergeSelect class.
92
    (*it)->cursor= NULL;
1237.13.5 by Padraig O'Sullivan
Split some classes from the range optimizer out in to their own header and implementation files.
93
  }
1237.13.17 by Padraig O'Sullivan
Replaced List with std::vector in the QuickIndexMergeSelect class.
94
  for_each(quick_selects.begin(),
95
           quick_selects.end(),
96
           DeletePtr());
97
  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.
98
  delete pk_quick_select;
1487 by Brian Aker
More updates for memory::Root
99
  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.
100
  return;
101
}
102
103
104
int optimizer::QuickIndexMergeSelect::read_keys_and_merge()
105
{
1237.13.17 by Padraig O'Sullivan
Replaced List with std::vector in the QuickIndexMergeSelect class.
106
  vector<optimizer::QuickRangeSelect *>::iterator it= quick_selects.begin();
107
  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.
108
  int result;
1237.13.17 by Padraig O'Sullivan
Replaced List with std::vector in the QuickIndexMergeSelect class.
109
  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.
110
  Cursor *cursor= head->cursor;
111
112
  cursor->extra(HA_EXTRA_KEYREAD);
113
  head->prepare_for_position();
114
1237.13.17 by Padraig O'Sullivan
Replaced List with std::vector in the QuickIndexMergeSelect class.
115
  cur_quick= *it;
116
  ++it;
1237.13.5 by Padraig O'Sullivan
Split some classes from the range optimizer out in to their own header and implementation files.
117
  assert(cur_quick != 0);
118
119
  /*
120
    We reuse the same instance of Cursor so we need to call both init and
121
    reset here.
122
  */
123
  if (cur_quick->init() || cur_quick->reset())
124
    return 0;
125
1240.3.1 by Brian Aker
Merge Padraig.
126
  unique= new Unique(refpos_order_cmp,
1237.13.17 by Padraig O'Sullivan
Replaced List with std::vector in the QuickIndexMergeSelect class.
127
                     (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.
128
                     cursor->ref_length,
129
                     session->variables.sortbuff_size);
1237.13.17 by Padraig O'Sullivan
Replaced List with std::vector in the QuickIndexMergeSelect class.
130
  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.
131
    return 0;
132
  for (;;)
133
  {
134
    while ((result= cur_quick->get_next()) == HA_ERR_END_OF_FILE)
135
    {
136
      cur_quick->range_end();
1237.13.17 by Padraig O'Sullivan
Replaced List with std::vector in the QuickIndexMergeSelect class.
137
      if (it == quick_selects.end())
138
      {
139
        break;
140
      }
141
      cur_quick= *it;
142
      ++it;
143
      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.
144
        break;
145
146
      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()
147
        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.
148
      if (cur_quick->init() || cur_quick->reset())
149
        return 0;
150
    }
151
152
    if (result)
153
    {
154
      if (result != HA_ERR_END_OF_FILE)
155
      {
156
        cur_quick->range_end();
157
        return result;
158
      }
159
      break;
160
    }
161
1910.2.8 by Brian Aker
Enapsulate Kill.
162
    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.
163
      return 0;
164
165
    /* skip row if it will be retrieved by clustered PK scan */
166
    if (pk_quick_select && pk_quick_select->row_in_ranges())
167
      continue;
168
169
    cur_quick->cursor->position(cur_quick->record);
1237.13.17 by Padraig O'Sullivan
Replaced List with std::vector in the QuickIndexMergeSelect class.
170
    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.
171
    if (result)
172
      return 0;
173
174
  }
175
176
  /* ok, all row ids are in Unique */
177
  result= unique->get(head);
178
  delete unique;
179
  doing_pk_scan= false;
180
  /* index_merge currently doesn't support "using index" at all */
181
  cursor->extra(HA_EXTRA_NO_KEYREAD);
182
  /* start table scan */
2049.2.1 by Stewart Smith
doStartTableScan() result not checked.
183
  if ((result= read_record.init_read_record(session, head, (optimizer::SqlSelect*) 0, 1, 1)))
184
  {
185
    head->print_error(result, MYF(0));
186
    return 0;
187
  }
1237.13.5 by Padraig O'Sullivan
Split some classes from the range optimizer out in to their own header and implementation files.
188
  return result;
189
}
190
191
192
int optimizer::QuickIndexMergeSelect::get_next()
193
{
194
  int result;
195
196
  if (doing_pk_scan)
197
    return(pk_quick_select->get_next());
198
199
  if ((result= read_record.read_record(&read_record)) == -1)
200
  {
201
    result= HA_ERR_END_OF_FILE;
1538 by Brian Aker
Code shuffle on ReadRecord
202
    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.
203
    /* All rows from Unique have been retrieved, do a clustered PK scan */
204
    if (pk_quick_select)
205
    {
206
      doing_pk_scan= true;
207
      if ((result= pk_quick_select->init()) ||
208
          (result= pk_quick_select->reset()))
209
        return result;
210
      return(pk_quick_select->get_next());
211
    }
212
  }
213
214
  return result;
215
}
216
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.
217
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.
218
{
1237.13.17 by Padraig O'Sullivan
Replaced List with std::vector in the QuickIndexMergeSelect class.
219
  for (vector<optimizer::QuickRangeSelect *>::iterator it= quick_selects.begin();
220
       it != quick_selects.end();
221
       ++it)
1237.13.5 by Padraig O'Sullivan
Split some classes from the range optimizer out in to their own header and implementation files.
222
  {
1237.13.17 by Padraig O'Sullivan
Replaced List with std::vector in the QuickIndexMergeSelect class.
223
    if (is_key_used(head, (*it)->index, fields))
224
    {
1237.13.5 by Padraig O'Sullivan
Split some classes from the range optimizer out in to their own header and implementation files.
225
      return 1;
1237.13.17 by Padraig O'Sullivan
Replaced List with std::vector in the QuickIndexMergeSelect class.
226
    }
1237.13.5 by Padraig O'Sullivan
Split some classes from the range optimizer out in to their own header and implementation files.
227
  }
228
  return 0;
229
}
230
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
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.
233
{
234
  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
235
  str->append("sort_union(");
1237.13.17 by Padraig O'Sullivan
Replaced List with std::vector in the QuickIndexMergeSelect class.
236
  for (vector<optimizer::QuickRangeSelect *>::iterator it= quick_selects.begin();
237
       it != quick_selects.end();
238
       ++it)
1237.13.5 by Padraig O'Sullivan
Split some classes from the range optimizer out in to their own header and implementation files.
239
  {
240
    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
241
      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.
242
    else
243
      first= false;
1237.13.17 by Padraig O'Sullivan
Replaced List with std::vector in the QuickIndexMergeSelect class.
244
    (*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.
245
  }
246
  if (pk_quick_select)
247
  {
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
248
    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.
249
    pk_quick_select->add_info_string(str);
250
  }
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
251
  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.
252
}
253
254
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
255
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
256
                                                            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.
257
{
258
  char buf[64];
1237.13.17 by Padraig O'Sullivan
Replaced List with std::vector in the QuickIndexMergeSelect class.
259
  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.
260
  bool first= true;
261
1237.13.17 by Padraig O'Sullivan
Replaced List with std::vector in the QuickIndexMergeSelect class.
262
  for (vector<optimizer::QuickRangeSelect *>::iterator it= quick_selects.begin();
263
       it != quick_selects.end();
264
       ++it)
1237.13.5 by Padraig O'Sullivan
Split some classes from the range optimizer out in to their own header and implementation files.
265
  {
266
    if (first)
267
      first= false;
268
    else
269
    {
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
270
      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
271
      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.
272
    }
273
1535 by Brian Aker
Rename of KEY to KeyInfo
274
    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.
275
    key_names->append(key_info->name);
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
276
    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.
277
    used_lengths->append(buf, length);
278
  }
279
  if (pk_quick_select)
280
  {
1535 by Brian Aker
Rename of KEY to KeyInfo
281
    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
282
    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.
283
    key_names->append(key_info->name);
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
284
    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
285
    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.
286
    used_lengths->append(buf, length);
287
  }
288
}
289
290
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
291
} /* namespace drizzled */