26
26
*
27
27
*
28
28
* IDENTIFICATION
29
- * $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.18 1997/08/22 03:12:16 vadim Exp $
29
+ * $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.19 1997/08/22 14:28:20 vadim Exp $
30
30
*
31
31
*-------------------------------------------------------------------------
32
32
*/
@@ -73,8 +73,6 @@ 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
-
78
76
/* end of local decls */
79
77
80
78
#ifdef QUERY_LIMIT
@@ -930,29 +928,15 @@ ExecAppend(TupleTableSlot *slot,
930
928
931
929
if ( resultRelationDesc -> rd_att -> constr )
932
930
{
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 )
931
+ HeapTuple newtuple ;
932
+
933
+ newtuple = ExecConstraints ("ExecAppend" , resultRelationDesc , tuple );
934
+
935
+ if ( newtuple != tuple ) /* modified by DEFAULT */
947
936
{
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
- }
937
+ Assert ( slot -> ttc_shouldFree );
938
+ pfree (tuple );
939
+ slot -> val = tuple = newtuple ;
956
940
}
957
941
}
958
942
@@ -1081,15 +1065,19 @@ ExecReplace(TupleTableSlot *slot,
1081
1065
* ----------------
1082
1066
*/
1083
1067
1084
- if (resultRelationDesc -> rd_att -> constr && resultRelationDesc -> rd_att -> constr -> has_not_null )
1085
- {
1086
- int attrChk ;
1087
- for (attrChk = 1 ; attrChk <= resultRelationDesc -> rd_att -> natts ; attrChk ++ ) {
1088
- if (resultRelationDesc -> rd_att -> attrs [attrChk - 1 ]-> attnotnull && heap_attisnull (tuple ,attrChk ))
1089
- elog (WARN ,"ExecReplace: Fail to update null value in not null attribute %s" ,
1090
- resultRelationDesc -> rd_att -> attrs [attrChk - 1 ]-> attname .data );
1091
- }
1092
- }
1068
+ if ( resultRelationDesc -> rd_att -> constr )
1069
+ {
1070
+ HeapTuple newtuple ;
1071
+
1072
+ newtuple = ExecConstraints ("ExecReplace" , resultRelationDesc , tuple );
1073
+
1074
+ if ( newtuple != tuple ) /* modified by DEFAULT */
1075
+ {
1076
+ Assert ( slot -> ttc_shouldFree );
1077
+ pfree (tuple );
1078
+ slot -> val = tuple = newtuple ;
1079
+ }
1080
+ }
1093
1081
1094
1082
/* ----------------
1095
1083
* replace the heap tuple
@@ -1140,7 +1128,8 @@ ExecAttrDefault (Relation rel, HeapTuple tuple)
1140
1128
{
1141
1129
int ndef = rel -> rd_att -> constr -> num_defval ;
1142
1130
AttrDefault * attrdef = rel -> rd_att -> constr -> defval ;
1143
- ExprContext * econtext = makeNode (ExprContext );
1131
+ ExprContext * econtext = makeNode (ExprContext );
1132
+ HeapTuple newtuple ;
1144
1133
Node * expr ;
1145
1134
bool isnull ;
1146
1135
bool isdone ;
@@ -1150,21 +1139,23 @@ ExecAttrDefault (Relation rel, HeapTuple tuple)
1150
1139
char * repl = NULL ;
1151
1140
int i ;
1152
1141
1142
+ econtext -> ecxt_scantuple = NULL ; /* scan tuple slot */
1143
+ econtext -> ecxt_innertuple = NULL ; /* inner tuple slot */
1144
+ econtext -> ecxt_outertuple = NULL ; /* outer tuple slot */
1145
+ econtext -> ecxt_relation = NULL ; /* relation */
1146
+ econtext -> ecxt_relid = 0 ; /* relid */
1147
+ econtext -> ecxt_param_list_info = NULL ; /* param list info */
1148
+ econtext -> ecxt_range_table = NULL ; /* range table */
1153
1149
for (i = 0 ; i < ndef ; i ++ )
1154
1150
{
1155
1151
if ( !heap_attisnull (tuple , attrdef [i ].adnum ) )
1156
1152
continue ;
1157
1153
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
1154
1166
1155
val = ExecEvalExpr (expr , econtext , & isnull , & isdone );
1167
1156
1157
+ pfree (expr );
1158
+
1168
1159
if ( isnull )
1169
1160
continue ;
1170
1161
@@ -1182,9 +1173,108 @@ ExecAttrDefault (Relation rel, HeapTuple tuple)
1182
1173
1183
1174
}
1184
1175
1176
+ pfree (econtext );
1177
+
1185
1178
if ( repl == NULL )
1186
1179
return (tuple );
1187
1180
1188
- return (heap_modifytuple (tuple , InvalidBuffer , rel , replValue , replNull , repl ));
1181
+ newtuple = heap_modifytuple (tuple , InvalidBuffer , rel , replValue , replNull , repl );
1182
+
1183
+ pfree (repl );
1184
+ pfree (replNull );
1185
+ pfree (replValue );
1186
+
1187
+ return (newtuple );
1188
+
1189
+ }
1190
+
1191
+ static char *
1192
+ ExecRelCheck (Relation rel , HeapTuple tuple )
1193
+ {
1194
+ int ncheck = rel -> rd_att -> constr -> num_check ;
1195
+ ConstrCheck * check = rel -> rd_att -> constr -> check ;
1196
+ ExprContext * econtext = makeNode (ExprContext );
1197
+ TupleTableSlot * slot = makeNode (TupleTableSlot );
1198
+ RangeTblEntry * rte = makeNode (RangeTblEntry );
1199
+ List * rtlist ;
1200
+ List * qual ;
1201
+ bool res ;
1202
+ int i ;
1203
+
1204
+ slot -> val = tuple ;
1205
+ slot -> ttc_shouldFree = false;
1206
+ slot -> ttc_descIsNew = true;
1207
+ slot -> ttc_tupleDescriptor = rel -> rd_att ;
1208
+ slot -> ttc_buffer = InvalidBuffer ;
1209
+ slot -> ttc_whichplan = -1 ;
1210
+ rte -> relname = nameout (& (rel -> rd_rel -> relname ));
1211
+ rte -> timeRange = NULL ;
1212
+ rte -> refname = rte -> relname ;
1213
+ rte -> relid = rel -> rd_id ;
1214
+ rte -> inh = false;
1215
+ rte -> archive = false;
1216
+ rte -> inFromCl = true;
1217
+ rte -> timeQual = NULL ;
1218
+ rtlist = lcons (rte , NIL );
1219
+ econtext -> ecxt_scantuple = slot ; /* scan tuple slot */
1220
+ econtext -> ecxt_innertuple = NULL ; /* inner tuple slot */
1221
+ econtext -> ecxt_outertuple = NULL ; /* outer tuple slot */
1222
+ econtext -> ecxt_relation = rel ; /* relation */
1223
+ econtext -> ecxt_relid = 0 ; /* relid */
1224
+ econtext -> ecxt_param_list_info = NULL ; /* param list info */
1225
+ econtext -> ecxt_range_table = rtlist ; /* range table */
1226
+
1227
+ for (i = 0 ; i < ncheck ; i ++ )
1228
+ {
1229
+ qual = (List * ) stringToNode (check [i ].ccbin );
1230
+
1231
+ res = ExecQual (qual , econtext );
1232
+
1233
+ pfree (qual );
1234
+
1235
+ if ( !res )
1236
+ return (check [i ].ccname );
1237
+ }
1238
+
1239
+ pfree (slot );
1240
+ pfree (rte -> relname );
1241
+ pfree (rte );
1242
+ pfree (rtlist );
1243
+ pfree (econtext );
1244
+
1245
+ return ((char * ) NULL );
1246
+
1247
+ }
1248
+
1249
+ HeapTuple
1250
+ ExecConstraints (char * caller , Relation rel , HeapTuple tuple )
1251
+ {
1252
+ HeapTuple newtuple = tuple ;
1253
+
1254
+ Assert ( rel -> rd_att -> constr );
1189
1255
1256
+ if ( rel -> rd_att -> constr -> num_defval > 0 )
1257
+ newtuple = tuple = ExecAttrDefault (rel , tuple );
1258
+
1259
+ if ( rel -> rd_att -> constr -> has_not_null )
1260
+ {
1261
+ int attrChk ;
1262
+
1263
+ for (attrChk = 1 ; attrChk <= rel -> rd_att -> natts ; attrChk ++ )
1264
+ {
1265
+ if (rel -> rd_att -> attrs [attrChk - 1 ]-> attnotnull && heap_attisnull (tuple ,attrChk ))
1266
+ elog (WARN ,"%s: Fail to add null value in not null attribute %s" ,
1267
+ caller , rel -> rd_att -> attrs [attrChk - 1 ]-> attname .data );
1268
+ }
1269
+ }
1270
+
1271
+ if ( rel -> rd_att -> constr -> num_check > 0 )
1272
+ {
1273
+ char * failed ;
1274
+
1275
+ if ( ( failed = ExecRelCheck (rel , tuple ) ) != NULL )
1276
+ elog (WARN ,"%s: rejected due to CHECK constraint %s" , caller , failed );
1277
+ }
1278
+
1279
+ return (newtuple );
1190
1280
}
0 commit comments