Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 1375422

Browse files
committed
Create ResultRelInfos later in InitPlan, index them by RT index.
Instead of allocating all the ResultRelInfos upfront in one big array, allocate them in ExecInitModifyTable(). es_result_relations is now an array of ResultRelInfo pointers, rather than an array of structs, and it is indexed by the RT index. This simplifies things: we get rid of the separate concept of a "result rel index", and don't need to set it in setrefs.c anymore. This also allows follow-up optimizations (not included in this commit yet) to skip initializing ResultRelInfos for target relations that were not needed at runtime, and removal of the es_result_relation_info pointer. The EState arrays of regular result rels and root result rels are merged into one array. Similarly, the resultRelations and rootResultRelations lists in PlannedStmt are merged into one. It's not actually clear to me why they were kept separate in the first place, but now that the es_result_relations array is indexed by RT index, it certainly seems pointless. The PlannedStmt->resultRelations list is now only needed for ExecRelationIsTargetRelation(). One visible effect of this change is that ExecRelationIsTargetRelation() will now return 'true' also for the partition root, if a partitioned table is updated. That seems like a good thing, although the function isn't used in core code, and I don't see any reason for an FDW to call it on a partition root. Author: Amit Langote Discussion: https://www.postgresql.org/message-id/CA%2BHiwqGEmiib8FLiHMhKB%2BCH5dRgHSLc5N5wnvc4kym%2BZYpQEQ%40mail.gmail.com
1 parent 2050832 commit 1375422

File tree

19 files changed

+184
-303
lines changed

19 files changed

+184
-303
lines changed

src/backend/commands/copy.c

+8-16
Original file line numberDiff line numberDiff line change
@@ -2727,6 +2727,7 @@ CopyFrom(CopyState cstate)
27272727
bool leafpart_use_multi_insert = false;
27282728

27292729
Assert(cstate->rel);
2730+
Assert(list_length(cstate->range_table) == 1);
27302731

27312732
/*
27322733
* The target must be a plain, foreign, or partitioned relation, or have
@@ -2829,25 +2830,17 @@ CopyFrom(CopyState cstate)
28292830
* index-entry-making machinery. (There used to be a huge amount of code
28302831
* here that basically duplicated execUtils.c ...)
28312832
*/
2832-
resultRelInfo = makeNode(ResultRelInfo);
2833-
InitResultRelInfo(resultRelInfo,
2834-
cstate->rel,
2835-
1, /* must match rel's position in range_table */
2836-
NULL,
2837-
0);
2838-
target_resultRelInfo = resultRelInfo;
2833+
ExecInitRangeTable(estate, cstate->range_table);
2834+
resultRelInfo = target_resultRelInfo = makeNode(ResultRelInfo);
2835+
ExecInitResultRelation(estate, resultRelInfo, 1);
28392836

28402837
/* Verify the named relation is a valid target for INSERT */
28412838
CheckValidResultRel(resultRelInfo, CMD_INSERT);
28422839

28432840
ExecOpenIndices(resultRelInfo, false);
28442841

2845-
estate->es_result_relations = resultRelInfo;
2846-
estate->es_num_result_relations = 1;
28472842
estate->es_result_relation_info = resultRelInfo;
28482843

2849-
ExecInitRangeTable(estate, cstate->range_table);
2850-
28512844
/*
28522845
* Set up a ModifyTableState so we can let FDW(s) init themselves for
28532846
* foreign-table result relation(s).
@@ -2856,7 +2849,7 @@ CopyFrom(CopyState cstate)
28562849
mtstate->ps.plan = NULL;
28572850
mtstate->ps.state = estate;
28582851
mtstate->operation = CMD_INSERT;
2859-
mtstate->resultRelInfo = estate->es_result_relations;
2852+
mtstate->resultRelInfo = resultRelInfo;
28602853

28612854
if (resultRelInfo->ri_FdwRoutine != NULL &&
28622855
resultRelInfo->ri_FdwRoutine->BeginForeignInsert != NULL)
@@ -3359,14 +3352,13 @@ CopyFrom(CopyState cstate)
33593352
if (insertMethod != CIM_SINGLE)
33603353
CopyMultiInsertInfoCleanup(&multiInsertInfo);
33613354

3362-
ExecCloseIndices(target_resultRelInfo);
3363-
33643355
/* Close all the partitioned tables, leaf partitions, and their indices */
33653356
if (proute)
33663357
ExecCleanupTupleRouting(mtstate, proute);
33673358

3368-
/* Close any trigger target relations */
3369-
ExecCleanUpTriggerState(estate);
3359+
/* Close the result relations, including any trigger target relations */
3360+
ExecCloseResultRelations(estate);
3361+
ExecCloseRangeTableRelations(estate);
33703362

33713363
FreeExecutorState(estate);
33723364

src/backend/commands/explain.c

+7-10
Original file line numberDiff line numberDiff line change
@@ -769,27 +769,24 @@ ExplainPrintTriggers(ExplainState *es, QueryDesc *queryDesc)
769769
{
770770
ResultRelInfo *rInfo;
771771
bool show_relname;
772-
int numrels = queryDesc->estate->es_num_result_relations;
773-
int numrootrels = queryDesc->estate->es_num_root_result_relations;
772+
List *resultrels;
774773
List *routerels;
775774
List *targrels;
776-
int nr;
777775
ListCell *l;
778776

777+
resultrels = queryDesc->estate->es_opened_result_relations;
779778
routerels = queryDesc->estate->es_tuple_routing_result_relations;
780779
targrels = queryDesc->estate->es_trig_target_relations;
781780

782781
ExplainOpenGroup("Triggers", "Triggers", false, es);
783782

784-
show_relname = (numrels > 1 || numrootrels > 0 ||
783+
show_relname = (list_length(resultrels) > 1 ||
785784
routerels != NIL || targrels != NIL);
786-
rInfo = queryDesc->estate->es_result_relations;
787-
for (nr = 0; nr < numrels; rInfo++, nr++)
788-
report_triggers(rInfo, show_relname, es);
789-
790-
rInfo = queryDesc->estate->es_root_result_relations;
791-
for (nr = 0; nr < numrootrels; rInfo++, nr++)
785+
foreach(l, resultrels)
786+
{
787+
rInfo = (ResultRelInfo *) lfirst(l);
792788
report_triggers(rInfo, show_relname, es);
789+
}
793790

794791
foreach(l, routerels)
795792
{

src/backend/commands/tablecmds.c

+7-2
Original file line numberDiff line numberDiff line change
@@ -1787,6 +1787,11 @@ ExecuteTruncateGuts(List *explicit_rels, List *relids, List *relids_logged,
17871787
/*
17881788
* To fire triggers, we'll need an EState as well as a ResultRelInfo for
17891789
* each relation. We don't need to call ExecOpenIndices, though.
1790+
*
1791+
* We put the ResultRelInfos in the es_opened_result_relations list, even
1792+
* though we don't have a range table and don't populate the
1793+
* es_result_relations array. That's a big bogus, but it's enough to make
1794+
* ExecGetTriggerResultRel() find them.
17901795
*/
17911796
estate = CreateExecutorState();
17921797
resultRelInfos = (ResultRelInfo *)
@@ -1801,10 +1806,10 @@ ExecuteTruncateGuts(List *explicit_rels, List *relids, List *relids_logged,
18011806
0, /* dummy rangetable index */
18021807
NULL,
18031808
0);
1809+
estate->es_opened_result_relations =
1810+
lappend(estate->es_opened_result_relations, resultRelInfo);
18041811
resultRelInfo++;
18051812
}
1806-
estate->es_result_relations = resultRelInfos;
1807-
estate->es_num_result_relations = list_length(rels);
18081813

18091814
/*
18101815
* Process all BEFORE STATEMENT TRUNCATE triggers before we begin

src/backend/commands/trigger.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -4227,7 +4227,7 @@ afterTriggerInvokeEvents(AfterTriggerEventList *events,
42274227

42284228
if (local_estate)
42294229
{
4230-
ExecCleanUpTriggerState(estate);
4230+
ExecCloseResultRelations(estate);
42314231
ExecResetTupleTable(estate->es_tupleTable, false);
42324232
FreeExecutorState(estate);
42334233
}

0 commit comments

Comments
 (0)