~linuxjedi/drizzle/trunk-bug-667053

« back to all changes in this revision

Viewing changes to mysys/my_handler.c

  • Committer: brian
  • Date: 2008-06-25 05:29:13 UTC
  • Revision ID: brian@localhost.localdomain-20080625052913-6upwo0jsrl4lnapl
clean slate

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright (C) 2002-2006 MySQL AB
 
2
   
 
3
   This library is free software; you can redistribute it and/or
 
4
   modify it under the terms of the GNU Library General Public
 
5
   License as published by the Free Software Foundation; version 2
 
6
   of the License.
 
7
   
 
8
   This library is distributed in the hope that it will be useful,
 
9
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
10
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
11
   Library General Public License for more details.
 
12
 
 
13
   You should have received a copy of the GNU Library General Public
 
14
   License along with this library; if not, write to the Free
 
15
   Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
 
16
   MA 02111-1307, USA */
 
17
 
 
18
#include <my_global.h>
 
19
#include <m_ctype.h>
 
20
#include <my_base.h>
 
21
#include <my_handler.h>
 
22
#include <my_sys.h>
 
23
 
 
24
#include "my_handler_errors.h"
 
25
 
 
26
int ha_compare_text(CHARSET_INFO *charset_info, uchar *a, uint a_length,
 
27
                    uchar *b, uint b_length, my_bool part_key,
 
28
                    my_bool skip_end_space)
 
29
{
 
30
  if (!part_key)
 
31
    return charset_info->coll->strnncollsp(charset_info, a, a_length,
 
32
                                           b, b_length, (my_bool)!skip_end_space);
 
33
  return charset_info->coll->strnncoll(charset_info, a, a_length,
 
34
                                       b, b_length, part_key);
 
35
}
 
36
 
 
37
 
 
38
static int compare_bin(uchar *a, uint a_length, uchar *b, uint b_length,
 
39
                       my_bool part_key, my_bool skip_end_space)
 
40
{
 
41
  uint length= min(a_length,b_length);
 
42
  uchar *end= a+ length;
 
43
  int flag;
 
44
 
 
45
  while (a < end)
 
46
    if ((flag= (int) *a++ - (int) *b++))
 
47
      return flag;
 
48
  if (part_key && b_length < a_length)
 
49
    return 0;
 
50
  if (skip_end_space && a_length != b_length)
 
51
  {
 
52
    int swap= 1;
 
53
    /*
 
54
      We are using space compression. We have to check if longer key
 
55
      has next character < ' ', in which case it's less than the shorter
 
56
      key that has an implicite space afterwards.
 
57
 
 
58
      This code is identical to the one in
 
59
      strings/ctype-simple.c:my_strnncollsp_simple
 
60
    */
 
61
    if (a_length < b_length)
 
62
    {
 
63
      /* put shorter key in a */
 
64
      a_length= b_length;
 
65
      a= b;
 
66
      swap= -1;                                 /* swap sign of result */
 
67
    }
 
68
    for (end= a + a_length-length; a < end ; a++)
 
69
    {
 
70
      if (*a != ' ')
 
71
        return (*a < ' ') ? -swap : swap;
 
72
    }
 
73
    return 0;
 
74
  }
 
75
  return (int) (a_length-b_length);
 
76
}
 
77
 
 
78
 
 
79
/*
 
80
  Compare two keys
 
81
 
 
82
  SYNOPSIS
 
83
    ha_key_cmp()
 
84
    keyseg      Array of key segments of key to compare
 
85
    a           First key to compare, in format from _mi_pack_key()
 
86
                This is normally key specified by user
 
87
    b           Second key to compare.  This is always from a row
 
88
    key_length  Length of key to compare.  This can be shorter than
 
89
                a to just compare sub keys
 
90
    next_flag   How keys should be compared
 
91
                If bit SEARCH_FIND is not set the keys includes the row
 
92
                position and this should also be compared
 
93
    diff_pos    OUT Number of first keypart where values differ, counting 
 
94
                from one.
 
95
    diff_pos[1] OUT  (b + diff_pos[1]) points to first value in tuple b
 
96
                      that is different from corresponding value in tuple a.
 
97
  
 
98
  EXAMPLES 
 
99
   Example1: if the function is called for tuples
 
100
     ('aaa','bbb') and ('eee','fff'), then
 
101
     diff_pos[0] = 1 (as 'aaa' != 'eee')
 
102
     diff_pos[1] = 0 (offset from beggining of tuple b to 'eee' keypart).
 
103
 
 
104
   Example2: if the index function is called for tuples
 
105
     ('aaa','bbb') and ('aaa','fff'),
 
106
     diff_pos[0] = 2 (as 'aaa' != 'eee')
 
107
     diff_pos[1] = 3 (offset from beggining of tuple b to 'fff' keypart,
 
108
                      here we assume that first key part is CHAR(3) NOT NULL)
 
109
 
 
110
  NOTES
 
111
    Number-keys can't be splited
 
112
 
 
113
  RETURN VALUES
 
114
    <0  If a < b
 
115
    0   If a == b
 
116
    >0  If a > b
 
117
*/
 
118
 
 
119
#define FCMP(A,B) ((int) (A) - (int) (B))
 
120
 
 
121
int ha_key_cmp(register HA_KEYSEG *keyseg, register uchar *a,
 
122
               register uchar *b, uint key_length, uint nextflag,
 
123
               uint *diff_pos)
 
124
{
 
125
  int flag;
 
126
  int16 s_1,s_2;
 
127
  int32 l_1,l_2;
 
128
  uint32 u_1,u_2;
 
129
  float f_1,f_2;
 
130
  double d_1,d_2;
 
131
  uint next_key_length;
 
132
  uchar *orig_b= b;
 
133
 
 
134
  *diff_pos=0;
 
135
  for ( ; (int) key_length >0 ; key_length=next_key_length, keyseg++)
 
136
  {
 
137
    uchar *end;
 
138
    uint piks=! (keyseg->flag & HA_NO_SORT);
 
139
    (*diff_pos)++;
 
140
    diff_pos[1]= (uint)(b - orig_b);
 
141
 
 
142
    /* Handle NULL part */
 
143
    if (keyseg->null_bit)
 
144
    {
 
145
      key_length--;
 
146
      if (*a != *b && piks)
 
147
      {
 
148
        flag = (int) *a - (int) *b;
 
149
        return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
 
150
      }
 
151
      b++;
 
152
      if (!*a++)                                /* If key was NULL */
 
153
      {
 
154
        if (nextflag == (SEARCH_FIND | SEARCH_UPDATE))
 
155
          nextflag=SEARCH_SAME;                 /* Allow duplicate keys */
 
156
        else if (nextflag & SEARCH_NULL_ARE_NOT_EQUAL)
 
157
        {
 
158
          /*
 
159
            This is only used from mi_check() to calculate cardinality.
 
160
            It can't be used when searching for a key as this would cause
 
161
            compare of (a,b) and (b,a) to return the same value.
 
162
          */
 
163
          return -1;
 
164
        }
 
165
        next_key_length=key_length;
 
166
        continue;                               /* To next key part */
 
167
      }
 
168
    }
 
169
    end= a+ min(keyseg->length,key_length);
 
170
    next_key_length=key_length-keyseg->length;
 
171
 
 
172
    switch ((enum ha_base_keytype) keyseg->type) {
 
173
    case HA_KEYTYPE_TEXT:                       /* Ascii; Key is converted */
 
174
      if (keyseg->flag & HA_SPACE_PACK)
 
175
      {
 
176
        int a_length,b_length,pack_length;
 
177
        get_key_length(a_length,a);
 
178
        get_key_pack_length(b_length,pack_length,b);
 
179
        next_key_length=key_length-b_length-pack_length;
 
180
 
 
181
        if (piks &&
 
182
            (flag=ha_compare_text(keyseg->charset,a,a_length,b,b_length,
 
183
                                  (my_bool) ((nextflag & SEARCH_PREFIX) &&
 
184
                                             next_key_length <= 0),
 
185
                                  (my_bool)!(nextflag & SEARCH_PREFIX))))
 
186
          return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
 
187
        a+=a_length;
 
188
        b+=b_length;
 
189
        break;
 
190
      }
 
191
      else
 
192
      {
 
193
        uint length=(uint) (end-a), a_length=length, b_length=length;
 
194
        if (piks &&
 
195
            (flag= ha_compare_text(keyseg->charset, a, a_length, b, b_length,
 
196
                                   (my_bool) ((nextflag & SEARCH_PREFIX) &&
 
197
                                              next_key_length <= 0),
 
198
                                   (my_bool)!(nextflag & SEARCH_PREFIX))))
 
199
          return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
 
200
        a=end;
 
201
        b+=length;
 
202
      }
 
203
      break;
 
204
    case HA_KEYTYPE_BINARY:
 
205
    case HA_KEYTYPE_BIT:
 
206
      if (keyseg->flag & HA_SPACE_PACK)
 
207
      {
 
208
        int a_length,b_length,pack_length;
 
209
        get_key_length(a_length,a);
 
210
        get_key_pack_length(b_length,pack_length,b);
 
211
        next_key_length=key_length-b_length-pack_length;
 
212
 
 
213
        if (piks &&
 
214
            (flag=compare_bin(a,a_length,b,b_length,
 
215
                              (my_bool) ((nextflag & SEARCH_PREFIX) &&
 
216
                                         next_key_length <= 0),1)))
 
217
          return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
 
218
        a+=a_length;
 
219
        b+=b_length;
 
220
        break;
 
221
      }
 
222
      else
 
223
      {
 
224
        uint length=keyseg->length;
 
225
        if (piks &&
 
226
            (flag=compare_bin(a,length,b,length,
 
227
                              (my_bool) ((nextflag & SEARCH_PREFIX) &&
 
228
                                         next_key_length <= 0),0)))
 
229
          return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
 
230
        a+=length;
 
231
        b+=length;
 
232
      }
 
233
      break;
 
234
    case HA_KEYTYPE_VARTEXT1:
 
235
    case HA_KEYTYPE_VARTEXT2:
 
236
      {
 
237
        int a_length,b_length,pack_length;
 
238
        get_key_length(a_length,a);
 
239
        get_key_pack_length(b_length,pack_length,b);
 
240
        next_key_length=key_length-b_length-pack_length;
 
241
 
 
242
        if (piks &&
 
243
            (flag= ha_compare_text(keyseg->charset,a,a_length,b,b_length,
 
244
                                   (my_bool) ((nextflag & SEARCH_PREFIX) &&
 
245
                                              next_key_length <= 0),
 
246
                                   (my_bool) ((nextflag & (SEARCH_FIND |
 
247
                                                           SEARCH_UPDATE)) ==
 
248
                                              SEARCH_FIND &&
 
249
                                              ! (keyseg->flag &
 
250
                                                 HA_END_SPACE_ARE_EQUAL)))))
 
251
          return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
 
252
        a+= a_length;
 
253
        b+= b_length;
 
254
        break;
 
255
      }
 
256
      break;
 
257
    case HA_KEYTYPE_VARBINARY1:
 
258
    case HA_KEYTYPE_VARBINARY2:
 
259
      {
 
260
        int a_length,b_length,pack_length;
 
261
        get_key_length(a_length,a);
 
262
        get_key_pack_length(b_length,pack_length,b);
 
263
        next_key_length=key_length-b_length-pack_length;
 
264
 
 
265
        if (piks &&
 
266
            (flag=compare_bin(a,a_length,b,b_length,
 
267
                              (my_bool) ((nextflag & SEARCH_PREFIX) &&
 
268
                                         next_key_length <= 0), 0)))
 
269
          return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
 
270
        a+=a_length;
 
271
        b+=b_length;
 
272
        break;
 
273
      }
 
274
      break;
 
275
    case HA_KEYTYPE_INT8:
 
276
    {
 
277
      int i_1= (int) *((signed char*) a);
 
278
      int i_2= (int) *((signed char*) b);
 
279
      if (piks && (flag = CMP_NUM(i_1,i_2)))
 
280
        return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
 
281
      a= end;
 
282
      b++;
 
283
      break;
 
284
    }
 
285
    case HA_KEYTYPE_SHORT_INT:
 
286
      s_1= mi_sint2korr(a);
 
287
      s_2= mi_sint2korr(b);
 
288
      if (piks && (flag = CMP_NUM(s_1,s_2)))
 
289
        return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
 
290
      a=  end;
 
291
      b+= 2; /* sizeof(short int); */
 
292
      break;
 
293
    case HA_KEYTYPE_USHORT_INT:
 
294
      {
 
295
        uint16 us_1,us_2;
 
296
        us_1= mi_sint2korr(a);
 
297
        us_2= mi_sint2korr(b);
 
298
        if (piks && (flag = CMP_NUM(us_1,us_2)))
 
299
          return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
 
300
        a=  end;
 
301
        b+=2; /* sizeof(short int); */
 
302
        break;
 
303
      }
 
304
    case HA_KEYTYPE_LONG_INT:
 
305
      l_1= mi_sint4korr(a);
 
306
      l_2= mi_sint4korr(b);
 
307
      if (piks && (flag = CMP_NUM(l_1,l_2)))
 
308
        return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
 
309
      a=  end;
 
310
      b+= 4; /* sizeof(long int); */
 
311
      break;
 
312
    case HA_KEYTYPE_ULONG_INT:
 
313
      u_1= mi_sint4korr(a);
 
314
      u_2= mi_sint4korr(b);
 
315
      if (piks && (flag = CMP_NUM(u_1,u_2)))
 
316
        return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
 
317
      a=  end;
 
318
      b+= 4; /* sizeof(long int); */
 
319
      break;
 
320
    case HA_KEYTYPE_INT24:
 
321
      l_1=mi_sint3korr(a);
 
322
      l_2=mi_sint3korr(b);
 
323
      if (piks && (flag = CMP_NUM(l_1,l_2)))
 
324
        return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
 
325
      a=  end;
 
326
      b+= 3;
 
327
      break;
 
328
    case HA_KEYTYPE_UINT24:
 
329
      l_1=mi_uint3korr(a);
 
330
      l_2=mi_uint3korr(b);
 
331
      if (piks && (flag = CMP_NUM(l_1,l_2)))
 
332
        return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
 
333
      a=  end;
 
334
      b+= 3;
 
335
      break;
 
336
    case HA_KEYTYPE_FLOAT:
 
337
      mi_float4get(f_1,a);
 
338
      mi_float4get(f_2,b);
 
339
      /*
 
340
        The following may give a compiler warning about floating point
 
341
        comparison not being safe, but this is ok in this context as
 
342
        we are bascily doing sorting
 
343
      */
 
344
      if (piks && (flag = CMP_NUM(f_1,f_2)))
 
345
        return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
 
346
      a=  end;
 
347
      b+= 4; /* sizeof(float); */
 
348
      break;
 
349
    case HA_KEYTYPE_DOUBLE:
 
350
      mi_float8get(d_1,a);
 
351
      mi_float8get(d_2,b);
 
352
      /*
 
353
        The following may give a compiler warning about floating point
 
354
        comparison not being safe, but this is ok in this context as
 
355
        we are bascily doing sorting
 
356
      */
 
357
      if (piks && (flag = CMP_NUM(d_1,d_2)))
 
358
        return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
 
359
      a=  end;
 
360
      b+= 8;  /* sizeof(double); */
 
361
      break;
 
362
    case HA_KEYTYPE_NUM:                                /* Numeric key */
 
363
    {
 
364
      int swap_flag= 0;
 
365
      int alength,blength;
 
366
 
 
367
      if (keyseg->flag & HA_REVERSE_SORT)
 
368
      {
 
369
        swap_variables(uchar*, a, b);
 
370
        swap_flag=1;                            /* Remember swap of a & b */
 
371
        end= a+ (int) (end-b);
 
372
      }
 
373
      if (keyseg->flag & HA_SPACE_PACK)
 
374
      {
 
375
        alength= *a++; blength= *b++;
 
376
        end=a+alength;
 
377
        next_key_length=key_length-blength-1;
 
378
      }
 
379
      else
 
380
      {
 
381
        alength= (int) (end-a);
 
382
        blength=keyseg->length;
 
383
        /* remove pre space from keys */
 
384
        for ( ; alength && *a == ' ' ; a++, alength--) ;
 
385
        for ( ; blength && *b == ' ' ; b++, blength--) ;
 
386
      }
 
387
      if (piks)
 
388
      {
 
389
        if (*a == '-')
 
390
        {
 
391
          if (*b != '-')
 
392
            return -1;
 
393
          a++; b++;
 
394
          swap_variables(uchar*, a, b);
 
395
          swap_variables(int, alength, blength);
 
396
          swap_flag=1-swap_flag;
 
397
          alength--; blength--;
 
398
          end=a+alength;
 
399
        }
 
400
        else if (*b == '-')
 
401
          return 1;
 
402
        while (alength && (*a == '+' || *a == '0'))
 
403
        {
 
404
          a++; alength--;
 
405
        }
 
406
        while (blength && (*b == '+' || *b == '0'))
 
407
        {
 
408
          b++; blength--;
 
409
        }
 
410
        if (alength != blength)
 
411
          return (alength < blength) ? -1 : 1;
 
412
        while (a < end)
 
413
          if (*a++ !=  *b++)
 
414
            return ((int) a[-1] - (int) b[-1]);
 
415
      }
 
416
      else
 
417
      {
 
418
        b+=(end-a);
 
419
        a=end;
 
420
      }
 
421
 
 
422
      if (swap_flag)                            /* Restore pointers */
 
423
        swap_variables(uchar*, a, b);
 
424
      break;
 
425
    }
 
426
#ifdef HAVE_LONG_LONG
 
427
    case HA_KEYTYPE_LONGLONG:
 
428
    {
 
429
      longlong ll_a,ll_b;
 
430
      ll_a= mi_sint8korr(a);
 
431
      ll_b= mi_sint8korr(b);
 
432
      if (piks && (flag = CMP_NUM(ll_a,ll_b)))
 
433
        return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
 
434
      a=  end;
 
435
      b+= 8;
 
436
      break;
 
437
    }
 
438
    case HA_KEYTYPE_ULONGLONG:
 
439
    {
 
440
      ulonglong ll_a,ll_b;
 
441
      ll_a= mi_uint8korr(a);
 
442
      ll_b= mi_uint8korr(b);
 
443
      if (piks && (flag = CMP_NUM(ll_a,ll_b)))
 
444
        return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
 
445
      a=  end;
 
446
      b+= 8;
 
447
      break;
 
448
    }
 
449
#endif
 
450
    case HA_KEYTYPE_END:                        /* Ready */
 
451
      goto end;                                 /* diff_pos is incremented */
 
452
    }
 
453
  }
 
454
  (*diff_pos)++;
 
455
end:
 
456
  if (!(nextflag & SEARCH_FIND))
 
457
  {
 
458
    uint i;
 
459
    if (nextflag & (SEARCH_NO_FIND | SEARCH_LAST)) /* Find record after key */
 
460
      return (nextflag & (SEARCH_BIGGER | SEARCH_LAST)) ? -1 : 1;
 
461
    flag=0;
 
462
    for (i=keyseg->length ; i-- > 0 ; )
 
463
    {
 
464
      if (*a++ != *b++)
 
465
      {
 
466
        flag= FCMP(a[-1],b[-1]);
 
467
        break;
 
468
      }
 
469
    }
 
470
    if (nextflag & SEARCH_SAME)
 
471
      return (flag);                            /* read same */
 
472
    if (nextflag & SEARCH_BIGGER)
 
473
      return (flag <= 0 ? -1 : 1);              /* read next */
 
474
    return (flag < 0 ? -1 : 1);                 /* read previous */
 
475
  }
 
476
  return 0;
 
477
} /* ha_key_cmp */
 
478
 
 
479
 
 
480
/*
 
481
  Find the first NULL value in index-suffix values tuple
 
482
 
 
483
  SYNOPSIS
 
484
    ha_find_null()
 
485
      keyseg     Array of keyparts for key suffix
 
486
      a          Key suffix value tuple
 
487
 
 
488
  DESCRIPTION
 
489
    Find the first NULL value in index-suffix values tuple.
 
490
 
 
491
  TODO
 
492
    Consider optimizing this function or its use so we don't search for
 
493
    NULL values in completely NOT NULL index suffixes.
 
494
 
 
495
  RETURN
 
496
    First key part that has NULL as value in values tuple, or the last key
 
497
    part (with keyseg->type==HA_TYPE_END) if values tuple doesn't contain
 
498
    NULLs.
 
499
*/
 
500
 
 
501
HA_KEYSEG *ha_find_null(HA_KEYSEG *keyseg, uchar *a)
 
502
{
 
503
  for (; (enum ha_base_keytype) keyseg->type != HA_KEYTYPE_END; keyseg++)
 
504
  {
 
505
    uchar *end;
 
506
    if (keyseg->null_bit)
 
507
    {
 
508
      if (!*a++)
 
509
        return keyseg;
 
510
    }
 
511
    end= a+ keyseg->length;
 
512
 
 
513
    switch ((enum ha_base_keytype) keyseg->type) {
 
514
    case HA_KEYTYPE_TEXT:
 
515
    case HA_KEYTYPE_BINARY:
 
516
    case HA_KEYTYPE_BIT:
 
517
      if (keyseg->flag & HA_SPACE_PACK)
 
518
      {
 
519
        int a_length;
 
520
        get_key_length(a_length, a);
 
521
        a += a_length;
 
522
        break;
 
523
      }
 
524
      else
 
525
        a= end;
 
526
      break;
 
527
    case HA_KEYTYPE_VARTEXT1:
 
528
    case HA_KEYTYPE_VARTEXT2:
 
529
    case HA_KEYTYPE_VARBINARY1:
 
530
    case HA_KEYTYPE_VARBINARY2:
 
531
      {
 
532
        int a_length;
 
533
        get_key_length(a_length, a);
 
534
        a+= a_length;
 
535
        break;
 
536
      }
 
537
    case HA_KEYTYPE_NUM:
 
538
      if (keyseg->flag & HA_SPACE_PACK)
 
539
      {
 
540
        int alength= *a++;
 
541
        end= a+alength;
 
542
      }
 
543
      a= end;
 
544
      break;
 
545
    case HA_KEYTYPE_INT8:
 
546
    case HA_KEYTYPE_SHORT_INT:
 
547
    case HA_KEYTYPE_USHORT_INT:
 
548
    case HA_KEYTYPE_LONG_INT:
 
549
    case HA_KEYTYPE_ULONG_INT:
 
550
    case HA_KEYTYPE_INT24:
 
551
    case HA_KEYTYPE_UINT24:
 
552
#ifdef HAVE_LONG_LONG
 
553
    case HA_KEYTYPE_LONGLONG:
 
554
    case HA_KEYTYPE_ULONGLONG:
 
555
#endif
 
556
    case HA_KEYTYPE_FLOAT:
 
557
    case HA_KEYTYPE_DOUBLE:
 
558
      a= end;
 
559
      break;
 
560
    case HA_KEYTYPE_END:                        /* purecov: inspected */
 
561
      /* keep compiler happy */
 
562
      DBUG_ASSERT(0);
 
563
      break;
 
564
    }
 
565
  }
 
566
  return keyseg;
 
567
}
 
568
 
 
569
 
 
570
 
 
571
/*
 
572
  Register handler error messages for usage with my_error()
 
573
 
 
574
  NOTES
 
575
    This is safe to call multiple times as my_error_register()
 
576
    will ignore calls to register already registered error numbers.
 
577
*/
 
578
 
 
579
 
 
580
void my_handler_error_register(void)
 
581
{
 
582
  /*
 
583
    If you got compilation error here about compile_time_assert array, check
 
584
    that every HA_ERR_xxx constant has a corresponding error message in
 
585
    handler_error_messages[] list (check mysys/ma_handler_errors.h and
 
586
    include/my_base.h).
 
587
  */
 
588
  compile_time_assert(HA_ERR_FIRST + array_elements(handler_error_messages) ==
 
589
                      HA_ERR_LAST + 1);
 
590
  my_error_register(handler_error_messages, HA_ERR_FIRST,
 
591
                    HA_ERR_FIRST+ array_elements(handler_error_messages)-1);
 
592
}
 
593
 
 
594
 
 
595
void my_handler_error_unregister(void)
 
596
{
 
597
  my_error_unregister(HA_ERR_FIRST,
 
598
                      HA_ERR_FIRST+ array_elements(handler_error_messages)-1);
 
599
}