From a986e224afa387aee02623b18fc7968a288dc341 Mon Sep 17 00:00:00 2001 From: naisila Date: Fri, 9 Jun 2023 16:32:27 +0300 Subject: [PATCH] Rework PlannedStmt and Query's Permission Info The main issue lies in the following entries of PlannedStmt: { rtable permInfos } Each rtable has an int perminfoindex, and its actual permission info is obtained through the following: permInfos[perminfoindex] We had a crash because perminfoindexes were not updated in the finalized planned statement after distributed planner hook. So, basically, everywhere we set a query's or planned statement's rtable entry, we need to set the rteperminfos/permInfos accordingly. Relevant PG commits: https://github.com/postgres/postgres/commit/a61b1f74823c9c4f79c95226a461f1e7a367764b a61b1f74823c9c4f79c95226a461f1e7a367764b https://github.com/postgres/postgres/commit/b803b7d132e3505ab77c29acf91f3d1caa298f95 b803b7d132e3505ab77c29acf91f3d1caa298f95 --- .../distributed/planner/deparse_shard_query.c | 3 + .../distributed/planner/distributed_planner.c | 34 +++++++++++ .../planner/fast_path_router_planner.c | 3 + .../planner/insert_select_planner.c | 30 ++++++++++ .../planner/local_distributed_join_planner.c | 43 +++++++++++++- .../distributed/planner/merge_planner.c | 29 ++++++++++ .../planner/query_colocation_checker.c | 25 ++++++++- .../planner/query_pushdown_planning.c | 3 + .../distributed/planner/recursive_planning.c | 56 +++++++++++++++++++ .../distributed/utils/relation_utils.c | 6 -- .../distributed/query_colocation_checker.h | 5 ++ src/include/distributed/recursive_planning.h | 5 ++ 12 files changed, 234 insertions(+), 8 deletions(-) diff --git a/src/backend/distributed/planner/deparse_shard_query.c b/src/backend/distributed/planner/deparse_shard_query.c index 5743ab1c1..c1ac6af10 100644 --- a/src/backend/distributed/planner/deparse_shard_query.c +++ b/src/backend/distributed/planner/deparse_shard_query.c @@ -358,6 +358,9 @@ ConvertRteToSubqueryWithEmptyResult(RangeTblEntry *rte) subquery->jointree = joinTree; rte->rtekind = RTE_SUBQUERY; +#if PG_VERSION_NUM >= PG_VERSION_16 + rte->perminfoindex = 0; +#endif rte->subquery = subquery; rte->alias = copyObject(rte->eref); } diff --git a/src/backend/distributed/planner/distributed_planner.c b/src/backend/distributed/planner/distributed_planner.c index ae2c83937..22c2a8ac2 100644 --- a/src/backend/distributed/planner/distributed_planner.c +++ b/src/backend/distributed/planner/distributed_planner.c @@ -57,6 +57,9 @@ #include "nodes/makefuncs.h" #include "nodes/nodeFuncs.h" #include "nodes/pg_list.h" +#if PG_VERSION_NUM >= PG_VERSION_16 +#include "parser/parse_relation.h" +#endif #include "parser/parsetree.h" #include "parser/parse_type.h" #include "optimizer/optimizer.h" @@ -1468,6 +1471,27 @@ FinalizeNonRouterPlan(PlannedStmt *localPlan, DistributedPlan *distributedPlan, /* add original range table list for access permission checks */ finalPlan->rtable = list_concat(finalPlan->rtable, localPlan->rtable); +#if PG_VERSION_NUM >= PG_VERSION_16 + + /* + * Original range table list is concatenated to final plan's range table list + * therefore all the perminfoindexes should be updated to their value + * PLUS the length of final plan's perminfos. + */ + int list_length_final_permInfos = list_length(finalPlan->permInfos); + finalPlan->permInfos = list_concat(finalPlan->permInfos, localPlan->permInfos); + + ListCell *lc; + foreach(lc, localPlan->rtable) + { + RangeTblEntry *rte = (RangeTblEntry *) lfirst(lc); + if (rte->perminfoindex != 0) + { + rte->perminfoindex = rte->perminfoindex + list_length_final_permInfos; + } + } +#endif + return finalPlan; } @@ -1505,6 +1529,16 @@ FinalizeRouterPlan(PlannedStmt *localPlan, CustomScan *customScan) /* add original range table list for access permission checks */ routerPlan->rtable = list_concat(routerPlan->rtable, localPlan->rtable); +#if PG_VERSION_NUM >= PG_VERSION_16 + + /* + * We know that extra remoteScanRangeTableEntry has perminfoindex 0 + * therefore we can simply use the perminfos we had in localplan + */ + Assert(remoteScanRangeTableEntry->perminfoindex == 0); + routerPlan->permInfos = localPlan->permInfos; +#endif + routerPlan->canSetTag = true; routerPlan->relationOids = NIL; diff --git a/src/backend/distributed/planner/fast_path_router_planner.c b/src/backend/distributed/planner/fast_path_router_planner.c index 41802ee83..933ee7425 100644 --- a/src/backend/distributed/planner/fast_path_router_planner.c +++ b/src/backend/distributed/planner/fast_path_router_planner.c @@ -136,6 +136,9 @@ GeneratePlaceHolderPlannedStmt(Query *parse) result->stmt_len = parse->stmt_len; result->rtable = copyObject(parse->rtable); +#if PG_VERSION_NUM >= PG_VERSION_16 + result->permInfos = copyObject(parse->rteperminfos); +#endif result->planTree = (Plan *) plan; result->hasReturning = (parse->returningList != NIL); diff --git a/src/backend/distributed/planner/insert_select_planner.c b/src/backend/distributed/planner/insert_select_planner.c index e3da3ac20..6efcc905b 100644 --- a/src/backend/distributed/planner/insert_select_planner.c +++ b/src/backend/distributed/planner/insert_select_planner.c @@ -604,6 +604,22 @@ CreateCombineQueryForRouterPlan(DistributedPlan *distPlan) combineQuery->querySource = QSRC_ORIGINAL; combineQuery->canSetTag = true; combineQuery->rtable = list_make1(rangeTableEntry); + +#if PG_VERSION_NUM >= PG_VERSION_16 + + /* + * This part of the code is more of a sanity check for readability, + * it doesn't really do anything. + * We know that Only relation RTEs and subquery RTEs that were once relation + * RTEs (views) have their perminfoindex set. (see ExecCheckPermissions function) + * DerivedRangeTableEntry sets the rtekind to RTE_FUNCTION + * Hence we should have no perminfos here. + */ + Assert(rangeTableEntry->rtekind == RTE_FUNCTION && + rangeTableEntry->perminfoindex == 0); + combineQuery->rteperminfos = NIL; +#endif + combineQuery->targetList = targetList; combineQuery->jointree = joinTree; return combineQuery; @@ -1541,6 +1557,20 @@ WrapSubquery(Query *subquery) selectAlias, false, true)); outerQuery->rtable = list_make1(newRangeTableEntry); +#if PG_VERSION_NUM >= PG_VERSION_16 + + /* + * This part of the code is more of a sanity check for readability, + * it doesn't really do anything. + * addRangeTableEntryForSubquery doesn't add permission info + * because the range table is set to be RTE_SUBQUERY. + * Hence we should also have no perminfos here. + */ + Assert(newRangeTableEntry->rtekind == RTE_SUBQUERY && + newRangeTableEntry->perminfoindex == 0); + outerQuery->rteperminfos = NIL; +#endif + /* set the FROM expression to the subquery */ RangeTblRef *newRangeTableRef = makeNode(RangeTblRef); newRangeTableRef->rtindex = 1; diff --git a/src/backend/distributed/planner/local_distributed_join_planner.c b/src/backend/distributed/planner/local_distributed_join_planner.c index 2c6a63de1..ecbd182f0 100644 --- a/src/backend/distributed/planner/local_distributed_join_planner.c +++ b/src/backend/distributed/planner/local_distributed_join_planner.c @@ -107,6 +107,7 @@ #include "optimizer/optimizer.h" #include "optimizer/planner.h" #include "optimizer/prep.h" +#include "parser/parse_relation.h" #include "parser/parsetree.h" #include "nodes/makefuncs.h" #include "nodes/nodeFuncs.h" @@ -136,6 +137,9 @@ typedef struct RangeTableEntryDetails RangeTblEntry *rangeTableEntry; List *requiredAttributeNumbers; bool hasConstantFilterOnUniqueColumn; +#if PG_VERSION_NUM >= PG_VERSION_16 + RTEPermissionInfo *perminfo; +#endif } RangeTableEntryDetails; /* @@ -176,7 +180,12 @@ static bool HasConstantFilterOnUniqueColumn(RangeTblEntry *rangeTableEntry, static ConversionCandidates * CreateConversionCandidates(PlannerRestrictionContext * plannerRestrictionContext, List *rangeTableList, +#if PG_VERSION_NUM >= PG_VERSION_16 + int resultRTEIdentity, + List *rteperminfos); +#else int resultRTEIdentity); +#endif static void AppendUniqueIndexColumnsToList(Form_pg_index indexForm, List **uniqueIndexes, int flags); static ConversionChoice GetConversionChoice(ConversionCandidates * @@ -205,10 +214,17 @@ RecursivelyPlanLocalTableJoins(Query *query, GetPlannerRestrictionContext(context); List *rangeTableList = query->rtable; +#if PG_VERSION_NUM >= PG_VERSION_16 + List *rteperminfos = query->rteperminfos; +#endif int resultRTEIdentity = ResultRTEIdentity(query); ConversionCandidates *conversionCandidates = CreateConversionCandidates(plannerRestrictionContext, +#if PG_VERSION_NUM >= PG_VERSION_16 + rangeTableList, resultRTEIdentity, rteperminfos); +#else rangeTableList, resultRTEIdentity); +#endif ConversionChoice conversionChoise = GetConversionChoice(conversionCandidates, plannerRestrictionContext); @@ -216,6 +232,12 @@ RecursivelyPlanLocalTableJoins(Query *query, List *rteListToConvert = RTEListToConvert(conversionCandidates, conversionChoise); ConvertRTEsToSubquery(rteListToConvert, context); + + /* + * Note: we don't need to remove converted rtes from query->rteperminfos to avoid + * crash of Assert(bms_num_members(indexset) == list_length(rteperminfos)); + * because query->rteperminfos has already gone through ExecCheckPermissions + */ } @@ -323,7 +345,12 @@ ConvertRTEsToSubquery(List *rangeTableEntryDetailsList, RecursivePlanningContext RangeTblEntry *rangeTableEntry = rangeTableEntryDetails->rangeTableEntry; List *requiredAttributeNumbers = rangeTableEntryDetails->requiredAttributeNumbers; ReplaceRTERelationWithRteSubquery(rangeTableEntry, +#if PG_VERSION_NUM >= PG_VERSION_16 + requiredAttributeNumbers, context, + rangeTableEntryDetails->perminfo); +#else requiredAttributeNumbers, context); +#endif } } @@ -530,7 +557,13 @@ RequiredAttrNumbersForRelationInternal(Query *queryToProcess, int rteIndex) */ static ConversionCandidates * CreateConversionCandidates(PlannerRestrictionContext *plannerRestrictionContext, - List *rangeTableList, int resultRTEIdentity) + List *rangeTableList, +#if PG_VERSION_NUM >= PG_VERSION_16 + int resultRTEIdentity, + List *rteperminfos) +#else + int resultRTEIdentity) +#endif { ConversionCandidates *conversionCandidates = palloc0(sizeof(ConversionCandidates)); @@ -564,6 +597,14 @@ CreateConversionCandidates(PlannerRestrictionContext *plannerRestrictionContext, RequiredAttrNumbersForRelation(rangeTableEntry, plannerRestrictionContext); rangeTableEntryDetails->hasConstantFilterOnUniqueColumn = HasConstantFilterOnUniqueColumn(rangeTableEntry, relationRestriction); +#if PG_VERSION_NUM >= PG_VERSION_16 + rangeTableEntryDetails->perminfo = NULL; + if (rangeTableEntry->perminfoindex) + { + rangeTableEntryDetails->perminfo = getRTEPermissionInfo(rteperminfos, + rangeTableEntry); + } +#endif bool referenceOrDistributedTable = IsCitusTableType(rangeTableEntry->relid, REFERENCE_TABLE) || diff --git a/src/backend/distributed/planner/merge_planner.c b/src/backend/distributed/planner/merge_planner.c index f6af545cb..d8f59779a 100644 --- a/src/backend/distributed/planner/merge_planner.c +++ b/src/backend/distributed/planner/merge_planner.c @@ -15,6 +15,7 @@ #include "nodes/makefuncs.h" #include "nodes/nodeFuncs.h" #include "optimizer/optimizer.h" +#include "parser/parse_relation.h" #include "parser/parsetree.h" #include "tcop/tcopprot.h" #include "utils/lsyscache.h" @@ -774,6 +775,11 @@ ConvertCteRTEIntoSubquery(Query *mergeQuery, RangeTblEntry *sourceRte) Query *cteQuery = (Query *) copyObject(sourceCte->ctequery); sourceRte->rtekind = RTE_SUBQUERY; +#if PG_VERSION_NUM >= PG_VERSION_16 + + /* sanity check - sourceRte was RTE_CTE previously so it should have no perminfo */ + Assert(sourceRte->perminfoindex == 0); +#endif /* * As we are delinking the CTE from main query, we have to walk through the @@ -824,6 +830,20 @@ ConvertRelationRTEIntoSubquery(Query *mergeQuery, RangeTblEntry *sourceRte, RangeTblEntry *newRangeTableEntry = copyObject(sourceRte); sourceResultsQuery->rtable = list_make1(newRangeTableEntry); +#if PG_VERSION_NUM >= PG_VERSION_16 + sourceResultsQuery->rteperminfos = NIL; + if (newRangeTableEntry->perminfoindex) + { + /* create permission info for newRangeTableEntry */ + RTEPermissionInfo *perminfo = getRTEPermissionInfo(mergeQuery->rteperminfos, + newRangeTableEntry); + + /* update the subquery's rteperminfos accordingly */ + newRangeTableEntry->perminfoindex = 1; + sourceResultsQuery->rteperminfos = list_make1(perminfo); + } +#endif + /* set the FROM expression to the subquery */ newRangeTableRef->rtindex = SINGLE_RTE_INDEX; sourceResultsQuery->jointree = makeFromExpr(list_make1(newRangeTableRef), NULL); @@ -849,6 +869,15 @@ ConvertRelationRTEIntoSubquery(Query *mergeQuery, RangeTblEntry *sourceRte, /* replace the function with the constructed subquery */ sourceRte->rtekind = RTE_SUBQUERY; +#if PG_VERSION_NUM >= PG_VERSION_16 + sourceRte->perminfoindex = 0; + + /* + * Note: we don't need to remove replaced sourceRte from mergeQuery->rteperminfos to avoid + * crash of Assert(bms_num_members(indexset) == list_length(rteperminfos)); + * because mergeQuery->rteperminfos has already gone through ExecCheckPermissions + */ +#endif sourceRte->subquery = sourceResultsQuery; sourceRte->inh = false; } diff --git a/src/backend/distributed/planner/query_colocation_checker.c b/src/backend/distributed/planner/query_colocation_checker.c index f5701fdb1..a39e50a56 100644 --- a/src/backend/distributed/planner/query_colocation_checker.c +++ b/src/backend/distributed/planner/query_colocation_checker.c @@ -83,7 +83,16 @@ CreateColocatedJoinChecker(Query *subquery, PlannerRestrictionContext *restricti * functions (i.e., FilterPlannerRestrictionForQuery()) rely on queries * not relations. */ +#if PG_VERSION_NUM >= PG_VERSION_16 + RTEPermissionInfo *perminfo = NULL; + if (anchorRangeTblEntry->perminfoindex) + { + perminfo = getRTEPermissionInfo(subquery->rteperminfos, anchorRangeTblEntry); + } + anchorSubquery = WrapRteRelationIntoSubquery(anchorRangeTblEntry, NIL, perminfo); +#else anchorSubquery = WrapRteRelationIntoSubquery(anchorRangeTblEntry, NIL); +#endif } else if (anchorRangeTblEntry->rtekind == RTE_SUBQUERY) { @@ -266,7 +275,13 @@ SubqueryColocated(Query *subquery, ColocatedJoinChecker *checker) * designed for generating a stub query. */ Query * -WrapRteRelationIntoSubquery(RangeTblEntry *rteRelation, List *requiredAttributes) +WrapRteRelationIntoSubquery(RangeTblEntry *rteRelation, +#if PG_VERSION_NUM >= PG_VERSION_16 + List *requiredAttributes, + RTEPermissionInfo *perminfo) +#else + List * requiredAttributes) +#endif { Query *subquery = makeNode(Query); RangeTblRef *newRangeTableRef = makeNode(RangeTblRef); @@ -277,6 +292,14 @@ WrapRteRelationIntoSubquery(RangeTblEntry *rteRelation, List *requiredAttributes RangeTblEntry *newRangeTableEntry = copyObject(rteRelation); subquery->rtable = list_make1(newRangeTableEntry); +#if PG_VERSION_NUM >= PG_VERSION_16 + if (perminfo) + { + newRangeTableEntry->perminfoindex = 1; + subquery->rteperminfos = list_make1(perminfo); + } +#endif + /* set the FROM expression to the subquery */ newRangeTableRef = makeNode(RangeTblRef); newRangeTableRef->rtindex = SINGLE_RTE_INDEX; diff --git a/src/backend/distributed/planner/query_pushdown_planning.c b/src/backend/distributed/planner/query_pushdown_planning.c index cbe6a3606..200509974 100644 --- a/src/backend/distributed/planner/query_pushdown_planning.c +++ b/src/backend/distributed/planner/query_pushdown_planning.c @@ -1915,6 +1915,9 @@ SubqueryPushdownMultiNodeTree(Query *originalQuery) pushedDownQuery->targetList = subqueryTargetEntryList; pushedDownQuery->jointree = copyObject(queryTree->jointree); pushedDownQuery->rtable = copyObject(queryTree->rtable); +#if PG_VERSION_NUM >= PG_VERSION_16 + pushedDownQuery->rteperminfos = copyObject(queryTree->rteperminfos); +#endif pushedDownQuery->setOperations = copyObject(queryTree->setOperations); pushedDownQuery->querySource = queryTree->querySource; pushedDownQuery->hasSubLinks = queryTree->hasSubLinks; diff --git a/src/backend/distributed/planner/recursive_planning.c b/src/backend/distributed/planner/recursive_planning.c index f582fd9df..ec1ab8419 100644 --- a/src/backend/distributed/planner/recursive_planning.c +++ b/src/backend/distributed/planner/recursive_planning.c @@ -80,6 +80,7 @@ #include "optimizer/optimizer.h" #include "optimizer/planner.h" #include "optimizer/prep.h" +#include "parser/parse_relation.h" #include "parser/parsetree.h" #include "nodes/makefuncs.h" #include "nodes/nodeFuncs.h" @@ -886,8 +887,25 @@ RecursivelyPlanDistributedJoinNode(Node *node, Query *query, List *requiredAttributes = RequiredAttrNumbersForRelation(distributedRte, restrictionContext); +#if PG_VERSION_NUM >= PG_VERSION_16 + RTEPermissionInfo *perminfo = NULL; + if (distributedRte->perminfoindex) + { + perminfo = getRTEPermissionInfo(query->rteperminfos, distributedRte); + } + + ReplaceRTERelationWithRteSubquery(distributedRte, requiredAttributes, + recursivePlanningContext, perminfo); +#else ReplaceRTERelationWithRteSubquery(distributedRte, requiredAttributes, recursivePlanningContext); +#endif + + /* + * Note: we don't need to remove replaced rtes from query->rteperminfos to avoid + * crash of Assert(bms_num_members(indexset) == list_length(rteperminfos)); + * because query->rteperminfos has already gone through ExecCheckPermissions + */ } else if (distributedRte->rtekind == RTE_SUBQUERY) { @@ -1751,9 +1769,17 @@ NodeContainsSubqueryReferencingOuterQuery(Node *node) void ReplaceRTERelationWithRteSubquery(RangeTblEntry *rangeTableEntry, List *requiredAttrNumbers, +#if PG_VERSION_NUM >= PG_VERSION_16 + RecursivePlanningContext *context, + RTEPermissionInfo *perminfo) +{ + Query *subquery = WrapRteRelationIntoSubquery(rangeTableEntry, requiredAttrNumbers, + perminfo); +#else RecursivePlanningContext *context) { Query *subquery = WrapRteRelationIntoSubquery(rangeTableEntry, requiredAttrNumbers); +#endif List *outerQueryTargetList = CreateAllTargetListForRelation(rangeTableEntry->relid, requiredAttrNumbers); @@ -1778,6 +1804,15 @@ ReplaceRTERelationWithRteSubquery(RangeTblEntry *rangeTableEntry, /* replace the function with the constructed subquery */ rangeTableEntry->rtekind = RTE_SUBQUERY; +#if PG_VERSION_NUM >= PG_VERSION_16 + + /* + * subquery already contains a copy of this rangeTableEntry's permission info + * Not we have replaced with the constructed subquery so we should + * set perminfoindex to 0. + */ + rangeTableEntry->perminfoindex = 0; +#endif rangeTableEntry->subquery = subquery; /* @@ -1850,6 +1885,15 @@ CreateOuterSubquery(RangeTblEntry *rangeTableEntry, List *outerSubqueryTargetLis innerSubqueryRTE->eref->colnames = innerSubqueryColNames; outerSubquery->rtable = list_make1(innerSubqueryRTE); +#if PG_VERSION_NUM >= PG_VERSION_16 + + /* sanity check */ + Assert(innerSubqueryRTE->rtekind == RTE_SUBQUERY && + innerSubqueryRTE->perminfoindex == 0); + outerSubquery->rteperminfos = NIL; +#endif + + /* set the FROM expression to the subquery */ RangeTblRef *newRangeTableRef = makeNode(RangeTblRef); newRangeTableRef->rtindex = 1; @@ -2022,6 +2066,15 @@ TransformFunctionRTE(RangeTblEntry *rangeTblEntry) /* set the FROM expression to the subquery */ subquery->rtable = list_make1(newRangeTableEntry); + +#if PG_VERSION_NUM >= PG_VERSION_16 + + /* sanity check */ + Assert(newRangeTableEntry->rtekind == RTE_FUNCTION && + newRangeTableEntry->perminfoindex == 0); + subquery->rteperminfos = NIL; +#endif + newRangeTableRef->rtindex = 1; subquery->jointree = makeFromExpr(list_make1(newRangeTableRef), NULL); @@ -2392,6 +2445,9 @@ BuildReadIntermediateResultsQuery(List *targetEntryList, List *columnAliasList, Query *resultQuery = makeNode(Query); resultQuery->commandType = CMD_SELECT; resultQuery->rtable = list_make1(rangeTableEntry); +#if PG_VERSION_NUM >= PG_VERSION_16 + resultQuery->rteperminfos = NIL; +#endif resultQuery->jointree = joinTree; resultQuery->targetList = targetList; diff --git a/src/backend/distributed/utils/relation_utils.c b/src/backend/distributed/utils/relation_utils.c index ef02736ea..d39c1f071 100644 --- a/src/backend/distributed/utils/relation_utils.c +++ b/src/backend/distributed/utils/relation_utils.c @@ -45,9 +45,6 @@ RelationGetNamespaceName(Relation relation) * we are dealing with GetUserId(). * Currently the following entries are filled like this: * perminfo->checkAsUser = GetUserId(); - * perminfo->selectedCols = NULL; - * perminfo->insertedCols = NULL; - * perminfo->updatedCols = NULL; */ RTEPermissionInfo * GetFilledPermissionInfo(Oid relid, bool inh, AclMode requiredPerms) @@ -57,9 +54,6 @@ GetFilledPermissionInfo(Oid relid, bool inh, AclMode requiredPerms) perminfo->inh = inh; perminfo->requiredPerms = requiredPerms; perminfo->checkAsUser = GetUserId(); - perminfo->selectedCols = NULL; - perminfo->insertedCols = NULL; - perminfo->updatedCols = NULL; return perminfo; } diff --git a/src/include/distributed/query_colocation_checker.h b/src/include/distributed/query_colocation_checker.h index 969ecbcf9..3aef01e4a 100644 --- a/src/include/distributed/query_colocation_checker.h +++ b/src/include/distributed/query_colocation_checker.h @@ -35,7 +35,12 @@ extern ColocatedJoinChecker CreateColocatedJoinChecker(Query *subquery, restrictionContext); extern bool SubqueryColocated(Query *subquery, ColocatedJoinChecker *context); extern Query * WrapRteRelationIntoSubquery(RangeTblEntry *rteRelation, +#if PG_VERSION_NUM >= PG_VERSION_16 + List *requiredAttributes, + RTEPermissionInfo *perminfo); +#else List *requiredAttributes); +#endif extern List * CreateAllTargetListForRelation(Oid relationId, List *requiredAttributes); #endif /* QUERY_COLOCATION_CHECKER_H */ diff --git a/src/include/distributed/recursive_planning.h b/src/include/distributed/recursive_planning.h index 8943443aa..d25937ce0 100644 --- a/src/include/distributed/recursive_planning.h +++ b/src/include/distributed/recursive_planning.h @@ -42,7 +42,12 @@ extern bool GeneratingSubplans(void); extern bool ContainsLocalTableDistributedTableJoin(List *rangeTableList); extern void ReplaceRTERelationWithRteSubquery(RangeTblEntry *rangeTableEntry, List *requiredAttrNumbers, +#if PG_VERSION_NUM >= PG_VERSION_16 + RecursivePlanningContext *context, + RTEPermissionInfo *perminfo); +#else RecursivePlanningContext *context); +#endif extern bool IsRecursivelyPlannableRelation(RangeTblEntry *rangeTableEntry); extern bool IsRelationLocalTableOrMatView(Oid relationId); extern bool ContainsReferencesToOuterQuery(Query *query);