2626 *
2727 *
2828 * IDENTIFICATION
29- * $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.17 1997/08/19 21:31:00 momjian Exp $
29+ * $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.18 1997/08/22 03:12:16 vadim Exp $
3030 *
3131 *-------------------------------------------------------------------------
3232 */
@@ -73,6 +73,8 @@ static void ExecDelete(TupleTableSlot *slot, ItemPointer tupleid,
7373static void ExecReplace (TupleTableSlot * slot ,ItemPointer tupleid ,
7474EState * estate ,Query * parseTree );
7575
76+ static HeapTuple ExecAttrDefault (Relation rel ,HeapTuple tuple );
77+
7678/* end of local decls */
7779
7880#ifdef QUERY_LIMIT
@@ -513,6 +515,7 @@ InitPlan(CmdType operation, Query *parseTree, Plan *plan, EState *estate)
513515char * intoName ;
514516char archiveMode ;
515517Oid intoRelationId ;
518+ TupleDesc tupdesc ;
516519
517520if (!parseTree -> isPortal ) {
518521/*
@@ -529,17 +532,24 @@ InitPlan(CmdType operation, Query *parseTree, Plan *plan, EState *estate)
529532 */
530533intoName = parseTree -> into ;
531534archiveMode = 'n' ;
535+
536+ /*
537+ * have to copy tupType to get rid of constraints
538+ */
539+ tupdesc = CreateTupleDescCopy (tupType );
532540
533541/* fixup to prevent zero-length columns in create */
534- setVarAttrLenForCreateTable (tupType ,targetList ,rangeTable );
542+ setVarAttrLenForCreateTable (tupdesc ,targetList ,rangeTable );
535543
536544intoRelationId = heap_create (intoName ,
537545intoName ,/* not used */
538546archiveMode ,
539547DEFAULT_SMGR ,
540- tupType );
541-
542- resetVarAttrLenForCreateTable (tupType );
548+ tupdesc );
549+ #ifdef NOT_USED /* it's copy ... */
550+ resetVarAttrLenForCreateTable (tupdesc );
551+ #endif
552+ FreeTupleDesc (tupdesc );
543553
544554/* ----------------
545555 * XXX rather than having to call setheapoverride(true)
@@ -918,16 +928,34 @@ ExecAppend(TupleTableSlot *slot,
918928 * ----------------
919929 */
920930
921- if (resultRelationDesc -> rd_att -> constr && resultRelationDesc -> rd_att -> constr -> has_not_null )
922- {
923- int attrChk ;
924- for (attrChk = 1 ;attrChk <=resultRelationDesc -> rd_att -> natts ;attrChk ++ ) {
925- if (resultRelationDesc -> rd_att -> attrs [attrChk - 1 ]-> attnotnull && heap_attisnull (tuple ,attrChk ))
926- elog (WARN ,"ExecAppend: Fail to add null value in not null attribute %s" ,
927- resultRelationDesc -> rd_att -> attrs [attrChk - 1 ]-> attname .data );
928- }
929- }
930-
931+ if (resultRelationDesc -> rd_att -> constr )
932+ {
933+ if (resultRelationDesc -> rd_att -> constr -> num_defval > 0 )
934+ {
935+ HeapTuple newtuple ;
936+
937+ newtuple = ExecAttrDefault (resultRelationDesc ,tuple );
938+
939+ if (newtuple != tuple )
940+ {
941+ Assert (slot -> ttc_shouldFree );
942+ slot -> val = tuple = newtuple ;
943+ }
944+ }
945+
946+ if (resultRelationDesc -> rd_att -> constr -> has_not_null )
947+ {
948+ int attrChk ;
949+
950+ for (attrChk = 1 ;attrChk <=resultRelationDesc -> rd_att -> natts ;attrChk ++ )
951+ {
952+ if (resultRelationDesc -> rd_att -> attrs [attrChk - 1 ]-> attnotnull && heap_attisnull (tuple ,attrChk ))
953+ elog (WARN ,"ExecAppend: Fail to add null value in not null attribute %s" ,
954+ resultRelationDesc -> rd_att -> attrs [attrChk - 1 ]-> attname .data );
955+ }
956+ }
957+ }
958+
931959/* ----------------
932960 *insert the tuple
933961 * ----------------
@@ -1106,3 +1134,57 @@ ExecReplace(TupleTableSlot *slot,
11061134ExecInsertIndexTuples (slot ,& (tuple -> t_ctid ),estate , true);
11071135 }
11081136}
1137+
1138+ static HeapTuple
1139+ ExecAttrDefault (Relation rel ,HeapTuple tuple )
1140+ {
1141+ int ndef = rel -> rd_att -> constr -> num_defval ;
1142+ AttrDefault * attrdef = rel -> rd_att -> constr -> defval ;
1143+ ExprContext * econtext = makeNode (ExprContext );
1144+ Node * expr ;
1145+ bool isnull ;
1146+ bool isdone ;
1147+ Datum val ;
1148+ Datum * replValue = NULL ;
1149+ char * replNull = NULL ;
1150+ char * repl = NULL ;
1151+ int i ;
1152+
1153+ for (i = 0 ;i < ndef ;i ++ )
1154+ {
1155+ if ( !heap_attisnull (tuple ,attrdef [i ].adnum ) )
1156+ continue ;
1157+ expr = (Node * )stringToNode (attrdef [i ].adbin );
1158+ econtext -> ecxt_scantuple = NULL ;/* scan tuple slot */
1159+ econtext -> ecxt_innertuple = NULL ;/* inner tuple slot */
1160+ econtext -> ecxt_outertuple = NULL ;/* outer tuple slot */
1161+ econtext -> ecxt_relation = NULL ;/* relation */
1162+ econtext -> ecxt_relid = 0 ;/* relid */
1163+ econtext -> ecxt_param_list_info = NULL ;/* param list info */
1164+ econtext -> ecxt_range_table = NULL ;/* range table */
1165+
1166+ val = ExecEvalExpr (expr ,econtext ,& isnull ,& isdone );
1167+
1168+ if (isnull )
1169+ continue ;
1170+
1171+ if (repl == NULL )
1172+ {
1173+ repl = (char * )palloc (rel -> rd_att -> natts * sizeof (char ));
1174+ replNull = (char * )palloc (rel -> rd_att -> natts * sizeof (char ));
1175+ replValue = (Datum * )palloc (rel -> rd_att -> natts * sizeof (Datum ));
1176+ memset (repl ,' ' ,rel -> rd_att -> natts * sizeof (char ));
1177+ }
1178+
1179+ repl [attrdef [i ].adnum - 1 ]= 'r' ;
1180+ replNull [attrdef [i ].adnum - 1 ]= ' ' ;
1181+ replValue [attrdef [i ].adnum - 1 ]= val ;
1182+
1183+ }
1184+
1185+ if (repl == NULL )
1186+ return (tuple );
1187+
1188+ return (heap_modifytuple (tuple ,InvalidBuffer ,rel ,replValue ,replNull ,repl ));
1189+
1190+ }