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)
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