aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/backend/commands/tablecmds.c35
-rw-r--r--src/backend/commands/typecmds.c21
2 files changed, 44 insertions, 12 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;
diff --git a/src/backend/commands/typecmds.c b/src/backend/commands/typecmds.c
index efeb3f3bab2..d9fffbec271 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.65 2004/12/31 21:59:42 pgsql Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/typecmds.c,v 1.66 2005/01/24 23:21:57 tgl Exp $
*
* DESCRIPTION
* The "DefineFoo" routines take the parse tree and pick out the
@@ -1929,6 +1929,9 @@ domainAddConstraint(Oid domainOid, Oid domainNamespace, Oid baseTypeOid,
* This is called by the executor during plan startup for a CoerceToDomain
* expression node. The given constraints will be checked for each value
* passed through the node.
+ *
+ * We allow this to be called for non-domain types, in which case the result
+ * is always NIL.
*/
List *
GetDomainConstraints(Oid typeOid)
@@ -1954,6 +1957,13 @@ GetDomainConstraints(Oid typeOid)
elog(ERROR, "cache lookup failed for type %u", typeOid);
typTup = (Form_pg_type) GETSTRUCT(tup);
+ if (typTup->typtype != 'd')
+ {
+ /* Not a domain, so done */
+ ReleaseSysCache(tup);
+ break;
+ }
+
/* Test for NOT NULL Constraint */
if (typTup->typnotnull)
notNull = true;
@@ -2010,14 +2020,7 @@ GetDomainConstraints(Oid typeOid)
systable_endscan(scan);
- if (typTup->typtype != 'd')
- {
- /* Not a domain, so done */
- ReleaseSysCache(tup);
- break;
- }
-
- /* else loop to next domain in stack */
+ /* loop to next domain in stack */
typeOid = typTup->typbasetype;
ReleaseSysCache(tup);
}