@@ -28,9 +28,10 @@ bool pg_pathman_enable_partition_router = true;
28
28
CustomScanMethods partition_router_plan_methods ;
29
29
CustomExecMethods partition_router_exec_methods ;
30
30
31
- static bool ExecDeleteInternal (ItemPointer tupleid ,
32
- EPQState * epqstate ,
33
- EState * estate );
31
+ static TupleTableSlot * ExecDeleteInternal (TupleTableSlot * slot ,
32
+ ItemPointer tupleid ,
33
+ EPQState * epqstate ,
34
+ EState * estate );
34
35
35
36
void
36
37
init_partition_router_static_data (void )
@@ -70,15 +71,6 @@ make_partition_router(Plan *subplan,
70
71
71
72
{
72
73
CustomScan * cscan = makeNode (CustomScan );
73
- Plan * pfilter ;
74
-
75
- /* Create child PartitionFilter node */
76
- pfilter = make_partition_filter (subplan ,
77
- parent_relid ,
78
- parent_rti ,
79
- ONCONFLICT_NONE ,
80
- returning_list ,
81
- CMD_UPDATE );
82
74
83
75
/* Copy costs etc */
84
76
cscan -> scan .plan .startup_cost = subplan -> startup_cost ;
@@ -88,14 +80,14 @@ make_partition_router(Plan *subplan,
88
80
89
81
/* Setup methods, child plan and param number for EPQ */
90
82
cscan -> methods = & partition_router_plan_methods ;
91
- cscan -> custom_plans = list_make1 (pfilter );
83
+ cscan -> custom_plans = list_make1 (subplan );
92
84
cscan -> custom_private = list_make1 (makeInteger (epq_param ));
93
85
94
86
/* No physical relation will be scanned */
95
87
cscan -> scan .scanrelid = 0 ;
96
88
97
89
/* Build an appropriate target list */
98
- cscan -> scan .plan .targetlist = pfilter -> targetlist ;
90
+ cscan -> scan .plan .targetlist = pfilter_build_tlist ( subplan ) ;
99
91
100
92
/* FIXME: should we use the same tlist? */
101
93
cscan -> custom_scan_tlist = subplan -> targetlist ;
@@ -126,6 +118,9 @@ partition_router_begin(CustomScanState *node, EState *estate, int eflags)
126
118
{
127
119
PartitionRouterState * state = (PartitionRouterState * ) node ;
128
120
121
+ /* Remember current relation we're going to delete from */
122
+ state -> current_rri = estate -> es_result_relation_info ;
123
+
129
124
EvalPlanQualInit (& state -> epqstate , estate ,
130
125
state -> subplan , NIL ,
131
126
state -> epqparam );
@@ -148,26 +143,18 @@ partition_router_exec(CustomScanState *node)
148
143
149
144
if (!TupIsNull (slot ))
150
145
{
151
- ResultRelInfo * new_rri , /* new tuple owner */
152
- * old_rri ; /* previous tuple owner */
153
- PartitionFilterState * child_state ;
154
- char relkind ;
155
- ItemPointerData ctid ;
146
+ ResultRelInfo * current_rri = state -> current_rri ;
147
+ char relkind ;
148
+ ItemPointerData ctid ;
156
149
157
150
ItemPointerSetInvalid (& ctid );
158
151
159
- child_state = (PartitionFilterState * ) child_ps ;
160
- Assert (child_state -> command_type == CMD_UPDATE );
161
-
162
- old_rri = child_state -> result_parts .base_rri ;
163
- new_rri = estate -> es_result_relation_info ;
164
-
165
152
/* Build new junkfilter if we have to */
166
153
if (state -> junkfilter == NULL )
167
154
{
168
155
state -> junkfilter =
169
156
ExecInitJunkFilter (state -> subplan -> targetlist ,
170
- old_rri -> ri_RelationDesc -> rd_att -> tdhasoid ,
157
+ current_rri -> ri_RelationDesc -> rd_att -> tdhasoid ,
171
158
ExecInitExtraTupleSlotCompat (estate ));
172
159
173
160
state -> junkfilter -> jf_junkAttNo =
@@ -177,13 +164,14 @@ partition_router_exec(CustomScanState *node)
177
164
elog (ERROR , "could not find junk ctid column" );
178
165
}
179
166
180
- relkind = old_rri -> ri_RelationDesc -> rd_rel -> relkind ;
167
+ /* Additional checks based on 'relkind' */
168
+ relkind = current_rri -> ri_RelationDesc -> rd_rel -> relkind ;
181
169
if (relkind == RELKIND_RELATION )
182
170
{
183
171
Datum ctid_datum ;
184
172
bool ctid_isnull ;
185
173
186
- ctid_datum = ExecGetJunkAttribute (child_state -> subplan_slot ,
174
+ ctid_datum = ExecGetJunkAttribute (slot ,
187
175
state -> junkfilter -> jf_junkAttNo ,
188
176
& ctid_isnull );
189
177
@@ -199,30 +187,26 @@ partition_router_exec(CustomScanState *node)
199
187
else
200
188
elog (ERROR , UPDATE_NODE_NAME " cannot handle relkind %u" , relkind );
201
189
202
- /*
203
- * Clean from junk attributes before INSERT,
204
- * but only if slot wasn't transformed in PartitionFilter.
205
- */
206
- if (TupIsNull (child_state -> tup_convert_slot ))
207
- slot = ExecFilterJunk (state -> junkfilter , slot );
190
+ elog (INFO , "deleting (%d, %d) from table: %s" ,
191
+ ItemPointerGetBlockNumber (& ctid ),
192
+ ItemPointerGetOffsetNumber (& ctid ),
193
+ get_rel_name (RelationGetRelid (current_rri -> ri_RelationDesc )));
208
194
209
- /* Magic: replace current ResultRelInfo with parent's one (DELETE) */
210
- estate -> es_result_relation_info = old_rri ;
195
+ /* Magic: replace parent's ResultRelInfo with ours */
196
+ estate -> es_result_relation_info = current_rri ;
211
197
212
198
/* Delete tuple from old partition */
213
199
Assert (ItemPointerIsValid (& ctid ));
214
- EvalPlanQualSetSlot (& state -> epqstate , child_state -> subplan_slot );
215
- if (!ExecDeleteInternal (& ctid , & state -> epqstate , estate ))
200
+ slot = ExecDeleteInternal (slot , & ctid , & state -> epqstate , estate );
201
+
202
+ if (TupIsNull (slot ))
216
203
{
217
204
elog (INFO , "oops, deleted, taking next tuple!" );
218
205
goto take_next_tuple ;
219
206
}
220
207
221
- /* Magic: replace parent's ResultRelInfo with child's one (INSERT) */
222
- estate -> es_result_relation_info = new_rri ;
223
-
224
208
/* Tuple will be inserted by ModifyTable */
225
- return slot ;
209
+ return ExecFilterJunk ( state -> junkfilter , slot ) ;
226
210
}
227
211
228
212
return NULL ;
@@ -231,7 +215,10 @@ partition_router_exec(CustomScanState *node)
231
215
void
232
216
partition_router_end (CustomScanState * node )
233
217
{
218
+ PartitionRouterState * state = (PartitionRouterState * ) node ;
219
+
234
220
Assert (list_length (node -> custom_ps ) == 1 );
221
+ EvalPlanQualEnd (& state -> epqstate );
235
222
ExecEndNode ((PlanState * ) linitial (node -> custom_ps ));
236
223
}
237
224
@@ -256,8 +243,9 @@ partition_router_explain(CustomScanState *node, List *ancestors, ExplainState *e
256
243
* ----------------------------------------------------------------
257
244
*/
258
245
259
- static bool
260
- ExecDeleteInternal (ItemPointer tupleid ,
246
+ static TupleTableSlot *
247
+ ExecDeleteInternal (TupleTableSlot * slot ,
248
+ ItemPointer tupleid ,
261
249
EPQState * epqstate ,
262
250
EState * estate )
263
251
{
@@ -284,13 +272,15 @@ ExecDeleteInternal(ItemPointer tupleid,
284
272
rri -> ri_TrigDesc -> trig_delete_before_row )
285
273
{
286
274
if (!ExecBRDeleteTriggers (estate , epqstate , rri , tupleid , NULL ))
287
- return false ;
275
+ return NULL ;
288
276
}
289
277
290
278
if (tupleid != NULL )
291
279
{
292
- /* delete the tuple */
280
+ EvalPlanQualSetSlot (epqstate , slot );
281
+
293
282
ldelete :
283
+ /* delete the tuple */
294
284
result = heap_delete_compat (rel , tupleid ,
295
285
estate -> es_output_cid ,
296
286
estate -> es_crosscheck_snapshot ,
@@ -305,8 +295,8 @@ ExecDeleteInternal(ItemPointer tupleid,
305
295
errmsg ("tuple to be updated was already modified by an operation triggered by the current command" ),
306
296
errhint ("Consider using an AFTER trigger instead of a BEFORE trigger to propagate changes to other rows." )));
307
297
308
- /* Else, already deleted by self; nothing to do */
309
- return false ;
298
+ /* Already deleted by self; nothing to do */
299
+ return NULL ;
310
300
311
301
case HeapTupleMayBeUpdated :
312
302
break ;
@@ -333,12 +323,13 @@ ExecDeleteInternal(ItemPointer tupleid,
333
323
{
334
324
Assert (tupleid != NULL );
335
325
* tupleid = hufd .ctid ;
326
+ slot = epqslot ;
336
327
goto ldelete ;
337
328
}
338
329
}
339
330
340
- /* tuple already deleted; nothing to do */
341
- return false ;
331
+ /* Tuple already deleted; nothing to do */
332
+ return NULL ;
342
333
343
334
default :
344
335
elog (ERROR , "unrecognized heap_delete status: %u" , result );
@@ -350,5 +341,5 @@ ExecDeleteInternal(ItemPointer tupleid,
350
341
/* AFTER ROW DELETE triggers */
351
342
ExecARDeleteTriggersCompat (estate , rri , tupleid , NULL , NULL );
352
343
353
- return true ;
344
+ return slot ;
354
345
}
0 commit comments