YugabyteDB (2.13.1.0-b60, 21121d69985fbf76aa6958d8f04a9bfa936293b5)

Coverage Report

Created: 2022-03-22 16:43

/Users/deen/code/yugabyte-db/src/postgres/src/common/keywords.c
Line
Count
Source
1
/*-------------------------------------------------------------------------
2
 *
3
 * keywords.c
4
 *    lexical token lookup for key words in PostgreSQL
5
 *
6
 *
7
 * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group
8
 * Portions Copyright (c) 1994, Regents of the University of California
9
 *
10
 *
11
 * IDENTIFICATION
12
 *    src/common/keywords.c
13
 *
14
 *-------------------------------------------------------------------------
15
 */
16
#ifndef FRONTEND
17
#include "postgres.h"
18
#else
19
#include "postgres_fe.h"
20
#endif
21
22
#ifndef FRONTEND
23
24
#include "parser/gramparse.h"
25
26
#define PG_KEYWORD(a,b,c) {a,b,c},
27
28
#else
29
30
#include "common/keywords.h"
31
32
/*
33
 * We don't need the token number for frontend uses, so leave it out to avoid
34
 * requiring backend headers that won't compile cleanly here.
35
 */
36
#define PG_KEYWORD(a,b,c) {a,0,c},
37
38
#endif              /* FRONTEND */
39
40
41
const ScanKeyword ScanKeywords[] = {
42
#include "parser/kwlist.h"
43
};
44
45
const int NumScanKeywords = lengthof(ScanKeywords);
46
47
48
/*
49
 * ScanKeywordLookup - see if a given word is a keyword
50
 *
51
 * The table to be searched is passed explicitly, so that this can be used
52
 * to search keyword lists other than the standard list appearing above.
53
 *
54
 * Returns a pointer to the ScanKeyword table entry, or NULL if no match.
55
 *
56
 * The match is done case-insensitively.  Note that we deliberately use a
57
 * dumbed-down case conversion that will only translate 'A'-'Z' into 'a'-'z',
58
 * even if we are in a locale where tolower() would produce more or different
59
 * translations.  This is to conform to the SQL99 spec, which says that
60
 * keywords are to be matched in this way even though non-keyword identifiers
61
 * receive a different case-normalization mapping.
62
 */
63
const ScanKeyword *
64
ScanKeywordLookup(const char *text,
65
          const ScanKeyword *keywords,
66
          int num_keywords)
67
15.5M
{
68
15.5M
  int     len,
69
15.5M
        i;
70
15.5M
  char    word[NAMEDATALEN];
71
15.5M
  const ScanKeyword *low;
72
15.5M
  const ScanKeyword *high;
73
74
15.5M
  len = strlen(text);
75
  /* We assume all keywords are shorter than NAMEDATALEN. */
76
15.5M
  if (len >= NAMEDATALEN)
77
480
    return NULL;
78
79
  /*
80
   * Apply an ASCII-only downcasing.  We must not use tolower() since it may
81
   * produce the wrong translation in some locales (eg, Turkish).
82
   */
83
103M
  
for (i = 0; 15.5M
i < len;
i++87.6M
)
84
87.6M
  {
85
87.6M
    char    ch = text[i];
86
87
87.6M
    if (ch >= 'A' && 
ch <= 'Z'86.3M
)
88
43.6M
      ch += 'a' - 'A';
89
87.6M
    word[i] = ch;
90
87.6M
  }
91
15.5M
  word[len] = '\0';
92
93
  /*
94
   * Now do a binary search using plain strcmp() comparison.
95
   */
96
15.5M
  low = keywords;
97
15.5M
  high = keywords + (num_keywords - 1);
98
133M
  while (low <= high)
99
127M
  {
100
127M
    const ScanKeyword *middle;
101
127M
    int     difference;
102
103
127M
    middle = low + (high - low) / 2;
104
127M
    difference = strcmp(middle->name, word);
105
127M
    if (difference == 0)
106
9.31M
      return middle;
107
117M
    else if (difference < 0)
108
65.7M
      low = middle + 1;
109
52.0M
    else
110
52.0M
      high = middle - 1;
111
127M
  }
112
113
6.26M
  return NULL;
114
15.5M
}