32
32
#include "drizzled/gettext.h"
33
33
#include "drizzled/probes.h"
34
34
#include "drizzled/sql_parse.h"
35
#include "drizzled/cost_vect.h"
35
#include "drizzled/optimizer/cost_vector.h"
36
36
#include "drizzled/session.h"
37
37
#include "drizzled/sql_base.h"
38
#include "drizzled/replication_services.h"
38
#include "drizzled/transaction_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,
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),
60
estimation_rows_to_insert(0),
61
62
key_used_on_scan(MAX_KEY), active_index(MAX_KEY),
62
63
ref_length(sizeof(internal::my_off_t)),
64
locked(false), implicit_emptied(0),
65
66
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
75
81
Cursor *Cursor::clone(memory::Root *mem_root)
77
Cursor *new_handler= table->s->db_type()->getCursor(*table->s, mem_root);
83
Cursor *new_handler= getTable()->getMutableShare()->db_type()->getCursor(*getTable());
80
86
Allocate Cursor->ref here because otherwise ha_open will allocate it
81
87
on this->table->mem_root and we will not be able to reclaim that memory
82
88
when the clone Cursor object is destroyed.
84
if (!(new_handler->ref= (unsigned char*) alloc_root(mem_root, ALIGN_SIZE(ref_length)*2)))
90
if (!(new_handler->ref= (unsigned char*) mem_root->alloc_root(ALIGN_SIZE(ref_length)*2)))
86
if (new_handler && !new_handler->ha_open(table,
87
table->s->normalized_path.str,
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(),
89
99
HA_OPEN_IGNORE_IF_LOCKED))
90
100
return new_handler;
94
int Cursor::ha_index_init(uint32_t idx, bool sorted)
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)
97
130
assert(inited == NONE);
98
if (!(result= index_init(idx, sorted)))
131
if (!(result= doStartIndexScan(idx, sorted)))
104
int Cursor::ha_index_end()
137
int Cursor::endIndexScan()
106
139
assert(inited==INDEX);
142
return(doEndIndexScan());
112
int Cursor::ha_rnd_init(bool scan)
145
int Cursor::startTableScan(bool scan)
115
148
assert(inited==NONE || (inited==RND && scan));
116
inited= (result= rnd_init(scan)) ? NONE: RND;
149
inited= (result= doStartTableScan(scan)) ? NONE: RND;
121
int Cursor::ha_rnd_end()
154
int Cursor::endTableScan()
123
156
assert(inited==RND);
158
return(doEndTableScan());
128
161
int Cursor::ha_index_or_rnd_end()
130
return inited == INDEX ? ha_index_end() : inited == RND ? ha_rnd_end() : 0;
163
return inited == INDEX ? endIndexScan() : inited == RND ? endTableScan() : 0;
133
166
void Cursor::ha_start_bulk_insert(ha_rows rows)
156
183
bool Cursor::has_transactions()
158
return (table->s->db_type()->check_flag(HTON_BIT_DOES_TRANSACTIONS));
185
return (getTable()->getShare()->db_type()->check_flag(HTON_BIT_DOES_TRANSACTIONS));
161
void Cursor::ha_statistic_increment(ulong system_status_var::*offset) const
188
void Cursor::ha_statistic_increment(uint64_t system_status_var::*offset) const
163
status_var_increment(table->in_use->status_var.*offset);
190
(getTable()->in_use->status_var.*offset)++;
166
193
void **Cursor::ha_data(Session *session) const
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;
195
return session->getEngineData(getEngine());
178
198
bool Cursor::is_fatal_error(int error, uint32_t flags)
189
209
ha_rows Cursor::records() { return stats.records; }
190
210
uint64_t Cursor::tableSize() { return stats.index_file_length + stats.data_file_length; }
191
uint64_t Cursor::rowSize() { return table->getRecordLength() + table->sizeFields(); }
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);
194
219
Open database-Cursor.
196
221
Try O_RDONLY if cannot open as O_RDWR
197
222
Don't wait for locks if not HA_OPEN_WAIT_IF_LOCKED is set
199
int Cursor::ha_open(Table *table_arg, const char *name, int mode,
224
int Cursor::ha_open(const TableIdentifier &identifier,
205
assert(table->s == table_share);
206
assert(alloc_root_inited(&table->mem_root));
208
if ((error=open(name,mode,test_if_locked)))
230
if ((error= doOpen(identifier, mode, test_if_locked)))
210
232
if ((error == EACCES || error == EROFS) && mode == O_RDWR &&
211
(table->db_stat & HA_TRY_READ_ONLY))
233
(getTable()->db_stat & HA_TRY_READ_ONLY))
213
table->db_stat|=HA_READ_ONLY;
214
error=open(name,O_RDONLY,test_if_locked);
235
getTable()->db_stat|=HA_READ_ONLY;
236
error= doOpen(identifier, O_RDONLY,test_if_locked);
223
if (table->s->db_options_in_use & HA_OPTION_READ_ONLY_DATA)
224
table->db_stat|=HA_READ_ONLY;
245
if (getTable()->getShare()->db_options_in_use & HA_OPTION_READ_ONLY_DATA)
246
getTable()->db_stat|=HA_READ_ONLY;
225
247
(void) extra(HA_EXTRA_NO_READCHECK); // Not needed in SQL
227
249
/* ref is already allocated for us if we're called from Cursor::clone() */
228
if (!ref && !(ref= (unsigned char*) alloc_root(&table->mem_root,
229
ALIGN_SIZE(ref_length)*2)))
250
if (!ref && !(ref= (unsigned char*) getTable()->alloc_root(ALIGN_SIZE(ref_length)*2)))
232
253
error=HA_ERR_OUT_OF_MEM;
241
one has to use this method when to find
242
random position by record as the plain
243
position() call doesn't work for some
244
handlers for random position
247
int Cursor::rnd_pos_by_record(unsigned char *record)
252
if (inited && (error= ha_index_end()))
254
if ((error= ha_rnd_init(false)))
257
return rnd_pos(record, ref);
261
262
Read first row (only) from a table.
263
264
This is never called for InnoDB tables, as these table types
275
276
TODO remove the test for HA_READ_ORDER
277
278
if (stats.deleted < 10 || primary_key >= MAX_KEY ||
278
!(table->index_flags(primary_key) & HA_READ_ORDER))
279
!(getTable()->index_flags(primary_key) & HA_READ_ORDER))
280
(void) ha_rnd_init(1);
281
(void) startTableScan(1);
281
282
while ((error= rnd_next(buf)) == HA_ERR_RECORD_DELETED) ;
283
(void) endTableScan();
286
287
/* Find the first row through the primary key */
287
(void) ha_index_init(primary_key, 0);
288
(void) startIndexScan(primary_key, 0);
288
289
error=index_first(buf);
289
(void) ha_index_end();
290
(void) endIndexScan();
303
304
@verbatim 1,5,15,25,35,... @endverbatim
306
compute_next_insert_id(uint64_t nr,struct system_variables *variables)
307
compute_next_insert_id(uint64_t nr, drizzle_system_variables *variables)
308
309
if (variables->auto_increment_increment == 1)
309
310
return (nr+1); // optimization of the formula below
453
454
for an auto increment column, not a magic value like NULL is.
454
455
same as sql_mode=NO_AUTO_VALUE_ON_ZERO */
456
if ((nr= table->next_number_field->val_int()) != 0
457
|| table->auto_increment_field_not_null)
457
if ((nr= getTable()->next_number_field->val_int()) != 0
458
|| getTable()->auto_increment_field_not_null)
460
461
Update next_insert_id if we had already generated a value in this
532
533
nr= compute_next_insert_id(nr-1, variables);
535
if (table->s->next_number_keypart == 0)
536
if (getTable()->getShare()->next_number_keypart == 0)
537
538
/* We must defer the appending until "nr" has been possibly truncated */
542
if (unlikely(table->next_number_field->store((int64_t) nr, true)))
543
if (unlikely(getTable()->next_number_field->store((int64_t) nr, true)))
545
546
first test if the query was aborted due to strict mode constraints
547
if (session->killed == Session::KILL_BAD_DATA)
548
if (session->getKilled() == Session::KILL_BAD_DATA)
548
549
return HA_ERR_AUTOINC_ERANGE;
555
556
bother shifting the right bound (anyway any other value from this
556
557
interval will cause a duplicate key).
558
nr= prev_insert_id(table->next_number_field->val_int(), variables);
559
if (unlikely(table->next_number_field->store((int64_t) nr, true)))
560
nr= table->next_number_field->val_int();
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();
598
599
@param first_value (OUT) the first value reserved by the Cursor
599
600
@param nb_reserved_values (OUT) how many values the Cursor reserved
601
void Cursor::get_auto_increment(uint64_t ,
604
uint64_t *first_value,
605
uint64_t *nb_reserved_values)
610
(void) extra(HA_EXTRA_KEYREAD);
611
table->mark_columns_used_by_index_no_reset(table->s->next_number_index);
612
index_init(table->s->next_number_index, 1);
613
if (table->s->next_number_keypart == 0)
614
{ // Autoincrement at key-start
615
error=index_last(table->record[1]);
617
MySQL implicitely assumes such method does locking (as MySQL decides to
618
use nr+increment without checking again with the Cursor, in
619
Cursor::update_auto_increment()), so reserves to infinite.
621
*nb_reserved_values= UINT64_MAX;
625
unsigned char key[MAX_KEY_LENGTH];
626
key_copy(key, table->record[0],
627
table->key_info + table->s->next_number_index,
628
table->s->next_number_key_offset);
629
error= index_read_map(table->record[1], key,
630
make_prev_keypart_map(table->s->next_number_keypart),
631
HA_READ_PREFIX_LAST);
633
MySQL needs to call us for next row: assume we are inserting ("a",null)
634
here, we return 3, and next this statement will want to insert
635
("b",null): there is no reason why ("b",3+1) would be the good row to
636
insert: maybe it already exists, maybe 3+1 is too large...
638
*nb_reserved_values= 1;
644
nr= ((uint64_t) table->next_number_field->
645
val_int_offset(table->s->rec_buff_length)+1);
647
(void) extra(HA_EXTRA_NO_KEYREAD);
652
603
void Cursor::ha_release_auto_increment()
701
652
Cursor::setTransactionReadWrite()
703
ResourceContext *resource_context= ha_session()->getResourceContext(engine);
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());
705
666
When a storage engine method is called, the transaction must
706
667
have been started, unless it's a DDL call, for which the
739
700
* Trigger post-truncate notification to plugins...
741
* @todo Make ReplicationServices generic to AfterTriggerServices
702
* @todo Make TransactionServices generic to AfterTriggerServices
744
Session *const session= table->in_use;
745
ReplicationServices &replication_services= ReplicationServices::singleton();
746
replication_services.truncateTable(session, table);
705
Session *const session= getTable()->in_use;
706
TransactionServices &transaction_services= TransactionServices::singleton();
707
transaction_services.truncateTable(session, getTable());
843
804
if (!(error=index_next(buf)))
845
ptrdiff_t ptrdiff= buf - table->record[0];
806
ptrdiff_t ptrdiff= buf - getTable()->getInsertRecord();
846
807
unsigned char *save_record_0= NULL;
848
KEY_PART_INFO *key_part;
849
KEY_PART_INFO *key_part_end= NULL;
808
KeyInfo *key_info= NULL;
809
KeyPartInfo *key_part;
810
KeyPartInfo *key_part_end= NULL;
852
key_cmp_if_same() compares table->record[0] against 'key'.
853
In parts it uses table->record[0] directly, in parts it uses
854
field objects with their local pointers into table->record[0].
855
If 'buf' is distinct from table->record[0], we need to move
856
all record references. This is table->record[0] itself and
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
857
818
the field pointers of the fields used in this key.
861
save_record_0= table->record[0];
862
table->record[0]= buf;
863
key_info= table->key_info + active_index;
822
save_record_0= getTable()->getInsertRecord();
823
getTable()->record[0]= buf;
824
key_info= getTable()->key_info + active_index;
864
825
key_part= key_info->key_part;
865
826
key_part_end= key_part + key_info->key_parts;
866
827
for (; key_part < key_part_end; key_part++)
873
if (key_cmp_if_same(table, key, active_index, keylen))
834
if (key_cmp_if_same(getTable(), key, active_index, keylen))
875
table->status=STATUS_NOT_FOUND;
836
getTable()->status=STATUS_NOT_FOUND;
876
837
error=HA_ERR_END_OF_FILE;
879
840
/* Move back if necessary. */
882
table->record[0]= save_record_0;
843
getTable()->record[0]= save_record_0;
883
844
for (key_part= key_info->key_part; key_part < key_part_end; key_part++)
884
845
key_part->field->move_field_offset(-ptrdiff);
961
922
Cursor::multi_range_read_info_const(uint32_t keyno, RANGE_SEQ_IF *seq,
962
923
void *seq_init_param,
964
uint32_t *bufsz, uint32_t *flags, COST_VECT *cost)
925
uint32_t *bufsz, uint32_t *flags, optimizer::CostVector *cost)
966
927
KEY_MULTI_RANGE range;
967
928
range_seq_t seq_it;
968
929
ha_rows rows, total_rows= 0;
969
930
uint32_t n_ranges=0;
970
Session *session= current_session;
972
932
/* Default MRR implementation doesn't need buffer */
1004
961
/* The following calculation is the same as in multi_range_read_info(): */
1005
962
*flags |= HA_MRR_USE_DEFAULT_IMPL;
1007
cost->avg_io_cost= 1; /* assume random seeks */
964
cost->setAvgIOCost(1); /* assume random seeks */
1008
965
if ((*flags & HA_MRR_INDEX_ONLY) && total_rows > 2)
1009
cost->io_count= index_only_read_time(keyno, (uint32_t)total_rows);
966
cost->setIOCount(index_only_read_time(keyno, (uint32_t)total_rows));
1011
cost->io_count= read_time(keyno, n_ranges, total_rows);
1012
cost->cpu_cost= (double) total_rows / TIME_FOR_COMPARE + 0.01;
968
cost->setIOCount(read_time(keyno, n_ranges, total_rows));
969
cost->setCpuCost((double) total_rows / TIME_FOR_COMPARE + 0.01);
1014
971
return total_rows;
1052
1009
int Cursor::multi_range_read_info(uint32_t keyno, uint32_t n_ranges, uint32_t n_rows,
1053
uint32_t *bufsz, uint32_t *flags, COST_VECT *cost)
1010
uint32_t *bufsz, uint32_t *flags, optimizer::CostVector *cost)
1055
1012
*bufsz= 0; /* Default implementation doesn't need a buffer */
1057
1014
*flags |= HA_MRR_USE_DEFAULT_IMPL;
1060
cost->avg_io_cost= 1; /* assume random seeks */
1017
cost->setAvgIOCost(1); /* assume random seeks */
1062
1019
/* Produce the same cost as non-MRR code does */
1063
1020
if (*flags & HA_MRR_INDEX_ONLY)
1064
cost->io_count= index_only_read_time(keyno, n_rows);
1021
cost->setIOCount(index_only_read_time(keyno, n_rows));
1066
cost->io_count= read_time(keyno, n_ranges, n_rows);
1023
cost->setIOCount(read_time(keyno, n_ranges, n_rows));
1102
1059
The callee consumes all or some fraction of the provided buffer space, and
1103
1060
sets the HANDLER_BUFFER members accordingly.
1104
1061
The callee may use the buffer memory until the next multi_range_read_init()
1105
call is made, all records have been read, or until index_end() call is
1062
call is made, all records have been read, or until doEndIndexScan() call is
1106
1063
made, whichever comes first.
1113
1070
Cursor::multi_range_read_init(RANGE_SEQ_IF *seq_funcs, void *seq_init_param,
1114
uint32_t n_ranges, uint32_t mode,
1071
uint32_t n_ranges, uint32_t mode)
1117
1073
mrr_iter= seq_funcs->init(seq_init_param, n_ranges, mode);
1118
1074
mrr_funcs= *seq_funcs;
1119
1075
mrr_is_output_sorted= test(mode & HA_MRR_SORTED);
1120
1076
mrr_have_range= false;
1227
1184
key_compare_result_on_equal= ((end_key->flag == HA_READ_BEFORE_KEY) ? 1 :
1228
1185
(end_key->flag == HA_READ_AFTER_KEY) ? -1 : 0);
1230
range_key_part= table->key_info[active_index].key_part;
1187
range_key_part= getTable()->key_info[active_index].key_part;
1232
1189
if (!start_key) // Read first record
1233
result= index_first(table->record[0]);
1190
result= index_first(getTable()->getInsertRecord());
1235
result= index_read_map(table->record[0],
1192
result= index_read_map(getTable()->getInsertRecord(),
1236
1193
start_key->key,
1237
1194
start_key->keypart_map,
1238
1195
start_key->flag);
1307
Same as compare_key() but doesn't check have in_range_check_pushed_down.
1308
This is used by index condition pushdown implementation.
1311
int Cursor::compare_key2(key_range *range)
1315
return 0; // no max range
1316
cmp= key_cmp(range_key_part, range->key, range->length);
1318
cmp= key_compare_result_on_equal;
1322
1262
int Cursor::index_read_idx_map(unsigned char * buf, uint32_t index,
1323
1263
const unsigned char * key,
1324
1264
key_part_map keypart_map,
1325
1265
enum ha_rkey_function find_flag)
1327
1267
int error, error1;
1328
error= index_init(index, 0);
1268
error= doStartIndexScan(index, 0);
1331
1271
error= index_read_map(buf, key, keypart_map, find_flag);
1332
error1= index_end();
1272
error1= doEndIndexScan();
1334
1274
return error ? error : error1;
1345
1285
const unsigned char *before_record,
1346
1286
const unsigned char *after_record)
1348
ReplicationServices &replication_services= ReplicationServices::singleton();
1288
TransactionServices &transaction_services= TransactionServices::singleton();
1349
1289
Session *const session= table->in_use;
1351
if (table->s->tmp_table || ! replication_services.isActive())
1291
if (table->getShare()->getType() || not transaction_services.shouldConstructMessages())
1354
1294
bool result= false;
1365
1305
* CREATE TABLE will commit the transaction containing
1368
result= replication_services.insertRecord(session, table);
1308
result= transaction_services.insertRecord(session, table);
1370
1310
case SQLCOM_REPLACE:
1371
1311
case SQLCOM_REPLACE_SELECT:
1373
1313
* This is a total hack because of the code that is
1374
1314
* in write_record() in sql_insert.cc. During
1375
* a REPLACE statement, a call to ha_write_row() is
1376
* called. If it fails, then a call to ha_delete_row()
1315
* a REPLACE statement, a call to insertRecord() is
1316
* called. If it fails, then a call to deleteRecord()
1377
1317
* is called, followed by a repeat of the original
1378
* call to ha_write_row(). So, log_row_for_replication
1379
* could be called either once or twice for a REPLACE
1318
* call to insertRecord(). So, log_row_for_replication
1319
* could be called multiple times for a REPLACE
1380
1320
* statement. The below looks at the values of before_record
1381
1321
* and after_record to determine which call to this
1382
1322
* function is for the delete or the insert, since NULL
1390
1330
if (after_record == NULL)
1392
replication_services.deleteRecord(session, table);
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);
1394
1339
* We set the "current" statement message to NULL. This triggers
1395
1340
* the replication services component to generate a new statement
1396
1341
* message for the inserted record which will come next.
1398
replication_services.finalizeStatement(*session->getStatementMessage(), session);
1343
transaction_services.finalizeStatementMessage(*session->getStatementMessage(), session);
1402
1347
if (before_record == NULL)
1403
result= replication_services.insertRecord(session, table);
1348
result= transaction_services.insertRecord(session, table);
1405
replication_services.updateRecord(session, table, before_record, after_record);
1350
transaction_services.updateRecord(session, table, before_record, after_record);
1408
1353
case SQLCOM_INSERT:
1409
1354
case SQLCOM_INSERT_SELECT:
1411
1357
* The else block below represents an
1412
1358
* INSERT ... ON DUPLICATE KEY UPDATE that
1416
1362
if (before_record == NULL)
1417
result= replication_services.insertRecord(session, table);
1363
result= transaction_services.insertRecord(session, table);
1419
replication_services.updateRecord(session, table, before_record, after_record);
1365
transaction_services.updateRecord(session, table, before_record, after_record);
1422
1368
case SQLCOM_UPDATE:
1423
replication_services.updateRecord(session, table, before_record, after_record);
1369
transaction_services.updateRecord(session, table, before_record, after_record);
1426
1372
case SQLCOM_DELETE:
1427
replication_services.deleteRecord(session, table);
1373
transaction_services.deleteRecord(session, table);
1449
1395
if (lock_type == F_RDLCK)
1451
DRIZZLE_CURSOR_RDLOCK_START(table_share->db.str,
1452
table_share->table_name.str);
1397
DRIZZLE_CURSOR_RDLOCK_START(getTable()->getShare()->getSchemaName(),
1398
getTable()->getShare()->getTableName());
1454
1400
else if (lock_type == F_WRLCK)
1456
DRIZZLE_CURSOR_WRLOCK_START(table_share->db.str,
1457
table_share->table_name.str);
1402
DRIZZLE_CURSOR_WRLOCK_START(getTable()->getShare()->getSchemaName(),
1403
getTable()->getShare()->getTableName());
1459
1405
else if (lock_type == F_UNLCK)
1461
DRIZZLE_CURSOR_UNLOCK_START(table_share->db.str,
1462
table_share->table_name.str);
1407
DRIZZLE_CURSOR_UNLOCK_START(getTable()->getShare()->getSchemaName(),
1408
getTable()->getShare()->getTableName());
1498
1444
int Cursor::ha_reset()
1500
1446
/* Check that we have called all proper deallocation functions */
1501
assert((unsigned char*) table->def_read_set.getBitmap() +
1502
table->s->column_bitmap_size ==
1503
(unsigned char*) table->def_write_set.getBitmap());
1504
assert(table->s->all_set.isSetAll());
1505
assert(table->key_read == 0);
1506
/* ensure that ha_index_end / ha_rnd_end has been called */
1447
assert(! getTable()->getShare()->all_set.none());
1448
assert(getTable()->key_read == 0);
1449
/* ensure that ha_index_end / endTableScan has been called */
1507
1450
assert(inited == NONE);
1508
1451
/* Free cache used by filesort */
1509
table->free_io_cache();
1452
getTable()->free_io_cache();
1510
1453
/* reset the bitmaps to point to defaults */
1511
table->default_column_bitmaps();
1454
getTable()->default_column_bitmaps();
1512
1455
return(reset());
1516
int Cursor::ha_write_row(unsigned char *buf)
1459
int Cursor::insertRecord(unsigned char *buf)
1523
1466
* @TODO Technically, the below two lines can be take even further out of the
1524
1467
* Cursor interface and into the fill_record() method.
1526
if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT)
1527
table->timestamp_field->set_time();
1469
if (getTable()->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT)
1471
getTable()->timestamp_field->set_time();
1529
DRIZZLE_INSERT_ROW_START(table_share->db.str, table_share->table_name.str);
1474
DRIZZLE_INSERT_ROW_START(getTable()->getShare()->getSchemaName(), getTable()->getShare()->getTableName());
1530
1475
setTransactionReadWrite();
1531
error= write_row(buf);
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);
1532
1492
DRIZZLE_INSERT_ROW_DONE(error);
1534
1494
if (unlikely(error))
1539
if (unlikely(log_row_for_replication(table, NULL, buf)))
1499
if (unlikely(log_row_for_replication(getTable(), NULL, buf)))
1540
1500
return HA_ERR_RBR_LOGGING_FAILED;
1546
int Cursor::ha_update_row(const unsigned char *old_data, unsigned char *new_data)
1506
int Cursor::updateRecord(const unsigned char *old_data, unsigned char *new_data)
1551
Some storage engines require that the new record is in record[0]
1552
(and the old record is in record[1]).
1511
Some storage engines require that the new record is in getInsertRecord()
1512
(and the old record is in getUpdateRecord()).
1554
assert(new_data == table->record[0]);
1514
assert(new_data == getTable()->getInsertRecord());
1556
DRIZZLE_UPDATE_ROW_START(table_share->db.str, table_share->table_name.str);
1516
DRIZZLE_UPDATE_ROW_START(getTable()->getShare()->getSchemaName(), getTable()->getShare()->getTableName());
1557
1517
setTransactionReadWrite();
1558
error= update_row(old_data, new_data);
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);
1559
1538
DRIZZLE_UPDATE_ROW_DONE(error);
1561
1540
if (unlikely(error))
1566
if (unlikely(log_row_for_replication(table, old_data, new_data)))
1545
if (unlikely(log_row_for_replication(getTable(), old_data, new_data)))
1567
1546
return HA_ERR_RBR_LOGGING_FAILED;
1550
TableShare *Cursor::getShare()
1552
return getTable()->getMutableShare();
1572
int Cursor::ha_delete_row(const unsigned char *buf)
1555
int Cursor::deleteRecord(const unsigned char *buf)
1576
DRIZZLE_DELETE_ROW_START(table_share->db.str, table_share->table_name.str);
1559
DRIZZLE_DELETE_ROW_START(getTable()->getShare()->getSchemaName(), getTable()->getShare()->getTableName());
1577
1560
setTransactionReadWrite();
1578
error= delete_row(buf);
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);
1579
1576
DRIZZLE_DELETE_ROW_DONE(error);
1581
1578
if (unlikely(error))
1584
if (unlikely(log_row_for_replication(table, buf, NULL)))
1581
if (unlikely(log_row_for_replication(getTable(), buf, NULL)))
1585
1582
return HA_ERR_RBR_LOGGING_FAILED;