Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitc0e3513

Browse files
committed
WIP more fixes in EPQ handling
1 parentd1255a5 commitc0e3513

6 files changed

+83
-88
lines changed

‎src/hooks.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -987,8 +987,9 @@ pathman_executor_hook(QueryDesc *queryDesc,
987987
{
988988
CustomScanState*pr_state= (CustomScanState*)mt_state->mt_plans[i];
989989

990-
/* Check if this is a PartitionRouter node */
991-
if (IsPartitionRouterState(pr_state))
990+
/* Check if this is a PartitionFilter + PartitionRouter combo */
991+
if (IsPartitionFilterState(pr_state)&&
992+
IsPartitionRouterState(linitial(pr_state->custom_ps)))
992993
{
993994
ResultRelInfo*rri=&mt_state->resultRelInfo[i];
994995

‎src/include/partition_filter.h

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -108,9 +108,6 @@ typedef struct
108108
ResultPartsStorageresult_parts;/* partition ResultRelInfo cache */
109109
CmdTypecommand_type;
110110

111-
boolwarning_triggered;/* warning message counter */
112-
113-
TupleTableSlot*subplan_slot;/* slot that was returned from subplan */
114111
TupleTableSlot*tup_convert_slot;/* slot for rebuilt tuples */
115112
}PartitionFilterState;
116113

@@ -170,6 +167,8 @@ PartRelationInfo * refresh_result_parts_storage(ResultPartsStorage *parts_storag
170167

171168
TupleConversionMap*build_part_tuple_map(Relationparent_rel,Relationchild_rel);
172169

170+
List*pfilter_build_tlist(Plan*subplan);
171+
173172

174173
/* Find suitable partition using 'value' */
175174
Oid*find_partitions_for_value(Datumvalue,Oidvalue_type,
@@ -183,8 +182,8 @@ Plan * make_partition_filter(Plan *subplan,
183182
Oidparent_relid,
184183
Indexparent_rti,
185184
OnConflictActionconflict_action,
186-
List*returning_list,
187-
CmdTypecommand_type);
185+
CmdTypecommand_type,
186+
List*returning_list);
188187

189188

190189
Node*partition_filter_create_scan_state(CustomScan*node);

‎src/include/partition_router.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,13 @@ typedef struct PartitionRouterState
3131
CustomScanStatecss;
3232

3333
Oidpartitioned_table;
34-
JunkFilter*junkfilter;
34+
Plan*subplan;/* proxy variable to store subplan */
35+
JunkFilter*junkfilter;/* 'ctid' extraction facility */
36+
3537
EPQStateepqstate;
3638
intepqparam;
37-
Plan*subplan;/* proxy variable to store subplan */
39+
40+
ResultRelInfo*current_rri;
3841
}PartitionRouterState;
3942

4043

‎src/partition_filter.c

Lines changed: 10 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include"partition_filter.h"
1717
#include"utils.h"
1818

19+
#include"access/htup_details.h"
1920
#include"catalog/pg_class.h"
2021
#include"catalog/pg_type.h"
2122
#include"foreign/fdwapi.h"
@@ -87,8 +88,6 @@ static Node *fix_returning_list_mutator(Node *node, void *state);
8788
staticIndexappend_rte_to_estate(EState*estate,RangeTblEntry*rte);
8889
staticintappend_rri_to_estate(EState*estate,ResultRelInfo*rri);
8990

90-
staticList*pfilter_build_tlist(Plan*subplan);
91-
9291
staticvoidpf_memcxt_callback(void*arg);
9392
staticestate_mod_data*fetch_estate_mod_data(EState*estate);
9493

@@ -633,8 +632,8 @@ make_partition_filter(Plan *subplan,
633632
Oidparent_relid,
634633
Indexparent_rti,
635634
OnConflictActionconflict_action,
636-
List*returning_list,
637-
CmdTypecommand_type)
635+
CmdTypecommand_type,
636+
List*returning_list)
638637
{
639638
CustomScan*cscan=makeNode(CustomScan);
640639

@@ -723,9 +722,6 @@ partition_filter_begin(CustomScanState *node, EState *estate, int eflags)
723722
state->on_conflict_action!=ONCONFLICT_NONE,
724723
RPS_RRI_CB(prepare_rri_for_insert,state),
725724
RPS_RRI_CB(NULL,NULL));
726-
727-
/* No warnings yet */
728-
state->warning_triggered= false;
729725
}
730726

731727
TupleTableSlot*
@@ -739,16 +735,12 @@ partition_filter_exec(CustomScanState *node)
739735
TupleTableSlot*slot;
740736

741737
slot=ExecProcNode(child_ps);
742-
state->subplan_slot=slot;
743-
744-
if (state->tup_convert_slot)
745-
ExecClearTuple(state->tup_convert_slot);
746738

747739
if (!TupIsNull(slot))
748740
{
749741
MemoryContextold_mcxt;
750742
ResultRelInfoHolder*rri_holder;
751-
ResultRelInfo*resultRelInfo;
743+
ResultRelInfo*rri;
752744

753745
/* Switch to per-tuple context */
754746
old_mcxt=MemoryContextSwitchTo(GetPerTupleMemoryContext(estate));
@@ -760,30 +752,28 @@ partition_filter_exec(CustomScanState *node)
760752
MemoryContextSwitchTo(old_mcxt);
761753
ResetExprContext(econtext);
762754

763-
resultRelInfo=rri_holder->result_rel_info;
755+
rri=rri_holder->result_rel_info;
764756

765757
/* Magic: replace parent's ResultRelInfo with ours */
766-
estate->es_result_relation_info=resultRelInfo;
758+
estate->es_result_relation_info=rri;
767759

768760
/* If there's a transform map, rebuild the tuple */
769761
if (rri_holder->tuple_map)
770762
{
771763
HeapTuplehtup_old,
772764
htup_new;
773-
Relationchild_rel=resultRelInfo->ri_RelationDesc;
765+
Relationchild_rel=rri->ri_RelationDesc;
774766

775767
htup_old=ExecMaterializeSlot(slot);
776768
htup_new=do_convert_tuple(htup_old,rri_holder->tuple_map);
769+
ExecClearTuple(slot);
777770

778771
/* Allocate new slot if needed */
779772
if (!state->tup_convert_slot)
780773
state->tup_convert_slot=MakeTupleTableSlotCompat();
781774

782775
ExecSetSlotDescriptor(state->tup_convert_slot,RelationGetDescr(child_rel));
783-
ExecStoreTuple(htup_new,state->tup_convert_slot,InvalidBuffer, true);
784-
785-
/* Now replace the original slot */
786-
slot=state->tup_convert_slot;
776+
slot=ExecStoreTuple(htup_new,state->tup_convert_slot,InvalidBuffer, true);
787777
}
788778

789779
returnslot;
@@ -826,7 +816,7 @@ partition_filter_explain(CustomScanState *node, List *ancestors, ExplainState *e
826816
/*
827817
* Build partition filter's target list pointing to subplan tuple's elements.
828818
*/
829-
staticList*
819+
List*
830820
pfilter_build_tlist(Plan*subplan)
831821
{
832822
List*result_tlist=NIL;

‎src/partition_router.c

Lines changed: 42 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,10 @@ boolpg_pathman_enable_partition_router = true;
2828
CustomScanMethodspartition_router_plan_methods;
2929
CustomExecMethodspartition_router_exec_methods;
3030

31-
staticboolExecDeleteInternal(ItemPointertupleid,
32-
EPQState*epqstate,
33-
EState*estate);
31+
staticTupleTableSlot*ExecDeleteInternal(TupleTableSlot*slot,
32+
ItemPointertupleid,
33+
EPQState*epqstate,
34+
EState*estate);
3435

3536
void
3637
init_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-
charrelkind;
155-
ItemPointerDatactid;
146+
ResultRelInfo*current_rri=state->current_rri;
147+
charrelkind;
148+
ItemPointerDatactid;
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
Datumctid_datum;
184172
boolctid_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: replacecurrent ResultRelInfo withparent'sone (DELETE) */
210-
estate->es_result_relation_info=old_rri;
195+
/* Magic: replace parent'sResultRelInfo 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
gototake_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-
returnslot;
209+
returnExecFilterJunk(state->junkfilter,slot);
226210
}
227211

228212
returnNULL;
@@ -231,7 +215,10 @@ partition_router_exec(CustomScanState *node)
231215
void
232216
partition_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-
staticbool
260-
ExecDeleteInternal(ItemPointertupleid,
246+
staticTupleTableSlot*
247+
ExecDeleteInternal(TupleTableSlot*slot,
248+
ItemPointertupleid,
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-
returnfalse;
275+
returnNULL;
288276
}
289277

290278
if (tupleid!=NULL)
291279
{
292-
/* delete the tuple */
280+
EvalPlanQualSetSlot(epqstate,slot);
281+
293282
ldelete:
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-
returnfalse;
298+
/*Already deleted by self; nothing to do */
299+
returnNULL;
310300

311301
caseHeapTupleMayBeUpdated:
312302
break;
@@ -333,12 +323,13 @@ ExecDeleteInternal(ItemPointer tupleid,
333323
{
334324
Assert(tupleid!=NULL);
335325
*tupleid=hufd.ctid;
326+
slot=epqslot;
336327
gotoldelete;
337328
}
338329
}
339330

340-
/*tuple already deleted; nothing to do */
341-
returnfalse;
331+
/*Tuple already deleted; nothing to do */
332+
returnNULL;
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-
returntrue;
344+
returnslot;
354345
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp