Skip to content

Commit 719f2f5

Browse files
committed
add blank PartitionFilter node (replaces RuntimeInsert), move nodes' static initialization code to init_XXX_static_data()
1 parent e0b080f commit 719f2f5

11 files changed

+283
-104
lines changed

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# contrib/pg_pathman/Makefile
22

33
MODULE_big = pg_pathman
4-
OBJS = src/init.o src/utils.o src/runtimeappend.o src/runtime_merge_append.o src/pg_pathman.o src/dsm_array.o \
4+
OBJS = src/init.o src/utils.o src/partition_filter.o src/runtimeappend.o src/runtime_merge_append.o src/pg_pathman.o src/dsm_array.o \
55
src/rangeset.o src/pl_funcs.o src/worker.o src/hooks.o src/nodes_common.o $(WIN32RES)
66

77
EXTENSION = pg_pathman

src/hooks.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include "pathman.h"
1616
#include "runtimeappend.h"
1717
#include "runtime_merge_append.h"
18+
#include "partition_filter.h"
1819
#include "utils.h"
1920

2021

@@ -346,14 +347,16 @@ void pg_pathman_enable_assign_hook(bool newval, void *extra)
346347
/* Return quickly if nothing has changed */
347348
if (newval == (pg_pathman_enable &&
348349
pg_pathman_enable_runtimeappend &&
349-
pg_pathman_enable_runtime_merge_append))
350+
pg_pathman_enable_runtime_merge_append &&
351+
pg_pathman_enable_partition_filter))
350352
return;
351353

352354
pg_pathman_enable_runtime_merge_append = newval;
353355
pg_pathman_enable_runtimeappend = newval;
356+
pg_pathman_enable_partition_filter = newval;
354357

355358
elog(NOTICE,
356-
"RuntimeAppend and RuntimeMergeAppend nodes have been %s",
359+
"RuntimeAppend, RuntimeMergeAppend and PartitionFilter nodes have been %s",
357360
newval ? "enabled" : "disabled");
358361
}
359362

src/partition_filter.c

Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
#include "partition_filter.h"
2+
#include "utils/guc.h"
3+
4+
5+
bool pg_pathman_enable_partition_filter = true;
6+
7+
CustomScanMethods partition_filter_plan_methods;
8+
CustomExecMethods partition_filter_exec_methods;
9+
10+
11+
12+
void
13+
init_partition_filter_static_data(void)
14+
{
15+
partition_filter_plan_methods.CustomName = "PartitionFilter";
16+
partition_filter_plan_methods.CreateCustomScanState = partition_filter_create_scan_state;
17+
18+
partition_filter_exec_methods.CustomName = "PartitionFilter";
19+
partition_filter_exec_methods.BeginCustomScan = partition_filter_begin;
20+
partition_filter_exec_methods.ExecCustomScan = partition_filter_exec;
21+
partition_filter_exec_methods.EndCustomScan = partition_filter_end;
22+
partition_filter_exec_methods.ReScanCustomScan = partition_filter_rescan;
23+
partition_filter_exec_methods.MarkPosCustomScan = NULL;
24+
partition_filter_exec_methods.RestrPosCustomScan = NULL;
25+
partition_filter_exec_methods.ExplainCustomScan = partition_filter_explain;
26+
27+
DefineCustomBoolVariable("pg_pathman.enable_partitionfilter",
28+
"Enables the planner's use of PartitionFilter custom node.",
29+
NULL,
30+
&pg_pathman_enable_partition_filter,
31+
true,
32+
PGC_USERSET,
33+
0,
34+
NULL,
35+
NULL,
36+
NULL);
37+
}
38+
39+
Plan *
40+
create_partition_filter_plan(Plan *subplan, PartRelationInfo *prel)
41+
{
42+
CustomScan *cscan = makeNode(CustomScan);
43+
44+
cscan->scan.plan.startup_cost = subplan->startup_cost;
45+
cscan->scan.plan.total_cost = subplan->total_cost;
46+
cscan->scan.plan.plan_rows = subplan->plan_rows;
47+
cscan->scan.plan.plan_width = subplan->plan_width;
48+
49+
cscan->scan.plan.qual = NIL;
50+
51+
cscan->custom_plans = list_make1(subplan);
52+
53+
cscan->scan.plan.targetlist = subplan->targetlist;
54+
55+
/* No relation will be scanned */
56+
cscan->scan.scanrelid = 0;
57+
cscan->custom_scan_tlist = subplan->targetlist;
58+
59+
cscan->methods = &partition_filter_plan_methods;
60+
61+
return &cscan->scan.plan;
62+
}
63+
64+
Node *
65+
partition_filter_create_scan_state(CustomScan *node)
66+
{
67+
PartitionFilterState *state = palloc0(sizeof(PartitionFilterState));
68+
69+
NodeSetTag(state, T_CustomScanState);
70+
71+
state->css.flags = node->flags;
72+
state->css.methods = &partition_filter_exec_methods;
73+
74+
state->subplan = (Plan *) linitial(node->custom_plans);
75+
76+
return (Node *) state;
77+
}
78+
79+
void
80+
partition_filter_begin(CustomScanState *node, EState *estate, int eflags)
81+
{
82+
PartitionFilterState *state = (PartitionFilterState *) node;
83+
84+
node->custom_ps = list_make1(ExecInitNode(state->subplan, estate, eflags));
85+
86+
state->firstStart = true;
87+
}
88+
89+
TupleTableSlot *
90+
partition_filter_exec(CustomScanState *node)
91+
{
92+
PartitionFilterState *state = (PartitionFilterState *) node;
93+
94+
EState *estate = node->ss.ps.state;
95+
PlanState *child_ps = (PlanState *) linitial(node->custom_ps);
96+
TupleTableSlot *slot;
97+
98+
if (state->firstStart)
99+
state->savedRelInfo = estate->es_result_relation_info;
100+
101+
slot = ExecProcNode(child_ps);
102+
103+
if (!TupIsNull(slot))
104+
{
105+
/* estate->es_result_relation_info = NULL; */
106+
107+
return slot;
108+
}
109+
110+
return NULL;
111+
}
112+
113+
void
114+
partition_filter_end(CustomScanState *node)
115+
{
116+
Assert(list_length(node->custom_ps) == 1);
117+
118+
ExecEndNode((PlanState *) linitial(node->custom_ps));
119+
}
120+
121+
void
122+
partition_filter_rescan(CustomScanState *node)
123+
{
124+
Assert(list_length(node->custom_ps) == 1);
125+
126+
ExecReScan((PlanState *) linitial(node->custom_ps));
127+
}
128+
129+
void
130+
partition_filter_explain(CustomScanState *node, List *ancestors, ExplainState *es)
131+
{
132+
/* Nothing to do here now */
133+
}
134+
135+
/* Add proxy PartitionFilter nodes to subplans of ModifyTable node */
136+
void
137+
add_partition_filters(List *rtable, ModifyTable *modify_table)
138+
{
139+
ListCell *lc1,
140+
*lc2;
141+
142+
Assert(IsA(modify_table, ModifyTable));
143+
144+
if (!pg_pathman_enable_partition_filter)
145+
return;
146+
147+
forboth (lc1, modify_table->plans, lc2, modify_table->resultRelations)
148+
{
149+
Index rindex = lfirst_int(lc2);
150+
PartRelationInfo *prel = get_pathman_relation_info(getrelid(rindex, rtable),
151+
NULL);
152+
if (prel)
153+
lfirst(lc1) = create_partition_filter_plan((Plan *) lfirst(lc1), prel);
154+
}
155+
}

src/partition_filter.h

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
#ifndef RUNTIME_INSERT_H
2+
#define RUNTIME_INSERT_H
3+
4+
#include "postgres.h"
5+
#include "optimizer/paths.h"
6+
#include "optimizer/pathnode.h"
7+
8+
#include "pathman.h"
9+
#include "nodes_common.h"
10+
11+
12+
typedef struct
13+
{
14+
CustomScanState css;
15+
bool firstStart;
16+
ResultRelInfo *savedRelInfo;
17+
Plan *subplan;
18+
} PartitionFilterState;
19+
20+
21+
extern bool pg_pathman_enable_partition_filter;
22+
23+
extern CustomScanMethods partition_filter_plan_methods;
24+
extern CustomExecMethods partition_filter_exec_methods;
25+
26+
27+
void add_partition_filters(List *rtable, ModifyTable *modify_table);
28+
29+
void init_partition_filter_static_data(void);
30+
31+
Plan * create_partition_filter_plan(Plan *subplan, PartRelationInfo *prel);
32+
33+
Node * partition_filter_create_scan_state(CustomScan *node);
34+
35+
void partition_filter_begin(CustomScanState *node, EState *estate, int eflags);
36+
37+
TupleTableSlot * partition_filter_exec(CustomScanState *node);
38+
39+
void partition_filter_end(CustomScanState *node);
40+
41+
void partition_filter_rescan(CustomScanState *node);
42+
43+
void partition_filter_explain(CustomScanState *node, List *ancestors, ExplainState *es);
44+
45+
#endif

src/pg_pathman.c

Lines changed: 9 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
#include "hooks.h"
4343
#include "runtimeappend.h"
4444
#include "runtime_merge_append.h"
45+
#include "partition_filter.h"
4546

4647
PG_MODULE_MAGIC;
4748

@@ -159,37 +160,9 @@ _PG_init(void)
159160
planner_hook_original = planner_hook;
160161
planner_hook = pathman_planner_hook;
161162

162-
/* RuntimeAppend */
163-
runtimeappend_path_methods.CustomName = "RuntimeAppend";
164-
runtimeappend_path_methods.PlanCustomPath = create_runtimeappend_plan;
165-
166-
runtimeappend_plan_methods.CustomName = "RuntimeAppend";
167-
runtimeappend_plan_methods.CreateCustomScanState = runtimeappend_create_scan_state;
168-
169-
runtimeappend_exec_methods.CustomName = "RuntimeAppend";
170-
runtimeappend_exec_methods.BeginCustomScan = runtimeappend_begin;
171-
runtimeappend_exec_methods.ExecCustomScan = runtimeappend_exec;
172-
runtimeappend_exec_methods.EndCustomScan = runtimeappend_end;
173-
runtimeappend_exec_methods.ReScanCustomScan = runtimeappend_rescan;
174-
runtimeappend_exec_methods.MarkPosCustomScan = NULL;
175-
runtimeappend_exec_methods.RestrPosCustomScan = NULL;
176-
runtimeappend_exec_methods.ExplainCustomScan = runtimeappend_explain;
177-
178-
/* RuntimeMergeAppend */
179-
runtime_merge_append_path_methods.CustomName = "RuntimeMergeAppend";
180-
runtime_merge_append_path_methods.PlanCustomPath = create_runtimemergeappend_plan;
181-
182-
runtime_merge_append_plan_methods.CustomName = "RuntimeMergeAppend";
183-
runtime_merge_append_plan_methods.CreateCustomScanState = runtimemergeappend_create_scan_state;
184-
185-
runtime_merge_append_exec_methods.CustomName = "RuntimeMergeAppend";
186-
runtime_merge_append_exec_methods.BeginCustomScan = runtimemergeappend_begin;
187-
runtime_merge_append_exec_methods.ExecCustomScan = runtimemergeappend_exec;
188-
runtime_merge_append_exec_methods.EndCustomScan = runtimemergeappend_end;
189-
runtime_merge_append_exec_methods.ReScanCustomScan = runtimemergeappend_rescan;
190-
runtime_merge_append_exec_methods.MarkPosCustomScan = NULL;
191-
runtime_merge_append_exec_methods.RestrPosCustomScan = NULL;
192-
runtime_merge_append_exec_methods.ExplainCustomScan = runtimemergeappend_explain;
163+
init_runtimeappend_static_data();
164+
init_runtime_merge_append_static_data();
165+
init_partition_filter_static_data();
193166

194167
DefineCustomBoolVariable("pg_pathman.enable",
195168
"Enables pg_pathman's optimizations during the planner stage",
@@ -201,28 +174,6 @@ _PG_init(void)
201174
NULL,
202175
pg_pathman_enable_assign_hook,
203176
NULL);
204-
205-
DefineCustomBoolVariable("pg_pathman.enable_runtimeappend",
206-
"Enables the planner's use of RuntimeAppend custom node.",
207-
NULL,
208-
&pg_pathman_enable_runtimeappend,
209-
true,
210-
PGC_USERSET,
211-
0,
212-
NULL,
213-
NULL,
214-
NULL);
215-
216-
DefineCustomBoolVariable("pg_pathman.enable_runtimemergeappend",
217-
"Enables the planner's use of RuntimeMergeAppend custom node.",
218-
NULL,
219-
&pg_pathman_enable_runtime_merge_append,
220-
true,
221-
PGC_USERSET,
222-
0,
223-
NULL,
224-
NULL,
225-
NULL);
226177
}
227178

228179
PartRelationInfo *
@@ -301,6 +252,11 @@ pathman_planner_hook(Query *parse, int cursorOptions, ParamListInfo boundParams)
301252
disable_inheritance_subselect(parse);
302253
handle_modification_query(parse);
303254
break;
255+
case CMD_INSERT:
256+
result = standard_planner(parse, cursorOptions, boundParams);
257+
add_partition_filters(result->rtable,
258+
(ModifyTable *) result->planTree);
259+
return result;
304260
default:
305261
break;
306262
}

src/runtime_insert.c

Lines changed: 0 additions & 1 deletion
This file was deleted.

src/runtime_insert.h

Lines changed: 0 additions & 47 deletions
This file was deleted.

0 commit comments

Comments
 (0)