~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/cursor.cc

  • Committer: Brian Aker
  • Date: 2011-02-22 06:12:02 UTC
  • mfrom: (2190.1.6 drizzle-build)
  • Revision ID: brian@tangent.org-20110222061202-k03czxykqy4x9hjs
List update, header fixes, multiple symbols, and David deletes some code.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
2
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3
3
 *
4
 
 *  Copyright (C) 2008 Sun Microsystems
 
4
 *  Copyright (C) 2008 Sun Microsystems, Inc.
5
5
 *
6
6
 *  This program is free software; you can redistribute it and/or modify
7
7
 *  it under the terms of the GNU General Public License as published by
23
23
  Handler-calling-functions
24
24
*/
25
25
 
26
 
#include "config.h"
 
26
#include <config.h>
27
27
 
28
28
#include <fcntl.h>
29
29
 
30
 
#include "drizzled/my_hash.h"
31
 
#include "drizzled/error.h"
32
 
#include "drizzled/gettext.h"
33
 
#include "drizzled/probes.h"
34
 
#include "drizzled/sql_parse.h"
35
 
#include "drizzled/optimizer/cost_vector.h"
36
 
#include "drizzled/session.h"
37
 
#include "drizzled/sql_base.h"
38
 
#include "drizzled/transaction_services.h"
39
 
#include "drizzled/lock.h"
40
 
#include "drizzled/item/int.h"
41
 
#include "drizzled/item/empty_string.h"
42
 
#include "drizzled/field/timestamp.h"
43
 
#include "drizzled/message/table.pb.h"
44
 
#include "drizzled/plugin/client.h"
45
 
#include "drizzled/internal/my_sys.h"
46
 
#include "drizzled/plugin/event_observer.h"
 
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>
47
48
 
48
49
using namespace std;
49
50
 
54
55
** General Cursor functions
55
56
****************************************************************************/
56
57
Cursor::Cursor(plugin::StorageEngine &engine_arg,
57
 
               TableShare &share_arg)
58
 
  : table_share(&share_arg), table(0),
59
 
    estimation_rows_to_insert(0), engine(&engine_arg),
 
58
               Table &arg)
 
59
  : table(arg),
 
60
    engine(engine_arg),
 
61
    estimation_rows_to_insert(0),
60
62
    ref(0),
61
63
    key_used_on_scan(MAX_KEY), active_index(MAX_KEY),
62
64
    ref_length(sizeof(internal::my_off_t)),
79
81
 */
80
82
Cursor *Cursor::clone(memory::Root *mem_root)
81
83
{
82
 
  Cursor *new_handler= table->getMutableShare()->db_type()->getCursor(*table->getMutableShare());
 
84
  Cursor *new_handler= getTable()->getMutableShare()->db_type()->getCursor(*getTable());
83
85
 
84
86
  /*
85
87
    Allocate Cursor->ref here because otherwise ha_open will allocate it
89
91
  if (!(new_handler->ref= (unsigned char*) mem_root->alloc_root(ALIGN_SIZE(ref_length)*2)))
90
92
    return NULL;
91
93
 
92
 
  TableIdentifier identifier(table->getShare()->getSchemaName(),
93
 
                             table->getShare()->getTableName(),
94
 
                             table->getShare()->getType());
 
94
  identifier::Table identifier(getTable()->getShare()->getSchemaName(),
 
95
                             getTable()->getShare()->getTableName(),
 
96
                             getTable()->getShare()->getType());
95
97
 
96
98
  if (new_handler && !new_handler->ha_open(identifier,
97
 
                                           table,
98
 
                                           table->getDBStat(),
 
99
                                           getTable()->getDBStat(),
99
100
                                           HA_OPEN_IGNORE_IF_LOCKED))
100
101
    return new_handler;
101
102
  return NULL;
111
112
  /* works only with key prefixes */
112
113
  assert(((keypart_map_arg + 1) & keypart_map_arg) == 0);
113
114
 
114
 
  const KeyPartInfo *key_part_found= table->getShare()->getKeyInfo(key_position).key_part;
115
 
  const KeyPartInfo *end_key_part_found= key_part_found + table->getShare()->getKeyInfo(key_position).key_parts;
 
115
  const KeyPartInfo *key_part_found= getTable()->getShare()->getKeyInfo(key_position).key_part;
 
116
  const KeyPartInfo *end_key_part_found= key_part_found + getTable()->getShare()->getKeyInfo(key_position).key_parts;
116
117
  uint32_t length= 0;
117
118
 
118
119
  while (key_part_found < end_key_part_found && keypart_map_arg)
175
176
  return end_bulk_insert();
176
177
}
177
178
 
178
 
void Cursor::change_table_ptr(Table *table_arg, TableShare *share)
179
 
{
180
 
  table= table_arg;
181
 
  table_share= share;
182
 
}
183
 
 
184
179
const key_map *Cursor::keys_to_use_for_scanning()
185
180
{
186
181
  return &key_map_empty;
188
183
 
189
184
bool Cursor::has_transactions()
190
185
{
191
 
  return (table->getShare()->db_type()->check_flag(HTON_BIT_DOES_TRANSACTIONS));
 
186
  return (getTable()->getShare()->db_type()->check_flag(HTON_BIT_DOES_TRANSACTIONS));
192
187
}
193
188
 
194
189
void Cursor::ha_statistic_increment(uint64_t system_status_var::*offset) const
195
190
{
196
 
  (table->in_use->status_var.*offset)++;
 
191
  (getTable()->in_use->status_var.*offset)++;
197
192
}
198
193
 
199
194
void **Cursor::ha_data(Session *session) const
200
195
{
201
 
  return session->getEngineData(engine);
 
196
  return session->getEngineData(getEngine());
202
197
}
203
198
 
204
199
bool Cursor::is_fatal_error(int error, uint32_t flags)
214
209
 
215
210
ha_rows Cursor::records() { return stats.records; }
216
211
uint64_t Cursor::tableSize() { return stats.index_file_length + stats.data_file_length; }
217
 
uint64_t Cursor::rowSize() { return table->getRecordLength() + table->sizeFields(); }
 
212
uint64_t Cursor::rowSize() { return getTable()->getRecordLength() + getTable()->sizeFields(); }
218
213
 
219
 
int Cursor::doOpen(const TableIdentifier &identifier, int mode, uint32_t test_if_locked)
 
214
int Cursor::doOpen(const identifier::Table &identifier, int mode, uint32_t test_if_locked)
220
215
{
221
216
  return open(identifier.getPath().c_str(), mode, test_if_locked);
222
217
}
227
222
  Try O_RDONLY if cannot open as O_RDWR
228
223
  Don't wait for locks if not HA_OPEN_WAIT_IF_LOCKED is set
229
224
*/
230
 
int Cursor::ha_open(const TableIdentifier &identifier,
231
 
                    Table *table_arg,
 
225
int Cursor::ha_open(const identifier::Table &identifier,
232
226
                    int mode,
233
227
                    int test_if_locked)
234
228
{
235
229
  int error;
236
230
 
237
 
  table= table_arg;
238
 
  assert(table->getShare() == table_share);
239
 
 
240
231
  if ((error= doOpen(identifier, mode, test_if_locked)))
241
232
  {
242
233
    if ((error == EACCES || error == EROFS) && mode == O_RDWR &&
243
 
        (table->db_stat & HA_TRY_READ_ONLY))
 
234
        (getTable()->db_stat & HA_TRY_READ_ONLY))
244
235
    {
245
 
      table->db_stat|=HA_READ_ONLY;
 
236
      getTable()->db_stat|=HA_READ_ONLY;
246
237
      error= doOpen(identifier, O_RDONLY,test_if_locked);
247
238
    }
248
239
  }
252
243
  }
253
244
  else
254
245
  {
255
 
    if (table->getShare()->db_options_in_use & HA_OPTION_READ_ONLY_DATA)
256
 
      table->db_stat|=HA_READ_ONLY;
 
246
    if (getTable()->getShare()->db_options_in_use & HA_OPTION_READ_ONLY_DATA)
 
247
      getTable()->db_stat|=HA_READ_ONLY;
257
248
    (void) extra(HA_EXTRA_NO_READCHECK);        // Not needed in SQL
258
249
 
259
250
    /* ref is already allocated for us if we're called from Cursor::clone() */
260
 
    if (!ref && !(ref= (unsigned char*) table->alloc_root(ALIGN_SIZE(ref_length)*2)))
 
251
    if (!ref && !(ref= (unsigned char*) getTable()->alloc_root(ALIGN_SIZE(ref_length)*2)))
261
252
    {
262
253
      close();
263
254
      error=HA_ERR_OUT_OF_MEM;
276
267
*/
277
268
int Cursor::read_first_row(unsigned char * buf, uint32_t primary_key)
278
269
{
279
 
  register int error;
 
270
  int error;
280
271
 
281
272
  ha_statistic_increment(&system_status_var::ha_read_first_count);
282
273
 
283
274
  /*
284
275
    If there is very few deleted rows in the table, find the first row by
285
276
    scanning the table.
286
 
    TODO remove the test for HA_READ_ORDER
 
277
    @todo remove the test for HA_READ_ORDER
287
278
  */
288
279
  if (stats.deleted < 10 || primary_key >= MAX_KEY ||
289
 
      !(table->index_flags(primary_key) & HA_READ_ORDER))
 
280
      !(getTable()->index_flags(primary_key) & HA_READ_ORDER))
290
281
  {
291
 
    (void) startTableScan(1);
292
 
    while ((error= rnd_next(buf)) == HA_ERR_RECORD_DELETED) ;
293
 
    (void) endTableScan();
 
282
    error= startTableScan(1);
 
283
    if (error == 0)
 
284
    {
 
285
      while ((error= rnd_next(buf)) == HA_ERR_RECORD_DELETED) ;
 
286
      (void) endTableScan();
 
287
    }
294
288
  }
295
289
  else
296
290
  {
297
291
    /* Find the first row through the primary key */
298
 
    (void) startIndexScan(primary_key, 0);
299
 
    error=index_first(buf);
300
 
    (void) endIndexScan();
 
292
    error= startIndexScan(primary_key, 0);
 
293
    if (error == 0)
 
294
    {
 
295
      error=index_first(buf);
 
296
      (void) endIndexScan();
 
297
    }
301
298
  }
302
299
  return error;
303
300
}
314
311
  @verbatim 1,5,15,25,35,... @endverbatim
315
312
*/
316
313
inline uint64_t
317
 
compute_next_insert_id(uint64_t nr,struct system_variables *variables)
 
314
compute_next_insert_id(uint64_t nr, drizzle_system_variables *variables)
318
315
{
319
316
  if (variables->auto_increment_increment == 1)
320
317
    return (nr+1); // optimization of the formula below
334
331
    Session::next_insert_id to be greater than the explicit value.
335
332
  */
336
333
  if ((next_insert_id > 0) && (nr >= next_insert_id))
337
 
    set_next_insert_id(compute_next_insert_id(nr, &table->in_use->variables));
 
334
    set_next_insert_id(compute_next_insert_id(nr, &getTable()->in_use->variables));
338
335
}
339
336
 
340
337
 
354
351
    The number X if it exists, "nr" otherwise.
355
352
*/
356
353
inline uint64_t
357
 
prev_insert_id(uint64_t nr, struct system_variables *variables)
 
354
prev_insert_id(uint64_t nr, drizzle_system_variables *variables)
358
355
{
359
356
  if (unlikely(nr < variables->auto_increment_offset))
360
357
  {
451
448
{
452
449
  uint64_t nr, nb_reserved_values;
453
450
  bool append= false;
454
 
  Session *session= table->in_use;
455
 
  struct system_variables *variables= &session->variables;
 
451
  Session *session= getTable()->in_use;
 
452
  drizzle_system_variables *variables= &session->variables;
456
453
 
457
454
  /*
458
455
    next_insert_id is a "cursor" into the reserved interval, it may go greater
464
461
     for an auto increment column, not a magic value like NULL is.
465
462
     same as sql_mode=NO_AUTO_VALUE_ON_ZERO */
466
463
 
467
 
  if ((nr= table->next_number_field->val_int()) != 0
468
 
      || table->auto_increment_field_not_null)
 
464
  if ((nr= getTable()->next_number_field->val_int()) != 0
 
465
      || getTable()->auto_increment_field_not_null)
469
466
  {
470
467
    /*
471
468
      Update next_insert_id if we had already generated a value in this
543
540
      nr= compute_next_insert_id(nr-1, variables);
544
541
    }
545
542
 
546
 
    if (table->getShare()->next_number_keypart == 0)
 
543
    if (getTable()->getShare()->next_number_keypart == 0)
547
544
    {
548
545
      /* We must defer the appending until "nr" has been possibly truncated */
549
546
      append= true;
550
547
    }
551
548
  }
552
549
 
553
 
  if (unlikely(table->next_number_field->store((int64_t) nr, true)))
 
550
  if (unlikely(getTable()->next_number_field->store((int64_t) nr, true)))
554
551
  {
555
552
    /*
556
553
      first test if the query was aborted due to strict mode constraints
557
554
    */
558
 
    if (session->killed == Session::KILL_BAD_DATA)
 
555
    if (session->getKilled() == Session::KILL_BAD_DATA)
559
556
      return HA_ERR_AUTOINC_ERANGE;
560
557
 
561
558
    /*
566
563
      bother shifting the right bound (anyway any other value from this
567
564
      interval will cause a duplicate key).
568
565
    */
569
 
    nr= prev_insert_id(table->next_number_field->val_int(), variables);
570
 
    if (unlikely(table->next_number_field->store((int64_t) nr, true)))
571
 
      nr= table->next_number_field->val_int();
 
566
    nr= prev_insert_id(getTable()->next_number_field->val_int(), variables);
 
567
    if (unlikely(getTable()->next_number_field->store((int64_t) nr, true)))
 
568
      nr= getTable()->next_number_field->val_int();
572
569
  }
573
570
  if (append)
574
571
  {
622
619
      this statement used forced auto_increment values if there were some,
623
620
      wipe them away for other statements.
624
621
    */
625
 
    table->in_use->auto_inc_intervals_forced.empty();
 
622
    getTable()->in_use->auto_inc_intervals_forced.empty();
626
623
  }
627
624
}
628
625
 
668
665
   * possible resource to gain (and if there is... then there is a bug such
669
666
   * that in_use should have been set.
670
667
 */
671
 
  if (not table || not table->in_use)
 
668
  if (not getTable()->in_use)
672
669
    return;
673
670
 
674
 
  resource_context= table->in_use->getResourceContext(engine);
 
671
  resource_context= getTable()->in_use->getResourceContext(getEngine());
675
672
  /*
676
673
    When a storage engine method is called, the transaction must
677
674
    have been started, unless it's a DDL call, for which the
712
709
     * @todo Make TransactionServices generic to AfterTriggerServices
713
710
     * or similar...
714
711
     */
715
 
    Session *const session= table->in_use;
 
712
    Session *const session= getTable()->in_use;
716
713
    TransactionServices &transaction_services= TransactionServices::singleton();
717
 
    transaction_services.truncateTable(session, table);
 
714
    transaction_services.truncateTable(*session, *getTable());
718
715
  }
719
716
 
720
717
  return result;
813
810
  int error;
814
811
  if (!(error=index_next(buf)))
815
812
  {
816
 
    ptrdiff_t ptrdiff= buf - table->getInsertRecord();
 
813
    ptrdiff_t ptrdiff= buf - getTable()->getInsertRecord();
817
814
    unsigned char *save_record_0= NULL;
818
815
    KeyInfo *key_info= NULL;
819
816
    KeyPartInfo *key_part;
829
826
    */
830
827
    if (ptrdiff)
831
828
    {
832
 
      save_record_0= table->getInsertRecord();
833
 
      table->record[0]= buf;
834
 
      key_info= table->key_info + active_index;
 
829
      save_record_0= getTable()->getInsertRecord();
 
830
      getTable()->record[0]= buf;
 
831
      key_info= getTable()->key_info + active_index;
835
832
      key_part= key_info->key_part;
836
833
      key_part_end= key_part + key_info->key_parts;
837
834
      for (; key_part < key_part_end; key_part++)
841
838
      }
842
839
    }
843
840
 
844
 
    if (key_cmp_if_same(table, key, active_index, keylen))
 
841
    if (key_cmp_if_same(getTable(), key, active_index, keylen))
845
842
    {
846
 
      table->status=STATUS_NOT_FOUND;
 
843
      getTable()->status=STATUS_NOT_FOUND;
847
844
      error=HA_ERR_END_OF_FILE;
848
845
    }
849
846
 
850
847
    /* Move back if necessary. */
851
848
    if (ptrdiff)
852
849
    {
853
 
      table->record[0]= save_record_0;
 
850
      getTable()->record[0]= save_record_0;
854
851
      for (key_part= key_info->key_part; key_part < key_part_end; key_part++)
855
852
        key_part->field->move_field_offset(-ptrdiff);
856
853
    }
887
884
double Cursor::index_only_read_time(uint32_t keynr, double key_records)
888
885
{
889
886
  uint32_t keys_per_block= (stats.block_size/2/
890
 
                        (table->key_info[keynr].key_length + ref_length) + 1);
 
887
                        (getTable()->key_info[keynr].key_length + ref_length) + 1);
891
888
  return ((double) (key_records + keys_per_block-1) /
892
889
          (double) keys_per_block);
893
890
}
916
913
 
917
914
  @note
918
915
    This method (or an overriding one in a derived class) must check for
919
 
    session->killed and return HA_POS_ERROR if it is not zero. This is required
 
916
    session->getKilled() and return HA_POS_ERROR if it is not zero. This is required
920
917
    for a user to be able to interrupt the calculation by killing the
921
918
    connection/query.
922
919
 
1194
1191
    key_compare_result_on_equal= ((end_key->flag == HA_READ_BEFORE_KEY) ? 1 :
1195
1192
                                  (end_key->flag == HA_READ_AFTER_KEY) ? -1 : 0);
1196
1193
  }
1197
 
  range_key_part= table->key_info[active_index].key_part;
 
1194
  range_key_part= getTable()->key_info[active_index].key_part;
1198
1195
 
1199
1196
  if (!start_key)                       // Read first record
1200
 
    result= index_first(table->getInsertRecord());
 
1197
    result= index_first(getTable()->getInsertRecord());
1201
1198
  else
1202
 
    result= index_read_map(table->getInsertRecord(),
 
1199
    result= index_read_map(getTable()->getInsertRecord(),
1203
1200
                           start_key->key,
1204
1201
                           start_key->keypart_map,
1205
1202
                           start_key->flag);
1232
1229
  if (eq_range)
1233
1230
  {
1234
1231
    /* We trust that index_next_same always gives a row in range */
1235
 
    return(index_next_same(table->getInsertRecord(),
 
1232
    return(index_next_same(getTable()->getInsertRecord(),
1236
1233
                                end_range->key,
1237
1234
                                end_range->length));
1238
1235
  }
1239
 
  result= index_next(table->getInsertRecord());
 
1236
  result= index_next(getTable()->getInsertRecord());
1240
1237
  if (result)
1241
1238
    return result;
1242
1239
  return(compare_key(end_range) <= 0 ? 0 : HA_ERR_END_OF_FILE);
1303
1300
 
1304
1301
  bool result= false;
1305
1302
 
1306
 
  switch (session->lex->sql_command)
 
1303
  switch (session->getLex()->sql_command)
1307
1304
  {
1308
1305
  case SQLCOM_CREATE_TABLE:
1309
1306
    /*
1315
1312
     * CREATE TABLE will commit the transaction containing
1316
1313
     * it).
1317
1314
     */
1318
 
    result= transaction_services.insertRecord(session, table);
 
1315
    result= transaction_services.insertRecord(*session, *table);
1319
1316
    break;
1320
1317
  case SQLCOM_REPLACE:
1321
1318
  case SQLCOM_REPLACE_SELECT:
1344
1341
       * as the row to delete (this is the conflicting row), so
1345
1342
       * we need to notify TransactionService to use that row.
1346
1343
       */
1347
 
      transaction_services.deleteRecord(session, table, true);
 
1344
      transaction_services.deleteRecord(*session, *table, true);
1348
1345
      /* 
1349
1346
       * We set the "current" statement message to NULL.  This triggers
1350
1347
       * the replication services component to generate a new statement
1351
1348
       * message for the inserted record which will come next.
1352
1349
       */
1353
 
      transaction_services.finalizeStatementMessage(*session->getStatementMessage(), session);
 
1350
      transaction_services.finalizeStatementMessage(*session->getStatementMessage(), *session);
1354
1351
    }
1355
1352
    else
1356
1353
    {
1357
1354
      if (before_record == NULL)
1358
 
        result= transaction_services.insertRecord(session, table);
 
1355
        result= transaction_services.insertRecord(*session, *table);
1359
1356
      else
1360
 
        transaction_services.updateRecord(session, table, before_record, after_record);
 
1357
        transaction_services.updateRecord(*session, *table, before_record, after_record);
1361
1358
    }
1362
1359
    break;
1363
1360
  case SQLCOM_INSERT:
1370
1367
     * an update.
1371
1368
     */
1372
1369
    if (before_record == NULL)
1373
 
      result= transaction_services.insertRecord(session, table);
 
1370
      result= transaction_services.insertRecord(*session, *table);
1374
1371
    else
1375
 
      transaction_services.updateRecord(session, table, before_record, after_record);
 
1372
      transaction_services.updateRecord(*session, *table, before_record, after_record);
1376
1373
    break;
1377
1374
 
1378
1375
  case SQLCOM_UPDATE:
1379
 
    transaction_services.updateRecord(session, table, before_record, after_record);
 
1376
    transaction_services.updateRecord(*session, *table, before_record, after_record);
1380
1377
    break;
1381
1378
 
1382
1379
  case SQLCOM_DELETE:
1383
 
    transaction_services.deleteRecord(session, table);
 
1380
    transaction_services.deleteRecord(*session, *table);
1384
1381
    break;
1385
1382
  default:
1386
1383
    break;
1404
1401
  {
1405
1402
    if (lock_type == F_RDLCK)
1406
1403
    {
1407
 
      DRIZZLE_CURSOR_RDLOCK_START(table_share->getSchemaName(),
1408
 
                                  table_share->getTableName());
 
1404
      DRIZZLE_CURSOR_RDLOCK_START(getTable()->getShare()->getSchemaName(),
 
1405
                                  getTable()->getShare()->getTableName());
1409
1406
    }
1410
1407
    else if (lock_type == F_WRLCK)
1411
1408
    {
1412
 
      DRIZZLE_CURSOR_WRLOCK_START(table_share->getSchemaName(),
1413
 
                                  table_share->getTableName());
 
1409
      DRIZZLE_CURSOR_WRLOCK_START(getTable()->getShare()->getSchemaName(),
 
1410
                                  getTable()->getShare()->getTableName());
1414
1411
    }
1415
1412
    else if (lock_type == F_UNLCK)
1416
1413
    {
1417
 
      DRIZZLE_CURSOR_UNLOCK_START(table_share->getSchemaName(),
1418
 
                                  table_share->getTableName());
 
1414
      DRIZZLE_CURSOR_UNLOCK_START(getTable()->getShare()->getSchemaName(),
 
1415
                                  getTable()->getShare()->getTableName());
1419
1416
    }
1420
1417
  }
1421
1418
 
1454
1451
int Cursor::ha_reset()
1455
1452
{
1456
1453
  /* Check that we have called all proper deallocation functions */
1457
 
  assert(! table->getShare()->all_set.none());
1458
 
  assert(table->key_read == 0);
 
1454
  assert(! getTable()->getShare()->all_set.none());
 
1455
  assert(getTable()->key_read == 0);
1459
1456
  /* ensure that ha_index_end / endTableScan has been called */
1460
1457
  assert(inited == NONE);
1461
1458
  /* Free cache used by filesort */
1462
 
  table->free_io_cache();
 
1459
  getTable()->free_io_cache();
1463
1460
  /* reset the bitmaps to point to defaults */
1464
 
  table->default_column_bitmaps();
 
1461
  getTable()->default_column_bitmaps();
1465
1462
  return(reset());
1466
1463
}
1467
1464
 
1476
1473
   * @TODO Technically, the below two lines can be take even further out of the
1477
1474
   * Cursor interface and into the fill_record() method.
1478
1475
   */
1479
 
  if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT)
 
1476
  if (getTable()->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT)
1480
1477
  {
1481
 
    table->timestamp_field->set_time();
 
1478
    getTable()->timestamp_field->set_time();
1482
1479
  }
1483
1480
 
1484
 
  DRIZZLE_INSERT_ROW_START(table_share->getSchemaName(), table_share->getTableName());
 
1481
  DRIZZLE_INSERT_ROW_START(getTable()->getShare()->getSchemaName(), getTable()->getShare()->getTableName());
1485
1482
  setTransactionReadWrite();
1486
1483
  
1487
 
  if (unlikely(plugin::EventObserver::beforeInsertRecord(*table, buf)))
 
1484
  if (unlikely(plugin::EventObserver::beforeInsertRecord(*getTable(), buf)))
1488
1485
  {
1489
1486
    error= ER_EVENT_OBSERVER_PLUGIN;
1490
1487
  }
1491
1488
  else
1492
1489
  {
1493
1490
    error= doInsertRecord(buf);
1494
 
    if (unlikely(plugin::EventObserver::afterInsertRecord(*table, buf, error))) 
 
1491
    if (unlikely(plugin::EventObserver::afterInsertRecord(*getTable(), buf, error))) 
1495
1492
    {
1496
1493
      error= ER_EVENT_OBSERVER_PLUGIN;
1497
1494
    }
1506
1503
    return error;
1507
1504
  }
1508
1505
 
1509
 
  if (unlikely(log_row_for_replication(table, NULL, buf)))
 
1506
  if (unlikely(log_row_for_replication(getTable(), NULL, buf)))
1510
1507
    return HA_ERR_RBR_LOGGING_FAILED;
1511
1508
 
1512
1509
  return 0;
1521
1518
    Some storage engines require that the new record is in getInsertRecord()
1522
1519
    (and the old record is in getUpdateRecord()).
1523
1520
   */
1524
 
  assert(new_data == table->getInsertRecord());
 
1521
  assert(new_data == getTable()->getInsertRecord());
1525
1522
 
1526
 
  DRIZZLE_UPDATE_ROW_START(table_share->getSchemaName(), table_share->getTableName());
 
1523
  DRIZZLE_UPDATE_ROW_START(getTable()->getShare()->getSchemaName(), getTable()->getShare()->getTableName());
1527
1524
  setTransactionReadWrite();
1528
 
  if (unlikely(plugin::EventObserver::beforeUpdateRecord(*table, old_data, new_data)))
 
1525
  if (unlikely(plugin::EventObserver::beforeUpdateRecord(*getTable(), old_data, new_data)))
1529
1526
  {
1530
1527
    error= ER_EVENT_OBSERVER_PLUGIN;
1531
1528
  }
1532
1529
  else
1533
1530
  {
1534
 
    if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE)
 
1531
    if (getTable()->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE)
1535
1532
    {
1536
 
      table->timestamp_field->set_time();
 
1533
      getTable()->timestamp_field->set_time();
1537
1534
    }
1538
1535
 
1539
1536
    error= doUpdateRecord(old_data, new_data);
1540
 
    if (unlikely(plugin::EventObserver::afterUpdateRecord(*table, old_data, new_data, error)))
 
1537
    if (unlikely(plugin::EventObserver::afterUpdateRecord(*getTable(), old_data, new_data, error)))
1541
1538
    {
1542
1539
      error= ER_EVENT_OBSERVER_PLUGIN;
1543
1540
    }
1552
1549
    return error;
1553
1550
  }
1554
1551
 
1555
 
  if (unlikely(log_row_for_replication(table, old_data, new_data)))
 
1552
  if (unlikely(log_row_for_replication(getTable(), old_data, new_data)))
1556
1553
    return HA_ERR_RBR_LOGGING_FAILED;
1557
1554
 
1558
1555
  return 0;
1559
1556
}
 
1557
TableShare *Cursor::getShare()
 
1558
{
 
1559
  return getTable()->getMutableShare();
 
1560
}
1560
1561
 
1561
1562
int Cursor::deleteRecord(const unsigned char *buf)
1562
1563
{
1563
1564
  int error;
1564
1565
 
1565
 
  DRIZZLE_DELETE_ROW_START(table_share->getSchemaName(), table_share->getTableName());
 
1566
  DRIZZLE_DELETE_ROW_START(getTable()->getShare()->getSchemaName(), getTable()->getShare()->getTableName());
1566
1567
  setTransactionReadWrite();
1567
 
  if (unlikely(plugin::EventObserver::beforeDeleteRecord(*table, buf)))
 
1568
  if (unlikely(plugin::EventObserver::beforeDeleteRecord(*getTable(), buf)))
1568
1569
  {
1569
1570
    error= ER_EVENT_OBSERVER_PLUGIN;
1570
1571
  }
1571
1572
  else
1572
1573
  {
1573
1574
    error= doDeleteRecord(buf);
1574
 
    if (unlikely(plugin::EventObserver::afterDeleteRecord(*table, buf, error)))
 
1575
    if (unlikely(plugin::EventObserver::afterDeleteRecord(*getTable(), buf, error)))
1575
1576
    {
1576
1577
      error= ER_EVENT_OBSERVER_PLUGIN;
1577
1578
    }
1584
1585
  if (unlikely(error))
1585
1586
    return error;
1586
1587
 
1587
 
  if (unlikely(log_row_for_replication(table, buf, NULL)))
 
1588
  if (unlikely(log_row_for_replication(getTable(), buf, NULL)))
1588
1589
    return HA_ERR_RBR_LOGGING_FAILED;
1589
1590
 
1590
1591
  return 0;