~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/cursor.cc

fix pthread atomics. operator precedence is important. The unit test now passes.

Show diffs side-by-side

added added

removed removed

Lines of Context:
54
54
** General Cursor functions
55
55
****************************************************************************/
56
56
Cursor::Cursor(plugin::StorageEngine &engine_arg,
57
 
               Table &arg)
58
 
  : table(arg),
59
 
    engine(engine_arg),
60
 
    estimation_rows_to_insert(0),
 
57
               TableShare &share_arg)
 
58
  : table_share(&share_arg), table(0),
 
59
    estimation_rows_to_insert(0), engine(&engine_arg),
61
60
    ref(0),
62
61
    key_used_on_scan(MAX_KEY), active_index(MAX_KEY),
63
62
    ref_length(sizeof(internal::my_off_t)),
73
72
}
74
73
 
75
74
 
76
 
/*
77
 
 * @note this only used in
78
 
 * optimizer::QuickRangeSelect::init_ror_merged_scan(bool reuse_handler) as
79
 
 * of the writing of this comment. -Brian
80
 
 */
81
75
Cursor *Cursor::clone(memory::Root *mem_root)
82
76
{
83
 
  Cursor *new_handler= getTable()->getMutableShare()->db_type()->getCursor(*getTable());
 
77
  Cursor *new_handler= table->getMutableShare()->db_type()->getCursor(*table->getMutableShare(), mem_root);
84
78
 
85
79
  /*
86
80
    Allocate Cursor->ref here because otherwise ha_open will allocate it
89
83
  */
90
84
  if (!(new_handler->ref= (unsigned char*) mem_root->alloc_root(ALIGN_SIZE(ref_length)*2)))
91
85
    return NULL;
92
 
 
93
 
  TableIdentifier identifier(getTable()->getShare()->getSchemaName(),
94
 
                             getTable()->getShare()->getTableName(),
95
 
                             getTable()->getShare()->getType());
96
 
 
97
 
  if (new_handler && !new_handler->ha_open(identifier,
98
 
                                           getTable()->getDBStat(),
 
86
  if (new_handler && !new_handler->ha_open(table,
 
87
                                           table->getMutableShare()->getNormalizedPath(),
 
88
                                           table->getDBStat(),
99
89
                                           HA_OPEN_IGNORE_IF_LOCKED))
100
90
    return new_handler;
101
91
  return NULL;
111
101
  /* works only with key prefixes */
112
102
  assert(((keypart_map_arg + 1) & keypart_map_arg) == 0);
113
103
 
114
 
  const KeyPartInfo *key_part_found= getTable()->getShare()->getKeyInfo(key_position).key_part;
115
 
  const KeyPartInfo *end_key_part_found= key_part_found + getTable()->getShare()->getKeyInfo(key_position).key_parts;
 
104
  KeyInfo *key_info_found= table->getShare()->key_info + key_position;
 
105
  KeyPartInfo *key_part_found= key_info_found->key_part;
 
106
  KeyPartInfo *end_key_part_found= key_part_found + key_info_found->key_parts;
116
107
  uint32_t length= 0;
117
108
 
118
109
  while (key_part_found < end_key_part_found && keypart_map_arg)
175
166
  return end_bulk_insert();
176
167
}
177
168
 
 
169
void Cursor::change_table_ptr(Table *table_arg, TableShare *share)
 
170
{
 
171
  table= table_arg;
 
172
  table_share= share;
 
173
}
 
174
 
178
175
const key_map *Cursor::keys_to_use_for_scanning()
179
176
{
180
177
  return &key_map_empty;
182
179
 
183
180
bool Cursor::has_transactions()
184
181
{
185
 
  return (getTable()->getShare()->db_type()->check_flag(HTON_BIT_DOES_TRANSACTIONS));
 
182
  return (table->getShare()->db_type()->check_flag(HTON_BIT_DOES_TRANSACTIONS));
186
183
}
187
184
 
188
 
void Cursor::ha_statistic_increment(uint64_t system_status_var::*offset) const
 
185
void Cursor::ha_statistic_increment(ulong system_status_var::*offset) const
189
186
{
190
 
  (getTable()->in_use->status_var.*offset)++;
 
187
  status_var_increment(table->in_use->status_var.*offset);
191
188
}
192
189
 
193
190
void **Cursor::ha_data(Session *session) const
194
191
{
195
 
  return session->getEngineData(getEngine());
196
 
}
 
192
  return session->getEngineData(engine);
 
193
}
 
194
 
 
195
Session *Cursor::ha_session(void) const
 
196
{
 
197
  assert(!table || !table->in_use || table->in_use == current_session);
 
198
  return (table && table->in_use) ? table->in_use : current_session;
 
199
}
 
200
 
197
201
 
198
202
bool Cursor::is_fatal_error(int error, uint32_t flags)
199
203
{
208
212
 
209
213
ha_rows Cursor::records() { return stats.records; }
210
214
uint64_t Cursor::tableSize() { return stats.index_file_length + stats.data_file_length; }
211
 
uint64_t Cursor::rowSize() { return getTable()->getRecordLength() + getTable()->sizeFields(); }
212
 
 
213
 
int Cursor::doOpen(const TableIdentifier &identifier, int mode, uint32_t test_if_locked)
214
 
{
215
 
  return open(identifier.getPath().c_str(), mode, test_if_locked);
216
 
}
 
215
uint64_t Cursor::rowSize() { return table->getRecordLength() + table->sizeFields(); }
217
216
 
218
217
/**
219
218
  Open database-Cursor.
221
220
  Try O_RDONLY if cannot open as O_RDWR
222
221
  Don't wait for locks if not HA_OPEN_WAIT_IF_LOCKED is set
223
222
*/
224
 
int Cursor::ha_open(const TableIdentifier &identifier,
225
 
                    int mode,
226
 
                    int test_if_locked)
 
223
int Cursor::ha_open(Table *table_arg, const char *name, int mode,
 
224
                     int test_if_locked)
227
225
{
228
226
  int error;
229
227
 
230
 
  if ((error= doOpen(identifier, mode, test_if_locked)))
 
228
  table= table_arg;
 
229
  assert(table->getShare() == table_share);
 
230
 
 
231
  if ((error=open(name, mode, test_if_locked)))
231
232
  {
232
233
    if ((error == EACCES || error == EROFS) && mode == O_RDWR &&
233
 
        (getTable()->db_stat & HA_TRY_READ_ONLY))
 
234
        (table->db_stat & HA_TRY_READ_ONLY))
234
235
    {
235
 
      getTable()->db_stat|=HA_READ_ONLY;
236
 
      error= doOpen(identifier, O_RDONLY,test_if_locked);
 
236
      table->db_stat|=HA_READ_ONLY;
 
237
      error=open(name,O_RDONLY,test_if_locked);
237
238
    }
238
239
  }
239
240
  if (error)
242
243
  }
243
244
  else
244
245
  {
245
 
    if (getTable()->getShare()->db_options_in_use & HA_OPTION_READ_ONLY_DATA)
246
 
      getTable()->db_stat|=HA_READ_ONLY;
 
246
    if (table->getShare()->db_options_in_use & HA_OPTION_READ_ONLY_DATA)
 
247
      table->db_stat|=HA_READ_ONLY;
247
248
    (void) extra(HA_EXTRA_NO_READCHECK);        // Not needed in SQL
248
249
 
249
250
    /* ref is already allocated for us if we're called from Cursor::clone() */
250
 
    if (!ref && !(ref= (unsigned char*) getTable()->alloc_root(ALIGN_SIZE(ref_length)*2)))
 
251
    if (!ref && !(ref= (unsigned char*) table->alloc_root(ALIGN_SIZE(ref_length)*2)))
251
252
    {
252
253
      close();
253
254
      error=HA_ERR_OUT_OF_MEM;
276
277
    TODO remove the test for HA_READ_ORDER
277
278
  */
278
279
  if (stats.deleted < 10 || primary_key >= MAX_KEY ||
279
 
      !(getTable()->index_flags(primary_key) & HA_READ_ORDER))
 
280
      !(table->index_flags(primary_key) & HA_READ_ORDER))
280
281
  {
281
282
    (void) startTableScan(1);
282
283
    while ((error= rnd_next(buf)) == HA_ERR_RECORD_DELETED) ;
304
305
  @verbatim 1,5,15,25,35,... @endverbatim
305
306
*/
306
307
inline uint64_t
307
 
compute_next_insert_id(uint64_t nr, drizzle_system_variables *variables)
 
308
compute_next_insert_id(uint64_t nr,struct system_variables *variables)
308
309
{
309
310
  if (variables->auto_increment_increment == 1)
310
311
    return (nr+1); // optimization of the formula below
324
325
    Session::next_insert_id to be greater than the explicit value.
325
326
  */
326
327
  if ((next_insert_id > 0) && (nr >= next_insert_id))
327
 
    set_next_insert_id(compute_next_insert_id(nr, &getTable()->in_use->variables));
 
328
    set_next_insert_id(compute_next_insert_id(nr, &table->in_use->variables));
328
329
}
329
330
 
330
331
 
344
345
    The number X if it exists, "nr" otherwise.
345
346
*/
346
347
inline uint64_t
347
 
prev_insert_id(uint64_t nr, drizzle_system_variables *variables)
 
348
prev_insert_id(uint64_t nr, struct system_variables *variables)
348
349
{
349
350
  if (unlikely(nr < variables->auto_increment_offset))
350
351
  {
441
442
{
442
443
  uint64_t nr, nb_reserved_values;
443
444
  bool append= false;
444
 
  Session *session= getTable()->in_use;
445
 
  drizzle_system_variables *variables= &session->variables;
 
445
  Session *session= table->in_use;
 
446
  struct system_variables *variables= &session->variables;
446
447
 
447
448
  /*
448
449
    next_insert_id is a "cursor" into the reserved interval, it may go greater
454
455
     for an auto increment column, not a magic value like NULL is.
455
456
     same as sql_mode=NO_AUTO_VALUE_ON_ZERO */
456
457
 
457
 
  if ((nr= getTable()->next_number_field->val_int()) != 0
458
 
      || getTable()->auto_increment_field_not_null)
 
458
  if ((nr= table->next_number_field->val_int()) != 0
 
459
      || table->auto_increment_field_not_null)
459
460
  {
460
461
    /*
461
462
      Update next_insert_id if we had already generated a value in this
533
534
      nr= compute_next_insert_id(nr-1, variables);
534
535
    }
535
536
 
536
 
    if (getTable()->getShare()->next_number_keypart == 0)
 
537
    if (table->getShare()->next_number_keypart == 0)
537
538
    {
538
539
      /* We must defer the appending until "nr" has been possibly truncated */
539
540
      append= true;
540
541
    }
541
542
  }
542
543
 
543
 
  if (unlikely(getTable()->next_number_field->store((int64_t) nr, true)))
 
544
  if (unlikely(table->next_number_field->store((int64_t) nr, true)))
544
545
  {
545
546
    /*
546
547
      first test if the query was aborted due to strict mode constraints
547
548
    */
548
 
    if (session->getKilled() == Session::KILL_BAD_DATA)
 
549
    if (session->killed == Session::KILL_BAD_DATA)
549
550
      return HA_ERR_AUTOINC_ERANGE;
550
551
 
551
552
    /*
556
557
      bother shifting the right bound (anyway any other value from this
557
558
      interval will cause a duplicate key).
558
559
    */
559
 
    nr= prev_insert_id(getTable()->next_number_field->val_int(), variables);
560
 
    if (unlikely(getTable()->next_number_field->store((int64_t) nr, true)))
561
 
      nr= getTable()->next_number_field->val_int();
 
560
    nr= prev_insert_id(table->next_number_field->val_int(), variables);
 
561
    if (unlikely(table->next_number_field->store((int64_t) nr, true)))
 
562
      nr= table->next_number_field->val_int();
562
563
  }
563
564
  if (append)
564
565
  {
612
613
      this statement used forced auto_increment values if there were some,
613
614
      wipe them away for other statements.
614
615
    */
615
 
    getTable()->in_use->auto_inc_intervals_forced.empty();
 
616
    table->in_use->auto_inc_intervals_forced.empty();
616
617
  }
617
618
}
618
619
 
651
652
void
652
653
Cursor::setTransactionReadWrite()
653
654
{
654
 
  ResourceContext *resource_context;
655
 
 
656
 
  /*
657
 
   * If the cursor has not context for execution then there should be no
658
 
   * possible resource to gain (and if there is... then there is a bug such
659
 
   * that in_use should have been set.
660
 
 */
661
 
  if (not getTable()->in_use)
662
 
    return;
663
 
 
664
 
  resource_context= getTable()->in_use->getResourceContext(getEngine());
 
655
  ResourceContext *resource_context= ha_session()->getResourceContext(engine);
665
656
  /*
666
657
    When a storage engine method is called, the transaction must
667
658
    have been started, unless it's a DDL call, for which the
702
693
     * @todo Make TransactionServices generic to AfterTriggerServices
703
694
     * or similar...
704
695
     */
705
 
    Session *const session= getTable()->in_use;
 
696
    Session *const session= table->in_use;
706
697
    TransactionServices &transaction_services= TransactionServices::singleton();
707
 
    transaction_services.truncateTable(session, getTable());
 
698
    transaction_services.truncateTable(session, table);
708
699
  }
709
700
 
710
701
  return result;
803
794
  int error;
804
795
  if (!(error=index_next(buf)))
805
796
  {
806
 
    ptrdiff_t ptrdiff= buf - getTable()->getInsertRecord();
 
797
    ptrdiff_t ptrdiff= buf - table->record[0];
807
798
    unsigned char *save_record_0= NULL;
808
799
    KeyInfo *key_info= NULL;
809
800
    KeyPartInfo *key_part;
810
801
    KeyPartInfo *key_part_end= NULL;
811
802
 
812
803
    /*
813
 
      key_cmp_if_same() compares table->getInsertRecord() against 'key'.
814
 
      In parts it uses table->getInsertRecord() directly, in parts it uses
815
 
      field objects with their local pointers into table->getInsertRecord().
816
 
      If 'buf' is distinct from table->getInsertRecord(), we need to move
817
 
      all record references. This is table->getInsertRecord() itself and
 
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
818
809
      the field pointers of the fields used in this key.
819
810
    */
820
811
    if (ptrdiff)
821
812
    {
822
 
      save_record_0= getTable()->getInsertRecord();
823
 
      getTable()->record[0]= buf;
824
 
      key_info= getTable()->key_info + active_index;
 
813
      save_record_0= table->record[0];
 
814
      table->record[0]= buf;
 
815
      key_info= table->key_info + active_index;
825
816
      key_part= key_info->key_part;
826
817
      key_part_end= key_part + key_info->key_parts;
827
818
      for (; key_part < key_part_end; key_part++)
831
822
      }
832
823
    }
833
824
 
834
 
    if (key_cmp_if_same(getTable(), key, active_index, keylen))
 
825
    if (key_cmp_if_same(table, key, active_index, keylen))
835
826
    {
836
 
      getTable()->status=STATUS_NOT_FOUND;
 
827
      table->status=STATUS_NOT_FOUND;
837
828
      error=HA_ERR_END_OF_FILE;
838
829
    }
839
830
 
840
831
    /* Move back if necessary. */
841
832
    if (ptrdiff)
842
833
    {
843
 
      getTable()->record[0]= save_record_0;
 
834
      table->record[0]= save_record_0;
844
835
      for (key_part= key_info->key_part; key_part < key_part_end; key_part++)
845
836
        key_part->field->move_field_offset(-ptrdiff);
846
837
    }
877
868
double Cursor::index_only_read_time(uint32_t keynr, double key_records)
878
869
{
879
870
  uint32_t keys_per_block= (stats.block_size/2/
880
 
                        (getTable()->key_info[keynr].key_length + ref_length) + 1);
 
871
                        (table->key_info[keynr].key_length + ref_length) + 1);
881
872
  return ((double) (key_records + keys_per_block-1) /
882
873
          (double) keys_per_block);
883
874
}
906
897
 
907
898
  @note
908
899
    This method (or an overriding one in a derived class) must check for
909
 
    session->getKilled() and return HA_POS_ERROR if it is not zero. This is required
 
900
    session->killed and return HA_POS_ERROR if it is not zero. This is required
910
901
    for a user to be able to interrupt the calculation by killing the
911
902
    connection/query.
912
903
 
928
919
  range_seq_t seq_it;
929
920
  ha_rows rows, total_rows= 0;
930
921
  uint32_t n_ranges=0;
 
922
  Session *session= current_session;
931
923
 
932
924
  /* Default MRR implementation doesn't need buffer */
933
925
  *bufsz= 0;
935
927
  seq_it= seq->init(seq_init_param, n_ranges, *flags);
936
928
  while (!seq->next(seq_it, &range))
937
929
  {
 
930
    if (unlikely(session->killed != 0))
 
931
      return HA_POS_ERROR;
 
932
 
938
933
    n_ranges++;
939
934
    key_range *min_endp, *max_endp;
940
935
    {
1159
1154
  @param sorted         Set to 1 if result should be sorted per key
1160
1155
 
1161
1156
  @note
1162
 
    Record is read into table->getInsertRecord()
 
1157
    Record is read into table->record[0]
1163
1158
 
1164
1159
  @retval
1165
1160
    0                   Found row
1184
1179
    key_compare_result_on_equal= ((end_key->flag == HA_READ_BEFORE_KEY) ? 1 :
1185
1180
                                  (end_key->flag == HA_READ_AFTER_KEY) ? -1 : 0);
1186
1181
  }
1187
 
  range_key_part= getTable()->key_info[active_index].key_part;
 
1182
  range_key_part= table->key_info[active_index].key_part;
1188
1183
 
1189
1184
  if (!start_key)                       // Read first record
1190
 
    result= index_first(getTable()->getInsertRecord());
 
1185
    result= index_first(table->record[0]);
1191
1186
  else
1192
 
    result= index_read_map(getTable()->getInsertRecord(),
 
1187
    result= index_read_map(table->record[0],
1193
1188
                           start_key->key,
1194
1189
                           start_key->keypart_map,
1195
1190
                           start_key->flag);
1206
1201
  Read next row between two endpoints.
1207
1202
 
1208
1203
  @note
1209
 
    Record is read into table->getInsertRecord()
 
1204
    Record is read into table->record[0]
1210
1205
 
1211
1206
  @retval
1212
1207
    0                   Found row
1222
1217
  if (eq_range)
1223
1218
  {
1224
1219
    /* We trust that index_next_same always gives a row in range */
1225
 
    return(index_next_same(getTable()->getInsertRecord(),
 
1220
    return(index_next_same(table->record[0],
1226
1221
                                end_range->key,
1227
1222
                                end_range->length));
1228
1223
  }
1229
 
  result= index_next(getTable()->getInsertRecord());
 
1224
  result= index_next(table->record[0]);
1230
1225
  if (result)
1231
1226
    return result;
1232
1227
  return(compare_key(end_range) <= 0 ? 0 : HA_ERR_END_OF_FILE);
1288
1283
  TransactionServices &transaction_services= TransactionServices::singleton();
1289
1284
  Session *const session= table->in_use;
1290
1285
 
1291
 
  if (table->getShare()->getType() || not transaction_services.shouldConstructMessages())
 
1286
  if (table->getShare()->tmp_table || not transaction_services.shouldConstructMessages())
1292
1287
    return false;
1293
1288
 
1294
1289
  bool result= false;
1316
1311
     * called.  If it fails, then a call to deleteRecord()
1317
1312
     * is called, followed by a repeat of the original
1318
1313
     * call to insertRecord().  So, log_row_for_replication
1319
 
     * could be called multiple times for a REPLACE
 
1314
     * could be called either once or twice for a REPLACE
1320
1315
     * statement.  The below looks at the values of before_record
1321
1316
     * and after_record to determine which call to this
1322
1317
     * function is for the delete or the insert, since NULL
1329
1324
     */
1330
1325
    if (after_record == NULL)
1331
1326
    {
1332
 
      /*
1333
 
       * The storage engine is passed the record in table->record[1]
1334
 
       * as the row to delete (this is the conflicting row), so
1335
 
       * we need to notify TransactionService to use that row.
1336
 
       */
1337
 
      transaction_services.deleteRecord(session, table, true);
 
1327
      transaction_services.deleteRecord(session, table);
1338
1328
      /* 
1339
1329
       * We set the "current" statement message to NULL.  This triggers
1340
1330
       * the replication services component to generate a new statement
1352
1342
    break;
1353
1343
  case SQLCOM_INSERT:
1354
1344
  case SQLCOM_INSERT_SELECT:
1355
 
  case SQLCOM_LOAD:
1356
1345
    /*
1357
1346
     * The else block below represents an 
1358
1347
     * INSERT ... ON DUPLICATE KEY UPDATE that
1394
1383
  {
1395
1384
    if (lock_type == F_RDLCK)
1396
1385
    {
1397
 
      DRIZZLE_CURSOR_RDLOCK_START(getTable()->getShare()->getSchemaName(),
1398
 
                                  getTable()->getShare()->getTableName());
 
1386
      DRIZZLE_CURSOR_RDLOCK_START(table_share->getSchemaName(),
 
1387
                                  table_share->getTableName());
1399
1388
    }
1400
1389
    else if (lock_type == F_WRLCK)
1401
1390
    {
1402
 
      DRIZZLE_CURSOR_WRLOCK_START(getTable()->getShare()->getSchemaName(),
1403
 
                                  getTable()->getShare()->getTableName());
 
1391
      DRIZZLE_CURSOR_WRLOCK_START(table_share->getSchemaName(),
 
1392
                                  table_share->getTableName());
1404
1393
    }
1405
1394
    else if (lock_type == F_UNLCK)
1406
1395
    {
1407
 
      DRIZZLE_CURSOR_UNLOCK_START(getTable()->getShare()->getSchemaName(),
1408
 
                                  getTable()->getShare()->getTableName());
 
1396
      DRIZZLE_CURSOR_UNLOCK_START(table_share->getSchemaName(),
 
1397
                                  table_share->getTableName());
1409
1398
    }
1410
1399
  }
1411
1400
 
1444
1433
int Cursor::ha_reset()
1445
1434
{
1446
1435
  /* Check that we have called all proper deallocation functions */
1447
 
  assert(! getTable()->getShare()->all_set.none());
1448
 
  assert(getTable()->key_read == 0);
 
1436
  assert((unsigned char*) table->def_read_set.getBitmap() +
 
1437
              table->getShare()->column_bitmap_size ==
 
1438
              (unsigned char*) table->def_write_set.getBitmap());
 
1439
  assert(table->getShare()->all_set.isSetAll());
 
1440
  assert(table->key_read == 0);
1449
1441
  /* ensure that ha_index_end / endTableScan has been called */
1450
1442
  assert(inited == NONE);
1451
1443
  /* Free cache used by filesort */
1452
 
  getTable()->free_io_cache();
 
1444
  table->free_io_cache();
1453
1445
  /* reset the bitmaps to point to defaults */
1454
 
  getTable()->default_column_bitmaps();
 
1446
  table->default_column_bitmaps();
1455
1447
  return(reset());
1456
1448
}
1457
1449
 
1466
1458
   * @TODO Technically, the below two lines can be take even further out of the
1467
1459
   * Cursor interface and into the fill_record() method.
1468
1460
   */
1469
 
  if (getTable()->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT)
1470
 
  {
1471
 
    getTable()->timestamp_field->set_time();
1472
 
  }
 
1461
  if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT)
 
1462
    table->timestamp_field->set_time();
1473
1463
 
1474
 
  DRIZZLE_INSERT_ROW_START(getTable()->getShare()->getSchemaName(), getTable()->getShare()->getTableName());
 
1464
  DRIZZLE_INSERT_ROW_START(table_share->getSchemaName(), table_share->getTableName());
1475
1465
  setTransactionReadWrite();
1476
1466
  
1477
 
  if (unlikely(plugin::EventObserver::beforeInsertRecord(*getTable(), buf)))
 
1467
  if (unlikely(plugin::EventObserver::beforeInsertRecord(*(table->in_use), *table_share, buf)))
1478
1468
  {
1479
1469
    error= ER_EVENT_OBSERVER_PLUGIN;
1480
1470
  }
1481
1471
  else
1482
1472
  {
1483
1473
    error= doInsertRecord(buf);
1484
 
    if (unlikely(plugin::EventObserver::afterInsertRecord(*getTable(), buf, error))) 
 
1474
    if (unlikely(plugin::EventObserver::afterInsertRecord(*(table->in_use), *table_share, buf, error))) 
1485
1475
    {
1486
1476
      error= ER_EVENT_OBSERVER_PLUGIN;
1487
1477
    }
1488
1478
  }
1489
 
 
1490
 
  ha_statistic_increment(&system_status_var::ha_write_count);
1491
 
 
 
1479
 
1492
1480
  DRIZZLE_INSERT_ROW_DONE(error);
1493
1481
 
1494
1482
  if (unlikely(error))
1496
1484
    return error;
1497
1485
  }
1498
1486
 
1499
 
  if (unlikely(log_row_for_replication(getTable(), NULL, buf)))
 
1487
  if (unlikely(log_row_for_replication(table, NULL, buf)))
1500
1488
    return HA_ERR_RBR_LOGGING_FAILED;
1501
1489
 
1502
1490
  return 0;
1508
1496
  int error;
1509
1497
 
1510
1498
  /*
1511
 
    Some storage engines require that the new record is in getInsertRecord()
1512
 
    (and the old record is in getUpdateRecord()).
 
1499
    Some storage engines require that the new record is in record[0]
 
1500
    (and the old record is in record[1]).
1513
1501
   */
1514
 
  assert(new_data == getTable()->getInsertRecord());
 
1502
  assert(new_data == table->record[0]);
1515
1503
 
1516
 
  DRIZZLE_UPDATE_ROW_START(getTable()->getShare()->getSchemaName(), getTable()->getShare()->getTableName());
 
1504
  DRIZZLE_UPDATE_ROW_START(table_share->getSchemaName(), table_share->getTableName());
1517
1505
  setTransactionReadWrite();
1518
 
  if (unlikely(plugin::EventObserver::beforeUpdateRecord(*getTable(), old_data, new_data)))
 
1506
  if (unlikely(plugin::EventObserver::beforeUpdateRecord(*(table->in_use), *table_share, old_data, new_data)))
1519
1507
  {
1520
1508
    error= ER_EVENT_OBSERVER_PLUGIN;
1521
1509
  }
1522
1510
  else
1523
1511
  {
1524
 
    if (getTable()->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE)
1525
 
    {
1526
 
      getTable()->timestamp_field->set_time();
1527
 
    }
1528
 
 
1529
1512
    error= doUpdateRecord(old_data, new_data);
1530
 
    if (unlikely(plugin::EventObserver::afterUpdateRecord(*getTable(), old_data, new_data, error)))
 
1513
    if (unlikely(plugin::EventObserver::afterUpdateRecord(*(table->in_use), *table_share, old_data, new_data, error)))
1531
1514
    {
1532
1515
      error= ER_EVENT_OBSERVER_PLUGIN;
1533
1516
    }
1534
1517
  }
1535
1518
 
1536
 
  ha_statistic_increment(&system_status_var::ha_update_count);
1537
 
 
1538
1519
  DRIZZLE_UPDATE_ROW_DONE(error);
1539
1520
 
1540
1521
  if (unlikely(error))
1542
1523
    return error;
1543
1524
  }
1544
1525
 
1545
 
  if (unlikely(log_row_for_replication(getTable(), old_data, new_data)))
 
1526
  if (unlikely(log_row_for_replication(table, old_data, new_data)))
1546
1527
    return HA_ERR_RBR_LOGGING_FAILED;
1547
1528
 
1548
1529
  return 0;
1549
1530
}
1550
 
TableShare *Cursor::getShare()
1551
 
{
1552
 
  return getTable()->getMutableShare();
1553
 
}
1554
1531
 
1555
1532
int Cursor::deleteRecord(const unsigned char *buf)
1556
1533
{
1557
1534
  int error;
1558
1535
 
1559
 
  DRIZZLE_DELETE_ROW_START(getTable()->getShare()->getSchemaName(), getTable()->getShare()->getTableName());
 
1536
  DRIZZLE_DELETE_ROW_START(table_share->getSchemaName(), table_share->getTableName());
1560
1537
  setTransactionReadWrite();
1561
 
  if (unlikely(plugin::EventObserver::beforeDeleteRecord(*getTable(), buf)))
 
1538
  if (unlikely(plugin::EventObserver::beforeDeleteRecord(*(table->in_use), *table_share, buf)))
1562
1539
  {
1563
1540
    error= ER_EVENT_OBSERVER_PLUGIN;
1564
1541
  }
1565
1542
  else
1566
1543
  {
1567
1544
    error= doDeleteRecord(buf);
1568
 
    if (unlikely(plugin::EventObserver::afterDeleteRecord(*getTable(), buf, error)))
 
1545
    if (unlikely(plugin::EventObserver::afterDeleteRecord(*(table->in_use), *table_share, buf, error)))
1569
1546
    {
1570
1547
      error= ER_EVENT_OBSERVER_PLUGIN;
1571
1548
    }
1572
1549
  }
1573
1550
 
1574
 
  ha_statistic_increment(&system_status_var::ha_delete_count);
1575
 
 
1576
1551
  DRIZZLE_DELETE_ROW_DONE(error);
1577
1552
 
1578
1553
  if (unlikely(error))
1579
1554
    return error;
1580
1555
 
1581
 
  if (unlikely(log_row_for_replication(getTable(), buf, NULL)))
 
1556
  if (unlikely(log_row_for_replication(table, buf, NULL)))
1582
1557
    return HA_ERR_RBR_LOGGING_FAILED;
1583
1558
 
1584
1559
  return 0;