diff --git a/doc/src/sgml/bki.sgml b/doc/src/sgml/bki.sgml index 5b557ffb7b..e3ba73a9a8 100644 --- a/doc/src/sgml/bki.sgml +++ b/doc/src/sgml/bki.sgml @@ -248,6 +248,8 @@ Null values are represented by _null_. + (Note that there is no way to create a value that is just that + string.) @@ -752,13 +754,13 @@ $ perl rewrite_dat_with_prokind.pl pg_proc.dat - close tablename + close tablename - Close the open table. The name of the table can be given as a - cross-check, but this is not required. + Close the open table. The name of the table must be given as a + cross-check. @@ -782,8 +784,8 @@ $ perl rewrite_dat_with_prokind.pl pg_proc.dat NULL values can be specified using the special key word - _null_. Values containing spaces must be - double quoted. + _null_. Values that do not look like + identifiers or digit strings must be double quoted. diff --git a/src/backend/bootstrap/bootparse.y b/src/backend/bootstrap/bootparse.y index 1ec0e5c8a9..4c72989cc2 100644 --- a/src/backend/bootstrap/bootparse.y +++ b/src/backend/bootstrap/bootparse.y @@ -105,6 +105,7 @@ static int num_columns_read = 0; List *list; IndexElem *ielem; char *str; + const char *kw; int ival; Oid oidval; } @@ -116,17 +117,17 @@ static int num_columns_read = 0; %type oidspec optoideq optrowtypeoid %token ID -%token OPEN XCLOSE XCREATE INSERT_TUPLE -%token XDECLARE INDEX ON USING XBUILD INDICES UNIQUE XTOAST %token COMMA EQUALS LPAREN RPAREN -%token OBJ_ID XBOOTSTRAP XSHARED_RELATION XWITHOUT_OIDS XROWTYPE_OID NULLVAL -%token XFORCE XNOT XNULL +/* NULLVAL is a reserved keyword */ +%token NULLVAL +/* All the rest are unreserved, and should be handled in boot_ident! */ +%token OPEN XCLOSE XCREATE INSERT_TUPLE +%token XDECLARE INDEX ON USING XBUILD INDICES UNIQUE XTOAST +%token OBJ_ID XBOOTSTRAP XSHARED_RELATION XWITHOUT_OIDS XROWTYPE_OID +%token XFORCE XNOT XNULL %start TopLevel -%nonassoc low -%nonassoc high - %% TopLevel: @@ -160,18 +161,12 @@ Boot_OpenStmt: ; Boot_CloseStmt: - XCLOSE boot_ident %prec low + XCLOSE boot_ident { do_start(); closerel($2); do_end(); } - | XCLOSE %prec high - { - do_start(); - closerel(NULL); - do_end(); - } ; Boot_CreateStmt: @@ -489,8 +484,28 @@ boot_column_val: { InsertOneNull(num_columns_read++); } ; -boot_ident : - ID { $$ = yylval.str; } +boot_ident: + ID { $$ = $1; } + | OPEN { $$ = pstrdup($1); } + | XCLOSE { $$ = pstrdup($1); } + | XCREATE { $$ = pstrdup($1); } + | INSERT_TUPLE { $$ = pstrdup($1); } + | XDECLARE { $$ = pstrdup($1); } + | INDEX { $$ = pstrdup($1); } + | ON { $$ = pstrdup($1); } + | USING { $$ = pstrdup($1); } + | XBUILD { $$ = pstrdup($1); } + | INDICES { $$ = pstrdup($1); } + | UNIQUE { $$ = pstrdup($1); } + | XTOAST { $$ = pstrdup($1); } + | OBJ_ID { $$ = pstrdup($1); } + | XBOOTSTRAP { $$ = pstrdup($1); } + | XSHARED_RELATION { $$ = pstrdup($1); } + | XWITHOUT_OIDS { $$ = pstrdup($1); } + | XROWTYPE_OID { $$ = pstrdup($1); } + | XFORCE { $$ = pstrdup($1); } + | XNOT { $$ = pstrdup($1); } + | XNULL { $$ = pstrdup($1); } ; %% diff --git a/src/backend/bootstrap/bootscanner.l b/src/backend/bootstrap/bootscanner.l index 1799757da2..739087b786 100644 --- a/src/backend/bootstrap/bootscanner.l +++ b/src/backend/bootstrap/bootscanner.l @@ -68,55 +68,67 @@ static int yyline = 1; /* line number for error reporting */ id [-A-Za-z0-9_]+ sid \"([^\"])*\" +/* + * Keyword tokens return the keyword text (as a constant string) in yylval.kw, + * just in case that's needed because we want to treat the keyword as an + * unreserved identifier. Note that _null_ is not treated as a keyword + * for this purpose; it's the one "reserved word" in the bootstrap syntax. + * + * Notice that all the keywords are case-sensitive, and for historical + * reasons some must be upper case. + * + * String tokens return a palloc'd string in yylval.str. + */ + %% -open { return OPEN; } +open { yylval.kw = "open"; return OPEN; } -close { return XCLOSE; } +close { yylval.kw = "close"; return XCLOSE; } -create { return XCREATE; } +create { yylval.kw = "create"; return XCREATE; } + +OID { yylval.kw = "OID"; return OBJ_ID; } +bootstrap { yylval.kw = "bootstrap"; return XBOOTSTRAP; } +shared_relation { yylval.kw = "shared_relation"; return XSHARED_RELATION; } +without_oids { yylval.kw = "without_oids"; return XWITHOUT_OIDS; } +rowtype_oid { yylval.kw = "rowtype_oid"; return XROWTYPE_OID; } + +insert { yylval.kw = "insert"; return INSERT_TUPLE; } -OID { return OBJ_ID; } -bootstrap { return XBOOTSTRAP; } -"shared_relation" { return XSHARED_RELATION; } -"without_oids" { return XWITHOUT_OIDS; } -"rowtype_oid" { return XROWTYPE_OID; } _null_ { return NULLVAL; } -insert { return INSERT_TUPLE; } - "," { return COMMA; } "=" { return EQUALS; } "(" { return LPAREN; } ")" { return RPAREN; } [\n] { yyline++; } -[\t] ; -" " ; +[\r\t ] ; -^\#[^\n]* ; /* drop everything after "#" for comments */ +^\#[^\n]* ; /* drop everything after "#" for comments */ - -"declare" { return XDECLARE; } -"build" { return XBUILD; } -"indices" { return INDICES; } -"unique" { return UNIQUE; } -"index" { return INDEX; } -"on" { return ON; } -"using" { return USING; } -"toast" { return XTOAST; } -"FORCE" { return XFORCE; } -"NOT" { return XNOT; } -"NULL" { return XNULL; } +declare { yylval.kw = "declare"; return XDECLARE; } +build { yylval.kw = "build"; return XBUILD; } +indices { yylval.kw = "indices"; return INDICES; } +unique { yylval.kw = "unique"; return UNIQUE; } +index { yylval.kw = "index"; return INDEX; } +on { yylval.kw = "on"; return ON; } +using { yylval.kw = "using"; return USING; } +toast { yylval.kw = "toast"; return XTOAST; } +FORCE { yylval.kw = "FORCE"; return XFORCE; } +NOT { yylval.kw = "NOT"; return XNOT; } +NULL { yylval.kw = "NULL"; return XNULL; } {id} { yylval.str = scanstr(yytext); return ID; } {sid} { - yytext[strlen(yytext)-1] = '\0'; /* strip off quotes */ + /* leading and trailing quotes are not passed to scanstr */ + yytext[strlen(yytext) - 1] = '\0'; yylval.str = scanstr(yytext+1); - yytext[strlen(yytext)] = '"'; /* restore quotes */ + yytext[strlen(yytext)] = '"'; /* restore yytext */ return ID; } @@ -124,8 +136,6 @@ insert { return INSERT_TUPLE; } elog(ERROR, "syntax error at line %d: unexpected character \"%s\"", yyline, yytext); } - - %% /* LCOV_EXCL_STOP */