MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
hp_rnext.c
1 /* Copyright (C) 2000-2002 MySQL AB
2 
3  This program is free software; you can redistribute it and/or modify
4  it under the terms of the GNU General Public License as published by
5  the Free Software Foundation; version 2 of the License.
6 
7  This program is distributed in the hope that it will be useful,
8  but WITHOUT ANY WARRANTY; without even the implied warranty of
9  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  GNU General Public License for more details.
11 
12  You should have received a copy of the GNU General Public License
13  along with this program; if not, write to the Free Software
14  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
15 
16 #include "heapdef.h"
17 
18 /* Read next record with the same key */
19 
20 int heap_rnext(HP_INFO *info, uchar *record)
21 {
22  uchar *pos;
23  HP_SHARE *share=info->s;
24  HP_KEYDEF *keyinfo;
25  DBUG_ENTER("heap_rnext");
26 
27  if (info->lastinx < 0)
28  DBUG_RETURN(my_errno=HA_ERR_WRONG_INDEX);
29 
30  keyinfo = share->keydef + info->lastinx;
31  if (keyinfo->algorithm == HA_KEY_ALG_BTREE)
32  {
33  heap_rb_param custom_arg;
34 
35  if (info->last_pos)
36  {
37  /*
38  We enter this branch for non-DELETE queries after heap_rkey()
39  or heap_rfirst(). As last key position (info->last_pos) is available,
40  we only need to climb the tree using tree_search_next().
41  */
42  pos = tree_search_next(&keyinfo->rb_tree, &info->last_pos,
43  offsetof(TREE_ELEMENT, left),
44  offsetof(TREE_ELEMENT, right));
45  }
46  else if (!info->lastkey_len)
47  {
48  /*
49  We enter this branch only for DELETE queries after heap_rfirst(). E.g.
50  DELETE FROM t1 WHERE a<10. As last key position is not available
51  (last key is removed by heap_delete()), we must restart search as it
52  is done in heap_rfirst().
53 
54  It should be safe to handle this situation without this branch. That is
55  branch below should find smallest element in a tree as lastkey_len is
56  zero. tree_search_edge() is a kind of optimisation here as it should be
57  faster than tree_search_key().
58  */
59  pos= tree_search_edge(&keyinfo->rb_tree, info->parents,
60  &info->last_pos, offsetof(TREE_ELEMENT, left));
61  }
62  else
63  {
64  /*
65  We enter this branch only for DELETE queries after heap_rkey(). E.g.
66  DELETE FROM t1 WHERE a=10. As last key position is not available
67  (last key is removed by heap_delete()), we must restart search as it
68  is done in heap_rkey().
69  */
70  custom_arg.keyseg = keyinfo->seg;
71  custom_arg.key_length = info->lastkey_len;
72  custom_arg.search_flag = SEARCH_SAME | SEARCH_FIND;
73  pos = tree_search_key(&keyinfo->rb_tree, info->lastkey, info->parents,
74  &info->last_pos, info->last_find_flag, &custom_arg);
75  }
76  if (pos)
77  {
78  memcpy(&pos, pos + (*keyinfo->get_key_length)(keyinfo, pos),
79  sizeof(uchar*));
80  info->current_ptr = pos;
81  }
82  else
83  {
84  my_errno = HA_ERR_KEY_NOT_FOUND;
85  }
86  }
87  else
88  {
89  if (info->current_hash_ptr)
90  pos= hp_search_next(info, keyinfo, info->lastkey,
91  info->current_hash_ptr);
92  else
93  {
94  if (!info->current_ptr && (info->update & HA_STATE_NEXT_FOUND))
95  {
96  pos=0; /* Read next after last */
97  my_errno=HA_ERR_KEY_NOT_FOUND;
98  }
99  else if (!info->current_ptr) /* Deleted or first call */
100  pos= hp_search(info, keyinfo, info->lastkey, 0);
101  else
102  pos= hp_search(info, keyinfo, info->lastkey, 1);
103  }
104  }
105  if (!pos)
106  {
107  info->update=HA_STATE_NEXT_FOUND; /* For heap_rprev */
108  if (my_errno == HA_ERR_KEY_NOT_FOUND)
109  my_errno=HA_ERR_END_OF_FILE;
110  DBUG_RETURN(my_errno);
111  }
112  memcpy(record,pos,(size_t) share->reclength);
113  info->update=HA_STATE_AKTIV | HA_STATE_NEXT_FOUND;
114  DBUG_RETURN(0);
115 }