]> git.8kb.co.uk Git - pgpool-ii/pgpool-ii_2.2.5/blob - parser/keywords.c
Attempt to send a proper failure message to frontend when authentication
[pgpool-ii/pgpool-ii_2.2.5] / parser / keywords.c
1 /*-------------------------------------------------------------------------
2  *
3  * keywords.c
4  *        lexical token lookup for key words in PostgreSQL
5  *
6  * Portions Copyright (c) 2003-2008, PgPool Global Development Group
7  * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
8  * Portions Copyright (c) 1994, Regents of the University of California
9  *
10  *
11  * IDENTIFICATION
12  *        $PostgreSQL: pgsql/src/backend/parser/keywords.c,v 1.192 2007/09/24 01:29:29 adunstan Exp $
13  *
14  *-------------------------------------------------------------------------
15  */
16 #include "pool_parser.h"
17
18 #include <ctype.h>
19 #include <string.h>
20
21 #include "parsenodes.h"
22 #include "gramparse.h"  /* required before parser/parse.h! */
23 #include "keywords.h"
24 #include "gram.h"
25
26 /* NB: This file is also used by pg_dump. */
27
28 /*
29  * List of keyword (name, token-value, category) entries.
30  *
31  * !!WARNING!!: This list must be sorted by ASCII name, because binary
32  *               search is used to locate entries.
33  */
34 static const ScanKeyword ScanKeywords[] = {
35         /* name, value, category */
36         {"abort", ABORT_P, UNRESERVED_KEYWORD},
37         {"absolute", ABSOLUTE_P, UNRESERVED_KEYWORD},
38         {"access", ACCESS, UNRESERVED_KEYWORD},
39         {"action", ACTION, UNRESERVED_KEYWORD},
40         {"add", ADD_P, UNRESERVED_KEYWORD},
41         {"admin", ADMIN, UNRESERVED_KEYWORD},
42         {"after", AFTER, UNRESERVED_KEYWORD},
43         {"aggregate", AGGREGATE, UNRESERVED_KEYWORD},
44         {"all", ALL, RESERVED_KEYWORD},
45         {"also", ALSO, UNRESERVED_KEYWORD},
46         {"alter", ALTER, UNRESERVED_KEYWORD},
47         {"always", ALWAYS, UNRESERVED_KEYWORD},
48         {"analyse", ANALYSE, RESERVED_KEYWORD},         /* British spelling */
49         {"analyze", ANALYZE, RESERVED_KEYWORD},
50         {"and", AND, RESERVED_KEYWORD},
51         {"any", ANY, RESERVED_KEYWORD},
52         {"array", ARRAY, RESERVED_KEYWORD},
53         {"as", AS, RESERVED_KEYWORD},
54         {"asc", ASC, RESERVED_KEYWORD},
55         {"assertion", ASSERTION, UNRESERVED_KEYWORD},
56         {"assignment", ASSIGNMENT, UNRESERVED_KEYWORD},
57         {"asymmetric", ASYMMETRIC, RESERVED_KEYWORD},
58         {"at", AT, UNRESERVED_KEYWORD},
59         {"authorization", AUTHORIZATION, TYPE_FUNC_NAME_KEYWORD},
60         {"backward", BACKWARD, UNRESERVED_KEYWORD},
61         {"before", BEFORE, UNRESERVED_KEYWORD},
62         {"begin", BEGIN_P, UNRESERVED_KEYWORD},
63         {"between", BETWEEN, TYPE_FUNC_NAME_KEYWORD},
64         {"bigint", BIGINT, COL_NAME_KEYWORD},
65         {"binary", BINARY, TYPE_FUNC_NAME_KEYWORD},
66         {"bit", BIT, COL_NAME_KEYWORD},
67         {"boolean", BOOLEAN_P, COL_NAME_KEYWORD},
68         {"both", BOTH, RESERVED_KEYWORD},
69         {"by", BY, UNRESERVED_KEYWORD},
70         {"cache", CACHE, UNRESERVED_KEYWORD},
71         {"called", CALLED, UNRESERVED_KEYWORD},
72         {"cascade", CASCADE, UNRESERVED_KEYWORD},
73         {"cascaded", CASCADED, UNRESERVED_KEYWORD},
74         {"case", CASE, RESERVED_KEYWORD},
75         {"cast", CAST, RESERVED_KEYWORD},
76         {"chain", CHAIN, UNRESERVED_KEYWORD},
77         {"char", CHAR_P, COL_NAME_KEYWORD},
78         {"character", CHARACTER, COL_NAME_KEYWORD},
79         {"characteristics", CHARACTERISTICS, UNRESERVED_KEYWORD},
80         {"check", CHECK, RESERVED_KEYWORD},
81         {"checkpoint", CHECKPOINT, UNRESERVED_KEYWORD},
82         {"class", CLASS, UNRESERVED_KEYWORD},
83         {"close", CLOSE, UNRESERVED_KEYWORD},
84         {"cluster", CLUSTER, UNRESERVED_KEYWORD},
85         {"coalesce", COALESCE, COL_NAME_KEYWORD},
86         {"collate", COLLATE, RESERVED_KEYWORD},
87         {"column", COLUMN, RESERVED_KEYWORD},
88         {"comment", COMMENT, UNRESERVED_KEYWORD},
89         {"commit", COMMIT, UNRESERVED_KEYWORD},
90         {"committed", COMMITTED, UNRESERVED_KEYWORD},
91         {"concurrently", CONCURRENTLY, UNRESERVED_KEYWORD},
92         {"configuration", CONFIGURATION, UNRESERVED_KEYWORD},
93         {"connection", CONNECTION, UNRESERVED_KEYWORD},
94         {"constraint", CONSTRAINT, RESERVED_KEYWORD},
95         {"constraints", CONSTRAINTS, UNRESERVED_KEYWORD},
96         {"content", CONTENT_P, UNRESERVED_KEYWORD},
97         {"conversion", CONVERSION_P, UNRESERVED_KEYWORD},
98         {"copy", COPY, UNRESERVED_KEYWORD},
99         {"cost", COST, UNRESERVED_KEYWORD},
100         {"create", CREATE, RESERVED_KEYWORD},
101         {"createdb", CREATEDB, UNRESERVED_KEYWORD},
102         {"createrole", CREATEROLE, UNRESERVED_KEYWORD},
103         {"createuser", CREATEUSER, UNRESERVED_KEYWORD},
104         {"cross", CROSS, TYPE_FUNC_NAME_KEYWORD},
105         {"csv", CSV, UNRESERVED_KEYWORD},
106         {"current", CURRENT_P, UNRESERVED_KEYWORD},
107         {"current_date", CURRENT_DATE, RESERVED_KEYWORD},
108         {"current_role", CURRENT_ROLE, RESERVED_KEYWORD},
109         {"current_time", CURRENT_TIME, RESERVED_KEYWORD},
110         {"current_timestamp", CURRENT_TIMESTAMP, RESERVED_KEYWORD},
111         {"current_user", CURRENT_USER, RESERVED_KEYWORD},
112         {"cursor", CURSOR, UNRESERVED_KEYWORD},
113         {"cycle", CYCLE, UNRESERVED_KEYWORD},
114         {"database", DATABASE, UNRESERVED_KEYWORD},
115         {"day", DAY_P, UNRESERVED_KEYWORD},
116         {"deallocate", DEALLOCATE, UNRESERVED_KEYWORD},
117         {"dec", DEC, COL_NAME_KEYWORD},
118         {"decimal", DECIMAL_P, COL_NAME_KEYWORD},
119         {"declare", DECLARE, UNRESERVED_KEYWORD},
120         {"default", DEFAULT, RESERVED_KEYWORD},
121         {"defaults", DEFAULTS, UNRESERVED_KEYWORD},
122         {"deferrable", DEFERRABLE, RESERVED_KEYWORD},
123         {"deferred", DEFERRED, UNRESERVED_KEYWORD},
124         {"definer", DEFINER, UNRESERVED_KEYWORD},
125         {"delete", DELETE_P, UNRESERVED_KEYWORD},
126         {"delimiter", DELIMITER, UNRESERVED_KEYWORD},
127         {"delimiters", DELIMITERS, UNRESERVED_KEYWORD},
128         {"desc", DESC, RESERVED_KEYWORD},
129         {"dictionary", DICTIONARY, UNRESERVED_KEYWORD},
130         {"disable", DISABLE_P, UNRESERVED_KEYWORD},
131         {"discard", DISCARD, UNRESERVED_KEYWORD},
132         {"distinct", DISTINCT, RESERVED_KEYWORD},
133         {"do", DO, RESERVED_KEYWORD},
134         {"document", DOCUMENT_P, UNRESERVED_KEYWORD},
135         {"domain", DOMAIN_P, UNRESERVED_KEYWORD},
136         {"double", DOUBLE_P, UNRESERVED_KEYWORD},
137         {"drop", DROP, UNRESERVED_KEYWORD},
138         {"each", EACH, UNRESERVED_KEYWORD},
139         {"else", ELSE, RESERVED_KEYWORD},
140         {"enable", ENABLE_P, UNRESERVED_KEYWORD},
141         {"encoding", ENCODING, UNRESERVED_KEYWORD},
142         {"encrypted", ENCRYPTED, UNRESERVED_KEYWORD},
143         {"end", END_P, RESERVED_KEYWORD},
144         {"enum", ENUM_P, UNRESERVED_KEYWORD},
145         {"escape", ESCAPE, UNRESERVED_KEYWORD},
146         {"except", EXCEPT, RESERVED_KEYWORD},
147         {"excluding", EXCLUDING, UNRESERVED_KEYWORD},
148         {"exclusive", EXCLUSIVE, UNRESERVED_KEYWORD},
149         {"execute", EXECUTE, UNRESERVED_KEYWORD},
150         {"exists", EXISTS, COL_NAME_KEYWORD},
151         {"explain", EXPLAIN, UNRESERVED_KEYWORD},
152         {"external", EXTERNAL, UNRESERVED_KEYWORD},
153         {"extract", EXTRACT, COL_NAME_KEYWORD},
154         {"false", FALSE_P, RESERVED_KEYWORD},
155         {"family", FAMILY, UNRESERVED_KEYWORD},
156         {"fetch", FETCH, UNRESERVED_KEYWORD},
157         {"first", FIRST_P, UNRESERVED_KEYWORD},
158         {"float", FLOAT_P, COL_NAME_KEYWORD},
159         {"for", FOR, RESERVED_KEYWORD},
160         {"force", FORCE, UNRESERVED_KEYWORD},
161         {"foreign", FOREIGN, RESERVED_KEYWORD},
162         {"forward", FORWARD, UNRESERVED_KEYWORD},
163         {"freeze", FREEZE, TYPE_FUNC_NAME_KEYWORD},
164         {"from", FROM, RESERVED_KEYWORD},
165         {"full", FULL, TYPE_FUNC_NAME_KEYWORD},
166         {"function", FUNCTION, UNRESERVED_KEYWORD},
167         {"global", GLOBAL, UNRESERVED_KEYWORD},
168         {"grant", GRANT, RESERVED_KEYWORD},
169         {"granted", GRANTED, UNRESERVED_KEYWORD},
170         {"greatest", GREATEST, COL_NAME_KEYWORD},
171         {"group", GROUP_P, RESERVED_KEYWORD},
172         {"handler", HANDLER, UNRESERVED_KEYWORD},
173         {"having", HAVING, RESERVED_KEYWORD},
174         {"header", HEADER_P, UNRESERVED_KEYWORD},
175         {"hold", HOLD, UNRESERVED_KEYWORD},
176         {"hour", HOUR_P, UNRESERVED_KEYWORD},
177         {"if", IF_P, UNRESERVED_KEYWORD},
178         {"ilike", ILIKE, TYPE_FUNC_NAME_KEYWORD},
179         {"immediate", IMMEDIATE, UNRESERVED_KEYWORD},
180         {"immutable", IMMUTABLE, UNRESERVED_KEYWORD},
181         {"implicit", IMPLICIT_P, UNRESERVED_KEYWORD},
182         {"in", IN_P, RESERVED_KEYWORD},
183         {"including", INCLUDING, UNRESERVED_KEYWORD},
184         {"increment", INCREMENT, UNRESERVED_KEYWORD},
185         {"index", INDEX, UNRESERVED_KEYWORD},
186         {"indexes", INDEXES, UNRESERVED_KEYWORD},
187         {"inherit", INHERIT, UNRESERVED_KEYWORD},
188         {"inherits", INHERITS, UNRESERVED_KEYWORD},
189         {"initially", INITIALLY, RESERVED_KEYWORD},
190         {"inner", INNER_P, TYPE_FUNC_NAME_KEYWORD},
191         {"inout", INOUT, COL_NAME_KEYWORD},
192         {"input", INPUT_P, UNRESERVED_KEYWORD},
193         {"insensitive", INSENSITIVE, UNRESERVED_KEYWORD},
194         {"insert", INSERT, UNRESERVED_KEYWORD},
195         {"instead", INSTEAD, UNRESERVED_KEYWORD},
196         {"int", INT_P, COL_NAME_KEYWORD},
197         {"integer", INTEGER, COL_NAME_KEYWORD},
198         {"intersect", INTERSECT, RESERVED_KEYWORD},
199         {"interval", INTERVAL, COL_NAME_KEYWORD},
200         {"into", INTO, RESERVED_KEYWORD},
201         {"invoker", INVOKER, UNRESERVED_KEYWORD},
202         {"is", IS, TYPE_FUNC_NAME_KEYWORD},
203         {"isnull", ISNULL, TYPE_FUNC_NAME_KEYWORD},
204         {"isolation", ISOLATION, UNRESERVED_KEYWORD},
205         {"join", JOIN, TYPE_FUNC_NAME_KEYWORD},
206         {"key", KEY, UNRESERVED_KEYWORD},
207         {"lancompiler", LANCOMPILER, UNRESERVED_KEYWORD},
208         {"language", LANGUAGE, UNRESERVED_KEYWORD},
209         {"large", LARGE_P, UNRESERVED_KEYWORD},
210         {"last", LAST_P, UNRESERVED_KEYWORD},
211         {"leading", LEADING, RESERVED_KEYWORD},
212         {"least", LEAST, COL_NAME_KEYWORD},
213         {"left", LEFT, TYPE_FUNC_NAME_KEYWORD},
214         {"level", LEVEL, UNRESERVED_KEYWORD},
215         {"like", LIKE, TYPE_FUNC_NAME_KEYWORD},
216         {"limit", LIMIT, RESERVED_KEYWORD},
217         {"listen", LISTEN, UNRESERVED_KEYWORD},
218         {"load", LOAD, UNRESERVED_KEYWORD},
219         {"local", LOCAL, UNRESERVED_KEYWORD},
220         {"localtime", LOCALTIME, RESERVED_KEYWORD},
221         {"localtimestamp", LOCALTIMESTAMP, RESERVED_KEYWORD},
222         {"location", LOCATION, UNRESERVED_KEYWORD},
223         {"lock", LOCK_P, UNRESERVED_KEYWORD},
224         {"login", LOGIN_P, UNRESERVED_KEYWORD},
225         {"mapping", MAPPING, UNRESERVED_KEYWORD},
226         {"match", MATCH, UNRESERVED_KEYWORD},
227         {"maxvalue", MAXVALUE, UNRESERVED_KEYWORD},
228         {"minute", MINUTE_P, UNRESERVED_KEYWORD},
229         {"minvalue", MINVALUE, UNRESERVED_KEYWORD},
230         {"mode", MODE, UNRESERVED_KEYWORD},
231         {"month", MONTH_P, UNRESERVED_KEYWORD},
232         {"move", MOVE, UNRESERVED_KEYWORD},
233         {"name", NAME_P, UNRESERVED_KEYWORD},
234         {"names", NAMES, UNRESERVED_KEYWORD},
235         {"national", NATIONAL, COL_NAME_KEYWORD},
236         {"natural", NATURAL, TYPE_FUNC_NAME_KEYWORD},
237         {"nchar", NCHAR, COL_NAME_KEYWORD},
238         {"new", NEW, RESERVED_KEYWORD},
239         {"next", NEXT, UNRESERVED_KEYWORD},
240         {"no", NO, UNRESERVED_KEYWORD},
241         {"nocreatedb", NOCREATEDB, UNRESERVED_KEYWORD},
242         {"nocreaterole", NOCREATEROLE, UNRESERVED_KEYWORD},
243         {"nocreateuser", NOCREATEUSER, UNRESERVED_KEYWORD},
244         {"noinherit", NOINHERIT, UNRESERVED_KEYWORD},
245         {"nologin", NOLOGIN_P, UNRESERVED_KEYWORD},
246         {"none", NONE, COL_NAME_KEYWORD},
247         {"nosuperuser", NOSUPERUSER, UNRESERVED_KEYWORD},
248         {"not", NOT, RESERVED_KEYWORD},
249         {"nothing", NOTHING, UNRESERVED_KEYWORD},
250         {"notify", NOTIFY, UNRESERVED_KEYWORD},
251         {"notnull", NOTNULL, TYPE_FUNC_NAME_KEYWORD},
252         {"nowait", NOWAIT, UNRESERVED_KEYWORD},
253         {"null", NULL_P, RESERVED_KEYWORD},
254         {"nullif", NULLIF, COL_NAME_KEYWORD},
255         {"nulls", NULLS_P, UNRESERVED_KEYWORD},
256         {"numeric", NUMERIC, COL_NAME_KEYWORD},
257         {"object", OBJECT_P, UNRESERVED_KEYWORD},
258         {"of", OF, UNRESERVED_KEYWORD},
259         {"off", OFF, RESERVED_KEYWORD},
260         {"offset", OFFSET, RESERVED_KEYWORD},
261         {"oids", OIDS, UNRESERVED_KEYWORD},
262         {"old", OLD, RESERVED_KEYWORD},
263         {"on", ON, RESERVED_KEYWORD},
264         {"only", ONLY, RESERVED_KEYWORD},
265         {"operator", OPERATOR, UNRESERVED_KEYWORD},
266         {"option", OPTION, UNRESERVED_KEYWORD},
267         {"or", OR, RESERVED_KEYWORD},
268         {"order", ORDER, RESERVED_KEYWORD},
269         {"out", OUT_P, COL_NAME_KEYWORD},
270         {"outer", OUTER_P, TYPE_FUNC_NAME_KEYWORD},
271         {"overlaps", OVERLAPS, TYPE_FUNC_NAME_KEYWORD},
272         {"overlay", OVERLAY, COL_NAME_KEYWORD},
273         {"owned", OWNED, UNRESERVED_KEYWORD},
274         {"owner", OWNER, UNRESERVED_KEYWORD},
275         {"parser", PARSER, UNRESERVED_KEYWORD},
276         {"partial", PARTIAL, UNRESERVED_KEYWORD},
277         {"password", PASSWORD, UNRESERVED_KEYWORD},
278         {"placing", PLACING, RESERVED_KEYWORD},
279         {"plans", PLANS, UNRESERVED_KEYWORD},
280         {"position", POSITION, COL_NAME_KEYWORD},
281         {"precision", PRECISION, COL_NAME_KEYWORD},
282         {"prepare", PREPARE, UNRESERVED_KEYWORD},
283         {"prepared", PREPARED, UNRESERVED_KEYWORD},
284         {"preserve", PRESERVE, UNRESERVED_KEYWORD},
285         {"primary", PRIMARY, RESERVED_KEYWORD},
286         {"prior", PRIOR, UNRESERVED_KEYWORD},
287         {"privileges", PRIVILEGES, UNRESERVED_KEYWORD},
288         {"procedural", PROCEDURAL, UNRESERVED_KEYWORD},
289         {"procedure", PROCEDURE, UNRESERVED_KEYWORD},
290         {"quote", QUOTE, UNRESERVED_KEYWORD},
291         {"read", READ, UNRESERVED_KEYWORD},
292         {"real", REAL, COL_NAME_KEYWORD},
293         {"reassign", REASSIGN, UNRESERVED_KEYWORD},
294         {"recheck", RECHECK, UNRESERVED_KEYWORD},
295         {"references", REFERENCES, RESERVED_KEYWORD},
296         {"reindex", REINDEX, UNRESERVED_KEYWORD},
297         {"relative", RELATIVE_P, UNRESERVED_KEYWORD},
298         {"release", RELEASE, UNRESERVED_KEYWORD},
299         {"rename", RENAME, UNRESERVED_KEYWORD},
300         {"repeatable", REPEATABLE, UNRESERVED_KEYWORD},
301         {"replace", REPLACE, UNRESERVED_KEYWORD},
302         {"replica", REPLICA, UNRESERVED_KEYWORD},
303         {"reset", RESET, UNRESERVED_KEYWORD},
304         {"restart", RESTART, UNRESERVED_KEYWORD},
305         {"restrict", RESTRICT, UNRESERVED_KEYWORD},
306         {"returning", RETURNING, RESERVED_KEYWORD},
307         {"returns", RETURNS, UNRESERVED_KEYWORD},
308         {"revoke", REVOKE, UNRESERVED_KEYWORD},
309         {"right", RIGHT, TYPE_FUNC_NAME_KEYWORD},
310         {"role", ROLE, UNRESERVED_KEYWORD},
311         {"rollback", ROLLBACK, UNRESERVED_KEYWORD},
312         {"row", ROW, COL_NAME_KEYWORD},
313         {"rows", ROWS, UNRESERVED_KEYWORD},
314         {"rule", RULE, UNRESERVED_KEYWORD},
315         {"savepoint", SAVEPOINT, UNRESERVED_KEYWORD},
316         {"schema", SCHEMA, UNRESERVED_KEYWORD},
317         {"scroll", SCROLL, UNRESERVED_KEYWORD},
318         {"search", SEARCH, UNRESERVED_KEYWORD},
319         {"second", SECOND_P, UNRESERVED_KEYWORD},
320         {"security", SECURITY, UNRESERVED_KEYWORD},
321         {"select", SELECT, RESERVED_KEYWORD},
322         {"sequence", SEQUENCE, UNRESERVED_KEYWORD},
323         {"serializable", SERIALIZABLE, UNRESERVED_KEYWORD},
324         {"session", SESSION, UNRESERVED_KEYWORD},
325         {"session_user", SESSION_USER, RESERVED_KEYWORD},
326         {"set", SET, UNRESERVED_KEYWORD},
327         {"setof", SETOF, COL_NAME_KEYWORD},
328         {"share", SHARE, UNRESERVED_KEYWORD},
329         {"show", SHOW, UNRESERVED_KEYWORD},
330         {"similar", SIMILAR, TYPE_FUNC_NAME_KEYWORD},
331         {"simple", SIMPLE, UNRESERVED_KEYWORD},
332         {"smallint", SMALLINT, COL_NAME_KEYWORD},
333         {"some", SOME, RESERVED_KEYWORD},
334         {"stable", STABLE, UNRESERVED_KEYWORD},
335         {"standalone", STANDALONE_P, UNRESERVED_KEYWORD},
336         {"start", START, UNRESERVED_KEYWORD},
337         {"statement", STATEMENT, UNRESERVED_KEYWORD},
338         {"statistics", STATISTICS, UNRESERVED_KEYWORD},
339         {"stdin", STDIN, UNRESERVED_KEYWORD},
340         {"stdout", STDOUT, UNRESERVED_KEYWORD},
341         {"storage", STORAGE, UNRESERVED_KEYWORD},
342         {"strict", STRICT_P, UNRESERVED_KEYWORD},
343         {"strip", STRIP_P, UNRESERVED_KEYWORD},
344         {"substring", SUBSTRING, COL_NAME_KEYWORD},
345         {"superuser", SUPERUSER_P, UNRESERVED_KEYWORD},
346         {"symmetric", SYMMETRIC, RESERVED_KEYWORD},
347         {"sysid", SYSID, UNRESERVED_KEYWORD},
348         {"system", SYSTEM_P, UNRESERVED_KEYWORD},
349         {"table", TABLE, RESERVED_KEYWORD},
350         {"tablespace", TABLESPACE, UNRESERVED_KEYWORD},
351         {"temp", TEMP, UNRESERVED_KEYWORD},
352         {"template", TEMPLATE, UNRESERVED_KEYWORD},
353         {"temporary", TEMPORARY, UNRESERVED_KEYWORD},
354         {"text", TEXT_P, UNRESERVED_KEYWORD},
355         {"then", THEN, RESERVED_KEYWORD},
356         {"time", TIME, COL_NAME_KEYWORD},
357         {"timestamp", TIMESTAMP, COL_NAME_KEYWORD},
358         {"to", TO, RESERVED_KEYWORD},
359         {"trailing", TRAILING, RESERVED_KEYWORD},
360         {"transaction", TRANSACTION, UNRESERVED_KEYWORD},
361         {"treat", TREAT, COL_NAME_KEYWORD},
362         {"trigger", TRIGGER, UNRESERVED_KEYWORD},
363         {"trim", TRIM, COL_NAME_KEYWORD},
364         {"true", TRUE_P, RESERVED_KEYWORD},
365         {"truncate", TRUNCATE, UNRESERVED_KEYWORD},
366         {"trusted", TRUSTED, UNRESERVED_KEYWORD},
367         {"type", TYPE_P, UNRESERVED_KEYWORD},
368         {"uncommitted", UNCOMMITTED, UNRESERVED_KEYWORD},
369         {"unencrypted", UNENCRYPTED, UNRESERVED_KEYWORD},
370         {"union", UNION, RESERVED_KEYWORD},
371         {"unique", UNIQUE, RESERVED_KEYWORD},
372         {"unknown", UNKNOWN, UNRESERVED_KEYWORD},
373         {"unlisten", UNLISTEN, UNRESERVED_KEYWORD},
374         {"until", UNTIL, UNRESERVED_KEYWORD},
375         {"update", UPDATE, UNRESERVED_KEYWORD},
376         {"user", USER, RESERVED_KEYWORD},
377         {"using", USING, RESERVED_KEYWORD},
378         {"vacuum", VACUUM, UNRESERVED_KEYWORD},
379         {"valid", VALID, UNRESERVED_KEYWORD},
380         {"validator", VALIDATOR, UNRESERVED_KEYWORD},
381         {"value", VALUE_P, UNRESERVED_KEYWORD},
382         {"values", VALUES, COL_NAME_KEYWORD},
383         {"varchar", VARCHAR, COL_NAME_KEYWORD},
384         {"varying", VARYING, UNRESERVED_KEYWORD},
385         {"verbose", VERBOSE, TYPE_FUNC_NAME_KEYWORD},
386         {"version", VERSION_P, UNRESERVED_KEYWORD},
387         {"view", VIEW, UNRESERVED_KEYWORD},
388         {"volatile", VOLATILE, UNRESERVED_KEYWORD},
389         {"when", WHEN, RESERVED_KEYWORD},
390         {"where", WHERE, RESERVED_KEYWORD},
391         {"whitespace", WHITESPACE_P, UNRESERVED_KEYWORD},
392         /*
393          * XXX we mark WITH as reserved to force it to be quoted in dumps, even
394          * though it is currently unreserved according to gram.y.  This is because
395          * we expect we'll have to make it reserved to implement SQL WITH clauses.
396          * If that patch manages to do without reserving WITH, adjust this entry
397          * at that time; in any case this should be back in sync with gram.y
398          * after WITH clauses are implemented.
399          */
400         {"with", WITH, RESERVED_KEYWORD},
401         {"without", WITHOUT, UNRESERVED_KEYWORD},
402         {"work", WORK, UNRESERVED_KEYWORD},
403         {"write", WRITE, UNRESERVED_KEYWORD},
404         {"xml", XML_P, UNRESERVED_KEYWORD},
405         {"xmlattributes", XMLATTRIBUTES, COL_NAME_KEYWORD},
406         {"xmlconcat", XMLCONCAT, COL_NAME_KEYWORD},
407         {"xmlelement", XMLELEMENT, COL_NAME_KEYWORD},
408         {"xmlforest", XMLFOREST, COL_NAME_KEYWORD},
409         {"xmlparse", XMLPARSE, COL_NAME_KEYWORD},
410         {"xmlpi", XMLPI, COL_NAME_KEYWORD},
411         {"xmlroot", XMLROOT, COL_NAME_KEYWORD},
412         {"xmlserialize", XMLSERIALIZE, COL_NAME_KEYWORD},
413         {"year", YEAR_P, UNRESERVED_KEYWORD},
414         {"yes", YES_P, UNRESERVED_KEYWORD},
415         {"zone", ZONE, UNRESERVED_KEYWORD},
416 };
417
418 /*
419  * ScanKeywordLookup - see if a given word is a keyword
420  *
421  * Returns a pointer to the ScanKeyword table entry, or NULL if no match.
422  *
423  * The match is done case-insensitively.  Note that we deliberately use a
424  * dumbed-down case conversion that will only translate 'A'-'Z' into 'a'-'z',
425  * even if we are in a locale where tolower() would produce more or different
426  * translations.  This is to conform to the SQL99 spec, which says that
427  * keywords are to be matched in this way even though non-keyword identifiers
428  * receive a different case-normalization mapping.
429  */
430 const ScanKeyword *
431 ScanKeywordLookup(const char *text)
432 {
433         int                     len,
434                                 i;
435         char            word[NAMEDATALEN];
436         const ScanKeyword *low;
437         const ScanKeyword *high;
438
439         len = strlen(text);
440         /* We assume all keywords are shorter than NAMEDATALEN. */
441         if (len >= NAMEDATALEN)
442                 return NULL;
443
444         /*
445          * Apply an ASCII-only downcasing.      We must not use tolower() since it may
446          * produce the wrong translation in some locales (eg, Turkish).
447          */
448         for (i = 0; i < len; i++)
449         {
450                 char            ch = text[i];
451
452                 if (ch >= 'A' && ch <= 'Z')
453                         ch += 'a' - 'A';
454                 word[i] = ch;
455         }
456         word[len] = '\0';
457
458         /*
459          * Now do a binary search using plain strcmp() comparison.
460          */
461         low = &ScanKeywords[0];
462         high = endof(ScanKeywords) - 1;
463         while (low <= high)
464         {
465                 const ScanKeyword *middle;
466                 int                     difference;
467
468                 middle = low + (high - low) / 2;
469                 difference = strcmp(middle->name, word);
470                 if (difference == 0)
471                         return middle;
472                 else if (difference < 0)
473                         low = middle + 1;
474                 else
475                         high = middle - 1;
476         }
477
478         return NULL;
479 }