@@ -264,10 +264,10 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
264264
265265%type <dbehavior> opt_drop_behavior
266266
267- %type <list> createdb_opt_list alterdb_opt_list copy_opt_list
267+ %type <list> createdb_opt_list createdb_opt_items copy_opt_list
268268 transaction_mode_list
269269 create_extension_opt_list alter_extension_opt_list
270- %type <defelt> createdb_opt_item alterdb_opt_item copy_opt_item
270+ %type <defelt> createdb_opt_item copy_opt_item
271271 transaction_mode_item
272272 create_extension_opt_item alter_extension_opt_item
273273
@@ -462,6 +462,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
462462%type <list> var_list
463463%type <str> ColId ColLabel var_name type_function_name param_name
464464%type <str> NonReservedWord NonReservedWord_or_Sconst
465+ %type <str> createdb_opt_name
465466%type <node> var_value zone_value
466467
467468%type <keyword> unreserved_keyword type_func_name_keyword
@@ -564,7 +565,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
564565
565566 KEY
566567
567- LABEL LANGUAGE LARGE_P LAST_P LATERAL_P LC_COLLATE_P LC_CTYPE_P
568+ LABEL LANGUAGE LARGE_P LAST_P LATERAL_P
568569 LEADING LEAKPROOF LEAST LEFT LEVEL LIKE LIMIT LISTEN LOAD LOCAL
569570 LOCALTIME LOCALTIMESTAMP LOCATION LOCK_P
570571
@@ -8320,77 +8321,51 @@ CreatedbStmt:
83208321 ;
83218322
83228323createdb_opt_list :
8323- createdb_opt_list createdb_opt_item { $$ = lappend( $1 , $2 ) ; }
8324+ createdb_opt_items { $$ = $1 ; }
83248325 | /* EMPTY */ { $$ = NIL; }
83258326 ;
83268327
8328+ createdb_opt_items :
8329+ createdb_opt_item { $$ = list_make1($1 ); }
8330+ | createdb_opt_items createdb_opt_item { $$ = lappend($1 , $2 ); }
8331+ ;
8332+
83278333createdb_opt_item :
8328- TABLESPACE opt_equal name
8329- {
8330- $$ = makeDefElem(" tablespace" , (Node *)makeString($3 ));
8331- }
8332- | TABLESPACE opt_equal DEFAULT
8333- {
8334- $$ = makeDefElem(" tablespace" , NULL );
8335- }
8336- | LOCATION opt_equal Sconst
8337- {
8338- $$ = makeDefElem(" location" , (Node *)makeString($3 ));
8339- }
8340- | LOCATION opt_equal DEFAULT
8341- {
8342- $$ = makeDefElem(" location" , NULL );
8343- }
8344- | TEMPLATE opt_equal name
8345- {
8346- $$ = makeDefElem(" template" , (Node *)makeString($3 ));
8347- }
8348- | TEMPLATE opt_equal DEFAULT
8349- {
8350- $$ = makeDefElem(" template" , NULL );
8351- }
8352- | ENCODING opt_equal Sconst
8353- {
8354- $$ = makeDefElem(" encoding" , (Node *)makeString($3 ));
8355- }
8356- | ENCODING opt_equal Iconst
8357- {
8358- $$ = makeDefElem(" encoding" , (Node *)makeInteger($3 ));
8359- }
8360- | ENCODING opt_equal DEFAULT
8361- {
8362- $$ = makeDefElem(" encoding" , NULL );
8363- }
8364- | LC_COLLATE_P opt_equal Sconst
8365- {
8366- $$ = makeDefElem(" lc_collate" , (Node *)makeString($3 ));
8367- }
8368- | LC_COLLATE_P opt_equal DEFAULT
8369- {
8370- $$ = makeDefElem(" lc_collate" , NULL );
8371- }
8372- | LC_CTYPE_P opt_equal Sconst
8334+ createdb_opt_name opt_equal SignedIconst
83738335 {
8374- $$ = makeDefElem(" lc_ctype " , (Node *)makeString ($3 ));
8336+ $$ = makeDefElem($1 , (Node *)makeInteger ($3 ));
83758337 }
8376- | LC_CTYPE_P opt_equal DEFAULT
8338+ | createdb_opt_name opt_equal opt_boolean_or_string
83778339 {
8378- $$ = makeDefElem(" lc_ctype " , NULL );
8340+ $$ = makeDefElem($1 , (Node *)makeString( $3 ) );
83798341 }
8380- | CONNECTION LIMIT opt_equal SignedIconst
8342+ | createdb_opt_name opt_equal DEFAULT
83818343 {
8382- $$ = makeDefElem(" connectionlimit" , (Node *)makeInteger($4 ));
8383- }
8384- | OWNER opt_equal name
8385- {
8386- $$ = makeDefElem(" owner" , (Node *)makeString($3 ));
8387- }
8388- | OWNER opt_equal DEFAULT
8389- {
8390- $$ = makeDefElem(" owner" , NULL );
8344+ $$ = makeDefElem($1 , NULL );
83918345 }
83928346 ;
83938347
8348+ /*
8349+ * Ideally we'd use ColId here, but that causes shift/reduce conflicts against
8350+ * the ALTER DATABASE SET/RESET syntaxes. Instead call out specific keywords
8351+ * we need, and allow IDENT so that database option names don't have to be
8352+ * parser keywords unless they are already keywords for other reasons.
8353+ *
8354+ * XXX this coding technique is fragile since if someone makes a formerly
8355+ * non-keyword option name into a keyword and forgets to add it here, the
8356+ * option will silently break. Best defense is to provide a regression test
8357+ * exercising every such option, at least at the syntax level.
8358+ */
8359+ createdb_opt_name :
8360+ IDENT { $$ = $1 ; }
8361+ | CONNECTION LIMIT { $$ = pstrdup(" connection_limit" ); }
8362+ | ENCODING { $$ = pstrdup($1 ); }
8363+ | LOCATION { $$ = pstrdup($1 ); }
8364+ | OWNER { $$ = pstrdup($1 ); }
8365+ | TABLESPACE { $$ = pstrdup($1 ); }
8366+ | TEMPLATE { $$ = pstrdup($1 ); }
8367+ ;
8368+
83948369/*
83958370 * Though the equals sign doesn't match other WITH options, pg_dump uses
83968371 * equals for backward compatibility, and it doesn't seem worth removing it.
@@ -8407,13 +8382,20 @@ opt_equal: '=' {}
84078382 *****************************************************************************/
84088383
84098384AlterDatabaseStmt :
8410- ALTER DATABASE database_name opt_with alterdb_opt_list
8385+ ALTER DATABASE database_name WITH createdb_opt_list
84118386 {
84128387 AlterDatabaseStmt *n = makeNode(AlterDatabaseStmt);
84138388 n->dbname = $3 ;
84148389 n->options = $5 ;
84158390 $$ = (Node *)n;
84168391 }
8392+ | ALTER DATABASE database_name createdb_opt_list
8393+ {
8394+ AlterDatabaseStmt *n = makeNode(AlterDatabaseStmt);
8395+ n->dbname = $3 ;
8396+ n->options = $4 ;
8397+ $$ = (Node *)n;
8398+ }
84178399 | ALTER DATABASE database_name SET TABLESPACE name
84188400 {
84198401 AlterDatabaseStmt *n = makeNode(AlterDatabaseStmt);
@@ -8435,19 +8417,6 @@ AlterDatabaseSetStmt:
84358417 ;
84368418
84378419
8438- alterdb_opt_list :
8439- alterdb_opt_list alterdb_opt_item { $$ = lappend($1 , $2 ); }
8440- | /* EMPTY */ { $$ = NIL; }
8441- ;
8442-
8443- alterdb_opt_item :
8444- CONNECTION LIMIT opt_equal SignedIconst
8445- {
8446- $$ = makeDefElem(" connectionlimit" , (Node *)makeInteger($4 ));
8447- }
8448- ;
8449-
8450-
84518420/* ****************************************************************************
84528421 *
84538422 * DROP DATABASE [ IF EXISTS ]
@@ -12958,8 +12927,6 @@ unreserved_keyword:
1295812927 | LANGUAGE
1295912928 | LARGE_P
1296012929 | LAST_P
12961- | LC_COLLATE_P
12962- | LC_CTYPE_P
1296312930 | LEAKPROOF
1296412931 | LEVEL
1296512932 | LISTEN
0 commit comments