mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
ha_innodb.cc, row0sel.c, row0mysql.c, row0mysql.h:
Allow HANDLER PREV and NEXT also after positioning the cursor with a unique search on the primary key innobase/include/row0mysql.h: Allow HANDLER PREV and NEXT also after positioning the cursor with a unique search on the primary key innobase/row/row0mysql.c: Allow HANDLER PREV and NEXT also after positioning the cursor with a unique search on the primary key innobase/row/row0sel.c: Allow HANDLER PREV and NEXT also after positioning the cursor with a unique search on the primary key sql/ha_innodb.cc: Allow HANDLER PREV and NEXT also after positioning the cursor with a unique search on the primary key
This commit is contained in:
@ -419,13 +419,21 @@ struct row_prebuilt_struct {
|
||||
index where the ordering column is
|
||||
the row id: in this case this flag
|
||||
is set to TRUE */
|
||||
dict_index_t* index; /* current index for a search, if any */
|
||||
dict_index_t* index; /* current index for a search, if
|
||||
any */
|
||||
ulint read_just_key; /* set to 1 when MySQL calls
|
||||
ha_innobase::extra with the
|
||||
argument HA_EXTRA_KEYREAD; it is enough
|
||||
to read just columns defined in
|
||||
the index (i.e., no read of the
|
||||
clustered index record necessary) */
|
||||
ibool used_in_HANDLER;/* TRUE if we have been using this
|
||||
handle in a MySQL HANDLER low level
|
||||
index cursor command: then we must
|
||||
store the pcur position even in a
|
||||
unique search from a clustered index,
|
||||
because HANDLER allows NEXT and PREV
|
||||
in such a situation */
|
||||
ulint template_type; /* ROW_MYSQL_WHOLE_ROW,
|
||||
ROW_MYSQL_REC_FIELDS,
|
||||
ROW_MYSQL_DUMMY_TEMPLATE, or
|
||||
|
@ -324,6 +324,9 @@ row_create_prebuilt(
|
||||
prebuilt->mysql_has_locked = FALSE;
|
||||
|
||||
prebuilt->index = NULL;
|
||||
|
||||
prebuilt->used_in_HANDLER = FALSE;
|
||||
|
||||
prebuilt->n_template = 0;
|
||||
prebuilt->mysql_template = NULL;
|
||||
|
||||
|
@ -2690,9 +2690,9 @@ row_search_for_mysql(
|
||||
|
||||
/* MySQL sometimes seems to do fetch next or fetch prev even
|
||||
if the search condition is unique; this can, for example,
|
||||
happen with the HANDLER commands; we do not store pcur position
|
||||
in this case, so we cannot restore cursor position, and must
|
||||
return immediately */
|
||||
happen with the HANDLER commands; we do not always store the
|
||||
pcur position in this case, so we cannot restore cursor
|
||||
position, and must return immediately */
|
||||
|
||||
/* printf("%s record not found 1\n", index->name); */
|
||||
|
||||
@ -2703,13 +2703,13 @@ row_search_for_mysql(
|
||||
mtr_start(&mtr);
|
||||
|
||||
/* In a search where at most one record in the index may match, we
|
||||
can use a LOCK_REC_NOT_GAP type record lock when locking a non-delete
|
||||
can use a LOCK_REC_NOT_GAP type record lock when locking a non-delete-
|
||||
marked matching record.
|
||||
|
||||
Note that in a unique secondary index there may be different delete
|
||||
Note that in a unique secondary index there may be different delete-
|
||||
marked versions of a record where only the primary key values differ:
|
||||
thus in a secondary index we must use next-key locks when locking
|
||||
delete marked records. */
|
||||
delete-marked records. */
|
||||
|
||||
if (match_mode == ROW_SEL_EXACT
|
||||
&& index->type & DICT_UNIQUE
|
||||
@ -2730,10 +2730,9 @@ row_search_for_mysql(
|
||||
if (unique_search
|
||||
&& index->type & DICT_CLUSTERED
|
||||
&& !prebuilt->templ_contains_blob
|
||||
&& !prebuilt->used_in_HANDLER
|
||||
&& (prebuilt->mysql_row_len < UNIV_PAGE_SIZE / 8)) {
|
||||
|
||||
ut_a(direction == 0); /* We cannot do fetch prev, as we have
|
||||
not stored the cursor position */
|
||||
mode = PAGE_CUR_GE;
|
||||
|
||||
unique_search_from_clust_index = TRUE;
|
||||
@ -3217,11 +3216,16 @@ rec_loop:
|
||||
}
|
||||
}
|
||||
got_row:
|
||||
/* TODO: should we in every case store the cursor position, even
|
||||
if this is just a join, for example? */
|
||||
/* We have an optimization to save CPU time: if this is a consistent
|
||||
read on a unique condition on the clustered index, then we do not
|
||||
store the pcur position, because any fetch next or prev will anyway
|
||||
return 'end of file'. An exception is the MySQL HANDLER command
|
||||
where the user can move the cursor with PREV or NEXT even after
|
||||
a unique search. */
|
||||
|
||||
if (!unique_search_from_clust_index
|
||||
|| prebuilt->select_lock_type == LOCK_X) {
|
||||
|| prebuilt->select_lock_type == LOCK_X
|
||||
|| prebuilt->used_in_HANDLER) {
|
||||
|
||||
/* Inside an update always store the cursor position */
|
||||
|
||||
|
@ -601,7 +601,7 @@ innobase_invalidate_query_cache(
|
||||
Call this when you have opened a new table handle in HANDLER, before you
|
||||
call index_read_idx() etc. Actually, we can let the cursor stay open even
|
||||
over a transaction commit! Then you should call this before every operation,
|
||||
fecth next etc. This function inits the necessary things even after a
|
||||
fetch next etc. This function inits the necessary things even after a
|
||||
transaction commit. */
|
||||
|
||||
void
|
||||
@ -648,6 +648,8 @@ ha_innobase::init_table_handle_for_HANDLER(void)
|
||||
we???? */
|
||||
|
||||
prebuilt->read_just_key = FALSE;
|
||||
|
||||
prebuilt->used_in_HANDLER = TRUE;
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
@ -4048,6 +4050,8 @@ ha_innobase::external_lock(
|
||||
|
||||
trx->mysql_n_tables_locked = 0;
|
||||
|
||||
prebuilt->used_in_HANDLER = FALSE;
|
||||
|
||||
/* Here we release the search latch and InnoDB
|
||||
thread FIFO ticket if they were reserved. */
|
||||
|
||||
|
Reference in New Issue
Block a user