32
32
#include "drizzled/gettext.h"
33
33
#include "drizzled/probes.h"
34
34
#include "drizzled/sql_parse.h"
35
#include "drizzled/optimizer/cost_vector.h"
35
#include "drizzled/cost_vect.h"
36
36
#include "drizzled/session.h"
37
37
#include "drizzled/sql_base.h"
38
#include "drizzled/transaction_services.h"
38
#include "drizzled/replication_services.h"
39
39
#include "drizzled/lock.h"
40
40
#include "drizzled/item/int.h"
41
41
#include "drizzled/item/empty_string.h"
54
54
** General Cursor functions
55
55
****************************************************************************/
56
56
Cursor::Cursor(plugin::StorageEngine &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),
60
ref(0), in_range_check_pushed_down(false),
62
61
key_used_on_scan(MAX_KEY), active_index(MAX_KEY),
63
62
ref_length(sizeof(internal::my_off_t)),
64
locked(false), implicit_emptied(0),
66
65
next_insert_id(0), insert_id_for_cur_row(0)
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
81
75
Cursor *Cursor::clone(memory::Root *mem_root)
83
Cursor *new_handler= getTable()->getMutableShare()->db_type()->getCursor(*getTable());
77
Cursor *new_handler= table->s->db_type()->getCursor(*table->s, mem_root);
86
80
Allocate Cursor->ref here because otherwise ha_open will allocate it
87
81
on this->table->mem_root and we will not be able to reclaim that memory
88
82
when the clone Cursor object is destroyed.
90
if (!(new_handler->ref= (unsigned char*) mem_root->alloc_root(ALIGN_SIZE(ref_length)*2)))
84
if (!(new_handler->ref= (unsigned char*) alloc_root(mem_root, ALIGN_SIZE(ref_length)*2)))
93
TableIdentifier identifier(getTable()->getShare()->getSchemaName(),
94
getTable()->getShare()->getTableName(),
95
getTable()->getShare()->getType());
97
if (new_handler && !new_handler->ha_open(identifier,
98
getTable()->getDBStat(),
86
if (new_handler && !new_handler->ha_open(table,
87
table->s->normalized_path.str,
99
89
HA_OPEN_IGNORE_IF_LOCKED))
100
90
return new_handler;
106
given a buffer with a key value, and a map of keyparts
107
that are present in this value, returns the length of the value
109
uint32_t Cursor::calculate_key_len(uint32_t key_position, key_part_map keypart_map_arg)
111
/* works only with key prefixes */
112
assert(((keypart_map_arg + 1) & keypart_map_arg) == 0);
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;
118
while (key_part_found < end_key_part_found && keypart_map_arg)
120
length+= key_part_found->store_length;
121
keypart_map_arg >>= 1;
127
int Cursor::startIndexScan(uint32_t idx, bool sorted)
94
int Cursor::ha_index_init(uint32_t idx, bool sorted)
130
97
assert(inited == NONE);
131
if (!(result= doStartIndexScan(idx, sorted)))
98
if (!(result= index_init(idx, sorted)))
137
int Cursor::endIndexScan()
104
int Cursor::ha_index_end()
139
106
assert(inited==INDEX);
142
return(doEndIndexScan());
145
int Cursor::startTableScan(bool scan)
112
int Cursor::ha_rnd_init(bool scan)
148
115
assert(inited==NONE || (inited==RND && scan));
149
inited= (result= doStartTableScan(scan)) ? NONE: RND;
116
inited= (result= rnd_init(scan)) ? NONE: RND;
154
int Cursor::endTableScan()
121
int Cursor::ha_rnd_end()
156
123
assert(inited==RND);
158
return(doEndTableScan());
161
128
int Cursor::ha_index_or_rnd_end()
163
return inited == INDEX ? endIndexScan() : inited == RND ? endTableScan() : 0;
130
return inited == INDEX ? ha_index_end() : inited == RND ? ha_rnd_end() : 0;
166
133
void Cursor::ha_start_bulk_insert(ha_rows rows)
183
156
bool Cursor::has_transactions()
185
return (getTable()->getShare()->db_type()->check_flag(HTON_BIT_DOES_TRANSACTIONS));
158
return (table->s->db_type()->check_flag(HTON_BIT_DOES_TRANSACTIONS));
188
void Cursor::ha_statistic_increment(uint64_t system_status_var::*offset) const
161
void Cursor::ha_statistic_increment(ulong SSV::*offset) const
190
(getTable()->in_use->status_var.*offset)++;
163
status_var_increment(table->in_use->status_var.*offset);
193
166
void **Cursor::ha_data(Session *session) const
195
return session->getEngineData(getEngine());
168
return session->getEngineData(engine);
171
Session *Cursor::ha_session(void) const
173
assert(!table || !table->in_use || table->in_use == current_session);
174
return (table && table->in_use) ? table->in_use : current_session;
198
178
bool Cursor::is_fatal_error(int error, uint32_t flags)
209
189
ha_rows Cursor::records() { return stats.records; }
210
uint64_t Cursor::tableSize() { return stats.index_file_length + stats.data_file_length; }
211
uint64_t Cursor::rowSize() { return getTable()->getRecordLength() + getTable()->sizeFields(); }
213
int Cursor::doOpen(const TableIdentifier &identifier, int mode, uint32_t test_if_locked)
215
return open(identifier.getPath().c_str(), mode, test_if_locked);
219
192
Open database-Cursor.
221
194
Try O_RDONLY if cannot open as O_RDWR
222
195
Don't wait for locks if not HA_OPEN_WAIT_IF_LOCKED is set
224
int Cursor::ha_open(const TableIdentifier &identifier,
197
int Cursor::ha_open(Table *table_arg, const char *name, int mode,
230
if ((error= doOpen(identifier, mode, test_if_locked)))
203
assert(table->s == table_share);
204
assert(alloc_root_inited(&table->mem_root));
206
if ((error=open(name,mode,test_if_locked)))
232
208
if ((error == EACCES || error == EROFS) && mode == O_RDWR &&
233
(getTable()->db_stat & HA_TRY_READ_ONLY))
209
(table->db_stat & HA_TRY_READ_ONLY))
235
getTable()->db_stat|=HA_READ_ONLY;
236
error= doOpen(identifier, O_RDONLY,test_if_locked);
211
table->db_stat|=HA_READ_ONLY;
212
error=open(name,O_RDONLY,test_if_locked);
245
if (getTable()->getShare()->db_options_in_use & HA_OPTION_READ_ONLY_DATA)
246
getTable()->db_stat|=HA_READ_ONLY;
221
if (table->s->db_options_in_use & HA_OPTION_READ_ONLY_DATA)
222
table->db_stat|=HA_READ_ONLY;
247
223
(void) extra(HA_EXTRA_NO_READCHECK); // Not needed in SQL
249
225
/* 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)))
226
if (!ref && !(ref= (unsigned char*) alloc_root(&table->mem_root,
227
ALIGN_SIZE(ref_length)*2)))
253
230
error=HA_ERR_OUT_OF_MEM;
239
one has to use this method when to find
240
random position by record as the plain
241
position() call doesn't work for some
242
handlers for random position
245
int Cursor::rnd_pos_by_record(unsigned char *record)
250
if (inited && (error= ha_index_end()))
252
if ((error= ha_rnd_init(false)))
255
return rnd_pos(record, ref);
262
259
Read first row (only) from a table.
264
261
This is never called for InnoDB tables, as these table types
276
273
TODO remove the test for HA_READ_ORDER
278
275
if (stats.deleted < 10 || primary_key >= MAX_KEY ||
279
!(getTable()->index_flags(primary_key) & HA_READ_ORDER))
276
!(table->index_flags(primary_key) & HA_READ_ORDER))
281
(void) startTableScan(1);
278
(void) ha_rnd_init(1);
282
279
while ((error= rnd_next(buf)) == HA_ERR_RECORD_DELETED) ;
283
(void) endTableScan();
287
284
/* Find the first row through the primary key */
288
(void) startIndexScan(primary_key, 0);
285
(void) ha_index_init(primary_key, 0);
289
286
error=index_first(buf);
290
(void) endIndexScan();
287
(void) ha_index_end();
304
301
@verbatim 1,5,15,25,35,... @endverbatim
307
compute_next_insert_id(uint64_t nr, drizzle_system_variables *variables)
304
compute_next_insert_id(uint64_t nr,struct system_variables *variables)
309
306
if (variables->auto_increment_increment == 1)
310
307
return (nr+1); // optimization of the formula below
454
451
for an auto increment column, not a magic value like NULL is.
455
452
same as sql_mode=NO_AUTO_VALUE_ON_ZERO */
457
if ((nr= getTable()->next_number_field->val_int()) != 0
458
|| getTable()->auto_increment_field_not_null)
454
if ((nr= table->next_number_field->val_int()) != 0
455
|| table->auto_increment_field_not_null)
461
458
Update next_insert_id if we had already generated a value in this
533
530
nr= compute_next_insert_id(nr-1, variables);
536
if (getTable()->getShare()->next_number_keypart == 0)
533
if (table->s->next_number_keypart == 0)
538
535
/* We must defer the appending until "nr" has been possibly truncated */
543
if (unlikely(getTable()->next_number_field->store((int64_t) nr, true)))
540
if (unlikely(table->next_number_field->store((int64_t) nr, true)))
546
543
first test if the query was aborted due to strict mode constraints
548
if (session->getKilled() == Session::KILL_BAD_DATA)
545
if (session->killed == Session::KILL_BAD_DATA)
549
546
return HA_ERR_AUTOINC_ERANGE;
556
553
bother shifting the right bound (anyway any other value from this
557
554
interval will cause a duplicate key).
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();
556
nr= prev_insert_id(table->next_number_field->val_int(), variables);
557
if (unlikely(table->next_number_field->store((int64_t) nr, true)))
558
nr= table->next_number_field->val_int();
599
596
@param first_value (OUT) the first value reserved by the Cursor
600
597
@param nb_reserved_values (OUT) how many values the Cursor reserved
599
void Cursor::get_auto_increment(uint64_t ,
602
uint64_t *first_value,
603
uint64_t *nb_reserved_values)
608
(void) extra(HA_EXTRA_KEYREAD);
609
table->mark_columns_used_by_index_no_reset(table->s->next_number_index);
610
index_init(table->s->next_number_index, 1);
611
if (table->s->next_number_keypart == 0)
612
{ // Autoincrement at key-start
613
error=index_last(table->record[1]);
615
MySQL implicitely assumes such method does locking (as MySQL decides to
616
use nr+increment without checking again with the Cursor, in
617
Cursor::update_auto_increment()), so reserves to infinite.
619
*nb_reserved_values= UINT64_MAX;
623
unsigned char key[MAX_KEY_LENGTH];
624
key_copy(key, table->record[0],
625
table->key_info + table->s->next_number_index,
626
table->s->next_number_key_offset);
627
error= index_read_map(table->record[1], key,
628
make_prev_keypart_map(table->s->next_number_keypart),
629
HA_READ_PREFIX_LAST);
631
MySQL needs to call us for next row: assume we are inserting ("a",null)
632
here, we return 3, and next this statement will want to insert
633
("b",null): there is no reason why ("b",3+1) would be the good row to
634
insert: maybe it already exists, maybe 3+1 is too large...
636
*nb_reserved_values= 1;
642
nr= ((uint64_t) table->next_number_field->
643
val_int_offset(table->s->rec_buff_length)+1);
645
(void) extra(HA_EXTRA_NO_KEYREAD);
603
650
void Cursor::ha_release_auto_increment()
652
Cursor::setTransactionReadWrite()
699
Cursor::mark_trx_read_write()
654
ResourceContext *resource_context;
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.
661
if (not getTable()->in_use)
664
resource_context= getTable()->in_use->getResourceContext(getEngine());
701
Ha_trx_info *ha_info= ha_session()->getEngineInfo(engine);
666
703
When a storage engine method is called, the transaction must
667
704
have been started, unless it's a DDL call, for which the
700
737
* Trigger post-truncate notification to plugins...
702
* @todo Make TransactionServices generic to AfterTriggerServices
739
* @todo Make ReplicationServices generic to AfterTriggerServices
705
Session *const session= getTable()->in_use;
706
TransactionServices &transaction_services= TransactionServices::singleton();
707
transaction_services.truncateTable(session, getTable());
742
Session *const session= table->in_use;
743
ReplicationServices &replication_services= ReplicationServices::singleton();
744
replication_services.truncateTable(session, table);
804
841
if (!(error=index_next(buf)))
806
ptrdiff_t ptrdiff= buf - getTable()->getInsertRecord();
843
ptrdiff_t ptrdiff= buf - table->record[0];
807
844
unsigned char *save_record_0= NULL;
808
KeyInfo *key_info= NULL;
809
KeyPartInfo *key_part;
810
KeyPartInfo *key_part_end= NULL;
846
KEY_PART_INFO *key_part;
847
KEY_PART_INFO *key_part_end= NULL;
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
850
key_cmp_if_same() compares table->record[0] against 'key'.
851
In parts it uses table->record[0] directly, in parts it uses
852
field objects with their local pointers into table->record[0].
853
If 'buf' is distinct from table->record[0], we need to move
854
all record references. This is table->record[0] itself and
818
855
the field pointers of the fields used in this key.
822
save_record_0= getTable()->getInsertRecord();
823
getTable()->record[0]= buf;
824
key_info= getTable()->key_info + active_index;
859
save_record_0= table->record[0];
860
table->record[0]= buf;
861
key_info= table->key_info + active_index;
825
862
key_part= key_info->key_part;
826
863
key_part_end= key_part + key_info->key_parts;
827
864
for (; key_part < key_part_end; key_part++)
834
if (key_cmp_if_same(getTable(), key, active_index, keylen))
871
if (key_cmp_if_same(table, key, active_index, keylen))
836
getTable()->status=STATUS_NOT_FOUND;
873
table->status=STATUS_NOT_FOUND;
837
874
error=HA_ERR_END_OF_FILE;
840
877
/* Move back if necessary. */
843
getTable()->record[0]= save_record_0;
880
table->record[0]= save_record_0;
844
881
for (key_part= key_info->key_part; key_part < key_part_end; key_part++)
845
882
key_part->field->move_field_offset(-ptrdiff);
922
959
Cursor::multi_range_read_info_const(uint32_t keyno, RANGE_SEQ_IF *seq,
923
960
void *seq_init_param,
925
uint32_t *bufsz, uint32_t *flags, optimizer::CostVector *cost)
962
uint32_t *bufsz, uint32_t *flags, COST_VECT *cost)
927
964
KEY_MULTI_RANGE range;
928
965
range_seq_t seq_it;
929
966
ha_rows rows, total_rows= 0;
930
967
uint32_t n_ranges=0;
968
Session *session= current_session;
932
970
/* Default MRR implementation doesn't need buffer */
961
1002
/* The following calculation is the same as in multi_range_read_info(): */
962
1003
*flags |= HA_MRR_USE_DEFAULT_IMPL;
964
cost->setAvgIOCost(1); /* assume random seeks */
1005
cost->avg_io_cost= 1; /* assume random seeks */
965
1006
if ((*flags & HA_MRR_INDEX_ONLY) && total_rows > 2)
966
cost->setIOCount(index_only_read_time(keyno, (uint32_t)total_rows));
1007
cost->io_count= index_only_read_time(keyno, (uint32_t)total_rows);
968
cost->setIOCount(read_time(keyno, n_ranges, total_rows));
969
cost->setCpuCost((double) total_rows / TIME_FOR_COMPARE + 0.01);
1009
cost->io_count= read_time(keyno, n_ranges, total_rows);
1010
cost->cpu_cost= (double) total_rows / TIME_FOR_COMPARE + 0.01;
971
1012
return total_rows;
1009
1050
int Cursor::multi_range_read_info(uint32_t keyno, uint32_t n_ranges, uint32_t n_rows,
1010
uint32_t *bufsz, uint32_t *flags, optimizer::CostVector *cost)
1051
uint32_t *bufsz, uint32_t *flags, COST_VECT *cost)
1012
1053
*bufsz= 0; /* Default implementation doesn't need a buffer */
1014
1055
*flags |= HA_MRR_USE_DEFAULT_IMPL;
1017
cost->setAvgIOCost(1); /* assume random seeks */
1058
cost->avg_io_cost= 1; /* assume random seeks */
1019
1060
/* Produce the same cost as non-MRR code does */
1020
1061
if (*flags & HA_MRR_INDEX_ONLY)
1021
cost->setIOCount(index_only_read_time(keyno, n_rows));
1062
cost->io_count= index_only_read_time(keyno, n_rows);
1023
cost->setIOCount(read_time(keyno, n_ranges, n_rows));
1064
cost->io_count= read_time(keyno, n_ranges, n_rows);
1059
1100
The callee consumes all or some fraction of the provided buffer space, and
1060
1101
sets the HANDLER_BUFFER members accordingly.
1061
1102
The callee may use the buffer memory until the next multi_range_read_init()
1062
call is made, all records have been read, or until doEndIndexScan() call is
1103
call is made, all records have been read, or until index_end() call is
1063
1104
made, whichever comes first.
1070
1111
Cursor::multi_range_read_init(RANGE_SEQ_IF *seq_funcs, void *seq_init_param,
1071
uint32_t n_ranges, uint32_t mode)
1112
uint32_t n_ranges, uint32_t mode,
1073
1115
mrr_iter= seq_funcs->init(seq_init_param, n_ranges, mode);
1074
1116
mrr_funcs= *seq_funcs;
1075
1117
mrr_is_output_sorted= test(mode & HA_MRR_SORTED);
1076
1118
mrr_have_range= false;
1184
1225
key_compare_result_on_equal= ((end_key->flag == HA_READ_BEFORE_KEY) ? 1 :
1185
1226
(end_key->flag == HA_READ_AFTER_KEY) ? -1 : 0);
1187
range_key_part= getTable()->key_info[active_index].key_part;
1228
range_key_part= table->key_info[active_index].key_part;
1189
1230
if (!start_key) // Read first record
1190
result= index_first(getTable()->getInsertRecord());
1231
result= index_first(table->record[0]);
1192
result= index_read_map(getTable()->getInsertRecord(),
1233
result= index_read_map(table->record[0],
1193
1234
start_key->key,
1194
1235
start_key->keypart_map,
1195
1236
start_key->flag);
1305
Same as compare_key() but doesn't check have in_range_check_pushed_down.
1306
This is used by index condition pushdown implementation.
1309
int Cursor::compare_key2(key_range *range)
1313
return 0; // no max range
1314
cmp= key_cmp(range_key_part, range->key, range->length);
1316
cmp= key_compare_result_on_equal;
1262
1320
int Cursor::index_read_idx_map(unsigned char * buf, uint32_t index,
1263
1321
const unsigned char * key,
1264
1322
key_part_map keypart_map,
1265
1323
enum ha_rkey_function find_flag)
1267
1325
int error, error1;
1268
error= doStartIndexScan(index, 0);
1326
error= index_init(index, 0);
1271
1329
error= index_read_map(buf, key, keypart_map, find_flag);
1272
error1= doEndIndexScan();
1330
error1= index_end();
1274
1332
return error ? error : error1;
1285
1343
const unsigned char *before_record,
1286
1344
const unsigned char *after_record)
1288
TransactionServices &transaction_services= TransactionServices::singleton();
1346
ReplicationServices &replication_services= ReplicationServices::singleton();
1289
1347
Session *const session= table->in_use;
1291
if (table->getShare()->getType() || not transaction_services.shouldConstructMessages())
1349
if (table->s->tmp_table || ! replication_services.isActive())
1294
1352
bool result= false;
1296
1354
switch (session->lex->sql_command)
1298
case SQLCOM_CREATE_TABLE:
1300
* We are in a CREATE TABLE ... SELECT statement
1301
* and the kernel has already created the table
1302
* and put a CreateTableStatement in the active
1303
* Transaction message. Here, we add a new InsertRecord
1304
* to a new Transaction message (because the above
1305
* CREATE TABLE will commit the transaction containing
1308
result= transaction_services.insertRecord(session, table);
1310
1356
case SQLCOM_REPLACE:
1311
1357
case SQLCOM_REPLACE_SELECT:
1313
1359
* This is a total hack because of the code that is
1314
1360
* in write_record() in sql_insert.cc. During
1315
* a REPLACE statement, a call to insertRecord() is
1316
* called. If it fails, then a call to deleteRecord()
1361
* a REPLACE statement, a call to ha_write_row() is
1362
* called. If it fails, then a call to ha_delete_row()
1317
1363
* is called, followed by a repeat of the original
1318
* call to insertRecord(). So, log_row_for_replication
1319
* could be called multiple times for a REPLACE
1364
* call to ha_write_row(). So, log_row_for_replication
1365
* could be called either once or twice for a REPLACE
1320
1366
* statement. The below looks at the values of before_record
1321
1367
* and after_record to determine which call to this
1322
1368
* function is for the delete or the insert, since NULL
1330
1376
if (after_record == NULL)
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.
1337
transaction_services.deleteRecord(session, table, true);
1378
replication_services.deleteRecord(session, table);
1339
1380
* We set the "current" statement message to NULL. This triggers
1340
1381
* the replication services component to generate a new statement
1341
1382
* message for the inserted record which will come next.
1343
transaction_services.finalizeStatementMessage(*session->getStatementMessage(), session);
1384
replication_services.finalizeStatement(*session->getStatementMessage(), session);
1347
1388
if (before_record == NULL)
1348
result= transaction_services.insertRecord(session, table);
1389
result= replication_services.insertRecord(session, table);
1350
transaction_services.updateRecord(session, table, before_record, after_record);
1391
replication_services.updateRecord(session, table, before_record, after_record);
1353
1394
case SQLCOM_INSERT:
1354
1395
case SQLCOM_INSERT_SELECT:
1357
1397
* The else block below represents an
1358
1398
* INSERT ... ON DUPLICATE KEY UPDATE that
1362
1402
if (before_record == NULL)
1363
result= transaction_services.insertRecord(session, table);
1403
result= replication_services.insertRecord(session, table);
1365
transaction_services.updateRecord(session, table, before_record, after_record);
1405
replication_services.updateRecord(session, table, before_record, after_record);
1368
1408
case SQLCOM_UPDATE:
1369
transaction_services.updateRecord(session, table, before_record, after_record);
1409
replication_services.updateRecord(session, table, before_record, after_record);
1372
1412
case SQLCOM_DELETE:
1373
transaction_services.deleteRecord(session, table);
1413
replication_services.deleteRecord(session, table);
1395
1435
if (lock_type == F_RDLCK)
1397
DRIZZLE_CURSOR_RDLOCK_START(getTable()->getShare()->getSchemaName(),
1398
getTable()->getShare()->getTableName());
1437
DRIZZLE_CURSOR_RDLOCK_START(table_share->db.str,
1438
table_share->table_name.str);
1400
1440
else if (lock_type == F_WRLCK)
1402
DRIZZLE_CURSOR_WRLOCK_START(getTable()->getShare()->getSchemaName(),
1403
getTable()->getShare()->getTableName());
1442
DRIZZLE_CURSOR_WRLOCK_START(table_share->db.str,
1443
table_share->table_name.str);
1405
1445
else if (lock_type == F_UNLCK)
1407
DRIZZLE_CURSOR_UNLOCK_START(getTable()->getShare()->getSchemaName(),
1408
getTable()->getShare()->getTableName());
1447
DRIZZLE_CURSOR_UNLOCK_START(table_share->db.str,
1448
table_share->table_name.str);
1444
1484
int Cursor::ha_reset()
1446
1486
/* Check that we have called all proper deallocation functions */
1447
assert(! getTable()->getShare()->all_set.none());
1448
assert(getTable()->key_read == 0);
1449
/* ensure that ha_index_end / endTableScan has been called */
1487
assert((unsigned char*) table->def_read_set.getBitmap() +
1488
table->s->column_bitmap_size ==
1489
(unsigned char*) table->def_write_set.getBitmap());
1490
assert(table->s->all_set.isSetAll());
1491
assert(table->key_read == 0);
1492
/* ensure that ha_index_end / ha_rnd_end has been called */
1450
1493
assert(inited == NONE);
1451
1494
/* Free cache used by filesort */
1452
getTable()->free_io_cache();
1495
table->free_io_cache();
1453
1496
/* reset the bitmaps to point to defaults */
1454
getTable()->default_column_bitmaps();
1497
table->default_column_bitmaps();
1455
1498
return(reset());
1459
int Cursor::insertRecord(unsigned char *buf)
1502
int Cursor::ha_write_row(unsigned char *buf)
1466
1509
* @TODO Technically, the below two lines can be take even further out of the
1467
1510
* Cursor interface and into the fill_record() method.
1469
if (getTable()->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT)
1471
getTable()->timestamp_field->set_time();
1474
DRIZZLE_INSERT_ROW_START(getTable()->getShare()->getSchemaName(), getTable()->getShare()->getTableName());
1475
setTransactionReadWrite();
1477
if (unlikely(plugin::EventObserver::beforeInsertRecord(*getTable(), buf)))
1479
error= ER_EVENT_OBSERVER_PLUGIN;
1483
error= doInsertRecord(buf);
1484
if (unlikely(plugin::EventObserver::afterInsertRecord(*getTable(), buf, error)))
1486
error= ER_EVENT_OBSERVER_PLUGIN;
1490
ha_statistic_increment(&system_status_var::ha_write_count);
1512
if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT)
1513
table->timestamp_field->set_time();
1515
DRIZZLE_INSERT_ROW_START(table_share->db.str, table_share->table_name.str);
1516
mark_trx_read_write();
1517
error= write_row(buf);
1492
1518
DRIZZLE_INSERT_ROW_DONE(error);
1494
1520
if (unlikely(error))
1499
if (unlikely(log_row_for_replication(getTable(), NULL, buf)))
1525
if (unlikely(log_row_for_replication(table, NULL, buf)))
1500
1526
return HA_ERR_RBR_LOGGING_FAILED;
1506
int Cursor::updateRecord(const unsigned char *old_data, unsigned char *new_data)
1532
int Cursor::ha_update_row(const unsigned char *old_data, unsigned char *new_data)
1511
Some storage engines require that the new record is in getInsertRecord()
1512
(and the old record is in getUpdateRecord()).
1537
Some storage engines require that the new record is in record[0]
1538
(and the old record is in record[1]).
1514
assert(new_data == getTable()->getInsertRecord());
1516
DRIZZLE_UPDATE_ROW_START(getTable()->getShare()->getSchemaName(), getTable()->getShare()->getTableName());
1517
setTransactionReadWrite();
1518
if (unlikely(plugin::EventObserver::beforeUpdateRecord(*getTable(), old_data, new_data)))
1520
error= ER_EVENT_OBSERVER_PLUGIN;
1524
if (getTable()->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE)
1526
getTable()->timestamp_field->set_time();
1529
error= doUpdateRecord(old_data, new_data);
1530
if (unlikely(plugin::EventObserver::afterUpdateRecord(*getTable(), old_data, new_data, error)))
1532
error= ER_EVENT_OBSERVER_PLUGIN;
1536
ha_statistic_increment(&system_status_var::ha_update_count);
1540
assert(new_data == table->record[0]);
1542
DRIZZLE_UPDATE_ROW_START(table_share->db.str, table_share->table_name.str);
1543
mark_trx_read_write();
1544
error= update_row(old_data, new_data);
1538
1545
DRIZZLE_UPDATE_ROW_DONE(error);
1540
1547
if (unlikely(error))
1545
if (unlikely(log_row_for_replication(getTable(), old_data, new_data)))
1552
if (unlikely(log_row_for_replication(table, old_data, new_data)))
1546
1553
return HA_ERR_RBR_LOGGING_FAILED;
1550
TableShare *Cursor::getShare()
1552
return getTable()->getMutableShare();
1555
int Cursor::deleteRecord(const unsigned char *buf)
1558
int Cursor::ha_delete_row(const unsigned char *buf)
1559
DRIZZLE_DELETE_ROW_START(getTable()->getShare()->getSchemaName(), getTable()->getShare()->getTableName());
1560
setTransactionReadWrite();
1561
if (unlikely(plugin::EventObserver::beforeDeleteRecord(*getTable(), buf)))
1563
error= ER_EVENT_OBSERVER_PLUGIN;
1567
error= doDeleteRecord(buf);
1568
if (unlikely(plugin::EventObserver::afterDeleteRecord(*getTable(), buf, error)))
1570
error= ER_EVENT_OBSERVER_PLUGIN;
1574
ha_statistic_increment(&system_status_var::ha_delete_count);
1562
DRIZZLE_DELETE_ROW_START(table_share->db.str, table_share->table_name.str);
1563
mark_trx_read_write();
1564
error= delete_row(buf);
1576
1565
DRIZZLE_DELETE_ROW_DONE(error);
1578
1567
if (unlikely(error))
1581
if (unlikely(log_row_for_replication(getTable(), buf, NULL)))
1570
if (unlikely(log_row_for_replication(table, buf, NULL)))
1582
1571
return HA_ERR_RBR_LOGGING_FAILED;