~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to storage/myisam/mi_unique.c

  • Committer: Stewart Smith
  • Date: 2008-07-13 06:56:15 UTC
  • mto: (210.1.1 drizzle)
  • mto: This revision was merged to the branch mainline in revision 211.
  • Revision ID: stewart@flamingspork.com-20080713065615-vzok75kgnnviokl9
Move MD5() into a UDF

Show diffs side-by-side

added added

removed removed

Lines of Context:
15
15
 
16
16
/* Functions to check if a row is unique */
17
17
 
18
 
#include "myisam_priv.h"
19
 
#include "drizzled/charset_info.h"
20
 
 
21
 
using namespace drizzled;
22
 
 
23
 
bool mi_check_unique(MI_INFO *info,
24
 
                     MI_UNIQUEDEF *def,
25
 
                     unsigned char *record,
26
 
                     internal::ha_checksum unique_hash,
27
 
                     internal::my_off_t disk_pos)
 
18
#include "myisamdef.h"
 
19
#include <m_ctype.h>
 
20
 
 
21
my_bool mi_check_unique(MI_INFO *info, MI_UNIQUEDEF *def, uchar *record,
 
22
                        ha_checksum unique_hash, my_off_t disk_pos)
28
23
{
29
 
  internal::my_off_t lastpos=info->lastpos;
 
24
  my_off_t lastpos=info->lastpos;
30
25
  MI_KEYDEF *key= &info->s->keyinfo[def->key];
31
 
  unsigned char *key_buff=info->lastkey2;
 
26
  uchar *key_buff=info->lastkey2;
 
27
  DBUG_ENTER("mi_check_unique");
32
28
 
33
29
  mi_unique_store(record+key->seg->start, unique_hash);
34
30
  _mi_make_key(info,def->key,key_buff,record,0);
41
37
  {
42
38
    info->page_changed=1;                       /* Can't optimize read next */
43
39
    info->lastpos= lastpos;
44
 
    return(0);                          /* No matching rows */
 
40
    DBUG_RETURN(0);                             /* No matching rows */
45
41
  }
46
42
 
47
43
  for (;;)
49
45
    if (info->lastpos != disk_pos &&
50
46
        !(*info->s->compare_unique)(info,def,record,info->lastpos))
51
47
    {
52
 
      errno=HA_ERR_FOUND_DUPP_UNIQUE;
 
48
      my_errno=HA_ERR_FOUND_DUPP_UNIQUE;
53
49
      info->errkey= (int) def->key;
54
50
      info->dupp_key_pos= info->lastpos;
55
51
      info->page_changed=1;                     /* Can't optimize read next */
56
52
      info->lastpos=lastpos;
57
 
      return(1);                                /* Found identical  */
 
53
      DBUG_PRINT("info",("Found duplicate"));
 
54
      DBUG_RETURN(1);                           /* Found identical  */
58
55
    }
59
56
    if (_mi_search_next(info,info->s->keyinfo+def->key, info->lastkey,
60
57
                        MI_UNIQUE_HASH_LENGTH, SEARCH_BIGGER,
61
58
                        info->s->state.key_root[def->key]) ||
62
 
        memcmp(info->lastkey, key_buff, MI_UNIQUE_HASH_LENGTH))
 
59
        bcmp((char*) info->lastkey, (char*) key_buff, MI_UNIQUE_HASH_LENGTH))
63
60
    {
64
61
      info->page_changed=1;                     /* Can't optimize read next */
65
62
      info->lastpos=lastpos;
66
 
      return(0);                                /* end of tree */
 
63
      DBUG_RETURN(0);                           /* end of tree */
67
64
    }
68
65
  }
69
66
}
76
73
    Add support for bit fields
77
74
*/
78
75
 
79
 
internal::ha_checksum mi_unique_hash(MI_UNIQUEDEF *def, const unsigned char *record)
 
76
ha_checksum mi_unique_hash(MI_UNIQUEDEF *def, const uchar *record)
80
77
{
81
 
  const unsigned char *pos, *end;
82
 
  internal::ha_checksum crc= 0;
83
 
  uint32_t seed1=0, seed2= 4;
 
78
  const uchar *pos, *end;
 
79
  ha_checksum crc= 0;
 
80
  ulong seed1=0, seed2= 4;
84
81
  HA_KEYSEG *keyseg;
85
82
 
86
83
  for (keyseg=def->seg ; keyseg < def->end ; keyseg++)
87
84
  {
88
85
    enum ha_base_keytype type=(enum ha_base_keytype) keyseg->type;
89
 
    uint32_t length=keyseg->length;
 
86
    uint length=keyseg->length;
90
87
 
91
88
    if (keyseg->null_bit)
92
89
    {
98
95
          done)
99
96
        */
100
97
        crc=((crc << 8) + 511+
101
 
             (crc >> (8*sizeof(internal::ha_checksum)-8)));
 
98
             (crc >> (8*sizeof(ha_checksum)-8)));
102
99
        continue;
103
100
      }
104
101
    }
105
102
    pos= record+keyseg->start;
106
103
    if (keyseg->flag & HA_VAR_LENGTH_PART)
107
104
    {
108
 
      uint32_t pack_length=  keyseg->bit_start;
109
 
      uint32_t tmp_length= (pack_length == 1 ? (uint) *(unsigned char*) pos :
 
105
      uint pack_length=  keyseg->bit_start;
 
106
      uint tmp_length= (pack_length == 1 ? (uint) *(uchar*) pos :
110
107
                        uint2korr(pos));
111
108
      pos+= pack_length;                        /* Skip VARCHAR length */
112
109
      set_if_smaller(length,tmp_length);
113
110
    }
114
111
    else if (keyseg->flag & HA_BLOB_PART)
115
112
    {
116
 
      uint32_t tmp_length=_mi_calc_blob_length(keyseg->bit_start,pos);
117
 
      memcpy(&pos,pos+keyseg->bit_start,sizeof(char*));
 
113
      uint tmp_length=_mi_calc_blob_length(keyseg->bit_start,pos);
 
114
      memcpy_fixed((uchar*) &pos,pos+keyseg->bit_start,sizeof(char*));
118
115
      if (!length || length > tmp_length)
119
116
        length=tmp_length;                      /* The whole blob */
120
117
    }
123
120
        type == HA_KEYTYPE_VARTEXT2)
124
121
    {
125
122
      keyseg->charset->coll->hash_sort(keyseg->charset,
126
 
                                       (const unsigned char*) pos, length, &seed1,
 
123
                                       (const uchar*) pos, length, &seed1,
127
124
                                       &seed2);
128
125
      crc^= seed1;
129
126
    }
130
127
    else
131
128
      while (pos != end)
132
129
        crc=((crc << 8) +
133
 
             (((unsigned char)  *(unsigned char*) pos++))) +
134
 
          (crc >> (8*sizeof(internal::ha_checksum)-8));
 
130
             (((uchar)  *(uchar*) pos++))) +
 
131
          (crc >> (8*sizeof(ha_checksum)-8));
135
132
  }
136
133
  return crc;
137
134
}
148
145
    #   Rows are different
149
146
*/
150
147
 
151
 
int mi_unique_comp(MI_UNIQUEDEF *def, const unsigned char *a, const unsigned char *b,
152
 
                   bool null_are_equal)
 
148
int mi_unique_comp(MI_UNIQUEDEF *def, const uchar *a, const uchar *b,
 
149
                   my_bool null_are_equal)
153
150
{
154
 
  const unsigned char *pos_a, *pos_b, *end;
 
151
  const uchar *pos_a, *pos_b, *end;
155
152
  HA_KEYSEG *keyseg;
156
153
 
157
154
  for (keyseg=def->seg ; keyseg < def->end ; keyseg++)
158
155
  {
159
156
    enum ha_base_keytype type=(enum ha_base_keytype) keyseg->type;
160
 
    uint16_t a_length, b_length;
 
157
    uint a_length, b_length;
161
158
    a_length= b_length= keyseg->length;
162
159
 
163
160
    /* If part is NULL it's regarded as different */
164
161
    if (keyseg->null_bit)
165
162
    {
166
 
      uint32_t tmp;
 
163
      uint tmp;
167
164
      if ((tmp=(a[keyseg->null_pos] & keyseg->null_bit)) !=
168
165
          (uint) (b[keyseg->null_pos] & keyseg->null_bit))
169
166
        return 1;
178
175
    pos_b= b+keyseg->start;
179
176
    if (keyseg->flag & HA_VAR_LENGTH_PART)
180
177
    {
181
 
      uint32_t pack_length= keyseg->bit_start;
 
178
      uint pack_length= keyseg->bit_start;
182
179
      if (pack_length == 1)
183
180
      {
184
 
        a_length= (uint) *(unsigned char*) pos_a++;
185
 
        b_length= (uint) *(unsigned char*) pos_b++;
 
181
        a_length= (uint) *(uchar*) pos_a++;
 
182
        b_length= (uint) *(uchar*) pos_b++;
186
183
      }
187
184
      else
188
185
      {
209
206
        set_if_smaller(a_length, keyseg->length);
210
207
        set_if_smaller(b_length, keyseg->length);
211
208
      }
212
 
      memcpy(&pos_a,pos_a+keyseg->bit_start,sizeof(char*));
213
 
      memcpy(&pos_b,pos_b+keyseg->bit_start,sizeof(char*));
 
209
      memcpy_fixed((uchar*) &pos_a,pos_a+keyseg->bit_start,sizeof(char*));
 
210
      memcpy_fixed((uchar*) &pos_b,pos_b+keyseg->bit_start,sizeof(char*));
214
211
    }
215
212
    if (type == HA_KEYTYPE_TEXT || type == HA_KEYTYPE_VARTEXT1 ||
216
213
        type == HA_KEYTYPE_VARTEXT2)
217
214
    {
218
 
      if (ha_compare_text(keyseg->charset, (unsigned char *) pos_a, a_length,
219
 
                                           (unsigned char *) pos_b, b_length, 0, 1))
 
215
      if (ha_compare_text(keyseg->charset, (uchar *) pos_a, a_length,
 
216
                                           (uchar *) pos_b, b_length, 0, 1))
220
217
        return 1;
221
218
    }
222
219
    else