Coverage Report

Created: 2026-05-25 06:46

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/mysql-server/sql/sql_lex_hash.cc
Line
Count
Source
1
/*
2
   Copyright (c) 2015, 2025, Oracle and/or its affiliates.
3
4
   This program is free software; you can redistribute it and/or modify
5
   it under the terms of the GNU General Public License, version 2.0,
6
   as published by the Free Software Foundation.
7
8
   This program is designed to work with certain software (including
9
   but not limited to OpenSSL) that is licensed under separate terms,
10
   as designated in a particular file or component or in included license
11
   documentation.  The authors of MySQL hereby grant you an additional
12
   permission to link the program and your derivative works with the
13
   separately licensed software that they have either included with
14
   the program or referenced in the documentation.
15
16
   This program is distributed in the hope that it will be useful,
17
   but WITHOUT ANY WARRANTY; without even the implied warranty of
18
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19
   GNU General Public License, version 2.0, for more details.
20
21
   You should have received a copy of the GNU General Public License
22
   along with this program; if not, write to the Free Software
23
   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA */
24
25
#include "sql/sql_lex_hash.h"
26
27
#include <sys/types.h>
28
29
#include "my_byteorder.h"
30
#include "my_dbug.h"
31
#include "my_inttypes.h"
32
#include "sql/lex.h"
33
#include "sql/lex_hash.h"
34
#include "sql/lex_symbol.h"
35
#include "template_utils.h"
36
37
const Lex_hash Lex_hash::sql_keywords(sql_keywords_map, sql_keywords_max_len);
38
const Lex_hash Lex_hash::sql_keywords_and_funcs(sql_keywords_and_funcs_map,
39
                                                sql_keywords_and_funcs_max_len);
40
41
const Lex_hash Lex_hash::hint_keywords(hint_keywords_map,
42
                                       hint_keywords_max_len);
43
44
/*
45
  The following data is based on the latin1 character set, and is only
46
  used when comparing keywords
47
*/
48
49
static const uchar to_upper_lex[] = {
50
    0,   1,   2,   3,   4,   5,   6,   7,   8,   9,   10,  11,  12,  13,  14,
51
    15,  16,  17,  18,  19,  20,  21,  22,  23,  24,  25,  26,  27,  28,  29,
52
    30,  31,  32,  33,  34,  35,  36,  37,  38,  39,  40,  41,  42,  43,  44,
53
    45,  46,  47,  48,  49,  50,  51,  52,  53,  54,  55,  56,  57,  58,  59,
54
    60,  61,  62,  63,  64,  65,  66,  67,  68,  69,  70,  71,  72,  73,  74,
55
    75,  76,  77,  78,  79,  80,  81,  82,  83,  84,  85,  86,  87,  88,  89,
56
    90,  91,  92,  93,  94,  95,  96,  65,  66,  67,  68,  69,  70,  71,  72,
57
    73,  74,  75,  76,  77,  78,  79,  80,  81,  82,  83,  84,  85,  86,  87,
58
    88,  89,  90,  123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134,
59
    135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149,
60
    150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164,
61
    165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179,
62
    180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194,
63
    195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209,
64
    210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 192,
65
    193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207,
66
    208, 209, 210, 211, 212, 213, 214, 247, 216, 217, 218, 219, 220, 221, 222,
67
    255};
68
69
88.6k
inline int lex_casecmp(const char *s, const char *t, uint len) {
70
96.1k
  while (len-- != 0 && to_upper_lex[(uchar)*s++] == to_upper_lex[(uchar)*t++])
71
7.49k
    ;
72
88.6k
  return (int)len + 1;
73
88.6k
}
74
75
323k
const SYMBOL *Lex_hash::get_hash_symbol(const char *s, unsigned int len) const {
76
323k
  const char *cur_str = s;
77
78
323k
  if (len == 0) {
79
57
    DBUG_PRINT("warning",
80
57
               ("get_hash_symbol() received a request for a zero-length symbol,"
81
57
                " which is probably a mistake."));
82
57
    return nullptr;
83
57
  }
84
85
323k
  if (len > entry_max_len) return nullptr;
86
87
318k
  uint32 cur_struct = uint4korr(hash_map + ((len - 1) * 4));
88
89
464k
  for (;;) {
90
464k
    const auto first_char = (uchar)cur_struct;
91
92
464k
    if (first_char == 0) {
93
110k
      const auto ires = (uint16)(cur_struct >> 16);
94
110k
      if (ires == array_elements(symbols)) return nullptr;
95
88.6k
      const SYMBOL *res = symbols + ires;
96
88.6k
      const uint count = (uint)(cur_str - s);
97
88.6k
      return lex_casecmp(cur_str, res->name + count, len - count) ? nullptr
98
88.6k
                                                                  : res;
99
110k
    }
100
101
353k
    const auto cur_char = (uchar)to_upper_lex[(uchar)*cur_str];
102
353k
    if (cur_char < first_char) return nullptr;
103
241k
    cur_struct >>= 8;
104
241k
    if (cur_char > (uchar)cur_struct) return nullptr;
105
106
145k
    cur_struct >>= 8;
107
145k
    cur_struct = uint4korr(hash_map +
108
145k
                           (((uint16)cur_struct + cur_char - first_char) * 4));
109
145k
    cur_str++;
110
145k
  }
111
318k
}