11#include "postgres.h"
22
3- #include "partition_overseer.h"
43#include "partition_filter.h"
4+ #include "partition_overseer.h"
55#include "partition_router.h"
6+ #include "planner_tree_modification.h"
67
78CustomScanMethods partition_overseer_plan_methods ;
89CustomExecMethods partition_overseer_exec_methods ;
@@ -64,6 +65,30 @@ partition_overseer_create_scan_state(CustomScan *node)
6465 return (Node * ) state ;
6566}
6667
68+ static void
69+ set_mt_state_for_router (PlanState * state , void * context )
70+ {
71+ if (IsA (state , ModifyTableState ))
72+ {
73+ ModifyTableState * mt_state = (ModifyTableState * ) state ;
74+ int i ;
75+
76+ for (i = 0 ; i < mt_state -> mt_nplans ; i ++ )
77+ {
78+ CustomScanState * pf_state = (CustomScanState * ) mt_state -> mt_plans [i ];
79+ PartitionRouterState * pr_state ;
80+
81+ /* Check if this is a PartitionFilter + PartitionRouter combo */
82+ if (IsPartitionFilterState (pf_state ) &&
83+ IsPartitionRouterState (pr_state = linitial (pf_state -> custom_ps )))
84+ {
85+ /* HACK: point to ModifyTable in PartitionRouter */
86+ pr_state -> mt_state = mt_state ;
87+ }
88+ }
89+ }
90+ }
91+
6792void
6893partition_overseer_begin (CustomScanState * node ,
6994 EState * estate ,
@@ -74,13 +99,48 @@ partition_overseer_begin(CustomScanState *node,
7499
75100 /* It's convenient to store PlanState in 'custom_ps' */
76101 node -> custom_ps = list_make1 (ExecInitNode (plan , estate , eflags ));
102+
103+ /* Save ModifyTableState in PartitionRouterState structs */
104+ state_tree_visitor ((PlanState * ) linitial (node -> custom_ps ),
105+ set_mt_state_for_router ,
106+ NULL );
77107}
78108
79109TupleTableSlot *
80110partition_overseer_exec (CustomScanState * node )
81111{
82- PlanState * state = linitial (node -> custom_ps );
83- return partition_router_run_modify_table (state );
112+ ModifyTableState * mt_state = linitial (node -> custom_ps );
113+
114+ TupleTableSlot * slot ;
115+ int mt_plans_old ,
116+ mt_plans_new ;
117+
118+ /* Get initial signal */
119+ mt_plans_old = mt_state -> mt_nplans ;
120+
121+ restart :
122+ /* Fetch next tuple */
123+ slot = ExecProcNode ((PlanState * ) mt_state );
124+
125+ /* Get current signal */
126+ mt_plans_new = MTHackField (mt_state , mt_nplans );
127+
128+ /* Did PartitionRouter ask us to restart? */
129+ if (mt_plans_new != mt_plans_old )
130+ {
131+ /* Signal points to current plan */
132+ int state_idx = - mt_plans_new ;
133+
134+ /* HACK: partially restore ModifyTable's state */
135+ MTHackField (mt_state , mt_done ) = false;
136+ MTHackField (mt_state , mt_nplans ) = mt_plans_old ;
137+ MTHackField (mt_state , mt_whichplan ) = state_idx ;
138+
139+ /* Restart ModifyTable */
140+ goto restart ;
141+ }
142+
143+ return slot ;
84144}
85145
86146void
@@ -101,5 +161,5 @@ partition_overseer_explain(CustomScanState *node,
101161 List * ancestors ,
102162 ExplainState * es )
103163{
104- /* nothing to do */
164+ /* Nothing to do here now */
105165}
0 commit comments