mirror of
https://github.com/MariaDB/server.git
synced 2025-08-01 03:47:19 +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
|
index where the ordering column is
|
||||||
the row id: in this case this flag
|
the row id: in this case this flag
|
||||||
is set to TRUE */
|
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
|
ulint read_just_key; /* set to 1 when MySQL calls
|
||||||
ha_innobase::extra with the
|
ha_innobase::extra with the
|
||||||
argument HA_EXTRA_KEYREAD; it is enough
|
argument HA_EXTRA_KEYREAD; it is enough
|
||||||
to read just columns defined in
|
to read just columns defined in
|
||||||
the index (i.e., no read of the
|
the index (i.e., no read of the
|
||||||
clustered index record necessary) */
|
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,
|
ulint template_type; /* ROW_MYSQL_WHOLE_ROW,
|
||||||
ROW_MYSQL_REC_FIELDS,
|
ROW_MYSQL_REC_FIELDS,
|
||||||
ROW_MYSQL_DUMMY_TEMPLATE, or
|
ROW_MYSQL_DUMMY_TEMPLATE, or
|
||||||
|
@ -324,6 +324,9 @@ row_create_prebuilt(
|
|||||||
prebuilt->mysql_has_locked = FALSE;
|
prebuilt->mysql_has_locked = FALSE;
|
||||||
|
|
||||||
prebuilt->index = NULL;
|
prebuilt->index = NULL;
|
||||||
|
|
||||||
|
prebuilt->used_in_HANDLER = FALSE;
|
||||||
|
|
||||||
prebuilt->n_template = 0;
|
prebuilt->n_template = 0;
|
||||||
prebuilt->mysql_template = NULL;
|
prebuilt->mysql_template = NULL;
|
||||||
|
|
||||||
|
@ -2690,9 +2690,9 @@ row_search_for_mysql(
|
|||||||
|
|
||||||
/* MySQL sometimes seems to do fetch next or fetch prev even
|
/* MySQL sometimes seems to do fetch next or fetch prev even
|
||||||
if the search condition is unique; this can, for example,
|
if the search condition is unique; this can, for example,
|
||||||
happen with the HANDLER commands; we do not store pcur position
|
happen with the HANDLER commands; we do not always store the
|
||||||
in this case, so we cannot restore cursor position, and must
|
pcur position in this case, so we cannot restore cursor
|
||||||
return immediately */
|
position, and must return immediately */
|
||||||
|
|
||||||
/* printf("%s record not found 1\n", index->name); */
|
/* printf("%s record not found 1\n", index->name); */
|
||||||
|
|
||||||
@ -2703,13 +2703,13 @@ row_search_for_mysql(
|
|||||||
mtr_start(&mtr);
|
mtr_start(&mtr);
|
||||||
|
|
||||||
/* In a search where at most one record in the index may match, we
|
/* 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.
|
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:
|
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
|
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
|
if (match_mode == ROW_SEL_EXACT
|
||||||
&& index->type & DICT_UNIQUE
|
&& index->type & DICT_UNIQUE
|
||||||
@ -2730,10 +2730,9 @@ row_search_for_mysql(
|
|||||||
if (unique_search
|
if (unique_search
|
||||||
&& index->type & DICT_CLUSTERED
|
&& index->type & DICT_CLUSTERED
|
||||||
&& !prebuilt->templ_contains_blob
|
&& !prebuilt->templ_contains_blob
|
||||||
|
&& !prebuilt->used_in_HANDLER
|
||||||
&& (prebuilt->mysql_row_len < UNIV_PAGE_SIZE / 8)) {
|
&& (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;
|
mode = PAGE_CUR_GE;
|
||||||
|
|
||||||
unique_search_from_clust_index = TRUE;
|
unique_search_from_clust_index = TRUE;
|
||||||
@ -3217,11 +3216,16 @@ rec_loop:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
got_row:
|
got_row:
|
||||||
/* TODO: should we in every case store the cursor position, even
|
/* We have an optimization to save CPU time: if this is a consistent
|
||||||
if this is just a join, for example? */
|
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
|
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 */
|
/* 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 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
|
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,
|
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. */
|
transaction commit. */
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -648,6 +648,8 @@ ha_innobase::init_table_handle_for_HANDLER(void)
|
|||||||
we???? */
|
we???? */
|
||||||
|
|
||||||
prebuilt->read_just_key = FALSE;
|
prebuilt->read_just_key = FALSE;
|
||||||
|
|
||||||
|
prebuilt->used_in_HANDLER = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
@ -4048,6 +4050,8 @@ ha_innobase::external_lock(
|
|||||||
|
|
||||||
trx->mysql_n_tables_locked = 0;
|
trx->mysql_n_tables_locked = 0;
|
||||||
|
|
||||||
|
prebuilt->used_in_HANDLER = FALSE;
|
||||||
|
|
||||||
/* Here we release the search latch and InnoDB
|
/* Here we release the search latch and InnoDB
|
||||||
thread FIFO ticket if they were reserved. */
|
thread FIFO ticket if they were reserved. */
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user