aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2007-06-20 18:15:49 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2007-06-20 18:15:49 +0000
commita060d5ffdcae76f8cabe0c4dbcbc3b88ad1515e7 (patch)
tree8ec72aa4da6bd190c7007f96c64a5f7395d4b599
parent52ba24a156f3f52f179a26513dee7f5e27191d8f (diff)
downloadpostgresql-a060d5ffdcae76f8cabe0c4dbcbc3b88ad1515e7.tar.gz
postgresql-a060d5ffdcae76f8cabe0c4dbcbc3b88ad1515e7.zip
CREATE DOMAIN ... DEFAULT NULL failed because gram.y special-cases DEFAULT
NULL and DefineDomain didn't. Bug goes all the way back to original coding of domains. Per bug #3396 from Sergey Burladyan.
-rw-r--r--src/backend/commands/typecmds.c67
1 files changed, 40 insertions, 27 deletions
diff --git a/src/backend/commands/typecmds.c b/src/backend/commands/typecmds.c
index d9748cf0ea8..86790308201 100644
--- a/src/backend/commands/typecmds.c
+++ b/src/backend/commands/typecmds.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/commands/typecmds.c,v 1.105 2007/06/15 20:56:49 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/typecmds.c,v 1.106 2007/06/20 18:15:49 tgl Exp $
*
* DESCRIPTION
* The "DefineFoo" routines take the parse tree and pick out the
@@ -605,9 +605,9 @@ DefineDomain(CreateDomainStmt *stmt)
char typtype;
Datum datum;
bool isnull;
- Node *defaultExpr = NULL;
char *defaultValue = NULL;
char *defaultValueBin = NULL;
+ bool saw_default = false;
bool typNotNull = false;
bool nullDefined = false;
int32 typNDims = list_length(stmt->typename->arrayBounds);
@@ -719,7 +719,6 @@ DefineDomain(CreateDomainStmt *stmt)
{
Node *newConstraint = lfirst(listptr);
Constraint *constr;
- ParseState *pstate;
/* Check for unsupported constraint types */
if (IsA(newConstraint, FkConstraint))
@@ -740,35 +739,49 @@ DefineDomain(CreateDomainStmt *stmt)
/*
* The inherited default value may be overridden by the user
- * with the DEFAULT <expr> statement.
+ * with the DEFAULT <expr> clause ... but only once.
*/
- if (defaultExpr)
+ if (saw_default)
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("multiple default expressions")));
+ saw_default = true;
- /* Create a dummy ParseState for transformExpr */
- pstate = make_parsestate(NULL);
-
- /*
- * Cook the constr->raw_expr into an expression. Note: Name is
- * strictly for error message
- */
- defaultExpr = cookDefault(pstate, constr->raw_expr,
- basetypeoid,
- basetypeMod,
- domainName);
-
- /*
- * Expression must be stored as a nodeToString result, but we
- * also require a valid textual representation (mainly to make
- * life easier for pg_dump).
- */
- defaultValue = deparse_expression(defaultExpr,
- deparse_context_for(domainName,
- InvalidOid),
- false, false);
- defaultValueBin = nodeToString(defaultExpr);
+ if (constr->raw_expr)
+ {
+ ParseState *pstate;
+ Node *defaultExpr;
+
+ /* Create a dummy ParseState for transformExpr */
+ pstate = make_parsestate(NULL);
+
+ /*
+ * Cook the constr->raw_expr into an expression.
+ * Note: name is strictly for error message
+ */
+ defaultExpr = cookDefault(pstate, constr->raw_expr,
+ basetypeoid,
+ basetypeMod,
+ domainName);
+
+ /*
+ * Expression must be stored as a nodeToString result, but
+ * we also require a valid textual representation (mainly
+ * to make life easier for pg_dump).
+ */
+ defaultValue =
+ deparse_expression(defaultExpr,
+ deparse_context_for(domainName,
+ InvalidOid),
+ false, false);
+ defaultValueBin = nodeToString(defaultExpr);
+ }
+ else
+ {
+ /* DEFAULT NULL is same as not having a default */
+ defaultValue = NULL;
+ defaultValueBin = NULL;
+ }
break;
case CONSTR_NOTNULL: