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   int res= 0;
00032 
00033   if ((inx = _mi_check_index(info,inx)) < 0)
00034     return(errno);
00035   flag=SEARCH_BIGGER;       /* Read next */
00036   if (info->lastpos == HA_OFFSET_ERROR && info->update & HA_STATE_PREV_FOUND)
00037     flag=0;         /* Read first */
00038 
00039   if (fast_mi_readinfo(info))
00040     return(errno);
00041   changed=_mi_test_if_changed(info);
00042   if (!flag)
00043   {
00044     switch(info->s->keyinfo[inx].key_alg){
00045     case HA_KEY_ALG_BTREE:
00046     default:
00047       error=_mi_search_first(info,info->s->keyinfo+inx,
00048          info->s->state.key_root[inx]);
00049       break;
00050     }
00051   }
00052   else
00053   {
00054     switch (info->s->keyinfo[inx].key_alg) {
00055     case HA_KEY_ALG_BTREE:
00056     default:
00057       if (!changed)
00058   error= _mi_search_next(info,info->s->keyinfo+inx,info->lastkey,
00059              info->lastkey_length,flag,
00060              info->s->state.key_root[inx]);
00061       else
00062   error= _mi_search(info,info->s->keyinfo+inx,info->lastkey,
00063         USE_WHOLE_KEY,flag, info->s->state.key_root[inx]);
00064     }
00065   }
00066 
00067   if (!error)
00068   {
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 */