#include <cursor.h>
Public Types | |
enum | { NONE =0, INDEX, RND } |
Public Member Functions | |
plugin::StorageEngine * | getEngine () const |
TableShare * | getShare () |
Table * | getTable () const |
uint64_t | getNextInsertId () const |
uint64_t | getAutoIncrement () const |
Cursor (plugin::StorageEngine &engine_arg, Table &share_arg) | |
virtual Cursor * | clone (memory::Root *mem_root) |
int | ha_open (const identifier::Table &identifier, int mode, int test_if_locked) |
int | startIndexScan (uint32_t idx, bool sorted) __attribute__((warn_unused_result)) |
int | endIndexScan () |
int | startTableScan (bool scan) __attribute__((warn_unused_result)) |
int | endTableScan () |
int | ha_reset () |
int | ha_index_or_rnd_end () |
int | ha_external_lock (Session *session, int lock_type) |
int | insertRecord (unsigned char *buf) __attribute__((warn_unused_result)) |
int | updateRecord (const unsigned char *old_data, unsigned char *new_data) __attribute__((warn_unused_result)) |
int | deleteRecord (const unsigned char *buf) __attribute__((warn_unused_result)) |
void | ha_release_auto_increment () |
int | ha_check (Session *) |
void | ha_start_bulk_insert (ha_rows rows) |
int | ha_end_bulk_insert () |
int | ha_delete_all_rows () |
int | ha_reset_auto_increment (uint64_t value) |
int | ha_analyze (Session *) |
int | ha_disable_indexes (uint32_t mode) |
int | ha_enable_indexes (uint32_t mode) |
int | ha_discard_or_import_tablespace (bool discard) |
void | closeMarkForDelete () |
void | adjust_next_insert_id_after_explicit_value (uint64_t nr) |
int | update_auto_increment () |
virtual double | scan_time (void) |
virtual double | read_time (uint32_t, uint32_t ranges, ha_rows rows) |
virtual double | index_only_read_time (uint32_t keynr, double records) |
virtual ha_rows | multi_range_read_info_const (uint32_t keyno, RANGE_SEQ_IF *seq, void *seq_init_param, uint32_t n_ranges, uint32_t *bufsz, uint32_t *flags, optimizer::CostVector *cost) |
virtual int | multi_range_read_info (uint32_t keyno, uint32_t n_ranges, uint32_t keys, uint32_t *bufsz, uint32_t *flags, optimizer::CostVector *cost) |
virtual int | multi_range_read_init (RANGE_SEQ_IF *seq, void *seq_init_param, uint32_t n_ranges, uint32_t mode) |
virtual int | multi_range_read_next (char **range_info) |
virtual const key_map * | keys_to_use_for_scanning () |
bool | has_transactions () |
virtual bool | is_fatal_error (int error, uint32_t flags) |
virtual ha_rows | records () |
virtual uint64_t | tableSize () |
virtual uint64_t | rowSize () |
virtual ha_rows | estimate_rows_upper_bound () |
virtual const char * | index_type (uint32_t) |
uint32_t | get_index (void) const |
virtual int | close (void)=0 |
virtual int | index_read_map (unsigned char *buf, const unsigned char *key, key_part_map keypart_map, enum ha_rkey_function find_flag) |
Positions an index cursor to the index specified in the handle. Fetches the row if available. If the key value is null, begin at the first key of the index. | |
virtual int | index_read_idx_map (unsigned char *buf, uint32_t index, const unsigned char *key, key_part_map keypart_map, enum ha_rkey_function find_flag) |
Positions an index cursor to the index specified in the handle. Fetches the row if available. If the key value is null, begin at the first key of the index. | |
virtual int | index_next (unsigned char *) __attribute__((warn_unused_result)) |
virtual int | index_prev (unsigned char *) |
virtual int | index_first (unsigned char *) |
virtual int | index_last (unsigned char *) |
virtual int | index_next_same (unsigned char *, const unsigned char *, uint32_t) |
virtual int | index_read_last_map (unsigned char *buf, const unsigned char *key, key_part_map keypart_map) |
The following functions works like index_read, but it find the last row with the current key value or prefix. | |
virtual int | read_range_first (const key_range *start_key, const key_range *end_key, bool eq_range, bool sorted) |
virtual int | read_range_next () |
int | compare_key (key_range *range) |
virtual int | rnd_next (unsigned char *)=0 |
virtual int | rnd_pos (unsigned char *, unsigned char *)=0 |
virtual int | read_first_row (unsigned char *buf, uint32_t primary_key) |
virtual int | rnd_same (unsigned char *, uint32_t) |
virtual ha_rows | records_in_range (uint32_t, key_range *, key_range *) |
virtual void | position (const unsigned char *record)=0 |
virtual int | info (uint32_t)=0 |
virtual uint32_t | calculate_key_hash_value (Field **) |
virtual int | extra (enum ha_extra_function) |
virtual int | extra_opt (enum ha_extra_function operation, uint32_t) |
virtual bool | was_semi_consistent_read () |
virtual void | try_semi_consistent_read (bool) |
virtual void | unlock_row (void) |
virtual void | get_auto_increment (uint64_t offset, uint64_t increment, uint64_t nb_desired_values, uint64_t *first_value, uint64_t *nb_reserved_values)=0 |
void | set_next_insert_id (uint64_t id) |
void | restore_auto_increment (uint64_t prev_insert_id) |
virtual int | indexes_are_disabled (void) |
virtual void | append_create_info (String *) |
virtual char * | get_foreign_key_create_info (void) |
virtual bool | can_switch_engines (void) |
virtual int | get_foreign_key_list (Session *, List< ForeignKeyInfo > *) |
virtual uint32_t | referenced_by_foreign_key () |
virtual void | free_foreign_key_create_info (char *) |
virtual THR_LOCK_DATA ** | store_lock (Session *, THR_LOCK_DATA **to, enum thr_lock_type) |
virtual bool | primary_key_is_clustered () |
virtual int | cmp_ref (const unsigned char *ref1, const unsigned char *ref2) |
virtual bool | isOrdered (void) |
Public Attributes | |
unsigned char * | ref |
unsigned char * | dup_ref |
ha_statistics | stats |
range_seq_t | mrr_iter |
RANGE_SEQ_IF | mrr_funcs |
uint32_t | ranges_in_seq |
bool | mrr_is_output_sorted |
bool | mrr_have_range |
bool | eq_range |
KEY_MULTI_RANGE | mrr_cur_range |
key_range | save_end_range |
key_range * | end_range |
KeyPartInfo * | range_key_part |
int | key_compare_result_on_equal |
uint32_t | errkey |
uint32_t | key_used_on_scan |
uint32_t | active_index |
uint32_t | ref_length |
enum drizzled::Cursor:: { ... } | inited |
bool | locked |
uint64_t | next_insert_id |
uint64_t | insert_id_for_cur_row |
Discrete_interval | auto_inc_interval_for_cur_row |
Protected Member Functions | |
void | ha_statistic_increment (uint64_t system_status_var::*offset) const |
void ** | ha_data (Session *) const |
Protected Attributes | |
ha_rows | estimation_rows_to_insert |
Private Member Functions | |
uint32_t | calculate_key_len (uint32_t key_position, key_part_map keypart_map_arg) |
void | setTransactionReadWrite () |
virtual int | open (const char *, int, uint32_t) |
virtual int | doOpen (const identifier::Table &identifier, int mode, uint32_t test_if_locked) |
virtual int | doStartIndexScan (uint32_t idx, bool) |
virtual int | doEndIndexScan () |
virtual int | doStartTableScan (bool scan) __attribute__((warn_unused_result))=0 |
virtual int | doEndTableScan () |
virtual int | doInsertRecord (unsigned char *) |
virtual int | doUpdateRecord (const unsigned char *, unsigned char *) |
virtual int | doDeleteRecord (const unsigned char *) |
virtual int | reset () |
virtual int | external_lock (Session *, int) |
virtual void | release_auto_increment (void) |
virtual int | check (Session *) |
virtual void | start_bulk_insert (ha_rows) |
virtual int | end_bulk_insert (void) |
virtual int | index_read (unsigned char *, const unsigned char *, uint32_t, enum ha_rkey_function) |
virtual int | index_read_last (unsigned char *, const unsigned char *, uint32_t) |
virtual int | delete_all_rows (void) |
virtual int | reset_auto_increment (uint64_t) |
virtual int | analyze (Session *) |
virtual int | disable_indexes (uint32_t) |
virtual int | enable_indexes (uint32_t) |
virtual int | discard_or_import_tablespace (bool) |
virtual void | drop_table () |
Private Attributes | |
Table & | table |
plugin::StorageEngine & | engine |
Friends | |
class | SEAPITesterCursor |
The Cursor class is the interface for dynamically loadable storage engines. Do not add ifdefs and take care when adding or changing virtual functions to avoid vtable confusion
Functions in this class accept and return table columns data. Two data representation formats are used:
[Warning: this description is work in progress and may be incomplete] The table record is stored in a fixed-size buffer:
record: null_bytes, column1_data, column2_data, ...
The offsets of the parts of the buffer are also fixed: every column has an offset to its column{i}_data, and if it is nullable it also has its own bit in null_bytes.
The record buffer only includes data about columns that are marked in the relevant column set (table->read_set and/or table->write_set, depending on the situation). <not-sure>It could be that it is required that null bits of non-present columns are set to 1</not-sure>
VARIOUS EXCEPTIONS AND SPECIAL CASES
f the table has no nullable columns, then null_bytes is still present, its length is one byte <not-sure> which must be set to 0xFF at all times. </not-sure>
For blob columns (see Field_blob), the record buffer stores length of the data, following by memory pointer to the blob data. The pointer is owned by the storage engine and is valid until the next operation.
If a blob column has NULL value, then its length and blob data pointer must be set to 0.
|
inlinevirtual |
used in ALTER Table; if changing storage engine is allowed. e.g. not be allowed if table has foreign key constraints in engine.
Reimplemented in ha_innobase.
Definition at line 433 of file cursor.h.
Referenced by drizzled::internal_alter_table().
|
inlineprivatevirtual |
admin commands - called from mysql_admin_table
Reimplemented in ha_innobase.
void drizzled::Cursor::closeMarkForDelete | ( | ) |
int drizzled::Cursor::compare_key | ( | key_range * | range | ) |
Compare if found key (in row) is over max-value.
range | range to compare to row. May be 0 for no range |
key.cc::key_cmp()
Definition at line 1191 of file cursor.cc.
References drizzled::key_cmp().
|
inlineprivatevirtual |
|
privatepure virtual |
doStartTableScan() can be called two times without doEndTableScan() in between (it only makes sense if scan=1). then the second call should prepare for the new table scan (e.g if rnd_init allocates the cursor, second call should position it to the start of the table, no need to deallocate and allocate it again
Implemented in drizzled::SEAPITesterCursor, ha_innobase, ha_heap, ha_myisam, FunctionCursor, and TableProtoTesterCursor.
|
inlinevirtual |
Return upper bound of current number of records in the table (max. of how many records one will retrieve when doing a full table scan) If upper bound is not known, HA_POS_ERROR should be returned as a max possible upper bound.
Reimplemented in ha_innobase, and FunctionCursor.
Definition at line 288 of file cursor.h.
Referenced by drizzled::FileSort::run().
|
inlineprivatevirtual |
Is not invoked for non-transactional temporary tables.
Tells the storage engine that we intend to read or write data from the table. This call is prefixed with a call to Cursor::store_lock() and is invoked only for those Cursor instances that stored the lock.
Calls to rnd_init/index_init are prefixed with this call. When table IO is complete, we call external_lock(F_UNLCK). A storage engine writer should expect that each call to ::external_lock(F_[RD|WR]LOCK is followed by a call to ::external_lock(F_UNLCK). If it is not, it is a bug in MySQL.
The name and signature originate from the first implementation in MyISAM, which would call fcntl to set/clear an advisory lock on the data file in this method.
lock_type | F_RDLCK, F_WRLCK, F_UNLCK |
Reimplemented in drizzled::SEAPITesterCursor, ha_innobase, and ha_myisam.
|
inlinevirtual |
If index == MAX_KEY then a check for table is made and if index < MAX_KEY then a check is made if the table has foreign keys and if a foreign key uses this index (and thus the index cannot be dropped).
index | Index to check if foreign key uses it |
true | Foreign key defined on table or index |
false | No foreign key defined |
Reimplemented in ha_innobase.
|
inlinevirtual |
used in REPLACE; is > 0 if table is referred by a FOREIGN KEY
Reimplemented in ha_innobase.
|
inline |
int drizzled::Cursor::ha_analyze | ( | Session * | session | ) |
int drizzled::Cursor::ha_delete_all_rows | ( | ) |
Delete all rows: public interface.
This is now equalivalent to TRUNCATE TABLE.
Trigger post-truncate notification to plugins...
Definition at line 636 of file cursor.cc.
Referenced by drizzled::select_union::cleanup(), and drizzled::delete_query().
int drizzled::Cursor::ha_disable_indexes | ( | uint32_t | mode | ) |
Disable indexes: public interface.
Definition at line 694 of file cursor.cc.
Referenced by drizzled::alter_table_manage_keys().
int drizzled::Cursor::ha_discard_or_import_tablespace | ( | bool | discard | ) |
int drizzled::Cursor::ha_enable_indexes | ( | uint32_t | mode | ) |
Enable indexes: public interface.
Definition at line 709 of file cursor.cc.
Referenced by drizzled::alter_table_manage_keys().
int drizzled::Cursor::ha_external_lock | ( | Session * | session, |
int | lock_type | ||
) |
int drizzled::Cursor::ha_open | ( | const identifier::Table & | identifier, |
int | mode, | ||
int | test_if_locked | ||
) |
void drizzled::Cursor::ha_release_auto_increment | ( | ) |
Reserves an interval of auto_increment values from the Cursor.
offset and increment means that we want values to be of the form offset + N * increment, where N>=0 is integer. If the function sets *first_value to ~(uint64_t)0 it means an error. If the function sets *nb_reserved_values to UINT64_MAX it means it has reserved to "positive infinite".
offset | |
increment | |
nb_desired_values | how many values we want |
first_value | (OUT) the first value reserved by the Cursor |
nb_reserved_values | (OUT) how many values the Cursor reserved |
Definition at line 576 of file cursor.cc.
Referenced by drizzled::insert_query().
int drizzled::Cursor::ha_reset | ( | ) |
Check Cursor usage and reset state of file to after 'open'
Definition at line 1376 of file cursor.cc.
Referenced by drizzled::Open_tables_state::free_cached_table().
int drizzled::Cursor::ha_reset_auto_increment | ( | uint64_t | value | ) |
Reset auto increment: public interface.
Definition at line 665 of file cursor.cc.
Referenced by drizzled::delete_query().
|
virtual |
Calculate cost of 'index only' scan for given index and number of records
keynr | Index number |
records | Estimated number of records to be retrieved |
Definition at line 817 of file cursor.cc.
Referenced by drizzled::best_access_path().
|
virtual |
This method is used to analyse the error to see whether the error is ignorable or not, certain handlers can have more error that are ignorable than others. E.g. the partition Cursor can get inserts into a range where there is no partition and this is an ignorable error. HA_ERR_FOUND_DUP_UNIQUE is a special case in MyISAM that means the same thing as HA_ERR_FOUND_DUP_KEY but can in some cases lead to a slightly different error message.
Definition at line 190 of file cursor.cc.
Referenced by drizzled::update_query().
|
virtual |
Get cost and other information about MRR scan over some sequence of ranges
Calculate estimated cost and other information about an MRR scan for some sequence of ranges.
The ranges themselves will be known only at execution phase. When this function is called we only know number of ranges and a (rough) E(records) within those ranges.
Currently this function is only called for "n-keypart singlepoint" ranges, i.e. each range is "keypart1=someconst1 AND ... AND keypartN=someconstN"
The flags parameter is a combination of those flags: HA_MRR_SORTED, HA_MRR_INDEX_ONLY, HA_MRR_NO_ASSOCIATION, HA_MRR_LIMITS.
keyno | Index number |
n_ranges | Estimated number of ranges (i.e. intervals) in the range sequence. |
n_rows | Estimated total number of records contained within all of the ranges |
bufsz | INOUT IN: Size of the buffer available for use OUT: Size of the buffer that will be actually used, or 0 if buffer is not needed. |
flags | INOUT A combination of HA_MRR_* flags |
cost | OUT Estimated cost of MRR access |
0 | OK, *cost contains cost of the scan, *bufsz and *flags contain scan parameters. |
other | Error or can't perform the requested scan |
|
virtual |
Get cost and other information about MRR scan over a known list of ranges
Calculate estimated cost and other information about an MRR scan for given sequence of ranges.
keyno | Index number |
seq | Range sequence to be traversed |
seq_init_param | First parameter for seq->init() |
n_ranges_arg | Number of ranges in the sequence, or 0 if the caller can't efficiently determine it |
bufsz | INOUT IN: Size of the buffer available for use OUT: Size of the buffer that is expected to be actually used, or 0 if buffer is not needed. |
flags | INOUT A combination of HA_MRR_* flags |
cost | OUT Estimated cost of MRR access |
HA_POS_ERROR | Error or the engine is unable to perform the requested scan. Values of OUT parameters are undefined. |
other | OK, *cost contains cost of the scan, *bufsz and *flags contain scan parameters. |
Definition at line 862 of file cursor.cc.
References TIME_FOR_COMPARE.
|
virtual |
Initialize the MRR scan
Initialize the MRR scan. This function may do heavyweight scan initialization like row prefetching/sorting/etc (NOTE: but better not do it here as we may not need it, e.g. if we never satisfy WHERE clause on previous tables. For many implementations it would be natural to do such initializations in the first multi_read_range_next() call)
mode is a combination of the following flags: HA_MRR_SORTED, HA_MRR_INDEX_ONLY, HA_MRR_NO_ASSOCIATION
seq | Range sequence to be traversed |
seq_init_param | First parameter for seq->init() |
n_ranges | Number of ranges in the sequence |
mode | Flags, see the description section for the details |
buf | INOUT: memory buffer to be used |
Until WL#2623 is done (see its text, section 3.2), the following will also hold: The caller will guarantee that if "seq->init == mrr_ranges_array_init" then seq_init_param is an array of n_ranges KEY_MULTI_RANGE structures. This property will only be used by NDB Cursor until WL#2623 is done.
Buffer memory management is done according to the following scenario: The caller allocates the buffer and provides it to the callee by filling the members of HANDLER_BUFFER structure. The callee consumes all or some fraction of the provided buffer space, and sets the HANDLER_BUFFER members accordingly. The callee may use the buffer memory until the next multi_range_read_init() call is made, all records have been read, or until doEndIndexScan() call is made, whichever comes first.
0 | OK |
1 | Error |
|
virtual |
Get next record in MRR scan
Default MRR implementation: read the next record
range_info | OUT Undefined if HA_MRR_NO_ASSOCIATION flag is in effect Otherwise, the opaque value associated with the range that contains the returned record. |
0 | OK |
other | Error code |
|
virtual |
|
virtual |
Read first row between two ranges.
start_key | Start key. Is 0 if no min range |
end_key | End key. Is 0 if no max range |
eq_range_arg | Set to 1 if start_key == end_key |
sorted | Set to 1 if result should be sorted per key |
0 | Found row |
HA_ERR_END_OF_FILE | No rows in range |
# Error code |
Reimplemented in ha_innobase, and ha_myisam.
|
virtual |
Read next row between two endpoints.
0 | Found row |
HA_ERR_END_OF_FILE | No rows in range |
# Error code |
Reimplemented in ha_innobase, and ha_myisam.
|
virtual |
|
inlineprivatevirtual |
Reset state of file to after 'open'. This function is called after every statement for all tables used by that statement.
Reimplemented in drizzled::SEAPITesterCursor, ha_innobase, ha_heap, ha_myisam, and FunctionCursor.
|
inlineprivatevirtual |
Reset the auto-increment counter to the given value, i.e. the next row inserted will get the given value. This is called e.g. after TRUNCATE is emulated by doing a 'DELETE FROM t'. HA_ERR_WRONG_COMMAND is returned by storage engines that don't support this operation.
Reimplemented in ha_innobase, ha_heap, and ha_myisam.
|
inlineprivate |
A helper function to mark a transaction read-write, if it is started.
Definition at line 601 of file cursor.cc.
References drizzled::ResourceContext::isStarted(), and drizzled::ResourceContext::markModifiedData().
|
inlinevirtual |
Is not invoked for non-transactional temporary tables.
Reimplemented in drizzled::SEAPITesterCursor, and ha_innobase.
Definition at line 453 of file cursor.h.
Referenced by drizzled::Session::get_lock_data().
|
inlinevirtual |
Tell the engine whether it should avoid unnecessary lock waits. If yes, in an UPDATE or DELETE, if the row under the cursor was locked by another transaction, the engine may try an optimistic read of the last committed row value under the cursor.
Reimplemented in ha_innobase.
Definition at line 386 of file cursor.h.
Referenced by drizzled::update_query().
|
inlinevirtual |
In an UPDATE or DELETE, if the row under the cursor was locked by another transaction, and the engine used an optimistic read of the last committed row value under the cursor, then the engine returns 1 from this function. MySQL must NOT try to update this optimistic value. If the optimistic value does not match the WHERE condition, MySQL can decide to skip over this row. Currently only works for InnoDB. This can be used to avoid unnecessary lock waits.
If this method returns nonzero, it will also signal the storage engine that the next read will be a locking re-read of the row.
Reimplemented in ha_innobase.
Definition at line 379 of file cursor.h.
Referenced by drizzled::update_query().
Discrete_interval drizzled::Cursor::auto_inc_interval_for_cur_row |
uint64_t drizzled::Cursor::insert_id_for_cur_row |
insert id for the current row (autogenerated; if not autogenerated, it's 0). At first successful insertion, this variable is stored into Session::first_successful_insert_id_in_cur_stmt.
KEY_MULTI_RANGE drizzled::Cursor::mrr_cur_range |
bool drizzled::Cursor::mrr_have_range |
range_seq_t drizzled::Cursor::mrr_iter |
uint64_t drizzled::Cursor::next_insert_id |
next_insert_id is the next value which should be inserted into the auto_increment column: in a inserting-multi-row statement (like INSERT SELECT), for the first row where the autoinc value is not specified by the statement, get_auto_increment() called and asked to generate a value, next_insert_id is set to the next value, then for all other rows next_insert_id is used (and increased each time) without calling get_auto_increment().
uint32_t drizzled::Cursor::ref_length |
Length of ref (1-8 or the clustered key length)
Definition at line 159 of file cursor.h.
Referenced by ha_innobase::doOpen(), ha_innobase::position(), drizzled::optimizer::QuickIndexMergeSelect::read_keys_and_merge(), ha_innobase::rnd_pos(), drizzled::FileSort::run(), and drizzled::update_query().
key_range drizzled::Cursor::save_end_range |