26
26
*
27
27
*
28
28
* 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 $
30
30
*
31
31
*-------------------------------------------------------------------------
32
32
*/
@@ -73,6 +73,8 @@ static void ExecDelete(TupleTableSlot *slot, ItemPointer tupleid,
73
73
static void ExecReplace (TupleTableSlot * slot , ItemPointer tupleid ,
74
74
EState * estate , Query * parseTree );
75
75
76
+ static HeapTuple ExecAttrDefault (Relation rel , HeapTuple tuple );
77
+
76
78
/* end of local decls */
77
79
78
80
#ifdef QUERY_LIMIT
@@ -513,6 +515,7 @@ InitPlan(CmdType operation, Query *parseTree, Plan *plan, EState *estate)
513
515
char * intoName ;
514
516
char archiveMode ;
515
517
Oid intoRelationId ;
518
+ TupleDesc tupdesc ;
516
519
517
520
if (!parseTree -> isPortal ) {
518
521
/*
@@ -529,17 +532,24 @@ InitPlan(CmdType operation, Query *parseTree, Plan *plan, EState *estate)
529
532
*/
530
533
intoName = parseTree -> into ;
531
534
archiveMode = 'n' ;
535
+
536
+ /*
537
+ * have to copy tupType to get rid of constraints
538
+ */
539
+ tupdesc = CreateTupleDescCopy (tupType );
532
540
533
541
/* fixup to prevent zero-length columns in create */
534
- setVarAttrLenForCreateTable (tupType , targetList , rangeTable );
542
+ setVarAttrLenForCreateTable (tupdesc , targetList , rangeTable );
535
543
536
544
intoRelationId = heap_create (intoName ,
537
545
intoName , /* not used */
538
546
archiveMode ,
539
547
DEFAULT_SMGR ,
540
- tupType );
541
-
542
- resetVarAttrLenForCreateTable (tupType );
548
+ tupdesc );
549
+ #ifdef NOT_USED /* it's copy ... */
550
+ resetVarAttrLenForCreateTable (tupdesc );
551
+ #endif
552
+ FreeTupleDesc (tupdesc );
543
553
544
554
/* ----------------
545
555
* XXX rather than having to call setheapoverride(true)
@@ -918,16 +928,34 @@ ExecAppend(TupleTableSlot *slot,
918
928
* ----------------
919
929
*/
920
930
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
+
931
959
/* ----------------
932
960
* insert the tuple
933
961
* ----------------
@@ -1106,3 +1134,57 @@ ExecReplace(TupleTableSlot *slot,
1106
1134
ExecInsertIndexTuples (slot , & (tuple -> t_ctid ), estate , true);
1107
1135
}
1108
1136
}
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
+ }
0 commit comments