diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2014-07-01 19:02:21 -0400 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2014-07-01 19:02:21 -0400 |
commit | 15c82efd6994affd1d5654d13bc8911a9faff659 (patch) | |
tree | eff2b12a3ac0e9b57dabcef80f2379dbfa549772 /src/backend/commands/dbcommands.c | |
parent | 2e8ce9ae46d15b2bfd34c2d53193da9858d3471a (diff) | |
download | postgresql-15c82efd6994affd1d5654d13bc8911a9faff659.tar.gz postgresql-15c82efd6994affd1d5654d13bc8911a9faff659.zip |
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
Diffstat (limited to 'src/backend/commands/dbcommands.c')
-rw-r--r-- | src/backend/commands/dbcommands.c | 54 |
1 files changed, 31 insertions, 23 deletions
diff --git a/src/backend/commands/dbcommands.c b/src/backend/commands/dbcommands.c index 5705889f31d..dd92aff89dc 100644 --- a/src/backend/commands/dbcommands.c +++ b/src/backend/commands/dbcommands.c @@ -39,6 +39,7 @@ #include "catalog/pg_tablespace.h" #include "commands/comment.h" #include "commands/dbcommands.h" +#include "commands/defrem.h" #include "commands/seclabel.h" #include "commands/tablespace.h" #include "mb/pg_wchar.h" @@ -188,7 +189,7 @@ createdb(const CreatedbStmt *stmt) errmsg("conflicting or redundant options"))); dctype = defel; } - else if (strcmp(defel->defname, "connectionlimit") == 0) + else if (strcmp(defel->defname, "connection_limit") == 0) { if (dconnlimit) ereport(ERROR, @@ -204,21 +205,22 @@ createdb(const CreatedbStmt *stmt) errhint("Consider using tablespaces instead."))); } else - elog(ERROR, "option \"%s\" not recognized", - defel->defname); + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("option \"%s\" not recognized", defel->defname))); } if (downer && downer->arg) - dbowner = strVal(downer->arg); + dbowner = defGetString(downer); if (dtemplate && dtemplate->arg) - dbtemplate = strVal(dtemplate->arg); + dbtemplate = defGetString(dtemplate); if (dencoding && dencoding->arg) { const char *encoding_name; if (IsA(dencoding->arg, Integer)) { - encoding = intVal(dencoding->arg); + encoding = defGetInt32(dencoding); encoding_name = pg_encoding_to_char(encoding); if (strcmp(encoding_name, "") == 0 || pg_valid_server_encoding(encoding_name) < 0) @@ -227,9 +229,9 @@ createdb(const CreatedbStmt *stmt) errmsg("%d is not a valid encoding code", encoding))); } - else if (IsA(dencoding->arg, String)) + else { - encoding_name = strVal(dencoding->arg); + encoding_name = defGetString(dencoding); encoding = pg_valid_server_encoding(encoding_name); if (encoding < 0) ereport(ERROR, @@ -237,18 +239,15 @@ createdb(const CreatedbStmt *stmt) errmsg("%s is not a valid encoding name", encoding_name))); } - else - elog(ERROR, "unrecognized node type: %d", - nodeTag(dencoding->arg)); } if (dcollate && dcollate->arg) - dbcollate = strVal(dcollate->arg); + dbcollate = defGetString(dcollate); if (dctype && dctype->arg) - dbctype = strVal(dctype->arg); + dbctype = defGetString(dctype); if (dconnlimit && dconnlimit->arg) { - dbconnlimit = intVal(dconnlimit->arg); + dbconnlimit = defGetInt32(dconnlimit); if (dbconnlimit < -1) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), @@ -379,7 +378,7 @@ createdb(const CreatedbStmt *stmt) char *tablespacename; AclResult aclresult; - tablespacename = strVal(dtablespacename->arg); + tablespacename = defGetString(dtablespacename); dst_deftablespace = get_tablespace_oid(tablespacename, false); /* check permissions */ aclresult = pg_tablespace_aclcheck(dst_deftablespace, GetUserId(), @@ -1341,7 +1340,7 @@ AlterDatabase(AlterDatabaseStmt *stmt, bool isTopLevel) { DefElem *defel = (DefElem *) lfirst(option); - if (strcmp(defel->defname, "connectionlimit") == 0) + if (strcmp(defel->defname, "connection_limit") == 0) { if (dconnlimit) ereport(ERROR, @@ -1358,23 +1357,32 @@ AlterDatabase(AlterDatabaseStmt *stmt, bool isTopLevel) dtablespace = defel; } else - elog(ERROR, "option \"%s\" not recognized", - defel->defname); + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("option \"%s\" not recognized", defel->defname))); } if (dtablespace) { - /* currently, can't be specified along with any other options */ - Assert(!dconnlimit); + /* + * While the SET TABLESPACE syntax doesn't allow any other options, + * somebody could write "WITH TABLESPACE ...". Forbid any other + * options from being specified in that case. + */ + if (list_length(stmt->options) != 1) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("option \"%s\" cannot be specified with other options", + dtablespace->defname))); /* this case isn't allowed within a transaction block */ PreventTransactionChain(isTopLevel, "ALTER DATABASE SET TABLESPACE"); - movedb(stmt->dbname, strVal(dtablespace->arg)); + movedb(stmt->dbname, defGetString(dtablespace)); return InvalidOid; } - if (dconnlimit) + if (dconnlimit && dconnlimit->arg) { - connlimit = intVal(dconnlimit->arg); + connlimit = defGetInt32(dconnlimit); if (connlimit < -1) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), |