~mysql/mysql-server/mysql-6.0

« back to all changes in this revision

Viewing changes to sql/sql_string.cc

Merge with 4.0.3
Some simple optimzations, more comments and indentation changes.
Add ` around database in 'use database' in binary log.
Moved max_error_count and max_warning_count to variables struct.
Removed SHOW_WARNS_COUNT and SHOW_ERRORS_COUNT calls.
Changed string functions to use character set of first string argument as default return characterset
(Each string function can change the above assumption if needed)

Show diffs side-by-side

added added

removed removed

Lines of Context:
120
120
  char *pos,*to;
121
121
 
122
122
  VOID(fconvert(num,(int) decimals,&decpt,&sign,buff+1));
123
 
  if (!isdigit(buff[1]))
 
123
  if (!my_isdigit(system_charset_info, buff[1]))
124
124
  {                                             // Nan or Inf
125
125
    pos=buff+1;
126
126
    if (sign)
200
200
  str_length=str.str_length;
201
201
  bmove(Ptr,str.Ptr,str_length);                // May be overlapping
202
202
  Ptr[str_length]=0;
 
203
  str_charset=str.str_charset;
203
204
  return FALSE;
204
205
}
205
206
 
231
232
 
232
233
void String::strip_sp()
233
234
{
234
 
   while (str_length && isspace(Ptr[str_length-1]))
 
235
   while (str_length && my_isspace(str_charset,Ptr[str_length-1]))
235
236
    str_length--;
236
237
}
237
238
 
293
294
  register uint32 n=0,mblen;
294
295
  register const char *mbstr=Ptr;
295
296
  register const char *end=mbstr+str_length;
296
 
  if (use_mb(default_charset_info))
 
297
  if (use_mb(str_charset))
297
298
  {
298
299
    while (mbstr < end) {
299
 
        if ((mblen=my_ismbchar(default_charset_info, mbstr,end))) mbstr+=mblen;
 
300
        if ((mblen=my_ismbchar(str_charset, mbstr,end))) mbstr+=mblen;
300
301
        else ++mbstr;
301
302
        ++n;
302
303
    }
313
314
  register uint32 mblen;
314
315
  register const char *mbstr=Ptr+offset;
315
316
  register const char *end=Ptr+str_length;
316
 
  if (use_mb(default_charset_info))
 
317
  if (use_mb(str_charset))
317
318
  {
318
319
    if (i<=0) return i;
319
320
    while (i && mbstr < end) {
320
 
       if ((mblen=my_ismbchar(default_charset_info, mbstr,end))) mbstr+=mblen;
 
321
       if ((mblen=my_ismbchar(str_charset, mbstr,end))) mbstr+=mblen;
321
322
       else ++mbstr;
322
323
       --i;
323
324
    }
377
378
skipp:
378
379
    while (str != end)
379
380
    {
380
 
      if (my_sort_order[*str++] == my_sort_order[*search])
 
381
      if (str_charset->sort_order[*str++] == str_charset->sort_order[*search])
381
382
      {
382
383
        register char *i,*j;
383
384
        i=(char*) str; j=(char*) search+1;
384
385
        while (j != search_end)
385
 
          if (my_sort_order[*i++] != my_sort_order[*j++]) goto skipp;
 
386
          if (str_charset->sort_order[*i++] != 
 
387
              str_charset->sort_order[*j++]) 
 
388
            goto skipp;
386
389
        return (int) (str-Ptr) -1;
387
390
      }
388
391
    }
456
459
  return FALSE;
457
460
}
458
461
 
 
462
// added by Holyfoot for "geometry" needs
 
463
int String::reserve(uint32 space_needed, uint32 grow_by)
 
464
{
 
465
  if (Alloced_length < str_length + space_needed)
 
466
  {
 
467
    if (realloc(Alloced_length + max(space_needed, grow_by) - 1))
 
468
      return TRUE;
 
469
  }
 
470
  return FALSE;
 
471
}
 
472
 
 
473
void String::qs_append(const char *str)
 
474
{
 
475
  int len = strlen(str);
 
476
  memcpy(Ptr + str_length, str, len + 1);
 
477
  str_length += len;
 
478
}
 
479
 
 
480
void String::qs_append(double d)
 
481
{
 
482
  char *buff = Ptr + str_length;
 
483
  sprintf(buff,"%.14g", d);
 
484
  str_length += strlen(buff);
 
485
}
 
486
 
 
487
void String::qs_append(double *d)
 
488
{
 
489
  double ld;
 
490
  float8get(ld, (char*) d);
 
491
  qs_append(ld);
 
492
}
 
493
 
 
494
void String::qs_append(const char &c)
 
495
{
 
496
  Ptr[str_length] = c;
 
497
  str_length += sizeof(c);
 
498
}
 
499
 
459
500
 
460
501
int sortcmp(const String *x,const String *y)
461
502
{
464
505
  uint32 x_len=x->length(),y_len=y->length(),len=min(x_len,y_len);
465
506
 
466
507
#ifdef USE_STRCOLL
467
 
  if (use_strcoll(default_charset_info))
 
508
  if (use_strcoll(x->str_charset))
468
509
  {
469
510
#ifndef CMP_ENDSPACE
470
 
    while (x_len && isspace(s[x_len-1]))
 
511
    while (x_len && my_isspace(x->str_charset,s[x_len-1]))
471
512
      x_len--;
472
 
    while (y_len && isspace(t[y_len-1]))
 
513
    while (y_len && my_isspace(x->str_charset,t[y_len-1]))
473
514
      y_len--;
474
515
#endif
475
 
    return my_strnncoll(default_charset_info,
 
516
    return my_strnncoll(x->str_charset,
476
517
                        (unsigned char *)s,x_len,(unsigned char *)t,y_len);
477
518
  }
478
519
  else
482
523
    y_len-=len;
483
524
    while (len--)
484
525
    {
485
 
      if (my_sort_order[(uchar) *s++] != my_sort_order[(uchar) *t++])
486
 
        return ((int) my_sort_order[(uchar) s[-1]] -
487
 
                (int) my_sort_order[(uchar) t[-1]]);
 
526
      if (x->str_charset->sort_order[(uchar) *s++] != 
 
527
          x->str_charset->sort_order[(uchar) *t++])
 
528
        return ((int) x->str_charset->sort_order[(uchar) s[-1]] -
 
529
                (int) x->str_charset->sort_order[(uchar) t[-1]]);
488
530
    }
489
531
#ifndef CMP_ENDSPACE
490
532
    /* Don't compare end space in strings */
493
535
      {
494
536
        const char *end=t+y_len;
495
537
        for (; t != end ; t++)
496
 
          if (!isspace(*t))
 
538
          if (!my_isspace(x->str_charset,*t))
497
539
            return -1;
498
540
      }
499
541
      else
500
542
      {
501
543
        const char *end=s+x_len;
502
544
        for (; s != end ; s++)
503
 
          if (!isspace(*s))
 
545
          if (!my_isspace(x->str_charset,*s))
504
546
            return 1;
505
547
      }
506
548
      return 0;
542
584
    return from;                                // Actually an error
543
585
  if ((to->str_length=min(from->str_length,from_length)))
544
586
    memcpy(to->Ptr,from->Ptr,to->str_length);
 
587
  to->str_charset=from->str_charset;
545
588
  return to;
546
589
}
547
590
 
548
591
/* Make it easier to handle different charactersets */
549
592
 
550
593
#ifdef USE_MB
551
 
#define INC_PTR(A,B) A+=((use_mb_flag && \
552
 
                          my_ismbchar(default_charset_info,A,B)) ? \
553
 
                          my_ismbchar(default_charset_info,A,B) : 1)
 
594
#define INC_PTR(cs,A,B) A+=((use_mb_flag && \
 
595
                          my_ismbchar(cs,A,B)) ? my_ismbchar(cs,A,B) : 1)
554
596
#else
555
 
#define INC_PTR(A,B) A++
 
597
#define INC_PTR(cs,A,B) A++
556
598
#endif
557
599
 
558
600
/*
563
605
*/
564
606
 
565
607
#ifdef LIKE_CMP_TOUPPER
566
 
#define likeconv(A) (uchar) toupper(A)
 
608
#define likeconv(s,A) (uchar) my_toupper(s,A)
567
609
#else
568
 
#define likeconv(A) (uchar) my_sort_order[(uchar) (A)]
 
610
#define likeconv(s,A) (uchar) (s)->sort_order[(uchar) (A)]
569
611
#endif
570
612
 
571
 
int wild_case_compare(const char *str,const char *str_end,
 
613
int wild_case_compare(CHARSET_INFO *cs, const char *str,const char *str_end,
572
614
                      const char *wildstr,const char *wildend,
573
615
                      char escape)
574
616
{
575
617
  int result= -1;                               // Not found, using wildcards
576
618
#ifdef USE_MB
577
 
  bool use_mb_flag=use_mb(default_charset_info);
 
619
  bool use_mb_flag=use_mb(cs);
578
620
#endif
579
621
  while (wildstr != wildend)
580
622
  {
585
627
#ifdef USE_MB
586
628
      int l;
587
629
      if (use_mb_flag &&
588
 
          (l = my_ismbchar(default_charset_info, wildstr, wildend)))
 
630
          (l = my_ismbchar(cs, wildstr, wildend)))
589
631
      {
590
632
          if (str+l > str_end || memcmp(str, wildstr, l) != 0)
591
633
              return 1;
594
636
      }
595
637
      else
596
638
#endif
597
 
      if (str == str_end || likeconv(*wildstr++) != likeconv(*str++))
 
639
      if (str == str_end || likeconv(cs,*wildstr++) != likeconv(cs,*str++))
598
640
        return(1);                              // No match
599
641
      if (wildstr == wildend)
600
642
        return (str != str_end);                // Match if both are at end
606
648
      {
607
649
        if (str == str_end)                     // Skip one char if possible
608
650
          return (result);
609
 
        INC_PTR(str,str_end);
 
651
        INC_PTR(cs,str,str_end);
610
652
      } while (++wildstr < wildend && *wildstr == wild_one);
611
653
      if (wildstr == wildend)
612
654
        break;
623
665
        {
624
666
          if (str == str_end)
625
667
            return (-1);
626
 
          INC_PTR(str,str_end);
 
668
          INC_PTR(cs,str,str_end);
627
669
          continue;
628
670
        }
629
671
        break;                                  // Not a wild character
641
683
      int mblen;
642
684
      LINT_INIT(mblen);
643
685
      if (use_mb_flag)
644
 
        mblen = my_ismbchar(default_charset_info, wildstr, wildend);
 
686
        mblen = my_ismbchar(cs, wildstr, wildend);
645
687
#endif
646
 
      INC_PTR(wildstr,wildend);                 // This is compared trough cmp
647
 
      cmp=likeconv(cmp);   
 
688
      INC_PTR(cs,wildstr,wildend);              // This is compared trough cmp
 
689
      cmp=likeconv(cs,cmp);   
648
690
      do
649
691
      {
650
692
#ifdef USE_MB
662
704
                break;
663
705
              }
664
706
            }
665
 
            else if (!my_ismbchar(default_charset_info, str, str_end) &&
666
 
                     likeconv(*str) == cmp)
 
707
            else if (!my_ismbchar(cs, str, str_end) &&
 
708
                     likeconv(cs,*str) == cmp)
667
709
            {
668
710
              str++;
669
711
              break;
670
712
            }
671
 
            INC_PTR(str, str_end);
 
713
            INC_PTR(cs,str, str_end);
672
714
          }
673
715
        }
674
716
        else
675
717
        {
676
718
#endif /* USE_MB */
677
 
          while (str != str_end && likeconv(*str) != cmp)
 
719
          while (str != str_end && likeconv(cs,*str) != cmp)
678
720
            str++;
679
721
          if (str++ == str_end) return (-1);
680
722
#ifdef USE_MB
681
723
        }
682
724
#endif
683
725
        {
684
 
          int tmp=wild_case_compare(str,str_end,wildstr,wildend,escape);
 
726
          int tmp=wild_case_compare(cs,str,str_end,wildstr,wildend,escape);
685
727
          if (tmp <= 0)
686
728
            return (tmp);
687
729
        }
698
740
  DBUG_ENTER("wild_case_compare");
699
741
  DBUG_PRINT("enter",("match='%s', wild='%s', escape='%c'"
700
742
                          ,match.ptr(),wild.ptr(),escape));
701
 
  DBUG_RETURN(wild_case_compare(match.ptr(),match.ptr()+match.length(),
 
743
  DBUG_RETURN(wild_case_compare(match.str_charset,match.ptr(),match.ptr()+match.length(),
702
744
                           wild.ptr(), wild.ptr()+wild.length(),escape));
703
745
}
704
746
 
802
844
  DBUG_RETURN(wild_compare(match.ptr(),match.ptr()+match.length(),
803
845
                      wild.ptr(), wild.ptr()+wild.length(),escape));
804
846
}
 
847
 
 
848