Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit f18aa52

Browse files
committed
Fix updating using Overseer node (still has errors)
1 parent 0207c4e commit f18aa52

File tree

5 files changed

+104
-98
lines changed

5 files changed

+104
-98
lines changed

expected/pathman_update_node.out

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -15,29 +15,31 @@ SELECT create_range_partitions('test_update_node.test_range', 'val', 1, 10);
1515

1616
/* Moving from 2st to 1st partition */
1717
EXPLAIN (COSTS OFF) UPDATE test_update_node.test_range SET val = 5 WHERE val = 15;
18-
QUERY PLAN
19-
-------------------------------------------------------------------
20-
Update on test_range_2
21-
-> Custom Scan (PartitionFilter)
22-
-> Custom Scan (PartitionRouter)
23-
-> Bitmap Heap Scan on test_range_2
24-
Recheck Cond: (val = '15'::numeric)
25-
-> Bitmap Index Scan on test_range_2_val_idx
26-
Index Cond: (val = '15'::numeric)
27-
(7 rows)
18+
QUERY PLAN
19+
-------------------------------------------------------------------------
20+
Custom Scan (PartitionOverseer)
21+
-> Update on test_range_2
22+
-> Custom Scan (PartitionFilter)
23+
-> Custom Scan (PartitionRouter)
24+
-> Bitmap Heap Scan on test_range_2
25+
Recheck Cond: (val = '15'::numeric)
26+
-> Bitmap Index Scan on test_range_2_val_idx
27+
Index Cond: (val = '15'::numeric)
28+
(8 rows)
2829

2930
/* Keep same partition */
3031
EXPLAIN (COSTS OFF) UPDATE test_update_node.test_range SET val = 14 WHERE val = 15;
31-
QUERY PLAN
32-
-------------------------------------------------------------------
33-
Update on test_range_2
34-
-> Custom Scan (PartitionFilter)
35-
-> Custom Scan (PartitionRouter)
36-
-> Bitmap Heap Scan on test_range_2
37-
Recheck Cond: (val = '15'::numeric)
38-
-> Bitmap Index Scan on test_range_2_val_idx
39-
Index Cond: (val = '15'::numeric)
40-
(7 rows)
32+
QUERY PLAN
33+
-------------------------------------------------------------------------
34+
Custom Scan (PartitionOverseer)
35+
-> Update on test_range_2
36+
-> Custom Scan (PartitionFilter)
37+
-> Custom Scan (PartitionRouter)
38+
-> Bitmap Heap Scan on test_range_2
39+
Recheck Cond: (val = '15'::numeric)
40+
-> Bitmap Index Scan on test_range_2_val_idx
41+
Index Cond: (val = '15'::numeric)
42+
(8 rows)
4143

4244
/* Update values in 1st partition (rows remain there) */
4345
UPDATE test_update_node.test_range SET val = 5 WHERE val <= 10;

src/include/partition_router.h

Lines changed: 7 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -56,43 +56,27 @@ extern CustomScanMethods partition_router_plan_methods;
5656
extern CustomExecMethods partition_router_exec_methods;
5757

5858

59-
#define IsPartitionRouterPlan(node) \
60-
( \
61-
IsA((node), CustomScan) && \
62-
(((CustomScan *) (node))->methods == &partition_router_plan_methods) \
63-
)
64-
6559
#define IsPartitionRouterState(node) \
6660
( \
6761
IsA((node), CustomScanState) && \
6862
(((CustomScanState *) (node))->methods == &partition_router_exec_methods) \
6963
)
7064

71-
#define IsPartitionRouter(node) \
72-
( IsPartitionRouterPlan(node) || IsPartitionRouterState(node) )
73-
65+
/* Highlight hacks with ModifyTable's fields */
66+
#define MTHackField(mt_state, field) ( (mt_state)->field )
7467

7568
void init_partition_router_static_data(void);
76-
77-
Plan *make_partition_router(Plan *subplan, int epq_param);
78-
79-
void prepare_modify_table_for_partition_router(PlanState *state, void *context);
80-
81-
82-
Node *partition_router_create_scan_state(CustomScan *node);
83-
69+
void prepare_modify_table_for_partition_router(PlanState *state,
70+
void *context);
8471
void partition_router_begin(CustomScanState *node, EState *estate, int eflags);
85-
86-
TupleTableSlot *partition_router_exec(CustomScanState *node);
87-
8872
void partition_router_end(CustomScanState *node);
89-
9073
void partition_router_rescan(CustomScanState *node);
91-
9274
void partition_router_explain(CustomScanState *node,
9375
List *ancestors,
9476
ExplainState *es);
9577

96-
TupleTableSlot *partition_router_run_modify_table(PlanState *state);
78+
Plan *make_partition_router(Plan *subplan, int epq_param);
79+
Node *partition_router_create_scan_state(CustomScan *node);
80+
TupleTableSlot *partition_router_exec(CustomScanState *node);
9781

9882
#endif /* PARTITION_UPDATE_H */

src/partition_overseer.c

Lines changed: 64 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
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

78
CustomScanMethods partition_overseer_plan_methods;
89
CustomExecMethods 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+
6792
void
6893
partition_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

79109
TupleTableSlot *
80110
partition_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

86146
void
@@ -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
}

src/partition_router.c

Lines changed: 0 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,6 @@
2626
#include "utils/rel.h"
2727

2828

29-
/* Highlight hacks with ModifyTable's fields */
30-
#define MTHackField(mt_state, field) ( (mt_state)->field )
31-
32-
3329
#define MTDisableStmtTriggers(mt_state, pr_state) \
3430
do { \
3531
TriggerDesc *triggers = (mt_state)->resultRelInfo->ri_TrigDesc; \
@@ -143,7 +139,6 @@ partition_router_create_scan_state(CustomScan *node)
143139
state = (PartitionRouterState *) palloc0(sizeof(PartitionRouterState));
144140
NodeSetTag(state, T_CustomScanState);
145141

146-
state = (PartitionRouterState *) makeNode(CustomScanState);
147142
state->css.flags = node->flags;
148143
state->css.methods = &partition_router_exec_methods;
149144

@@ -246,46 +241,6 @@ partition_router_explain(CustomScanState *node,
246241
/* Nothing to do here now */
247242
}
248243

249-
250-
/* Smart wrapper over ModifyTable */
251-
TupleTableSlot *
252-
partition_router_run_modify_table(PlanState *state)
253-
{
254-
ModifyTableState *mt_state;
255-
TupleTableSlot *slot;
256-
int mt_plans_old,
257-
mt_plans_new;
258-
259-
mt_state = (ModifyTableState *) state;
260-
261-
/* Get initial signal */
262-
mt_plans_old = mt_state->mt_nplans;
263-
264-
restart:
265-
/* Fetch next tuple */
266-
slot = ExecProcNode(state);
267-
268-
/* Get current signal */
269-
mt_plans_new = MTHackField(mt_state, mt_nplans);
270-
271-
/* Did PartitionRouter ask us to restart? */
272-
if (mt_plans_new != mt_plans_old)
273-
{
274-
/* Signal points to current plan */
275-
int state_idx = -mt_plans_new;
276-
277-
/* HACK: partially restore ModifyTable's state */
278-
MTHackField(mt_state, mt_done) = false;
279-
MTHackField(mt_state, mt_nplans) = mt_plans_old;
280-
MTHackField(mt_state, mt_whichplan) = state_idx;
281-
282-
/* Restart ModifyTable */
283-
goto restart;
284-
}
285-
286-
return slot;
287-
}
288-
289244
/* Return tuple OR yield it and change ModifyTable's operation */
290245
static TupleTableSlot *
291246
router_set_slot(PartitionRouterState *state,

src/planner_tree_modification.c

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -765,11 +765,12 @@ partition_filter_visitor(Plan *plan, void *context)
765765
static Plan *
766766
partition_router_visitor(Plan *plan, void *context)
767767
{
768-
List *rtable = (List *) context;
769-
ModifyTable *modify_table = (ModifyTable *) plan;
770-
ListCell *lc1,
771-
*lc2,
772-
*lc3;
768+
List *rtable = (List *) context;
769+
ModifyTable *modify_table = (ModifyTable *) plan;
770+
ListCell *lc1,
771+
*lc2,
772+
*lc3;
773+
bool changed = false;
773774

774775
/* Skip if not ModifyTable with 'UPDATE' command */
775776
if (!IsA(modify_table, ModifyTable) || modify_table->operation != CMD_UPDATE)
@@ -821,10 +822,14 @@ partition_router_visitor(Plan *plan, void *context)
821822
returning_list);
822823

823824
lfirst(lc1) = pfilter;
825+
changed = true;
824826
}
825827
}
826828

827-
return make_partition_overseer(plan);
829+
if (changed)
830+
return make_partition_overseer(plan);
831+
832+
return NULL;
828833
}
829834

830835

0 commit comments

Comments
 (0)