Commit 01545bd4 authored by unknown's avatar unknown

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
parent 7214d07b
......@@ -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 @@ row_search_for_mysql(
}
}
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. */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment