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