1 | /* Copyright (C) 2006 MySQL AB & MySQL Finland AB & TCX DataKonsult 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 02111-1301 USA */ |
15 | |
16 | #include "maria_def.h" |
17 | #include "ma_rt_index.h" |
18 | |
19 | /* |
20 | Read next row with the same key as previous read, but abort if |
21 | the key changes. |
22 | One may have done a write, update or delete of the previous row. |
23 | |
24 | NOTE! Even if one changes the previous row, the next read is done |
25 | based on the position of the last used key! |
26 | */ |
27 | |
28 | int maria_rnext_same(MARIA_HA *info, uchar *buf) |
29 | { |
30 | int error; |
31 | uint inx,not_used[2]; |
32 | MARIA_KEYDEF *keyinfo; |
33 | ICP_RESULT icp_res= ICP_MATCH; |
34 | DBUG_ENTER("maria_rnext_same" ); |
35 | |
36 | if ((int) (inx= info->lastinx) < 0 || |
37 | info->cur_row.lastpos == HA_OFFSET_ERROR) |
38 | DBUG_RETURN(my_errno=HA_ERR_WRONG_INDEX); |
39 | if (fast_ma_readinfo(info)) |
40 | DBUG_RETURN(my_errno); |
41 | |
42 | keyinfo= info->s->keyinfo+inx; |
43 | if (info->s->lock_key_trees) |
44 | mysql_rwlock_rdlock(&keyinfo->root_lock); |
45 | |
46 | switch (keyinfo->key_alg) { |
47 | #ifdef HAVE_RTREE_KEYS |
48 | case HA_KEY_ALG_RTREE: |
49 | if ((error=maria_rtree_find_next(info,inx, |
50 | maria_read_vec[info->last_key_func]))) |
51 | { |
52 | error=1; |
53 | my_errno=HA_ERR_END_OF_FILE; |
54 | info->cur_row.lastpos= HA_OFFSET_ERROR; |
55 | break; |
56 | } |
57 | break; |
58 | #endif |
59 | case HA_KEY_ALG_BTREE: |
60 | default: |
61 | if (!(info->update & HA_STATE_RNEXT_SAME)) |
62 | { |
63 | /* First rnext_same; Store old key */ |
64 | memcpy(info->lastkey_buff2, info->last_key.data, |
65 | info->last_rkey_length); |
66 | } |
67 | for (;;) |
68 | { |
69 | if ((error= _ma_search_next(info, &info->last_key, |
70 | SEARCH_BIGGER, |
71 | info->s->state.key_root[inx]))) |
72 | break; |
73 | if (ha_key_cmp(keyinfo->seg, info->last_key.data, |
74 | info->lastkey_buff2, |
75 | info->last_rkey_length, SEARCH_FIND, |
76 | not_used)) |
77 | { |
78 | error=1; |
79 | my_errno=HA_ERR_END_OF_FILE; |
80 | info->cur_row.lastpos= HA_OFFSET_ERROR; |
81 | break; |
82 | } |
83 | /* |
84 | If we are at the last key on the key page, allow writers to |
85 | access the index. |
86 | */ |
87 | if (info->int_keypos >= info->int_maxpos && |
88 | ma_yield_and_check_if_killed(info, inx)) |
89 | { |
90 | error= 1; |
91 | break; |
92 | } |
93 | /* Skip rows that are inserted by other threads since we got a lock */ |
94 | if ((info->s->row_is_visible)(info) && |
95 | ((icp_res= ma_check_index_cond(info, inx, buf)) != ICP_NO_MATCH)) |
96 | break; |
97 | } |
98 | } |
99 | if (info->s->lock_key_trees) |
100 | mysql_rwlock_unlock(&keyinfo->root_lock); |
101 | /* Don't clear if database-changed */ |
102 | info->update&= (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED); |
103 | info->update|= HA_STATE_NEXT_FOUND | HA_STATE_RNEXT_SAME; |
104 | |
105 | if (error || icp_res != ICP_MATCH) |
106 | { |
107 | fast_ma_writeinfo(info); |
108 | if (my_errno == HA_ERR_KEY_NOT_FOUND) |
109 | my_errno= HA_ERR_END_OF_FILE; |
110 | } |
111 | else if (!buf) |
112 | { |
113 | fast_ma_writeinfo(info); |
114 | DBUG_RETURN(info->cur_row.lastpos == HA_OFFSET_ERROR ? my_errno : 0); |
115 | } |
116 | else if (!(*info->read_record)(info, buf, info->cur_row.lastpos)) |
117 | { |
118 | info->update|= HA_STATE_AKTIV; /* Record is read */ |
119 | DBUG_RETURN(0); |
120 | } |
121 | DBUG_RETURN(my_errno); |
122 | } /* maria_rnext_same */ |
123 | |