~drizzle-trunk/drizzle/development

575.1.5 by Monty Taylor
Moved stuff to handlerton.cc
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 Sun Microsystems, Inc.
575.1.5 by Monty Taylor
Moved stuff to handlerton.cc
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
 */
1 by brian
clean slate
19
20
/**
1183.1.2 by Brian Aker
Rename of handler to Cursor. You would not believe how long I have wanted
21
  @file Cursor.cc
1 by brian
clean slate
22
23
  Handler-calling-functions
24
*/
25
2173.2.1 by Monty Taylor
Fixes incorrect usage of include
26
#include <config.h>
1241.9.1 by Monty Taylor
Removed global.h. Fixed all the headers.
27
#include <fcntl.h>
2173.2.1 by Monty Taylor
Fixes incorrect usage of include
28
#include <drizzled/error.h>
29
#include <drizzled/field/epoch.h>
30
#include <drizzled/gettext.h>
31
#include <drizzled/internal/my_sys.h>
32
#include <drizzled/item/empty_string.h>
33
#include <drizzled/item/int.h>
34
#include <drizzled/lock.h>
35
#include <drizzled/message/table.h>
36
#include <drizzled/optimizer/cost_vector.h>
37
#include <drizzled/plugin/client.h>
38
#include <drizzled/plugin/event_observer.h>
39
#include <drizzled/plugin/storage_engine.h>
40
#include <drizzled/probes.h>
41
#include <drizzled/session.h>
42
#include <drizzled/sql_base.h>
43
#include <drizzled/sql_parse.h>
44
#include <drizzled/transaction_services.h>
2198.1.1 by Olaf van der Spek
Remove unnecessary alter* includes
45
#include <drizzled/key.h>
2234.1.3 by Olaf van der Spek
Refactor includes
46
#include <drizzled/sql_lex.h>
2239.1.7 by Olaf van der Spek
Refactor includes
47
#include <drizzled/resource_context.h>
2241.3.1 by Olaf van der Spek
Refactor Session::status_var
48
#include <drizzled/statistics_variables.h>
2241.3.2 by Olaf van der Spek
Refactor Session::variables
49
#include <drizzled/system_variables.h>
572.1.4 by Monty Taylor
Removed a bunch of unusued tests and defines from autoconf.
50
919.2.14 by Monty Taylor
Use math.h instead of cmath... one of these days...
51
using namespace std;
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
52
2221.7.5 by Olaf van der Spek
Refactor
53
namespace drizzled {
1 by brian
clean slate
54
55
/****************************************************************************
1183.1.2 by Brian Aker
Rename of handler to Cursor. You would not believe how long I have wanted
56
** General Cursor functions
1 by brian
clean slate
57
****************************************************************************/
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
58
Cursor::Cursor(plugin::StorageEngine &engine_arg,
1869.1.4 by Brian Aker
TableShare is no longer in the house (i.e. we no longer directly have a copy
59
               Table &arg)
1869.1.5 by Brian Aker
getTable()
60
  : table(arg),
1869.1.7 by Brian Aker
Cleanup of caller to ha_open().
61
    engine(engine_arg),
62
    estimation_rows_to_insert(0),
1492 by Brian Aker
Dead code removal.
63
    ref(0),
1241.9.57 by Monty Taylor
Oy. Bigger change than I normally like - but this stuff is all intertwined.
64
    key_used_on_scan(MAX_KEY), active_index(MAX_KEY),
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
65
    ref_length(sizeof(internal::my_off_t)),
1241.9.57 by Monty Taylor
Oy. Bigger change than I normally like - but this stuff is all intertwined.
66
    inited(NONE),
1491.1.8 by Jay Pipes
Removes HEAP-specific Cursor::implicit_emptied member. Was unused.
67
    locked(false),
1241.9.57 by Monty Taylor
Oy. Bigger change than I normally like - but this stuff is all intertwined.
68
    next_insert_id(0), insert_id_for_cur_row(0)
69
{ }
70
2318.6.65 by Olaf van der Spek
Refactor
71
Cursor::~Cursor()
1022.2.29 by Monty Taylor
Fixed some no-inline warnings.
72
{
2318.6.65 by Olaf van der Spek
Refactor
73
  assert(not locked);
1022.2.29 by Monty Taylor
Fixed some no-inline warnings.
74
  /* TODO: assert(inited == NONE); */
75
}
76
77
1626.3.3 by Brian Aker
Additional checks on path.
78
/*
79
 * @note this only used in
80
 * optimizer::QuickRangeSelect::init_ror_merged_scan(bool reuse_handler) as
81
 * of the writing of this comment. -Brian
82
 */
1253.1.3 by Monty Taylor
MEM_ROOT == memory::Root
83
Cursor *Cursor::clone(memory::Root *mem_root)
1 by brian
clean slate
84
{
1869.1.5 by Brian Aker
getTable()
85
  Cursor *new_handler= getTable()->getMutableShare()->db_type()->getCursor(*getTable());
1 by brian
clean slate
86
  /*
1183.1.2 by Brian Aker
Rename of handler to Cursor. You would not believe how long I have wanted
87
    Allocate Cursor->ref here because otherwise ha_open will allocate it
575.2.2 by Monty Taylor
Moved vio stuff into libdrizzle.
88
    on this->table->mem_root and we will not be able to reclaim that memory
1183.1.2 by Brian Aker
Rename of handler to Cursor. You would not believe how long I have wanted
89
    when the clone Cursor object is destroyed.
1 by brian
clean slate
90
  */
2318.6.44 by Olaf van der Spek
Refactor
91
  new_handler->ref= mem_root->alloc(ALIGN_SIZE(ref_length)*2);
2385.1.3 by Olaf van der Spek
Refactor getTableName
92
  identifier::Table identifier(getTable()->getShare()->getSchemaName(), getTable()->getShare()->getTableName(), getTable()->getShare()->getType());
93
  return new_handler->ha_open(identifier, getTable()->getDBStat(), HA_OPEN_IGNORE_IF_LOCKED) ? NULL : new_handler;
1 by brian
clean slate
94
}
95
1483 by Brian Aker
Small change to move over call to cursor API.
96
/*
97
  DESCRIPTION
98
    given a buffer with a key value, and a map of keyparts
99
    that are present in this value, returns the length of the value
100
*/
101
uint32_t Cursor::calculate_key_len(uint32_t key_position, key_part_map keypart_map_arg)
102
{
103
  /* works only with key prefixes */
104
  assert(((keypart_map_arg + 1) & keypart_map_arg) == 0);
105
1869.1.5 by Brian Aker
getTable()
106
  const KeyPartInfo *key_part_found= getTable()->getShare()->getKeyInfo(key_position).key_part;
107
  const KeyPartInfo *end_key_part_found= key_part_found + getTable()->getShare()->getKeyInfo(key_position).key_parts;
1483 by Brian Aker
Small change to move over call to cursor API.
108
  uint32_t length= 0;
109
110
  while (key_part_found < end_key_part_found && keypart_map_arg)
111
  {
112
    length+= key_part_found->store_length;
113
    keypart_map_arg >>= 1;
114
    key_part_found++;
115
  }
116
  return length;
117
}
118
1491.1.6 by Jay Pipes
Cursor::ha_index_init() -> Cursor::startIndexScan(). Cursor::ha_index_end() -> Cursor::endIndexScan()
119
int Cursor::startIndexScan(uint32_t idx, bool sorted)
575.1.4 by Monty Taylor
Moved implementation of some methods into handler.cc from handler.h.
120
{
121
  int result;
1046.1.9 by Brian Aker
Remove caller that wasn't correctly locking, and reverted code to 5.1
122
  assert(inited == NONE);
1491.1.6 by Jay Pipes
Cursor::ha_index_init() -> Cursor::startIndexScan(). Cursor::ha_index_end() -> Cursor::endIndexScan()
123
  if (!(result= doStartIndexScan(idx, sorted)))
575.1.4 by Monty Taylor
Moved implementation of some methods into handler.cc from handler.h.
124
    inited=INDEX;
125
  end_range= NULL;
1046.1.9 by Brian Aker
Remove caller that wasn't correctly locking, and reverted code to 5.1
126
  return result;
575.1.4 by Monty Taylor
Moved implementation of some methods into handler.cc from handler.h.
127
}
128
1491.1.6 by Jay Pipes
Cursor::ha_index_init() -> Cursor::startIndexScan(). Cursor::ha_index_end() -> Cursor::endIndexScan()
129
int Cursor::endIndexScan()
575.1.4 by Monty Taylor
Moved implementation of some methods into handler.cc from handler.h.
130
{
131
  assert(inited==INDEX);
132
  inited=NONE;
133
  end_range= NULL;
1491.1.6 by Jay Pipes
Cursor::ha_index_init() -> Cursor::startIndexScan(). Cursor::ha_index_end() -> Cursor::endIndexScan()
134
  return(doEndIndexScan());
575.1.4 by Monty Taylor
Moved implementation of some methods into handler.cc from handler.h.
135
}
136
1491.1.10 by Jay Pipes
ha_rnd_init -> startTableScan, rnd_init -> doStartTableScan, ha_rnd_end -> endTableScan, rnd_end -> doEndTableScan
137
int Cursor::startTableScan(bool scan)
575.1.4 by Monty Taylor
Moved implementation of some methods into handler.cc from handler.h.
138
{
139
  int result;
140
  assert(inited==NONE || (inited==RND && scan));
1491.1.10 by Jay Pipes
ha_rnd_init -> startTableScan, rnd_init -> doStartTableScan, ha_rnd_end -> endTableScan, rnd_end -> doEndTableScan
141
  inited= (result= doStartTableScan(scan)) ? NONE: RND;
1046.1.9 by Brian Aker
Remove caller that wasn't correctly locking, and reverted code to 5.1
142
143
  return result;
575.1.4 by Monty Taylor
Moved implementation of some methods into handler.cc from handler.h.
144
}
145
1491.1.10 by Jay Pipes
ha_rnd_init -> startTableScan, rnd_init -> doStartTableScan, ha_rnd_end -> endTableScan, rnd_end -> doEndTableScan
146
int Cursor::endTableScan()
575.1.4 by Monty Taylor
Moved implementation of some methods into handler.cc from handler.h.
147
{
148
  assert(inited==RND);
149
  inited=NONE;
1491.1.10 by Jay Pipes
ha_rnd_init -> startTableScan, rnd_init -> doStartTableScan, ha_rnd_end -> endTableScan, rnd_end -> doEndTableScan
150
  return(doEndTableScan());
575.1.4 by Monty Taylor
Moved implementation of some methods into handler.cc from handler.h.
151
}
152
1183.1.2 by Brian Aker
Rename of handler to Cursor. You would not believe how long I have wanted
153
int Cursor::ha_index_or_rnd_end()
575.1.4 by Monty Taylor
Moved implementation of some methods into handler.cc from handler.h.
154
{
1491.1.10 by Jay Pipes
ha_rnd_init -> startTableScan, rnd_init -> doStartTableScan, ha_rnd_end -> endTableScan, rnd_end -> doEndTableScan
155
  return inited == INDEX ? endIndexScan() : inited == RND ? endTableScan() : 0;
575.1.4 by Monty Taylor
Moved implementation of some methods into handler.cc from handler.h.
156
}
157
1183.1.2 by Brian Aker
Rename of handler to Cursor. You would not believe how long I have wanted
158
void Cursor::ha_start_bulk_insert(ha_rows rows)
575.1.4 by Monty Taylor
Moved implementation of some methods into handler.cc from handler.h.
159
{
160
  estimation_rows_to_insert= rows;
161
  start_bulk_insert(rows);
162
}
163
1183.1.2 by Brian Aker
Rename of handler to Cursor. You would not believe how long I have wanted
164
int Cursor::ha_end_bulk_insert()
575.1.4 by Monty Taylor
Moved implementation of some methods into handler.cc from handler.h.
165
{
166
  estimation_rows_to_insert= 0;
167
  return end_bulk_insert();
168
}
169
1183.1.2 by Brian Aker
Rename of handler to Cursor. You would not believe how long I have wanted
170
const key_map *Cursor::keys_to_use_for_scanning()
575.1.4 by Monty Taylor
Moved implementation of some methods into handler.cc from handler.h.
171
{
172
  return &key_map_empty;
173
}
174
1183.1.2 by Brian Aker
Rename of handler to Cursor. You would not believe how long I have wanted
175
bool Cursor::has_transactions()
575.1.4 by Monty Taylor
Moved implementation of some methods into handler.cc from handler.h.
176
{
1869.1.5 by Brian Aker
getTable()
177
  return (getTable()->getShare()->db_type()->check_flag(HTON_BIT_DOES_TRANSACTIONS));
575.1.4 by Monty Taylor
Moved implementation of some methods into handler.cc from handler.h.
178
}
1 by brian
clean slate
179
1561.3.12 by Joe Daly
add missing header file, and change ha_statistic_increment from ulong to uint64_t
180
void Cursor::ha_statistic_increment(uint64_t system_status_var::*offset) const
1 by brian
clean slate
181
{
1869.1.5 by Brian Aker
getTable()
182
  (getTable()->in_use->status_var.*offset)++;
1 by brian
clean slate
183
}
184
1183.1.2 by Brian Aker
Rename of handler to Cursor. You would not believe how long I have wanted
185
void **Cursor::ha_data(Session *session) const
1 by brian
clean slate
186
{
1869.1.3 by Brian Aker
Engine now as a referene.
187
  return session->getEngineData(getEngine());
1 by brian
clean slate
188
}
189
1183.1.2 by Brian Aker
Rename of handler to Cursor. You would not believe how long I have wanted
190
bool Cursor::is_fatal_error(int error, uint32_t flags)
575.1.4 by Monty Taylor
Moved implementation of some methods into handler.cc from handler.h.
191
{
192
  if (!error ||
193
      ((flags & HA_CHECK_DUP_KEY) &&
194
       (error == HA_ERR_FOUND_DUPP_KEY ||
195
        error == HA_ERR_FOUND_DUPP_UNIQUE)))
196
    return false;
197
  return true;
198
}
199
575.1.5 by Monty Taylor
Moved stuff to handlerton.cc
200
1183.1.2 by Brian Aker
Rename of handler to Cursor. You would not believe how long I have wanted
201
ha_rows Cursor::records() { return stats.records; }
1320.1.18 by Brian Aker
Overhaul of SHOW TABLE STATUS.
202
uint64_t Cursor::tableSize() { return stats.index_file_length + stats.data_file_length; }
1869.1.5 by Brian Aker
getTable()
203
uint64_t Cursor::rowSize() { return getTable()->getRecordLength() + getTable()->sizeFields(); }
575.1.5 by Monty Taylor
Moved stuff to handlerton.cc
204
2087.4.2 by Brian Aker
Modify TableIdentifier to fit with the rest of the identifiers.
205
int Cursor::doOpen(const identifier::Table &identifier, int mode, uint32_t test_if_locked)
1626.3.3 by Brian Aker
Additional checks on path.
206
{
207
  return open(identifier.getPath().c_str(), mode, test_if_locked);
208
}
209
1 by brian
clean slate
210
/**
1183.1.2 by Brian Aker
Rename of handler to Cursor. You would not believe how long I have wanted
211
  Open database-Cursor.
1 by brian
clean slate
212
213
  Try O_RDONLY if cannot open as O_RDWR
214
  Don't wait for locks if not HA_OPEN_WAIT_IF_LOCKED is set
215
*/
2087.4.2 by Brian Aker
Modify TableIdentifier to fit with the rest of the identifiers.
216
int Cursor::ha_open(const identifier::Table &identifier,
1749.3.9 by Brian Aker
Remove table name from ha_open (we modified this a while ago to just use
217
                    int mode,
1626.3.1 by Brian Aker
Adding in TableIdentifier for ha_open; (first pass)
218
                    int test_if_locked)
1 by brian
clean slate
219
{
220
  int error;
221
1626.3.3 by Brian Aker
Additional checks on path.
222
  if ((error= doOpen(identifier, mode, test_if_locked)))
1 by brian
clean slate
223
  {
224
    if ((error == EACCES || error == EROFS) && mode == O_RDWR &&
1869.1.5 by Brian Aker
getTable()
225
        (getTable()->db_stat & HA_TRY_READ_ONLY))
1 by brian
clean slate
226
    {
1869.1.5 by Brian Aker
getTable()
227
      getTable()->db_stat|=HA_READ_ONLY;
1626.3.3 by Brian Aker
Additional checks on path.
228
      error= doOpen(identifier, O_RDONLY,test_if_locked);
1 by brian
clean slate
229
    }
230
  }
231
  if (error)
232
  {
1241.9.57 by Monty Taylor
Oy. Bigger change than I normally like - but this stuff is all intertwined.
233
    errno= error;                            /* Safeguard */
1 by brian
clean slate
234
  }
235
  else
236
  {
1869.1.5 by Brian Aker
getTable()
237
    if (getTable()->getShare()->db_options_in_use & HA_OPTION_READ_ONLY_DATA)
238
      getTable()->db_stat|=HA_READ_ONLY;
1 by brian
clean slate
239
    (void) extra(HA_EXTRA_NO_READCHECK);	// Not needed in SQL
240
1183.1.2 by Brian Aker
Rename of handler to Cursor. You would not believe how long I have wanted
241
    /* ref is already allocated for us if we're called from Cursor::clone() */
2318.6.40 by Olaf van der Spek
Refactor
242
    if (!ref)
2318.6.44 by Olaf van der Spek
Refactor
243
      ref= getTable()->alloc(ALIGN_SIZE(ref_length)*2);
2318.6.40 by Olaf van der Spek
Refactor
244
    dup_ref=ref+ALIGN_SIZE(ref_length);
1 by brian
clean slate
245
  }
1046.1.9 by Brian Aker
Remove caller that wasn't correctly locking, and reverted code to 5.1
246
  return error;
1 by brian
clean slate
247
}
248
249
/**
250
  Read first row (only) from a table.
251
252
  This is never called for InnoDB tables, as these table types
253
  has the HA_STATS_RECORDS_IS_EXACT set.
254
*/
1183.1.2 by Brian Aker
Rename of handler to Cursor. You would not believe how long I have wanted
255
int Cursor::read_first_row(unsigned char * buf, uint32_t primary_key)
1 by brian
clean slate
256
{
2170.5.1 by Olaf van der Spek
Remove register keyword
257
  int error;
1 by brian
clean slate
258
1273.16.8 by Brian Aker
Remove typedef.
259
  ha_statistic_increment(&system_status_var::ha_read_first_count);
1 by brian
clean slate
260
261
  /*
262
    If there is very few deleted rows in the table, find the first row by
263
    scanning the table.
2172.3.22 by Brian Aker
This patch adds safe_delete(). All of these locations in the code should be
264
    @todo remove the test for HA_READ_ORDER
1 by brian
clean slate
265
  */
266
  if (stats.deleted < 10 || primary_key >= MAX_KEY ||
1869.1.5 by Brian Aker
getTable()
267
      !(getTable()->index_flags(primary_key) & HA_READ_ORDER))
1 by brian
clean slate
268
  {
2049.2.1 by Stewart Smith
doStartTableScan() result not checked.
269
    error= startTableScan(1);
270
    if (error == 0)
271
    {
272
      while ((error= rnd_next(buf)) == HA_ERR_RECORD_DELETED) ;
273
      (void) endTableScan();
274
    }
1 by brian
clean slate
275
  }
276
  else
277
  {
278
    /* Find the first row through the primary key */
2049.2.5 by Stewart Smith
check return value of Cursor::startIndexScan in read_first_row
279
    error= startIndexScan(primary_key, 0);
280
    if (error == 0)
281
    {
282
      error=index_first(buf);
283
      (void) endIndexScan();
284
    }
1 by brian
clean slate
285
  }
1046.1.9 by Brian Aker
Remove caller that wasn't correctly locking, and reverted code to 5.1
286
  return error;
1 by brian
clean slate
287
}
288
289
/**
290
  Generate the next auto-increment number based on increment and offset.
291
  computes the lowest number
292
  - strictly greater than "nr"
293
  - of the form: auto_increment_offset + N * auto_increment_increment
294
295
  In most cases increment= offset= 1, in which case we get:
296
  @verbatim 1,2,3,4,5,... @endverbatim
297
    If increment=10 and offset=5 and previous number is 1, we get:
298
  @verbatim 1,5,15,25,35,... @endverbatim
299
*/
300
inline uint64_t
1878.3.2 by Monty Taylor
Split out show_type into its own header and made sys_var work through
301
compute_next_insert_id(uint64_t nr, drizzle_system_variables *variables)
1 by brian
clean slate
302
{
303
  if (variables->auto_increment_increment == 1)
304
    return (nr+1); // optimization of the formula below
305
  nr= (((nr+ variables->auto_increment_increment -
306
         variables->auto_increment_offset)) /
307
       (uint64_t) variables->auto_increment_increment);
308
  return (nr* (uint64_t) variables->auto_increment_increment +
309
          variables->auto_increment_offset);
310
}
311
312
1183.1.2 by Brian Aker
Rename of handler to Cursor. You would not believe how long I have wanted
313
void Cursor::adjust_next_insert_id_after_explicit_value(uint64_t nr)
1 by brian
clean slate
314
{
315
  /*
520.1.21 by Brian Aker
THD -> Session rename
316
    If we have set Session::next_insert_id previously and plan to insert an
1 by brian
clean slate
317
    explicitely-specified value larger than this, we need to increase
520.1.21 by Brian Aker
THD -> Session rename
318
    Session::next_insert_id to be greater than the explicit value.
1 by brian
clean slate
319
  */
320
  if ((next_insert_id > 0) && (nr >= next_insert_id))
1869.1.5 by Brian Aker
getTable()
321
    set_next_insert_id(compute_next_insert_id(nr, &getTable()->in_use->variables));
1 by brian
clean slate
322
}
323
324
325
/**
326
  Compute a previous insert id
327
328
  Computes the largest number X:
329
  - smaller than or equal to "nr"
330
  - of the form: auto_increment_offset + N * auto_increment_increment
331
    where N>=0.
332
333
  @param nr            Number to "round down"
334
  @param variables     variables struct containing auto_increment_increment and
335
                       auto_increment_offset
336
337
  @return
338
    The number X if it exists, "nr" otherwise.
339
*/
340
inline uint64_t
1878.3.2 by Monty Taylor
Split out show_type into its own header and made sys_var work through
341
prev_insert_id(uint64_t nr, drizzle_system_variables *variables)
1 by brian
clean slate
342
{
343
  if (unlikely(nr < variables->auto_increment_offset))
344
  {
345
    /*
346
      There's nothing good we can do here. That is a pathological case, where
347
      the offset is larger than the column's max possible value, i.e. not even
348
      the first sequence value may be inserted. User will receive warning.
349
    */
350
    return nr;
351
  }
352
  if (variables->auto_increment_increment == 1)
353
    return nr; // optimization of the formula below
354
  nr= (((nr - variables->auto_increment_offset)) /
355
       (uint64_t) variables->auto_increment_increment);
356
  return (nr * (uint64_t) variables->auto_increment_increment +
357
          variables->auto_increment_offset);
358
}
359
360
361
/**
362
  Update the auto_increment field if necessary.
363
364
  Updates columns with type NEXT_NUMBER if:
365
1055.2.2 by Jay Pipes
Cleanup of style, indentation, and documentation of Table class members. Removed 5 or 6 dead Table member variables.
366
  - If column value is set to NULL (in which case auto_increment_field_not_null is false)
1 by brian
clean slate
367
  - If column is set to 0 and (sql_mode & MODE_NO_AUTO_VALUE_ON_ZERO) is not
368
    set. In the future we will only set NEXT_NUMBER fields if one sets them
369
    to NULL (or they are not included in the insert list).
370
371
    In those cases, we check if the currently reserved interval still has
372
    values we have not used. If yes, we pick the smallest one and use it.
373
    Otherwise:
374
375
  - If a list of intervals has been provided to the statement via SET
376
    INSERT_ID or via an Intvar_log_event (in a replication slave), we pick the
377
    first unused interval from this list, consider it as reserved.
378
379
  - Otherwise we set the column for the first row to the value
380
    next_insert_id(get_auto_increment(column))) which is usually
381
    max-used-column-value+1.
382
    We call get_auto_increment() for the first row in a multi-row
383
    statement. get_auto_increment() will tell us the interval of values it
384
    reserved for us.
385
386
  - In both cases, for the following rows we use those reserved values without
1183.1.2 by Brian Aker
Rename of handler to Cursor. You would not believe how long I have wanted
387
    calling the Cursor again (we just progress in the interval, computing
1 by brian
clean slate
388
    each new value from the previous one). Until we have exhausted them, then
389
    we either take the next provided interval or call get_auto_increment()
390
    again to reserve a new interval.
391
392
  - In both cases, the reserved intervals are remembered in
520.1.22 by Brian Aker
Second pass of thd cleanup
393
    session->auto_inc_intervals_in_cur_stmt_for_binlog if statement-based
1 by brian
clean slate
394
    binlogging; the last reserved interval is remembered in
395
    auto_inc_interval_for_cur_row.
396
397
    The idea is that generated auto_increment values are predictable and
398
    independent of the column values in the table.  This is needed to be
399
    able to replicate into a table that already has rows with a higher
400
    auto-increment value than the one that is inserted.
401
402
    After we have already generated an auto-increment number and the user
403
    inserts a column with a higher value than the last used one, we will
404
    start counting from the inserted value.
405
406
    This function's "outputs" are: the table's auto_increment field is filled
520.1.22 by Brian Aker
Second pass of thd cleanup
407
    with a value, session->next_insert_id is filled with the value to use for the
1 by brian
clean slate
408
    next row, if a value was autogenerated for the current row it is stored in
520.1.22 by Brian Aker
Second pass of thd cleanup
409
    session->insert_id_for_cur_row, if get_auto_increment() was called
410
    session->auto_inc_interval_for_cur_row is modified, if that interval is not
411
    present in session->auto_inc_intervals_in_cur_stmt_for_binlog it is added to
1 by brian
clean slate
412
    this list.
413
414
  @todo
415
    Replace all references to "next number" or NEXT_NUMBER to
416
    "auto_increment", everywhere (see below: there is
417
    table->auto_increment_field_not_null, and there also exists
418
    table->next_number_field, it's not consistent).
419
420
  @retval
421
    0	ok
422
  @retval
423
    HA_ERR_AUTOINC_READ_FAILED  get_auto_increment() was called and
424
    returned ~(uint64_t) 0
425
  @retval
426
    HA_ERR_AUTOINC_ERANGE storing value in field caused strict mode
427
    failure.
428
*/
429
430
#define AUTO_INC_DEFAULT_NB_ROWS 1 // Some prefer 1024 here
431
#define AUTO_INC_DEFAULT_NB_MAX_BITS 16
432
#define AUTO_INC_DEFAULT_NB_MAX ((1 << AUTO_INC_DEFAULT_NB_MAX_BITS) - 1)
433
1183.1.2 by Brian Aker
Rename of handler to Cursor. You would not believe how long I have wanted
434
int Cursor::update_auto_increment()
1 by brian
clean slate
435
{
436
  uint64_t nr, nb_reserved_values;
56 by brian
Next pass of true/false update.
437
  bool append= false;
1869.1.5 by Brian Aker
getTable()
438
  Session *session= getTable()->in_use;
1878.3.2 by Monty Taylor
Split out show_type into its own header and made sys_var work through
439
  drizzle_system_variables *variables= &session->variables;
1 by brian
clean slate
440
441
  /*
442
    next_insert_id is a "cursor" into the reserved interval, it may go greater
443
    than the interval, but not smaller.
444
  */
51.1.77 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
445
  assert(next_insert_id >= auto_inc_interval_for_cur_row.minimum());
1 by brian
clean slate
446
1055.2.2 by Jay Pipes
Cleanup of style, indentation, and documentation of Table class members. Removed 5 or 6 dead Table member variables.
447
  /* We check if auto_increment_field_not_null is false
1008.3.2 by Stewart Smith
Make sql_mode=NO_AUTO_VALUE_ON_ZERO default for Drizzle.
448
     for an auto increment column, not a magic value like NULL is.
449
     same as sql_mode=NO_AUTO_VALUE_ON_ZERO */
450
1869.1.5 by Brian Aker
getTable()
451
  if ((nr= getTable()->next_number_field->val_int()) != 0
452
      || getTable()->auto_increment_field_not_null)
1 by brian
clean slate
453
  {
454
    /*
455
      Update next_insert_id if we had already generated a value in this
456
      statement (case of INSERT VALUES(null),(3763),(null):
457
      the last NULL needs to insert 3764, not the value of the first NULL plus
458
      1).
459
    */
460
    adjust_next_insert_id_after_explicit_value(nr);
461
    insert_id_for_cur_row= 0; // didn't generate anything
1046.1.9 by Brian Aker
Remove caller that wasn't correctly locking, and reverted code to 5.1
462
463
    return 0;
1 by brian
clean slate
464
  }
465
466
  if ((nr= next_insert_id) >= auto_inc_interval_for_cur_row.maximum())
467
  {
468
    {
469
      /*
1183.1.2 by Brian Aker
Rename of handler to Cursor. You would not believe how long I have wanted
470
        Cursor::estimation_rows_to_insert was set by
471
        Cursor::ha_start_bulk_insert(); if 0 it means "unknown".
1 by brian
clean slate
472
      */
2241.2.3 by Olaf van der Spek
Refactor unused code
473
      uint32_t nb_already_reserved_intervals= 0;
1 by brian
clean slate
474
      uint64_t nb_desired_values;
475
      /*
476
        If an estimation was given to the engine:
477
        - use it.
478
        - if we already reserved numbers, it means the estimation was
479
        not accurate, then we'll reserve 2*AUTO_INC_DEFAULT_NB_ROWS the 2nd
480
        time, twice that the 3rd time etc.
481
        If no estimation was given, use those increasing defaults from the
482
        start, starting from AUTO_INC_DEFAULT_NB_ROWS.
483
        Don't go beyond a max to not reserve "way too much" (because
484
        reservation means potentially losing unused values).
485
      */
486
      if (nb_already_reserved_intervals == 0 &&
487
          (estimation_rows_to_insert > 0))
488
        nb_desired_values= estimation_rows_to_insert;
489
      else /* go with the increasing defaults */
490
      {
491
        /* avoid overflow in formula, with this if() */
492
        if (nb_already_reserved_intervals <= AUTO_INC_DEFAULT_NB_MAX_BITS)
493
        {
575.2.2 by Monty Taylor
Moved vio stuff into libdrizzle.
494
          nb_desired_values= AUTO_INC_DEFAULT_NB_ROWS *
1 by brian
clean slate
495
            (1 << nb_already_reserved_intervals);
937.2.6 by Stewart Smith
make set_if_bigger typesafe for C and C++. Fix up everywhere.
496
          set_if_smaller(nb_desired_values, (uint64_t)AUTO_INC_DEFAULT_NB_MAX);
1 by brian
clean slate
497
        }
498
        else
499
          nb_desired_values= AUTO_INC_DEFAULT_NB_MAX;
500
      }
501
      /* This call ignores all its parameters but nr, currently */
502
      get_auto_increment(variables->auto_increment_offset,
503
                         variables->auto_increment_increment,
504
                         nb_desired_values, &nr,
505
                         &nb_reserved_values);
506
      if (nr == ~(uint64_t) 0)
1046.1.9 by Brian Aker
Remove caller that wasn't correctly locking, and reverted code to 5.1
507
        return HA_ERR_AUTOINC_READ_FAILED;  // Mark failure
575.2.2 by Monty Taylor
Moved vio stuff into libdrizzle.
508
1 by brian
clean slate
509
      /*
510
        That rounding below should not be needed when all engines actually
511
        respect offset and increment in get_auto_increment(). But they don't
512
        so we still do it. Wonder if for the not-first-in-index we should do
513
        it. Hope that this rounding didn't push us out of the interval; even
514
        if it did we cannot do anything about it (calling the engine again
515
        will not help as we inserted no row).
516
      */
517
      nr= compute_next_insert_id(nr-1, variables);
518
    }
575.2.2 by Monty Taylor
Moved vio stuff into libdrizzle.
519
1869.1.5 by Brian Aker
getTable()
520
    if (getTable()->getShare()->next_number_keypart == 0)
1 by brian
clean slate
521
    {
522
      /* We must defer the appending until "nr" has been possibly truncated */
56 by brian
Next pass of true/false update.
523
      append= true;
1 by brian
clean slate
524
    }
525
  }
526
1869.1.5 by Brian Aker
getTable()
527
  if (unlikely(getTable()->next_number_field->store((int64_t) nr, true)))
1 by brian
clean slate
528
  {
529
    /*
530
      first test if the query was aborted due to strict mode constraints
531
    */
1910.2.8 by Brian Aker
Enapsulate Kill.
532
    if (session->getKilled() == Session::KILL_BAD_DATA)
1046.1.9 by Brian Aker
Remove caller that wasn't correctly locking, and reverted code to 5.1
533
      return HA_ERR_AUTOINC_ERANGE;
1 by brian
clean slate
534
535
    /*
536
      field refused this value (overflow) and truncated it, use the result of
537
      the truncation (which is going to be inserted); however we try to
538
      decrease it to honour auto_increment_* variables.
539
      That will shift the left bound of the reserved interval, we don't
540
      bother shifting the right bound (anyway any other value from this
541
      interval will cause a duplicate key).
542
    */
1869.1.5 by Brian Aker
getTable()
543
    nr= prev_insert_id(getTable()->next_number_field->val_int(), variables);
544
    if (unlikely(getTable()->next_number_field->store((int64_t) nr, true)))
545
      nr= getTable()->next_number_field->val_int();
1 by brian
clean slate
546
  }
547
  if (append)
2241.2.3 by Olaf van der Spek
Refactor unused code
548
    auto_inc_interval_for_cur_row.replace(nr, nb_reserved_values, variables->auto_increment_increment);
1 by brian
clean slate
549
550
  /*
551
    Record this autogenerated value. If the caller then
552
    succeeds to insert this value, it will call
553
    record_first_successful_insert_id_in_cur_stmt()
554
    which will set first_successful_insert_id_in_cur_stmt if it's not
555
    already set.
556
  */
557
  insert_id_for_cur_row= nr;
558
  /*
559
    Set next insert id to point to next auto-increment value to be able to
560
    handle multi-row statements.
561
  */
562
  set_next_insert_id(compute_next_insert_id(nr, variables));
563
1046.1.9 by Brian Aker
Remove caller that wasn't correctly locking, and reverted code to 5.1
564
  return 0;
1 by brian
clean slate
565
}
566
567
568
/**
1183.1.2 by Brian Aker
Rename of handler to Cursor. You would not believe how long I have wanted
569
  Reserves an interval of auto_increment values from the Cursor.
1 by brian
clean slate
570
571
  offset and increment means that we want values to be of the form
572
  offset + N * increment, where N>=0 is integer.
573
  If the function sets *first_value to ~(uint64_t)0 it means an error.
163 by Brian Aker
Merge Monty's code.
574
  If the function sets *nb_reserved_values to UINT64_MAX it means it has
1 by brian
clean slate
575
  reserved to "positive infinite".
576
577
  @param offset
578
  @param increment
579
  @param nb_desired_values   how many values we want
1183.1.2 by Brian Aker
Rename of handler to Cursor. You would not believe how long I have wanted
580
  @param first_value         (OUT) the first value reserved by the Cursor
581
  @param nb_reserved_values  (OUT) how many values the Cursor reserved
1 by brian
clean slate
582
*/
583
1183.1.2 by Brian Aker
Rename of handler to Cursor. You would not believe how long I have wanted
584
void Cursor::ha_release_auto_increment()
1 by brian
clean slate
585
{
586
  release_auto_increment();
587
  insert_id_for_cur_row= 0;
588
  auto_inc_interval_for_cur_row.replace(0, 0, 0);
2241.2.3 by Olaf van der Spek
Refactor unused code
589
  next_insert_id= 0;
1 by brian
clean slate
590
}
591
2385.2.5 by Olaf van der Spek
Refactor
592
void Cursor::drop_table()
1 by brian
clean slate
593
{
594
  close();
595
}
596
2385.2.5 by Olaf van der Spek
Refactor
597
int Cursor::ha_check(Session*)
1 by brian
clean slate
598
{
590.1.4 by Stewart Smith
remove frm_version from TABLE_SHARE
599
  return HA_ADMIN_OK;
1 by brian
clean slate
600
}
601
602
/**
603
  A helper function to mark a transaction read-write,
604
  if it is started.
605
*/
606
607
inline
608
void
1273.1.12 by Jay Pipes
Cleanup style and documentation for ResourceContext and setTransactionReadWrite
609
Cursor::setTransactionReadWrite()
1 by brian
clean slate
610
{
1578.6.1 by Brian Aker
Remove ha_session where table->in_use should have been checked.
611
  /*
612
   * If the cursor has not context for execution then there should be no
613
   * possible resource to gain (and if there is... then there is a bug such
614
   * that in_use should have been set.
615
 */
1869.1.5 by Brian Aker
getTable()
616
  if (not getTable()->in_use)
1578.6.1 by Brian Aker
Remove ha_session where table->in_use should have been checked.
617
    return;
618
1 by brian
clean slate
619
  /*
620
    When a storage engine method is called, the transaction must
621
    have been started, unless it's a DDL call, for which the
622
    storage engine starts the transaction internally, and commits
623
    it internally, without registering in the ha_list.
624
    Unfortunately here we can't know know for sure if the engine
625
    has registered the transaction or not, so we must check.
626
  */
2241.2.9 by Olaf van der Spek
Refactor
627
  ResourceContext& resource_context= getTable()->in_use->getResourceContext(*getEngine());
2241.2.8 by Olaf van der Spek
Refactor
628
  if (resource_context.isStarted())
629
    resource_context.markModifiedData();
1 by brian
clean slate
630
}
631
632
633
/**
634
  Delete all rows: public interface.
635
1183.1.2 by Brian Aker
Rename of handler to Cursor. You would not believe how long I have wanted
636
  @sa Cursor::delete_all_rows()
1143.4.6 by Jay Pipes
Adds test case to transaction log for TRUNCATE TABLE.
637
638
  @note
639
640
  This is now equalivalent to TRUNCATE TABLE.
1 by brian
clean slate
641
*/
642
643
int
1183.1.2 by Brian Aker
Rename of handler to Cursor. You would not believe how long I have wanted
644
Cursor::ha_delete_all_rows()
1 by brian
clean slate
645
{
1273.1.12 by Jay Pipes
Cleanup style and documentation for ResourceContext and setTransactionReadWrite
646
  setTransactionReadWrite();
1 by brian
clean slate
647
1143.4.6 by Jay Pipes
Adds test case to transaction log for TRUNCATE TABLE.
648
  int result= delete_all_rows();
649
650
  if (result == 0)
651
  {
652
    /** 
653
     * Trigger post-truncate notification to plugins... 
654
     *
1336.2.2 by Jay Pipes
NO CODE CHANGES - Simply moves pieces of ReplicationServices to TransactionServices. Preparation for making the ReplicationServices component only responsible for communication between replicators, appliers, publishers, and subscribers.
655
     * @todo Make TransactionServices generic to AfterTriggerServices
1143.4.6 by Jay Pipes
Adds test case to transaction log for TRUNCATE TABLE.
656
     * or similar...
657
     */
2318.6.60 by Olaf van der Spek
Refactor
658
    Session& session= *getTable()->in_use;
2318.6.62 by Olaf van der Spek
Refactor
659
    TransactionServices::truncateTable(session, *getTable());
1143.4.6 by Jay Pipes
Adds test case to transaction log for TRUNCATE TABLE.
660
  }
661
662
  return result;
1 by brian
clean slate
663
}
664
665
666
/**
667
  Reset auto increment: public interface.
668
1183.1.2 by Brian Aker
Rename of handler to Cursor. You would not believe how long I have wanted
669
  @sa Cursor::reset_auto_increment()
1 by brian
clean slate
670
*/
671
672
int
1183.1.2 by Brian Aker
Rename of handler to Cursor. You would not believe how long I have wanted
673
Cursor::ha_reset_auto_increment(uint64_t value)
1 by brian
clean slate
674
{
1273.1.12 by Jay Pipes
Cleanup style and documentation for ResourceContext and setTransactionReadWrite
675
  setTransactionReadWrite();
1 by brian
clean slate
676
677
  return reset_auto_increment(value);
678
}
679
680
681
/**
682
  Analyze table: public interface.
683
1183.1.2 by Brian Aker
Rename of handler to Cursor. You would not believe how long I have wanted
684
  @sa Cursor::analyze()
1 by brian
clean slate
685
*/
686
687
int
2318.6.60 by Olaf van der Spek
Refactor
688
Cursor::ha_analyze(Session* session)
1 by brian
clean slate
689
{
1273.1.12 by Jay Pipes
Cleanup style and documentation for ResourceContext and setTransactionReadWrite
690
  setTransactionReadWrite();
1 by brian
clean slate
691
1222.1.10 by Brian Aker
Removes options from DDL left in Cursor for admin operations (they were
692
  return analyze(session);
1 by brian
clean slate
693
}
694
695
/**
696
  Disable indexes: public interface.
697
1183.1.2 by Brian Aker
Rename of handler to Cursor. You would not believe how long I have wanted
698
  @sa Cursor::disable_indexes()
1 by brian
clean slate
699
*/
700
701
int
1183.1.2 by Brian Aker
Rename of handler to Cursor. You would not believe how long I have wanted
702
Cursor::ha_disable_indexes(uint32_t mode)
1 by brian
clean slate
703
{
1273.1.12 by Jay Pipes
Cleanup style and documentation for ResourceContext and setTransactionReadWrite
704
  setTransactionReadWrite();
1 by brian
clean slate
705
706
  return disable_indexes(mode);
707
}
708
709
710
/**
711
  Enable indexes: public interface.
712
1183.1.2 by Brian Aker
Rename of handler to Cursor. You would not believe how long I have wanted
713
  @sa Cursor::enable_indexes()
1 by brian
clean slate
714
*/
715
716
int
1183.1.2 by Brian Aker
Rename of handler to Cursor. You would not believe how long I have wanted
717
Cursor::ha_enable_indexes(uint32_t mode)
1 by brian
clean slate
718
{
1273.1.12 by Jay Pipes
Cleanup style and documentation for ResourceContext and setTransactionReadWrite
719
  setTransactionReadWrite();
1 by brian
clean slate
720
721
  return enable_indexes(mode);
722
}
723
724
725
/**
726
  Discard or import tablespace: public interface.
727
1183.1.2 by Brian Aker
Rename of handler to Cursor. You would not believe how long I have wanted
728
  @sa Cursor::discard_or_import_tablespace()
1 by brian
clean slate
729
*/
730
2385.2.5 by Olaf van der Spek
Refactor
731
int Cursor::ha_discard_or_import_tablespace(bool discard)
1 by brian
clean slate
732
{
1273.1.12 by Jay Pipes
Cleanup style and documentation for ResourceContext and setTransactionReadWrite
733
  setTransactionReadWrite();
1 by brian
clean slate
734
  return discard_or_import_tablespace(discard);
735
}
736
737
/**
738
  Drop table in the engine: public interface.
739
1183.1.2 by Brian Aker
Rename of handler to Cursor. You would not believe how long I have wanted
740
  @sa Cursor::drop_table()
1 by brian
clean slate
741
*/
742
2385.2.5 by Olaf van der Spek
Refactor
743
void Cursor::closeMarkForDelete()
1 by brian
clean slate
744
{
1273.1.12 by Jay Pipes
Cleanup style and documentation for ResourceContext and setTransactionReadWrite
745
  setTransactionReadWrite();
2385.2.5 by Olaf van der Spek
Refactor
746
  return drop_table();
1 by brian
clean slate
747
}
748
1183.1.2 by Brian Aker
Rename of handler to Cursor. You would not believe how long I have wanted
749
int Cursor::index_next_same(unsigned char *buf, const unsigned char *key, uint32_t keylen)
1 by brian
clean slate
750
{
2385.2.5 by Olaf van der Spek
Refactor
751
  int error= index_next(buf);
752
  if (error)
753
    return error;
754
755
  ptrdiff_t ptrdiff= buf - getTable()->getInsertRecord();
756
  unsigned char *save_record_0= NULL;
757
  KeyInfo *key_info= NULL;
758
  KeyPartInfo *key_part;
759
  KeyPartInfo *key_part_end= NULL;
760
761
  /*
762
  key_cmp_if_same() compares table->getInsertRecord() against 'key'.
763
  In parts it uses table->getInsertRecord() directly, in parts it uses
764
  field objects with their local pointers into table->getInsertRecord().
765
  If 'buf' is distinct from table->getInsertRecord(), we need to move
766
  all record references. This is table->getInsertRecord() itself and
767
  the field pointers of the fields used in this key.
768
  */
769
  if (ptrdiff)
770
  {
771
    save_record_0= getTable()->getInsertRecord();
772
    getTable()->record[0]= buf;
773
    key_info= getTable()->key_info + active_index;
774
    key_part= key_info->key_part;
775
    key_part_end= key_part + key_info->key_parts;
776
    for (; key_part < key_part_end; key_part++)
777
    {
778
      assert(key_part->field);
779
      key_part->field->move_field_offset(ptrdiff);
780
    }
781
  }
782
783
  if (key_cmp_if_same(getTable(), key, active_index, keylen))
784
  {
785
    getTable()->status=STATUS_NOT_FOUND;
786
    error= HA_ERR_END_OF_FILE;
787
  }
788
789
  /* Move back if necessary. */
790
  if (ptrdiff)
791
  {
792
    getTable()->record[0]= save_record_0;
793
    for (key_part= key_info->key_part; key_part < key_part_end; key_part++)
794
      key_part->field->move_field_offset(-ptrdiff);
1 by brian
clean slate
795
  }
1046.1.9 by Brian Aker
Remove caller that wasn't correctly locking, and reverted code to 5.1
796
  return error;
1 by brian
clean slate
797
}
798
799
800
/****************************************************************************
1183.1.2 by Brian Aker
Rename of handler to Cursor. You would not believe how long I have wanted
801
** Some general functions that isn't in the Cursor class
1 by brian
clean slate
802
****************************************************************************/
803
804
/**
805
  Calculate cost of 'index only' scan for given index and number of records
806
807
  @param keynr    Index number
808
  @param records  Estimated number of records to be retrieved
809
810
  @note
811
    It is assumed that we will read trough the whole key range and that all
812
    key blocks are half full (normally things are much better). It is also
1183.1.2 by Brian Aker
Rename of handler to Cursor. You would not believe how long I have wanted
813
    assumed that each time we read the next key from the index, the Cursor
1 by brian
clean slate
814
    performs a random seek, thus the cost is proportional to the number of
815
    blocks read.
816
817
  @todo
1183.1.2 by Brian Aker
Rename of handler to Cursor. You would not believe how long I have wanted
818
    Consider joining this function and Cursor::read_time() into one
819
    Cursor::read_time(keynr, records, ranges, bool index_only) function.
1 by brian
clean slate
820
821
  @return
822
    Estimated cost of 'index only' scan
823
*/
824
1183.1.2 by Brian Aker
Rename of handler to Cursor. You would not believe how long I have wanted
825
double Cursor::index_only_read_time(uint32_t keynr, double key_records)
1 by brian
clean slate
826
{
482 by Brian Aker
Remove uint.
827
  uint32_t keys_per_block= (stats.block_size/2/
1869.1.5 by Brian Aker
getTable()
828
			(getTable()->key_info[keynr].key_length + ref_length) + 1);
779.3.10 by Monty Taylor
Turned on -Wshadow.
829
  return ((double) (key_records + keys_per_block-1) /
830
          (double) keys_per_block);
1 by brian
clean slate
831
}
832
833
834
/****************************************************************************
835
 * Default MRR implementation (MRR to non-MRR converter)
836
 ***************************************************************************/
837
838
/**
839
  Get cost and other information about MRR scan over a known list of ranges
840
841
  Calculate estimated cost and other information about an MRR scan for given
842
  sequence of ranges.
843
844
  @param keyno           Index number
845
  @param seq             Range sequence to be traversed
846
  @param seq_init_param  First parameter for seq->init()
847
  @param n_ranges_arg    Number of ranges in the sequence, or 0 if the caller
848
                         can't efficiently determine it
849
  @param bufsz    INOUT  IN:  Size of the buffer available for use
850
                         OUT: Size of the buffer that is expected to be actually
851
                              used, or 0 if buffer is not needed.
852
  @param flags    INOUT  A combination of HA_MRR_* flags
853
  @param cost     OUT    Estimated cost of MRR access
854
855
  @note
856
    This method (or an overriding one in a derived class) must check for
1910.2.8 by Brian Aker
Enapsulate Kill.
857
    session->getKilled() and return HA_POS_ERROR if it is not zero. This is required
1 by brian
clean slate
858
    for a user to be able to interrupt the calculation by killing the
859
    connection/query.
860
861
  @retval
862
    HA_POS_ERROR  Error or the engine is unable to perform the requested
863
                  scan. Values of OUT parameters are undefined.
864
  @retval
865
    other         OK, *cost contains cost of the scan, *bufsz and *flags
866
                  contain scan parameters.
867
*/
868
77.1.15 by Monty Taylor
Bunch of warning cleanups.
869
ha_rows
1183.1.2 by Brian Aker
Rename of handler to Cursor. You would not believe how long I have wanted
870
Cursor::multi_range_read_info_const(uint32_t keyno, RANGE_SEQ_IF *seq,
77.1.15 by Monty Taylor
Bunch of warning cleanups.
871
                                     void *seq_init_param,
779.1.27 by Monty Taylor
Got rid of __attribute__((unused)) and the like from the .cc files.
872
                                     uint32_t ,
1336.3.2 by Djellel E. Difallah
rename class COST_VECT to CostVector and move it to ./drizzled/optimizer directory
873
                                     uint32_t *bufsz, uint32_t *flags, optimizer::CostVector *cost)
1 by brian
clean slate
874
{
875
  KEY_MULTI_RANGE range;
876
  range_seq_t seq_it;
877
  ha_rows rows, total_rows= 0;
482 by Brian Aker
Remove uint.
878
  uint32_t n_ranges=0;
575.2.2 by Monty Taylor
Moved vio stuff into libdrizzle.
879
1 by brian
clean slate
880
  /* Default MRR implementation doesn't need buffer */
881
  *bufsz= 0;
882
883
  seq_it= seq->init(seq_init_param, n_ranges, *flags);
884
  while (!seq->next(seq_it, &range))
885
  {
886
    n_ranges++;
887
    key_range *min_endp, *max_endp;
888
    {
889
      min_endp= range.start_key.length? &range.start_key : NULL;
890
      max_endp= range.end_key.length? &range.end_key : NULL;
891
    }
892
    if ((range.range_flag & UNIQUE_RANGE) && !(range.range_flag & NULL_RANGE))
893
      rows= 1; /* there can be at most one row */
894
    else
895
    {
575.2.2 by Monty Taylor
Moved vio stuff into libdrizzle.
896
      if (HA_POS_ERROR == (rows= this->records_in_range(keyno, min_endp,
1 by brian
clean slate
897
                                                        max_endp)))
898
      {
899
        /* Can't scan one range => can't do MRR scan at all */
900
        total_rows= HA_POS_ERROR;
901
        break;
902
      }
903
    }
904
    total_rows += rows;
905
  }
575.2.2 by Monty Taylor
Moved vio stuff into libdrizzle.
906
1 by brian
clean slate
907
  if (total_rows != HA_POS_ERROR)
908
  {
909
    /* The following calculation is the same as in multi_range_read_info(): */
910
    *flags |= HA_MRR_USE_DEFAULT_IMPL;
911
    cost->zero();
1336.3.2 by Djellel E. Difallah
rename class COST_VECT to CostVector and move it to ./drizzled/optimizer directory
912
    cost->setAvgIOCost(1); /* assume random seeks */
1 by brian
clean slate
913
    if ((*flags & HA_MRR_INDEX_ONLY) && total_rows > 2)
1336.3.2 by Djellel E. Difallah
rename class COST_VECT to CostVector and move it to ./drizzled/optimizer directory
914
      cost->setIOCount(index_only_read_time(keyno, (uint32_t)total_rows));
1 by brian
clean slate
915
    else
1336.3.2 by Djellel E. Difallah
rename class COST_VECT to CostVector and move it to ./drizzled/optimizer directory
916
      cost->setIOCount(read_time(keyno, n_ranges, total_rows));
917
    cost->setCpuCost((double) total_rows / TIME_FOR_COMPARE + 0.01);
1 by brian
clean slate
918
  }
919
  return total_rows;
920
}
921
922
923
/**
924
  Get cost and other information about MRR scan over some sequence of ranges
925
926
  Calculate estimated cost and other information about an MRR scan for some
927
  sequence of ranges.
928
929
  The ranges themselves will be known only at execution phase. When this
930
  function is called we only know number of ranges and a (rough) E(#records)
931
  within those ranges.
932
933
  Currently this function is only called for "n-keypart singlepoint" ranges,
934
  i.e. each range is "keypart1=someconst1 AND ... AND keypartN=someconstN"
935
936
  The flags parameter is a combination of those flags: HA_MRR_SORTED,
937
  HA_MRR_INDEX_ONLY, HA_MRR_NO_ASSOCIATION, HA_MRR_LIMITS.
938
939
  @param keyno           Index number
940
  @param n_ranges        Estimated number of ranges (i.e. intervals) in the
941
                         range sequence.
942
  @param n_rows          Estimated total number of records contained within all
943
                         of the ranges
944
  @param bufsz    INOUT  IN:  Size of the buffer available for use
945
                         OUT: Size of the buffer that will be actually used, or
946
                              0 if buffer is not needed.
947
  @param flags    INOUT  A combination of HA_MRR_* flags
948
  @param cost     OUT    Estimated cost of MRR access
949
950
  @retval
951
    0     OK, *cost contains cost of the scan, *bufsz and *flags contain scan
952
          parameters.
953
  @retval
954
    other Error or can't perform the requested scan
955
*/
956
1183.1.2 by Brian Aker
Rename of handler to Cursor. You would not believe how long I have wanted
957
int Cursor::multi_range_read_info(uint32_t keyno, uint32_t n_ranges, uint32_t n_rows,
1336.3.2 by Djellel E. Difallah
rename class COST_VECT to CostVector and move it to ./drizzled/optimizer directory
958
                                   uint32_t *bufsz, uint32_t *flags, optimizer::CostVector *cost)
1 by brian
clean slate
959
{
960
  *bufsz= 0; /* Default implementation doesn't need a buffer */
961
962
  *flags |= HA_MRR_USE_DEFAULT_IMPL;
963
964
  cost->zero();
1336.3.2 by Djellel E. Difallah
rename class COST_VECT to CostVector and move it to ./drizzled/optimizer directory
965
  cost->setAvgIOCost(1); /* assume random seeks */
1 by brian
clean slate
966
967
  /* Produce the same cost as non-MRR code does */
968
  if (*flags & HA_MRR_INDEX_ONLY)
1336.3.2 by Djellel E. Difallah
rename class COST_VECT to CostVector and move it to ./drizzled/optimizer directory
969
    cost->setIOCount(index_only_read_time(keyno, n_rows));
1 by brian
clean slate
970
  else
1336.3.2 by Djellel E. Difallah
rename class COST_VECT to CostVector and move it to ./drizzled/optimizer directory
971
    cost->setIOCount(read_time(keyno, n_ranges, n_rows));
1 by brian
clean slate
972
  return 0;
973
}
974
975
976
/**
977
  Initialize the MRR scan
978
575.2.2 by Monty Taylor
Moved vio stuff into libdrizzle.
979
  Initialize the MRR scan. This function may do heavyweight scan
1 by brian
clean slate
980
  initialization like row prefetching/sorting/etc (NOTE: but better not do
981
  it here as we may not need it, e.g. if we never satisfy WHERE clause on
982
  previous tables. For many implementations it would be natural to do such
983
  initializations in the first multi_read_range_next() call)
984
985
  mode is a combination of the following flags: HA_MRR_SORTED,
575.2.2 by Monty Taylor
Moved vio stuff into libdrizzle.
986
  HA_MRR_INDEX_ONLY, HA_MRR_NO_ASSOCIATION
1 by brian
clean slate
987
988
  @param seq             Range sequence to be traversed
989
  @param seq_init_param  First parameter for seq->init()
990
  @param n_ranges        Number of ranges in the sequence
991
  @param mode            Flags, see the description section for the details
992
  @param buf             INOUT: memory buffer to be used
993
994
  @note
1491.1.6 by Jay Pipes
Cursor::ha_index_init() -> Cursor::startIndexScan(). Cursor::ha_index_end() -> Cursor::endIndexScan()
995
    One must have called doStartIndexScan() before calling this function. Several
1 by brian
clean slate
996
    multi_range_read_init() calls may be made in course of one query.
997
575.2.2 by Monty Taylor
Moved vio stuff into libdrizzle.
998
    Until WL#2623 is done (see its text, section 3.2), the following will
1 by brian
clean slate
999
    also hold:
1000
    The caller will guarantee that if "seq->init == mrr_ranges_array_init"
1001
    then seq_init_param is an array of n_ranges KEY_MULTI_RANGE structures.
1183.1.2 by Brian Aker
Rename of handler to Cursor. You would not believe how long I have wanted
1002
    This property will only be used by NDB Cursor until WL#2623 is done.
575.2.2 by Monty Taylor
Moved vio stuff into libdrizzle.
1003
1 by brian
clean slate
1004
    Buffer memory management is done according to the following scenario:
1005
    The caller allocates the buffer and provides it to the callee by filling
1006
    the members of HANDLER_BUFFER structure.
1007
    The callee consumes all or some fraction of the provided buffer space, and
1008
    sets the HANDLER_BUFFER members accordingly.
1009
    The callee may use the buffer memory until the next multi_range_read_init()
1491.1.6 by Jay Pipes
Cursor::ha_index_init() -> Cursor::startIndexScan(). Cursor::ha_index_end() -> Cursor::endIndexScan()
1010
    call is made, all records have been read, or until doEndIndexScan() call is
1 by brian
clean slate
1011
    made, whichever comes first.
1012
1013
  @retval 0  OK
1014
  @retval 1  Error
1015
*/
1016
1017
int
1183.1.2 by Brian Aker
Rename of handler to Cursor. You would not believe how long I have wanted
1018
Cursor::multi_range_read_init(RANGE_SEQ_IF *seq_funcs, void *seq_init_param,
1491 by Brian Aker
Remove call bits in dead mrr caller.
1019
                               uint32_t n_ranges, uint32_t mode)
1 by brian
clean slate
1020
{
1021
  mrr_iter= seq_funcs->init(seq_init_param, n_ranges, mode);
1022
  mrr_funcs= *seq_funcs;
1023
  mrr_is_output_sorted= test(mode & HA_MRR_SORTED);
56 by brian
Next pass of true/false update.
1024
  mrr_have_range= false;
1491 by Brian Aker
Remove call bits in dead mrr caller.
1025
1046.1.9 by Brian Aker
Remove caller that wasn't correctly locking, and reverted code to 5.1
1026
  return 0;
1 by brian
clean slate
1027
}
1028
1029
1030
/**
1031
  Get next record in MRR scan
1032
1033
  Default MRR implementation: read the next record
1034
1035
  @param range_info  OUT  Undefined if HA_MRR_NO_ASSOCIATION flag is in effect
1036
                          Otherwise, the opaque value associated with the range
1037
                          that contains the returned record.
1038
1039
  @retval 0      OK
1040
  @retval other  Error code
1041
*/
1042
1183.1.2 by Brian Aker
Rename of handler to Cursor. You would not believe how long I have wanted
1043
int Cursor::multi_range_read_next(char **range_info)
1 by brian
clean slate
1044
{
1045
  int result= 0;
236.2.2 by rbradfor
Using correct coding standards for variable initialization
1046
  int range_res= 0;
1 by brian
clean slate
1047
1492 by Brian Aker
Dead code removal.
1048
  if (not mrr_have_range)
1 by brian
clean slate
1049
  {
56 by brian
Next pass of true/false update.
1050
    mrr_have_range= true;
1 by brian
clean slate
1051
    goto start;
1052
  }
1053
1054
  do
1055
  {
1056
    /* Save a call if there can be only one row in range. */
1057
    if (mrr_cur_range.range_flag != (UNIQUE_RANGE | EQ_RANGE))
1058
    {
1059
      result= read_range_next();
1060
      /* On success or non-EOF errors jump to the end. */
1061
      if (result != HA_ERR_END_OF_FILE)
1062
        break;
1063
    }
1064
    else
1065
    {
1066
      if (was_semi_consistent_read())
1067
        goto scan_it_again;
1068
      /*
1069
        We need to set this for the last range only, but checking this
1070
        condition is more expensive than just setting the result code.
1071
      */
1072
      result= HA_ERR_END_OF_FILE;
1073
    }
1074
1075
start:
1076
    /* Try the next range(s) until one matches a record. */
1077
    while (!(range_res= mrr_funcs.next(mrr_iter, &mrr_cur_range)))
1078
    {
1079
scan_it_again:
1080
      result= read_range_first(mrr_cur_range.start_key.keypart_map ?
1081
                                 &mrr_cur_range.start_key : 0,
1082
                               mrr_cur_range.end_key.keypart_map ?
1083
                                 &mrr_cur_range.end_key : 0,
1084
                               test(mrr_cur_range.range_flag & EQ_RANGE),
1085
                               mrr_is_output_sorted);
1086
      if (result != HA_ERR_END_OF_FILE)
1087
        break;
1088
    }
1089
  }
1090
  while ((result == HA_ERR_END_OF_FILE) && !range_res);
1091
1092
  *range_info= mrr_cur_range.ptr;
1046.1.9 by Brian Aker
Remove caller that wasn't correctly locking, and reverted code to 5.1
1093
  return result;
1 by brian
clean slate
1094
}
1095
1096
1097
/* **************************************************************************
1098
 * DS-MRR implementation ends
1099
 ***************************************************************************/
1100
1101
/**
1102
  Read first row between two ranges.
1103
1104
  @param start_key		Start key. Is 0 if no min range
1105
  @param end_key		End key.  Is 0 if no max range
1106
  @param eq_range_arg	        Set to 1 if start_key == end_key
1107
  @param sorted		Set to 1 if result should be sorted per key
1108
1109
  @note
1672.3.6 by Brian Aker
First pass in encapsulating row
1110
    Record is read into table->getInsertRecord()
1 by brian
clean slate
1111
1112
  @retval
1113
    0			Found row
1114
  @retval
1115
    HA_ERR_END_OF_FILE	No rows in range
1116
  @retval
1117
    \#			Error code
1118
*/
1183.1.2 by Brian Aker
Rename of handler to Cursor. You would not believe how long I have wanted
1119
int Cursor::read_range_first(const key_range *start_key,
1183.1.4 by Brian Aker
Minor interface bits around Cursor.
1120
                             const key_range *end_key,
1121
                             bool eq_range_arg,
1122
                             bool )
1 by brian
clean slate
1123
{
1124
  int result;
1125
1126
  eq_range= eq_range_arg;
1127
  end_range= 0;
1128
  if (end_key)
1129
  {
1130
    end_range= &save_end_range;
1131
    save_end_range= *end_key;
1132
    key_compare_result_on_equal= ((end_key->flag == HA_READ_BEFORE_KEY) ? 1 :
1133
				  (end_key->flag == HA_READ_AFTER_KEY) ? -1 : 0);
1134
  }
1869.1.5 by Brian Aker
getTable()
1135
  range_key_part= getTable()->key_info[active_index].key_part;
1 by brian
clean slate
1136
1137
  if (!start_key)			// Read first record
1869.1.5 by Brian Aker
getTable()
1138
    result= index_first(getTable()->getInsertRecord());
1 by brian
clean slate
1139
  else
1869.1.5 by Brian Aker
getTable()
1140
    result= index_read_map(getTable()->getInsertRecord(),
1 by brian
clean slate
1141
                           start_key->key,
1142
                           start_key->keypart_map,
1143
                           start_key->flag);
1144
  if (result)
575.2.2 by Monty Taylor
Moved vio stuff into libdrizzle.
1145
    return((result == HA_ERR_KEY_NOT_FOUND)
1 by brian
clean slate
1146
		? HA_ERR_END_OF_FILE
1147
		: result);
1148
51.1.77 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
1149
  return (compare_key(end_range) <= 0 ? 0 : HA_ERR_END_OF_FILE);
1 by brian
clean slate
1150
}
1151
1152
1153
/**
1154
  Read next row between two endpoints.
1155
1156
  @note
1672.3.6 by Brian Aker
First pass in encapsulating row
1157
    Record is read into table->getInsertRecord()
1 by brian
clean slate
1158
1159
  @retval
1160
    0			Found row
1161
  @retval
1162
    HA_ERR_END_OF_FILE	No rows in range
1163
  @retval
1164
    \#			Error code
1165
*/
1183.1.2 by Brian Aker
Rename of handler to Cursor. You would not believe how long I have wanted
1166
int Cursor::read_range_next()
1 by brian
clean slate
1167
{
1168
  int result;
1169
1170
  if (eq_range)
1171
  {
1172
    /* We trust that index_next_same always gives a row in range */
1869.1.5 by Brian Aker
getTable()
1173
    return(index_next_same(getTable()->getInsertRecord(),
1 by brian
clean slate
1174
                                end_range->key,
1175
                                end_range->length));
1176
  }
1869.1.5 by Brian Aker
getTable()
1177
  result= index_next(getTable()->getInsertRecord());
1 by brian
clean slate
1178
  if (result)
1046.1.9 by Brian Aker
Remove caller that wasn't correctly locking, and reverted code to 5.1
1179
    return result;
51.1.77 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
1180
  return(compare_key(end_range) <= 0 ? 0 : HA_ERR_END_OF_FILE);
1 by brian
clean slate
1181
}
1182
1183
1184
/**
1185
  Compare if found key (in row) is over max-value.
1186
1187
  @param range		range to compare to row. May be 0 for no range
1188
1189
  @seealso
1190
    key.cc::key_cmp()
1191
1192
  @return
1193
    The return value is SIGN(key_in_row - range_key):
1194
1195
    - 0   : Key is equal to range or 'range' == 0 (no range)
1196
    - -1  : Key is less than range
1197
    - 1   : Key is larger than range
1198
*/
1183.1.2 by Brian Aker
Rename of handler to Cursor. You would not believe how long I have wanted
1199
int Cursor::compare_key(key_range *range)
1 by brian
clean slate
1200
{
1201
  int cmp;
1492 by Brian Aker
Dead code removal.
1202
  if (not range)
1 by brian
clean slate
1203
    return 0;					// No max range
1204
  cmp= key_cmp(range_key_part, range->key, range->length);
1205
  if (!cmp)
1206
    cmp= key_compare_result_on_equal;
1207
  return cmp;
1208
}
1209
1183.1.2 by Brian Aker
Rename of handler to Cursor. You would not believe how long I have wanted
1210
int Cursor::index_read_idx_map(unsigned char * buf, uint32_t index,
656.1.1 by Monty Taylor
OOOh doggie. Got rid of my_alloca.
1211
                                const unsigned char * key,
1 by brian
clean slate
1212
                                key_part_map keypart_map,
1213
                                enum ha_rkey_function find_flag)
1214
{
1215
  int error, error1;
1491.1.6 by Jay Pipes
Cursor::ha_index_init() -> Cursor::startIndexScan(). Cursor::ha_index_end() -> Cursor::endIndexScan()
1216
  error= doStartIndexScan(index, 0);
1 by brian
clean slate
1217
  if (!error)
1218
  {
1219
    error= index_read_map(buf, key, keypart_map, find_flag);
1491.1.6 by Jay Pipes
Cursor::ha_index_init() -> Cursor::startIndexScan(). Cursor::ha_index_end() -> Cursor::endIndexScan()
1220
    error1= doEndIndexScan();
1 by brian
clean slate
1221
  }
1222
  return error ?  error : error1;
1223
}
1224
1225
/**
1226
  Check if the conditions for row-based binlogging is correct for the table.
1227
1228
  A row in the given table should be replicated if:
1229
  - It is not a temporary table
1230
*/
1231
1039.1.16 by Brian Aker
A lot of little cleanups (most based off lcov)
1232
static bool log_row_for_replication(Table* table,
1143.2.20 by Jay Pipes
* Fixes bug in replication where inserts, updates, and
1233
                                    const unsigned char *before_record,
1234
                                    const unsigned char *after_record)
1 by brian
clean slate
1235
{
520.1.22 by Brian Aker
Second pass of thd cleanup
1236
  Session *const session= table->in_use;
1 by brian
clean slate
1237
2318.6.62 by Olaf van der Spek
Refactor
1238
  if (table->getShare()->getType() || not TransactionServices::shouldConstructMessages())
1143.2.20 by Jay Pipes
* Fixes bug in replication where inserts, updates, and
1239
    return false;
1240
1143.4.15 by Jay Pipes
Adds error for when a record is inserted into a table containing
1241
  bool result= false;
1242
2227.4.8 by Olaf van der Spek
Session::lex()
1243
  switch (session->lex().sql_command)
661 by Brian Aker
First major pass through new replication.
1244
  {
1308.2.11 by Jay Pipes
* Adds CREATE TABLE as a specific CreateTableStatement message in the
1245
  case SQLCOM_CREATE_TABLE:
1246
    /*
1247
     * We are in a CREATE TABLE ... SELECT statement
1248
     * and the kernel has already created the table
1249
     * and put a CreateTableStatement in the active
1250
     * Transaction message.  Here, we add a new InsertRecord
1251
     * to a new Transaction message (because the above
1252
     * CREATE TABLE will commit the transaction containing
1253
     * it).
1254
     */
2318.6.62 by Olaf van der Spek
Refactor
1255
    result= TransactionServices::insertRecord(*session, *table);
1308.2.11 by Jay Pipes
* Adds CREATE TABLE as a specific CreateTableStatement message in the
1256
    break;
661 by Brian Aker
First major pass through new replication.
1257
  case SQLCOM_REPLACE:
1143.2.22 by Jay Pipes
Adds functionality to handle REPLACE statements correctly in the replication
1258
  case SQLCOM_REPLACE_SELECT:
1143.2.24 by Jay Pipes
Fixes some stuff from make check (include guards). Also adds stuff for REPLACE logic that does not work.
1259
    /*
1143.2.27 by Jay Pipes
Corrects problems where REPLACE and INSERT ... ON DUPLICATE KEY UPDATE
1260
     * This is a total hack because of the code that is
1261
     * in write_record() in sql_insert.cc. During
1491.1.2 by Jay Pipes
Cursor::write_row() -> Cursor::doInsertRecord(). Cursor::ha_write_row() -> Cursor::insertRecord()
1262
     * a REPLACE statement, a call to insertRecord() is
1491.1.4 by Jay Pipes
delete_row() is now deleteRecord() and doDeleteRecord() in Cursor
1263
     * called.  If it fails, then a call to deleteRecord()
1143.2.24 by Jay Pipes
Fixes some stuff from make check (include guards). Also adds stuff for REPLACE logic that does not work.
1264
     * is called, followed by a repeat of the original
1491.1.2 by Jay Pipes
Cursor::write_row() -> Cursor::doInsertRecord(). Cursor::ha_write_row() -> Cursor::insertRecord()
1265
     * call to insertRecord().  So, log_row_for_replication
1730.5.3 by David Shrewsbury
Correct comments regarding REPLACE logic.
1266
     * could be called multiple times for a REPLACE
1143.2.24 by Jay Pipes
Fixes some stuff from make check (include guards). Also adds stuff for REPLACE logic that does not work.
1267
     * statement.  The below looks at the values of before_record
1268
     * and after_record to determine which call to this
1269
     * function is for the delete or the insert, since NULL
1270
     * is passed for after_record for the delete and NULL is
1271
     * passed for before_record for the insert...
1143.2.27 by Jay Pipes
Corrects problems where REPLACE and INSERT ... ON DUPLICATE KEY UPDATE
1272
     *
1273
     * In addition, there is an optimization that allows an
1274
     * engine to convert the above delete + insert into an
1275
     * update, so we must also check for this case below...
1143.2.22 by Jay Pipes
Adds functionality to handle REPLACE statements correctly in the replication
1276
     */
1143.2.24 by Jay Pipes
Fixes some stuff from make check (include guards). Also adds stuff for REPLACE logic that does not work.
1277
    if (after_record == NULL)
1278
    {
1730.5.3 by David Shrewsbury
Correct comments regarding REPLACE logic.
1279
      /*
1280
       * The storage engine is passed the record in table->record[1]
1281
       * as the row to delete (this is the conflicting row), so
1282
       * we need to notify TransactionService to use that row.
1283
       */
2318.6.62 by Olaf van der Spek
Refactor
1284
      TransactionServices::deleteRecord(*session, *table, true);
1143.2.24 by Jay Pipes
Fixes some stuff from make check (include guards). Also adds stuff for REPLACE logic that does not work.
1285
      /* 
1286
       * We set the "current" statement message to NULL.  This triggers
1287
       * the replication services component to generate a new statement
1288
       * message for the inserted record which will come next.
1289
       */
2318.6.62 by Olaf van der Spek
Refactor
1290
      TransactionServices::finalizeStatementMessage(*session->getStatementMessage(), *session);
1143.2.24 by Jay Pipes
Fixes some stuff from make check (include guards). Also adds stuff for REPLACE logic that does not work.
1291
    }
1292
    else
1293
    {
1143.2.27 by Jay Pipes
Corrects problems where REPLACE and INSERT ... ON DUPLICATE KEY UPDATE
1294
      if (before_record == NULL)
2318.6.62 by Olaf van der Spek
Refactor
1295
        result= TransactionServices::insertRecord(*session, *table);
1143.2.27 by Jay Pipes
Corrects problems where REPLACE and INSERT ... ON DUPLICATE KEY UPDATE
1296
      else
2318.6.62 by Olaf van der Spek
Refactor
1297
        TransactionServices::updateRecord(*session, *table, before_record, after_record);
1143.2.24 by Jay Pipes
Fixes some stuff from make check (include guards). Also adds stuff for REPLACE logic that does not work.
1298
    }
1143.2.22 by Jay Pipes
Adds functionality to handle REPLACE statements correctly in the replication
1299
    break;
661 by Brian Aker
First major pass through new replication.
1300
  case SQLCOM_INSERT:
1301
  case SQLCOM_INSERT_SELECT:
1719.3.1 by David Shrewsbury
Fix to capture INSERTs from a LOAD DATA command in the replication stream.
1302
  case SQLCOM_LOAD:
1143.2.27 by Jay Pipes
Corrects problems where REPLACE and INSERT ... ON DUPLICATE KEY UPDATE
1303
    /*
1304
     * The else block below represents an 
1305
     * INSERT ... ON DUPLICATE KEY UPDATE that
1306
     * has hit a key conflict and actually done
1307
     * an update.
1308
     */
1309
    if (before_record == NULL)
2318.6.62 by Olaf van der Spek
Refactor
1310
      result= TransactionServices::insertRecord(*session, *table);
1143.2.27 by Jay Pipes
Corrects problems where REPLACE and INSERT ... ON DUPLICATE KEY UPDATE
1311
    else
2318.6.62 by Olaf van der Spek
Refactor
1312
      TransactionServices::updateRecord(*session, *table, before_record, after_record);
661 by Brian Aker
First major pass through new replication.
1313
    break;
1314
1315
  case SQLCOM_UPDATE:
2318.6.62 by Olaf van der Spek
Refactor
1316
    TransactionServices::updateRecord(*session, *table, before_record, after_record);
661 by Brian Aker
First major pass through new replication.
1317
    break;
1318
1319
  case SQLCOM_DELETE:
2318.6.62 by Olaf van der Spek
Refactor
1320
    TransactionServices::deleteRecord(*session, *table);
661 by Brian Aker
First major pass through new replication.
1321
    break;
1322
  default:
1323
    break;
1 by brian
clean slate
1324
  }
592 by Brian Aker
Remove one set.
1325
1143.4.15 by Jay Pipes
Adds error for when a record is inserted into a table containing
1326
  return result;
1 by brian
clean slate
1327
}
1328
1183.1.2 by Brian Aker
Rename of handler to Cursor. You would not believe how long I have wanted
1329
int Cursor::ha_external_lock(Session *session, int lock_type)
1 by brian
clean slate
1330
{
1331
  /*
1332
    Whether this is lock or unlock, this should be true, and is to verify that
1333
    if get_auto_increment() was called (thus may have reserved intervals or
1334
    taken a table lock), ha_release_auto_increment() was too.
1335
  */
51.1.77 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
1336
  assert(next_insert_id == 0);
1 by brian
clean slate
1337
1241.7.5 by Padraig O'Sullivan
Added the lock related dtrace probes to the cursor interface.
1338
  if (DRIZZLE_CURSOR_RDLOCK_START_ENABLED() ||
1339
      DRIZZLE_CURSOR_WRLOCK_START_ENABLED() ||
1340
      DRIZZLE_CURSOR_UNLOCK_START_ENABLED())
1341
  {
1342
    if (lock_type == F_RDLCK)
1343
    {
1869.1.2 by Brian Aker
Remove table_share from being required in a cursor.
1344
      DRIZZLE_CURSOR_RDLOCK_START(getTable()->getShare()->getSchemaName(),
1345
                                  getTable()->getShare()->getTableName());
1241.7.5 by Padraig O'Sullivan
Added the lock related dtrace probes to the cursor interface.
1346
    }
1347
    else if (lock_type == F_WRLCK)
1348
    {
1869.1.2 by Brian Aker
Remove table_share from being required in a cursor.
1349
      DRIZZLE_CURSOR_WRLOCK_START(getTable()->getShare()->getSchemaName(),
1350
                                  getTable()->getShare()->getTableName());
1241.7.5 by Padraig O'Sullivan
Added the lock related dtrace probes to the cursor interface.
1351
    }
1352
    else if (lock_type == F_UNLCK)
1353
    {
1869.1.2 by Brian Aker
Remove table_share from being required in a cursor.
1354
      DRIZZLE_CURSOR_UNLOCK_START(getTable()->getShare()->getSchemaName(),
1355
                                  getTable()->getShare()->getTableName());
1241.7.5 by Padraig O'Sullivan
Added the lock related dtrace probes to the cursor interface.
1356
    }
1357
  }
1358
1 by brian
clean slate
1359
  /*
1360
    We cache the table flags if the locking succeeded. Otherwise, we
1361
    keep them as they were when they were fetched in ha_open().
1362
  */
1363
520.1.22 by Brian Aker
Second pass of thd cleanup
1364
  int error= external_lock(session, lock_type);
1126.10.11 by Padraig O'Sullivan
Added calls to the dtrace probes related to locks.
1365
1241.7.5 by Padraig O'Sullivan
Added the lock related dtrace probes to the cursor interface.
1366
  if (DRIZZLE_CURSOR_RDLOCK_DONE_ENABLED() ||
1367
      DRIZZLE_CURSOR_WRLOCK_DONE_ENABLED() ||
1368
      DRIZZLE_CURSOR_UNLOCK_DONE_ENABLED())
1369
  {
1370
    if (lock_type == F_RDLCK)
1371
    {
1372
      DRIZZLE_CURSOR_RDLOCK_DONE(error);
1373
    }
1374
    else if (lock_type == F_WRLCK)
1375
    {
1376
      DRIZZLE_CURSOR_WRLOCK_DONE(error);
1377
    }
1378
    else if (lock_type == F_UNLCK)
1379
    {
1380
      DRIZZLE_CURSOR_UNLOCK_DONE(error);
1381
    }
1382
  }
1383
1046.1.9 by Brian Aker
Remove caller that wasn't correctly locking, and reverted code to 5.1
1384
  return error;
1 by brian
clean slate
1385
}
1386
1387
1388
/**
1183.1.2 by Brian Aker
Rename of handler to Cursor. You would not believe how long I have wanted
1389
  Check Cursor usage and reset state of file to after 'open'
1 by brian
clean slate
1390
*/
1183.1.2 by Brian Aker
Rename of handler to Cursor. You would not believe how long I have wanted
1391
int Cursor::ha_reset()
1 by brian
clean slate
1392
{
1005.2.3 by Monty Taylor
Further reversion of P.
1393
  /* Check that we have called all proper deallocation functions */
1869.1.5 by Brian Aker
getTable()
1394
  assert(! getTable()->getShare()->all_set.none());
1395
  assert(getTable()->key_read == 0);
1491.1.10 by Jay Pipes
ha_rnd_init -> startTableScan, rnd_init -> doStartTableScan, ha_rnd_end -> endTableScan, rnd_end -> doEndTableScan
1396
  /* ensure that ha_index_end / endTableScan has been called */
51.1.77 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
1397
  assert(inited == NONE);
1 by brian
clean slate
1398
  /* Free cache used by filesort */
1869.1.5 by Brian Aker
getTable()
1399
  getTable()->free_io_cache();
1 by brian
clean slate
1400
  /* reset the bitmaps to point to defaults */
1869.1.5 by Brian Aker
getTable()
1401
  getTable()->default_column_bitmaps();
51.1.77 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
1402
  return(reset());
1 by brian
clean slate
1403
}
1404
1405
1491.1.2 by Jay Pipes
Cursor::write_row() -> Cursor::doInsertRecord(). Cursor::ha_write_row() -> Cursor::insertRecord()
1406
int Cursor::insertRecord(unsigned char *buf)
1 by brian
clean slate
1407
{
1408
  int error;
1409
1235.1.11 by Brian Aker
Small cleanups, did in MERGE table only engine flag.
1410
  /*
1411
   * If we have a timestamp column, update it to the current time
1412
   *
873.1.16 by Jay Pipes
This patch pulls the setting of the auto-set timestamp out of the individual
1413
   * @TODO Technically, the below two lines can be take even further out of the
1183.1.2 by Brian Aker
Rename of handler to Cursor. You would not believe how long I have wanted
1414
   * Cursor interface and into the fill_record() method.
873.1.16 by Jay Pipes
This patch pulls the setting of the auto-set timestamp out of the individual
1415
   */
1869.1.5 by Brian Aker
getTable()
1416
  if (getTable()->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT)
1607 by Brian Aker
Cursor now fully handles the update to timestamp for the engine.
1417
  {
1869.1.5 by Brian Aker
getTable()
1418
    getTable()->timestamp_field->set_time();
1607 by Brian Aker
Cursor now fully handles the update to timestamp for the engine.
1419
  }
873.1.16 by Jay Pipes
This patch pulls the setting of the auto-set timestamp out of the individual
1420
1869.1.2 by Brian Aker
Remove table_share from being required in a cursor.
1421
  DRIZZLE_INSERT_ROW_START(getTable()->getShare()->getSchemaName(), getTable()->getShare()->getTableName());
1273.1.12 by Jay Pipes
Cleanup style and documentation for ResourceContext and setTransactionReadWrite
1422
  setTransactionReadWrite();
1502.5.2 by Barry.Leslie at PrimeBase
Changes made to drizzle source when building in the events plugin.
1423
  
1869.1.5 by Brian Aker
getTable()
1424
  if (unlikely(plugin::EventObserver::beforeInsertRecord(*getTable(), buf)))
1502.5.7 by Barry.Leslie at PrimeBase
Renamed the 'Event' plugin to 'EventObserver' plugin along with some internal class renames to make things clearer.
1425
  {
1426
    error= ER_EVENT_OBSERVER_PLUGIN;
1427
  }
1502.5.2 by Barry.Leslie at PrimeBase
Changes made to drizzle source when building in the events plugin.
1428
  else
1429
  {
1430
    error= doInsertRecord(buf);
1869.1.5 by Brian Aker
getTable()
1431
    if (unlikely(plugin::EventObserver::afterInsertRecord(*getTable(), buf, error))) 
1502.5.7 by Barry.Leslie at PrimeBase
Renamed the 'Event' plugin to 'EventObserver' plugin along with some internal class renames to make things clearer.
1432
    {
1433
      error= ER_EVENT_OBSERVER_PLUGIN;
1434
    }
1502.5.2 by Barry.Leslie at PrimeBase
Changes made to drizzle source when building in the events plugin.
1435
  }
1619.3.3 by Stewart Smith
move ha_statistic_increment for ha_write count (the Handler_write status variable) to the Cursor layer so that each Storage Engine's Cursor doesn't have to increment it.
1436
1437
  ha_statistic_increment(&system_status_var::ha_write_count);
1438
1241.7.4 by Padraig O'Sullivan
Inserted calls to the cursor related probes that fire on inserts, updates, and deletes.
1439
  DRIZZLE_INSERT_ROW_DONE(error);
1 by brian
clean slate
1440
1241.7.4 by Padraig O'Sullivan
Inserted calls to the cursor related probes that fire on inserts, updates, and deletes.
1441
  if (unlikely(error))
1126.10.17 by Padraig O'Sullivan
Added calls to the update related dtrace probes.
1442
  {
1046.1.9 by Brian Aker
Remove caller that wasn't correctly locking, and reverted code to 5.1
1443
    return error;
1126.10.17 by Padraig O'Sullivan
Added calls to the update related dtrace probes.
1444
  }
662 by Brian Aker
Remove dead methods.
1445
1869.1.5 by Brian Aker
getTable()
1446
  if (unlikely(log_row_for_replication(getTable(), NULL, buf)))
971.6.11 by Eric Day
Removed purecov messages.
1447
    return HA_ERR_RBR_LOGGING_FAILED;
662 by Brian Aker
Remove dead methods.
1448
1046.1.9 by Brian Aker
Remove caller that wasn't correctly locking, and reverted code to 5.1
1449
  return 0;
1 by brian
clean slate
1450
}
1451
1452
1491.1.3 by Jay Pipes
Cursor::update_row() changed to doUpdateRecord() and updateRecord()
1453
int Cursor::updateRecord(const unsigned char *old_data, unsigned char *new_data)
1 by brian
clean slate
1454
{
1455
  int error;
1456
1457
  /*
1672.3.6 by Brian Aker
First pass in encapsulating row
1458
    Some storage engines require that the new record is in getInsertRecord()
1459
    (and the old record is in getUpdateRecord()).
1 by brian
clean slate
1460
   */
1869.1.5 by Brian Aker
getTable()
1461
  assert(new_data == getTable()->getInsertRecord());
1 by brian
clean slate
1462
1869.1.2 by Brian Aker
Remove table_share from being required in a cursor.
1463
  DRIZZLE_UPDATE_ROW_START(getTable()->getShare()->getSchemaName(), getTable()->getShare()->getTableName());
1273.1.12 by Jay Pipes
Cleanup style and documentation for ResourceContext and setTransactionReadWrite
1464
  setTransactionReadWrite();
1869.1.5 by Brian Aker
getTable()
1465
  if (unlikely(plugin::EventObserver::beforeUpdateRecord(*getTable(), old_data, new_data)))
1502.5.7 by Barry.Leslie at PrimeBase
Renamed the 'Event' plugin to 'EventObserver' plugin along with some internal class renames to make things clearer.
1466
  {
1467
    error= ER_EVENT_OBSERVER_PLUGIN;
1468
  }
1502.5.2 by Barry.Leslie at PrimeBase
Changes made to drizzle source when building in the events plugin.
1469
  else
1470
  {
1869.1.5 by Brian Aker
getTable()
1471
    if (getTable()->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE)
1607 by Brian Aker
Cursor now fully handles the update to timestamp for the engine.
1472
    {
1869.1.5 by Brian Aker
getTable()
1473
      getTable()->timestamp_field->set_time();
1607 by Brian Aker
Cursor now fully handles the update to timestamp for the engine.
1474
    }
1475
1502.5.2 by Barry.Leslie at PrimeBase
Changes made to drizzle source when building in the events plugin.
1476
    error= doUpdateRecord(old_data, new_data);
1869.1.5 by Brian Aker
getTable()
1477
    if (unlikely(plugin::EventObserver::afterUpdateRecord(*getTable(), old_data, new_data, error)))
1502.5.7 by Barry.Leslie at PrimeBase
Renamed the 'Event' plugin to 'EventObserver' plugin along with some internal class renames to make things clearer.
1478
    {
1479
      error= ER_EVENT_OBSERVER_PLUGIN;
1480
    }
1502.5.2 by Barry.Leslie at PrimeBase
Changes made to drizzle source when building in the events plugin.
1481
  }
1482
1619.3.5 by Stewart Smith
move ha_statistic_increment for ha_update_count (the Handler_update status variable) to the Cursor layer so that each Storage Engine's Cursor doesn't have to increment it.
1483
  ha_statistic_increment(&system_status_var::ha_update_count);
1484
1241.7.4 by Padraig O'Sullivan
Inserted calls to the cursor related probes that fire on inserts, updates, and deletes.
1485
  DRIZZLE_UPDATE_ROW_DONE(error);
1 by brian
clean slate
1486
1241.7.4 by Padraig O'Sullivan
Inserted calls to the cursor related probes that fire on inserts, updates, and deletes.
1487
  if (unlikely(error))
1126.10.17 by Padraig O'Sullivan
Added calls to the update related dtrace probes.
1488
  {
1 by brian
clean slate
1489
    return error;
1126.10.17 by Padraig O'Sullivan
Added calls to the update related dtrace probes.
1490
  }
1491
1869.1.5 by Brian Aker
getTable()
1492
  if (unlikely(log_row_for_replication(getTable(), old_data, new_data)))
662 by Brian Aker
Remove dead methods.
1493
    return HA_ERR_RBR_LOGGING_FAILED;
1494
1 by brian
clean slate
1495
  return 0;
1496
}
1869.1.2 by Brian Aker
Remove table_share from being required in a cursor.
1497
TableShare *Cursor::getShare()
1498
{
1499
  return getTable()->getMutableShare();
1500
}
1 by brian
clean slate
1501
1491.1.4 by Jay Pipes
delete_row() is now deleteRecord() and doDeleteRecord() in Cursor
1502
int Cursor::deleteRecord(const unsigned char *buf)
1 by brian
clean slate
1503
{
1504
  int error;
1505
1869.1.2 by Brian Aker
Remove table_share from being required in a cursor.
1506
  DRIZZLE_DELETE_ROW_START(getTable()->getShare()->getSchemaName(), getTable()->getShare()->getTableName());
1273.1.12 by Jay Pipes
Cleanup style and documentation for ResourceContext and setTransactionReadWrite
1507
  setTransactionReadWrite();
1869.1.5 by Brian Aker
getTable()
1508
  if (unlikely(plugin::EventObserver::beforeDeleteRecord(*getTable(), buf)))
1502.5.7 by Barry.Leslie at PrimeBase
Renamed the 'Event' plugin to 'EventObserver' plugin along with some internal class renames to make things clearer.
1509
  {
1510
    error= ER_EVENT_OBSERVER_PLUGIN;
1511
  }
1502.5.2 by Barry.Leslie at PrimeBase
Changes made to drizzle source when building in the events plugin.
1512
  else
1513
  {
1514
    error= doDeleteRecord(buf);
1869.1.5 by Brian Aker
getTable()
1515
    if (unlikely(plugin::EventObserver::afterDeleteRecord(*getTable(), buf, error)))
1502.5.7 by Barry.Leslie at PrimeBase
Renamed the 'Event' plugin to 'EventObserver' plugin along with some internal class renames to make things clearer.
1516
    {
1517
      error= ER_EVENT_OBSERVER_PLUGIN;
1518
    }
1502.5.2 by Barry.Leslie at PrimeBase
Changes made to drizzle source when building in the events plugin.
1519
  }
1520
1619.3.7 by Stewart Smith
move ha_statistic_increment for ha_delete_count (the Handler_delete status variable) to the Cursor layer so that each Storage Engine's Cursor doesn't have to increment it.
1521
  ha_statistic_increment(&system_status_var::ha_delete_count);
1522
1241.7.4 by Padraig O'Sullivan
Inserted calls to the cursor related probes that fire on inserts, updates, and deletes.
1523
  DRIZZLE_DELETE_ROW_DONE(error);
1 by brian
clean slate
1524
1241.7.4 by Padraig O'Sullivan
Inserted calls to the cursor related probes that fire on inserts, updates, and deletes.
1525
  if (unlikely(error))
1 by brian
clean slate
1526
    return error;
662 by Brian Aker
Remove dead methods.
1527
1869.1.5 by Brian Aker
getTable()
1528
  if (unlikely(log_row_for_replication(getTable(), buf, NULL)))
662 by Brian Aker
Remove dead methods.
1529
    return HA_ERR_RBR_LOGGING_FAILED;
1530
1 by brian
clean slate
1531
  return 0;
1532
}
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
1533
1534
} /* namespace drizzled */