~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to plugin/myisam/mi_write.cc

  • Committer: Daniel Nichter
  • Date: 2011-10-23 16:01:37 UTC
  • mto: This revision was merged to the branch mainline in revision 2448.
  • Revision ID: daniel@percona.com-20111023160137-7ac3blgz8z4tf8za
Add Administration Getting Started and Logging.  Capitalize SQL clause keywords.

Show diffs side-by-side

added added

removed removed

Lines of Context:
11
11
 
12
12
   You should have received a copy of the GNU General Public License
13
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 */
 
14
   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
15
15
 
16
16
/* Write a row to a MyISAM table */
17
17
 
18
 
#include "myisamdef.h"
 
18
#include "myisam_priv.h"
19
19
 
20
 
#include <mystrings/m_string.h>
 
20
#include <drizzled/internal/m_string.h>
21
21
#include <drizzled/util/test.h>
22
22
 
 
23
using namespace drizzled;
23
24
 
24
25
#define MAX_POINTER_LENGTH 8
25
26
 
27
28
 
28
29
static int w_search(MI_INFO *info,MI_KEYDEF *keyinfo,
29
30
                    uint32_t comp_flag, unsigned char *key,
30
 
                    uint32_t key_length, my_off_t pos, unsigned char *father_buff,
31
 
                    unsigned char *father_keypos, my_off_t father_page,
 
31
                    uint32_t key_length, internal::my_off_t pos, unsigned char *father_buff,
 
32
                    unsigned char *father_keypos, internal::my_off_t father_page,
32
33
                    bool insert_last);
33
34
static int _mi_balance_page(MI_INFO *info,MI_KEYDEF *keyinfo,unsigned char *key,
34
35
                            unsigned char *curr_buff,unsigned char *father_buff,
35
 
                            unsigned char *father_keypos,my_off_t father_page);
 
36
                            unsigned char *father_keypos,internal::my_off_t father_page);
36
37
static unsigned char *_mi_find_last_pos(MI_KEYDEF *keyinfo, unsigned char *page,
37
38
                                unsigned char *key, uint32_t *return_key_length,
38
39
                                unsigned char **after_key);
48
49
  MYISAM_SHARE *share=info->s;
49
50
  uint32_t i;
50
51
  int save_errno;
51
 
  my_off_t filepos;
 
52
  internal::my_off_t filepos;
52
53
  unsigned char *buff;
53
54
  bool lock_tree= share->concurrent_insert;
54
55
 
55
56
  if (share->options & HA_OPTION_READ_ONLY_DATA)
56
57
  {
57
 
    return(my_errno=EACCES);
 
58
    return(errno=EACCES);
58
59
  }
59
60
  if (_mi_readinfo(info,F_WRLCK,1))
60
 
    return(my_errno);
 
61
    return(errno);
61
62
  filepos= ((share->state.dellink != HA_OFFSET_ERROR &&
62
63
             !info->append_insert_at_end) ?
63
64
            share->state.dellink :
67
68
      share->base.records == (ha_rows) 1 &&
68
69
      info->state->records == (ha_rows) 1)
69
70
  {                                             /* System file */
70
 
    my_errno=HA_ERR_RECORD_FILE_FULL;
 
71
    errno=HA_ERR_RECORD_FILE_FULL;
71
72
    goto err2;
72
73
  }
73
74
  if (info->state->key_file_length >= share->base.margin_key_file_length)
74
75
  {
75
 
    my_errno=HA_ERR_INDEX_FILE_FULL;
 
76
    errno=HA_ERR_INDEX_FILE_FULL;
76
77
    goto err2;
77
78
  }
78
79
  if (_mi_mark_file_changed(info))
99
100
                                  is_tree_inited(&info->bulk_insert[i])));
100
101
      if (local_lock_tree)
101
102
      {
102
 
        rw_wrlock(&share->key_root_lock[i]);
103
103
        share->keyinfo[i].version++;
104
104
      }
105
105
      {
106
106
        if (share->keyinfo[i].ck_insert(info,i,buff,
107
107
                        _mi_make_key(info,i,buff,record,filepos)))
108
108
        {
109
 
          if (local_lock_tree)
110
 
            rw_unlock(&share->key_root_lock[i]);
111
109
          goto err;
112
110
        }
113
111
      }
114
112
 
115
113
      /* The above changed info->lastkey2. Inform mi_rnext_same(). */
116
114
      info->update&= ~HA_STATE_RNEXT_SAME;
117
 
 
118
 
      if (local_lock_tree)
119
 
        rw_unlock(&share->key_root_lock[i]);
120
115
    }
121
116
  }
122
117
  if (share->calc_checksum)
135
130
  info->state->records++;
136
131
  info->lastpos=filepos;
137
132
  _mi_writeinfo(info, WRITEINFO_UPDATE_KEYFILE);
138
 
  if (info->invalidator != 0)
139
 
  {
140
 
    (*info->invalidator)(info->filename);
141
 
    info->invalidator=0;
142
 
  }
143
133
 
144
134
  /*
145
135
    Update status of the table. We need to do so after each row write
149
139
    not critical to use outdated share->is_log_table value (2) locking
150
140
    mutex here for every write is too expensive.
151
141
  */
152
 
  if (share->is_log_table)
153
 
    mi_update_status((void*) info);
 
142
  if (share->is_log_table) // Log table do not exist in Drizzle
 
143
    assert(0);
154
144
 
155
145
  return(0);
156
146
 
157
147
err:
158
 
  save_errno=my_errno;
159
 
  if (my_errno == HA_ERR_FOUND_DUPP_KEY || my_errno == HA_ERR_RECORD_FILE_FULL ||
160
 
      my_errno == HA_ERR_NULL_IN_SPATIAL || my_errno == HA_ERR_OUT_OF_MEM)
 
148
  save_errno=errno;
 
149
  if (errno == HA_ERR_FOUND_DUPP_KEY || errno == HA_ERR_RECORD_FILE_FULL ||
 
150
      errno == HA_ERR_NULL_IN_SPATIAL || errno == HA_ERR_OUT_OF_MEM)
161
151
  {
162
152
    if (info->bulk_insert)
163
153
    {
170
160
    {
171
161
      if (mi_is_key_active(share->state.key_map, i))
172
162
      {
173
 
        bool local_lock_tree= (lock_tree &&
174
 
                                  !(info->bulk_insert &&
175
 
                                    is_tree_inited(&info->bulk_insert[i])));
176
 
        if (local_lock_tree)
177
 
          rw_wrlock(&share->key_root_lock[i]);
178
163
        {
179
164
          uint32_t key_length=_mi_make_key(info,i,buff,record,filepos);
180
165
          if (_mi_ck_delete(info,i,buff,key_length))
181
166
          {
182
 
            if (local_lock_tree)
183
 
              rw_unlock(&share->key_root_lock[i]);
184
167
            break;
185
168
          }
186
169
        }
187
 
        if (local_lock_tree)
188
 
          rw_unlock(&share->key_root_lock[i]);
189
170
      }
190
171
    }
191
172
  }
195
176
    mi_mark_crashed(info);
196
177
  }
197
178
  info->update= (HA_STATE_CHANGED | HA_STATE_WRITTEN | HA_STATE_ROW_CHANGED);
198
 
  my_errno=save_errno;
 
179
  errno=save_errno;
199
180
err2:
200
 
  save_errno=my_errno;
 
181
  save_errno=errno;
201
182
  _mi_writeinfo(info,WRITEINFO_UPDATE_KEYFILE);
202
 
  return(my_errno=save_errno);
 
183
  return(errno=save_errno);
203
184
} /* mi_write */
204
185
 
205
186
 
228
209
  uint32_t error;
229
210
  uint32_t comp_flag;
230
211
  MI_KEYDEF *keyinfo=info->s->keyinfo+keynr;
231
 
  my_off_t  *root=&info->s->state.key_root[keynr];
 
212
  internal::my_off_t  *root=&info->s->state.key_root[keynr];
232
213
 
233
214
  if (keyinfo->flag & HA_SORT_ALLOWS_SAME)
234
215
    comp_flag=SEARCH_BIGGER;                    /* Put after same key */
247
228
} /* _mi_ck_write_btree */
248
229
 
249
230
int _mi_ck_real_write_btree(MI_INFO *info, MI_KEYDEF *keyinfo,
250
 
    unsigned char *key, uint32_t key_length, my_off_t *root, uint32_t comp_flag)
 
231
    unsigned char *key, uint32_t key_length, internal::my_off_t *root, uint32_t comp_flag)
251
232
{
252
233
  int error;
253
234
  /* key_length parameter is used only if comp_flag is SEARCH_FIND */
254
235
  if (*root == HA_OFFSET_ERROR ||
255
236
      (error=w_search(info, keyinfo, comp_flag, key, key_length,
256
237
                      *root, (unsigned char *) 0, (unsigned char*) 0,
257
 
                      (my_off_t) 0, 1)) > 0)
 
238
                      (internal::my_off_t) 0, 1)) > 0)
258
239
    error=_mi_enlarge_root(info,keyinfo,key,root);
259
240
  return(error);
260
241
} /* _mi_ck_real_write_btree */
263
244
        /* Make a new root with key as only pointer */
264
245
 
265
246
int _mi_enlarge_root(MI_INFO *info, MI_KEYDEF *keyinfo, unsigned char *key,
266
 
                     my_off_t *root)
 
247
                     internal::my_off_t *root)
267
248
{
268
249
  uint32_t t_length,nod_flag;
269
250
  MI_KEY_PARAM s_temp;
291
272
        */
292
273
 
293
274
static int w_search(register MI_INFO *info, register MI_KEYDEF *keyinfo,
294
 
                    uint32_t comp_flag, unsigned char *key, uint32_t key_length, my_off_t page,
 
275
                    uint32_t comp_flag, unsigned char *key, uint32_t key_length, internal::my_off_t page,
295
276
                    unsigned char *father_buff, unsigned char *father_keypos,
296
 
                    my_off_t father_page, bool insert_last)
 
277
                    internal::my_off_t father_page, bool insert_last)
297
278
{
298
279
  int error,flag;
299
280
  uint32_t nod_flag, search_key_length;
300
281
  unsigned char *temp_buff,*keypos;
301
282
  unsigned char keybuff[MI_MAX_KEY_BUFF];
302
283
  bool was_last_key;
303
 
  my_off_t next_page, dupp_key_pos;
 
284
  internal::my_off_t next_page, dupp_key_pos;
304
285
 
305
286
  search_key_length= (comp_flag & SEARCH_FIND) ? key_length : USE_WHOLE_KEY;
306
 
  if (!(temp_buff= (unsigned char*) my_alloca((uint) keyinfo->block_length+
307
 
                                      MI_MAX_KEY_BUFF*2)))
 
287
  if (!(temp_buff= (unsigned char*) malloc(keyinfo->block_length+
 
288
                                           MI_MAX_KEY_BUFF*2)))
308
289
    return(-1);
309
290
  if (!_mi_fetch_keypage(info,keyinfo,page,DFLT_INIT_HITS,temp_buff,0))
310
291
    goto err;
324
305
 
325
306
    {
326
307
      info->dupp_key_pos= dupp_key_pos;
327
 
      my_afree((unsigned char*) temp_buff);
328
 
      my_errno=HA_ERR_FOUND_DUPP_KEY;
 
308
      free(temp_buff);
 
309
      errno=HA_ERR_FOUND_DUPP_KEY;
329
310
      return(-1);
330
311
    }
331
312
  }
343
324
    if (_mi_write_keypage(info,keyinfo,page,DFLT_INIT_HITS,temp_buff))
344
325
      goto err;
345
326
  }
346
 
  my_afree((unsigned char*) temp_buff);
 
327
  free(temp_buff);
347
328
  return(error);
348
329
err:
349
 
  my_afree((unsigned char*) temp_buff);
 
330
  free(temp_buff);
350
331
  return (-1);
351
332
} /* w_search */
352
333
 
378
359
 
379
360
int _mi_insert(register MI_INFO *info, register MI_KEYDEF *keyinfo,
380
361
               unsigned char *key, unsigned char *anc_buff, unsigned char *key_pos, unsigned char *key_buff,
381
 
               unsigned char *father_buff, unsigned char *father_key_pos, my_off_t father_page,
 
362
               unsigned char *father_buff, unsigned char *father_key_pos, internal::my_off_t father_page,
382
363
               bool insert_last)
383
364
{
384
365
  uint32_t a_length,nod_flag;
400
381
    if (t_length >= keyinfo->maxlength*2+MAX_POINTER_LENGTH)
401
382
    {
402
383
      mi_print_error(info->s, HA_ERR_CRASHED);
403
 
      my_errno=HA_ERR_CRASHED;
 
384
      errno=HA_ERR_CRASHED;
404
385
      return(-1);
405
386
    }
406
 
    bmove_upp((unsigned char*) endpos+t_length,(unsigned char*) endpos,(uint) (endpos-key_pos));
 
387
    internal::bmove_upp((unsigned char*) endpos+t_length,(unsigned char*) endpos,(uint) (endpos-key_pos));
407
388
  }
408
389
  else
409
390
  {
410
391
    if (-t_length >= keyinfo->maxlength*2+MAX_POINTER_LENGTH)
411
392
    {
412
393
      mi_print_error(info->s, HA_ERR_CRASHED);
413
 
      my_errno=HA_ERR_CRASHED;
 
394
      errno=HA_ERR_CRASHED;
414
395
      return(-1);
415
396
    }
416
 
    memcpy(key_pos, key_pos - t_length, endpos - key_pos + t_length);
 
397
    memmove(key_pos, key_pos - t_length, endpos - key_pos + t_length);
417
398
  }
418
399
  (*keyinfo->store_key)(keyinfo,key_pos,&s_temp);
419
400
  a_length+=t_length;
441
422
{
442
423
  uint32_t length,a_length,key_ref_length,t_length,nod_flag,key_length;
443
424
  unsigned char *key_pos,*pos, *after_key= NULL;
444
 
  my_off_t new_pos;
 
425
  internal::my_off_t new_pos;
445
426
  MI_KEY_PARAM s_temp;
446
427
 
447
428
  if (info->s->keyinfo+info->lastinx == keyinfo)
580
561
    if (!(length=(*keyinfo->get_key)(keyinfo,0,&page,key_buff)))
581
562
    {
582
563
      mi_print_error(keyinfo->share, HA_ERR_CRASHED);
583
 
      my_errno=HA_ERR_CRASHED;
 
564
      errno=HA_ERR_CRASHED;
584
565
      return(0);
585
566
    }
586
567
  }
595
576
 
596
577
static int _mi_balance_page(register MI_INFO *info, MI_KEYDEF *keyinfo,
597
578
                            unsigned char *key, unsigned char *curr_buff, unsigned char *father_buff,
598
 
                            unsigned char *father_key_pos, my_off_t father_page)
 
579
                            unsigned char *father_key_pos, internal::my_off_t father_page)
599
580
{
600
581
  bool right;
601
582
  uint32_t k_length,father_length,father_keylength,nod_flag,curr_keylength,
602
583
       right_length,left_length,new_right_length,new_left_length,extra_length,
603
584
       length,keys;
604
585
  unsigned char *pos,*buff,*extra_buff;
605
 
  my_off_t next_page,new_pos;
 
586
  internal::my_off_t next_page,new_pos;
606
587
  unsigned char tmp_part_key[MI_MAX_KEY_BUFF];
607
588
 
608
589
  k_length=keyinfo->keylength;
655
636
      memcpy(pos+k_length, buff+2, length);
656
637
      pos=buff+2+length;
657
638
      memcpy(father_key_pos, pos, k_length);
658
 
      memcpy(buff+2, pos+k_length, new_right_length);
 
639
      memmove(buff+2, pos+k_length, new_right_length);
659
640
    }
660
641
    else
661
642
    {                                           /* Move keys -> buff */
662
643
 
663
 
      bmove_upp((unsigned char*) buff+new_right_length,(unsigned char*) buff+right_length,
 
644
      internal::bmove_upp((unsigned char*) buff+new_right_length,(unsigned char*) buff+right_length,
664
645
                right_length-2);
665
646
      length=new_right_length-right_length-k_length;
666
647
      memcpy(buff+2+length,father_key_pos, k_length);
693
674
  /* Save new parting key */
694
675
  memcpy(tmp_part_key, pos-k_length,k_length);
695
676
  /* Make place for new keys */
696
 
  bmove_upp((unsigned char*) buff+new_right_length,(unsigned char*) pos-k_length,
 
677
  internal::bmove_upp((unsigned char*) buff+new_right_length,(unsigned char*) pos-k_length,
697
678
            right_length-extra_length-k_length-2);
698
679
  /* Copy keys from left page */
699
680
  pos= curr_buff+new_left_length;
768
749
  case free_init:
769
750
    if (param->info->s->concurrent_insert)
770
751
    {
771
 
      rw_wrlock(&param->info->s->key_root_lock[param->keynr]);
772
752
      param->info->s->keyinfo[param->keynr].version++;
773
753
    }
774
754
    return 0;
779
759
    return _mi_ck_write_btree(param->info,param->keynr,lastkey,
780
760
                              keylen - param->info->s->rec_reflength);
781
761
  case free_end:
782
 
    if (param->info->s->concurrent_insert)
783
 
      rw_unlock(&param->info->s->key_root_lock[param->keynr]);
784
762
    return 0;
785
763
  }
786
764
  return -1;
820
798
    cache_size/=total_keylength*16;
821
799
 
822
800
  info->bulk_insert=(TREE *)
823
 
    my_malloc((sizeof(TREE)*share->base.keys+
824
 
               sizeof(bulk_insert_param)*num_keys),MYF(0));
 
801
    malloc((sizeof(TREE)*share->base.keys+
 
802
           sizeof(bulk_insert_param)*num_keys));
825
803
 
826
804
  if (!info->bulk_insert)
827
805
    return(HA_ERR_OUT_OF_MEM);
837
815
      init_tree(&info->bulk_insert[i],
838
816
                cache_size * key[i].maxlength,
839
817
                cache_size * key[i].maxlength, 0,
840
 
                (qsort_cmp2)keys_compare, 0,
 
818
                (qsort_cmp2)keys_compare, false,
841
819
                (tree_element_free) keys_free, (void *)params++);
842
820
    }
843
821
    else