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