summaryrefslogtreecommitdiff
path: root/src/backend/parser
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/parser')
-rw-r--r--src/backend/parser/gram.y31
-rw-r--r--src/backend/parser/keywords.c6
-rw-r--r--src/backend/parser/kwlookup.c13
-rw-r--r--src/backend/parser/parser.c6
-rw-r--r--src/backend/parser/scan.l48
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.
*/