~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to mysys/my_handler.c

Merged vcol stuff.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
 
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3
 
 *
4
 
 *  Copyright (C) 2008 Sun Microsystems, Inc.
5
 
 *
6
 
 *  This program is free software; you can redistribute it and/or modify
7
 
 *  it under the terms of the GNU General Public License as published by
8
 
 *  the Free Software Foundation; version 2 of the License.
9
 
 *
10
 
 *  This program is distributed in the hope that it will be useful,
11
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 
 *  GNU General Public License for more details.
14
 
 *
15
 
 *  You should have received a copy of the GNU General Public License
16
 
 *  along with this program; if not, write to the Free Software
17
 
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
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 "mysys_priv.h"
 
19
 
 
20
#include <mystrings/m_ctype.h>
 
21
#include <drizzled/base.h>
 
22
#include <my_handler.h>
 
23
#include <my_sys.h>
 
24
 
 
25
#include "my_handler_errors.h"
 
26
 
 
27
/**
 
28
  Swap the contents of two variables.
18
29
 */
19
 
 
20
 
#include "config.h"
21
 
 
22
 
#include "drizzled/charset_info.h"
23
 
#include <drizzled/base.h>
24
 
#include <plugin/myisam/my_handler.h>
25
 
#include "drizzled/internal/my_sys.h"
26
 
 
27
 
#include <cassert>
28
 
#include <algorithm>
29
 
 
30
 
using namespace drizzled;
31
 
using namespace std;
32
 
 
33
 
template<class T>
34
 
int CMP_NUM(const T& a, const T&b)
35
 
{
36
 
  return (a < b) ? -1 : (a == b) ? 0 : 1;
37
 
}
 
30
#define swap_variables(TYPE, a, b) \
 
31
  do {                             \
 
32
    TYPE dummy;                    \
 
33
    dummy= a;                      \
 
34
    a= b;                          \
 
35
    b= dummy;                      \
 
36
  } while (0)
 
37
 
 
38
#define CMP_NUM(a,b) (((a) < (b)) ? -1 : ((a) == (b)) ? 0 : 1)
38
39
 
39
40
 
40
41
int ha_compare_text(const CHARSET_INFO * const charset_info, unsigned char *a, uint32_t a_length,
52
53
static int compare_bin(unsigned char *a, uint32_t a_length, unsigned char *b, uint32_t b_length,
53
54
                       bool part_key, bool skip_end_space)
54
55
{
55
 
  uint32_t length= min(a_length,b_length);
 
56
  uint32_t length= cmin(a_length,b_length);
56
57
  unsigned char *end= a+ length;
57
58
  int flag;
58
59
 
104
105
    next_flag   How keys should be compared
105
106
                If bit SEARCH_FIND is not set the keys includes the row
106
107
                position and this should also be compared
107
 
    diff_pos    OUT Number of first keypart where values differ, counting
 
108
    diff_pos    OUT Number of first keypart where values differ, counting 
108
109
                from one.
109
110
    diff_pos[1] OUT  (b + diff_pos[1]) points to first value in tuple b
110
111
                      that is different from corresponding value in tuple a.
111
 
 
112
 
  EXAMPLES
 
112
  
 
113
  EXAMPLES 
113
114
   Example1: if the function is called for tuples
114
115
     ('aaa','bbb') and ('eee','fff'), then
115
116
     diff_pos[0] = 1 (as 'aaa' != 'eee')
137
138
               uint32_t *diff_pos)
138
139
{
139
140
  int flag;
 
141
  int16_t s_1,s_2;
140
142
  int32_t l_1,l_2;
141
143
  uint32_t u_1,u_2;
 
144
  float f_1,f_2;
142
145
  double d_1,d_2;
143
146
  uint32_t next_key_length;
144
147
  unsigned char *orig_b= b;
178
181
        continue;                               /* To next key part */
179
182
      }
180
183
    }
181
 
    end= a+ min((uint32_t)keyseg->length,key_length);
 
184
    end= a+ cmin(keyseg->length,key_length);
182
185
    next_key_length=key_length-keyseg->length;
183
186
 
184
187
    switch ((enum ha_base_keytype) keyseg->type) {
214
217
      }
215
218
      break;
216
219
    case HA_KEYTYPE_BINARY:
 
220
    case HA_KEYTYPE_BIT:
217
221
      if (keyseg->flag & HA_SPACE_PACK)
218
222
      {
219
223
        int a_length,b_length,pack_length;
264
268
        b+= b_length;
265
269
        break;
266
270
      }
 
271
      break;
267
272
    case HA_KEYTYPE_VARBINARY1:
268
273
    case HA_KEYTYPE_VARBINARY2:
269
274
      {
281
286
        b+=b_length;
282
287
        break;
283
288
      }
 
289
      break;
 
290
    case HA_KEYTYPE_INT8:
 
291
    {
 
292
      int i_1= (int) *((signed char*) a);
 
293
      int i_2= (int) *((signed char*) b);
 
294
      if (piks && (flag = CMP_NUM(i_1,i_2)))
 
295
        return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
 
296
      a= end;
 
297
      b++;
 
298
      break;
 
299
    }
 
300
    case HA_KEYTYPE_SHORT_INT:
 
301
      s_1= mi_sint2korr(a);
 
302
      s_2= mi_sint2korr(b);
 
303
      if (piks && (flag = CMP_NUM(s_1,s_2)))
 
304
        return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
 
305
      a=  end;
 
306
      b+= 2; /* sizeof(short int); */
 
307
      break;
 
308
    case HA_KEYTYPE_USHORT_INT:
 
309
      {
 
310
        uint16_t us_1,us_2;
 
311
        us_1= mi_sint2korr(a);
 
312
        us_2= mi_sint2korr(b);
 
313
        if (piks && (flag = CMP_NUM(us_1,us_2)))
 
314
          return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
 
315
        a=  end;
 
316
        b+=2; /* sizeof(short int); */
 
317
        break;
 
318
      }
284
319
    case HA_KEYTYPE_LONG_INT:
285
320
      l_1= mi_sint4korr(a);
286
321
      l_2= mi_sint4korr(b);
297
332
      a=  end;
298
333
      b+= 4; /* sizeof(long int); */
299
334
      break;
 
335
    case HA_KEYTYPE_INT24:
 
336
      l_1=mi_sint3korr(a);
 
337
      l_2=mi_sint3korr(b);
 
338
      if (piks && (flag = CMP_NUM(l_1,l_2)))
 
339
        return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
 
340
      a=  end;
 
341
      b+= 3;
 
342
      break;
 
343
    case HA_KEYTYPE_UINT24:
 
344
      l_1=mi_uint3korr(a);
 
345
      l_2=mi_uint3korr(b);
 
346
      if (piks && (flag = CMP_NUM(l_1,l_2)))
 
347
        return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
 
348
      a=  end;
 
349
      b+= 3;
 
350
      break;
 
351
    case HA_KEYTYPE_FLOAT:
 
352
      mi_float4get(f_1,a);
 
353
      mi_float4get(f_2,b);
 
354
      /*
 
355
        The following may give a compiler warning about floating point
 
356
        comparison not being safe, but this is ok in this context as
 
357
        we are bascily doing sorting
 
358
      */
 
359
      if (piks && (flag = CMP_NUM(f_1,f_2)))
 
360
        return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
 
361
      a=  end;
 
362
      b+= 4; /* sizeof(float); */
 
363
      break;
300
364
    case HA_KEYTYPE_DOUBLE:
301
365
      mi_float8get(d_1,a);
302
366
      mi_float8get(d_2,b);
310
374
      a=  end;
311
375
      b+= 8;  /* sizeof(double); */
312
376
      break;
 
377
    case HA_KEYTYPE_NUM:                                /* Numeric key */
 
378
    {
 
379
      int swap_flag= 0;
 
380
      int alength,blength;
 
381
 
 
382
      if (keyseg->flag & HA_REVERSE_SORT)
 
383
      {
 
384
        swap_variables(unsigned char*, a, b);
 
385
        swap_flag=1;                            /* Remember swap of a & b */
 
386
        end= a+ (int) (end-b);
 
387
      }
 
388
      if (keyseg->flag & HA_SPACE_PACK)
 
389
      {
 
390
        alength= *a++; blength= *b++;
 
391
        end=a+alength;
 
392
        next_key_length=key_length-blength-1;
 
393
      }
 
394
      else
 
395
      {
 
396
        alength= (int) (end-a);
 
397
        blength=keyseg->length;
 
398
        /* remove pre space from keys */
 
399
        for ( ; alength && *a == ' ' ; a++, alength--) ;
 
400
        for ( ; blength && *b == ' ' ; b++, blength--) ;
 
401
      }
 
402
      if (piks)
 
403
      {
 
404
        if (*a == '-')
 
405
        {
 
406
          if (*b != '-')
 
407
            return -1;
 
408
          a++; b++;
 
409
          swap_variables(unsigned char*, a, b);
 
410
          swap_variables(int, alength, blength);
 
411
          swap_flag=1-swap_flag;
 
412
          alength--; blength--;
 
413
          end=a+alength;
 
414
        }
 
415
        else if (*b == '-')
 
416
          return 1;
 
417
        while (alength && (*a == '+' || *a == '0'))
 
418
        {
 
419
          a++; alength--;
 
420
        }
 
421
        while (blength && (*b == '+' || *b == '0'))
 
422
        {
 
423
          b++; blength--;
 
424
        }
 
425
        if (alength != blength)
 
426
          return (alength < blength) ? -1 : 1;
 
427
        while (a < end)
 
428
          if (*a++ !=  *b++)
 
429
            return ((int) a[-1] - (int) b[-1]);
 
430
      }
 
431
      else
 
432
      {
 
433
        b+=(end-a);
 
434
        a=end;
 
435
      }
 
436
 
 
437
      if (swap_flag)                            /* Restore pointers */
 
438
        swap_variables(unsigned char*, a, b);
 
439
      break;
 
440
    }
313
441
    case HA_KEYTYPE_LONGLONG:
314
442
    {
315
443
      int64_t ll_a,ll_b;
398
526
    switch ((enum ha_base_keytype) keyseg->type) {
399
527
    case HA_KEYTYPE_TEXT:
400
528
    case HA_KEYTYPE_BINARY:
 
529
    case HA_KEYTYPE_BIT:
401
530
      if (keyseg->flag & HA_SPACE_PACK)
402
531
      {
403
532
        int a_length;
418
547
        a+= a_length;
419
548
        break;
420
549
      }
 
550
    case HA_KEYTYPE_NUM:
 
551
      if (keyseg->flag & HA_SPACE_PACK)
 
552
      {
 
553
        int alength= *a++;
 
554
        end= a+alength;
 
555
      }
 
556
      a= end;
 
557
      break;
 
558
    case HA_KEYTYPE_INT8:
 
559
    case HA_KEYTYPE_SHORT_INT:
 
560
    case HA_KEYTYPE_USHORT_INT:
421
561
    case HA_KEYTYPE_LONG_INT:
422
562
    case HA_KEYTYPE_ULONG_INT:
 
563
    case HA_KEYTYPE_INT24:
 
564
    case HA_KEYTYPE_UINT24:
423
565
    case HA_KEYTYPE_LONGLONG:
424
566
    case HA_KEYTYPE_ULONGLONG:
 
567
    case HA_KEYTYPE_FLOAT:
425
568
    case HA_KEYTYPE_DOUBLE:
426
569
      a= end;
427
570
      break;
428
 
    case HA_KEYTYPE_END:
 
571
    case HA_KEYTYPE_END:                        /* purecov: inspected */
429
572
      /* keep compiler happy */
430
573
      assert(0);
431
574
      break;
436
579
 
437
580
 
438
581
 
 
582
/*
 
583
  Register handler error messages for usage with my_error()
 
584
 
 
585
  NOTES
 
586
    This is safe to call multiple times as my_error_register()
 
587
    will ignore calls to register already registered error numbers.
 
588
*/
 
589
 
 
590
 
 
591
void my_handler_error_register(void)
 
592
{
 
593
  /*
 
594
    If you got compilation error here about compile_time_assert array, check
 
595
    that every HA_ERR_xxx constant has a corresponding error message in
 
596
    handler_error_messages[] list (check mysys/ma_handler_errors.h and
 
597
    include/my_base.h).
 
598
 
 
599
    TODO: Remove fix the handler_error_messages so that this hack isn't 
 
600
          necessary.
 
601
  */
 
602
#ifdef __GNUC__
 
603
  char compile_time_assert[(HA_ERR_FIRST +
 
604
                            array_elements(handler_error_messages) ==
 
605
                            HA_ERR_LAST + 1) ? 1 : -1]
 
606
      __attribute__ ((__unused__));
 
607
#endif
 
608
  my_error_register(handler_error_messages, HA_ERR_FIRST,
 
609
                    HA_ERR_FIRST+ array_elements(handler_error_messages)-1);
 
610
}
 
611
 
 
612
 
 
613
void my_handler_error_unregister(void)
 
614
{
 
615
  my_error_unregister(HA_ERR_FIRST,
 
616
                      HA_ERR_FIRST+ array_elements(handler_error_messages)-1);
 
617
}