Skip to content

Commit 9fd99a3

Browse files
committed
add ResultRelInfos for partitions to estate->es_result_relations with append_rri_to_estate(), add 'close_rels' param to fini_result_parts_storage(), don't close partitions till xact end after INSERT, fixes
1 parent 4d154b4 commit 9fd99a3

File tree

5 files changed

+94
-46
lines changed

5 files changed

+94
-46
lines changed

src/copy_stmt_hooking.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -516,7 +516,9 @@ PathmanCopyFrom(CopyState cstate, Relation parent_rel,
516516
pfree(nulls);
517517

518518
ExecResetTupleTable(estate->es_tupleTable, false);
519-
fini_result_parts_storage(&parts_storage);
519+
520+
/* Close partitions and destroy hash table */
521+
fini_result_parts_storage(&parts_storage, true);
520522

521523
FreeExecutorState(estate);
522524

src/nodes_common.c

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,8 @@ transform_plans_into_states(RuntimeAppendState *scan_state,
8484
static ChildScanCommon *
8585
select_required_plans(HTAB *children_table, Oid *parts, int nparts, int *nres)
8686
{
87-
int allocated = INITIAL_ALLOC_NUM;
88-
int used = 0;
87+
uint32 allocated = INITIAL_ALLOC_NUM,
88+
used = 0;
8989
ChildScanCommon *result;
9090
int i;
9191

@@ -101,7 +101,7 @@ select_required_plans(HTAB *children_table, Oid *parts, int nparts, int *nres)
101101

102102
if (allocated <= used)
103103
{
104-
allocated *= ALLOC_EXP;
104+
allocated = allocated * ALLOC_EXP + 1;
105105
result = repalloc(result, allocated * sizeof(ChildScanCommon));
106106
}
107107

@@ -289,8 +289,8 @@ get_partition_oids(List *ranges, int *n, const PartRelationInfo *prel,
289289
bool include_parent)
290290
{
291291
ListCell *range_cell;
292-
uint32 allocated = INITIAL_ALLOC_NUM;
293-
uint32 used = 0;
292+
uint32 allocated = INITIAL_ALLOC_NUM,
293+
used = 0;
294294
Oid *result = (Oid *) palloc(allocated * sizeof(Oid));
295295
Oid *children = PrelGetChildrenArray(prel);
296296

@@ -310,7 +310,7 @@ get_partition_oids(List *ranges, int *n, const PartRelationInfo *prel,
310310
{
311311
if (allocated <= used)
312312
{
313-
allocated *= ALLOC_EXP;
313+
allocated = allocated * ALLOC_EXP + 1;
314314
result = repalloc(result, allocated * sizeof(Oid));
315315
}
316316

@@ -595,10 +595,10 @@ explain_append_common(CustomScanState *node, HTAB *children_table, ExplainState
595595
/* Construct excess PlanStates */
596596
if (!es->analyze)
597597
{
598-
int allocated = INITIAL_ALLOC_NUM;
599-
int used = 0;
600-
ChildScanCommon *custom_ps;
601-
ChildScanCommon child;
598+
uint32 allocated = INITIAL_ALLOC_NUM,
599+
used = 0;
600+
ChildScanCommon *custom_ps,
601+
child;
602602
HASH_SEQ_STATUS seqstat;
603603
int i;
604604

@@ -614,7 +614,7 @@ explain_append_common(CustomScanState *node, HTAB *children_table, ExplainState
614614
{
615615
if (allocated <= used)
616616
{
617-
allocated *= ALLOC_EXP;
617+
allocated = allocated * ALLOC_EXP + 1;
618618
custom_ps = repalloc(custom_ps, allocated * sizeof(ChildScanCommon));
619619
}
620620

src/partition_filter.c

Lines changed: 72 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@
1919
#include "utils/lsyscache.h"
2020

2121

22+
#define ALLOC_EXP 2
23+
24+
2225
bool pg_pathman_enable_partition_filter = true;
2326

2427
CustomScanMethods partition_filter_plan_methods;
@@ -27,6 +30,7 @@ CustomExecMethods partition_filter_exec_methods;
2730

2831
static void partition_filter_visitor(Plan *plan, void *context);
2932
static List * pfilter_build_tlist(List *tlist);
33+
static int append_rri_to_estate(EState *estate, ResultRelInfo *rri, int cur_allocated);
3034

3135

3236
void
@@ -86,7 +90,7 @@ check_acl_for_partition(EState *estate,
8690
rte->relkind = part_rel->rd_rel->relkind;
8791
rte->requiredPerms = ACL_INSERT;
8892

89-
/* Check permissions for current partition */
93+
/* FIXME: Check permissions for partition */
9094
ExecCheckRTPerms(list_make1(rte), true);
9195

9296
/* TODO: append RTE to estate->es_range_table */
@@ -125,40 +129,51 @@ init_result_parts_storage(ResultPartsStorage *parts_storage,
125129

126130
parts_storage->on_new_rri_holder_callback = on_new_rri_holder_cb;
127131
parts_storage->callback_arg = on_new_rri_holder_cb_arg;
132+
133+
/* Partitions must remain locked till transaction's end */
134+
parts_storage->head_open_lock_mode = RowExclusiveLock;
135+
parts_storage->heap_close_lock_mode = NoLock;
128136
}
129137

130138
/*
131139
* Free ResultPartsStorage (close relations etc).
132140
*/
133141
void
134-
fini_result_parts_storage(ResultPartsStorage *parts_storage)
142+
fini_result_parts_storage(ResultPartsStorage *parts_storage, bool close_rels)
135143
{
136-
HASH_SEQ_STATUS stat;
137-
ResultRelInfoHolder *rri_holder; /* ResultRelInfo holder */
138-
139-
hash_seq_init(&stat, parts_storage->result_rels_table);
140-
while ((rri_holder = (ResultRelInfoHolder *) hash_seq_search(&stat)) != NULL)
144+
/* Close partitions and their indices if asked to */
145+
if (close_rels)
141146
{
142-
ExecCloseIndices(rri_holder->result_rel_info);
143-
heap_close(rri_holder->result_rel_info->ri_RelationDesc,
144-
RowExclusiveLock);
147+
HASH_SEQ_STATUS stat;
148+
ResultRelInfoHolder *rri_holder; /* ResultRelInfo holder */
149+
150+
hash_seq_init(&stat, parts_storage->result_rels_table);
151+
while ((rri_holder = (ResultRelInfoHolder *) hash_seq_search(&stat)) != NULL)
152+
{
153+
ExecCloseIndices(rri_holder->result_rel_info);
154+
155+
heap_close(rri_holder->result_rel_info->ri_RelationDesc,
156+
parts_storage->heap_close_lock_mode);
157+
}
145158
}
159+
160+
/* Finally destroy hash table */
146161
hash_destroy(parts_storage->result_rels_table);
147162
}
148163

149164
/*
150165
* Find a ResultRelInfo for the partition using ResultPartsStorage.
151166
*/
152167
ResultRelInfoHolder *
153-
scan_result_parts_storage(Oid partid, ResultPartsStorage *storage)
168+
scan_result_parts_storage(Oid partid, ResultPartsStorage *parts_storage)
154169
{
155170
#define CopyToResultRelInfo(field_name) \
156-
( part_result_rel_info->field_name = storage->saved_rel_info->field_name )
171+
( part_result_rel_info->field_name = parts_storage->saved_rel_info->field_name )
157172

158173
ResultRelInfoHolder *rri_holder;
159174
bool found;
160175

161-
rri_holder = hash_search(storage->result_rels_table,
176+
rri_holder = hash_search(parts_storage->result_rels_table,
162177
(const void *) &partid,
163178
HASH_ENTER, &found);
164179

@@ -167,16 +182,16 @@ scan_result_parts_storage(Oid partid, ResultPartsStorage *storage)
167182
{
168183
ResultRelInfo *part_result_rel_info = makeNode(ResultRelInfo);
169184

185+
/* Check that 'saved_rel_info' is set */
186+
if (!parts_storage->saved_rel_info)
187+
elog(ERROR, "ResultPartsStorage contains no saved_rel_info");
188+
170189
InitResultRelInfo(part_result_rel_info,
171-
heap_open(partid, RowExclusiveLock),
172-
0,
190+
heap_open(partid, parts_storage->head_open_lock_mode),
191+
parts_storage->saved_rel_info->ri_RangeTableIndex,
173192
0); /* TODO: select suitable options */
174193

175-
ExecOpenIndices(part_result_rel_info, storage->speculative_inserts);
176-
177-
/* Check that 'saved_rel_info' is set */
178-
if (!storage->saved_rel_info)
179-
elog(ERROR, "ResultPartsStorage contains no saved_rel_info");
194+
ExecOpenIndices(part_result_rel_info, parts_storage->speculative_inserts);
180195

181196
/* Copy necessary fields from saved ResultRelInfo */
182197
CopyToResultRelInfo(ri_WithCheckOptions);
@@ -189,18 +204,21 @@ scan_result_parts_storage(Oid partid, ResultPartsStorage *storage)
189204
/* ri_ConstraintExprs will be initialized by ExecRelCheck() */
190205
part_result_rel_info->ri_ConstraintExprs = NULL;
191206

192-
/* Make 'range table index' point to the parent relation */
193-
part_result_rel_info->ri_RangeTableIndex =
194-
storage->saved_rel_info->ri_RangeTableIndex;
195-
196207
/* Now fill the ResultRelInfo holder */
197208
rri_holder->partid = partid;
198209
rri_holder->result_rel_info = part_result_rel_info;
199210

211+
/* Add ResultRelInfo to storage->es_alloc_result_rels */
212+
parts_storage->es_alloc_result_rels =
213+
append_rri_to_estate(parts_storage->estate,
214+
part_result_rel_info,
215+
parts_storage->es_alloc_result_rels);
216+
200217
/* Call on_new_rri_holder_callback() if needed */
201-
if (storage->on_new_rri_holder_callback)
202-
storage->on_new_rri_holder_callback(storage->estate, rri_holder,
203-
storage->callback_arg);
218+
if (parts_storage->on_new_rri_holder_callback)
219+
parts_storage->on_new_rri_holder_callback(parts_storage->estate,
220+
rri_holder,
221+
parts_storage->callback_arg);
204222
}
205223

206224
return rri_holder;
@@ -412,8 +430,8 @@ partition_filter_end(CustomScanState *node)
412430
{
413431
PartitionFilterState *state = (PartitionFilterState *) node;
414432

415-
/* Close cached relations */
416-
fini_result_parts_storage(&state->result_parts);
433+
/* Executor will close rels via estate->es_result_relations */
434+
fini_result_parts_storage(&state->result_parts, false);
417435

418436
Assert(list_length(node->custom_ps) == 1);
419437
ExecEndNode((PlanState *) linitial(node->custom_ps));
@@ -432,6 +450,29 @@ partition_filter_explain(CustomScanState *node, List *ancestors, ExplainState *e
432450
/* Nothing to do here now */
433451
}
434452

453+
static int
454+
append_rri_to_estate(EState *estate, ResultRelInfo *rri, int cur_allocated)
455+
{
456+
int result_rels_allocated = cur_allocated;
457+
458+
if (result_rels_allocated <= estate->es_num_result_relations)
459+
{
460+
ResultRelInfo *rri_array = estate->es_result_relations;
461+
462+
result_rels_allocated = result_rels_allocated * ALLOC_EXP + 1;
463+
estate->es_result_relations = palloc(result_rels_allocated *
464+
sizeof(ResultRelInfo));
465+
memcpy(estate->es_result_relations,
466+
rri_array,
467+
estate->es_num_result_relations * sizeof(ResultRelInfo));
468+
}
469+
470+
/* Append ResultRelInfo to 'es_result_relations' array */
471+
estate->es_result_relations[estate->es_num_result_relations++] = *rri;
472+
473+
return result_rels_allocated;
474+
}
475+
435476
/*
436477
* Build partition filter's target list pointing to subplan tuple's elements
437478
*/
@@ -465,9 +506,9 @@ pfilter_build_tlist(List *tlist)
465506
}
466507

467508
/*
468-
* Add partition filters to ModifyTable node's children
509+
* Add partition filters to ModifyTable node's children.
469510
*
470-
* 'context' should point to the PlannedStmt->rtable
511+
* 'context' should point to the PlannedStmt->rtable.
471512
*/
472513
static void
473514
partition_filter_visitor(Plan *plan, void *context)

src/partition_filter.h

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
#define RUNTIME_INSERT_H
1313

1414
#include "relation_info.h"
15-
#include "pathman.h"
15+
#include "utils.h"
1616

1717
#include "postgres.h"
1818
#include "commands/explain.h"
@@ -51,6 +51,9 @@ typedef struct
5151

5252
EState *estate;
5353
int es_alloc_result_rels; /* number of allocated result rels */
54+
55+
LOCKMODE head_open_lock_mode;
56+
LOCKMODE heap_close_lock_mode;
5457
} ResultPartsStorage;
5558

5659
/*
@@ -68,7 +71,7 @@ typedef struct
6871
Plan *subplan; /* proxy variable to store subplan */
6972
ResultPartsStorage result_parts; /* partition ResultRelInfo cache */
7073

71-
bool warning_triggered; /* WARNING message counter */
74+
bool warning_triggered; /* warning message counter */
7275
} PartitionFilterState;
7376

7477

@@ -92,7 +95,8 @@ void init_result_parts_storage(ResultPartsStorage *parts_storage,
9295
Size table_entry_size,
9396
on_new_rri_holder on_new_rri_holder_cb,
9497
void *on_new_rri_holder_cb_arg);
95-
void fini_result_parts_storage(ResultPartsStorage *parts_storage);
98+
void fini_result_parts_storage(ResultPartsStorage *parts_storage,
99+
bool close_rels);
96100
ResultRelInfoHolder * scan_result_parts_storage(Oid partid,
97101
ResultPartsStorage *storage);
98102

src/pg_pathman.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -406,6 +406,7 @@ append_child_relation(PlannerInfo *root, RelOptInfo *rel, Index rti,
406406
PlanRowMark *child_rowmark;
407407
AttrNumber i;
408408

409+
/* FIXME: acquire a suitable lock on partition */
409410
newrelation = heap_open(childOid, NoLock);
410411

411412
/*

0 commit comments

Comments
 (0)