~drizzle-trunk/drizzle/development

1237.13.11 by Padraig O'Sullivan
Split the QUICK_ROR_INTERSECT_SELECT class out into its 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.11 by Padraig O'Sullivan
Split the QUICK_ROR_INTERSECT_SELECT class out into its own header and implementation files.
21
#include "drizzled/session.h"
1237.13.16 by Padraig O'Sullivan
Replaced List with std::vector in the QuickRorIntersectSelect class.
22
#include "drizzled/util/functors.h"
1237.13.11 by Padraig O'Sullivan
Split the QUICK_ROR_INTERSECT_SELECT class out into its own header and implementation files.
23
#include "drizzled/optimizer/range.h"
24
#include "drizzled/optimizer/quick_range_select.h"
25
#include "drizzled/optimizer/quick_ror_intersect_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.11 by Padraig O'Sullivan
Split the QUICK_ROR_INTERSECT_SELECT class out into its own header and implementation files.
27
1237.13.16 by Padraig O'Sullivan
Replaced List with std::vector in the QuickRorIntersectSelect 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
{
1237.13.11 by Padraig O'Sullivan
Split the QUICK_ROR_INTERSECT_SELECT class out into its own header and implementation files.
34
35
1237.13.12 by Padraig O'Sullivan
Corrected the name of the QUICK_ROR_INTERSECT_CLASS class to adhere to the drizzle coding standards.
36
optimizer::QuickRorIntersectSelect::QuickRorIntersectSelect(Session *session_param,
37
                                                            Table *table,
38
                                                            bool retrieve_full_rows,
1253.1.3 by Monty Taylor
MEM_ROOT == memory::Root
39
                                                            memory::Root *parent_alloc)
1237.13.11 by Padraig O'Sullivan
Split the QUICK_ROR_INTERSECT_SELECT class out into its own header and implementation files.
40
  :
41
    cpk_quick(NULL),
42
    session(session_param),
43
    need_to_fetch_row(retrieve_full_rows),
44
    scans_inited(false)
45
{
46
  index= MAX_KEY;
47
  head= table;
48
  record= head->record[0];
49
  if (! parent_alloc)
50
  {
1253.1.6 by Monty Taylor
Moved mem_root functions into drizzled::memory:: namespace.
51
    memory::init_sql_alloc(&alloc, session->variables.range_alloc_block_size, 0);
1237.13.11 by Padraig O'Sullivan
Split the QUICK_ROR_INTERSECT_SELECT class out into its own header and implementation files.
52
  }
53
  else
54
  {
1253.1.3 by Monty Taylor
MEM_ROOT == memory::Root
55
    memset(&alloc, 0, sizeof(memory::Root));
1237.13.11 by Padraig O'Sullivan
Split the QUICK_ROR_INTERSECT_SELECT class out into its own header and implementation files.
56
  }
1485 by Brian Aker
Updates to confine memroot
57
58
  if (parent_alloc)
59
  {
60
    last_rowid= (unsigned char*) parent_alloc->alloc_root(head->cursor->ref_length);
61
  }
62
  else
63
  {
64
    last_rowid= (unsigned char*) alloc.alloc_root(head->cursor->ref_length);
65
  }
1237.13.11 by Padraig O'Sullivan
Split the QUICK_ROR_INTERSECT_SELECT class out into its own header and implementation files.
66
}
67
68
1237.13.12 by Padraig O'Sullivan
Corrected the name of the QUICK_ROR_INTERSECT_CLASS class to adhere to the drizzle coding standards.
69
optimizer::QuickRorIntersectSelect::~QuickRorIntersectSelect()
1237.13.11 by Padraig O'Sullivan
Split the QUICK_ROR_INTERSECT_SELECT class out into its own header and implementation files.
70
{
1237.13.16 by Padraig O'Sullivan
Replaced List with std::vector in the QuickRorIntersectSelect class.
71
  for_each(quick_selects.begin(),
72
           quick_selects.end(),
73
           DeletePtr());
74
  quick_selects.clear();
1237.13.11 by Padraig O'Sullivan
Split the QUICK_ROR_INTERSECT_SELECT class out into its own header and implementation files.
75
  delete cpk_quick;
1487 by Brian Aker
More updates for memory::Root
76
  alloc.free_root(MYF(0));
1237.13.11 by Padraig O'Sullivan
Split the QUICK_ROR_INTERSECT_SELECT class out into its own header and implementation files.
77
  if (need_to_fetch_row && head->cursor->inited != Cursor::NONE)
78
  {
1491.1.10 by Jay Pipes
ha_rnd_init -> startTableScan, rnd_init -> doStartTableScan, ha_rnd_end -> endTableScan, rnd_end -> doEndTableScan
79
    head->cursor->endTableScan();
1237.13.11 by Padraig O'Sullivan
Split the QUICK_ROR_INTERSECT_SELECT class out into its own header and implementation files.
80
  }
81
  return;
82
}
83
84
1237.13.12 by Padraig O'Sullivan
Corrected the name of the QUICK_ROR_INTERSECT_CLASS class to adhere to the drizzle coding standards.
85
int optimizer::QuickRorIntersectSelect::init()
1237.13.11 by Padraig O'Sullivan
Split the QUICK_ROR_INTERSECT_SELECT class out into its own header and implementation files.
86
{
87
 /* Check if last_rowid was successfully allocated in ctor */
88
  return (! last_rowid);
89
}
90
91
1237.13.12 by Padraig O'Sullivan
Corrected the name of the QUICK_ROR_INTERSECT_CLASS class to adhere to the drizzle coding standards.
92
int optimizer::QuickRorIntersectSelect::init_ror_merged_scan(bool reuse_handler)
1237.13.11 by Padraig O'Sullivan
Split the QUICK_ROR_INTERSECT_SELECT class out into its own header and implementation files.
93
{
1237.13.16 by Padraig O'Sullivan
Replaced List with std::vector in the QuickRorIntersectSelect class.
94
  vector<optimizer::QuickRangeSelect *>::iterator it= quick_selects.begin();
1237.13.11 by Padraig O'Sullivan
Split the QUICK_ROR_INTERSECT_SELECT class out into its own header and implementation files.
95
96
  /* Initialize all merged "children" quick selects */
1237.13.16 by Padraig O'Sullivan
Replaced List with std::vector in the QuickRorIntersectSelect class.
97
  assert(! need_to_fetch_row || reuse_handler);
1237.13.11 by Padraig O'Sullivan
Split the QUICK_ROR_INTERSECT_SELECT class out into its own header and implementation files.
98
  if (! need_to_fetch_row && reuse_handler)
99
  {
1237.13.16 by Padraig O'Sullivan
Replaced List with std::vector in the QuickRorIntersectSelect class.
100
    optimizer::QuickRangeSelect *quick= *it;
101
    ++it;
1237.13.11 by Padraig O'Sullivan
Split the QUICK_ROR_INTERSECT_SELECT class out into its own header and implementation files.
102
    /*
103
      There is no use of this->cursor. Use it for the first of merged range
104
      selects.
105
    */
106
    if (quick->init_ror_merged_scan(true))
107
      return 0;
108
    quick->cursor->extra(HA_EXTRA_KEYREAD_PRESERVE_FIELDS);
109
  }
1237.13.16 by Padraig O'Sullivan
Replaced List with std::vector in the QuickRorIntersectSelect class.
110
  while (it != quick_selects.end())
1237.13.11 by Padraig O'Sullivan
Split the QUICK_ROR_INTERSECT_SELECT class out into its own header and implementation files.
111
  {
1237.13.16 by Padraig O'Sullivan
Replaced List with std::vector in the QuickRorIntersectSelect class.
112
    if ((*it)->init_ror_merged_scan(false))
1237.13.11 by Padraig O'Sullivan
Split the QUICK_ROR_INTERSECT_SELECT class out into its own header and implementation files.
113
    {
114
      return 0;
115
    }
1237.13.16 by Padraig O'Sullivan
Replaced List with std::vector in the QuickRorIntersectSelect class.
116
    (*it)->cursor->extra(HA_EXTRA_KEYREAD_PRESERVE_FIELDS);
1237.13.11 by Padraig O'Sullivan
Split the QUICK_ROR_INTERSECT_SELECT class out into its own header and implementation files.
117
    /* All merged scans share the same record buffer in intersection. */
1237.13.16 by Padraig O'Sullivan
Replaced List with std::vector in the QuickRorIntersectSelect class.
118
    (*it)->record= head->record[0];
119
    ++it;
1237.13.11 by Padraig O'Sullivan
Split the QUICK_ROR_INTERSECT_SELECT class out into its own header and implementation files.
120
  }
121
1491.1.10 by Jay Pipes
ha_rnd_init -> startTableScan, rnd_init -> doStartTableScan, ha_rnd_end -> endTableScan, rnd_end -> doEndTableScan
122
  if (need_to_fetch_row && head->cursor->startTableScan(1))
1237.13.11 by Padraig O'Sullivan
Split the QUICK_ROR_INTERSECT_SELECT class out into its own header and implementation files.
123
  {
124
    return 0;
125
  }
126
  return 0;
127
}
128
129
1237.13.12 by Padraig O'Sullivan
Corrected the name of the QUICK_ROR_INTERSECT_CLASS class to adhere to the drizzle coding standards.
130
int optimizer::QuickRorIntersectSelect::reset()
1237.13.11 by Padraig O'Sullivan
Split the QUICK_ROR_INTERSECT_SELECT class out into its own header and implementation files.
131
{
132
  if (! scans_inited && init_ror_merged_scan(true))
133
  {
134
    return 0;
135
  }
136
  scans_inited= true;
1237.13.16 by Padraig O'Sullivan
Replaced List with std::vector in the QuickRorIntersectSelect class.
137
  for (vector<optimizer::QuickRangeSelect *>::iterator it= quick_selects.begin();
138
       it != quick_selects.end();
139
       ++it)
1237.13.11 by Padraig O'Sullivan
Split the QUICK_ROR_INTERSECT_SELECT class out into its own header and implementation files.
140
  {
1237.13.16 by Padraig O'Sullivan
Replaced List with std::vector in the QuickRorIntersectSelect class.
141
    (*it)->reset();
1237.13.11 by Padraig O'Sullivan
Split the QUICK_ROR_INTERSECT_SELECT class out into its own header and implementation files.
142
  }
143
  return 0;
144
}
145
146
147
bool
1237.13.12 by Padraig O'Sullivan
Corrected the name of the QUICK_ROR_INTERSECT_CLASS class to adhere to the drizzle coding standards.
148
optimizer::QuickRorIntersectSelect::push_quick_back(optimizer::QuickRangeSelect *quick)
1237.13.11 by Padraig O'Sullivan
Split the QUICK_ROR_INTERSECT_SELECT class out into its own header and implementation files.
149
{
1237.13.16 by Padraig O'Sullivan
Replaced List with std::vector in the QuickRorIntersectSelect class.
150
  quick_selects.push_back(quick);
151
  return false;
1237.13.11 by Padraig O'Sullivan
Split the QUICK_ROR_INTERSECT_SELECT class out into its own header and implementation files.
152
}
153
154
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.
155
bool optimizer::QuickRorIntersectSelect::is_keys_used(const boost::dynamic_bitset<>& fields)
1237.13.11 by Padraig O'Sullivan
Split the QUICK_ROR_INTERSECT_SELECT class out into its own header and implementation files.
156
{
1237.13.16 by Padraig O'Sullivan
Replaced List with std::vector in the QuickRorIntersectSelect class.
157
  for (vector<optimizer::QuickRangeSelect *>::iterator it= quick_selects.begin();
158
       it != quick_selects.end();
159
       ++it)
1237.13.11 by Padraig O'Sullivan
Split the QUICK_ROR_INTERSECT_SELECT class out into its own header and implementation files.
160
  {
1237.13.16 by Padraig O'Sullivan
Replaced List with std::vector in the QuickRorIntersectSelect class.
161
    if (is_key_used(head, (*it)->index, fields))
162
    {
1237.13.11 by Padraig O'Sullivan
Split the QUICK_ROR_INTERSECT_SELECT class out into its own header and implementation files.
163
      return 1;
1237.13.16 by Padraig O'Sullivan
Replaced List with std::vector in the QuickRorIntersectSelect class.
164
    }
1237.13.11 by Padraig O'Sullivan
Split the QUICK_ROR_INTERSECT_SELECT class out into its own header and implementation files.
165
  }
166
  return 0;
167
}
168
169
1237.13.12 by Padraig O'Sullivan
Corrected the name of the QUICK_ROR_INTERSECT_CLASS class to adhere to the drizzle coding standards.
170
int optimizer::QuickRorIntersectSelect::get_next()
1237.13.11 by Padraig O'Sullivan
Split the QUICK_ROR_INTERSECT_SELECT class out into its own header and implementation files.
171
{
172
  optimizer::QuickRangeSelect *quick= NULL;
1237.13.16 by Padraig O'Sullivan
Replaced List with std::vector in the QuickRorIntersectSelect class.
173
  vector<optimizer::QuickRangeSelect *>::iterator it= quick_selects.begin();
1237.13.11 by Padraig O'Sullivan
Split the QUICK_ROR_INTERSECT_SELECT class out into its own header and implementation files.
174
  int error;
1237.13.16 by Padraig O'Sullivan
Replaced List with std::vector in the QuickRorIntersectSelect class.
175
  int cmp;
1237.13.11 by Padraig O'Sullivan
Split the QUICK_ROR_INTERSECT_SELECT class out into its own header and implementation files.
176
  uint32_t last_rowid_count= 0;
177
178
  do
179
  {
180
    /* Get a rowid for first quick and save it as a 'candidate' */
1237.13.16 by Padraig O'Sullivan
Replaced List with std::vector in the QuickRorIntersectSelect class.
181
    quick= *it;
182
    ++it;
1237.13.11 by Padraig O'Sullivan
Split the QUICK_ROR_INTERSECT_SELECT class out into its own header and implementation files.
183
    error= quick->get_next();
184
    if (cpk_quick)
185
    {
186
      while (! error && ! cpk_quick->row_in_ranges())
187
        error= quick->get_next();
188
    }
189
    if (error)
190
      return error;
191
192
    quick->cursor->position(quick->record);
193
    memcpy(last_rowid, quick->cursor->ref, head->cursor->ref_length);
194
    last_rowid_count= 1;
195
1237.13.16 by Padraig O'Sullivan
Replaced List with std::vector in the QuickRorIntersectSelect class.
196
    while (last_rowid_count < quick_selects.size())
1237.13.11 by Padraig O'Sullivan
Split the QUICK_ROR_INTERSECT_SELECT class out into its own header and implementation files.
197
    {
1237.13.16 by Padraig O'Sullivan
Replaced List with std::vector in the QuickRorIntersectSelect class.
198
      /** @todo: fix this madness!!!! */
199
      if (it != quick_selects.end())
200
      {
201
        quick= *it;
202
        ++it;
203
      }
204
      else
205
      {
206
        it= quick_selects.begin();
207
        quick= *it;
208
        ++it;
1237.13.11 by Padraig O'Sullivan
Split the QUICK_ROR_INTERSECT_SELECT class out into its own header and implementation files.
209
      }
210
211
      do
212
      {
213
        if ((error= quick->get_next()))
1237.13.16 by Padraig O'Sullivan
Replaced List with std::vector in the QuickRorIntersectSelect class.
214
          return error;
1237.13.11 by Padraig O'Sullivan
Split the QUICK_ROR_INTERSECT_SELECT class out into its own header and implementation files.
215
        quick->cursor->position(quick->record);
216
        cmp= head->cursor->cmp_ref(quick->cursor->ref, last_rowid);
217
      } while (cmp < 0);
218
219
      /* Ok, current select 'caught up' and returned ref >= cur_ref */
220
      if (cmp > 0)
221
      {
222
        /* Found a row with ref > cur_ref. Make it a new 'candidate' */
223
        if (cpk_quick)
224
        {
225
          while (! cpk_quick->row_in_ranges())
226
          {
227
            if ((error= quick->get_next()))
228
              return error;
229
          }
230
        }
231
        memcpy(last_rowid, quick->cursor->ref, head->cursor->ref_length);
232
        last_rowid_count= 1;
233
      }
234
      else
235
      {
236
        /* current 'candidate' row confirmed by this select */
237
        last_rowid_count++;
238
      }
239
    }
240
241
    /* We get here if we got the same row ref in all scans. */
242
    if (need_to_fetch_row)
243
      error= head->cursor->rnd_pos(head->record[0], last_rowid);
244
  } while (error == HA_ERR_RECORD_DELETED);
245
  return error;
246
}
247
248
1237.13.12 by Padraig O'Sullivan
Corrected the name of the QUICK_ROR_INTERSECT_CLASS class to adhere to the drizzle coding standards.
249
void optimizer::QuickRorIntersectSelect::add_info_string(String *str)
1237.13.11 by Padraig O'Sullivan
Split the QUICK_ROR_INTERSECT_SELECT class out into its own header and implementation files.
250
{
251
  bool first= true;
252
  str->append(STRING_WITH_LEN("intersect("));
1237.13.16 by Padraig O'Sullivan
Replaced List with std::vector in the QuickRorIntersectSelect class.
253
  for (vector<optimizer::QuickRangeSelect *>::iterator it= quick_selects.begin();
254
       it != quick_selects.end();
255
       ++it)
1237.13.11 by Padraig O'Sullivan
Split the QUICK_ROR_INTERSECT_SELECT class out into its own header and implementation files.
256
  {
1535 by Brian Aker
Rename of KEY to KeyInfo
257
    KeyInfo *key_info= head->key_info + (*it)->index;
1237.13.11 by Padraig O'Sullivan
Split the QUICK_ROR_INTERSECT_SELECT class out into its own header and implementation files.
258
    if (! first)
259
      str->append(',');
260
    else
261
      first= false;
262
    str->append(key_info->name);
263
  }
264
  if (cpk_quick)
265
  {
1535 by Brian Aker
Rename of KEY to KeyInfo
266
    KeyInfo *key_info= head->key_info + cpk_quick->index;
1237.13.11 by Padraig O'Sullivan
Split the QUICK_ROR_INTERSECT_SELECT class out into its own header and implementation files.
267
    str->append(',');
268
    str->append(key_info->name);
269
  }
270
  str->append(')');
271
}
272
273
1237.13.12 by Padraig O'Sullivan
Corrected the name of the QUICK_ROR_INTERSECT_CLASS class to adhere to the drizzle coding standards.
274
void optimizer::QuickRorIntersectSelect::add_keys_and_lengths(String *key_names,
275
                                                              String *used_lengths)
1237.13.11 by Padraig O'Sullivan
Split the QUICK_ROR_INTERSECT_SELECT class out into its own header and implementation files.
276
{
277
  char buf[64];
278
  uint32_t length;
279
  bool first= true;
1237.13.16 by Padraig O'Sullivan
Replaced List with std::vector in the QuickRorIntersectSelect class.
280
  for (vector<optimizer::QuickRangeSelect *>::iterator it= quick_selects.begin();
281
       it != quick_selects.end();
282
       ++it)
1237.13.11 by Padraig O'Sullivan
Split the QUICK_ROR_INTERSECT_SELECT class out into its own header and implementation files.
283
  {
1535 by Brian Aker
Rename of KEY to KeyInfo
284
    KeyInfo *key_info= head->key_info + (*it)->index;
1237.13.11 by Padraig O'Sullivan
Split the QUICK_ROR_INTERSECT_SELECT class out into its own header and implementation files.
285
    if (first)
286
    {
287
      first= false;
288
    }
289
    else
290
    {
291
      key_names->append(',');
292
      used_lengths->append(',');
293
    }
294
    key_names->append(key_info->name);
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
295
    length= internal::int64_t2str((*it)->max_used_key_length, buf, 10) - buf;
1237.13.11 by Padraig O'Sullivan
Split the QUICK_ROR_INTERSECT_SELECT class out into its own header and implementation files.
296
    used_lengths->append(buf, length);
297
  }
298
299
  if (cpk_quick)
300
  {
1535 by Brian Aker
Rename of KEY to KeyInfo
301
    KeyInfo *key_info= head->key_info + cpk_quick->index;
1237.13.11 by Padraig O'Sullivan
Split the QUICK_ROR_INTERSECT_SELECT class out into its own header and implementation files.
302
    key_names->append(',');
303
    key_names->append(key_info->name);
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
304
    length= internal::int64_t2str(cpk_quick->max_used_key_length, buf, 10) - buf;
1237.13.11 by Padraig O'Sullivan
Split the QUICK_ROR_INTERSECT_SELECT class out into its own header and implementation files.
305
    used_lengths->append(',');
306
    used_lengths->append(buf, length);
307
  }
308
}
309
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
310
} /* namespace drizzled */