Skip to content

Commit 1b2bb7c

Browse files
committed
initial release of PartitionFilter node
1 parent 4eb7f3d commit 1b2bb7c

File tree

6 files changed

+314
-165
lines changed

6 files changed

+314
-165
lines changed

src/nodes_common.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ select_required_plans(HTAB *children_table, Oid *parts, int nparts, int *nres)
105105
}
106106

107107
/* Transform partition ranges into plain array of partition Oids */
108-
static Oid *
108+
Oid *
109109
get_partition_oids(List *ranges, int *n, PartRelationInfo *prel)
110110
{
111111
ListCell *range_cell;

src/nodes_common.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ clear_plan_states(CustomScanState *scan_state)
5151
}
5252
}
5353

54+
Oid * get_partition_oids(List *ranges, int *n, PartRelationInfo *prel);
55+
5456
Path * create_append_path_common(PlannerInfo *root,
5557
AppendPath *inner_append,
5658
ParamPathInfo *param_info,

src/partition_filter.c

Lines changed: 81 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ CustomExecMethods partition_filter_exec_methods;
1010

1111

1212
static List * pfilter_build_tlist(List *tlist);
13+
static ResultRelInfo * getResultRelInfo(Oid partid, PartitionFilterState *state);
1314

1415
void
1516
init_partition_filter_static_data(void)
@@ -39,7 +40,8 @@ init_partition_filter_static_data(void)
3940
}
4041

4142
Plan *
42-
make_partition_filter_plan(Plan *subplan, PartRelationInfo *prel)
43+
make_partition_filter_plan(Plan *subplan, Oid partitioned_table,
44+
OnConflictAction conflict_action)
4345
{
4446
CustomScan *cscan = makeNode(CustomScan);
4547

@@ -57,8 +59,9 @@ make_partition_filter_plan(Plan *subplan, PartRelationInfo *prel)
5759
cscan->scan.scanrelid = 0;
5860
cscan->custom_scan_tlist = subplan->targetlist;
5961

60-
/* Save partitioned table's Oid */
61-
cscan->custom_private = list_make1_int(prel->key.relid);
62+
/* Pack partitioned table's Oid and conflict_action */
63+
cscan->custom_private = list_make2_int(partitioned_table,
64+
conflict_action);
6265

6366
return &cscan->scan.plan;
6467
}
@@ -76,6 +79,11 @@ partition_filter_create_scan_state(CustomScan *node)
7679
/* Extract necessary variables */
7780
state->subplan = (Plan *) linitial(node->custom_plans);
7881
state->partitioned_table = linitial_int(node->custom_private);
82+
state->onConflictAction = lsecond_int(node->custom_private);
83+
84+
/* Check boundaries */
85+
Assert(state->onConflictAction >= ONCONFLICT_NONE ||
86+
state->onConflictAction <= ONCONFLICT_UPDATE);
7987

8088
/* Prepare dummy Const node */
8189
NodeSetTag(&state->temp_const, T_Const);
@@ -89,9 +97,21 @@ partition_filter_begin(CustomScanState *node, EState *estate, int eflags)
8997
{
9098
PartitionFilterState *state = (PartitionFilterState *) node;
9199

100+
HTAB *result_rels_table;
101+
HASHCTL *result_rels_table_config = &state->result_rels_table_config;
102+
92103
node->custom_ps = list_make1(ExecInitNode(state->subplan, estate, eflags));
93104
state->prel = get_pathman_relation_info(state->partitioned_table, NULL);
94-
state->firstStart = true;
105+
106+
memset(result_rels_table_config, 0, sizeof(HASHCTL));
107+
result_rels_table_config->keysize = sizeof(Oid);
108+
result_rels_table_config->entrysize = sizeof(ResultRelInfoHandle);
109+
110+
result_rels_table = hash_create("ResultRelInfo storage", 10,
111+
result_rels_table_config,
112+
HASH_ELEM | HASH_BLOBS);
113+
114+
state->result_rels_table = result_rels_table;
95115
}
96116

97117
TupleTableSlot *
@@ -107,14 +127,15 @@ partition_filter_exec(CustomScanState *node)
107127
PlanState *child_ps = (PlanState *) linitial(node->custom_ps);
108128
TupleTableSlot *slot;
109129

110-
if (state->firstStart)
111-
state->savedRelInfo = estate->es_result_relation_info;
112-
113130
slot = ExecProcNode(child_ps);
114131

115132
if (!TupIsNull(slot))
116133
{
117134
WalkerContext wcxt;
135+
List *ranges;
136+
int nparts;
137+
Oid *parts;
138+
118139
bool isnull;
119140
AttrNumber attnum = state->prel->attnum;
120141
Datum value = slot_getattr(slot, attnum, &isnull);
@@ -133,9 +154,11 @@ partition_filter_exec(CustomScanState *node)
133154
wcxt.hasLeast = false;
134155
wcxt.hasGreatest = false;
135156

136-
walk_expr_tree((Expr *) &state->temp_const, &wcxt);
157+
ranges = walk_expr_tree((Expr *) &state->temp_const, &wcxt)->rangeset;
158+
parts = get_partition_oids(ranges, &nparts, state->prel);
159+
Assert(nparts == 1); /* there has to be only 1 partition */
137160

138-
/* estate->es_result_relation_info = NULL; */
161+
estate->es_result_relation_info = getResultRelInfo(parts[0], state);
139162

140163
return slot;
141164
}
@@ -146,8 +169,22 @@ partition_filter_exec(CustomScanState *node)
146169
void
147170
partition_filter_end(CustomScanState *node)
148171
{
149-
Assert(list_length(node->custom_ps) == 1);
172+
PartitionFilterState *state = (PartitionFilterState *) node;
173+
174+
HASH_SEQ_STATUS stat;
175+
ResultRelInfoHandle *rri_handle;
176+
177+
hash_seq_init(&stat, state->result_rels_table);
178+
while ((rri_handle = (ResultRelInfoHandle *) hash_seq_search(&stat)) != NULL)
179+
{
180+
ExecCloseIndices(rri_handle->resultRelInfo);
181+
heap_close(rri_handle->resultRelInfo->ri_RelationDesc,
182+
RowExclusiveLock);
183+
}
184+
185+
hash_destroy(state->result_rels_table);
150186

187+
Assert(list_length(node->custom_ps) == 1);
151188
ExecEndNode((PlanState *) linitial(node->custom_ps));
152189
}
153190

@@ -165,6 +202,34 @@ partition_filter_explain(CustomScanState *node, List *ancestors, ExplainState *e
165202
/* Nothing to do here now */
166203
}
167204

205+
206+
static ResultRelInfo *
207+
getResultRelInfo(Oid partid, PartitionFilterState *state)
208+
{
209+
ResultRelInfoHandle *resultRelInfoHandle;
210+
bool found;
211+
212+
resultRelInfoHandle = hash_search(state->result_rels_table,
213+
(const void *) &partid,
214+
HASH_ENTER, &found);
215+
216+
if (!found)
217+
{
218+
ResultRelInfo *resultRelInfo = (ResultRelInfo *) palloc(sizeof(ResultRelInfo));
219+
InitResultRelInfo(resultRelInfo,
220+
heap_open(partid, RowExclusiveLock),
221+
0,
222+
state->css.ss.ps.state->es_instrument);
223+
224+
ExecOpenIndices(resultRelInfo, state->onConflictAction != ONCONFLICT_NONE);
225+
226+
resultRelInfoHandle->partid = partid;
227+
resultRelInfoHandle->resultRelInfo = resultRelInfo;
228+
}
229+
230+
return resultRelInfoHandle->resultRelInfo;
231+
}
232+
168233
/*
169234
* Build partition filter's target list pointing to subplan tuple's elements
170235
*/
@@ -212,9 +277,12 @@ add_partition_filters(List *rtable, ModifyTable *modify_table)
212277
forboth (lc1, modify_table->plans, lc2, modify_table->resultRelations)
213278
{
214279
Index rindex = lfirst_int(lc2);
215-
PartRelationInfo *prel = get_pathman_relation_info(getrelid(rindex, rtable),
216-
NULL);
280+
Oid relid = getrelid(rindex, rtable);
281+
PartRelationInfo *prel = get_pathman_relation_info(relid, NULL);
282+
217283
if (prel)
218-
lfirst(lc1) = make_partition_filter_plan((Plan *) lfirst(lc1), prel);
284+
lfirst(lc1) = make_partition_filter_plan((Plan *) lfirst(lc1),
285+
relid,
286+
modify_table->onConflictAction);
219287
}
220288
}

src/partition_filter.h

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,18 +9,25 @@
99
#include "nodes_common.h"
1010

1111

12+
typedef struct
13+
{
14+
Oid partid;
15+
ResultRelInfo *resultRelInfo;
16+
} ResultRelInfoHandle;
17+
1218
typedef struct
1319
{
1420
CustomScanState css;
15-
bool firstStart;
16-
ResultRelInfo *savedRelInfo;
1721

1822
Oid partitioned_table;
1923
PartRelationInfo *prel;
24+
OnConflictAction onConflictAction;
2025

2126
Plan *subplan;
2227
Const temp_const; /* temporary const for expr walker */
2328

29+
HTAB *result_rels_table;
30+
HASHCTL result_rels_table_config;
2431
} PartitionFilterState;
2532

2633

@@ -34,7 +41,8 @@ void add_partition_filters(List *rtable, ModifyTable *modify_table);
3441

3542
void init_partition_filter_static_data(void);
3643

37-
Plan * make_partition_filter_plan(Plan *subplan, PartRelationInfo *prel);
44+
Plan * make_partition_filter_plan(Plan *subplan, Oid partitioned_table,
45+
OnConflictAction conflict_action);
3846

3947
Node * partition_filter_create_scan_state(CustomScan *node);
4048

src/pathman.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,10 @@ typedef struct
227227
ExprContext *econtext;
228228
} WalkerContext;
229229

230+
bool search_range_partition(Datum value,
231+
const PartRelationInfo *prel, const RangeRelation *rangerel,
232+
int strategy, FmgrInfo *cmp_func, WrapperNode *result);
233+
230234
WrapperNode *walk_expr_tree(Expr *expr, WalkerContext *context);
231235
void finish_least_greatest(WrapperNode *wrap, WalkerContext *context);
232236

0 commit comments

Comments
 (0)