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