~ubuntu-branches/ubuntu/hardy/mysql-dfsg-5.0/hardy-proposed

« back to all changes in this revision

Viewing changes to mysys/my_handler.c

  • Committer: Package Import Robot
  • Author(s): Marc Deslauriers
  • Date: 2012-02-23 11:21:11 UTC
  • mfrom: (1.1.16) (38.1.4 hardy-security)
  • Revision ID: package-import@ubuntu.com-20120223112111-rn9ruzg86juli2ec
Tags: 5.0.95-0ubuntu1
* SECURITY UPDATE: Update to 5.0.95 to fix multiple security issues
  (LP: #937869)
  - http://www.oracle.com/technetwork/topics/security/cpujan2012-366304.html
  - CVE-2012-0075
  - CVE-2012-0087
  - CVE-2012-0101
  - CVE-2012-0102
  - CVE-2012-0114
  - CVE-2012-0484
  - CVE-2012-0490
* Dropped patches unnecessary with 5.0.95:
  - debian/patches/91_SECURITY_CVE-2007-5925.dpatch
  - debian/patches/95_SECURITY_CVE-2008-3963.dpatch
  - debian/patches/96_SECURITY_CVE-2008-4098.dpatch
  - debian/patches/97_CVE-2008-4456.dpatch
  - debian/patches/97_CVE-2009-2446.dpatch
  - debian/patches/97_CVE-2009-4019.dpatch
  - debian/patches/97_CVE-2009-4030.dpatch
  - debian/patches/98_CVE-2009-4484.dpatch
  - debian/patches/99_ssl_test_certs.dpatch
  - debian/patches/100_CVE-2010-1850.dpatch
  - debian/patches/101_CVE-2010-1849.dpatch
  - debian/patches/102_CVE-2010-1848.dpatch
  - debian/patches/103_CVE-2010-1626.dpatch
  - debian/patches/98_CVE-2010-3677.dpatch
  - debian/patches/98_CVE-2010-3680.dpatch
  - debian/patches/98_CVE-2010-3681.dpatch
  - debian/patches/98_CVE-2010-3682.dpatch
  - debian/patches/98_CVE-2010-3833.dpatch
  - debian/patches/98_CVE-2010-3834.dpatch
  - debian/patches/98_CVE-2010-3835.dpatch
  - debian/patches/98_CVE-2010-3836.dpatch
  - debian/patches/98_CVE-2010-3837.dpatch
  - debian/patches/98_CVE-2010-3838.dpatch
  - debian/patches/98_CVE-2010-3840.dpatch
  - debian/patches/45_warn-CLI-passwords.dpatch
  - debian/patches/50_fix_mysqldump.dpatch
  - debian/patches/51_incorrect-order.dpatch
  - debian/patches/52_ndb-gcc-4.2.dpatch
  - debian/patches/53_integer-gcc-4.2.dpatch
  - debian/patches/54_ssl-client-support.dpatch
  - debian/patches/55_testsuite-2008.dpatch
  - debian/patches/58-disable-ndb-backup-print.dpatch
  - debian/patches/59-fix-mysql-replication-logs.dpatch
  - debian/patches/86_PATH_MAX.dpatch
  - debian/patches/90_upstreamdebiandir.dpatch
  - debian/patches/92_fix_order_by32202.dpatch
  - debian/patches/93_fix_user_setup_on_localhost.dpatch
  - debian/patches/94_fix_mysqldump_with_old_versions.dpatch
  - debian/patches/56-mysqlhotcopy-invalid-dbtable.dpatch
  - debian/patches/57-fix-mysqlslowdump-config.dpatch
* debian/mysql-client-5.0.docs, debian/mysql-server-5.0.docs: removed
  EXCEPTIONS-CLIENT file
* debian/libmysqlclient15-dev.docs, debian/libmysqlclient15off.docs:
  removed, no longer necessary.
* debian/patches/25_mysys__default.c.dpatch: updated for 5.0.95.
* debian/mysql-server-5.0.files: change ndb_mgmd and ndbd manpage
  locations. Removed mysqlmanagerc.1 and mysqlmanager-pwgen.1

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