Drizzled Public API Documentation

mi_rnext_same.cc

00001 /* Copyright (C) 2000-2006 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, but abort if
00022      the key changes.
00023      One may have done a write, update or delete of the previous row.
00024      NOTE! Even if one changes the previous row, the next read is done
00025      based on the position of the last used key!
00026   */
00027 
00028 int mi_rnext_same(MI_INFO *info, unsigned char *buf)
00029 {
00030   int error;
00031   uint32_t inx,not_used[2];
00032   MI_KEYDEF *keyinfo;
00033 
00034   if ((int) (inx=info->lastinx) < 0 || info->lastpos == HA_OFFSET_ERROR)
00035     return(errno=HA_ERR_WRONG_INDEX);
00036   keyinfo=info->s->keyinfo+inx;
00037   if (fast_mi_readinfo(info))
00038     return(errno);
00039 
00040   switch (keyinfo->key_alg)
00041   {
00042     case HA_KEY_ALG_BTREE:
00043     default:
00044       if (!(info->update & HA_STATE_RNEXT_SAME))
00045       {
00046         /* First rnext_same; Store old key */
00047         memcpy(info->lastkey2,info->lastkey,info->last_rkey_length);
00048       }
00049       for (;;)
00050       {
00051         if ((error=_mi_search_next(info,keyinfo,info->lastkey,
00052              info->lastkey_length,SEARCH_BIGGER,
00053              info->s->state.key_root[inx])))
00054           break;
00055         if (ha_key_cmp(keyinfo->seg, info->lastkey, info->lastkey2,
00056                        info->last_rkey_length, SEARCH_FIND, not_used))
00057         {
00058           error=1;
00059           errno=HA_ERR_END_OF_FILE;
00060           info->lastpos= HA_OFFSET_ERROR;
00061           break;
00062         }
00063         /* Skip rows that are inserted by other threads since we got a lock */
00064         if (info->lastpos < info->state->data_file_length &&
00065             (!info->index_cond_func || mi_check_index_cond(info, inx, buf)))
00066           break;
00067       }
00068   }
00069   /* Don't clear if database-changed */
00070   info->update&= (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED);
00071   info->update|= HA_STATE_NEXT_FOUND | HA_STATE_RNEXT_SAME;
00072 
00073   if (error)
00074   {
00075     if (errno == HA_ERR_KEY_NOT_FOUND)
00076       errno=HA_ERR_END_OF_FILE;
00077   }
00078   else if (!buf)
00079   {
00080     return(info->lastpos==HA_OFFSET_ERROR ? errno : 0);
00081   }
00082   else if (!(*info->read_record)(info,info->lastpos,buf))
00083   {
00084     info->update|= HA_STATE_AKTIV;    /* Record is read */
00085     return(0);
00086   }
00087   return(errno);
00088 } /* mi_rnext_same */