1
1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
2
* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
4
* Copyright (C) 2008 Sun Microsystems, Inc.
4
* Copyright (C) 2008 Sun Microsystems
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
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>
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"
49
48
using namespace std;
55
54
** General Cursor functions
56
55
****************************************************************************/
57
56
Cursor::Cursor(plugin::StorageEngine &engine_arg,
61
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),
63
61
key_used_on_scan(MAX_KEY), active_index(MAX_KEY),
64
62
ref_length(sizeof(internal::my_off_t)),
78
* @note this only used in
79
* optimizer::QuickRangeSelect::init_ror_merged_scan(bool reuse_handler) as
80
* of the writing of this comment. -Brian
82
75
Cursor *Cursor::clone(memory::Root *mem_root)
84
Cursor *new_handler= getTable()->getMutableShare()->db_type()->getCursor(*getTable());
77
Cursor *new_handler= table->getMutableShare()->db_type()->getCursor(*table->getMutableShare(), mem_root);
87
80
Allocate Cursor->ref here because otherwise ha_open will allocate it
91
84
if (!(new_handler->ref= (unsigned char*) mem_root->alloc_root(ALIGN_SIZE(ref_length)*2)))
94
identifier::Table identifier(getTable()->getShare()->getSchemaName(),
95
getTable()->getShare()->getTableName(),
96
getTable()->getShare()->getType());
98
if (new_handler && !new_handler->ha_open(identifier,
99
getTable()->getDBStat(),
86
if (new_handler && !new_handler->ha_open(table,
87
table->getMutableShare()->getNormalizedPath(),
100
89
HA_OPEN_IGNORE_IF_LOCKED))
101
90
return new_handler;
112
101
/* works only with key prefixes */
113
102
assert(((keypart_map_arg + 1) & keypart_map_arg) == 0);
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;
104
const KeyPartInfo *key_part_found= table->getShare()->getKeyInfo(key_position).key_part;
105
const KeyPartInfo *end_key_part_found= key_part_found + table->getShare()->getKeyInfo(key_position).key_parts;
117
106
uint32_t length= 0;
119
108
while (key_part_found < end_key_part_found && keypart_map_arg)
184
179
bool Cursor::has_transactions()
186
return (getTable()->getShare()->db_type()->check_flag(HTON_BIT_DOES_TRANSACTIONS));
181
return (table->getShare()->db_type()->check_flag(HTON_BIT_DOES_TRANSACTIONS));
189
void Cursor::ha_statistic_increment(uint64_t system_status_var::*offset) const
184
void Cursor::ha_statistic_increment(ulong system_status_var::*offset) const
191
(getTable()->in_use->status_var.*offset)++;
186
status_var_increment(table->in_use->status_var.*offset);
194
189
void **Cursor::ha_data(Session *session) const
196
return session->getEngineData(getEngine());
191
return session->getEngineData(engine);
194
Session *Cursor::ha_session(void) const
196
assert(!table || !table->in_use || table->in_use == current_session);
197
return (table && table->in_use) ? table->in_use : current_session;
199
201
bool Cursor::is_fatal_error(int error, uint32_t flags)
210
212
ha_rows Cursor::records() { return stats.records; }
211
213
uint64_t Cursor::tableSize() { return stats.index_file_length + stats.data_file_length; }
212
uint64_t Cursor::rowSize() { return getTable()->getRecordLength() + getTable()->sizeFields(); }
214
int Cursor::doOpen(const identifier::Table &identifier, int mode, uint32_t test_if_locked)
216
return open(identifier.getPath().c_str(), mode, test_if_locked);
214
uint64_t Cursor::rowSize() { return table->getRecordLength() + table->sizeFields(); }
220
217
Open database-Cursor.
222
219
Try O_RDONLY if cannot open as O_RDWR
223
220
Don't wait for locks if not HA_OPEN_WAIT_IF_LOCKED is set
225
int Cursor::ha_open(const identifier::Table &identifier,
222
int Cursor::ha_open(Table *table_arg, const char *name, int mode,
231
if ((error= doOpen(identifier, mode, test_if_locked)))
228
assert(table->getShare() == table_share);
230
if ((error=open(name, mode, test_if_locked)))
233
232
if ((error == EACCES || error == EROFS) && mode == O_RDWR &&
234
(getTable()->db_stat & HA_TRY_READ_ONLY))
233
(table->db_stat & HA_TRY_READ_ONLY))
236
getTable()->db_stat|=HA_READ_ONLY;
237
error= doOpen(identifier, O_RDONLY,test_if_locked);
235
table->db_stat|=HA_READ_ONLY;
236
error=open(name,O_RDONLY,test_if_locked);
246
if (getTable()->getShare()->db_options_in_use & HA_OPTION_READ_ONLY_DATA)
247
getTable()->db_stat|=HA_READ_ONLY;
245
if (table->getShare()->db_options_in_use & HA_OPTION_READ_ONLY_DATA)
246
table->db_stat|=HA_READ_ONLY;
248
247
(void) extra(HA_EXTRA_NO_READCHECK); // Not needed in SQL
250
249
/* ref is already allocated for us if we're called from Cursor::clone() */
251
if (!ref && !(ref= (unsigned char*) getTable()->alloc_root(ALIGN_SIZE(ref_length)*2)))
250
if (!ref && !(ref= (unsigned char*) table->alloc_root(ALIGN_SIZE(ref_length)*2)))
254
253
error=HA_ERR_OUT_OF_MEM;
268
267
int Cursor::read_first_row(unsigned char * buf, uint32_t primary_key)
272
271
ha_statistic_increment(&system_status_var::ha_read_first_count);
275
274
If there is very few deleted rows in the table, find the first row by
276
275
scanning the table.
277
@todo remove the test for HA_READ_ORDER
276
TODO remove the test for HA_READ_ORDER
279
278
if (stats.deleted < 10 || primary_key >= MAX_KEY ||
280
!(getTable()->index_flags(primary_key) & HA_READ_ORDER))
279
!(table->index_flags(primary_key) & HA_READ_ORDER))
282
error= startTableScan(1);
285
while ((error= rnd_next(buf)) == HA_ERR_RECORD_DELETED) ;
286
(void) endTableScan();
281
(void) startTableScan(1);
282
while ((error= rnd_next(buf)) == HA_ERR_RECORD_DELETED) ;
283
(void) endTableScan();
291
287
/* Find the first row through the primary key */
292
error= startIndexScan(primary_key, 0);
295
error=index_first(buf);
296
(void) endIndexScan();
288
(void) startIndexScan(primary_key, 0);
289
error=index_first(buf);
290
(void) endIndexScan();
311
304
@verbatim 1,5,15,25,35,... @endverbatim
314
compute_next_insert_id(uint64_t nr, drizzle_system_variables *variables)
307
compute_next_insert_id(uint64_t nr,struct system_variables *variables)
316
309
if (variables->auto_increment_increment == 1)
317
310
return (nr+1); // optimization of the formula below
331
324
Session::next_insert_id to be greater than the explicit value.
333
326
if ((next_insert_id > 0) && (nr >= next_insert_id))
334
set_next_insert_id(compute_next_insert_id(nr, &getTable()->in_use->variables));
327
set_next_insert_id(compute_next_insert_id(nr, &table->in_use->variables));
351
344
The number X if it exists, "nr" otherwise.
354
prev_insert_id(uint64_t nr, drizzle_system_variables *variables)
347
prev_insert_id(uint64_t nr, struct system_variables *variables)
356
349
if (unlikely(nr < variables->auto_increment_offset))
449
442
uint64_t nr, nb_reserved_values;
450
443
bool append= false;
451
Session *session= getTable()->in_use;
452
drizzle_system_variables *variables= &session->variables;
444
Session *session= table->in_use;
445
struct system_variables *variables= &session->variables;
455
448
next_insert_id is a "cursor" into the reserved interval, it may go greater
461
454
for an auto increment column, not a magic value like NULL is.
462
455
same as sql_mode=NO_AUTO_VALUE_ON_ZERO */
464
if ((nr= getTable()->next_number_field->val_int()) != 0
465
|| getTable()->auto_increment_field_not_null)
457
if ((nr= table->next_number_field->val_int()) != 0
458
|| table->auto_increment_field_not_null)
468
461
Update next_insert_id if we had already generated a value in this
540
533
nr= compute_next_insert_id(nr-1, variables);
543
if (getTable()->getShare()->next_number_keypart == 0)
536
if (table->getShare()->next_number_keypart == 0)
545
538
/* We must defer the appending until "nr" has been possibly truncated */
550
if (unlikely(getTable()->next_number_field->store((int64_t) nr, true)))
543
if (unlikely(table->next_number_field->store((int64_t) nr, true)))
553
546
first test if the query was aborted due to strict mode constraints
555
if (session->getKilled() == Session::KILL_BAD_DATA)
548
if (session->killed == Session::KILL_BAD_DATA)
556
549
return HA_ERR_AUTOINC_ERANGE;
563
556
bother shifting the right bound (anyway any other value from this
564
557
interval will cause a duplicate key).
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();
559
nr= prev_insert_id(table->next_number_field->val_int(), variables);
560
if (unlikely(table->next_number_field->store((int64_t) nr, true)))
561
nr= table->next_number_field->val_int();
619
612
this statement used forced auto_increment values if there were some,
620
613
wipe them away for other statements.
622
getTable()->in_use->auto_inc_intervals_forced.empty();
615
table->in_use->auto_inc_intervals_forced.empty();
659
652
Cursor::setTransactionReadWrite()
661
ResourceContext *resource_context;
664
* If the cursor has not context for execution then there should be no
665
* possible resource to gain (and if there is... then there is a bug such
666
* that in_use should have been set.
668
if (not getTable()->in_use)
671
resource_context= getTable()->in_use->getResourceContext(getEngine());
654
ResourceContext *resource_context= ha_session()->getResourceContext(engine);
673
656
When a storage engine method is called, the transaction must
674
657
have been started, unless it's a DDL call, for which the
709
692
* @todo Make TransactionServices generic to AfterTriggerServices
712
Session *const session= getTable()->in_use;
695
Session *const session= table->in_use;
713
696
TransactionServices &transaction_services= TransactionServices::singleton();
714
transaction_services.truncateTable(*session, *getTable());
697
transaction_services.truncateTable(session, table);
811
794
if (!(error=index_next(buf)))
813
ptrdiff_t ptrdiff= buf - getTable()->getInsertRecord();
796
ptrdiff_t ptrdiff= buf - table->record[0];
814
797
unsigned char *save_record_0= NULL;
815
798
KeyInfo *key_info= NULL;
816
799
KeyPartInfo *key_part;
817
800
KeyPartInfo *key_part_end= NULL;
820
key_cmp_if_same() compares table->getInsertRecord() against 'key'.
821
In parts it uses table->getInsertRecord() directly, in parts it uses
822
field objects with their local pointers into table->getInsertRecord().
823
If 'buf' is distinct from table->getInsertRecord(), we need to move
824
all record references. This is table->getInsertRecord() itself and
803
key_cmp_if_same() compares table->record[0] against 'key'.
804
In parts it uses table->record[0] directly, in parts it uses
805
field objects with their local pointers into table->record[0].
806
If 'buf' is distinct from table->record[0], we need to move
807
all record references. This is table->record[0] itself and
825
808
the field pointers of the fields used in this key.
829
save_record_0= getTable()->getInsertRecord();
830
getTable()->record[0]= buf;
831
key_info= getTable()->key_info + active_index;
812
save_record_0= table->record[0];
813
table->record[0]= buf;
814
key_info= table->key_info + active_index;
832
815
key_part= key_info->key_part;
833
816
key_part_end= key_part + key_info->key_parts;
834
817
for (; key_part < key_part_end; key_part++)
841
if (key_cmp_if_same(getTable(), key, active_index, keylen))
824
if (key_cmp_if_same(table, key, active_index, keylen))
843
getTable()->status=STATUS_NOT_FOUND;
826
table->status=STATUS_NOT_FOUND;
844
827
error=HA_ERR_END_OF_FILE;
847
830
/* Move back if necessary. */
850
getTable()->record[0]= save_record_0;
833
table->record[0]= save_record_0;
851
834
for (key_part= key_info->key_part; key_part < key_part_end; key_part++)
852
835
key_part->field->move_field_offset(-ptrdiff);
884
867
double Cursor::index_only_read_time(uint32_t keynr, double key_records)
886
869
uint32_t keys_per_block= (stats.block_size/2/
887
(getTable()->key_info[keynr].key_length + ref_length) + 1);
870
(table->key_info[keynr].key_length + ref_length) + 1);
888
871
return ((double) (key_records + keys_per_block-1) /
889
872
(double) keys_per_block);
915
898
This method (or an overriding one in a derived class) must check for
916
session->getKilled() and return HA_POS_ERROR if it is not zero. This is required
899
session->killed and return HA_POS_ERROR if it is not zero. This is required
917
900
for a user to be able to interrupt the calculation by killing the
918
901
connection/query.
942
926
seq_it= seq->init(seq_init_param, n_ranges, *flags);
943
927
while (!seq->next(seq_it, &range))
929
if (unlikely(session->killed != 0))
946
933
key_range *min_endp, *max_endp;
1191
1178
key_compare_result_on_equal= ((end_key->flag == HA_READ_BEFORE_KEY) ? 1 :
1192
1179
(end_key->flag == HA_READ_AFTER_KEY) ? -1 : 0);
1194
range_key_part= getTable()->key_info[active_index].key_part;
1181
range_key_part= table->key_info[active_index].key_part;
1196
1183
if (!start_key) // Read first record
1197
result= index_first(getTable()->getInsertRecord());
1184
result= index_first(table->record[0]);
1199
result= index_read_map(getTable()->getInsertRecord(),
1186
result= index_read_map(table->record[0],
1200
1187
start_key->key,
1201
1188
start_key->keypart_map,
1202
1189
start_key->flag);
1231
1218
/* We trust that index_next_same always gives a row in range */
1232
return(index_next_same(getTable()->getInsertRecord(),
1219
return(index_next_same(table->record[0],
1233
1220
end_range->key,
1234
1221
end_range->length));
1236
result= index_next(getTable()->getInsertRecord());
1223
result= index_next(table->record[0]);
1239
1226
return(compare_key(end_range) <= 0 ? 0 : HA_ERR_END_OF_FILE);
1295
1282
TransactionServices &transaction_services= TransactionServices::singleton();
1296
1283
Session *const session= table->in_use;
1298
if (table->getShare()->getType() || not transaction_services.shouldConstructMessages())
1285
if (table->getShare()->tmp_table || not transaction_services.shouldConstructMessages())
1301
1288
bool result= false;
1303
switch (session->getLex()->sql_command)
1290
switch (session->lex->sql_command)
1305
1292
case SQLCOM_CREATE_TABLE:
1312
1299
* CREATE TABLE will commit the transaction containing
1315
result= transaction_services.insertRecord(*session, *table);
1302
result= transaction_services.insertRecord(session, table);
1317
1304
case SQLCOM_REPLACE:
1318
1305
case SQLCOM_REPLACE_SELECT:
1323
1310
* called. If it fails, then a call to deleteRecord()
1324
1311
* is called, followed by a repeat of the original
1325
1312
* call to insertRecord(). So, log_row_for_replication
1326
* could be called multiple times for a REPLACE
1313
* could be called either once or twice for a REPLACE
1327
1314
* statement. The below looks at the values of before_record
1328
1315
* and after_record to determine which call to this
1329
1316
* function is for the delete or the insert, since NULL
1337
1324
if (after_record == NULL)
1340
* The storage engine is passed the record in table->record[1]
1341
* as the row to delete (this is the conflicting row), so
1342
* we need to notify TransactionService to use that row.
1344
transaction_services.deleteRecord(*session, *table, true);
1326
transaction_services.deleteRecord(session, table);
1346
1328
* We set the "current" statement message to NULL. This triggers
1347
1329
* the replication services component to generate a new statement
1348
1330
* message for the inserted record which will come next.
1350
transaction_services.finalizeStatementMessage(*session->getStatementMessage(), *session);
1332
transaction_services.finalizeStatementMessage(*session->getStatementMessage(), session);
1354
1336
if (before_record == NULL)
1355
result= transaction_services.insertRecord(*session, *table);
1337
result= transaction_services.insertRecord(session, table);
1357
transaction_services.updateRecord(*session, *table, before_record, after_record);
1339
transaction_services.updateRecord(session, table, before_record, after_record);
1360
1342
case SQLCOM_INSERT:
1361
1343
case SQLCOM_INSERT_SELECT:
1364
1345
* The else block below represents an
1365
1346
* INSERT ... ON DUPLICATE KEY UPDATE that
1369
1350
if (before_record == NULL)
1370
result= transaction_services.insertRecord(*session, *table);
1351
result= transaction_services.insertRecord(session, table);
1372
transaction_services.updateRecord(*session, *table, before_record, after_record);
1353
transaction_services.updateRecord(session, table, before_record, after_record);
1375
1356
case SQLCOM_UPDATE:
1376
transaction_services.updateRecord(*session, *table, before_record, after_record);
1357
transaction_services.updateRecord(session, table, before_record, after_record);
1379
1360
case SQLCOM_DELETE:
1380
transaction_services.deleteRecord(*session, *table);
1361
transaction_services.deleteRecord(session, table);
1402
1383
if (lock_type == F_RDLCK)
1404
DRIZZLE_CURSOR_RDLOCK_START(getTable()->getShare()->getSchemaName(),
1405
getTable()->getShare()->getTableName());
1385
DRIZZLE_CURSOR_RDLOCK_START(table_share->getSchemaName(),
1386
table_share->getTableName());
1407
1388
else if (lock_type == F_WRLCK)
1409
DRIZZLE_CURSOR_WRLOCK_START(getTable()->getShare()->getSchemaName(),
1410
getTable()->getShare()->getTableName());
1390
DRIZZLE_CURSOR_WRLOCK_START(table_share->getSchemaName(),
1391
table_share->getTableName());
1412
1393
else if (lock_type == F_UNLCK)
1414
DRIZZLE_CURSOR_UNLOCK_START(getTable()->getShare()->getSchemaName(),
1415
getTable()->getShare()->getTableName());
1395
DRIZZLE_CURSOR_UNLOCK_START(table_share->getSchemaName(),
1396
table_share->getTableName());
1451
1432
int Cursor::ha_reset()
1453
1434
/* Check that we have called all proper deallocation functions */
1454
assert(! getTable()->getShare()->all_set.none());
1455
assert(getTable()->key_read == 0);
1435
assert((unsigned char*) table->def_read_set.getBitmap() +
1436
table->getShare()->column_bitmap_size ==
1437
(unsigned char*) table->def_write_set.getBitmap());
1438
assert(table->getShare()->all_set.isSetAll());
1439
assert(table->key_read == 0);
1456
1440
/* ensure that ha_index_end / endTableScan has been called */
1457
1441
assert(inited == NONE);
1458
1442
/* Free cache used by filesort */
1459
getTable()->free_io_cache();
1443
table->free_io_cache();
1460
1444
/* reset the bitmaps to point to defaults */
1461
getTable()->default_column_bitmaps();
1445
table->default_column_bitmaps();
1462
1446
return(reset());
1473
1457
* @TODO Technically, the below two lines can be take even further out of the
1474
1458
* Cursor interface and into the fill_record() method.
1476
if (getTable()->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT)
1478
getTable()->timestamp_field->set_time();
1460
if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT)
1461
table->timestamp_field->set_time();
1481
DRIZZLE_INSERT_ROW_START(getTable()->getShare()->getSchemaName(), getTable()->getShare()->getTableName());
1463
DRIZZLE_INSERT_ROW_START(table_share->getSchemaName(), table_share->getTableName());
1482
1464
setTransactionReadWrite();
1484
if (unlikely(plugin::EventObserver::beforeInsertRecord(*getTable(), buf)))
1466
if (unlikely(plugin::EventObserver::beforeInsertRecord(*(table->in_use), *table_share, buf)))
1486
1468
error= ER_EVENT_OBSERVER_PLUGIN;
1490
1472
error= doInsertRecord(buf);
1491
if (unlikely(plugin::EventObserver::afterInsertRecord(*getTable(), buf, error)))
1473
if (unlikely(plugin::EventObserver::afterInsertRecord(*(table->in_use), *table_share, buf, error)))
1493
1475
error= ER_EVENT_OBSERVER_PLUGIN;
1497
ha_statistic_increment(&system_status_var::ha_write_count);
1499
1479
DRIZZLE_INSERT_ROW_DONE(error);
1501
1481
if (unlikely(error))
1506
if (unlikely(log_row_for_replication(getTable(), NULL, buf)))
1486
if (unlikely(log_row_for_replication(table, NULL, buf)))
1507
1487
return HA_ERR_RBR_LOGGING_FAILED;
1518
Some storage engines require that the new record is in getInsertRecord()
1519
(and the old record is in getUpdateRecord()).
1498
Some storage engines require that the new record is in record[0]
1499
(and the old record is in record[1]).
1521
assert(new_data == getTable()->getInsertRecord());
1501
assert(new_data == table->record[0]);
1523
DRIZZLE_UPDATE_ROW_START(getTable()->getShare()->getSchemaName(), getTable()->getShare()->getTableName());
1503
DRIZZLE_UPDATE_ROW_START(table_share->getSchemaName(), table_share->getTableName());
1524
1504
setTransactionReadWrite();
1525
if (unlikely(plugin::EventObserver::beforeUpdateRecord(*getTable(), old_data, new_data)))
1505
if (unlikely(plugin::EventObserver::beforeUpdateRecord(*(table->in_use), *table_share, old_data, new_data)))
1527
1507
error= ER_EVENT_OBSERVER_PLUGIN;
1531
if (getTable()->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE)
1533
getTable()->timestamp_field->set_time();
1536
1511
error= doUpdateRecord(old_data, new_data);
1537
if (unlikely(plugin::EventObserver::afterUpdateRecord(*getTable(), old_data, new_data, error)))
1512
if (unlikely(plugin::EventObserver::afterUpdateRecord(*(table->in_use), *table_share, old_data, new_data, error)))
1539
1514
error= ER_EVENT_OBSERVER_PLUGIN;
1543
ha_statistic_increment(&system_status_var::ha_update_count);
1545
1518
DRIZZLE_UPDATE_ROW_DONE(error);
1547
1520
if (unlikely(error))
1552
if (unlikely(log_row_for_replication(getTable(), old_data, new_data)))
1525
if (unlikely(log_row_for_replication(table, old_data, new_data)))
1553
1526
return HA_ERR_RBR_LOGGING_FAILED;
1557
TableShare *Cursor::getShare()
1559
return getTable()->getMutableShare();
1562
1531
int Cursor::deleteRecord(const unsigned char *buf)
1566
DRIZZLE_DELETE_ROW_START(getTable()->getShare()->getSchemaName(), getTable()->getShare()->getTableName());
1535
DRIZZLE_DELETE_ROW_START(table_share->getSchemaName(), table_share->getTableName());
1567
1536
setTransactionReadWrite();
1568
if (unlikely(plugin::EventObserver::beforeDeleteRecord(*getTable(), buf)))
1537
if (unlikely(plugin::EventObserver::beforeDeleteRecord(*(table->in_use), *table_share, buf)))
1570
1539
error= ER_EVENT_OBSERVER_PLUGIN;
1574
1543
error= doDeleteRecord(buf);
1575
if (unlikely(plugin::EventObserver::afterDeleteRecord(*getTable(), buf, error)))
1544
if (unlikely(plugin::EventObserver::afterDeleteRecord(*(table->in_use), *table_share, buf, error)))
1577
1546
error= ER_EVENT_OBSERVER_PLUGIN;
1581
ha_statistic_increment(&system_status_var::ha_delete_count);
1583
1550
DRIZZLE_DELETE_ROW_DONE(error);
1585
1552
if (unlikely(error))
1588
if (unlikely(log_row_for_replication(getTable(), buf, NULL)))
1555
if (unlikely(log_row_for_replication(table, buf, NULL)))
1589
1556
return HA_ERR_RBR_LOGGING_FAILED;