58
57
TableShare &share_arg)
59
58
: table_share(&share_arg), table(0),
60
59
estimation_rows_to_insert(0), engine(&engine_arg),
61
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)),
65
locked(false), implicit_emptied(0),
66
65
next_insert_id(0), insert_id_for_cur_row(0)
76
* @note this only used in
77
* optimizer::QuickRangeSelect::init_ror_merged_scan(bool reuse_handler) as
78
* of the writing of this comment. -Brian
76
80
Cursor *Cursor::clone(memory::Root *mem_root)
78
Cursor *new_handler= table->s->db_type()->getCursor(*table->s, mem_root);
82
Cursor *new_handler= table->getMutableShare()->db_type()->getCursor(*table->getMutableShare(), mem_root);
81
85
Allocate Cursor->ref here because otherwise ha_open will allocate it
82
86
on this->table->mem_root and we will not be able to reclaim that memory
83
87
when the clone Cursor object is destroyed.
85
if (!(new_handler->ref= (unsigned char*) alloc_root(mem_root, ALIGN_SIZE(ref_length)*2)))
89
if (!(new_handler->ref= (unsigned char*) mem_root->alloc_root(ALIGN_SIZE(ref_length)*2)))
87
if (new_handler && !new_handler->ha_open(table,
88
table->s->normalized_path.str,
92
TableIdentifier identifier(table->getShare()->getSchemaName(),
93
table->getShare()->getTableName(),
94
table->getShare()->getType());
96
if (new_handler && !new_handler->ha_open(identifier,
98
table->getMutableShare()->getNormalizedPath(),
89
99
table->getDBStat(),
90
100
HA_OPEN_IGNORE_IF_LOCKED))
91
101
return new_handler;
95
int Cursor::ha_index_init(uint32_t idx, bool sorted)
107
given a buffer with a key value, and a map of keyparts
108
that are present in this value, returns the length of the value
110
uint32_t Cursor::calculate_key_len(uint32_t key_position, key_part_map keypart_map_arg)
112
/* works only with key prefixes */
113
assert(((keypart_map_arg + 1) & keypart_map_arg) == 0);
115
const KeyPartInfo *key_part_found= table->getShare()->getKeyInfo(key_position).key_part;
116
const KeyPartInfo *end_key_part_found= key_part_found + table->getShare()->getKeyInfo(key_position).key_parts;
119
while (key_part_found < end_key_part_found && keypart_map_arg)
121
length+= key_part_found->store_length;
122
keypart_map_arg >>= 1;
128
int Cursor::startIndexScan(uint32_t idx, bool sorted)
98
131
assert(inited == NONE);
99
if (!(result= index_init(idx, sorted)))
132
if (!(result= doStartIndexScan(idx, sorted)))
105
int Cursor::ha_index_end()
138
int Cursor::endIndexScan()
107
140
assert(inited==INDEX);
143
return(doEndIndexScan());
113
int Cursor::ha_rnd_init(bool scan)
146
int Cursor::startTableScan(bool scan)
116
149
assert(inited==NONE || (inited==RND && scan));
117
inited= (result= rnd_init(scan)) ? NONE: RND;
150
inited= (result= doStartTableScan(scan)) ? NONE: RND;
122
int Cursor::ha_rnd_end()
155
int Cursor::endTableScan()
124
157
assert(inited==RND);
159
return(doEndTableScan());
129
162
int Cursor::ha_index_or_rnd_end()
131
return inited == INDEX ? ha_index_end() : inited == RND ? ha_rnd_end() : 0;
164
return inited == INDEX ? endIndexScan() : inited == RND ? endTableScan() : 0;
134
167
void Cursor::ha_start_bulk_insert(ha_rows rows)
191
217
uint64_t Cursor::tableSize() { return stats.index_file_length + stats.data_file_length; }
192
218
uint64_t Cursor::rowSize() { return table->getRecordLength() + table->sizeFields(); }
220
int Cursor::doOpen(const TableIdentifier &identifier, int mode, uint32_t test_if_locked)
222
return open(identifier.getPath().c_str(), mode, test_if_locked);
195
226
Open database-Cursor.
197
228
Try O_RDONLY if cannot open as O_RDWR
198
229
Don't wait for locks if not HA_OPEN_WAIT_IF_LOCKED is set
200
int Cursor::ha_open(Table *table_arg, const char *name, int mode,
231
int Cursor::ha_open(const TableIdentifier &identifier,
232
Table *table_arg, const char *name, int mode,
205
237
table= table_arg;
206
assert(table->s == table_share);
207
assert(alloc_root_inited(&table->mem_root));
238
assert(table->getShare() == table_share);
209
if ((error=open(name, mode, test_if_locked)))
240
assert(identifier.getPath().compare(name) == 0);
241
if ((error= doOpen(identifier, mode, test_if_locked)))
211
243
if ((error == EACCES || error == EROFS) && mode == O_RDWR &&
212
244
(table->db_stat & HA_TRY_READ_ONLY))
214
246
table->db_stat|=HA_READ_ONLY;
215
error=open(name,O_RDONLY,test_if_locked);
247
error= doOpen(identifier, O_RDONLY,test_if_locked);
224
if (table->s->db_options_in_use & HA_OPTION_READ_ONLY_DATA)
256
if (table->getShare()->db_options_in_use & HA_OPTION_READ_ONLY_DATA)
225
257
table->db_stat|=HA_READ_ONLY;
226
258
(void) extra(HA_EXTRA_NO_READCHECK); // Not needed in SQL
228
260
/* ref is already allocated for us if we're called from Cursor::clone() */
229
if (!ref && !(ref= (unsigned char*) alloc_root(&table->mem_root,
230
ALIGN_SIZE(ref_length)*2)))
261
if (!ref && !(ref= (unsigned char*) table->alloc_root(ALIGN_SIZE(ref_length)*2)))
233
264
error=HA_ERR_OUT_OF_MEM;
242
one has to use this method when to find
243
random position by record as the plain
244
position() call doesn't work for some
245
handlers for random position
248
int Cursor::rnd_pos_by_record(unsigned char *record)
253
if (inited && (error= ha_index_end()))
255
if ((error= ha_rnd_init(false)))
258
return rnd_pos(record, ref);
262
273
Read first row (only) from a table.
264
275
This is never called for InnoDB tables, as these table types
278
289
if (stats.deleted < 10 || primary_key >= MAX_KEY ||
279
290
!(table->index_flags(primary_key) & HA_READ_ORDER))
281
(void) ha_rnd_init(1);
292
(void) startTableScan(1);
282
293
while ((error= rnd_next(buf)) == HA_ERR_RECORD_DELETED) ;
294
(void) endTableScan();
287
298
/* Find the first row through the primary key */
288
(void) ha_index_init(primary_key, 0);
299
(void) startIndexScan(primary_key, 0);
289
300
error=index_first(buf);
290
(void) ha_index_end();
301
(void) endIndexScan();
652
663
Cursor::setTransactionReadWrite()
654
ResourceContext *resource_context= ha_session()->getResourceContext(engine);
665
ResourceContext *resource_context;
668
* If the cursor has not context for execution then there should be no
669
* possible resource to gain (and if there is... then there is a bug such
670
* that in_use should have been set.
672
if (not table || not table->in_use)
675
resource_context= table->in_use->getResourceContext(engine);
656
677
When a storage engine method is called, the transaction must
657
678
have been started, unless it's a DDL call, for which the
1053
1070
The callee consumes all or some fraction of the provided buffer space, and
1054
1071
sets the HANDLER_BUFFER members accordingly.
1055
1072
The callee may use the buffer memory until the next multi_range_read_init()
1056
call is made, all records have been read, or until index_end() call is
1073
call is made, all records have been read, or until doEndIndexScan() call is
1057
1074
made, whichever comes first.
1064
1081
Cursor::multi_range_read_init(RANGE_SEQ_IF *seq_funcs, void *seq_init_param,
1065
uint32_t n_ranges, uint32_t mode,
1082
uint32_t n_ranges, uint32_t mode)
1068
1084
mrr_iter= seq_funcs->init(seq_init_param, n_ranges, mode);
1069
1085
mrr_funcs= *seq_funcs;
1070
1086
mrr_is_output_sorted= test(mode & HA_MRR_SORTED);
1071
1087
mrr_have_range= false;
1258
Same as compare_key() but doesn't check have in_range_check_pushed_down.
1259
This is used by index condition pushdown implementation.
1262
int Cursor::compare_key2(key_range *range)
1266
return 0; // no max range
1267
cmp= key_cmp(range_key_part, range->key, range->length);
1269
cmp= key_compare_result_on_equal;
1273
1273
int Cursor::index_read_idx_map(unsigned char * buf, uint32_t index,
1274
1274
const unsigned char * key,
1275
1275
key_part_map keypart_map,
1276
1276
enum ha_rkey_function find_flag)
1278
1278
int error, error1;
1279
error= index_init(index, 0);
1279
error= doStartIndexScan(index, 0);
1282
1282
error= index_read_map(buf, key, keypart_map, find_flag);
1283
error1= index_end();
1283
error1= doEndIndexScan();
1285
1285
return error ? error : error1;
1325
1324
* This is a total hack because of the code that is
1326
1325
* in write_record() in sql_insert.cc. During
1327
* a REPLACE statement, a call to ha_write_row() is
1328
* called. If it fails, then a call to ha_delete_row()
1326
* a REPLACE statement, a call to insertRecord() is
1327
* called. If it fails, then a call to deleteRecord()
1329
1328
* is called, followed by a repeat of the original
1330
* call to ha_write_row(). So, log_row_for_replication
1329
* call to insertRecord(). So, log_row_for_replication
1331
1330
* could be called either once or twice for a REPLACE
1332
1331
* statement. The below looks at the values of before_record
1333
1332
* and after_record to determine which call to this
1452
1451
/* Check that we have called all proper deallocation functions */
1453
1452
assert((unsigned char*) table->def_read_set.getBitmap() +
1454
table->s->column_bitmap_size ==
1453
table->getShare()->column_bitmap_size ==
1455
1454
(unsigned char*) table->def_write_set.getBitmap());
1456
assert(table->s->all_set.isSetAll());
1455
assert(table->getShare()->all_set.isSetAll());
1457
1456
assert(table->key_read == 0);
1458
/* ensure that ha_index_end / ha_rnd_end has been called */
1457
/* ensure that ha_index_end / endTableScan has been called */
1459
1458
assert(inited == NONE);
1460
1459
/* Free cache used by filesort */
1461
1460
table->free_io_cache();
1476
1475
* Cursor interface and into the fill_record() method.
1478
1477
if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT)
1479
1479
table->timestamp_field->set_time();
1481
1482
DRIZZLE_INSERT_ROW_START(table_share->getSchemaName(), table_share->getTableName());
1482
1483
setTransactionReadWrite();
1483
error= write_row(buf);
1485
if (unlikely(plugin::EventObserver::beforeInsertRecord(*table, buf)))
1487
error= ER_EVENT_OBSERVER_PLUGIN;
1491
error= doInsertRecord(buf);
1492
if (unlikely(plugin::EventObserver::afterInsertRecord(*table, buf, error)))
1494
error= ER_EVENT_OBSERVER_PLUGIN;
1498
ha_statistic_increment(&system_status_var::ha_write_count);
1484
1500
DRIZZLE_INSERT_ROW_DONE(error);
1486
1502
if (unlikely(error))
1508
1524
DRIZZLE_UPDATE_ROW_START(table_share->getSchemaName(), table_share->getTableName());
1509
1525
setTransactionReadWrite();
1510
error= update_row(old_data, new_data);
1526
if (unlikely(plugin::EventObserver::beforeUpdateRecord(*table, old_data, new_data)))
1528
error= ER_EVENT_OBSERVER_PLUGIN;
1532
if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE)
1534
table->timestamp_field->set_time();
1537
error= doUpdateRecord(old_data, new_data);
1538
if (unlikely(plugin::EventObserver::afterUpdateRecord(*table, old_data, new_data, error)))
1540
error= ER_EVENT_OBSERVER_PLUGIN;
1544
ha_statistic_increment(&system_status_var::ha_update_count);
1511
1546
DRIZZLE_UPDATE_ROW_DONE(error);
1513
1548
if (unlikely(error))
1524
int Cursor::ha_delete_row(const unsigned char *buf)
1559
int Cursor::deleteRecord(const unsigned char *buf)
1528
1563
DRIZZLE_DELETE_ROW_START(table_share->getSchemaName(), table_share->getTableName());
1529
1564
setTransactionReadWrite();
1530
error= delete_row(buf);
1565
if (unlikely(plugin::EventObserver::beforeDeleteRecord(*table, buf)))
1567
error= ER_EVENT_OBSERVER_PLUGIN;
1571
error= doDeleteRecord(buf);
1572
if (unlikely(plugin::EventObserver::afterDeleteRecord(*table, buf, error)))
1574
error= ER_EVENT_OBSERVER_PLUGIN;
1578
ha_statistic_increment(&system_status_var::ha_delete_count);
1531
1580
DRIZZLE_DELETE_ROW_DONE(error);
1533
1582
if (unlikely(error))