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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy