@@ -28,9 +28,10 @@ bool pg_pathman_enable_partition_router = true;
2828CustomScanMethods partition_router_plan_methods ;
2929CustomExecMethods partition_router_exec_methods ;
3030
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 );
3435
3536void
3637init_partition_router_static_data (void )
@@ -70,15 +71,6 @@ make_partition_router(Plan *subplan,
7071
7172{
7273 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 );
8274
8375 /* Copy costs etc */
8476 cscan -> scan .plan .startup_cost = subplan -> startup_cost ;
@@ -88,14 +80,14 @@ make_partition_router(Plan *subplan,
8880
8981 /* Setup methods, child plan and param number for EPQ */
9082 cscan -> methods = & partition_router_plan_methods ;
91- cscan -> custom_plans = list_make1 (pfilter );
83+ cscan -> custom_plans = list_make1 (subplan );
9284 cscan -> custom_private = list_make1 (makeInteger (epq_param ));
9385
9486 /* No physical relation will be scanned */
9587 cscan -> scan .scanrelid = 0 ;
9688
9789 /* Build an appropriate target list */
98- cscan -> scan .plan .targetlist = pfilter -> targetlist ;
90+ cscan -> scan .plan .targetlist = pfilter_build_tlist ( subplan ) ;
9991
10092 /* FIXME: should we use the same tlist? */
10193 cscan -> custom_scan_tlist = subplan -> targetlist ;
@@ -126,6 +118,9 @@ partition_router_begin(CustomScanState *node, EState *estate, int eflags)
126118{
127119 PartitionRouterState * state = (PartitionRouterState * ) node ;
128120
121+ /* Remember current relation we're going to delete from */
122+ state -> current_rri = estate -> es_result_relation_info ;
123+
129124 EvalPlanQualInit (& state -> epqstate , estate ,
130125 state -> subplan , NIL ,
131126 state -> epqparam );
@@ -148,26 +143,18 @@ partition_router_exec(CustomScanState *node)
148143
149144 if (!TupIsNull (slot ))
150145 {
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 ;
156149
157150 ItemPointerSetInvalid (& ctid );
158151
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-
165152 /* Build new junkfilter if we have to */
166153 if (state -> junkfilter == NULL )
167154 {
168155 state -> junkfilter =
169156 ExecInitJunkFilter (state -> subplan -> targetlist ,
170- old_rri -> ri_RelationDesc -> rd_att -> tdhasoid ,
157+ current_rri -> ri_RelationDesc -> rd_att -> tdhasoid ,
171158 ExecInitExtraTupleSlotCompat (estate ));
172159
173160 state -> junkfilter -> jf_junkAttNo =
@@ -177,13 +164,14 @@ partition_router_exec(CustomScanState *node)
177164 elog (ERROR , "could not find junk ctid column" );
178165 }
179166
180- relkind = old_rri -> ri_RelationDesc -> rd_rel -> relkind ;
167+ /* Additional checks based on 'relkind' */
168+ relkind = current_rri -> ri_RelationDesc -> rd_rel -> relkind ;
181169 if (relkind == RELKIND_RELATION )
182170 {
183171 Datum ctid_datum ;
184172 bool ctid_isnull ;
185173
186- ctid_datum = ExecGetJunkAttribute (child_state -> subplan_slot ,
174+ ctid_datum = ExecGetJunkAttribute (slot ,
187175 state -> junkfilter -> jf_junkAttNo ,
188176 & ctid_isnull );
189177
@@ -199,30 +187,26 @@ partition_router_exec(CustomScanState *node)
199187 else
200188 elog (ERROR , UPDATE_NODE_NAME " cannot handle relkind %u" , relkind );
201189
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 )));
208194
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 ;
211197
212198 /* Delete tuple from old partition */
213199 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 ))
216203 {
217204 elog (INFO , "oops, deleted, taking next tuple!" );
218205 goto take_next_tuple ;
219206 }
220207
221- /* Magic: replace parent's ResultRelInfo with child's one (INSERT) */
222- estate -> es_result_relation_info = new_rri ;
223-
224208 /* Tuple will be inserted by ModifyTable */
225- return slot ;
209+ return ExecFilterJunk ( state -> junkfilter , slot ) ;
226210 }
227211
228212 return NULL ;
@@ -231,7 +215,10 @@ partition_router_exec(CustomScanState *node)
231215void
232216partition_router_end (CustomScanState * node )
233217{
218+ PartitionRouterState * state = (PartitionRouterState * ) node ;
219+
234220 Assert (list_length (node -> custom_ps ) == 1 );
221+ EvalPlanQualEnd (& state -> epqstate );
235222 ExecEndNode ((PlanState * ) linitial (node -> custom_ps ));
236223}
237224
@@ -256,8 +243,9 @@ partition_router_explain(CustomScanState *node, List *ancestors, ExplainState *e
256243 * ----------------------------------------------------------------
257244 */
258245
259- static bool
260- ExecDeleteInternal (ItemPointer tupleid ,
246+ static TupleTableSlot *
247+ ExecDeleteInternal (TupleTableSlot * slot ,
248+ ItemPointer tupleid ,
261249 EPQState * epqstate ,
262250 EState * estate )
263251{
@@ -284,13 +272,15 @@ ExecDeleteInternal(ItemPointer tupleid,
284272 rri -> ri_TrigDesc -> trig_delete_before_row )
285273 {
286274 if (!ExecBRDeleteTriggers (estate , epqstate , rri , tupleid , NULL ))
287- return false ;
275+ return NULL ;
288276 }
289277
290278 if (tupleid != NULL )
291279 {
292- /* delete the tuple */
280+ EvalPlanQualSetSlot (epqstate , slot );
281+
293282ldelete :
283+ /* delete the tuple */
294284 result = heap_delete_compat (rel , tupleid ,
295285 estate -> es_output_cid ,
296286 estate -> es_crosscheck_snapshot ,
@@ -305,8 +295,8 @@ ExecDeleteInternal(ItemPointer tupleid,
305295 errmsg ("tuple to be updated was already modified by an operation triggered by the current command" ),
306296 errhint ("Consider using an AFTER trigger instead of a BEFORE trigger to propagate changes to other rows." )));
307297
308- /* Else, already deleted by self; nothing to do */
309- return false ;
298+ /* Already deleted by self; nothing to do */
299+ return NULL ;
310300
311301 case HeapTupleMayBeUpdated :
312302 break ;
@@ -333,12 +323,13 @@ ExecDeleteInternal(ItemPointer tupleid,
333323 {
334324 Assert (tupleid != NULL );
335325 * tupleid = hufd .ctid ;
326+ slot = epqslot ;
336327 goto ldelete ;
337328 }
338329 }
339330
340- /* tuple already deleted; nothing to do */
341- return false ;
331+ /* Tuple already deleted; nothing to do */
332+ return NULL ;
342333
343334 default :
344335 elog (ERROR , "unrecognized heap_delete status: %u" , result );
@@ -350,5 +341,5 @@ ExecDeleteInternal(ItemPointer tupleid,
350341 /* AFTER ROW DELETE triggers */
351342 ExecARDeleteTriggersCompat (estate , rri , tupleid , NULL , NULL );
352343
353- return true ;
344+ return slot ;
354345}
0 commit comments