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,
28532854 int minattnum ,
28542855 maxatts ;
28552856 HeapTuple typeTuple ;
2857+ Oid typeOid ;
28562858 Form_pg_type tform ;
28572859 Expr * defval ;
28582860
@@ -2930,9 +2932,10 @@ ATExecAddColumn(AlteredTableInfo *tab, Relation rel,
29302932
29312933 typeTuple = typenameType (colDef -> typename );
29322934 tform = (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
29372940 attributeTuple = heap_addheader (Natts_pg_attribute ,
29382941 false,
@@ -2943,7 +2946,7 @@ ATExecAddColumn(AlteredTableInfo *tab, Relation rel,
29432946
29442947 attribute -> attrelid = myrelid ;
29452948 namestrcpy (& (attribute -> attname ), colDef -> colname );
2946- attribute -> atttypid = HeapTupleGetOid ( typeTuple ) ;
2949+ attribute -> atttypid = typeOid ;
29472950 attribute -> attstattarget = -1 ;
29482951 attribute -> attlen = tform -> typlen ;
29492952 attribute -> 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 */
30223034 defval = (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+
30233052 if (defval )
30243053 {
30253054 NewColumnValue * newval ;
0 commit comments