static int add_collation()

in mysql_sys/charset.cc [221:322]


static int add_collation(CHARSET_INFO *cs) {
  if (cs->name &&
      (cs->number || (cs->number = get_collation_number_internal(cs->name))) &&
      cs->number < array_elements(all_charsets)) {
    if (!all_charsets[cs->number]) {
      if (!(all_charsets[cs->number] =
                (CHARSET_INFO *)my_once_alloc(sizeof(CHARSET_INFO), MYF(0))))
        return MY_XML_ERROR;
      memset(all_charsets[cs->number], 0, sizeof(CHARSET_INFO));
    } else if (all_charsets[cs->number]->state & MY_CS_COMPILED) {
      // Disallow overwriting compiled character sets
      clear_cs_info(cs);
      return MY_XML_OK;  // Just ignore it.
    }

    if (cs->primary_number == cs->number) cs->state |= MY_CS_PRIMARY;

    if (cs->binary_number == cs->number) cs->state |= MY_CS_BINSORT;

    all_charsets[cs->number]->state |= cs->state;
    map_coll_name_to_number(cs->name, cs->number);
    map_cs_name_to_number(cs->csname, cs->number, cs->state);

    if (!(all_charsets[cs->number]->state & MY_CS_COMPILED)) {
      CHARSET_INFO *newcs = all_charsets[cs->number];
      if (cs_copy_data(all_charsets[cs->number], cs)) return MY_XML_ERROR;

      newcs->caseup_multiply = newcs->casedn_multiply = 1;
      newcs->levels_for_compare = 1;

      if (!strcmp(cs->csname, "ucs2")) {
        copy_uca_collation(newcs, &my_charset_ucs2_unicode_ci);
        newcs->state |= MY_CS_AVAILABLE | MY_CS_LOADED | MY_CS_NONASCII;
      } else if (!strcmp(cs->csname, "utf8") ||
                 !strcmp(cs->csname, "utf8mb3")) {
        copy_uca_collation(newcs, &my_charset_utf8_unicode_ci);
        newcs->ctype = my_charset_utf8_unicode_ci.ctype;
        if (init_state_maps(newcs)) return MY_XML_ERROR;
      } else if (!strcmp(cs->csname, "utf8mb4")) {
        copy_uca_collation(newcs, &my_charset_utf8mb4_unicode_ci);
        newcs->ctype = my_charset_utf8mb4_unicode_ci.ctype;
        newcs->state |= MY_CS_AVAILABLE | MY_CS_LOADED;
      } else if (!strcmp(cs->csname, "utf16")) {
        copy_uca_collation(newcs, &my_charset_utf16_unicode_ci);
        newcs->state |= MY_CS_AVAILABLE | MY_CS_LOADED | MY_CS_NONASCII;
      } else if (!strcmp(cs->csname, "utf32")) {
        copy_uca_collation(newcs, &my_charset_utf32_unicode_ci);
        newcs->state |= MY_CS_AVAILABLE | MY_CS_LOADED | MY_CS_NONASCII;
      } else {
        const uchar *sort_order = all_charsets[cs->number]->sort_order;
        simple_cs_init_functions(all_charsets[cs->number]);
        newcs->mbminlen = 1;
        newcs->mbmaxlen = 1;
        if (simple_cs_is_full(all_charsets[cs->number])) {
          all_charsets[cs->number]->state |= MY_CS_LOADED;
        }
        all_charsets[cs->number]->state |= MY_CS_AVAILABLE;

        /*
          Check if case sensitive sort order: A < a < B.
          We need MY_CS_FLAG for regex library, and for
          case sensitivity flag for 5.0 client protocol,
          to support isCaseSensitive() method in JDBC driver
        */
        if (sort_order &&
            sort_order[static_cast<int>('A')] <
                sort_order[static_cast<int>('a')] &&
            sort_order[static_cast<int>('a')] <
                sort_order[static_cast<int>('B')])
          all_charsets[cs->number]->state |= MY_CS_CSSORT;

        if (my_charset_is_8bit_pure_ascii(all_charsets[cs->number]))
          all_charsets[cs->number]->state |= MY_CS_PUREASCII;
        if (!my_charset_is_ascii_compatible(cs))
          all_charsets[cs->number]->state |= MY_CS_NONASCII;
      }
    } else {
      /*
        We need the below to make get_charset_name()
        and get_charset_number() working even if a
        character set has not been really incompiled.
        The above functions are used for example
        in error message compiler utilities/comp_err.cc.
        If a character set was compiled, this information
        will get lost and overwritten in add_compiled_collation().
      */
      CHARSET_INFO *dst = all_charsets[cs->number];
      dst->number = cs->number;
      if (cs->comment)
        if (!(dst->comment = my_once_strdup(cs->comment, MYF(MY_WME))))
          return MY_XML_ERROR;
      if (cs->csname)
        if (!(dst->csname = my_once_strdup(cs->csname, MYF(MY_WME))))
          return MY_XML_ERROR;
      if (cs->name)
        if (!(dst->name = my_once_strdup(cs->name, MYF(MY_WME))))
          return MY_XML_ERROR;
    }
    clear_cs_info(cs);
  }
  return MY_XML_OK;
}