aboutsummaryrefslogtreecommitdiff
path: root/src/backend/commands/dbcommands.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2014-07-01 19:02:21 -0400
committerTom Lane <tgl@sss.pgh.pa.us>2014-07-01 19:02:21 -0400
commit15c82efd6994affd1d5654d13bc8911a9faff659 (patch)
treeeff2b12a3ac0e9b57dabcef80f2379dbfa549772 /src/backend/commands/dbcommands.c
parent2e8ce9ae46d15b2bfd34c2d53193da9858d3471a (diff)
downloadpostgresql-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.c54
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),