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),
62
61
key_used_on_scan(MAX_KEY), active_index(MAX_KEY),
63
62
ref_length(sizeof(internal::my_off_t)),
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->getMutableShare()->db_type()->getCursor(*table->getMutableShare(), mem_root);
86
80
Allocate Cursor->ref here because otherwise ha_open will allocate it
90
84
if (!(new_handler->ref= (unsigned char*) mem_root->alloc_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->getMutableShare()->getNormalizedPath(),
99
89
HA_OPEN_IGNORE_IF_LOCKED))
100
90
return new_handler;
111
101
/* works only with key prefixes */
112
102
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;
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;
118
109
while (key_part_found < end_key_part_found && keypart_map_arg)
183
180
bool Cursor::has_transactions()
185
return (getTable()->getShare()->db_type()->check_flag(HTON_BIT_DOES_TRANSACTIONS));
182
return (table->getShare()->db_type()->check_flag(HTON_BIT_DOES_TRANSACTIONS));
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
190
(getTable()->in_use->status_var.*offset)++;
187
status_var_increment(table->in_use->status_var.*offset);
193
190
void **Cursor::ha_data(Session *session) const
195
return session->getEngineData(getEngine());
192
return session->getEngineData(engine);
195
Session *Cursor::ha_session(void) const
197
assert(!table || !table->in_use || table->in_use == current_session);
198
return (table && table->in_use) ? table->in_use : current_session;
198
202
bool Cursor::is_fatal_error(int error, uint32_t flags)
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(); }
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);
215
uint64_t Cursor::rowSize() { return table->getRecordLength() + table->sizeFields(); }
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
224
int Cursor::ha_open(const TableIdentifier &identifier,
223
int Cursor::ha_open(Table *table_arg, const char *name, int mode,
230
if ((error= doOpen(identifier, mode, test_if_locked)))
229
assert(table->getShare() == table_share);
231
if ((error=open(name, mode, test_if_locked)))
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))
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);
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
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)))
253
254
error=HA_ERR_OUT_OF_MEM;
276
277
TODO remove the test for HA_READ_ORDER
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))
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
307
compute_next_insert_id(uint64_t nr, drizzle_system_variables *variables)
308
compute_next_insert_id(uint64_t nr,struct system_variables *variables)
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.
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));
344
345
The number X if it exists, "nr" otherwise.
347
prev_insert_id(uint64_t nr, drizzle_system_variables *variables)
348
prev_insert_id(uint64_t nr, struct system_variables *variables)
349
350
if (unlikely(nr < variables->auto_increment_offset))
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;
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 */
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)
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);
536
if (getTable()->getShare()->next_number_keypart == 0)
537
if (table->getShare()->next_number_keypart == 0)
538
539
/* We must defer the appending until "nr" has been possibly truncated */
543
if (unlikely(getTable()->next_number_field->store((int64_t) nr, true)))
544
if (unlikely(table->next_number_field->store((int64_t) nr, true)))
546
547
first test if the query was aborted due to strict mode constraints
548
if (session->getKilled() == Session::KILL_BAD_DATA)
549
if (session->killed == Session::KILL_BAD_DATA)
549
550
return HA_ERR_AUTOINC_ERANGE;
556
557
bother shifting the right bound (anyway any other value from this
557
558
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();
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();
612
613
this statement used forced auto_increment values if there were some,
613
614
wipe them away for other statements.
615
getTable()->in_use->auto_inc_intervals_forced.empty();
616
table->in_use->auto_inc_intervals_forced.empty();
652
653
Cursor::setTransactionReadWrite()
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());
655
ResourceContext *resource_context= ha_session()->getResourceContext(engine);
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
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);
804
795
if (!(error=index_next(buf)))
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;
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.
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++)
834
if (key_cmp_if_same(getTable(), key, active_index, keylen))
825
if (key_cmp_if_same(table, key, active_index, keylen))
836
getTable()->status=STATUS_NOT_FOUND;
827
table->status=STATUS_NOT_FOUND;
837
828
error=HA_ERR_END_OF_FILE;
840
831
/* Move back if necessary. */
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);
877
868
double Cursor::index_only_read_time(uint32_t keynr, double key_records)
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);
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.
935
927
seq_it= seq->init(seq_init_param, n_ranges, *flags);
936
928
while (!seq->next(seq_it, &range))
930
if (unlikely(session->killed != 0))
939
934
key_range *min_endp, *max_endp;
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);
1187
range_key_part= getTable()->key_info[active_index].key_part;
1182
range_key_part= table->key_info[active_index].key_part;
1189
1184
if (!start_key) // Read first record
1190
result= index_first(getTable()->getInsertRecord());
1185
result= index_first(table->record[0]);
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);
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));
1229
result= index_next(getTable()->getInsertRecord());
1224
result= index_next(table->record[0]);
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;
1291
if (table->getShare()->getType() || not transaction_services.shouldConstructMessages())
1286
if (table->getShare()->tmp_table || not transaction_services.shouldConstructMessages())
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
1330
1325
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);
1327
transaction_services.deleteRecord(session, table);
1339
1329
* We set the "current" statement message to NULL. This triggers
1340
1330
* the replication services component to generate a new statement
1395
1384
if (lock_type == F_RDLCK)
1397
DRIZZLE_CURSOR_RDLOCK_START(getTable()->getShare()->getSchemaName(),
1398
getTable()->getShare()->getTableName());
1386
DRIZZLE_CURSOR_RDLOCK_START(table_share->getSchemaName(),
1387
table_share->getTableName());
1400
1389
else if (lock_type == F_WRLCK)
1402
DRIZZLE_CURSOR_WRLOCK_START(getTable()->getShare()->getSchemaName(),
1403
getTable()->getShare()->getTableName());
1391
DRIZZLE_CURSOR_WRLOCK_START(table_share->getSchemaName(),
1392
table_share->getTableName());
1405
1394
else if (lock_type == F_UNLCK)
1407
DRIZZLE_CURSOR_UNLOCK_START(getTable()->getShare()->getSchemaName(),
1408
getTable()->getShare()->getTableName());
1396
DRIZZLE_CURSOR_UNLOCK_START(table_share->getSchemaName(),
1397
table_share->getTableName());
1444
1433
int Cursor::ha_reset()
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());
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.
1469
if (getTable()->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT)
1471
getTable()->timestamp_field->set_time();
1461
if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT)
1462
table->timestamp_field->set_time();
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();
1477
if (unlikely(plugin::EventObserver::beforeInsertRecord(*getTable(), buf)))
1467
if (unlikely(plugin::EventObserver::beforeInsertRecord(*(table->in_use), *table_share, buf)))
1479
1469
error= ER_EVENT_OBSERVER_PLUGIN;
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)))
1486
1476
error= ER_EVENT_OBSERVER_PLUGIN;
1490
ha_statistic_increment(&system_status_var::ha_write_count);
1492
1480
DRIZZLE_INSERT_ROW_DONE(error);
1494
1482
if (unlikely(error))
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;
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]).
1514
assert(new_data == getTable()->getInsertRecord());
1502
assert(new_data == table->record[0]);
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)))
1520
1508
error= ER_EVENT_OBSERVER_PLUGIN;
1524
if (getTable()->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE)
1526
getTable()->timestamp_field->set_time();
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)))
1532
1515
error= ER_EVENT_OBSERVER_PLUGIN;
1536
ha_statistic_increment(&system_status_var::ha_update_count);
1538
1519
DRIZZLE_UPDATE_ROW_DONE(error);
1540
1521
if (unlikely(error))
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;
1550
TableShare *Cursor::getShare()
1552
return getTable()->getMutableShare();
1555
1532
int Cursor::deleteRecord(const unsigned char *buf)
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)))
1563
1540
error= ER_EVENT_OBSERVER_PLUGIN;
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)))
1570
1547
error= ER_EVENT_OBSERVER_PLUGIN;
1574
ha_statistic_increment(&system_status_var::ha_delete_count);
1576
1551
DRIZZLE_DELETE_ROW_DONE(error);
1578
1553
if (unlikely(error))
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;