Skip to content

Commit 4eb7f3d

Browse files
committed
PartitionFilter can be executed
1 parent 719f2f5 commit 4eb7f3d

File tree

2 files changed

+85
-14
lines changed

2 files changed

+85
-14
lines changed

src/partition_filter.c

Lines changed: 78 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#include "partition_filter.h"
22
#include "utils/guc.h"
3+
#include "nodes/nodeFuncs.h"
34

45

56
bool pg_pathman_enable_partition_filter = true;
@@ -8,6 +9,7 @@ CustomScanMethods partition_filter_plan_methods;
89
CustomExecMethods partition_filter_exec_methods;
910

1011

12+
static List * pfilter_build_tlist(List *tlist);
1113

1214
void
1315
init_partition_filter_static_data(void)
@@ -37,7 +39,7 @@ init_partition_filter_static_data(void)
3739
}
3840

3941
Plan *
40-
create_partition_filter_plan(Plan *subplan, PartRelationInfo *prel)
42+
make_partition_filter_plan(Plan *subplan, PartRelationInfo *prel)
4143
{
4244
CustomScan *cscan = makeNode(CustomScan);
4345

@@ -46,54 +48,64 @@ create_partition_filter_plan(Plan *subplan, PartRelationInfo *prel)
4648
cscan->scan.plan.plan_rows = subplan->plan_rows;
4749
cscan->scan.plan.plan_width = subplan->plan_width;
4850

49-
cscan->scan.plan.qual = NIL;
50-
51+
cscan->methods = &partition_filter_plan_methods;
5152
cscan->custom_plans = list_make1(subplan);
5253

53-
cscan->scan.plan.targetlist = subplan->targetlist;
54+
cscan->scan.plan.targetlist = pfilter_build_tlist(subplan->targetlist);
5455

5556
/* No relation will be scanned */
5657
cscan->scan.scanrelid = 0;
5758
cscan->custom_scan_tlist = subplan->targetlist;
5859

59-
cscan->methods = &partition_filter_plan_methods;
60+
/* Save partitioned table's Oid */
61+
cscan->custom_private = list_make1_int(prel->key.relid);
6062

6163
return &cscan->scan.plan;
6264
}
6365

6466
Node *
6567
partition_filter_create_scan_state(CustomScan *node)
6668
{
67-
PartitionFilterState *state = palloc0(sizeof(PartitionFilterState));
69+
PartitionFilterState *state = palloc0(sizeof(PartitionFilterState));
6870

6971
NodeSetTag(state, T_CustomScanState);
7072

7173
state->css.flags = node->flags;
7274
state->css.methods = &partition_filter_exec_methods;
7375

76+
/* Extract necessary variables */
7477
state->subplan = (Plan *) linitial(node->custom_plans);
78+
state->partitioned_table = linitial_int(node->custom_private);
79+
80+
/* Prepare dummy Const node */
81+
NodeSetTag(&state->temp_const, T_Const);
82+
state->temp_const.location = -1;
7583

7684
return (Node *) state;
7785
}
7886

7987
void
8088
partition_filter_begin(CustomScanState *node, EState *estate, int eflags)
8189
{
82-
PartitionFilterState *state = (PartitionFilterState *) node;
90+
PartitionFilterState *state = (PartitionFilterState *) node;
8391

8492
node->custom_ps = list_make1(ExecInitNode(state->subplan, estate, eflags));
85-
93+
state->prel = get_pathman_relation_info(state->partitioned_table, NULL);
8694
state->firstStart = true;
8795
}
8896

8997
TupleTableSlot *
9098
partition_filter_exec(CustomScanState *node)
9199
{
92-
PartitionFilterState *state = (PartitionFilterState *) node;
100+
#define CopyToTempConst(const_field, attr_field) \
101+
( state->temp_const.const_field = \
102+
slot->tts_tupleDescriptor->attrs[attnum - 1]->attr_field )
93103

94-
EState *estate = node->ss.ps.state;
95-
PlanState *child_ps = (PlanState *) linitial(node->custom_ps);
96-
TupleTableSlot *slot;
104+
PartitionFilterState *state = (PartitionFilterState *) node;
105+
106+
EState *estate = node->ss.ps.state;
107+
PlanState *child_ps = (PlanState *) linitial(node->custom_ps);
108+
TupleTableSlot *slot;
97109

98110
if (state->firstStart)
99111
state->savedRelInfo = estate->es_result_relation_info;
@@ -102,6 +114,27 @@ partition_filter_exec(CustomScanState *node)
102114

103115
if (!TupIsNull(slot))
104116
{
117+
WalkerContext wcxt;
118+
bool isnull;
119+
AttrNumber attnum = state->prel->attnum;
120+
Datum value = slot_getattr(slot, attnum, &isnull);
121+
122+
state->temp_const.constvalue = value;
123+
state->temp_const.constisnull = isnull;
124+
125+
CopyToTempConst(consttype, atttypid);
126+
CopyToTempConst(consttypmod, atttypmod);
127+
CopyToTempConst(constcollid, attcollation);
128+
CopyToTempConst(constlen, attlen);
129+
CopyToTempConst(constbyval, attbyval);
130+
131+
wcxt.prel = state->prel;
132+
wcxt.econtext = NULL;
133+
wcxt.hasLeast = false;
134+
wcxt.hasGreatest = false;
135+
136+
walk_expr_tree((Expr *) &state->temp_const, &wcxt);
137+
105138
/* estate->es_result_relation_info = NULL; */
106139

107140
return slot;
@@ -132,6 +165,38 @@ partition_filter_explain(CustomScanState *node, List *ancestors, ExplainState *e
132165
/* Nothing to do here now */
133166
}
134167

168+
/*
169+
* Build partition filter's target list pointing to subplan tuple's elements
170+
*/
171+
static List *
172+
pfilter_build_tlist(List *tlist)
173+
{
174+
List *result_tlist = NIL;
175+
ListCell *lc;
176+
int i = 1;
177+
178+
foreach (lc, tlist)
179+
{
180+
TargetEntry *tle = (TargetEntry *) lfirst(lc);
181+
182+
Var *var = makeVar(INDEX_VAR, /* point to subplan's elements */
183+
i, /* direct attribute mapping */
184+
exprType((Node *) tle->expr),
185+
exprTypmod((Node *) tle->expr),
186+
exprCollation((Node *) tle->expr),
187+
0);
188+
189+
result_tlist = lappend(result_tlist,
190+
makeTargetEntry((Expr *) var,
191+
i,
192+
NULL,
193+
tle->resjunk));
194+
i++; /* next resno */
195+
}
196+
197+
return result_tlist;
198+
}
199+
135200
/* Add proxy PartitionFilter nodes to subplans of ModifyTable node */
136201
void
137202
add_partition_filters(List *rtable, ModifyTable *modify_table)
@@ -150,6 +215,6 @@ add_partition_filters(List *rtable, ModifyTable *modify_table)
150215
PartRelationInfo *prel = get_pathman_relation_info(getrelid(rindex, rtable),
151216
NULL);
152217
if (prel)
153-
lfirst(lc1) = create_partition_filter_plan((Plan *) lfirst(lc1), prel);
218+
lfirst(lc1) = make_partition_filter_plan((Plan *) lfirst(lc1), prel);
154219
}
155220
}

src/partition_filter.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,13 @@ typedef struct
1414
CustomScanState css;
1515
bool firstStart;
1616
ResultRelInfo *savedRelInfo;
17+
18+
Oid partitioned_table;
19+
PartRelationInfo *prel;
20+
1721
Plan *subplan;
22+
Const temp_const; /* temporary const for expr walker */
23+
1824
} PartitionFilterState;
1925

2026

@@ -28,7 +34,7 @@ void add_partition_filters(List *rtable, ModifyTable *modify_table);
2834

2935
void init_partition_filter_static_data(void);
3036

31-
Plan * create_partition_filter_plan(Plan *subplan, PartRelationInfo *prel);
37+
Plan * make_partition_filter_plan(Plan *subplan, PartRelationInfo *prel);
3238

3339
Node * partition_filter_create_scan_state(CustomScan *node);
3440

0 commit comments

Comments
 (0)