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