~drizzle-trunk/drizzle/development

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