#include "fulltext.h"#include "rt_index.h"Include dependency graph for mi_update.c:

Functions | |
| int | mi_update (register MI_INFO *info, const byte *oldrec, byte *newrec) |
|
||||||||||||||||
|
00023 {
00024 int flag,key_changed,save_errno;
00025 reg3 my_off_t pos;
00026 uint i;
00027 uchar old_key[MI_MAX_KEY_BUFF],*new_key;
00028 bool auto_key_changed=0;
00029 ulonglong changed;
00030 MYISAM_SHARE *share=info->s;
00031 ha_checksum old_checksum;
00032 DBUG_ENTER("mi_update");
00033 LINT_INIT(new_key);
00034 LINT_INIT(changed);
00035 LINT_INIT(old_checksum);
00036
00037 if (!(info->update & HA_STATE_AKTIV))
00038 {
00039 DBUG_RETURN(my_errno=HA_ERR_KEY_NOT_FOUND);
00040 }
00041 if (share->options & HA_OPTION_READ_ONLY_DATA)
00042 {
00043 DBUG_RETURN(my_errno=EACCES);
00044 }
00045 if (info->state->key_file_length >= share->base.margin_key_file_length)
00046 {
00047 DBUG_RETURN(my_errno=HA_ERR_INDEX_FILE_FULL);
00048 }
00049 pos=info->lastpos;
00050 if (_mi_readinfo(info,F_WRLCK,1))
00051 DBUG_RETURN(my_errno);
00052
00053 if (share->calc_checksum)
00054 old_checksum=info->checksum=(*share->calc_checksum)(info,oldrec);
00055 if ((*share->compare_record)(info,oldrec))
00056 {
00057 save_errno=my_errno;
00058 goto err_end; /* Record has changed */
00059 }
00060
00061
00062 /* Calculate and check all unique constraints */
00063 key_changed=0;
00064 for (i=0 ; i < share->state.header.uniques ; i++)
00065 {
00066 MI_UNIQUEDEF *def=share->uniqueinfo+i;
00067 if (mi_unique_comp(def, newrec, oldrec,1) &&
00068 mi_check_unique(info, def, newrec, mi_unique_hash(def, newrec),
00069 info->lastpos))
00070 {
00071 save_errno=my_errno;
00072 goto err_end;
00073 }
00074 }
00075 if (_mi_mark_file_changed(info))
00076 {
00077 save_errno=my_errno;
00078 goto err_end;
00079 }
00080
00081 /* Check which keys changed from the original row */
00082
00083 new_key=info->lastkey2;
00084 changed=0;
00085 for (i=0 ; i < share->base.keys ; i++)
00086 {
00087 if (((ulonglong) 1 << i) & share->state.key_map)
00088 {
00089 if (share->keyinfo[i].flag & HA_FULLTEXT )
00090 {
00091 if (_mi_ft_cmp(info,i,oldrec, newrec))
00092 {
00093 if ((int) i == info->lastinx)
00094 {
00095 /*
00096 We are changeing the index we are reading on. Mark that
00097 the index data has changed and we need to do a full search
00098 when doing read-next
00099 */
00100 key_changed|=HA_STATE_WRITTEN;
00101 }
00102 changed|=((ulonglong) 1 << i);
00103 if (_mi_ft_update(info,i,(char*) old_key,oldrec,newrec,pos))
00104 goto err;
00105 }
00106 }
00107 else
00108 {
00109 uint new_length=_mi_make_key(info,i,new_key,newrec,pos);
00110 uint old_length=_mi_make_key(info,i,old_key,oldrec,pos);
00111 if (new_length != old_length ||
00112 memcmp((byte*) old_key,(byte*) new_key,new_length))
00113 {
00114 if ((int) i == info->lastinx)
00115 key_changed|=HA_STATE_WRITTEN; /* Mark that keyfile changed */
00116 changed|=((ulonglong) 1 << i);
00117 share->keyinfo[i].version++;
00118 if (share->keyinfo[i].ck_delete(info,i,old_key,old_length)) goto err;
00119 if (share->keyinfo[i].ck_insert(info,i,new_key,new_length)) goto err;
00120 if (share->base.auto_key == i+1)
00121 auto_key_changed=1;
00122 }
00123 }
00124 }
00125 }
00126 /*
00127 If we are running with external locking, we must update the index file
00128 that something has changed.
00129 */
00130 if (changed || !my_disable_locking)
00131 key_changed|= HA_STATE_CHANGED;
00132
00133 if (share->calc_checksum)
00134 {
00135 info->checksum=(*share->calc_checksum)(info,newrec);
00136 /* Store new checksum in index file header */
00137 key_changed|= HA_STATE_CHANGED;
00138 }
00139 {
00140 /*
00141 Don't update index file if data file is not extended and no status
00142 information changed
00143 */
00144 MI_STATUS_INFO state;
00145 ha_rows org_split;
00146 my_off_t org_delete_link;
00147
00148 memcpy((char*) &state, (char*) info->state, sizeof(state));
00149 org_split= share->state.split;
00150 org_delete_link= share->state.dellink;
00151 if ((*share->update_record)(info,pos,newrec))
00152 goto err;
00153 if (!key_changed &&
00154 (memcmp((char*) &state, (char*) info->state, sizeof(state)) ||
00155 org_split != share->state.split ||
00156 org_delete_link != share->state.dellink))
00157 key_changed|= HA_STATE_CHANGED; /* Must update index file */
00158 }
00159 if (auto_key_changed)
00160 update_auto_increment(info,newrec);
00161 if (share->calc_checksum)
00162 share->state.checksum+=(info->checksum - old_checksum);
00163
00164 info->update= (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED | HA_STATE_AKTIV |
00165 key_changed);
00166 myisam_log_record(MI_LOG_UPDATE,info,newrec,info->lastpos,0);
00167 VOID(_mi_writeinfo(info,key_changed ? WRITEINFO_UPDATE_KEYFILE : 0));
00168 allow_break(); /* Allow SIGHUP & SIGINT */
00169 if (info->invalidator != 0)
00170 {
00171 DBUG_PRINT("info", ("invalidator... '%s' (update)", info->filename));
00172 (*info->invalidator)(info->filename);
00173 info->invalidator=0;
00174 }
00175 DBUG_RETURN(0);
00176
00177 err:
00178 DBUG_PRINT("error",("key: %d errno: %d",i,my_errno));
00179 save_errno=my_errno;
00180 if (changed)
00181 key_changed|= HA_STATE_CHANGED;
00182 if (my_errno == HA_ERR_FOUND_DUPP_KEY || my_errno == HA_ERR_RECORD_FILE_FULL)
00183 {
00184 info->errkey= (int) i;
00185 flag=0;
00186 do
00187 {
00188 if (((ulonglong) 1 << i) & changed)
00189 {
00190 if (share->keyinfo[i].flag & HA_FULLTEXT)
00191 {
00192 if ((flag++ && _mi_ft_del(info,i,(char*) new_key,newrec,pos)) ||
00193 _mi_ft_add(info,i,(char*) old_key,oldrec,pos))
00194 break;
00195 }
00196 else
00197 {
00198 uint new_length=_mi_make_key(info,i,new_key,newrec,pos);
00199 uint old_length= _mi_make_key(info,i,old_key,oldrec,pos);
00200 if ((flag++ && _mi_ck_delete(info,i,new_key,new_length)) ||
00201 _mi_ck_write(info,i,old_key,old_length))
00202 break;
00203 }
00204 }
00205 } while (i-- != 0);
00206 }
00207 else
00208 mi_mark_crashed(info);
00209 info->update= (HA_STATE_CHANGED | HA_STATE_AKTIV | HA_STATE_ROW_CHANGED |
00210 key_changed);
00211
00212 err_end:
00213 myisam_log_record(MI_LOG_UPDATE,info,newrec,info->lastpos,my_errno);
00214 VOID(_mi_writeinfo(info,WRITEINFO_UPDATE_KEYFILE));
00215 allow_break(); /* Allow SIGHUP & SIGINT */
00216 if (save_errno == HA_ERR_KEY_NOT_FOUND)
00217 save_errno=HA_ERR_CRASHED;
00218 DBUG_RETURN(my_errno=save_errno);
00219 } /* mi_update */
|
1.3.9.1