MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
hp_rprev.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 prev record for key */
19 
20 
21 int heap_rprev(HP_INFO *info, uchar *record)
22 {
23  uchar *pos;
24  HP_SHARE *share=info->s;
25  HP_KEYDEF *keyinfo;
26  DBUG_ENTER("heap_rprev");
27 
28  if (info->lastinx < 0)
29  DBUG_RETURN(my_errno=HA_ERR_WRONG_INDEX);
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  pos = tree_search_next(&keyinfo->rb_tree, &info->last_pos,
37  offsetof(TREE_ELEMENT, right),
38  offsetof(TREE_ELEMENT, left));
39  else
40  {
41  custom_arg.keyseg = keyinfo->seg;
42  custom_arg.key_length = keyinfo->length;
43  custom_arg.search_flag = SEARCH_SAME;
44  pos = tree_search_key(&keyinfo->rb_tree, info->lastkey, info->parents,
45  &info->last_pos, info->last_find_flag, &custom_arg);
46  }
47  if (pos)
48  {
49  memcpy(&pos, pos + (*keyinfo->get_key_length)(keyinfo, pos),
50  sizeof(uchar*));
51  info->current_ptr = pos;
52  }
53  else
54  {
55  my_errno = HA_ERR_KEY_NOT_FOUND;
56  }
57  }
58  else
59  {
60  if (info->current_ptr || (info->update & HA_STATE_NEXT_FOUND))
61  {
62  if ((info->update & HA_STATE_DELETED))
63  pos= hp_search(info, share->keydef + info->lastinx, info->lastkey, 3);
64  else
65  pos= hp_search(info, share->keydef + info->lastinx, info->lastkey, 2);
66  }
67  else
68  {
69  pos=0; /* Read next after last */
70  my_errno=HA_ERR_KEY_NOT_FOUND;
71  }
72  }
73  if (!pos)
74  {
75  info->update=HA_STATE_PREV_FOUND; /* For heap_rprev */
76  if (my_errno == HA_ERR_KEY_NOT_FOUND)
77  my_errno=HA_ERR_END_OF_FILE;
78  DBUG_RETURN(my_errno);
79  }
80  memcpy(record,pos,(size_t) share->reclength);
81  info->update=HA_STATE_AKTIV | HA_STATE_PREV_FOUND;
82  DBUG_RETURN(0);
83 }