aboutsummaryrefslogtreecommitdiff
path: root/src/backend/commands/tablecmds.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/commands/tablecmds.c')
-rw-r--r--src/backend/commands/tablecmds.c35
1 files changed, 32 insertions, 3 deletions
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index b788db35cbb..89dd8dffae0 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.142 2005/01/10 20:02:20 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.143 2005/01/24 23:21:57 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -35,6 +35,7 @@
#include "commands/tablecmds.h"
#include "commands/tablespace.h"
#include "commands/trigger.h"
+#include "commands/typecmds.h"
#include "executor/executor.h"
#include "lib/stringinfo.h"
#include "miscadmin.h"
@@ -2853,6 +2854,7 @@ ATExecAddColumn(AlteredTableInfo *tab, Relation rel,
int minattnum,
maxatts;
HeapTuple typeTuple;
+ Oid typeOid;
Form_pg_type tform;
Expr *defval;
@@ -2930,9 +2932,10 @@ ATExecAddColumn(AlteredTableInfo *tab, Relation rel,
typeTuple = typenameType(colDef->typename);
tform = (Form_pg_type) GETSTRUCT(typeTuple);
+ typeOid = HeapTupleGetOid(typeTuple);
/* make sure datatype is legal for a column */
- CheckAttributeType(colDef->colname, HeapTupleGetOid(typeTuple));
+ CheckAttributeType(colDef->colname, typeOid);
attributeTuple = heap_addheader(Natts_pg_attribute,
false,
@@ -2943,7 +2946,7 @@ ATExecAddColumn(AlteredTableInfo *tab, Relation rel,
attribute->attrelid = myrelid;
namestrcpy(&(attribute->attname), colDef->colname);
- attribute->atttypid = HeapTupleGetOid(typeTuple);
+ attribute->atttypid = typeOid;
attribute->attstattarget = -1;
attribute->attlen = tform->typlen;
attribute->attcacheoff = -1;
@@ -3015,11 +3018,37 @@ ATExecAddColumn(AlteredTableInfo *tab, Relation rel,
* and return NULL if so, so without any modification of the tuple
* data we will get the effect of NULL values in the new column.
*
+ * An exception occurs when the new column is of a domain type: the
+ * domain might have a NOT NULL constraint, or a check constraint that
+ * indirectly rejects nulls. If there are any domain constraints then
+ * we construct an explicit NULL default value that will be passed through
+ * CoerceToDomain processing. (This is a tad inefficient, since it
+ * causes rewriting the table which we really don't have to do, but
+ * the present design of domain processing doesn't offer any simple way
+ * of checking the constraints more directly.)
+ *
* Note: we use build_column_default, and not just the cooked default
* returned by AddRelationRawConstraints, so that the right thing
* happens when a datatype's default applies.
*/
defval = (Expr *) build_column_default(rel, attribute->attnum);
+
+ if (!defval && GetDomainConstraints(typeOid) != NIL)
+ {
+ Oid basetype = getBaseType(typeOid);
+
+ defval = (Expr *) makeNullConst(basetype);
+ defval = (Expr *) coerce_to_target_type(NULL,
+ (Node *) defval,
+ basetype,
+ typeOid,
+ colDef->typename->typmod,
+ COERCION_ASSIGNMENT,
+ COERCE_IMPLICIT_CAST);
+ if (defval == NULL) /* should not happen */
+ elog(ERROR, "failed to coerce base type to domain");
+ }
+
if (defval)
{
NewColumnValue *newval;