~drizzle-trunk/drizzle/development

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