1
by brian
clean slate |
1 |
/* Copyright (C) 2000-2006 MySQL 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 |
/* Update an old row in a MyISAM table */
|
|
17 |
||
75
by Brian Aker
Another round of cleanup of MyISAM |
18 |
#include "myisamdef.h" |
1
by brian
clean slate |
19 |
|
20 |
int mi_update(register MI_INFO *info, const uchar *oldrec, uchar *newrec) |
|
21 |
{
|
|
22 |
int flag,key_changed,save_errno; |
|
23 |
register my_off_t pos; |
|
24 |
uint i; |
|
25 |
uchar old_key[MI_MAX_KEY_BUFF],*new_key; |
|
281
by Brian Aker
Converted myisam away from my_bool |
26 |
bool auto_key_changed=0; |
151
by Brian Aker
Ulonglong to uint64_t |
27 |
uint64_t changed; |
1
by brian
clean slate |
28 |
MYISAM_SHARE *share= info->s; |
29 |
ha_checksum old_checksum= 0; |
|
30 |
||
31 |
if (!(info->update & HA_STATE_AKTIV)) |
|
32 |
{
|
|
51.1.114
by Jay Pipes
DBUG symbol removal |
33 |
return(my_errno=HA_ERR_KEY_NOT_FOUND); |
1
by brian
clean slate |
34 |
}
|
35 |
if (share->options & HA_OPTION_READ_ONLY_DATA) |
|
36 |
{
|
|
51.1.114
by Jay Pipes
DBUG symbol removal |
37 |
return(my_errno=EACCES); |
1
by brian
clean slate |
38 |
}
|
39 |
if (info->state->key_file_length >= share->base.margin_key_file_length) |
|
40 |
{
|
|
51.1.114
by Jay Pipes
DBUG symbol removal |
41 |
return(my_errno=HA_ERR_INDEX_FILE_FULL); |
1
by brian
clean slate |
42 |
}
|
43 |
pos=info->lastpos; |
|
44 |
if (_mi_readinfo(info,F_WRLCK,1)) |
|
51.1.114
by Jay Pipes
DBUG symbol removal |
45 |
return(my_errno); |
1
by brian
clean slate |
46 |
|
47 |
if (share->calc_checksum) |
|
48 |
old_checksum=info->checksum=(*share->calc_checksum)(info,oldrec); |
|
49 |
if ((*share->compare_record)(info,oldrec)) |
|
50 |
{
|
|
51 |
save_errno=my_errno; |
|
52 |
goto err_end; /* Record has changed */ |
|
53 |
}
|
|
54 |
||
55 |
||
56 |
/* Calculate and check all unique constraints */
|
|
57 |
key_changed=0; |
|
58 |
for (i=0 ; i < share->state.header.uniques ; i++) |
|
59 |
{
|
|
60 |
MI_UNIQUEDEF *def=share->uniqueinfo+i; |
|
61 |
if (mi_unique_comp(def, newrec, oldrec,1) && |
|
62 |
mi_check_unique(info, def, newrec, mi_unique_hash(def, newrec), |
|
63 |
info->lastpos)) |
|
64 |
{
|
|
65 |
save_errno=my_errno; |
|
66 |
goto err_end; |
|
67 |
}
|
|
68 |
}
|
|
69 |
if (_mi_mark_file_changed(info)) |
|
70 |
{
|
|
71 |
save_errno=my_errno; |
|
72 |
goto err_end; |
|
73 |
}
|
|
74 |
||
75 |
/* Check which keys changed from the original row */
|
|
76 |
||
77 |
new_key=info->lastkey2; |
|
78 |
changed=0; |
|
79 |
for (i=0 ; i < share->base.keys ; i++) |
|
80 |
{
|
|
81 |
if (mi_is_key_active(share->state.key_map, i)) |
|
82 |
{
|
|
83 |
{
|
|
84 |
uint new_length=_mi_make_key(info,i,new_key,newrec,pos); |
|
85 |
uint old_length=_mi_make_key(info,i,old_key,oldrec,pos); |
|
86 |
||
87 |
/* The above changed info->lastkey2. Inform mi_rnext_same(). */
|
|
88 |
info->update&= ~HA_STATE_RNEXT_SAME; |
|
89 |
||
90 |
if (new_length != old_length || |
|
212.6.12
by Mats Kindahl
Removing redundant use of casts in MyISAM storage for memcmp(), memcpy(), memset(), and memmove(). |
91 |
memcmp(old_key,new_key,new_length)) |
1
by brian
clean slate |
92 |
{
|
93 |
if ((int) i == info->lastinx) |
|
94 |
key_changed|=HA_STATE_WRITTEN; /* Mark that keyfile changed */ |
|
151
by Brian Aker
Ulonglong to uint64_t |
95 |
changed|=((uint64_t) 1 << i); |
1
by brian
clean slate |
96 |
share->keyinfo[i].version++; |
97 |
if (share->keyinfo[i].ck_delete(info,i,old_key,old_length)) goto err; |
|
98 |
if (share->keyinfo[i].ck_insert(info,i,new_key,new_length)) goto err; |
|
99 |
if (share->base.auto_key == i+1) |
|
100 |
auto_key_changed=1; |
|
101 |
}
|
|
102 |
}
|
|
103 |
}
|
|
104 |
}
|
|
105 |
/*
|
|
106 |
If we are running with external locking, we must update the index file
|
|
107 |
that something has changed.
|
|
108 |
*/
|
|
77.1.96
by Monty Taylor
Removed skip-external-locking. |
109 |
if (changed) |
1
by brian
clean slate |
110 |
key_changed|= HA_STATE_CHANGED; |
111 |
||
112 |
if (share->calc_checksum) |
|
113 |
{
|
|
114 |
info->checksum=(*share->calc_checksum)(info,newrec); |
|
115 |
/* Store new checksum in index file header */
|
|
116 |
key_changed|= HA_STATE_CHANGED; |
|
117 |
}
|
|
118 |
{
|
|
119 |
/*
|
|
120 |
Don't update index file if data file is not extended and no status
|
|
121 |
information changed
|
|
122 |
*/
|
|
123 |
MI_STATUS_INFO state; |
|
124 |
ha_rows org_split; |
|
125 |
my_off_t org_delete_link; |
|
126 |
||
212.6.12
by Mats Kindahl
Removing redundant use of casts in MyISAM storage for memcmp(), memcpy(), memset(), and memmove(). |
127 |
memcpy(&state, info->state, sizeof(state)); |
1
by brian
clean slate |
128 |
org_split= share->state.split; |
129 |
org_delete_link= share->state.dellink; |
|
130 |
if ((*share->update_record)(info,pos,newrec)) |
|
131 |
goto err; |
|
132 |
if (!key_changed && |
|
212.6.12
by Mats Kindahl
Removing redundant use of casts in MyISAM storage for memcmp(), memcpy(), memset(), and memmove(). |
133 |
(memcmp(&state, info->state, sizeof(state)) || |
1
by brian
clean slate |
134 |
org_split != share->state.split || |
135 |
org_delete_link != share->state.dellink)) |
|
136 |
key_changed|= HA_STATE_CHANGED; /* Must update index file */ |
|
137 |
}
|
|
138 |
if (auto_key_changed) |
|
139 |
set_if_bigger(info->s->state.auto_increment, |
|
140 |
retrieve_auto_increment(info, newrec)); |
|
141 |
if (share->calc_checksum) |
|
142 |
info->state->checksum+=(info->checksum - old_checksum); |
|
143 |
||
144 |
info->update= (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED | HA_STATE_AKTIV | |
|
145 |
key_changed); |
|
146 |
/*
|
|
147 |
Every myisam function that updates myisam table must end with
|
|
148 |
call to _mi_writeinfo(). If operation (second param of
|
|
149 |
_mi_writeinfo()) is not 0 it sets share->changed to 1, that is
|
|
150 |
flags that data has changed. If operation is 0, this function
|
|
151 |
equals to no-op in this case.
|
|
152 |
||
153 |
mi_update() must always pass !0 value as operation, since even if
|
|
154 |
there is no index change there could be data change.
|
|
155 |
*/
|
|
156 |
VOID(_mi_writeinfo(info, WRITEINFO_UPDATE_KEYFILE)); |
|
157 |
if (info->invalidator != 0) |
|
158 |
{
|
|
159 |
(*info->invalidator)(info->filename); |
|
160 |
info->invalidator=0; |
|
161 |
}
|
|
51.1.114
by Jay Pipes
DBUG symbol removal |
162 |
return(0); |
1
by brian
clean slate |
163 |
|
164 |
err: |
|
165 |
save_errno=my_errno; |
|
166 |
if (changed) |
|
167 |
key_changed|= HA_STATE_CHANGED; |
|
168 |
if (my_errno == HA_ERR_FOUND_DUPP_KEY || my_errno == HA_ERR_OUT_OF_MEM || |
|
169 |
my_errno == HA_ERR_RECORD_FILE_FULL) |
|
170 |
{
|
|
171 |
info->errkey= (int) i; |
|
172 |
flag=0; |
|
173 |
do
|
|
174 |
{
|
|
151
by Brian Aker
Ulonglong to uint64_t |
175 |
if (((uint64_t) 1 << i) & changed) |
1
by brian
clean slate |
176 |
{
|
177 |
{
|
|
178 |
uint new_length=_mi_make_key(info,i,new_key,newrec,pos); |
|
179 |
uint old_length= _mi_make_key(info,i,old_key,oldrec,pos); |
|
180 |
if ((flag++ && _mi_ck_delete(info,i,new_key,new_length)) || |
|
181 |
_mi_ck_write(info,i,old_key,old_length)) |
|
182 |
break; |
|
183 |
}
|
|
184 |
}
|
|
185 |
} while (i-- != 0); |
|
186 |
}
|
|
187 |
else
|
|
188 |
{
|
|
189 |
mi_print_error(info->s, HA_ERR_CRASHED); |
|
190 |
mi_mark_crashed(info); |
|
191 |
}
|
|
192 |
info->update= (HA_STATE_CHANGED | HA_STATE_AKTIV | HA_STATE_ROW_CHANGED | |
|
193 |
key_changed); |
|
194 |
||
195 |
err_end: |
|
196 |
VOID(_mi_writeinfo(info,WRITEINFO_UPDATE_KEYFILE)); |
|
197 |
if (save_errno == HA_ERR_KEY_NOT_FOUND) |
|
198 |
{
|
|
199 |
mi_print_error(info->s, HA_ERR_CRASHED); |
|
200 |
save_errno=HA_ERR_CRASHED; |
|
201 |
}
|
|
51.1.114
by Jay Pipes
DBUG symbol removal |
202 |
return(my_errno=save_errno); |
1
by brian
clean slate |
203 |
} /* mi_update */ |