1 /*-------------------------------------------------------------------------
4 * lexical token lookup for key words in PostgreSQL
6 * NB - this file is also used by ECPG and several frontend programs in
7 * src/bin/ including pg_dump and psql
9 * Note that this file expects that the ScanKeywords array is defined
10 * and that LastScanKeyword points to its element one past the last.
12 * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
13 * Portions Copyright (c) 1994, Regents of the University of California
19 *-------------------------------------------------------------------------
22 /* use c.h so this can be built as either frontend or backend */
27 #include "parser/keywords.h"
30 * ScanKeywordLookup - see if a given word is a keyword
32 * Returns a pointer to the ScanKeyword table entry, or NULL if no match.
34 * The match is done case-insensitively. Note that we deliberately use a
35 * dumbed-down case conversion that will only translate 'A'-'Z' into 'a'-'z',
36 * even if we are in a locale where tolower() would produce more or different
37 * translations. This is to conform to the SQL99 spec, which says that
38 * keywords are to be matched in this way even though non-keyword identifiers
39 * receive a different case-normalization mapping.
42 ScanKeywordLookup(const char *text
)
46 char word
[NAMEDATALEN
];
47 const ScanKeyword
*low
;
48 const ScanKeyword
*high
;
51 /* We assume all keywords are shorter than NAMEDATALEN. */
52 if (len
>= NAMEDATALEN
)
56 * Apply an ASCII-only downcasing. We must not use tolower() since it may
57 * produce the wrong translation in some locales (eg, Turkish).
59 for (i
= 0; i
< len
; i
++)
63 if (ch
>= 'A' && ch
<= 'Z')
70 * Now do a binary search using plain strcmp() comparison.
72 low
= &ScanKeywords
[0];
73 high
= LastScanKeyword
- 1;
76 const ScanKeyword
*middle
;
79 middle
= low
+ (high
- low
) / 2;
80 difference
= strcmp(middle
->name
, word
);
83 else if (difference
< 0)