1
0
mirror of https://github.com/postgres/postgres.git synced 2025-06-26 12:21:12 +03:00

Refactor CREATE/ALTER DATABASE syntax so options need not be keywords.

Most of the existing option names are keywords anyway, but we can get rid
of LC_COLLATE and LC_CTYPE as keywords known to the lexer/grammar.  This
immediately reduces the size of the grammar tables by about 8KB, and will
save more when we add additional CREATE/ALTER DATABASE options in future.

A side effect of the implementation is that the CONNECTION LIMIT option
can now also be spelled CONNECTION_LIMIT.  We choose not to document this,
however.

Vik Fearing, based on a suggestion by me; reviewed by Pavel Stehule
This commit is contained in:
Tom Lane
2014-07-01 19:02:21 -04:00
parent 2e8ce9ae46
commit 15c82efd69
3 changed files with 76 additions and 103 deletions

View File

@ -264,10 +264,10 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
%type <dbehavior> opt_drop_behavior
%type <list> createdb_opt_list alterdb_opt_list copy_opt_list
%type <list> createdb_opt_list createdb_opt_items copy_opt_list
transaction_mode_list
create_extension_opt_list alter_extension_opt_list
%type <defelt> createdb_opt_item alterdb_opt_item copy_opt_item
%type <defelt> createdb_opt_item copy_opt_item
transaction_mode_item
create_extension_opt_item alter_extension_opt_item
@ -462,6 +462,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
%type <list> var_list
%type <str> ColId ColLabel var_name type_function_name param_name
%type <str> NonReservedWord NonReservedWord_or_Sconst
%type <str> createdb_opt_name
%type <node> var_value zone_value
%type <keyword> unreserved_keyword type_func_name_keyword
@ -564,7 +565,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
KEY
LABEL LANGUAGE LARGE_P LAST_P LATERAL_P LC_COLLATE_P LC_CTYPE_P
LABEL LANGUAGE LARGE_P LAST_P LATERAL_P
LEADING LEAKPROOF LEAST LEFT LEVEL LIKE LIMIT LISTEN LOAD LOCAL
LOCALTIME LOCALTIMESTAMP LOCATION LOCK_P
@ -8320,77 +8321,51 @@ CreatedbStmt:
;
createdb_opt_list:
createdb_opt_list createdb_opt_item { $$ = lappend($1, $2); }
createdb_opt_items { $$ = $1; }
| /* EMPTY */ { $$ = NIL; }
;
createdb_opt_items:
createdb_opt_item { $$ = list_make1($1); }
| createdb_opt_items createdb_opt_item { $$ = lappend($1, $2); }
;
createdb_opt_item:
TABLESPACE opt_equal name
createdb_opt_name opt_equal SignedIconst
{
$$ = makeDefElem("tablespace", (Node *)makeString($3));
$$ = makeDefElem($1, (Node *)makeInteger($3));
}
| TABLESPACE opt_equal DEFAULT
| createdb_opt_name opt_equal opt_boolean_or_string
{
$$ = makeDefElem("tablespace", NULL);
$$ = makeDefElem($1, (Node *)makeString($3));
}
| LOCATION opt_equal Sconst
| createdb_opt_name opt_equal DEFAULT
{
$$ = makeDefElem("location", (Node *)makeString($3));
}
| LOCATION opt_equal DEFAULT
{
$$ = makeDefElem("location", NULL);
}
| TEMPLATE opt_equal name
{
$$ = makeDefElem("template", (Node *)makeString($3));
}
| TEMPLATE opt_equal DEFAULT
{
$$ = makeDefElem("template", NULL);
}
| ENCODING opt_equal Sconst
{
$$ = makeDefElem("encoding", (Node *)makeString($3));
}
| ENCODING opt_equal Iconst
{
$$ = makeDefElem("encoding", (Node *)makeInteger($3));
}
| ENCODING opt_equal DEFAULT
{
$$ = makeDefElem("encoding", NULL);
}
| LC_COLLATE_P opt_equal Sconst
{
$$ = makeDefElem("lc_collate", (Node *)makeString($3));
}
| LC_COLLATE_P opt_equal DEFAULT
{
$$ = makeDefElem("lc_collate", NULL);
}
| LC_CTYPE_P opt_equal Sconst
{
$$ = makeDefElem("lc_ctype", (Node *)makeString($3));
}
| LC_CTYPE_P opt_equal DEFAULT
{
$$ = makeDefElem("lc_ctype", NULL);
}
| CONNECTION LIMIT opt_equal SignedIconst
{
$$ = makeDefElem("connectionlimit", (Node *)makeInteger($4));
}
| OWNER opt_equal name
{
$$ = makeDefElem("owner", (Node *)makeString($3));
}
| OWNER opt_equal DEFAULT
{
$$ = makeDefElem("owner", NULL);
$$ = makeDefElem($1, NULL);
}
;
/*
* Ideally we'd use ColId here, but that causes shift/reduce conflicts against
* the ALTER DATABASE SET/RESET syntaxes. Instead call out specific keywords
* we need, and allow IDENT so that database option names don't have to be
* parser keywords unless they are already keywords for other reasons.
*
* XXX this coding technique is fragile since if someone makes a formerly
* non-keyword option name into a keyword and forgets to add it here, the
* option will silently break. Best defense is to provide a regression test
* exercising every such option, at least at the syntax level.
*/
createdb_opt_name:
IDENT { $$ = $1; }
| CONNECTION LIMIT { $$ = pstrdup("connection_limit"); }
| ENCODING { $$ = pstrdup($1); }
| LOCATION { $$ = pstrdup($1); }
| OWNER { $$ = pstrdup($1); }
| TABLESPACE { $$ = pstrdup($1); }
| TEMPLATE { $$ = pstrdup($1); }
;
/*
* Though the equals sign doesn't match other WITH options, pg_dump uses
* equals for backward compatibility, and it doesn't seem worth removing it.
@ -8407,13 +8382,20 @@ opt_equal: '=' {}
*****************************************************************************/
AlterDatabaseStmt:
ALTER DATABASE database_name opt_with alterdb_opt_list
ALTER DATABASE database_name WITH createdb_opt_list
{
AlterDatabaseStmt *n = makeNode(AlterDatabaseStmt);
n->dbname = $3;
n->options = $5;
$$ = (Node *)n;
}
| ALTER DATABASE database_name createdb_opt_list
{
AlterDatabaseStmt *n = makeNode(AlterDatabaseStmt);
n->dbname = $3;
n->options = $4;
$$ = (Node *)n;
}
| ALTER DATABASE database_name SET TABLESPACE name
{
AlterDatabaseStmt *n = makeNode(AlterDatabaseStmt);
@ -8435,19 +8417,6 @@ AlterDatabaseSetStmt:
;
alterdb_opt_list:
alterdb_opt_list alterdb_opt_item { $$ = lappend($1, $2); }
| /* EMPTY */ { $$ = NIL; }
;
alterdb_opt_item:
CONNECTION LIMIT opt_equal SignedIconst
{
$$ = makeDefElem("connectionlimit", (Node *)makeInteger($4));
}
;
/*****************************************************************************
*
* DROP DATABASE [ IF EXISTS ]
@ -12958,8 +12927,6 @@ unreserved_keyword:
| LANGUAGE
| LARGE_P
| LAST_P
| LC_COLLATE_P
| LC_CTYPE_P
| LEAKPROOF
| LEVEL
| LISTEN