]> granicus.if.org Git - postgresql/commitdiff
CREATE DOMAIN ... DEFAULT NULL failed because gram.y special-cases DEFAULT
authorTom Lane <tgl@sss.pgh.pa.us>
Wed, 20 Jun 2007 18:16:18 +0000 (18:16 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Wed, 20 Jun 2007 18:16:18 +0000 (18:16 +0000)
NULL and DefineDomain didn't.  Bug goes all the way back to original coding
of domains.  Per bug #3396 from Sergey Burladyan.

src/backend/commands/typecmds.c

index e6d1b5c50b271f97106bb1ee6df2a9a91659fabe..bc3b8be95107c0586be45c808d64e805278fd1ac 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/commands/typecmds.c,v 1.48 2003/10/02 06:34:03 petere Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/commands/typecmds.c,v 1.48.2.1 2007/06/20 18:16:18 tgl Exp $
  *
  * DESCRIPTION
  *       The "DefineFoo" routines take the parse tree and pick out the
@@ -480,9 +480,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;
        Oid                     basetypelem;
@@ -589,7 +589,6 @@ DefineDomain(CreateDomainStmt *stmt)
        {
                Node       *newConstraint = lfirst(listptr);
                Constraint *constr;
-               ParseState *pstate;
 
                /* Check for unsupported constraint types */
                if (IsA(newConstraint, FkConstraint))
@@ -610,35 +609,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,
-                                                                                 stmt->typename->typmod,
-                                                                                 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,
+                                                                                         stmt->typename->typmod,
+                                                                                         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: