Drizzled Public API Documentation

mi_rnext.cc
00001 /* Copyright (C) 2000-2004 MySQL AB
00002 
00003    This program is free software; you can redistribute it and/or modify
00004    it under the terms of the GNU General Public License as published by
00005    the Free Software Foundation; version 2 of the License.
00006 
00007    This program is distributed in the hope that it will be useful,
00008    but WITHOUT ANY WARRANTY; without even the implied warranty of
00009    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00010    GNU General Public License for more details.
00011 
00012    You should have received a copy of the GNU General Public License
00013    along with this program; if not, write to the Free Software
00014    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
00015 
00016 #include "myisam_priv.h"
00017 
00018 using namespace drizzled;
00019 
00020   /*
00021      Read next row with the same key as previous read
00022      One may have done a write, update or delete of the previous row.
00023      NOTE! Even if one changes the previous row, the next read is done
00024      based on the position of the last used key!
00025   */
00026 
00027 int mi_rnext(MI_INFO *info, unsigned char *buf, int inx)
00028 {
00029   int error,changed;
00030   uint32_t flag;
00031 
00032   if ((inx = _mi_check_index(info,inx)) < 0)
00033     return(errno);
00034   flag=SEARCH_BIGGER;       /* Read next */
00035   if (info->lastpos == HA_OFFSET_ERROR && info->update & HA_STATE_PREV_FOUND)
00036     flag=0;         /* Read first */
00037 
00038   if (fast_mi_readinfo(info))
00039     return(errno);
00040   changed=_mi_test_if_changed(info);
00041   if (!flag)
00042   {
00043     switch(info->s->keyinfo[inx].key_alg){
00044     case HA_KEY_ALG_BTREE:
00045     default:
00046       error=_mi_search_first(info,info->s->keyinfo+inx,
00047          info->s->state.key_root[inx]);
00048       break;
00049     }
00050   }
00051   else
00052   {
00053     switch (info->s->keyinfo[inx].key_alg) {
00054     case HA_KEY_ALG_BTREE:
00055     default:
00056       if (!changed)
00057   error= _mi_search_next(info,info->s->keyinfo+inx,info->lastkey,
00058              info->lastkey_length,flag,
00059              info->s->state.key_root[inx]);
00060       else
00061   error= _mi_search(info,info->s->keyinfo+inx,info->lastkey,
00062         USE_WHOLE_KEY,flag, info->s->state.key_root[inx]);
00063     }
00064   }
00065 
00066   if (!error)
00067   {
00068     int res= 0;
00069     while ((info->s->concurrent_insert &&
00070             info->lastpos >= info->state->data_file_length) ||
00071            (info->index_cond_func &&
00072            !(res= mi_check_index_cond(info, inx, buf))))
00073     {
00074       /* Skip rows inserted by other threads since we got a lock */
00075       if  ((error=_mi_search_next(info,info->s->keyinfo+inx,
00076                                   info->lastkey,
00077                                   info->lastkey_length,
00078                                   SEARCH_BIGGER,
00079                                   info->s->state.key_root[inx])))
00080         break;
00081     }
00082     if (!error && res == 2)
00083     {
00084       info->lastpos= HA_OFFSET_ERROR;
00085       return(errno= HA_ERR_END_OF_FILE);
00086     }
00087   }
00088 
00089   /* Don't clear if database-changed */
00090   info->update&= (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED);
00091   info->update|= HA_STATE_NEXT_FOUND;
00092 
00093   if (error)
00094   {
00095     if (errno == HA_ERR_KEY_NOT_FOUND)
00096       errno=HA_ERR_END_OF_FILE;
00097   }
00098   else if (!buf)
00099   {
00100     return(info->lastpos==HA_OFFSET_ERROR ? errno : 0);
00101   }
00102   else if (!(*info->read_record)(info,info->lastpos,buf))
00103   {
00104     info->update|= HA_STATE_AKTIV;    /* Record is read */
00105     return(0);
00106   }
00107   return(errno);
00108 } /* mi_rnext */