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(),
87
if (new_handler && !new_handler->ha_open(table,
88
table->getMutableShare()->getNormalizedPath(),
99
90
HA_OPEN_IGNORE_IF_LOCKED))
100
91
return new_handler;
111
102
/* works only with key prefixes */
112
103
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;
105
const KeyPartInfo *key_part_found= table->getShare()->getKeyInfo(key_position).key_part;
106
const KeyPartInfo *end_key_part_found= key_part_found + table->getShare()->getKeyInfo(key_position).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
185
void Cursor::ha_statistic_increment(uint64_t 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);
198
195
bool Cursor::is_fatal_error(int error, uint32_t flags)
209
206
ha_rows Cursor::records() { return stats.records; }
210
207
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);
208
uint64_t Cursor::rowSize() { return table->getRecordLength() + table->sizeFields(); }
219
211
Open database-Cursor.
221
213
Try O_RDONLY if cannot open as O_RDWR
222
214
Don't wait for locks if not HA_OPEN_WAIT_IF_LOCKED is set
224
int Cursor::ha_open(const TableIdentifier &identifier,
216
int Cursor::ha_open(Table *table_arg, const char *name, int mode,
230
if ((error= doOpen(identifier, mode, test_if_locked)))
222
assert(table->getShare() == table_share);
224
if ((error=open(name, mode, test_if_locked)))
232
226
if ((error == EACCES || error == EROFS) && mode == O_RDWR &&
233
(getTable()->db_stat & HA_TRY_READ_ONLY))
227
(table->db_stat & HA_TRY_READ_ONLY))
235
getTable()->db_stat|=HA_READ_ONLY;
236
error= doOpen(identifier, O_RDONLY,test_if_locked);
229
table->db_stat|=HA_READ_ONLY;
230
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;
239
if (table->getShare()->db_options_in_use & HA_OPTION_READ_ONLY_DATA)
240
table->db_stat|=HA_READ_ONLY;
247
241
(void) extra(HA_EXTRA_NO_READCHECK); // Not needed in SQL
249
243
/* 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)))
244
if (!ref && !(ref= (unsigned char*) table->alloc_root(ALIGN_SIZE(ref_length)*2)))
253
247
error=HA_ERR_OUT_OF_MEM;
276
270
TODO remove the test for HA_READ_ORDER
278
272
if (stats.deleted < 10 || primary_key >= MAX_KEY ||
279
!(getTable()->index_flags(primary_key) & HA_READ_ORDER))
273
!(table->index_flags(primary_key) & HA_READ_ORDER))
281
275
(void) startTableScan(1);
282
276
while ((error= rnd_next(buf)) == HA_ERR_RECORD_DELETED) ;
304
298
@verbatim 1,5,15,25,35,... @endverbatim
307
compute_next_insert_id(uint64_t nr, drizzle_system_variables *variables)
301
compute_next_insert_id(uint64_t nr,struct system_variables *variables)
309
303
if (variables->auto_increment_increment == 1)
310
304
return (nr+1); // optimization of the formula below
324
318
Session::next_insert_id to be greater than the explicit value.
326
320
if ((next_insert_id > 0) && (nr >= next_insert_id))
327
set_next_insert_id(compute_next_insert_id(nr, &getTable()->in_use->variables));
321
set_next_insert_id(compute_next_insert_id(nr, &table->in_use->variables));
344
338
The number X if it exists, "nr" otherwise.
347
prev_insert_id(uint64_t nr, drizzle_system_variables *variables)
341
prev_insert_id(uint64_t nr, struct system_variables *variables)
349
343
if (unlikely(nr < variables->auto_increment_offset))
442
436
uint64_t nr, nb_reserved_values;
443
437
bool append= false;
444
Session *session= getTable()->in_use;
445
drizzle_system_variables *variables= &session->variables;
438
Session *session= table->in_use;
439
struct system_variables *variables= &session->variables;
448
442
next_insert_id is a "cursor" into the reserved interval, it may go greater
454
448
for an auto increment column, not a magic value like NULL is.
455
449
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)
451
if ((nr= table->next_number_field->val_int()) != 0
452
|| table->auto_increment_field_not_null)
461
455
Update next_insert_id if we had already generated a value in this
533
527
nr= compute_next_insert_id(nr-1, variables);
536
if (getTable()->getShare()->next_number_keypart == 0)
530
if (table->getShare()->next_number_keypart == 0)
538
532
/* We must defer the appending until "nr" has been possibly truncated */
543
if (unlikely(getTable()->next_number_field->store((int64_t) nr, true)))
537
if (unlikely(table->next_number_field->store((int64_t) nr, true)))
546
540
first test if the query was aborted due to strict mode constraints
548
if (session->getKilled() == Session::KILL_BAD_DATA)
542
if (session->killed == Session::KILL_BAD_DATA)
549
543
return HA_ERR_AUTOINC_ERANGE;
556
550
bother shifting the right bound (anyway any other value from this
557
551
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();
553
nr= prev_insert_id(table->next_number_field->val_int(), variables);
554
if (unlikely(table->next_number_field->store((int64_t) nr, true)))
555
nr= table->next_number_field->val_int();
612
606
this statement used forced auto_increment values if there were some,
613
607
wipe them away for other statements.
615
getTable()->in_use->auto_inc_intervals_forced.empty();
609
table->in_use->auto_inc_intervals_forced.empty();
658
652
* possible resource to gain (and if there is... then there is a bug such
659
653
* that in_use should have been set.
661
if (not getTable()->in_use)
655
if (not table || not table->in_use)
664
resource_context= getTable()->in_use->getResourceContext(getEngine());
658
resource_context= table->in_use->getResourceContext(engine);
666
660
When a storage engine method is called, the transaction must
667
661
have been started, unless it's a DDL call, for which the
702
696
* @todo Make TransactionServices generic to AfterTriggerServices
705
Session *const session= getTable()->in_use;
699
Session *const session= table->in_use;
706
700
TransactionServices &transaction_services= TransactionServices::singleton();
707
transaction_services.truncateTable(session, getTable());
701
transaction_services.truncateTable(session, table);
804
798
if (!(error=index_next(buf)))
806
ptrdiff_t ptrdiff= buf - getTable()->getInsertRecord();
800
ptrdiff_t ptrdiff= buf - table->record[0];
807
801
unsigned char *save_record_0= NULL;
808
802
KeyInfo *key_info= NULL;
809
803
KeyPartInfo *key_part;
810
804
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
807
key_cmp_if_same() compares table->record[0] against 'key'.
808
In parts it uses table->record[0] directly, in parts it uses
809
field objects with their local pointers into table->record[0].
810
If 'buf' is distinct from table->record[0], we need to move
811
all record references. This is table->record[0] itself and
818
812
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;
816
save_record_0= table->record[0];
817
table->record[0]= buf;
818
key_info= table->key_info + active_index;
825
819
key_part= key_info->key_part;
826
820
key_part_end= key_part + key_info->key_parts;
827
821
for (; key_part < key_part_end; key_part++)
834
if (key_cmp_if_same(getTable(), key, active_index, keylen))
828
if (key_cmp_if_same(table, key, active_index, keylen))
836
getTable()->status=STATUS_NOT_FOUND;
830
table->status=STATUS_NOT_FOUND;
837
831
error=HA_ERR_END_OF_FILE;
840
834
/* Move back if necessary. */
843
getTable()->record[0]= save_record_0;
837
table->record[0]= save_record_0;
844
838
for (key_part= key_info->key_part; key_part < key_part_end; key_part++)
845
839
key_part->field->move_field_offset(-ptrdiff);
877
871
double Cursor::index_only_read_time(uint32_t keynr, double key_records)
879
873
uint32_t keys_per_block= (stats.block_size/2/
880
(getTable()->key_info[keynr].key_length + ref_length) + 1);
874
(table->key_info[keynr].key_length + ref_length) + 1);
881
875
return ((double) (key_records + keys_per_block-1) /
882
876
(double) keys_per_block);
908
902
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
903
session->killed and return HA_POS_ERROR if it is not zero. This is required
910
904
for a user to be able to interrupt the calculation by killing the
911
905
connection/query.
1184
1178
key_compare_result_on_equal= ((end_key->flag == HA_READ_BEFORE_KEY) ? 1 :
1185
1179
(end_key->flag == HA_READ_AFTER_KEY) ? -1 : 0);
1187
range_key_part= getTable()->key_info[active_index].key_part;
1181
range_key_part= table->key_info[active_index].key_part;
1189
1183
if (!start_key) // Read first record
1190
result= index_first(getTable()->getInsertRecord());
1184
result= index_first(table->record[0]);
1192
result= index_read_map(getTable()->getInsertRecord(),
1186
result= index_read_map(table->record[0],
1193
1187
start_key->key,
1194
1188
start_key->keypart_map,
1195
1189
start_key->flag);
1224
1218
/* We trust that index_next_same always gives a row in range */
1225
return(index_next_same(getTable()->getInsertRecord(),
1219
return(index_next_same(table->record[0],
1226
1220
end_range->key,
1227
1221
end_range->length));
1229
result= index_next(getTable()->getInsertRecord());
1223
result= index_next(table->record[0]);
1232
1226
return(compare_key(end_range) <= 0 ? 0 : HA_ERR_END_OF_FILE);
1316
1310
* called. If it fails, then a call to deleteRecord()
1317
1311
* is called, followed by a repeat of the original
1318
1312
* call to insertRecord(). So, log_row_for_replication
1319
* could be called multiple times for a REPLACE
1313
* could be called either once or twice for a REPLACE
1320
1314
* statement. The below looks at the values of before_record
1321
1315
* and after_record to determine which call to this
1322
1316
* function is for the delete or the insert, since NULL
1330
1324
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);
1326
transaction_services.deleteRecord(session, table);
1339
1328
* We set the "current" statement message to NULL. This triggers
1340
1329
* the replication services component to generate a new statement
1395
1383
if (lock_type == F_RDLCK)
1397
DRIZZLE_CURSOR_RDLOCK_START(getTable()->getShare()->getSchemaName(),
1398
getTable()->getShare()->getTableName());
1385
DRIZZLE_CURSOR_RDLOCK_START(table_share->getSchemaName(),
1386
table_share->getTableName());
1400
1388
else if (lock_type == F_WRLCK)
1402
DRIZZLE_CURSOR_WRLOCK_START(getTable()->getShare()->getSchemaName(),
1403
getTable()->getShare()->getTableName());
1390
DRIZZLE_CURSOR_WRLOCK_START(table_share->getSchemaName(),
1391
table_share->getTableName());
1405
1393
else if (lock_type == F_UNLCK)
1407
DRIZZLE_CURSOR_UNLOCK_START(getTable()->getShare()->getSchemaName(),
1408
getTable()->getShare()->getTableName());
1395
DRIZZLE_CURSOR_UNLOCK_START(table_share->getSchemaName(),
1396
table_share->getTableName());
1444
1432
int Cursor::ha_reset()
1446
1434
/* Check that we have called all proper deallocation functions */
1447
assert(! getTable()->getShare()->all_set.none());
1448
assert(getTable()->key_read == 0);
1435
assert((unsigned char*) table->def_read_set.getBitmap() +
1436
table->getShare()->column_bitmap_size ==
1437
(unsigned char*) table->def_write_set.getBitmap());
1438
assert(table->getShare()->all_set.isSetAll());
1439
assert(table->key_read == 0);
1449
1440
/* ensure that ha_index_end / endTableScan has been called */
1450
1441
assert(inited == NONE);
1451
1442
/* Free cache used by filesort */
1452
getTable()->free_io_cache();
1443
table->free_io_cache();
1453
1444
/* reset the bitmaps to point to defaults */
1454
getTable()->default_column_bitmaps();
1445
table->default_column_bitmaps();
1455
1446
return(reset());
1466
1457
* @TODO Technically, the below two lines can be take even further out of the
1467
1458
* Cursor interface and into the fill_record() method.
1469
if (getTable()->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT)
1460
if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT)
1471
getTable()->timestamp_field->set_time();
1462
table->timestamp_field->set_time();
1474
DRIZZLE_INSERT_ROW_START(getTable()->getShare()->getSchemaName(), getTable()->getShare()->getTableName());
1465
DRIZZLE_INSERT_ROW_START(table_share->getSchemaName(), table_share->getTableName());
1475
1466
setTransactionReadWrite();
1477
if (unlikely(plugin::EventObserver::beforeInsertRecord(*getTable(), buf)))
1468
if (unlikely(plugin::EventObserver::beforeInsertRecord(*table, buf)))
1479
1470
error= ER_EVENT_OBSERVER_PLUGIN;
1483
1474
error= doInsertRecord(buf);
1484
if (unlikely(plugin::EventObserver::afterInsertRecord(*getTable(), buf, error)))
1475
if (unlikely(plugin::EventObserver::afterInsertRecord(*table, buf, error)))
1486
1477
error= ER_EVENT_OBSERVER_PLUGIN;
1499
if (unlikely(log_row_for_replication(getTable(), NULL, buf)))
1490
if (unlikely(log_row_for_replication(table, NULL, buf)))
1500
1491
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()).
1502
Some storage engines require that the new record is in record[0]
1503
(and the old record is in record[1]).
1514
assert(new_data == getTable()->getInsertRecord());
1505
assert(new_data == table->record[0]);
1516
DRIZZLE_UPDATE_ROW_START(getTable()->getShare()->getSchemaName(), getTable()->getShare()->getTableName());
1507
DRIZZLE_UPDATE_ROW_START(table_share->getSchemaName(), table_share->getTableName());
1517
1508
setTransactionReadWrite();
1518
if (unlikely(plugin::EventObserver::beforeUpdateRecord(*getTable(), old_data, new_data)))
1509
if (unlikely(plugin::EventObserver::beforeUpdateRecord(*table, old_data, new_data)))
1520
1511
error= ER_EVENT_OBSERVER_PLUGIN;
1524
if (getTable()->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE)
1515
if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE)
1526
getTable()->timestamp_field->set_time();
1517
table->timestamp_field->set_time();
1529
1520
error= doUpdateRecord(old_data, new_data);
1530
if (unlikely(plugin::EventObserver::afterUpdateRecord(*getTable(), old_data, new_data, error)))
1521
if (unlikely(plugin::EventObserver::afterUpdateRecord(*table, old_data, new_data, error)))
1532
1523
error= ER_EVENT_OBSERVER_PLUGIN;
1545
if (unlikely(log_row_for_replication(getTable(), old_data, new_data)))
1536
if (unlikely(log_row_for_replication(table, old_data, new_data)))
1546
1537
return HA_ERR_RBR_LOGGING_FAILED;
1550
TableShare *Cursor::getShare()
1552
return getTable()->getMutableShare();
1555
1542
int Cursor::deleteRecord(const unsigned char *buf)
1559
DRIZZLE_DELETE_ROW_START(getTable()->getShare()->getSchemaName(), getTable()->getShare()->getTableName());
1546
DRIZZLE_DELETE_ROW_START(table_share->getSchemaName(), table_share->getTableName());
1560
1547
setTransactionReadWrite();
1561
if (unlikely(plugin::EventObserver::beforeDeleteRecord(*getTable(), buf)))
1548
if (unlikely(plugin::EventObserver::beforeDeleteRecord(*table, buf)))
1563
1550
error= ER_EVENT_OBSERVER_PLUGIN;
1567
1554
error= doDeleteRecord(buf);
1568
if (unlikely(plugin::EventObserver::afterDeleteRecord(*getTable(), buf, error)))
1555
if (unlikely(plugin::EventObserver::afterDeleteRecord(*table, buf, error)))
1570
1557
error= ER_EVENT_OBSERVER_PLUGIN;
1578
1565
if (unlikely(error))
1581
if (unlikely(log_row_for_replication(getTable(), buf, NULL)))
1568
if (unlikely(log_row_for_replication(table, buf, NULL)))
1582
1569
return HA_ERR_RBR_LOGGING_FAILED;