~drizzle-trunk/drizzle/development

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