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