88 *
99 *
1010 * IDENTIFICATION
11- * $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.142 2005/01/10 20:02:20 tgl Exp $
11+ * $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.143 2005/01/24 23:21:57 tgl Exp $
1212 *
1313 *-------------------------------------------------------------------------
1414 */
3535#include "commands/tablecmds.h"
3636#include "commands/tablespace.h"
3737#include "commands/trigger.h"
38+ #include "commands/typecmds.h"
3839#include "executor/executor.h"
3940#include "lib/stringinfo.h"
4041#include "miscadmin.h"
@@ -2853,6 +2854,7 @@ ATExecAddColumn(AlteredTableInfo *tab, Relation rel,
28532854int minattnum ,
28542855maxatts ;
28552856HeapTuple typeTuple ;
2857+ Oid typeOid ;
28562858Form_pg_type tform ;
28572859Expr * defval ;
28582860
@@ -2930,9 +2932,10 @@ ATExecAddColumn(AlteredTableInfo *tab, Relation rel,
29302932
29312933typeTuple = typenameType (colDef -> typename );
29322934tform = (Form_pg_type )GETSTRUCT (typeTuple );
2935+ typeOid = HeapTupleGetOid (typeTuple );
29332936
29342937/* make sure datatype is legal for a column */
2935- CheckAttributeType (colDef -> colname ,HeapTupleGetOid ( typeTuple ) );
2938+ CheckAttributeType (colDef -> colname ,typeOid );
29362939
29372940attributeTuple = heap_addheader (Natts_pg_attribute ,
29382941false,
@@ -2943,7 +2946,7 @@ ATExecAddColumn(AlteredTableInfo *tab, Relation rel,
29432946
29442947attribute -> attrelid = myrelid ;
29452948namestrcpy (& (attribute -> attname ),colDef -> colname );
2946- attribute -> atttypid = HeapTupleGetOid ( typeTuple ) ;
2949+ attribute -> atttypid = typeOid ;
29472950attribute -> attstattarget = -1 ;
29482951attribute -> attlen = tform -> typlen ;
29492952attribute -> attcacheoff = -1 ;
@@ -3015,11 +3018,37 @@ ATExecAddColumn(AlteredTableInfo *tab, Relation rel,
30153018 * and return NULL if so, so without any modification of the tuple
30163019 * data we will get the effect of NULL values in the new column.
30173020 *
3021+ * An exception occurs when the new column is of a domain type: the
3022+ * domain might have a NOT NULL constraint, or a check constraint that
3023+ * indirectly rejects nulls. If there are any domain constraints then
3024+ * we construct an explicit NULL default value that will be passed through
3025+ * CoerceToDomain processing. (This is a tad inefficient, since it
3026+ * causes rewriting the table which we really don't have to do, but
3027+ * the present design of domain processing doesn't offer any simple way
3028+ * of checking the constraints more directly.)
3029+ *
30183030 * Note: we use build_column_default, and not just the cooked default
30193031 * returned by AddRelationRawConstraints, so that the right thing
30203032 * happens when a datatype's default applies.
30213033 */
30223034defval = (Expr * )build_column_default (rel ,attribute -> attnum );
3035+
3036+ if (!defval && GetDomainConstraints (typeOid )!= NIL )
3037+ {
3038+ Oid basetype = getBaseType (typeOid );
3039+
3040+ defval = (Expr * )makeNullConst (basetype );
3041+ defval = (Expr * )coerce_to_target_type (NULL ,
3042+ (Node * )defval ,
3043+ basetype ,
3044+ typeOid ,
3045+ colDef -> typename -> typmod ,
3046+ COERCION_ASSIGNMENT ,
3047+ COERCE_IMPLICIT_CAST );
3048+ if (defval == NULL )/* should not happen */
3049+ elog (ERROR ,"failed to coerce base type to domain" );
3050+ }
3051+
30233052if (defval )
30243053{
30253054NewColumnValue * newval ;