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