diff options
Diffstat (limited to 'src/backend/parser')
| -rw-r--r-- | src/backend/parser/gram.y | 31 | ||||
| -rw-r--r-- | src/backend/parser/keywords.c | 6 | ||||
| -rw-r--r-- | src/backend/parser/kwlookup.c | 13 | ||||
| -rw-r--r-- | src/backend/parser/parser.c | 6 | ||||
| -rw-r--r-- | src/backend/parser/scan.l | 48 |
5 files changed, 72 insertions, 32 deletions
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index f4b795db45..dfe9b19cf1 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -11,7 +11,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.668 2009/07/13 02:02:20 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.669 2009/07/14 20:24:10 tgl Exp $ * * HISTORY * AUTHOR DATE MAJOR EVENT @@ -421,10 +421,23 @@ static TypeName *TableFuncTypeName(List *columns); /* - * If you make any token changes, update the keyword table in - * src/include/parser/kwlist.h and add new keywords to the appropriate one of - * the reserved-or-not-so-reserved keyword lists, below; search - * this file for "Name classification hierarchy". + * Non-keyword token types. These are hard-wired into the "flex" lexer. + * They must be listed first so that their numeric codes do not depend on + * the set of keywords. PL/pgsql depends on this so that it can share the + * same lexer. If you add/change tokens here, fix PL/pgsql to match! + * + * DOT_DOT and COLON_EQUALS are unused in the core SQL grammar, and so will + * always provoke parse errors. They are needed by PL/pgsql. + */ +%token <str> IDENT FCONST SCONST BCONST XCONST Op +%token <ival> ICONST PARAM +%token TYPECAST DOT_DOT COLON_EQUALS + +/* + * If you want to make any keyword changes, update the keyword table in + * src/include/parser/kwlist.h and add new keywords to the appropriate one + * of the reserved-or-not-so-reserved keyword lists, below; search + * this file for "Keyword category lists". */ /* ordinary key words in alphabetical order */ @@ -515,17 +528,15 @@ static TypeName *TableFuncTypeName(List *columns); ZONE -/* The grammar thinks these are keywords, but they are not in the kwlist.h +/* + * The grammar thinks these are keywords, but they are not in the kwlist.h * list and so can never be entered directly. The filter in parser.c * creates these tokens when required. */ %token NULLS_FIRST NULLS_LAST WITH_TIME -/* Special token types, not actually keywords - see the "lex" file */ -%token <str> IDENT FCONST SCONST BCONST XCONST Op -%token <ival> ICONST PARAM -/* precedence: lowest to highest */ +/* Precedence: lowest to highest */ %nonassoc SET /* see relation_expr_opt_alias */ %left UNION EXCEPT %left INTERSECT diff --git a/src/backend/parser/keywords.c b/src/backend/parser/keywords.c index 05e7fb9ee5..4fce452846 100644 --- a/src/backend/parser/keywords.c +++ b/src/backend/parser/keywords.c @@ -9,14 +9,13 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/parser/keywords.c,v 1.213 2009/07/12 17:12:33 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/parser/keywords.c,v 1.214 2009/07/14 20:24:10 tgl Exp $ * *------------------------------------------------------------------------- */ #include "postgres.h" #include "parser/gramparse.h" -#include "parser/keywords.h" #define PG_KEYWORD(a,b,c) {a,b,c}, @@ -25,5 +24,4 @@ const ScanKeyword ScanKeywords[] = { #include "parser/kwlist.h" }; -/* End of ScanKeywords, for use in kwlookup.c and elsewhere */ -const ScanKeyword *LastScanKeyword = endof(ScanKeywords); +const int NumScanKeywords = lengthof(ScanKeywords); diff --git a/src/backend/parser/kwlookup.c b/src/backend/parser/kwlookup.c index 7321a57c15..58c8cdd78f 100644 --- a/src/backend/parser/kwlookup.c +++ b/src/backend/parser/kwlookup.c @@ -6,15 +6,12 @@ * NB - this file is also used by ECPG and several frontend programs in * src/bin/ including pg_dump and psql * - * Note that this file expects that the ScanKeywords array is defined - * and that LastScanKeyword points to its element one past the last. - * * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/parser/kwlookup.c,v 2.2 2009/03/08 16:53:30 alvherre Exp $ + * $PostgreSQL: pgsql/src/backend/parser/kwlookup.c,v 2.3 2009/07/14 20:24:10 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -39,7 +36,9 @@ * receive a different case-normalization mapping. */ const ScanKeyword * -ScanKeywordLookup(const char *text) +ScanKeywordLookup(const char *text, + const ScanKeyword *keywords, + int num_keywords) { int len, i; @@ -69,8 +68,8 @@ ScanKeywordLookup(const char *text) /* * Now do a binary search using plain strcmp() comparison. */ - low = &ScanKeywords[0]; - high = LastScanKeyword - 1; + low = keywords; + high = keywords + (num_keywords - 1); while (low <= high) { const ScanKeyword *middle; diff --git a/src/backend/parser/parser.c b/src/backend/parser/parser.c index cb8ff8a339..93632c8811 100644 --- a/src/backend/parser/parser.c +++ b/src/backend/parser/parser.c @@ -14,7 +14,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/parser/parser.c,v 1.80 2009/07/13 02:02:20 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/parser/parser.c,v 1.81 2009/07/14 20:24:10 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -39,7 +39,7 @@ raw_parser(const char *str) int yyresult; /* initialize the flex scanner */ - yyscanner = scanner_init(str, &yyextra); + yyscanner = scanner_init(str, &yyextra, ScanKeywords, NumScanKeywords); /* filtered_base_yylex() only needs this much initialization */ yyextra.have_lookahead = false; @@ -79,7 +79,7 @@ pg_parse_string_token(const char *token) YYSTYPE yylval; YYLTYPE yylloc; - yyscanner = scanner_init(token, &yyextra); + yyscanner = scanner_init(token, &yyextra, ScanKeywords, NumScanKeywords); ctoken = base_yylex(&yylval, &yylloc, yyscanner); diff --git a/src/backend/parser/scan.l b/src/backend/parser/scan.l index a73934913d..a5ed54792b 100644 --- a/src/backend/parser/scan.l +++ b/src/backend/parser/scan.l @@ -24,7 +24,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/parser/scan.l,v 1.156 2009/07/13 03:11:12 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/parser/scan.l,v 1.157 2009/07/14 20:24:10 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -304,6 +304,10 @@ identifier {ident_start}{ident_cont}* typecast "::" +/* these two token types are used by PL/pgsql, though not in core SQL */ +dot_dot \.\. +colon_equals ":=" + /* * "self" is the set of chars that should be returned as single-character * tokens. "op_chars" is the set of chars that can make up "Op" tokens, @@ -450,11 +454,21 @@ other . SET_YYLLOC(); yyless(1); /* eat only 'n' this time */ - /* nchar had better be a keyword! */ - keyword = ScanKeywordLookup("nchar"); - Assert(keyword != NULL); - yylval->keyword = keyword->name; - return keyword->value; + + keyword = ScanKeywordLookup("nchar", + yyextra->keywords, + yyextra->num_keywords); + if (keyword != NULL) + { + yylval->keyword = keyword->name; + return keyword->value; + } + else + { + /* If NCHAR isn't a keyword, just return "n" */ + yylval->str = pstrdup("n"); + return IDENT; + } } {xqstart} { @@ -680,6 +694,16 @@ other . return TYPECAST; } +{dot_dot} { + SET_YYLLOC(); + return DOT_DOT; + } + +{colon_equals} { + SET_YYLLOC(); + return COLON_EQUALS; + } + {self} { SET_YYLLOC(); return yytext[0]; @@ -830,7 +854,9 @@ other . SET_YYLLOC(); /* Is it a keyword? */ - keyword = ScanKeywordLookup(yytext); + keyword = ScanKeywordLookup(yytext, + yyextra->keywords, + yyextra->num_keywords); if (keyword != NULL) { yylval->keyword = keyword->name; @@ -939,7 +965,10 @@ scanner_yyerror(const char *message, base_yyscan_t yyscanner) * Called before any actual parsing is done */ base_yyscan_t -scanner_init(const char *str, base_yy_extra_type *yyext) +scanner_init(const char *str, + base_yy_extra_type *yyext, + const ScanKeyword *keywords, + int num_keywords) { Size slen = strlen(str); yyscan_t scanner; @@ -949,6 +978,9 @@ scanner_init(const char *str, base_yy_extra_type *yyext) base_yyset_extra(yyext, scanner); + yyext->keywords = keywords; + yyext->num_keywords = num_keywords; + /* * Make a scan buffer with special termination needed by flex. */ |
