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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
15 :
16 : #include "maria_def.h"
17 :
18 : #include "ma_rt_index.h"
19 :
20 : /*
21 : Read next row with the same key as previous read
22 : One may have done a write, update or delete of the previous row.
23 : NOTE! Even if one changes the previous row, the next read is done
24 : based on the position of the last used key!
25 : */
26 :
27 : int maria_rnext(MARIA_HA *info, uchar *buf, int inx)
28 101253 : {
29 : int error,changed;
30 : uint flag;
31 101253 : MARIA_SHARE *share= info->s;
32 : MARIA_KEYDEF *keyinfo;
33 101253 : DBUG_ENTER("maria_rnext");
34 :
35 101253 : if ((inx = _ma_check_index(info,inx)) < 0)
36 0 : DBUG_RETURN(my_errno);
37 101253 : flag=SEARCH_BIGGER; /* Read next */
38 101253 : if (info->cur_row.lastpos == HA_OFFSET_ERROR &&
39 : info->update & HA_STATE_PREV_FOUND)
40 810 : flag=0; /* Read first */
41 :
42 101253 : if (fast_ma_readinfo(info))
43 0 : DBUG_RETURN(my_errno);
44 101253 : keyinfo= share->keyinfo + inx;
45 101253 : if (share->lock_key_trees)
46 0 : rw_rdlock(&keyinfo->root_lock);
47 101253 : changed= _ma_test_if_changed(info);
48 101253 : if (!flag)
49 : {
50 810 : switch (keyinfo->key_alg){
51 : #ifdef HAVE_RTREE_KEYS
52 : case HA_KEY_ALG_RTREE:
53 0 : error=maria_rtree_get_first(info, inx,
54 : info->last_key.data_length +
55 : info->last_key.ref_length);
56 :
57 0 : break;
58 : #endif
59 : case HA_KEY_ALG_BTREE:
60 : default:
61 810 : error= _ma_search_first(info, keyinfo, share->state.key_root[inx]);
62 : break;
63 : }
64 : }
65 : else
66 : {
67 100443 : switch (keyinfo->key_alg) {
68 : #ifdef HAVE_RTREE_KEYS
69 : case HA_KEY_ALG_RTREE:
70 : /*
71 : Note that rtree doesn't support that the table
72 : may be changed since last call, so we do need
73 : to skip rows inserted by other threads like in btree
74 : */
75 0 : error= maria_rtree_get_next(info, inx, info->last_key.data_length +
76 : info->last_key.ref_length);
77 0 : break;
78 : #endif
79 : case HA_KEY_ALG_BTREE:
80 : default:
81 100443 : if (!changed)
82 100271 : error= _ma_search_next(info, &info->last_key,
83 : flag | info->last_key.flag,
84 : share->state.key_root[inx]);
85 : else
86 172 : error= _ma_search(info, &info->last_key, flag | info->last_key.flag,
87 : share->state.key_root[inx]);
88 : }
89 : }
90 :
91 101253 : if (!error)
92 : {
93 101081 : while (!(*share->row_is_visible)(info))
94 : {
95 : /* Skip rows inserted by other threads since we got a lock */
96 0 : if ((error= _ma_search_next(info, &info->last_key,
97 : SEARCH_BIGGER,
98 : share->state.key_root[inx])))
99 101081 : break;
100 : }
101 : }
102 101253 : if (share->lock_key_trees)
103 0 : rw_unlock(&keyinfo->root_lock);
104 :
105 : /* Don't clear if database-changed */
106 101253 : info->update&= (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED);
107 101253 : info->update|= HA_STATE_NEXT_FOUND;
108 :
109 101253 : if (error)
110 : {
111 172 : if (my_errno == HA_ERR_KEY_NOT_FOUND)
112 172 : my_errno=HA_ERR_END_OF_FILE;
113 : }
114 101081 : else if (!buf)
115 : {
116 0 : DBUG_RETURN(info->cur_row.lastpos == HA_OFFSET_ERROR ? my_errno : 0);
117 : }
118 101081 : else if (!(*info->read_record)(info, buf, info->cur_row.lastpos))
119 : {
120 101081 : info->update|= HA_STATE_AKTIV; /* Record is read */
121 101081 : DBUG_RETURN(0);
122 : }
123 172 : DBUG_PRINT("error",("Got error: %d, errno: %d",error, my_errno));
124 172 : DBUG_RETURN(my_errno);
125 : } /* maria_rnext */
|