~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to plugin/myisam/mi_update.cc

  • Committer: Padraig O'Sullivan
  • Date: 2009-09-13 01:03:01 UTC
  • mto: (1126.9.2 captain-20090915-01)
  • mto: This revision was merged to the branch mainline in revision 1133.
  • Revision ID: osullivan.padraig@gmail.com-20090913010301-tcvvezipx1124acy
Added calls to the dtrace delete begin/end probes.

Show diffs side-by-side

added added

removed removed

Lines of Context:
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
 
 
18
 
#include "myisam_priv.h"
19
 
#include <drizzled/util/test.h>
20
 
 
21
 
using namespace drizzled;
22
 
 
23
 
int mi_update(register MI_INFO *info, const unsigned char *oldrec, unsigned char *newrec)
24
 
{
25
 
  int flag,key_changed,save_errno;
26
 
  register internal::my_off_t pos;
27
 
  uint32_t i;
28
 
  unsigned char old_key[MI_MAX_KEY_BUFF],*new_key;
29
 
  bool auto_key_changed=0;
30
 
  uint64_t changed;
31
 
  MYISAM_SHARE *share= info->s;
32
 
  internal::ha_checksum old_checksum= 0;
33
 
 
34
 
  if (!(info->update & HA_STATE_AKTIV))
35
 
  {
36
 
    return(errno=HA_ERR_KEY_NOT_FOUND);
37
 
  }
38
 
  if (share->options & HA_OPTION_READ_ONLY_DATA)
39
 
  {
40
 
    return(errno=EACCES);
41
 
  }
42
 
  if (info->state->key_file_length >= share->base.margin_key_file_length)
43
 
  {
44
 
    return(errno=HA_ERR_INDEX_FILE_FULL);
45
 
  }
46
 
  pos=info->lastpos;
47
 
  if (_mi_readinfo(info,F_WRLCK,1))
48
 
    return(errno);
49
 
 
50
 
  if (share->calc_checksum)
51
 
    old_checksum=info->checksum=(*share->calc_checksum)(info,oldrec);
52
 
  if ((*share->compare_record)(info,oldrec))
53
 
  {
54
 
    save_errno=errno;
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
 
    {
68
 
      save_errno=errno;
69
 
      goto err_end;
70
 
    }
71
 
  }
72
 
  if (_mi_mark_file_changed(info))
73
 
  {
74
 
    save_errno=errno;
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
 
      {
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);
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 ||
94
 
            memcmp(old_key,new_key,new_length))
95
 
        {
96
 
          if ((int) i == info->lastinx)
97
 
            key_changed|=HA_STATE_WRITTEN;      /* Mark that keyfile changed */
98
 
          changed|=((uint64_t) 1 << i);
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
 
  */
112
 
  if (changed)
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;
128
 
    internal::my_off_t org_delete_link;
129
 
 
130
 
    memcpy(&state, info->state, sizeof(state));
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 &&
136
 
        (memcmp(&state, info->state, sizeof(state)) ||
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
 
  */
159
 
  _mi_writeinfo(info, WRITEINFO_UPDATE_KEYFILE);
160
 
  return(0);
161
 
 
162
 
err:
163
 
  save_errno=errno;
164
 
  if (changed)
165
 
    key_changed|= HA_STATE_CHANGED;
166
 
  if (errno == HA_ERR_FOUND_DUPP_KEY || errno == HA_ERR_OUT_OF_MEM ||
167
 
      errno == HA_ERR_RECORD_FILE_FULL)
168
 
  {
169
 
    info->errkey= (int) i;
170
 
    flag=0;
171
 
    do
172
 
    {
173
 
      if (((uint64_t) 1 << i) & changed)
174
 
      {
175
 
        {
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);
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:
194
 
  _mi_writeinfo(info,WRITEINFO_UPDATE_KEYFILE);
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
 
  }
200
 
  return(errno=save_errno);
201
 
} /* mi_update */