From 04d24039ec7c14672955aaaba37e3aa512858a0d Mon Sep 17 00:00:00 2001 From: Melanie Plageman Date: Fri, 27 Mar 2026 09:21:22 -0400 Subject: [PATCH v48 1/6] Make it cheap to check if a relation is modified by a query Save the range table indexes of result relations and row mark relations in separate bitmaps in the PlannedStmt. Precomputing them allows cheap membership checks during execution. With a few exceptions, these two groups comprise all relations that will be modified by a query. This includes relations targeted by INSERT, UPDATE, DELETE, and MERGE as well as relations with any row mark (like SELECT FOR UPDATE). A later commit will use this information during scans to control whether or not on-access pruning is allowed to set the visibility map -- which would be counterproductive if the query will modify the page. PlannedStmt->resultRelations is only used in a membership check, so it may make sense to replace its usage with the new resultRelationRelids. Author: Melanie Plageman Reviewed-by: Andres Freund Reviewed-by: David Rowley Reviewed-by: Chao Li Discussion: https://postgr.es/m/F5CDD1B5-628C-44A1-9F85-3958C626F6A9%40gmail.com --- src/backend/executor/execParallel.c | 2 ++ src/backend/optimizer/plan/planner.c | 19 ++++++++++++++++++- src/include/nodes/plannodes.h | 9 +++++++++ 3 files changed, 29 insertions(+), 1 deletion(-) diff --git a/src/backend/executor/execParallel.c b/src/backend/executor/execParallel.c index ac84af294c9..791fcb88de9 100644 --- a/src/backend/executor/execParallel.c +++ b/src/backend/executor/execParallel.c @@ -188,6 +188,8 @@ ExecSerializePlan(Plan *plan, EState *estate) pstmt->partPruneInfos = estate->es_part_prune_infos; pstmt->rtable = estate->es_range_table; pstmt->unprunableRelids = estate->es_unpruned_relids; + pstmt->resultRelationRelids = estate->es_plannedstmt->resultRelationRelids; + pstmt->rowMarkRelids = estate->es_plannedstmt->rowMarkRelids; pstmt->permInfos = estate->es_rteperminfos; pstmt->resultRelations = NIL; pstmt->appendRelations = NIL; diff --git a/src/backend/optimizer/plan/planner.c b/src/backend/optimizer/plan/planner.c index d19800ad6a5..df4c99fc3ff 100644 --- a/src/backend/optimizer/plan/planner.c +++ b/src/backend/optimizer/plan/planner.c @@ -340,8 +340,11 @@ standard_planner(Query *parse, const char *query_string, int cursorOptions, RelOptInfo *final_rel; Path *best_path; Plan *top_plan; + Bitmapset *resultRelationRelids = NULL; + Bitmapset *rowMarkRelids = NULL; ListCell *lp, - *lr; + *lr, + *lc; /* * Set up global state for this planner invocation. This data is needed @@ -661,6 +664,20 @@ standard_planner(Query *parse, const char *query_string, int cursorOptions, result->subplans = glob->subplans; result->rewindPlanIDs = glob->rewindPlanIDs; result->rowMarks = glob->finalrowmarks; + + /* + * Compute resultRelationRelids and rowMarkRelids from resultRelations and + * rowMarks for quick access. + */ + foreach(lc, glob->resultRelations) + resultRelationRelids = bms_add_member(resultRelationRelids, + lfirst_int(lc)); + foreach(lc, glob->finalrowmarks) + rowMarkRelids = bms_add_member(rowMarkRelids, + ((PlanRowMark *) lfirst(lc))->rti); + result->resultRelationRelids = resultRelationRelids; + result->rowMarkRelids = rowMarkRelids; + result->relationOids = glob->relationOids; result->invalItems = glob->invalItems; result->paramExecTypes = glob->paramExecTypes; diff --git a/src/include/nodes/plannodes.h b/src/include/nodes/plannodes.h index b6185825fcb..88be65d7bde 100644 --- a/src/include/nodes/plannodes.h +++ b/src/include/nodes/plannodes.h @@ -121,6 +121,9 @@ typedef struct PlannedStmt /* integer list of RT indexes, or NIL */ List *resultRelations; + /* RT indexes of result relations targeted by INSERT/UPDATE/DELETE/MERGE */ + Bitmapset *resultRelationRelids; + /* list of AppendRelInfo nodes */ List *appendRelations; @@ -138,6 +141,12 @@ typedef struct PlannedStmt /* a list of PlanRowMark's */ List *rowMarks; + /* + * RT indexes of relations with row marks. Useful for quick membership + * checks instead of iterating through rowMarks. + */ + Bitmapset *rowMarkRelids; + /* OIDs of relations the plan depends on */ List *relationOids; -- 2.43.0