File: charset_collations.cc

package info (click to toggle)
mariadb 1%3A11.8.3-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 772,520 kB
  • sloc: ansic: 2,414,714; cpp: 1,791,394; asm: 381,336; perl: 62,905; sh: 49,647; pascal: 40,897; java: 39,363; python: 20,791; yacc: 20,432; sql: 17,907; xml: 12,344; ruby: 8,544; cs: 6,542; makefile: 6,145; ada: 1,879; lex: 1,193; javascript: 996; objc: 80; tcl: 73; awk: 46; php: 22
file content (117 lines) | stat: -rw-r--r-- 3,939 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
/* Copyright (c) 2023, MariaDB Corporation.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; version 2 of the License.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335  USA */


#include "my_global.h"
#include "my_sys.h"
#include "lex_charset.h"
#include "mysqld_error.h"
#include "charset_collations.h"
#include "simple_tokenizer.h"

bool Charset_collation_map_st::insert_or_replace(
                                  const Lex_exact_charset &charset,
                                  const Lex_extended_collation &collation,
                                  bool error_on_conflicting_duplicate)
{
  Lex_exact_charset_opt_extended_collate res(charset);
  Sql_used used;
  if (res.merge_collation_override(&used, *this, collation))
    return true;

  if (error_on_conflicting_duplicate)
  {
    const Elem_st *dup;
    if ((dup= find_elem_by_charset_id(charset.charset_info()->number)) &&
        dup->to() != res.collation().charset_info())
    {
      my_error(ER_CONFLICTING_DECLARATIONS, MYF(0),
               "", dup->to()->coll_name.str,
               "", res.collation().charset_info()->coll_name.str);
      return true;
    }
  }
  return insert_or_replace(Elem(charset.charset_info(),
                                res.collation().charset_info()));
}


bool Charset_collation_map_st::insert_or_replace(
                                  const LEX_CSTRING &cs_name,
                                  const LEX_CSTRING &cl_name,
                                  bool error_on_conflicting_duplicate,
                                  myf utf8_flag)
{
  char charset_name_c[MY_CS_CHARACTER_SET_NAME_SIZE + 1/*for '\0'*/];
  strmake(charset_name_c, cs_name.str, cs_name.length);
  CHARSET_INFO *cs= get_charset_by_csname(charset_name_c,
                                          MY_CS_PRIMARY, utf8_flag);
  if (!cs)
  {
    my_error(ER_UNKNOWN_CHARACTER_SET, MYF(0), charset_name_c);
    return true;
  }

  char collation_name_c[MY_CS_COLLATION_NAME_SIZE + 1/*for '\0'*/];
  strmake(collation_name_c, cl_name.str, cl_name.length);

  Lex_exact_collation tmpec(&my_charset_bin);
  Lex_extended_collation tmp(tmpec);
  if (tmp.set_by_name(collation_name_c, utf8_flag))
    return true;

  return insert_or_replace(Lex_exact_charset(cs), tmp,
                           error_on_conflicting_duplicate);
}


bool Charset_collation_map_st::from_text(const LEX_CSTRING &str, myf utf8_flag)
{
  init();
  Simple_tokenizer stream(str.str, str.length);

  /*
    Allow relaxed comma parsing:
    SET @@character_set_collations=
       ',,,utf8mb3 = utf8mb3_bin,,latin1 = latin1_bin,,,';
    It makes it easier for the user to edit the value
    using SQL functions CONCAT or REGEXP_REPLACE.
  */
  for ( ; ; )
  {
    LEX_CSTRING charset_name= stream.get_ident();
    if (charset_name.length)
    {
      if (stream.get_char('='))
        return true;
      LEX_CSTRING collation_name= stream.get_ident();
      if (!collation_name.length)
        return true;
      /*
        Don't allow duplicate conflicting declarations within the same string:
          SET @@var='utf8mb3=utf8mb3_general_ci,utf8mb3=utf8mb3_bin';
      */
      if (insert_or_replace(charset_name, collation_name,
                            true/*err on dup*/, utf8_flag))
        return true;
    }
    if (!stream.get_char(','))
      continue;
    if (stream.eof())
      return false;
    return true;
  }
  return false;
}