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
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;
116
106
uint32_t length= 0;
118
108
while (key_part_found < end_key_part_found && keypart_map_arg)
183
179
bool Cursor::has_transactions()
185
return (getTable()->getShare()->db_type()->check_flag(HTON_BIT_DOES_TRANSACTIONS));
181
return (table->getShare()->db_type()->check_flag(HTON_BIT_DOES_TRANSACTIONS));
188
void Cursor::ha_statistic_increment(uint64_t system_status_var::*offset) const
184
void Cursor::ha_statistic_increment(ulong system_status_var::*offset) const
190
(getTable()->in_use->status_var.*offset)++;
186
status_var_increment(table->in_use->status_var.*offset);
193
189
void **Cursor::ha_data(Session *session) const
195
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;
198
201
bool Cursor::is_fatal_error(int error, uint32_t flags)
209
212
ha_rows Cursor::records() { return stats.records; }
210
213
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);
214
uint64_t Cursor::rowSize() { return table->getRecordLength() + table->sizeFields(); }
219
217
Open database-Cursor.
221
219
Try O_RDONLY if cannot open as O_RDWR
222
220
Don't wait for locks if not HA_OPEN_WAIT_IF_LOCKED is set
224
int Cursor::ha_open(const TableIdentifier &identifier,
222
int Cursor::ha_open(Table *table_arg, const char *name, int mode,
230
if ((error= doOpen(identifier, mode, test_if_locked)))
228
assert(table->getShare() == table_share);
230
if ((error=open(name, mode, test_if_locked)))
232
232
if ((error == EACCES || error == EROFS) && mode == O_RDWR &&
233
(getTable()->db_stat & HA_TRY_READ_ONLY))
233
(table->db_stat & HA_TRY_READ_ONLY))
235
getTable()->db_stat|=HA_READ_ONLY;
236
error= doOpen(identifier, O_RDONLY,test_if_locked);
235
table->db_stat|=HA_READ_ONLY;
236
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;
245
if (table->getShare()->db_options_in_use & HA_OPTION_READ_ONLY_DATA)
246
table->db_stat|=HA_READ_ONLY;
247
247
(void) extra(HA_EXTRA_NO_READCHECK); // Not needed in SQL
249
249
/* 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)))
250
if (!ref && !(ref= (unsigned char*) table->alloc_root(ALIGN_SIZE(ref_length)*2)))
253
253
error=HA_ERR_OUT_OF_MEM;
276
276
TODO remove the test for HA_READ_ORDER
278
278
if (stats.deleted < 10 || primary_key >= MAX_KEY ||
279
!(getTable()->index_flags(primary_key) & HA_READ_ORDER))
279
!(table->index_flags(primary_key) & HA_READ_ORDER))
281
281
(void) startTableScan(1);
282
282
while ((error= rnd_next(buf)) == HA_ERR_RECORD_DELETED) ;
304
304
@verbatim 1,5,15,25,35,... @endverbatim
307
compute_next_insert_id(uint64_t nr, drizzle_system_variables *variables)
307
compute_next_insert_id(uint64_t nr,struct system_variables *variables)
309
309
if (variables->auto_increment_increment == 1)
310
310
return (nr+1); // optimization of the formula below
324
324
Session::next_insert_id to be greater than the explicit value.
326
326
if ((next_insert_id > 0) && (nr >= next_insert_id))
327
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));
344
344
The number X if it exists, "nr" otherwise.
347
prev_insert_id(uint64_t nr, drizzle_system_variables *variables)
347
prev_insert_id(uint64_t nr, struct system_variables *variables)
349
349
if (unlikely(nr < variables->auto_increment_offset))
442
442
uint64_t nr, nb_reserved_values;
443
443
bool append= false;
444
Session *session= getTable()->in_use;
445
drizzle_system_variables *variables= &session->variables;
444
Session *session= table->in_use;
445
struct system_variables *variables= &session->variables;
448
448
next_insert_id is a "cursor" into the reserved interval, it may go greater
454
454
for an auto increment column, not a magic value like NULL is.
455
455
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)
457
if ((nr= table->next_number_field->val_int()) != 0
458
|| table->auto_increment_field_not_null)
461
461
Update next_insert_id if we had already generated a value in this
533
533
nr= compute_next_insert_id(nr-1, variables);
536
if (getTable()->getShare()->next_number_keypart == 0)
536
if (table->getShare()->next_number_keypart == 0)
538
538
/* We must defer the appending until "nr" has been possibly truncated */
543
if (unlikely(getTable()->next_number_field->store((int64_t) nr, true)))
543
if (unlikely(table->next_number_field->store((int64_t) nr, true)))
546
546
first test if the query was aborted due to strict mode constraints
548
if (session->getKilled() == Session::KILL_BAD_DATA)
548
if (session->killed == Session::KILL_BAD_DATA)
549
549
return HA_ERR_AUTOINC_ERANGE;
556
556
bother shifting the right bound (anyway any other value from this
557
557
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();
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();
612
612
this statement used forced auto_increment values if there were some,
613
613
wipe them away for other statements.
615
getTable()->in_use->auto_inc_intervals_forced.empty();
615
table->in_use->auto_inc_intervals_forced.empty();
652
652
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());
654
ResourceContext *resource_context= ha_session()->getResourceContext(engine);
666
656
When a storage engine method is called, the transaction must
667
657
have been started, unless it's a DDL call, for which the
702
692
* @todo Make TransactionServices generic to AfterTriggerServices
705
Session *const session= getTable()->in_use;
695
Session *const session= table->in_use;
706
696
TransactionServices &transaction_services= TransactionServices::singleton();
707
transaction_services.truncateTable(session, getTable());
697
transaction_services.truncateTable(session, table);
804
794
if (!(error=index_next(buf)))
806
ptrdiff_t ptrdiff= buf - getTable()->getInsertRecord();
796
ptrdiff_t ptrdiff= buf - table->record[0];
807
797
unsigned char *save_record_0= NULL;
808
798
KeyInfo *key_info= NULL;
809
799
KeyPartInfo *key_part;
810
800
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
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
818
808
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;
812
save_record_0= table->record[0];
813
table->record[0]= buf;
814
key_info= table->key_info + active_index;
825
815
key_part= key_info->key_part;
826
816
key_part_end= key_part + key_info->key_parts;
827
817
for (; key_part < key_part_end; key_part++)
834
if (key_cmp_if_same(getTable(), key, active_index, keylen))
824
if (key_cmp_if_same(table, key, active_index, keylen))
836
getTable()->status=STATUS_NOT_FOUND;
826
table->status=STATUS_NOT_FOUND;
837
827
error=HA_ERR_END_OF_FILE;
840
830
/* Move back if necessary. */
843
getTable()->record[0]= save_record_0;
833
table->record[0]= save_record_0;
844
834
for (key_part= key_info->key_part; key_part < key_part_end; key_part++)
845
835
key_part->field->move_field_offset(-ptrdiff);
877
867
double Cursor::index_only_read_time(uint32_t keynr, double key_records)
879
869
uint32_t keys_per_block= (stats.block_size/2/
880
(getTable()->key_info[keynr].key_length + ref_length) + 1);
870
(table->key_info[keynr].key_length + ref_length) + 1);
881
871
return ((double) (key_records + keys_per_block-1) /
882
872
(double) keys_per_block);
908
898
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
899
session->killed and return HA_POS_ERROR if it is not zero. This is required
910
900
for a user to be able to interrupt the calculation by killing the
911
901
connection/query.
1184
1174
key_compare_result_on_equal= ((end_key->flag == HA_READ_BEFORE_KEY) ? 1 :
1185
1175
(end_key->flag == HA_READ_AFTER_KEY) ? -1 : 0);
1187
range_key_part= getTable()->key_info[active_index].key_part;
1177
range_key_part= table->key_info[active_index].key_part;
1189
1179
if (!start_key) // Read first record
1190
result= index_first(getTable()->getInsertRecord());
1180
result= index_first(table->record[0]);
1192
result= index_read_map(getTable()->getInsertRecord(),
1182
result= index_read_map(table->record[0],
1193
1183
start_key->key,
1194
1184
start_key->keypart_map,
1195
1185
start_key->flag);
1224
1214
/* We trust that index_next_same always gives a row in range */
1225
return(index_next_same(getTable()->getInsertRecord(),
1215
return(index_next_same(table->record[0],
1226
1216
end_range->key,
1227
1217
end_range->length));
1229
result= index_next(getTable()->getInsertRecord());
1219
result= index_next(table->record[0]);
1232
1222
return(compare_key(end_range) <= 0 ? 0 : HA_ERR_END_OF_FILE);
1288
1278
TransactionServices &transaction_services= TransactionServices::singleton();
1289
1279
Session *const session= table->in_use;
1291
if (table->getShare()->getType() || not transaction_services.shouldConstructMessages())
1281
if (table->getShare()->tmp_table || not transaction_services.shouldConstructMessages())
1294
1284
bool result= false;
1316
1306
* called. If it fails, then a call to deleteRecord()
1317
1307
* is called, followed by a repeat of the original
1318
1308
* call to insertRecord(). So, log_row_for_replication
1319
* could be called multiple times for a REPLACE
1309
* could be called either once or twice for a REPLACE
1320
1310
* statement. The below looks at the values of before_record
1321
1311
* and after_record to determine which call to this
1322
1312
* function is for the delete or the insert, since NULL
1330
1320
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);
1322
transaction_services.deleteRecord(session, table);
1339
1324
* We set the "current" statement message to NULL. This triggers
1340
1325
* the replication services component to generate a new statement
1395
1379
if (lock_type == F_RDLCK)
1397
DRIZZLE_CURSOR_RDLOCK_START(getTable()->getShare()->getSchemaName(),
1398
getTable()->getShare()->getTableName());
1381
DRIZZLE_CURSOR_RDLOCK_START(table_share->getSchemaName(),
1382
table_share->getTableName());
1400
1384
else if (lock_type == F_WRLCK)
1402
DRIZZLE_CURSOR_WRLOCK_START(getTable()->getShare()->getSchemaName(),
1403
getTable()->getShare()->getTableName());
1386
DRIZZLE_CURSOR_WRLOCK_START(table_share->getSchemaName(),
1387
table_share->getTableName());
1405
1389
else if (lock_type == F_UNLCK)
1407
DRIZZLE_CURSOR_UNLOCK_START(getTable()->getShare()->getSchemaName(),
1408
getTable()->getShare()->getTableName());
1391
DRIZZLE_CURSOR_UNLOCK_START(table_share->getSchemaName(),
1392
table_share->getTableName());
1444
1428
int Cursor::ha_reset()
1446
1430
/* Check that we have called all proper deallocation functions */
1447
assert(! getTable()->getShare()->all_set.none());
1448
assert(getTable()->key_read == 0);
1431
assert((unsigned char*) table->def_read_set.getBitmap() +
1432
table->getShare()->column_bitmap_size ==
1433
(unsigned char*) table->def_write_set.getBitmap());
1434
assert(table->getShare()->all_set.isSetAll());
1435
assert(table->key_read == 0);
1449
1436
/* ensure that ha_index_end / endTableScan has been called */
1450
1437
assert(inited == NONE);
1451
1438
/* Free cache used by filesort */
1452
getTable()->free_io_cache();
1439
table->free_io_cache();
1453
1440
/* reset the bitmaps to point to defaults */
1454
getTable()->default_column_bitmaps();
1441
table->default_column_bitmaps();
1455
1442
return(reset());
1466
1453
* @TODO Technically, the below two lines can be take even further out of the
1467
1454
* 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();
1456
if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT)
1457
table->timestamp_field->set_time();
1474
DRIZZLE_INSERT_ROW_START(getTable()->getShare()->getSchemaName(), getTable()->getShare()->getTableName());
1459
DRIZZLE_INSERT_ROW_START(table_share->getSchemaName(), table_share->getTableName());
1475
1460
setTransactionReadWrite();
1477
if (unlikely(plugin::EventObserver::beforeInsertRecord(*getTable(), buf)))
1462
if (unlikely(plugin::EventObserver::beforeInsertRecord(*(table->in_use), *table_share, buf)))
1479
1464
error= ER_EVENT_OBSERVER_PLUGIN;
1483
1468
error= doInsertRecord(buf);
1484
if (unlikely(plugin::EventObserver::afterInsertRecord(*getTable(), buf, error)))
1469
if (unlikely(plugin::EventObserver::afterInsertRecord(*(table->in_use), *table_share, buf, error)))
1486
1471
error= ER_EVENT_OBSERVER_PLUGIN;
1490
ha_statistic_increment(&system_status_var::ha_write_count);
1492
1475
DRIZZLE_INSERT_ROW_DONE(error);
1494
1477
if (unlikely(error))
1499
if (unlikely(log_row_for_replication(getTable(), NULL, buf)))
1482
if (unlikely(log_row_for_replication(table, NULL, buf)))
1500
1483
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()).
1494
Some storage engines require that the new record is in record[0]
1495
(and the old record is in record[1]).
1514
assert(new_data == getTable()->getInsertRecord());
1497
assert(new_data == table->record[0]);
1516
DRIZZLE_UPDATE_ROW_START(getTable()->getShare()->getSchemaName(), getTable()->getShare()->getTableName());
1499
DRIZZLE_UPDATE_ROW_START(table_share->getSchemaName(), table_share->getTableName());
1517
1500
setTransactionReadWrite();
1518
if (unlikely(plugin::EventObserver::beforeUpdateRecord(*getTable(), old_data, new_data)))
1501
if (unlikely(plugin::EventObserver::beforeUpdateRecord(*(table->in_use), *table_share, old_data, new_data)))
1520
1503
error= ER_EVENT_OBSERVER_PLUGIN;
1524
if (getTable()->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE)
1526
getTable()->timestamp_field->set_time();
1529
1507
error= doUpdateRecord(old_data, new_data);
1530
if (unlikely(plugin::EventObserver::afterUpdateRecord(*getTable(), old_data, new_data, error)))
1508
if (unlikely(plugin::EventObserver::afterUpdateRecord(*(table->in_use), *table_share, old_data, new_data, error)))
1532
1510
error= ER_EVENT_OBSERVER_PLUGIN;
1536
ha_statistic_increment(&system_status_var::ha_update_count);
1538
1514
DRIZZLE_UPDATE_ROW_DONE(error);
1540
1516
if (unlikely(error))
1545
if (unlikely(log_row_for_replication(getTable(), old_data, new_data)))
1521
if (unlikely(log_row_for_replication(table, old_data, new_data)))
1546
1522
return HA_ERR_RBR_LOGGING_FAILED;
1550
TableShare *Cursor::getShare()
1552
return getTable()->getMutableShare();
1555
1527
int Cursor::deleteRecord(const unsigned char *buf)
1559
DRIZZLE_DELETE_ROW_START(getTable()->getShare()->getSchemaName(), getTable()->getShare()->getTableName());
1531
DRIZZLE_DELETE_ROW_START(table_share->getSchemaName(), table_share->getTableName());
1560
1532
setTransactionReadWrite();
1561
if (unlikely(plugin::EventObserver::beforeDeleteRecord(*getTable(), buf)))
1533
if (unlikely(plugin::EventObserver::beforeDeleteRecord(*(table->in_use), *table_share, buf)))
1563
1535
error= ER_EVENT_OBSERVER_PLUGIN;
1567
1539
error= doDeleteRecord(buf);
1568
if (unlikely(plugin::EventObserver::afterDeleteRecord(*getTable(), buf, error)))
1540
if (unlikely(plugin::EventObserver::afterDeleteRecord(*(table->in_use), *table_share, buf, error)))
1570
1542
error= ER_EVENT_OBSERVER_PLUGIN;
1574
ha_statistic_increment(&system_status_var::ha_delete_count);
1576
1546
DRIZZLE_DELETE_ROW_DONE(error);
1578
1548
if (unlikely(error))
1581
if (unlikely(log_row_for_replication(getTable(), buf, NULL)))
1551
if (unlikely(log_row_for_replication(table, buf, NULL)))
1582
1552
return HA_ERR_RBR_LOGGING_FAILED;