aboutsummaryrefslogtreecommitdiff
path: root/src/backend/commands/tablecmds.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2005-01-24 23:22:13 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2005-01-24 23:22:13 +0000
commit56915ea29622e85b296b65e2fd6fd164c5bfd5d6 (patch)
treea1809626e9e928b4292e3d3b511226a41a37c1b3 /src/backend/commands/tablecmds.c
parent49b35eb14b7b3df8c550bc4638856a4f79769d9c (diff)
downloadpostgresql-56915ea29622e85b296b65e2fd6fd164c5bfd5d6.tar.gz
postgresql-56915ea29622e85b296b65e2fd6fd164c5bfd5d6.zip
Fix ALTER TABLE ADD COLUMN so that constraints of domain types are
enforced properly when there is no explicit default value for the new column. Per report from Craig Perras.
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..74df2b23e36 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.142.4.1 2005/01/24 23:22:12 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;