List:Commits« Previous MessageNext Message »
From:bar Date:December 13 2005 11:38am
Subject:bk commit into 5.1 tree (bar:1.1958)
View as plain text  
Below is the list of changes that have just been committed into a local
5.1 repository of bar. When bar does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html

ChangeSet
  1.1958 05/12/13 15:37:52 bar@stripped +4 -0
    WL#2993  Add Hungarian collations for cp1250, latin2, utf8, ucs2
  ctype_uca.result, ctype_uca.test:
    Adding test case.
  ctype-uca.c:
    1. New code to process complex contraction:
       - consisting of 2,3, or 4 characters
       - producing 1 weight, or
       - producing 2 weights (i.e. contraction with expansion)
    2. Adding utf8_hungarian_ci using the new code.
    3. Splitting create_tailoring() into two parts:
       - create_tailoring_for_non_contractions()
       - create_tailoring_for_simple_contractions()
       to reuse part of the old code in the new functions.
    4. Introducing a new collation flag MY_CS_COMPLEX_CONTRACTION,
       to switch between the old "simple contractions" and
       the new "complex contractions" argorithms during processing.
  
  charset-def.c:
    Adding new collations.
  
  TODO:
    1. Fix tailoring parser to understand complex contractions
      (currently Hungarian rules are hardcoded as a MY_COLL_RULE array,
       instead of parsing a tailoring string).
    2. resuse the same code for cp1250, latin2 and ucs2.

  mysql-test/r/ctype_uca.result
    1.17 05/12/13 15:24:21 bar@stripped +214 -0
    Adding test case.

  mysql-test/t/ctype_uca.test
    1.15 05/12/13 15:24:13 bar@stripped +216 -0
    Adding test case.

  strings/ctype-uca.c
    1.40 05/12/13 15:23:46 bar@stripped +688 -88
    Adding code to process complex contraction,
    and adding utf8_hungarian_ci using the new code.

  mysys/charset-def.c
    1.15 05/12/13 15:22:52 bar@stripped +2 -0
    WL#2993  Add Hungarian collations for cp1250, latin2, utf8, ucs2
    Adding new collations.

# This is a BitKeeper patch.  What follows are the unified diffs for the
# set of deltas contained in the patch.  The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User:	bar
# Host:	bar.intranet.mysql.r18.ru
# Root:	/usr/home/bar/mysql-5.1-new.hu

--- 1.39/strings/ctype-uca.c	2005-10-13 19:10:09 +05:00
+++ 1.40/strings/ctype-uca.c	2005-12-13 15:23:46 +04:00
@@ -38,6 +38,7 @@
 
 #ifdef HAVE_UCA_COLLATIONS
 
+
 #define MY_UCA_NPAGES 256
 #define MY_UCA_NCHARS 256
 #define MY_UCA_CMASK  255
@@ -6705,6 +6706,29 @@
     "& S < \\u015d <<< \\u015c"
     "& U < \\u016d <<< \\u016c";
 
+
+#define MY_CS_COMPLEX_CONTRACTION	0x4000
+#define MY_CNT1 1
+#define MY_CNT2 2
+#define MY_CNT3 4
+#define MY_CNT4 8
+
+typedef struct cont_hrd_st
+{
+  uint16 min_char;
+  uint16 max_char;
+  uint16 num_pos;     /* Number of characters in contraction */
+  uint16 num_chars;   /* max_char - min_char + 1             */
+  uint16 num_weights;
+  uint16 weight_len;
+  uint16 posnum[4];
+  uint16 posfactor[4];
+  uint16 *code[4];
+  uint16 *flag;
+  uint16 *weight;
+} MY_CONT_HDR;
+
+
 /*
   Unicode Collation Algorithm:
   Collation element (weight) scanner, 
@@ -6904,6 +6928,7 @@
   scanner->cs= cs;
 }
 
+
 static int my_uca_scanner_next_any(my_uca_scanner *scanner)
 {
   
@@ -6932,23 +6957,94 @@
     scanner->code= wc & 0xFF;
     scanner->sbeg+= mblen;
     
-    if (scanner->contractions && !scanner->page &&
-        (scanner->code > 0x40) && (scanner->code < 0x80))
+    if (scanner->contractions)
     {
-      uint page1, code1, cweight;
-      
-      if (((mblen= scanner->cs->cset->mb_wc(scanner->cs, &wc,
-                                            scanner->sbeg, 
-                                            scanner->send)) >=0) &&
-           (!(page1= (wc >> 8))) &&
-           ((code1= (wc & 0xFF)) > 0x40) &&
-           (code1 < 0x80) && 
-           (cweight= scanner->contractions[(scanner->code-0x40)*0x40 + code1-0x40]))
+      if (!(scanner->cs->state & MY_CS_COMPLEX_CONTRACTION))
+      {
+        /* Collation with simple contractions */ 
+        if (!scanner->page &&
+           (scanner->code > 0x40) && (scanner->code < 0x80))
+        {
+          uint page1, code1, cweight;
+
+          if (((mblen= scanner->cs->cset->mb_wc(scanner->cs, &wc,
+                                                scanner->sbeg, 
+                                                scanner->send)) >=0) &&
+               (!(page1= (wc >> 8))) &&
+               ((code1= (wc & 0xFF)) > 0x40) &&
+               (code1 < 0x80) && 
+               (cweight= scanner->contractions[(scanner->code-0x40)*0x40 +
+                                               code1-0x40]))
+          {
+            scanner->implicit[0]= 0;
+            scanner->wbeg= scanner->implicit;
+            scanner->sbeg+= mblen;
+            return cweight;
+          }
+        }
+      }
+      else
       {
-        scanner->implicit[0]= 0;
-        scanner->wbeg= scanner->implicit;
-        scanner->sbeg+= mblen;
-        return cweight;
+        /* Collation with complex contractions */
+        uint addr;
+        uint16 *weight;
+        MY_CONT_HDR *cont= (MY_CONT_HDR*) scanner->cs->contractions;
+        if (wc <= cont->max_char && (cont->flag[wc] & MY_CNT1))
+        {
+          my_wc_t wc1;
+          int mblen1;
+          if ((mblen1= scanner->cs->cset->mb_wc(scanner->cs, &wc1,
+                                                scanner->sbeg, 
+                                                scanner->send)) > 0 &&
+              wc1 <= cont->max_char && (cont->flag[wc1] & MY_CNT2))
+          {
+            my_wc_t wc2;
+            int mblen2;
+            if ((mblen2= scanner->cs->cset->mb_wc(scanner->cs, &wc2,
+                                                  scanner->sbeg + mblen1, 
+                                                  scanner->send)) > 0 &&
+                wc2 <= cont->max_char && (cont->flag[wc2] & MY_CNT3))
+            {
+              my_wc_t wc3;
+              int mblen3;
+              if ((mblen3= scanner->cs->cset->mb_wc(scanner->cs, &wc3,
+                                                    scanner->sbeg +
+                                                    mblen1 + mblen2,
+                                                    scanner->send)) > 0 &&
+                wc2 <= cont->max_char && (cont->flag[wc3] & MY_CNT4))
+              {
+                addr= cont->code[0][wc] + cont->code[1][wc1] +
+                      cont->code[2][wc2] + cont->code[3][wc3];
+                weight= &cont->weight[addr*cont->weight_len];
+                if (weight[0])
+                {
+                  scanner->sbeg+= mblen1 + mblen2 + mblen3;
+                  scanner->wbeg= &weight[1];
+                  return weight[0];
+                }
+              }
+            
+              addr= cont->code[0][wc] + cont->code[1][wc1] +
+                    cont->code[2][wc2];
+              weight= &cont->weight[addr*cont->weight_len];
+              if (weight[0])
+              {
+                scanner->sbeg+= (mblen1 + mblen2);
+                scanner->wbeg= &weight[1];
+                return weight[0];
+              }
+            }
+
+            addr= cont->code[0][wc] + cont->code[1][wc1];
+            weight= &cont->weight[addr*cont->weight_len];
+            if (weight[0])
+            {
+              scanner->wbeg= &weight[1];
+              scanner->sbeg+= mblen1;
+              return weight[0];
+            }
+          }
+        }
       }
     }
     
@@ -7655,9 +7751,10 @@
 
 typedef struct my_coll_rule_item_st
 {
-  uint base;     /* Base character                             */
-  uint curr[2];  /* Current character                          */
+  uint base[6];  /* Base character                             */
+  uint curr[4];  /* Current character                          */
   int diff[3];   /* Primary, Secondary and Tertiary difference */
+  uint16 p[4];   /* Primary weight                             */
 } MY_COLL_RULE;
 
 
@@ -7731,7 +7828,7 @@
       
       if (prevlexnum == MY_COLL_LEXEM_SHIFT)
       {
-        item.base= lexem.code;
+        item.base[0]= lexem.code;
         item.diff[0]= 0;
         item.diff[1]= 0;
         item.diff[2]= 0;
@@ -7787,48 +7884,62 @@
 #define MY_MAX_COLL_RULE 128
 
 /*
-  This function copies an UCS2 collation from
-  the default Unicode Collation Algorithm (UCA)
-  weights applying tailorings, i.e. a set of
-  alternative weights for some characters. 
-  
-  The default UCA weights are stored in uca_weight/uca_length.
-  They consist of 256 pages, 256 character each.
-  
-  If a page is not overwritten by tailoring rules,
-  it is copies as is from UCA as is.
-  
-  If a page contains some overwritten characters, it is
-  allocated. Untouched characters are copied from the
-  default weights.
+  Create tailoring for non-contractions.
+
+  SYNOPSIS:
+    create_tailoring_for_non_contractions()
+    cs            - character set + collation pair
+    rule          - a set of collation customization rule
+    nrules        - number of individual rules in the set
+    ncontractions - to return how many contractions were found
+    alloc         - memor allocation function
+
+  NOTES:
+    This function copies the default Unicode Collation Algorithm (UCA)
+    weights applying tailorings, i.e. a set of so customization rules:
+    alternative weights for some characters.
+    
+    Only these cases are processed:
+      1. one character - one weight
+      2. one character - many weights (aka expansion)
+
+    The default UCA weights are stored in uca_weight/uca_length.
+    They consist of 256 pages, 256 character each.
+    
+    If a page is not overwritten by tailoring rules,
+    it is copied from the default UCA weights as is.
+    
+    If a page contains some overwritten characters, it is
+    allocated. Untouched characters are copied from the
+    default weights.
+  
+    
+    These cases are not processed:
+      1. many characters - one weight (aka contraction)
+      2. many characters - many weights (aka contraction with expansion)
+    
+    Contractions are just ignored by this function
+    and need to be processed additionally, after calling of this function.
+    The caller should check the "ncontraction" value to see if 
+    additional contraction processing is required.
+    
+  RETURN:
+    0 on success
+    1 on error: no memory
+
 */
 
-static my_bool create_tailoring(CHARSET_INFO *cs, void *(*alloc)(uint))
+static my_bool
+create_tailoring_for_non_contractions(CHARSET_INFO *cs,
+                                      MY_COLL_RULE *rule, int nrules,
+                                      int *ncontractions,
+                                      void *(*alloc)(uint))
 {
-  MY_COLL_RULE rule[MY_MAX_COLL_RULE];
-  char errstr[128];
   uchar   *newlengths;
   uint16 **newweights;
   const uchar *deflengths= uca_length;
   uint16     **defweights= uca_weight;
-  int rc, i;
-  int ncontractions= 0;
-  
-  if (!cs->tailoring)
-    return 1;
-  
-  /* Parse ICU Collation Customization expression */
-  if ((rc= my_coll_rule_parse(rule, MY_MAX_COLL_RULE,
-                              cs->tailoring,
-                              cs->tailoring + strlen(cs->tailoring),
-                              errstr, sizeof(errstr))) < 0)
-  {
-    /* 
-      TODO: add error message reporting.
-      printf("Error: %d '%s'\n", rc, errstr);
-    */
-    return 1;
-  }
+  int i;
   
   if (!(newweights= (uint16**) (*alloc)(256*sizeof(uint16*))))
     return 1;
@@ -7843,23 +7954,25 @@
     Calculate maximum lenghts for the pages
     which will be overwritten.
   */
-  for (i=0; i < rc; i++)
+  for (i=0; i < nrules; i++)
   {
     if (!rule[i].curr[1]) /* If not a contraction */
     {
-      uint pageb= (rule[i].base >> 8) & 0xFF;
+      uint pageb= (rule[i].base[0] >> 8) & 0xFF;
       uint pagec= (rule[i].curr[0] >> 8) & 0xFF;
     
       if (newlengths[pagec] < deflengths[pageb])
         newlengths[pagec]= deflengths[pageb];
     }
     else
-      ncontractions++;
+    {
+      (*ncontractions)++;
+    }
   }
   
-  for (i=0; i < rc;  i++)
+  for (i=0; i < nrules;  i++)
   {
-    uint pageb= (rule[i].base >> 8) & 0xFF;
+    uint pageb= (rule[i].base[0] >> 8) & 0xFF;
     uint pagec= (rule[i].curr[0] >> 8) & 0xFF;
     uint chb, chc;
     
@@ -7888,7 +8001,7 @@
       shift to the base character and primary difference.
     */
     chc= rule[i].curr[0] & 0xFF;
-    chb= rule[i].base & 0xFF;
+    chb= rule[i].base[0] & 0xFF;
     memcpy(newweights[pagec] + chc*newlengths[pagec],
            defweights[pageb] + chb*deflengths[pageb],
            deflengths[pageb]*sizeof(uint16));
@@ -7906,42 +8019,481 @@
   cs->sort_order= newlengths;
   cs->sort_order_big= newweights;
   cs->contractions= NULL;
-  
-  /* Now process contractions */
-  if (ncontractions)
+  return 0;
+}
+
+
+/*
+  Create tailoring for simple contractions.
+
+  SYNOPSIS:
+    create_tailoring_for_simple_contractions()
+    cs            - character set + collation pair
+    rule          - a set of collation customization rule
+    nrules        - number of individual rules in the set
+    alloc         - memor allocation function
+
+  NOTES:
+    Should be called after create_tailoring_for_non_contraction()
+    
+    Creates tailiring for "simple" contractions:
+    - consisting of only two letters
+    - both letters are basic Latin letters a..z and A..Z.
+    - reset can be done to only a single character
+    - contraction produces only one weight (i.e. "contraction with expansion"
+      is not supported)
+    
+  RETURN:
+    0 on success
+    1 on error: if no memory, or if the rules have "complex" contractions
+*/
+
+static my_bool
+create_tailoring_for_simple_contractions(CHARSET_INFO *cs,
+                                         MY_COLL_RULE *rule, int nrules,
+                                         void *(*alloc)(uint))
+{
+  int i;
+  const uchar *deflengths= uca_length;
+  uint16     **defweights= uca_weight;
+  uint size= 0x40*0x40*sizeof(uint16); /* 8K, for basic latin letter only */
+  if (!(cs->contractions= (uint16*) (*alloc)(size)))
+      return 1;
+  bzero((void*)cs->contractions, size);
+  for (i=0; i < nrules; i++)
   {
-    uint size= 0x40*0x40*sizeof(uint16); /* 8K, for basic latin letter only */
-    if (!(cs->contractions= (uint16*) (*alloc)(size)))
+    if (rule[i].curr[1])
+    {
+      uint pageb= (rule[i].base[0] >> 8) & 0xFF;
+      uint chb= rule[i].base[0] & 0xFF;
+      uint16 *offsb= defweights[pageb] + chb*deflengths[pageb];
+      uint offsc;
+      
+      if (offsb[1] || 
+          rule[i].curr[0] < 0x40 || rule[i].curr[0] > 0x7f ||
+          rule[i].curr[1] < 0x40 || rule[i].curr[1] > 0x7f)
+      {
+        /* 
+         TODO: add error reporting;
+         We support only basic latin letters contractions at this point.
+         Also, We don't support contractions with weight longer than one.
+         Otherwise, we'd need much more memory.
+        */
         return 1;
-    bzero((void*)cs->contractions, size);
-    for (i=0; i < rc; i++)
+      }
+      offsc= (rule[i].curr[0]-0x40)*0x40+(rule[i].curr[1]-0x40);
+      
+      /* Copy base weight applying primary difference */
+      cs->contractions[offsc]= offsb[0] + rule[i].diff[0];
+    }
+  }
+  return 0;
+}
+
+
+/**********************************************************/
+#define HUNGARIAN_NRULES 129
+
+MY_COLL_RULE hung[HUNGARIAN_NRULES]=
+{
+  /* &C < cs   <<< cS   <<< Cs   <<< CS */
+  {{'C',0,0,0,0,0}, {'c','s',0,0}, {1,0,0}, {0x0E61,0,0,0}},
+  {{'C',0,0,0,0,0}, {'c','S',0,0}, {1,0,1}, {0x0E61,0,0,0}},
+  {{'C',0,0,0,0,0}, {'C','s',0,0}, {1,0,2}, {0x0E61,0,0,0}},
+  {{'C',0,0,0,0,0}, {'C','S',0,0}, {1,0,3}, {0x0E61,0,0,0}},
+
+  /*
+    &D < dz      <<< dZ      <<< Dz      <<< DZ
+       < dzs     <<< dzS     <<< dZs     <<< dZS
+     <<< Dzs     <<< DzS     <<< DZs     <<< DZS
+  */
+  {{'D',0,0,0,0,0}, {'d','z',0,0}, {1,0,0}, {0x0E6E,0,0,0}},
+  {{'D',0,0,0,0,0}, {'d','Z',0,0}, {1,0,1}, {0x0E6E,0,0,0}},
+  {{'D',0,0,0,0,0}, {'D','z',0,0}, {1,0,2}, {0x0E6E,0,0,0}},
+  {{'D',0,0,0,0,0}, {'D','Z',0,0}, {1,0,3}, {0x0E6E,0,0,0}},
+  {{'D',0,0,0,0,0}, {'d','z','s',0}, {2,0,0}, {0x0E6F,0,0,0}},
+  {{'D',0,0,0,0,0}, {'d','z','S',0}, {2,0,1}, {0x0E6F,0,0,0}},
+  {{'D',0,0,0,0,0}, {'d','Z','s',0}, {2,0,2}, {0x0E6F,0,0,0}},
+  {{'D',0,0,0,0,0}, {'d','Z','S',0}, {2,0,3}, {0x0E6F,0,0,0}},
+  {{'D',0,0,0,0,0}, {'D','z','s',0}, {2,0,4}, {0x0E6F,0,0,0}},
+  {{'D',0,0,0,0,0}, {'D','z','S',0}, {2,0,5}, {0x0E6F,0,0,0}},
+  {{'D',0,0,0,0,0}, {'D','Z','s',0}, {2,0,6}, {0x0E6F,0,0,0}},
+  {{'D',0,0,0,0,0}, {'D','Z','S',0}, {2,0,7}, {0x0E6F,0,0,0}},
+
+  /* &G < gy      <<< gY      <<< Gy      <<< GY */
+  {{'G',0,0,0,0,0}, {'g','y',0,0}, {1,0,0}, {0x0EC2,0,0,0}},
+  {{'G',0,0,0,0,0}, {'g','Y',0,0}, {1,0,1}, {0x0EC2,0,0,0}},
+  {{'G',0,0,0,0,0}, {'G','y',0,0}, {1,0,2}, {0x0EC2,0,0,0}},
+  {{'G',0,0,0,0,0}, {'G','Y',0,0}, {1,0,3}, {0x0EC2,0,0,0}},
+
+  /* &L < ly      <<< lY      <<< Ly      <<< LY */
+  {{'L',0,0,0,0,0}, {'l','y',0,0}, {1,0,0}, {0x0F2F,0,0,0}},
+  {{'L',0,0,0,0,0}, {'l','Y',0,0}, {1,0,1}, {0x0F2F,0,0,0}},
+  {{'L',0,0,0,0,0}, {'L','y',0,0}, {1,0,2}, {0x0F2F,0,0,0}},
+  {{'L',0,0,0,0,0}, {'L','Y',0,0}, {1,0,3}, {0x0F2F,0,0,0}},
+
+  /* &N < ny      <<< nY      <<< Ny      <<< NY */
+  {{'N',0,0,0,0,0}, {'n','y',0,0}, {1,0,0}, {0x0F65,0,0,0}},
+  {{'N',0,0,0,0,0}, {'n','Y',0,0}, {1,0,1}, {0x0F65,0,0,0}},
+  {{'N',0,0,0,0,0}, {'N','y',0,0}, {1,0,2}, {0x0F65,0,0,0}},
+  {{'N',0,0,0,0,0}, {'N','Y',0,0}, {1,0,3}, {0x0F65,0,0,0}},
+
+  /* & O < \u00F6 <<< \u00D6 << \u0151 <<< \u0150 */
+  {{'O',0,0,0,0,0}, {0x00F6,0,0,0}, {1,0,0}, {0x0F83,0,0,0}},
+  {{'O',0,0,0,0,0}, {0x00D6,0,0,0}, {1,0,1}, {0x0F83,0,0,0}},
+  {{'O',0,0,0,0,0}, {0x0151,0,0,0}, {1,1,0}, {0x0F83,0,0,0}},
+  {{'O',0,0,0,0,0}, {0x0150,0,0,0}, {1,1,1}, {0x0F83,0,0,0}},
+
+  /* &S < sz      <<< sZ      <<< Sz      <<< SZ */
+  {{'S',0,0,0,0,0}, {'s','z',0,0}, {1,0,0}, {0x0FEB,0,0,0}},
+  {{'S',0,0,0,0,0}, {'s','Z',0,0}, {1,0,1}, {0x0FEB,0,0,0}},
+  {{'S',0,0,0,0,0}, {'S','z',0,0}, {1,0,2}, {0x0FEB,0,0,0}},
+  {{'S',0,0,0,0,0}, {'S','Z',0,0}, {1,0,3}, {0x0FEB,0,0,0}},
+
+  /* &T < ty      <<< tY      <<< Ty      <<< TY */
+  {{'T',0,0,0,0,0}, {'t','y',0,0}, {1,0,0}, {0x1003,0,0,0}},
+  {{'T',0,0,0,0,0}, {'t','Y',0,0}, {1,0,1}, {0x1003,0,0,0}},
+  {{'T',0,0,0,0,0}, {'T','y',0,0}, {1,0,2}, {0x1003,0,0,0}},
+  {{'T',0,0,0,0,0}, {'T','Y',0,0}, {1,0,3}, {0x1003,0,0,0}},
+
+  /* & U < \u00FC <<< \u00DC << \u0171 <<< \u0170" */
+  {{'U',0,0,0,0,0}, {0x00FC,0,0,0}, {1,0,0}, {0x1020,0,0,0}},
+  {{'U',0,0,0,0,0}, {0x00DC,0,0,0}, {1,0,1}, {0x1020,0,0,0}},
+  {{'U',0,0,0,0,0}, {0x0171,0,0,0}, {1,1,0}, {0x1020,0,0,0}},
+  {{'U',0,0,0,0,0}, {0x0170,0,0,0}, {1,1,1}, {0x1020,0,0,0}},
+
+  /* &Z < zs      <<< zS      <<< Zs      <<< ZS */
+  {{'Z',0,0,0,0,0}, {'z','s',0,0}, {1,0,0}, {0x106B,0,0,0}},
+  {{'Z',0,0,0,0,0}, {'z','S',0,0}, {1,0,1}, {0x106B,0,0,0}},
+  {{'Z',0,0,0,0,0}, {'Z','s',0,0}, {1,0,2}, {0x106B,0,0,0}},
+  {{'Z',0,0,0,0,0}, {'Z','S',0,0}, {1,0,3}, {0x106B,0,0,0}},
+
+  /* &CSCS <<< ccs <<< ccS <<< cCs <<< cCS <<< Ccs <<< CcS <<< CCs <<< CCS */
+  {{'C','S','C','S',0,0}, {'c','c','s',0}, {0,0,1}, {0x0E61,0x0E61,0,0}},
+  {{'C','S','C','S',0,0}, {'c','c','S',0}, {0,0,2}, {0x0E61,0x0E61,0,0}},
+  {{'C','S','C','S',0,0}, {'c','C','s',0}, {0,0,3}, {0x0E61,0x0E61,0,0}},
+  {{'C','S','C','S',0,0}, {'c','C','S',0}, {0,0,4}, {0x0E61,0x0E61,0,0}},
+  {{'C','S','C','S',0,0}, {'C','c','s',0}, {0,0,5}, {0x0E61,0x0E61,0,0}},
+  {{'C','S','C','S',0,0}, {'C','c','S',0}, {0,0,6}, {0x0E61,0x0E61,0,0}},
+  {{'C','S','C','S',0,0}, {'C','C','s',0}, {0,0,7}, {0x0E61,0x0E61,0,0}},
+  {{'C','S','C','S',0,0}, {'C','C','S',0}, {0,0,8}, {0x0E61,0x0E61,0,0}},
+  
+  /* &DZDZ <<< ddz <<< ddZ <<< dDz <<< dDZ <<< Ddz <<< DdZ <<< DDz <<< DDZ */
+  {{'D','Z','D','Z',0,0}, {'d','d','z',0}, {0,0,1}, {0x0E6E,0x0E6E,0,0}},
+  {{'D','Z','D','Z',0,0}, {'d','d','Z',0}, {0,0,2}, {0x0E6E,0x0E6E,0,0}},
+  {{'D','Z','D','Z',0,0}, {'d','D','z',0}, {0,0,3}, {0x0E6E,0x0E6E,0,0}},
+  {{'D','Z','D','Z',0,0}, {'d','D','Z',0}, {0,0,4}, {0x0E6E,0x0E6E,0,0}},
+  {{'D','Z','D','Z',0,0}, {'D','d','z',0}, {0,0,5}, {0x0E6E,0x0E6E,0,0}},
+  {{'D','Z','D','Z',0,0}, {'D','d','Z',0}, {0,0,6}, {0x0E6E,0x0E6E,0,0}},
+  {{'D','Z','D','Z',0,0}, {'D','D','z',0}, {0,0,7}, {0x0E6E,0x0E6E,0,0}},
+  {{'D','Z','D','Z',0,0}, {'D','D','Z',0}, {0,0,8}, {0x0E6E,0x0E6E,0,0}},
+  
+  /*
+    &DZSDZS <<< ddzs <<< ddzS <<< ddZs <<< ddZS
+            <<< dDzs <<< dDzS <<< dDZs <<< dDZS
+            <<< Ddzs <<< DdzS <<< DdZs <<< DdZS
+            <<< DDzs <<< DDzS <<< DDZs <<< DDZS
+  */
+  {{'D','Z','S','D','Z','S'}, {'d','d','z','s'}, {0,0,1}, {0x0E6F,0x0E6F,0,0}},
+  {{'D','Z','S','D','Z','S'}, {'d','d','z','S'}, {0,0,2}, {0x0E6F,0x0E6F,0,0}},
+  {{'D','Z','S','D','Z','S'}, {'d','d','Z','s'}, {0,0,3}, {0x0E6F,0x0E6F,0,0}},
+  {{'D','Z','S','D','Z','S'}, {'d','d','Z','S'}, {0,0,4}, {0x0E6F,0x0E6F,0,0}},
+  {{'D','Z','S','D','Z','S'}, {'d','D','z','s'}, {0,0,5}, {0x0E6F,0x0E6F,0,0}},
+  {{'D','Z','S','D','Z','S'}, {'d','D','z','S'}, {0,0,6}, {0x0E6F,0x0E6F,0,0}},
+  {{'D','Z','S','D','Z','S'}, {'d','D','Z','s'}, {0,0,7}, {0x0E6F,0x0E6F,0,0}},
+  {{'D','Z','S','D','Z','S'}, {'d','D','Z','S'}, {0,0,8}, {0x0E6F,0x0E6F,0,0}},
+  {{'D','Z','S','D','Z','S'}, {'D','d','z','s'}, {0,0,9}, {0x0E6F,0x0E6F,0,0}},
+  {{'D','Z','S','D','Z','S'}, {'D','d','z','S'}, {0,0,10}, {0x0E6F,0x0E6F,0,0}},
+  {{'D','Z','S','D','Z','S'}, {'D','d','Z','s'}, {0,0,11}, {0x0E6F,0x0E6F,0,0}},
+  {{'D','Z','S','D','Z','S'}, {'D','d','Z','S'}, {0,0,12}, {0x0E6F,0x0E6F,0,0}},
+  {{'D','Z','S','D','Z','S'}, {'D','D','z','s'}, {0,0,13}, {0x0E6F,0x0E6F,0,0}},
+  {{'D','Z','S','D','Z','S'}, {'D','D','z','S'}, {0,0,14}, {0x0E6F,0x0E6F,0,0}},
+  {{'D','Z','S','D','Z','S'}, {'D','D','Z','s'}, {0,0,15}, {0x0E6F,0x0E6F,0,0}},
+  {{'D','Z','S','D','Z','S'}, {'D','D','Z','S'}, {0,0,16}, {0x0E6F,0x0E6F,0,0}},
+  
+  /*&GYGY <<< ggy <<< ggY <<< gGy <<< gGY <<< Ggy <<< GgY <<< GGy <<< GGY */
+  {{'G','Y','G','Y'}, {'g','g','y',0}, {0,0,1}, {0x0EC2,0x0EC2,0,0}},
+  {{'G','Y','G','Y'}, {'g','g','Y',0}, {0,0,2}, {0x0EC2,0x0EC2,0,0}},
+  {{'G','Y','G','Y'}, {'g','G','y',0}, {0,0,3}, {0x0EC2,0x0EC2,0,0}},
+  {{'G','Y','G','Y'}, {'g','G','Y',0}, {0,0,4}, {0x0EC2,0x0EC2,0,0}},
+  {{'G','Y','G','Y'}, {'G','g','y',0}, {0,0,5}, {0x0EC2,0x0EC2,0,0}},
+  {{'G','Y','G','Y'}, {'G','g','Y',0}, {0,0,6}, {0x0EC2,0x0EC2,0,0}},
+  {{'G','Y','G','Y'}, {'G','G','y',0}, {0,0,7}, {0x0EC2,0x0EC2,0,0}},
+  {{'G','Y','G','Y'}, {'G','G','Y',0}, {0,0,8}, {0x0EC2,0x0EC2,0,0}},
+  
+  /*&LYLY <<< lly <<< llY <<< lLy <<< lLY <<< Lly <<< LlY <<< LLy <<< LLY */
+  {{'L','Y','L','Y'}, {'l','l','y',0}, {0,0,1}, {0x0F2F,0x0F2F,0,0}},
+  {{'L','Y','L','Y'}, {'l','l','Y',0}, {0,0,2}, {0x0F2F,0x0F2F,0,0}},
+  {{'L','Y','L','Y'}, {'l','L','y',0}, {0,0,3}, {0x0F2F,0x0F2F,0,0}},
+  {{'L','Y','L','Y'}, {'l','L','Y',0}, {0,0,4}, {0x0F2F,0x0F2F,0,0}},
+  {{'L','Y','L','Y'}, {'L','l','y',0}, {0,0,5}, {0x0F2F,0x0F2F,0,0}},
+  {{'L','Y','L','Y'}, {'L','l','Y',0}, {0,0,6}, {0x0F2F,0x0F2F,0,0}},
+  {{'L','Y','L','Y'}, {'L','L','y',0}, {0,0,7}, {0x0F2F,0x0F2F,0,0}},
+  {{'L','Y','L','Y'}, {'L','L','Y',0}, {0,0,8}, {0x0F2F,0x0F2F,0,0}},
+
+  /*&NYNY <<< nny <<< nnY <<< nNy <<< nNY <<< Nny <<< NnY <<< NNy <<< NNY */
+  {{'N','Y','N','Y'}, {'n','n','y',0}, {0,0,1}, {0x0F65,0x0F65,0,0}},
+  {{'N','Y','N','Y'}, {'n','n','Y',0}, {0,0,2}, {0x0F65,0x0F65,0,0}},
+  {{'N','Y','N','Y'}, {'n','N','y',0}, {0,0,3}, {0x0F65,0x0F65,0,0}},
+  {{'N','Y','N','Y'}, {'n','N','Y',0}, {0,0,4}, {0x0F65,0x0F65,0,0}},
+  {{'N','Y','N','Y'}, {'N','n','y',0}, {0,0,5}, {0x0F65,0x0F65,0,0}},
+  {{'N','Y','N','Y'}, {'N','n','Y',0}, {0,0,6}, {0x0F65,0x0F65,0,0}},
+  {{'N','Y','N','Y'}, {'N','N','y',0}, {0,0,7}, {0x0F65,0x0F65,0,0}},
+  {{'N','Y','N','Y'}, {'N','N','Y',0}, {0,0,8}, {0x0F65,0x0F65,0,0}},
+
+  /*&SZSZ <<< ssz <<< ssZ <<< sSz <<< sSZ <<< Ssz <<< SsZ <<< SSz <<< SSZ */
+  {{'S','Z','S','Z'}, {'s','s','z',0}, {0,0,1}, {0x0FEB,0x0FEB,0,0}},
+  {{'S','Z','S','Z'}, {'s','s','Z',0}, {0,0,2}, {0x0FEB,0x0FEB,0,0}},
+  {{'S','Z','S','Z'}, {'s','S','z',0}, {0,0,3}, {0x0FEB,0x0FEB,0,0}},
+  {{'S','Z','S','Z'}, {'s','S','Z',0}, {0,0,4}, {0x0FEB,0x0FEB,0,0}},
+  {{'S','Z','S','Z'}, {'S','s','z',0}, {0,0,5}, {0x0FEB,0x0FEB,0,0}},
+  {{'S','Z','S','Z'}, {'S','s','Z',0}, {0,0,6}, {0x0FEB,0x0FEB,0,0}},
+  {{'S','Z','S','Z'}, {'S','S','z',0}, {0,0,7}, {0x0FEB,0x0FEB,0,0}},
+  {{'S','Z','S','Z'}, {'S','S','Z',0}, {0,0,8}, {0x0FEB,0x0FEB,0,0}},
+
+  /*&TYTY <<< tty <<< ttY <<< tTy <<< tTY <<< Tty <<< TtY <<< TTy <<< TTY */
+  {{'T','Y','T','Y'}, {'t','t','y',0}, {0,0,1}, {0x1003,0x1003,0,0}},
+  {{'T','Y','T','Y'}, {'t','t','Y',0}, {0,0,2}, {0x1003,0x1003,0,0}},
+  {{'T','Y','T','Y'}, {'t','T','y',0}, {0,0,3}, {0x1003,0x1003,0,0}},
+  {{'T','Y','T','Y'}, {'t','T','Y',0}, {0,0,4}, {0x1003,0x1003,0,0}},
+  {{'T','Y','T','Y'}, {'T','t','y',0}, {0,0,5}, {0x1003,0x1003,0,0}},
+  {{'T','Y','T','Y'}, {'T','t','Y',0}, {0,0,6}, {0x1003,0x1003,0,0}},
+  {{'T','Y','T','Y'}, {'T','T','y',0}, {0,0,7}, {0x1003,0x1003,0,0}},
+  {{'T','Y','T','Y'}, {'T','T','Y',0}, {0,0,8}, {0x1003,0x1003,0,0}},
+
+  /*&ZSZS <<< zzs <<< zzS <<< zZs <<< zZS <<< Zzs <<< ZzS <<< ZZs <<< ZZS */
+  {{'Z','S','Z','S'}, {'z','z','s',0}, {0,0,1}, {0x106B,0x106B,0,0}},
+  {{'Z','S','Z','S'}, {'z','z','S',0}, {0,0,2}, {0x106B,0x106B,0,0}},
+  {{'Z','S','Z','S'}, {'z','Z','s',0}, {0,0,3}, {0x106B,0x106B,0,0}},
+  {{'Z','S','Z','S'}, {'z','Z','S',0}, {0,0,4}, {0x106B,0x106B,0,0}},
+  {{'Z','S','Z','S'}, {'Z','z','s',0}, {0,0,5}, {0x106B,0x106B,0,0}},
+  {{'Z','S','Z','S'}, {'Z','z','S',0}, {0,0,6}, {0x106B,0x106B,0,0}},
+  {{'Z','S','Z','S'}, {'Z','Z','s',0}, {0,0,7}, {0x106B,0x106B,0,0}},
+  {{'Z','S','Z','S'}, {'Z','Z','S',0}, {0,0,8}, {0x106B,0x106B,0,0}},
+
+  {{0,0,0,0,0,0}, {0,0,0,0}, {0,0,0}, {0,0,0,0}}
+};
+
+
+/*
+  Set min and max character which can appear as a contraction part,
+  max contraction length, and max weight length.
+*/
+static void
+my_coll_set_contraction_minmax_char(MY_CONT_HDR *cont,
+                                   MY_COLL_RULE *rule, uint nrules)
+{
+  for (cont->min_char=0, cont->max_char= 0;
+       nrules && rule->base[0];
+       rule++, nrules--)
+  {
+    uint pos;
+    uint *ch;
+    if (!rule->curr[1]) /* Not a contraction */
+      continue;
+    for (pos= 0, ch= rule->curr; *ch && pos < 4; pos++, ch++)
+    {
+      if (*ch > cont->max_char)
+        cont->max_char= *ch;
+    }
+  }
+  cont->num_chars= cont->max_char - cont->min_char + 1;
+  cont->num_pos= 4; /* Set max contraction length */
+  cont->weight_len= 3;
+}  
+
+
+/* 
+  Fill flags marking the characters which can appear one
+  the first, second, third, fourth etc, place position a contraction.
+  At the same time, enumerate letters inside each postition,
+  starting from 1. We'll keep 0 to mean EOL.
+*/
+static void
+my_coll_fill_contraction_flags(MY_CONT_HDR *cont,
+                               MY_COLL_RULE *rule, uint nrules)
+{
+  for (; nrules && rule->base[0]; rule++, nrules--)
+  {
+    const uint *ch;
+    int fl[]= {MY_CNT1, MY_CNT2, MY_CNT3, MY_CNT4};
+    size_t pos;
+    for (pos= 0, ch= rule->curr; *ch && pos < 4; ch++, pos++)
     {
-      if (rule[i].curr[1])
+      size_t offs;
+      if (!rule->curr[1])
+        continue; /* Not a contraction */
+      offs= *ch - cont->min_char;
+      if (!(cont->flag[offs] & fl[pos]))
       {
-        uint pageb= (rule[i].base >> 8) & 0xFF;
-        uint chb= rule[i].base & 0xFF;
-        uint16 *offsb= defweights[pageb] + chb*deflengths[pageb];
-        uint offsc;
-        
-        if (offsb[1] || 
-            rule[i].curr[0] < 0x40 || rule[i].curr[0] > 0x7f ||
-            rule[i].curr[1] < 0x40 || rule[i].curr[1] > 0x7f)
-        {
-          /* 
-           TODO: add error reporting;
-           We support only basic latin letters contractions at this point.
-           Also, We don't support contractions with weight longer than one.
-           Otherwise, we'd need much more memory.
-          */
-          return 1;
-        }
-        offsc= (rule[i].curr[0]-0x40)*0x40+(rule[i].curr[1]-0x40);
-        
-        /* Copy base weight applying primary difference */
-        cs->contractions[offsc]= offsb[0] + rule[i].diff[0];
+        cont->flag[offs] |= fl[pos];
+        /* Start from 1, keep 0 for EOF */
+        cont->code[pos][offs]= ++cont->posnum[pos];
       }
     }
   }
+}
+
+
+/*
+  Fill contraction weights
+*/
+static void
+my_coll_fill_contraction_weights(MY_CONT_HDR *cont,
+                                 MY_COLL_RULE *rule, uint nrules)
+{
+  /* Now fill weights */
+  for ( ; nrules && rule->base[0]; rule++, nrules--)
+  {
+    const uint *ch;
+    size_t pos, addr= 0;
+    if (!rule->curr[1]) /* Skip if not a contraction */
+      continue;
+    for (pos= 0, ch= rule->curr; *ch && pos < 4; ch++, pos++)
+    {
+      size_t offs= (*ch - cont->min_char);
+      addr+= cont->code[pos][offs];
+    }
+    addr*= cont->weight_len;
+    cont->weight[addr]= rule->p[0];
+    cont->weight[addr+1]= rule->p[1];
+    cont->weight[addr+2]= rule->p[2];
+  }
+}
+
+
+/* Calculate offsets */
+static void
+my_coll_calc_contraction_offsets_and_num_weights(MY_CONT_HDR *cont)
+{
+  uint i;
+  for (i=0 ; i < cont->num_pos; i++)
+  {
+    uint j;
+    cont->posnum[i]++; /* Reserve space for EOL */
+    cont->posfactor[i]= (i == 0) ? 1 : cont->posfactor[i - 1] * cont->posnum[i-1];
+    for (j= 0; j < cont->num_chars; j++)
+    {
+      if (cont->code[i][j])
+        cont->code[i][j]*= cont->posfactor[i];
+    }
+  }
+  cont->num_weights= cont->posfactor[i-1] * cont->posnum[i-1];
+}
+
+
+static int
+my_init_complex_contraction(MY_CONT_HDR *cont,
+                            MY_COLL_RULE *rule,
+                            uint nrules, void *(alloc)(uint))
+{
+  uint i, nbytes;
+  
+  bzero((void*) cont, sizeof(MY_CONT_HDR));
+  my_coll_set_contraction_minmax_char(cont, rule, nrules);
+  
+  /* Allocate flag map */
+  nbytes= cont->num_chars * sizeof(uint16);
+  cont->flag= alloc(nbytes);
+  bzero((void*)cont->flag, nbytes);
+  
+  /* Allocate code map, for all pos at once */
+  nbytes= cont->num_chars * cont->num_pos * sizeof(uint16);
+  cont->code[0]= alloc(nbytes);
+  bzero(cont->code[0], nbytes);
+  /* Set code offset for each pos */
+  for (i= 1; i < cont->num_pos; i++)
+    cont->code[i]= cont->code[0] + i * cont->num_chars;
+  
+  my_coll_fill_contraction_flags(cont, rule, nrules);
+  my_coll_calc_contraction_offsets_and_num_weights(cont);
+  
+  /* Alloc weight map */
+  nbytes= cont->weight_len * cont->num_weights * sizeof(uint16);
+  cont->weight= (uint16*) alloc(nbytes);
+  bzero((void*)cont->weight, nbytes);
+  
+  my_coll_fill_contraction_weights(cont, rule, nrules);
+  return 0;
+}
+
+
+/**********************************************************/
+
+/*
+  Create tailoring for simple collations.
+
+  SYNOPSIS:
+    create_tailoring()
+    cs            - character set + collation pair
+    alloc         - memor allocation function
+
+  NOTES:
+    
+    Creates tailoring for collations which don't have
+    complex contractions.
+    
+  RETURN:
+    0 on success
+    1 on error
+*/
+
+static my_bool
+create_tailoring(CHARSET_INFO *cs, void *(*alloc)(uint))
+{
+  MY_COLL_RULE rule[MY_MAX_COLL_RULE];
+  char errstr[128];
+  int nrules, ncontractions= 0;
+  
+  if (!cs->tailoring)
+    return 1;
+  
+  /* Parse ICU Collation Customization expression */
+  if ((nrules= my_coll_rule_parse(rule, MY_MAX_COLL_RULE,
+                                  cs->tailoring,
+                                  cs->tailoring + strlen(cs->tailoring),
+                                  errstr, sizeof(errstr))) < 0)
+  {
+    /* 
+      TODO: add error message reporting.
+      printf("Error: %d '%s'\n", rc, errstr);
+    */
+    return 1;
+  }
+  
+  if (create_tailoring_for_non_contractions(cs, rule, nrules,
+                                            &ncontractions, alloc))
+    return 1;
+  
+  if (ncontractions && create_tailoring_for_simple_contractions(cs,
+                                                                rule, nrules,
+                                                                alloc))
+    return 1;
+  
+  return 0;
+}
+
+
+static my_bool
+my_coll_init_uca_with_complex_contractions(CHARSET_INFO *cs,
+                                           void *(*alloc)(uint))
+{
+  MY_CONT_HDR cont;
+  MY_COLL_RULE *rule= hung;
+  int nrules= HUNGARIAN_NRULES;
+  int ncontractions= 0;
+  
+  cs->pad_char= ' ';
+
+  if (create_tailoring_for_non_contractions(cs, rule, nrules,
+                                            &ncontractions, alloc))
+    return 1;
+
+  if (my_init_complex_contraction(&cont, rule, (uint) nrules, alloc))
+    return 1;
+  
+  cs->contractions= (uint16*) alloc(sizeof(MY_CONT_HDR));
+  memcpy(cs->contractions, &cont, sizeof(MY_CONT_HDR));
   return 0;
 }
 
@@ -8646,6 +9198,21 @@
     my_propagate_complex
 };
 
+MY_COLLATION_HANDLER my_collation_any_uca_with_complex_contractions_handler =
+{
+    my_coll_init_uca_with_complex_contractions,
+    my_strnncoll_any_uca,
+    my_strnncollsp_any_uca,
+    my_strnxfrm_any_uca,
+    my_strnxfrmlen_simple,
+    my_like_range_mb,
+    my_wildcmp_uca,
+    NULL,
+    my_instr_mb,
+    my_hash_sort_any_uca,
+    my_propagate_complex
+};
+
 /* 
   We consider bytes with code more than 127 as a letter.
   This garantees that word boundaries work fine with regular
@@ -9250,6 +9817,39 @@
     0,                  /* escape_with_backslash_is_dangerous */
     &my_charset_utf8_handler,
     &my_collation_any_uca_handler
+};
+
+
+CHARSET_INFO my_charset_utf8_hungarian_uca_ci=
+{
+    210,0,0,		/* number       */
+    MY_CS_COMPILED|MY_CS_STRNXFRM|MY_CS_UNICODE|MY_CS_COMPLEX_CONTRACTION,
+    "utf8",		/* cs name    */
+    "utf8_hungarian_ci",/* name         */
+    "",			/* comment      */
+    NULL,		/* tailoring    */
+    ctype_utf8,		/* ctype        */
+    NULL,		/* to_lower     */
+    NULL,		/* to_upper     */
+    NULL,		/* sort_order   */
+    NULL,		/* contractions */
+    NULL,		/* sort_order_big*/
+    NULL,		/* tab_to_uni   */
+    NULL,		/* tab_from_uni */
+    my_unicase_default, /* caseinfo     */
+    NULL,		/* state_map    */
+    NULL,		/* ident_map    */
+    8,			/* strxfrm_multiply */
+    1,                  /* caseup_multiply  */
+    1,                  /* casedn_multiply  */
+    1,			/* mbminlen     */
+    3,			/* mbmaxlen     */
+    9,			/* min_sort_char */
+    0xFFFF,		/* max_sort_char */
+    ' ',                /* pad char      */
+    0,                  /* escape_with_backslash_is_dangerous */
+    &my_charset_utf8_handler,
+    &my_collation_any_uca_with_complex_contractions_handler
 };
 
 #endif /* HAVE_CHARSET_utf8 */

--- 1.16/mysql-test/r/ctype_uca.result	2005-10-06 17:40:13 +05:00
+++ 1.17/mysql-test/r/ctype_uca.result	2005-12-13 15:24:21 +04:00
@@ -2548,3 +2548,217 @@
 İİ	4	ii	2	İİ	4
 II	2	ıı	4	II	2
 DROP TABLE t1;
+SET NAMES utf8;
+CREATE TABLE t1 (
+a varchar(10) character set utf8 collate utf8_hungarian_ci not null,
+b varchar(64));
+INSERT INTO t1 VALUES ('a','simple');
+INSERT INTO t1 VALUES ('c','simple'),('C','simple');
+INSERT INTO t1 VALUES ('ca','simple'),('cA','simple');
+INSERT INTO t1 VALUES ('Ca','simple'),('CA','simple');
+INSERT INTO t1 VALUES ('cs','contraction2'),('cS','contraction2');
+INSERT INTO t1 VALUES ('Cs','contraction2'),('CS','contraction2');
+INSERT INTO t1 VALUES ('cz','simple'),('cZ','simple');
+INSERT INTO t1 VALUES ('Cz','simple'),('CZ','simple');
+INSERT INTO t1 VALUES ('d','simple'),('D','simple');
+INSERT INTO t1 VALUES ('da','simple'),('dA','simple');
+INSERT INTO t1 VALUES ('Da','simple'),('DA','simple');
+INSERT INTO t1 VALUES ('ds','simple'),('dS','simple');
+INSERT INTO t1 VALUES ('Ds','simple'),('DS','simple');
+INSERT INTO t1 VALUES ('dz','contraction2'),('dZ','contraction2');
+INSERT INTO t1 VALUES ('Dz','contraction2'),('DZ','contraction2');
+INSERT INTO t1 VALUES ('dzs','contraction3'),('dzS','contraction3');
+INSERT INTO t1 VALUES ('dZs','contraction3'),('dZS','contraction3');
+INSERT INTO t1 VALUES ('Dzs','contraction3'),('DzS','contraction3');
+INSERT INTO t1 VALUES ('DZs','contraction3'),('DZS','contraction3');
+INSERT INTO t1 VALUES ('dzdz', 'contraction2 + contraction2');
+INSERT INTO t1 VALUES ('ddz', 'contraction2expansion2');
+INSERT INTO t1 VALUES ('ddZ', 'contraction2expansion2');
+INSERT INTO t1 VALUES ('dDz', 'contraction2expansion2');
+INSERT INTO t1 VALUES ('dDZ', 'contraction2expansion2');
+INSERT INTO t1 VALUES ('Ddz', 'contraction2expansion2');
+INSERT INTO t1 VALUES ('DdZ', 'contraction2expansion2');
+INSERT INTO t1 VALUES ('DDz', 'contraction2expansion2');
+INSERT INTO t1 VALUES ('DDZ', 'contraction2expansion2');
+INSERT INTO t1 VALUES ('dzsdzs', 'contraction3 + contraction3');
+INSERT INTO t1 VALUES ('ddzs', 'contraction4expansion2');
+INSERT INTO t1 VALUES ('ddzS', 'contraction4expansion2');
+INSERT INTO t1 VALUES ('ddZs', 'contraction4expansion2');
+INSERT INTO t1 VALUES ('ddZS', 'contraction4expansion2');
+INSERT INTO t1 VALUES ('dDzs', 'contraction4expansion2');
+INSERT INTO t1 VALUES ('dDzS', 'contraction4expansion2');
+INSERT INTO t1 VALUES ('dDZs', 'contraction4expansion2');
+INSERT INTO t1 VALUES ('dDZS', 'contraction4expansion2');
+INSERT INTO t1 VALUES ('Ddzs', 'contraction4expansion2');
+INSERT INTO t1 VALUES ('DdzS', 'contraction4expansion2');
+INSERT INTO t1 VALUES ('DdZs', 'contraction4expansion2');
+INSERT INTO t1 VALUES ('DdZS', 'contraction4expansion2');
+INSERT INTO t1 VALUES ('DDzs', 'contraction4expansion2');
+INSERT INTO t1 VALUES ('DDzS', 'contraction4expansion2');
+INSERT INTO t1 VALUES ('DDZs', 'contraction4expansion2');
+INSERT INTO t1 VALUES ('DDZS', 'contraction4expansion2');
+INSERT INTO t1 VALUES ('g','simple'),('G','simple');
+INSERT INTO t1 VALUES ('ga','simple'),('gA','simple');
+INSERT INTO t1 VALUES ('Ga','simple'),('GA','simple');
+INSERT INTO t1 VALUES ('gy','contraction2'),('gY','contraction2');
+INSERT INTO t1 VALUES ('Gy','contraction2'),('GY','contraction2');
+INSERT INTO t1 VALUES ('gz','simple'),('gZ','simple');
+INSERT INTO t1 VALUES ('Gz','simple'),('GZ','simple');
+INSERT INTO t1 VALUES ('l','simple'),('L','simple');
+INSERT INTO t1 VALUES ('la','simple'),('lA','simple');
+INSERT INTO t1 VALUES ('La','simple'),('LA','simple');
+INSERT INTO t1 VALUES ('ly','contraction2'),('lY','contraction2');
+INSERT INTO t1 VALUES ('Ly','contraction2'),('LY','contraction2');
+INSERT INTO t1 VALUES ('lz','simple'),('lZ','simple');
+INSERT INTO t1 VALUES ('Lz','simple'),('LZ','simple');
+INSERT INTO t1 VALUES ('n','simple'),('N','simple');
+INSERT INTO t1 VALUES ('na','simple'),('nA','simple');
+INSERT INTO t1 VALUES ('Na','simple'),('NA','simple');
+INSERT INTO t1 VALUES ('ny','contraction2'),('nY','contraction2');
+INSERT INTO t1 VALUES ('Ny','contraction2'),('NY','contraction2');
+INSERT INTO t1 VALUES ('nz','simple'),('nZ','simple');
+INSERT INTO t1 VALUES ('Nz','simple'),('NZ','simple');
+INSERT INTO t1 VALUES ('o', 'simple');
+INSERT INTO t1 VALUES (_ucs2 0x00F6, 'simple');
+INSERT INTO t1 VALUES (_ucs2 0x00D6, 'simple');
+INSERT INTO t1 VALUES (_ucs2 0x0151, 'simple');
+INSERT INTO t1 VALUES (_ucs2 0x0150, 'simple');
+INSERT INTO t1 VALUES ('s','simple'),('S','simple');
+INSERT INTO t1 VALUES ('sa','simple'),('sA','simple');
+INSERT INTO t1 VALUES ('Sa','simple'),('SA','simple');
+INSERT INTO t1 VALUES ('ss','simple'),('sS','simple');
+INSERT INTO t1 VALUES ('Ss','simple'),('SS','simple');
+INSERT INTO t1 VALUES ('sz','contraction2'),('sZ','contraction2');
+INSERT INTO t1 VALUES ('Sz','contraction2'),('SZ','contraction2');
+INSERT INTO t1 VALUES ('t','simple'),('T','simple');
+INSERT INTO t1 VALUES ('ta','simple'),('tA','simple');
+INSERT INTO t1 VALUES ('Ta','simple'),('TA','simple');
+INSERT INTO t1 VALUES ('ty','contraction2'),('tY','contraction2');
+INSERT INTO t1 VALUES ('Ty','contraction2'),('TY','contraction2');
+INSERT INTO t1 VALUES ('tz','simple'),('tZ','simple');
+INSERT INTO t1 VALUES ('Tz','simple'),('TZ','simple');
+INSERT INTO t1 VALUES ('u', 'simple');
+INSERT INTO t1 VALUES (_ucs2 0x00FC, 'simple');
+INSERT INTO t1 VALUES (_ucs2 0x00DC, 'simple');
+INSERT INTO t1 VALUES (_ucs2 0x0171, 'simple');
+INSERT INTO t1 VALUES (_ucs2 0x0170, 'simple');
+INSERT INTO t1 VALUES ('z','simple'),('Z','simple');
+INSERT INTO t1 VALUES ('za','simple'),('zA','simple');
+INSERT INTO t1 VALUES ('Za','simple'),('ZA','simple');
+INSERT INTO t1 VALUES ('zs','contraction2'),('zS','contraction2');
+INSERT INTO t1 VALUES ('Zs','contraction2'),('ZS','contraction2');
+INSERT INTO t1 VALUES ('zz','simple'),('zZ','simple');
+INSERT INTO t1 VALUES ('Zz','simple'),('ZZ','simple');
+INSERT INTO t1 VALUES ('cscs', 'contraction2 + contraction2');
+INSERT INTO t1 VALUES ('ccs', 'contraction2expansion2');
+INSERT INTO t1 VALUES ('ccS', 'contraction2expansion2');
+INSERT INTO t1 VALUES ('cCs', 'contraction2expansion2');
+INSERT INTO t1 VALUES ('cCS', 'contraction2expansion2');
+INSERT INTO t1 VALUES ('Ccs', 'contraction2expansion2');
+INSERT INTO t1 VALUES ('CcS', 'contraction2expansion2');
+INSERT INTO t1 VALUES ('CCs', 'contraction2expansion2');
+INSERT INTO t1 VALUES ('CCS', 'contraction2expansion2');
+INSERT INTO t1 VALUES ('gygy', 'contraction2 + contraction2');
+INSERT INTO t1 VALUES ('ggy', 'contraction2expansion2');
+INSERT INTO t1 VALUES ('ggY', 'contraction2expansion2');
+INSERT INTO t1 VALUES ('gGy', 'contraction2expansion2');
+INSERT INTO t1 VALUES ('gGY', 'contraction2expansion2');
+INSERT INTO t1 VALUES ('Ggy', 'contraction2expansion2');
+INSERT INTO t1 VALUES ('GgY', 'contraction2expansion2');
+INSERT INTO t1 VALUES ('GGy', 'contraction2expansion2');
+INSERT INTO t1 VALUES ('GGY', 'contraction2expansion2');
+INSERT INTO t1 VALUES ('lyly', 'contraction2 + contraction2');
+INSERT INTO t1 VALUES ('lly', 'contraction2expansion2');
+INSERT INTO t1 VALUES ('llY', 'contraction2expansion2');
+INSERT INTO t1 VALUES ('lLy', 'contraction2expansion2');
+INSERT INTO t1 VALUES ('lLY', 'contraction2expansion2');
+INSERT INTO t1 VALUES ('Lly', 'contraction2expansion2');
+INSERT INTO t1 VALUES ('LlY', 'contraction2expansion2');
+INSERT INTO t1 VALUES ('LLy', 'contraction2expansion2');
+INSERT INTO t1 VALUES ('LLY', 'contraction2expansion2');
+INSERT INTO t1 VALUES ('nyny', 'contraction2 + contraction2');
+INSERT INTO t1 VALUES ('nny', 'contraction2expansion2');
+INSERT INTO t1 VALUES ('nnY', 'contraction2expansion2');
+INSERT INTO t1 VALUES ('nNy', 'contraction2expansion2');
+INSERT INTO t1 VALUES ('nNY', 'contraction2expansion2');
+INSERT INTO t1 VALUES ('Nny', 'contraction2expansion2');
+INSERT INTO t1 VALUES ('NnY', 'contraction2expansion2');
+INSERT INTO t1 VALUES ('NNy', 'contraction2expansion2');
+INSERT INTO t1 VALUES ('NNY', 'contraction2expansion2');
+INSERT INTO t1 VALUES ('szsz', 'contraction2 + contraction2');
+INSERT INTO t1 VALUES ('ssz', 'contraction2expansion2');
+INSERT INTO t1 VALUES ('ssZ', 'contraction2expansion2');
+INSERT INTO t1 VALUES ('sSz', 'contraction2expansion2');
+INSERT INTO t1 VALUES ('sSZ', 'contraction2expansion2');
+INSERT INTO t1 VALUES ('Ssz', 'contraction2expansion2');
+INSERT INTO t1 VALUES ('SsZ', 'contraction2expansion2');
+INSERT INTO t1 VALUES ('SSz', 'contraction2expansion2');
+INSERT INTO t1 VALUES ('SSZ', 'contraction2expansion2');
+INSERT INTO t1 VALUES ('tyty', 'contraction2 + contraction2');
+INSERT INTO t1 VALUES ('tty', 'contraction2expansion2');
+INSERT INTO t1 VALUES ('ttY', 'contraction2expansion2');
+INSERT INTO t1 VALUES ('tTy', 'contraction2expansion2');
+INSERT INTO t1 VALUES ('tTY', 'contraction2expansion2');
+INSERT INTO t1 VALUES ('Tty', 'contraction2expansion2');
+INSERT INTO t1 VALUES ('TtY', 'contraction2expansion2');
+INSERT INTO t1 VALUES ('TTy', 'contraction2expansion2');
+INSERT INTO t1 VALUES ('TTY', 'contraction2expansion2');
+INSERT INTO t1 VALUES ('zszs', 'contraction2 + contraction2');
+INSERT INTO t1 VALUES ('zzs', 'contraction2expansion2');
+INSERT INTO t1 VALUES ('zzS', 'contraction2expansion2');
+INSERT INTO t1 VALUES ('zZs', 'contraction2expansion2');
+INSERT INTO t1 VALUES ('zZS', 'contraction2expansion2');
+INSERT INTO t1 VALUES ('Zzs', 'contraction2expansion2');
+INSERT INTO t1 VALUES ('ZzS', 'contraction2expansion2');
+INSERT INTO t1 VALUES ('ZZs', 'contraction2expansion2');
+INSERT INTO t1 VALUES ('ZZS', 'contraction2expansion2');
+SELECT group_concat(a order by binary a) from t1 group by a;
+group_concat(a order by binary a)
+a
+C,c
+CA,Ca,cA,ca
+CZ,Cz,cZ,cz
+CS,Cs,cS,cs
+CCS,CCs,CcS,Ccs,cCS,cCs,ccS,ccs,cscs
+D,d
+DA,Da,dA,da
+DS,Ds,dS,ds
+DZ,Dz,dZ,dz
+DDZ,DDz,DdZ,Ddz,dDZ,dDz,ddZ,ddz,dzdz
+DZS,DZs,DzS,Dzs,dZS,dZs,dzS,dzs
+DDZS,DDZs,DDzS,DDzs,DdZS,DdZs,DdzS,Ddzs,dDZS,dDZs,dDzS,dDzs,ddZS,ddZs,ddzS,ddzs,dzsdzs
+G,g
+GA,Ga,gA,ga
+GZ,Gz,gZ,gz
+GY,Gy,gY,gy
+GGY,GGy,GgY,Ggy,gGY,gGy,ggY,ggy,gygy
+L,l
+LA,La,lA,la
+LZ,Lz,lZ,lz
+LY,Ly,lY,ly
+LLY,LLy,LlY,Lly,lLY,lLy,llY,lly,lyly
+N,n
+NA,Na,nA,na
+NZ,Nz,nZ,nz
+NY,Ny,nY,ny
+NNY,NNy,NnY,Nny,nNY,nNy,nnY,nny,nyny
+o
+Ö,ö,Ő,ő
+S,s
+SA,Sa,sA,sa
+SS,Ss,sS,ss
+SZ,Sz,sZ,sz
+SSZ,SSz,SsZ,Ssz,sSZ,sSz,ssZ,ssz,szsz
+T,t
+TA,Ta,tA,ta
+TZ,Tz,tZ,tz
+TY,Ty,tY,ty
+TTY,TTy,TtY,Tty,tTY,tTy,ttY,tty,tyty
+u
+Ü,ü,Ű,ű
+Z,z
+ZA,Za,zA,za
+ZZ,Zz,zZ,zz
+ZS,Zs,zS,zs
+ZZS,ZZs,ZzS,Zzs,zZS,zZs,zszs,zzS,zzs
+DROP TABLE t1;

--- 1.14/mysql-test/t/ctype_uca.test	2005-10-06 17:36:54 +05:00
+++ 1.15/mysql-test/t/ctype_uca.test	2005-12-13 15:24:13 +04:00
@@ -474,3 +474,219 @@
 SELECT a, length(a) la, @l:=lower(a) l, length(@l) ll, @u:=upper(a) u, length(@u) lu
 FROM t1 ORDER BY id;
 DROP TABLE t1;
+
+#
+# Check complex contractions: Hungarian
+#
+SET NAMES utf8;
+CREATE TABLE t1 (
+a varchar(10) character set utf8 collate utf8_hungarian_ci not null,
+b varchar(64));
+
+INSERT INTO t1 VALUES ('a','simple');
+
+-- &C < cs   <<< cS   <<< Cs   <<< CS
+INSERT INTO t1 VALUES ('c','simple'),('C','simple');
+INSERT INTO t1 VALUES ('ca','simple'),('cA','simple');
+INSERT INTO t1 VALUES ('Ca','simple'),('CA','simple');
+INSERT INTO t1 VALUES ('cs','contraction2'),('cS','contraction2');
+INSERT INTO t1 VALUES ('Cs','contraction2'),('CS','contraction2');
+INSERT INTO t1 VALUES ('cz','simple'),('cZ','simple');
+INSERT INTO t1 VALUES ('Cz','simple'),('CZ','simple');
+
+-- &D < dz      <<< dZ      <<< Dz      <<< DZ
+--    < dzs     <<< dzS     <<< dZs     <<< dZS
+--  <<< Dzs     <<< DzS     <<< DZs     <<< DZS
+
+INSERT INTO t1 VALUES ('d','simple'),('D','simple');
+INSERT INTO t1 VALUES ('da','simple'),('dA','simple');
+INSERT INTO t1 VALUES ('Da','simple'),('DA','simple');
+INSERT INTO t1 VALUES ('ds','simple'),('dS','simple');
+INSERT INTO t1 VALUES ('Ds','simple'),('DS','simple');
+INSERT INTO t1 VALUES ('dz','contraction2'),('dZ','contraction2');
+INSERT INTO t1 VALUES ('Dz','contraction2'),('DZ','contraction2');
+INSERT INTO t1 VALUES ('dzs','contraction3'),('dzS','contraction3');
+INSERT INTO t1 VALUES ('dZs','contraction3'),('dZS','contraction3');
+INSERT INTO t1 VALUES ('Dzs','contraction3'),('DzS','contraction3');
+INSERT INTO t1 VALUES ('DZs','contraction3'),('DZS','contraction3');
+
+-- &DZDZ <<< ddz <<< ddZ <<< dDz <<< dDZ <<< Ddz <<< DdZ <<< DDz <<< DDZ
+INSERT INTO t1 VALUES ('dzdz', 'contraction2 + contraction2');
+INSERT INTO t1 VALUES ('ddz', 'contraction2expansion2');
+INSERT INTO t1 VALUES ('ddZ', 'contraction2expansion2');
+INSERT INTO t1 VALUES ('dDz', 'contraction2expansion2');
+INSERT INTO t1 VALUES ('dDZ', 'contraction2expansion2');
+INSERT INTO t1 VALUES ('Ddz', 'contraction2expansion2');
+INSERT INTO t1 VALUES ('DdZ', 'contraction2expansion2');
+INSERT INTO t1 VALUES ('DDz', 'contraction2expansion2');
+INSERT INTO t1 VALUES ('DDZ', 'contraction2expansion2');
+
+-- &DZSDZS <<< ddzs <<< ddzS <<< ddZs <<< ddZS
+--         <<< dDzs <<< dDzS <<< dDZs <<< dDZS
+--         <<< Ddzs <<< DdzS <<< DdZs <<< DdZS
+--         <<< DDzs <<< DDzS <<< DDZs <<< DDZS
+INSERT INTO t1 VALUES ('dzsdzs', 'contraction3 + contraction3');
+INSERT INTO t1 VALUES ('ddzs', 'contraction4expansion2');
+INSERT INTO t1 VALUES ('ddzS', 'contraction4expansion2');
+INSERT INTO t1 VALUES ('ddZs', 'contraction4expansion2');
+INSERT INTO t1 VALUES ('ddZS', 'contraction4expansion2');
+INSERT INTO t1 VALUES ('dDzs', 'contraction4expansion2');
+INSERT INTO t1 VALUES ('dDzS', 'contraction4expansion2');
+INSERT INTO t1 VALUES ('dDZs', 'contraction4expansion2');
+INSERT INTO t1 VALUES ('dDZS', 'contraction4expansion2');
+INSERT INTO t1 VALUES ('Ddzs', 'contraction4expansion2');
+INSERT INTO t1 VALUES ('DdzS', 'contraction4expansion2');
+INSERT INTO t1 VALUES ('DdZs', 'contraction4expansion2');
+INSERT INTO t1 VALUES ('DdZS', 'contraction4expansion2');
+INSERT INTO t1 VALUES ('DDzs', 'contraction4expansion2');
+INSERT INTO t1 VALUES ('DDzS', 'contraction4expansion2');
+INSERT INTO t1 VALUES ('DDZs', 'contraction4expansion2');
+INSERT INTO t1 VALUES ('DDZS', 'contraction4expansion2');
+
+-- &G < gy      <<< gY      <<< Gy      <<< GY 
+INSERT INTO t1 VALUES ('g','simple'),('G','simple');
+INSERT INTO t1 VALUES ('ga','simple'),('gA','simple');
+INSERT INTO t1 VALUES ('Ga','simple'),('GA','simple');
+INSERT INTO t1 VALUES ('gy','contraction2'),('gY','contraction2');
+INSERT INTO t1 VALUES ('Gy','contraction2'),('GY','contraction2');
+INSERT INTO t1 VALUES ('gz','simple'),('gZ','simple');
+INSERT INTO t1 VALUES ('Gz','simple'),('GZ','simple');
+
+-- &L < ly      <<< lY      <<< Ly      <<< LY
+INSERT INTO t1 VALUES ('l','simple'),('L','simple');
+INSERT INTO t1 VALUES ('la','simple'),('lA','simple');
+INSERT INTO t1 VALUES ('La','simple'),('LA','simple');
+INSERT INTO t1 VALUES ('ly','contraction2'),('lY','contraction2');
+INSERT INTO t1 VALUES ('Ly','contraction2'),('LY','contraction2');
+INSERT INTO t1 VALUES ('lz','simple'),('lZ','simple');
+INSERT INTO t1 VALUES ('Lz','simple'),('LZ','simple');
+
+-- &N < ny      <<< nY      <<< Ny      <<< NY
+INSERT INTO t1 VALUES ('n','simple'),('N','simple');
+INSERT INTO t1 VALUES ('na','simple'),('nA','simple');
+INSERT INTO t1 VALUES ('Na','simple'),('NA','simple');
+INSERT INTO t1 VALUES ('ny','contraction2'),('nY','contraction2');
+INSERT INTO t1 VALUES ('Ny','contraction2'),('NY','contraction2');
+INSERT INTO t1 VALUES ('nz','simple'),('nZ','simple');
+INSERT INTO t1 VALUES ('Nz','simple'),('NZ','simple');
+
+-- & O < \u00F6 <<< \u00D6 << \u0151 <<< \u0150 */
+INSERT INTO t1 VALUES ('o', 'simple');
+INSERT INTO t1 VALUES (_ucs2 0x00F6, 'simple');
+INSERT INTO t1 VALUES (_ucs2 0x00D6, 'simple');
+INSERT INTO t1 VALUES (_ucs2 0x0151, 'simple');
+INSERT INTO t1 VALUES (_ucs2 0x0150, 'simple');
+
+-- &S < sz      <<< sZ      <<< Sz      <<< SZ
+INSERT INTO t1 VALUES ('s','simple'),('S','simple');
+INSERT INTO t1 VALUES ('sa','simple'),('sA','simple');
+INSERT INTO t1 VALUES ('Sa','simple'),('SA','simple');
+INSERT INTO t1 VALUES ('ss','simple'),('sS','simple');
+INSERT INTO t1 VALUES ('Ss','simple'),('SS','simple');
+INSERT INTO t1 VALUES ('sz','contraction2'),('sZ','contraction2');
+INSERT INTO t1 VALUES ('Sz','contraction2'),('SZ','contraction2');
+
+-- &T < ty      <<< tY      <<< Ty      <<< TY 
+INSERT INTO t1 VALUES ('t','simple'),('T','simple');
+INSERT INTO t1 VALUES ('ta','simple'),('tA','simple');
+INSERT INTO t1 VALUES ('Ta','simple'),('TA','simple');
+INSERT INTO t1 VALUES ('ty','contraction2'),('tY','contraction2');
+INSERT INTO t1 VALUES ('Ty','contraction2'),('TY','contraction2');
+INSERT INTO t1 VALUES ('tz','simple'),('tZ','simple');
+INSERT INTO t1 VALUES ('Tz','simple'),('TZ','simple');
+
+-- &U < \u00FC <<< \u00DC << \u0171 <<< \u0170"
+INSERT INTO t1 VALUES ('u', 'simple');
+INSERT INTO t1 VALUES (_ucs2 0x00FC, 'simple');
+INSERT INTO t1 VALUES (_ucs2 0x00DC, 'simple');
+INSERT INTO t1 VALUES (_ucs2 0x0171, 'simple');
+INSERT INTO t1 VALUES (_ucs2 0x0170, 'simple');
+
+-- &Z < zs      <<< zS      <<< Zs      <<< ZS
+INSERT INTO t1 VALUES ('z','simple'),('Z','simple');
+INSERT INTO t1 VALUES ('za','simple'),('zA','simple');
+INSERT INTO t1 VALUES ('Za','simple'),('ZA','simple');
+INSERT INTO t1 VALUES ('zs','contraction2'),('zS','contraction2');
+INSERT INTO t1 VALUES ('Zs','contraction2'),('ZS','contraction2');
+INSERT INTO t1 VALUES ('zz','simple'),('zZ','simple');
+INSERT INTO t1 VALUES ('Zz','simple'),('ZZ','simple');
+
+-- &CSCS <<< ccs <<< ccS <<< cCs <<< cCS <<< Ccs <<< CcS <<< CCs <<< CCS
+INSERT INTO t1 VALUES ('cscs', 'contraction2 + contraction2');
+INSERT INTO t1 VALUES ('ccs', 'contraction2expansion2');
+INSERT INTO t1 VALUES ('ccS', 'contraction2expansion2');
+INSERT INTO t1 VALUES ('cCs', 'contraction2expansion2');
+INSERT INTO t1 VALUES ('cCS', 'contraction2expansion2');
+INSERT INTO t1 VALUES ('Ccs', 'contraction2expansion2');
+INSERT INTO t1 VALUES ('CcS', 'contraction2expansion2');
+INSERT INTO t1 VALUES ('CCs', 'contraction2expansion2');
+INSERT INTO t1 VALUES ('CCS', 'contraction2expansion2');
+
+-- &GYGY <<< ggy <<< ggY <<< gGy <<< gGY <<< Ggy <<< GgY <<< GGy <<< GGY 
+INSERT INTO t1 VALUES ('gygy', 'contraction2 + contraction2');
+INSERT INTO t1 VALUES ('ggy', 'contraction2expansion2');
+INSERT INTO t1 VALUES ('ggY', 'contraction2expansion2');
+INSERT INTO t1 VALUES ('gGy', 'contraction2expansion2');
+INSERT INTO t1 VALUES ('gGY', 'contraction2expansion2');
+INSERT INTO t1 VALUES ('Ggy', 'contraction2expansion2');
+INSERT INTO t1 VALUES ('GgY', 'contraction2expansion2');
+INSERT INTO t1 VALUES ('GGy', 'contraction2expansion2');
+INSERT INTO t1 VALUES ('GGY', 'contraction2expansion2');
+
+-- &LYLY <<< lly <<< llY <<< lLy <<< lLY <<< Lly <<< LlY <<< LLy <<< LLY
+INSERT INTO t1 VALUES ('lyly', 'contraction2 + contraction2');
+INSERT INTO t1 VALUES ('lly', 'contraction2expansion2');
+INSERT INTO t1 VALUES ('llY', 'contraction2expansion2');
+INSERT INTO t1 VALUES ('lLy', 'contraction2expansion2');
+INSERT INTO t1 VALUES ('lLY', 'contraction2expansion2');
+INSERT INTO t1 VALUES ('Lly', 'contraction2expansion2');
+INSERT INTO t1 VALUES ('LlY', 'contraction2expansion2');
+INSERT INTO t1 VALUES ('LLy', 'contraction2expansion2');
+INSERT INTO t1 VALUES ('LLY', 'contraction2expansion2');
+
+-- &NYNY <<< nny <<< nnY <<< nNy <<< nNY <<< Nny <<< NnY <<< NNy <<< NNY 
+INSERT INTO t1 VALUES ('nyny', 'contraction2 + contraction2');
+INSERT INTO t1 VALUES ('nny', 'contraction2expansion2');
+INSERT INTO t1 VALUES ('nnY', 'contraction2expansion2');
+INSERT INTO t1 VALUES ('nNy', 'contraction2expansion2');
+INSERT INTO t1 VALUES ('nNY', 'contraction2expansion2');
+INSERT INTO t1 VALUES ('Nny', 'contraction2expansion2');
+INSERT INTO t1 VALUES ('NnY', 'contraction2expansion2');
+INSERT INTO t1 VALUES ('NNy', 'contraction2expansion2');
+INSERT INTO t1 VALUES ('NNY', 'contraction2expansion2');
+
+-- &SZSZ <<< ssz <<< ssZ <<< sSz <<< sSZ <<< Ssz <<< SsZ <<< SSz <<< SSZ
+INSERT INTO t1 VALUES ('szsz', 'contraction2 + contraction2');
+INSERT INTO t1 VALUES ('ssz', 'contraction2expansion2');
+INSERT INTO t1 VALUES ('ssZ', 'contraction2expansion2');
+INSERT INTO t1 VALUES ('sSz', 'contraction2expansion2');
+INSERT INTO t1 VALUES ('sSZ', 'contraction2expansion2');
+INSERT INTO t1 VALUES ('Ssz', 'contraction2expansion2');
+INSERT INTO t1 VALUES ('SsZ', 'contraction2expansion2');
+INSERT INTO t1 VALUES ('SSz', 'contraction2expansion2');
+INSERT INTO t1 VALUES ('SSZ', 'contraction2expansion2');
+
+-- &TYTY <<< tty <<< ttY <<< tTy <<< tTY <<< Tty <<< TtY <<< TTy <<< TTY
+INSERT INTO t1 VALUES ('tyty', 'contraction2 + contraction2');
+INSERT INTO t1 VALUES ('tty', 'contraction2expansion2');
+INSERT INTO t1 VALUES ('ttY', 'contraction2expansion2');
+INSERT INTO t1 VALUES ('tTy', 'contraction2expansion2');
+INSERT INTO t1 VALUES ('tTY', 'contraction2expansion2');
+INSERT INTO t1 VALUES ('Tty', 'contraction2expansion2');
+INSERT INTO t1 VALUES ('TtY', 'contraction2expansion2');
+INSERT INTO t1 VALUES ('TTy', 'contraction2expansion2');
+INSERT INTO t1 VALUES ('TTY', 'contraction2expansion2');
+
+-- &ZSZS <<< zzs <<< zzS <<< zZs <<< zZS <<< Zzs <<< ZzS <<< ZZs <<< ZZS
+INSERT INTO t1 VALUES ('zszs', 'contraction2 + contraction2');
+INSERT INTO t1 VALUES ('zzs', 'contraction2expansion2');
+INSERT INTO t1 VALUES ('zzS', 'contraction2expansion2');
+INSERT INTO t1 VALUES ('zZs', 'contraction2expansion2');
+INSERT INTO t1 VALUES ('zZS', 'contraction2expansion2');
+INSERT INTO t1 VALUES ('Zzs', 'contraction2expansion2');
+INSERT INTO t1 VALUES ('ZzS', 'contraction2expansion2');
+INSERT INTO t1 VALUES ('ZZs', 'contraction2expansion2');
+INSERT INTO t1 VALUES ('ZZS', 'contraction2expansion2');
+
+SELECT group_concat(a order by binary a) from t1 group by a;
+DROP TABLE t1;

--- 1.14/mysys/charset-def.c	2005-09-12 19:35:16 +05:00
+++ 1.15/mysys/charset-def.c	2005-12-13 15:22:52 +04:00
@@ -64,6 +64,7 @@
 extern CHARSET_INFO my_charset_utf8_roman_uca_ci;
 extern CHARSET_INFO my_charset_utf8_persian_uca_ci;
 extern CHARSET_INFO my_charset_utf8_esperanto_uca_ci;
+extern CHARSET_INFO my_charset_utf8_hungarian_uca_ci;
 #ifdef HAVE_UTF8_GENERAL_CS
 extern CHARSET_INFO my_charset_utf8_general_cs;
 #endif
@@ -184,6 +185,7 @@
   add_compiled_collation(&my_charset_utf8_roman_uca_ci);
   add_compiled_collation(&my_charset_utf8_persian_uca_ci);
   add_compiled_collation(&my_charset_utf8_esperanto_uca_ci);
+  add_compiled_collation(&my_charset_utf8_hungarian_uca_ci);
 #endif
 #endif
 
Thread
bk commit into 5.1 tree (bar:1.1958)bar13 Dec