summaryrefslogtreecommitdiff
path: root/innobase
diff options
context:
space:
mode:
authorunknown <heikki@hundin.mysql.fi>2003-04-17 02:28:40 +0300
committerunknown <heikki@hundin.mysql.fi>2003-04-17 02:28:40 +0300
commit01545bd472169f8637ba0dab1630a069db6d2195 (patch)
treefe38cf2b4bce797b5c6a405c301fc3e22a92e800 /innobase
parent7214d07baf67817974a87da9faa61eaa8e2bb4ae (diff)
downloadmariadb-git-01545bd472169f8637ba0dab1630a069db6d2195.tar.gz
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
Diffstat (limited to 'innobase')
-rw-r--r--innobase/include/row0mysql.h10
-rw-r--r--innobase/row/row0mysql.c3
-rw-r--r--innobase/row/row0sel.c26
3 files changed, 27 insertions, 12 deletions
diff --git a/innobase/include/row0mysql.h b/innobase/include/row0mysql.h
index 25d2ab77007..940b4c61b2f 100644
--- a/innobase/include/row0mysql.h
+++ b/innobase/include/row0mysql.h
@@ -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
diff --git a/innobase/row/row0mysql.c b/innobase/row/row0mysql.c
index 81ed94e2628..af4f484b43d 100644
--- a/innobase/row/row0mysql.c
+++ b/innobase/row/row0mysql.c
@@ -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;
diff --git a/innobase/row/row0sel.c b/innobase/row/row0sel.c
index 7e292bbb042..44dece3d64d 100644
--- a/innobase/row/row0sel.c
+++ b/innobase/row/row0sel.c
@@ -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 */