1
0
mirror of https://github.com/postgres/postgres.git synced 2025-06-27 23:21:58 +03:00

Fire per-statement triggers on partitioned tables.

Even though no actual tuples are ever inserted into a partitioned
table (the actual tuples are in the partitions, not the partitioned
table itself), we still need to have a ResultRelInfo for the
partitioned table, or per-statement triggers won't get fired.

Amit Langote, per a report from Rajkumar Raghuwanshi.  Reviewed by me.

Discussion: http://postgr.es/m/CAKcux6%3DwYospCRY2J4XEFuVy0L41S%3Dfic7rmkbsU-GXhhSbmBg%40mail.gmail.com
This commit is contained in:
Robert Haas
2017-05-01 08:23:01 -04:00
parent e18b2c480d
commit e180c8aa8c
14 changed files with 296 additions and 27 deletions

View File

@ -861,17 +861,52 @@ InitPlan(QueryDesc *queryDesc, int eflags)
/*
* In the partitioned result relation case, lock the non-leaf result
* relations too. We don't however need ResultRelInfos for them.
* relations too. A subset of these are the roots of respective
* partitioned tables, for which we also allocate ResulRelInfos.
*/
estate->es_root_result_relations = NULL;
estate->es_num_root_result_relations = 0;
if (plannedstmt->nonleafResultRelations)
{
int num_roots = list_length(plannedstmt->rootResultRelations);
/*
* Firstly, build ResultRelInfos for all the partitioned table
* roots, because we will need them to fire the statement-level
* triggers, if any.
*/
resultRelInfos = (ResultRelInfo *)
palloc(num_roots * sizeof(ResultRelInfo));
resultRelInfo = resultRelInfos;
foreach(l, plannedstmt->rootResultRelations)
{
Index resultRelIndex = lfirst_int(l);
Oid resultRelOid;
Relation resultRelDesc;
resultRelOid = getrelid(resultRelIndex, rangeTable);
resultRelDesc = heap_open(resultRelOid, RowExclusiveLock);
InitResultRelInfo(resultRelInfo,
resultRelDesc,
lfirst_int(l),
NULL,
estate->es_instrument);
resultRelInfo++;
}
estate->es_root_result_relations = resultRelInfos;
estate->es_num_root_result_relations = num_roots;
/* Simply lock the rest of them. */
foreach(l, plannedstmt->nonleafResultRelations)
{
Index resultRelationIndex = lfirst_int(l);
Oid resultRelationOid;
Index resultRelIndex = lfirst_int(l);
resultRelationOid = getrelid(resultRelationIndex, rangeTable);
LockRelationOid(resultRelationOid, RowExclusiveLock);
/* We locked the roots above. */
if (!list_member_int(plannedstmt->rootResultRelations,
resultRelIndex))
LockRelationOid(getrelid(resultRelIndex, rangeTable),
RowExclusiveLock);
}
}
}
@ -883,6 +918,8 @@ InitPlan(QueryDesc *queryDesc, int eflags)
estate->es_result_relations = NULL;
estate->es_num_result_relations = 0;
estate->es_result_relation_info = NULL;
estate->es_root_result_relations = NULL;
estate->es_num_root_result_relations = 0;
}
/*
@ -1565,6 +1602,14 @@ ExecEndPlan(PlanState *planstate, EState *estate)
resultRelInfo++;
}
/* Close the root target relation(s). */
resultRelInfo = estate->es_root_result_relations;
for (i = estate->es_num_root_result_relations; i > 0; i--)
{
heap_close(resultRelInfo->ri_RelationDesc, NoLock);
resultRelInfo++;
}
/*
* likewise close any trigger target relations
*/