PG16 compatibility - Rework PlannedStmt and Query's Permission Info (#7098)

PG16 compatibility - Part 6

Check out part 1 42d956888d
part 2 0d503dd5ac
part 3 907d72e60d
part 4 7c6b4ce103
part 5 6056cb2c29

This commit is in the series of PG16 compatibility commits.
It handles the Permission Info changes in PG16. See below:

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 crashes 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:
a61b1f7482
a61b1f74823c9c4f79c95226a461f1e7a367764b
b803b7d132
b803b7d132e3505ab77c29acf91f3d1caa298f95

More PG16 compatibility commits are coming soon ...
pull/7115/head
Naisila Puka 2023-08-09 15:23:00 +03:00 committed by GitHub
parent 6056cb2c29
commit b36c431abb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 210 additions and 19 deletions

View File

@ -358,6 +358,11 @@ ConvertRteToSubqueryWithEmptyResult(RangeTblEntry *rte)
subquery->jointree = joinTree; subquery->jointree = joinTree;
rte->rtekind = RTE_SUBQUERY; rte->rtekind = RTE_SUBQUERY;
#if PG_VERSION_NUM >= PG_VERSION_16
/* no permission checking for this RTE */
rte->perminfoindex = 0;
#endif
rte->subquery = subquery; rte->subquery = subquery;
rte->alias = copyObject(rte->eref); rte->alias = copyObject(rte->eref);
} }

View File

@ -56,6 +56,9 @@
#include "nodes/makefuncs.h" #include "nodes/makefuncs.h"
#include "nodes/nodeFuncs.h" #include "nodes/nodeFuncs.h"
#include "nodes/pg_list.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/parsetree.h"
#include "parser/parse_type.h" #include "parser/parse_type.h"
#include "optimizer/optimizer.h" #include "optimizer/optimizer.h"
@ -145,6 +148,8 @@ static void WarnIfListHasForeignDistributedTable(List *rangeTableList);
static RouterPlanType GetRouterPlanType(Query *query, static RouterPlanType GetRouterPlanType(Query *query,
Query *originalQuery, Query *originalQuery,
bool hasUnresolvedParams); bool hasUnresolvedParams);
static void ConcatenateRTablesAndPerminfos(PlannedStmt *mainPlan,
PlannedStmt *concatPlan);
/* Distributed planner hook */ /* Distributed planner hook */
@ -1081,6 +1086,11 @@ CreateDistributedPlan(uint64 planId, bool allowRecursivePlanning, Query *origina
/* /*
* Plan subqueries and CTEs that cannot be pushed down by recursively * Plan subqueries and CTEs that cannot be pushed down by recursively
* calling the planner and return the resulting plans to subPlanList. * calling the planner and return the resulting plans to subPlanList.
* Note that GenerateSubplansForSubqueriesAndCTEs will reset perminfoindexes
* for some RTEs in originalQuery->rtable list, while not changing
* originalQuery->rteperminfos. That's fine because we will go through
* standard_planner again, which will adjust things accordingly in
* set_plan_references>add_rtes_to_flat_rtable>add_rte_to_flat_rtable.
*/ */
List *subPlanList = GenerateSubplansForSubqueriesAndCTEs(planId, originalQuery, List *subPlanList = GenerateSubplansForSubqueriesAndCTEs(planId, originalQuery,
plannerRestrictionContext); plannerRestrictionContext);
@ -1480,12 +1490,42 @@ FinalizeNonRouterPlan(PlannedStmt *localPlan, DistributedPlan *distributedPlan,
finalPlan->utilityStmt = localPlan->utilityStmt; finalPlan->utilityStmt = localPlan->utilityStmt;
/* add original range table list for access permission checks */ /* add original range table list for access permission checks */
finalPlan->rtable = list_concat(finalPlan->rtable, localPlan->rtable); ConcatenateRTablesAndPerminfos(finalPlan, localPlan);
return finalPlan; return finalPlan;
} }
static void
ConcatenateRTablesAndPerminfos(PlannedStmt *mainPlan, PlannedStmt *concatPlan)
{
mainPlan->rtable = list_concat(mainPlan->rtable, concatPlan->rtable);
#if PG_VERSION_NUM >= PG_VERSION_16
/*
* concatPlan's range table list is concatenated to mainPlan's range table list
* therefore all the perminfoindexes should be updated to their value
* PLUS the highest perminfoindex in mainPlan's perminfos, which is exactly
* the list length.
*/
int mainPlan_highest_perminfoindex = list_length(mainPlan->permInfos);
ListCell *lc;
foreach(lc, concatPlan->rtable)
{
RangeTblEntry *rte = (RangeTblEntry *) lfirst(lc);
if (rte->perminfoindex != 0)
{
rte->perminfoindex = rte->perminfoindex + mainPlan_highest_perminfoindex;
}
}
/* finally, concatenate perminfos as well */
mainPlan->permInfos = list_concat(mainPlan->permInfos, concatPlan->permInfos);
#endif
}
/* /*
* FinalizeRouterPlan gets a CustomScan node which already wrapped distributed * FinalizeRouterPlan gets a CustomScan node which already wrapped distributed
* part of a router plan and sets it as the direct child of the router plan * part of a router plan and sets it as the direct child of the router plan
@ -1517,7 +1557,7 @@ FinalizeRouterPlan(PlannedStmt *localPlan, CustomScan *customScan)
routerPlan->rtable = list_make1(remoteScanRangeTableEntry); routerPlan->rtable = list_make1(remoteScanRangeTableEntry);
/* add original range table list for access permission checks */ /* add original range table list for access permission checks */
routerPlan->rtable = list_concat(routerPlan->rtable, localPlan->rtable); ConcatenateRTablesAndPerminfos(routerPlan, localPlan);
routerPlan->canSetTag = true; routerPlan->canSetTag = true;
routerPlan->relationOids = NIL; routerPlan->relationOids = NIL;

View File

@ -136,6 +136,9 @@ GeneratePlaceHolderPlannedStmt(Query *parse)
result->stmt_len = parse->stmt_len; result->stmt_len = parse->stmt_len;
result->rtable = copyObject(parse->rtable); result->rtable = copyObject(parse->rtable);
#if PG_VERSION_NUM >= PG_VERSION_16
result->permInfos = copyObject(parse->rteperminfos);
#endif
result->planTree = (Plan *) plan; result->planTree = (Plan *) plan;
result->hasReturning = (parse->returningList != NIL); result->hasReturning = (parse->returningList != NIL);

View File

@ -604,6 +604,22 @@ CreateCombineQueryForRouterPlan(DistributedPlan *distPlan)
combineQuery->querySource = QSRC_ORIGINAL; combineQuery->querySource = QSRC_ORIGINAL;
combineQuery->canSetTag = true; combineQuery->canSetTag = true;
combineQuery->rtable = list_make1(rangeTableEntry); 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->targetList = targetList;
combineQuery->jointree = joinTree; combineQuery->jointree = joinTree;
return combineQuery; return combineQuery;
@ -1533,6 +1549,20 @@ WrapSubquery(Query *subquery)
selectAlias, false, true)); selectAlias, false, true));
outerQuery->rtable = list_make1(newRangeTableEntry); 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 */ /* set the FROM expression to the subquery */
RangeTblRef *newRangeTableRef = makeNode(RangeTblRef); RangeTblRef *newRangeTableRef = makeNode(RangeTblRef);
newRangeTableRef->rtindex = 1; newRangeTableRef->rtindex = 1;

View File

@ -107,6 +107,7 @@
#include "optimizer/optimizer.h" #include "optimizer/optimizer.h"
#include "optimizer/planner.h" #include "optimizer/planner.h"
#include "optimizer/prep.h" #include "optimizer/prep.h"
#include "parser/parse_relation.h"
#include "parser/parsetree.h" #include "parser/parsetree.h"
#include "nodes/makefuncs.h" #include "nodes/makefuncs.h"
#include "nodes/nodeFuncs.h" #include "nodes/nodeFuncs.h"
@ -136,6 +137,9 @@ typedef struct RangeTableEntryDetails
RangeTblEntry *rangeTableEntry; RangeTblEntry *rangeTableEntry;
List *requiredAttributeNumbers; List *requiredAttributeNumbers;
bool hasConstantFilterOnUniqueColumn; bool hasConstantFilterOnUniqueColumn;
#if PG_VERSION_NUM >= PG_VERSION_16
RTEPermissionInfo *perminfo;
#endif
} RangeTableEntryDetails; } RangeTableEntryDetails;
/* /*
@ -176,7 +180,8 @@ static bool HasConstantFilterOnUniqueColumn(RangeTblEntry *rangeTableEntry,
static ConversionCandidates * CreateConversionCandidates(PlannerRestrictionContext * static ConversionCandidates * CreateConversionCandidates(PlannerRestrictionContext *
plannerRestrictionContext, plannerRestrictionContext,
List *rangeTableList, List *rangeTableList,
int resultRTEIdentity); int resultRTEIdentity,
List *rteperminfos);
static void AppendUniqueIndexColumnsToList(Form_pg_index indexForm, List **uniqueIndexes, static void AppendUniqueIndexColumnsToList(Form_pg_index indexForm, List **uniqueIndexes,
int flags); int flags);
static ConversionChoice GetConversionChoice(ConversionCandidates * static ConversionChoice GetConversionChoice(ConversionCandidates *
@ -205,10 +210,17 @@ RecursivelyPlanLocalTableJoins(Query *query,
GetPlannerRestrictionContext(context); GetPlannerRestrictionContext(context);
List *rangeTableList = query->rtable; List *rangeTableList = query->rtable;
#if PG_VERSION_NUM >= PG_VERSION_16
List *rteperminfos = query->rteperminfos;
#endif
int resultRTEIdentity = ResultRTEIdentity(query); int resultRTEIdentity = ResultRTEIdentity(query);
ConversionCandidates *conversionCandidates = ConversionCandidates *conversionCandidates =
CreateConversionCandidates(plannerRestrictionContext, CreateConversionCandidates(plannerRestrictionContext,
rangeTableList, resultRTEIdentity); #if PG_VERSION_NUM >= PG_VERSION_16
rangeTableList, resultRTEIdentity, rteperminfos);
#else
rangeTableList, resultRTEIdentity, NIL);
#endif
ConversionChoice conversionChoise = ConversionChoice conversionChoise =
GetConversionChoice(conversionCandidates, plannerRestrictionContext); GetConversionChoice(conversionCandidates, plannerRestrictionContext);
@ -323,7 +335,12 @@ ConvertRTEsToSubquery(List *rangeTableEntryDetailsList, RecursivePlanningContext
RangeTblEntry *rangeTableEntry = rangeTableEntryDetails->rangeTableEntry; RangeTblEntry *rangeTableEntry = rangeTableEntryDetails->rangeTableEntry;
List *requiredAttributeNumbers = rangeTableEntryDetails->requiredAttributeNumbers; List *requiredAttributeNumbers = rangeTableEntryDetails->requiredAttributeNumbers;
ReplaceRTERelationWithRteSubquery(rangeTableEntry, ReplaceRTERelationWithRteSubquery(rangeTableEntry,
requiredAttributeNumbers, context); #if PG_VERSION_NUM >= PG_VERSION_16
requiredAttributeNumbers, context,
rangeTableEntryDetails->perminfo);
#else
requiredAttributeNumbers, context, NULL);
#endif
} }
} }
@ -530,7 +547,9 @@ RequiredAttrNumbersForRelationInternal(Query *queryToProcess, int rteIndex)
*/ */
static ConversionCandidates * static ConversionCandidates *
CreateConversionCandidates(PlannerRestrictionContext *plannerRestrictionContext, CreateConversionCandidates(PlannerRestrictionContext *plannerRestrictionContext,
List *rangeTableList, int resultRTEIdentity) List *rangeTableList,
int resultRTEIdentity,
List *rteperminfos)
{ {
ConversionCandidates *conversionCandidates = ConversionCandidates *conversionCandidates =
palloc0(sizeof(ConversionCandidates)); palloc0(sizeof(ConversionCandidates));
@ -564,6 +583,14 @@ CreateConversionCandidates(PlannerRestrictionContext *plannerRestrictionContext,
RequiredAttrNumbersForRelation(rangeTableEntry, plannerRestrictionContext); RequiredAttrNumbersForRelation(rangeTableEntry, plannerRestrictionContext);
rangeTableEntryDetails->hasConstantFilterOnUniqueColumn = rangeTableEntryDetails->hasConstantFilterOnUniqueColumn =
HasConstantFilterOnUniqueColumn(rangeTableEntry, relationRestriction); HasConstantFilterOnUniqueColumn(rangeTableEntry, relationRestriction);
#if PG_VERSION_NUM >= PG_VERSION_16
rangeTableEntryDetails->perminfo = NULL;
if (rangeTableEntry->perminfoindex)
{
rangeTableEntryDetails->perminfo = getRTEPermissionInfo(rteperminfos,
rangeTableEntry);
}
#endif
bool referenceOrDistributedTable = bool referenceOrDistributedTable =
IsCitusTableType(rangeTableEntry->relid, REFERENCE_TABLE) || IsCitusTableType(rangeTableEntry->relid, REFERENCE_TABLE) ||

View File

@ -15,6 +15,7 @@
#include "nodes/makefuncs.h" #include "nodes/makefuncs.h"
#include "nodes/nodeFuncs.h" #include "nodes/nodeFuncs.h"
#include "optimizer/optimizer.h" #include "optimizer/optimizer.h"
#include "parser/parse_relation.h"
#include "parser/parsetree.h" #include "parser/parsetree.h"
#include "tcop/tcopprot.h" #include "tcop/tcopprot.h"
#include "utils/lsyscache.h" #include "utils/lsyscache.h"
@ -777,6 +778,11 @@ ConvertCteRTEIntoSubquery(Query *mergeQuery, RangeTblEntry *sourceRte)
Query *cteQuery = (Query *) copyObject(sourceCte->ctequery); Query *cteQuery = (Query *) copyObject(sourceCte->ctequery);
sourceRte->rtekind = RTE_SUBQUERY; 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 * As we are delinking the CTE from main query, we have to walk through the
@ -827,6 +833,20 @@ ConvertRelationRTEIntoSubquery(Query *mergeQuery, RangeTblEntry *sourceRte,
RangeTblEntry *newRangeTableEntry = copyObject(sourceRte); RangeTblEntry *newRangeTableEntry = copyObject(sourceRte);
sourceResultsQuery->rtable = list_make1(newRangeTableEntry); sourceResultsQuery->rtable = list_make1(newRangeTableEntry);
#if PG_VERSION_NUM >= PG_VERSION_16
sourceResultsQuery->rteperminfos = NIL;
if (sourceRte->perminfoindex)
{
/* create permission info for newRangeTableEntry */
RTEPermissionInfo *perminfo = getRTEPermissionInfo(mergeQuery->rteperminfos,
sourceRte);
/* update the sourceResultsQuery's rteperminfos accordingly */
newRangeTableEntry->perminfoindex = 1;
sourceResultsQuery->rteperminfos = list_make1(perminfo);
}
#endif
/* set the FROM expression to the subquery */ /* set the FROM expression to the subquery */
newRangeTableRef->rtindex = SINGLE_RTE_INDEX; newRangeTableRef->rtindex = SINGLE_RTE_INDEX;
sourceResultsQuery->jointree = makeFromExpr(list_make1(newRangeTableRef), NULL); sourceResultsQuery->jointree = makeFromExpr(list_make1(newRangeTableRef), NULL);
@ -852,6 +872,9 @@ ConvertRelationRTEIntoSubquery(Query *mergeQuery, RangeTblEntry *sourceRte,
/* replace the function with the constructed subquery */ /* replace the function with the constructed subquery */
sourceRte->rtekind = RTE_SUBQUERY; sourceRte->rtekind = RTE_SUBQUERY;
#if PG_VERSION_NUM >= PG_VERSION_16
sourceRte->perminfoindex = 0;
#endif
sourceRte->subquery = sourceResultsQuery; sourceRte->subquery = sourceResultsQuery;
sourceRte->inh = false; sourceRte->inh = false;
} }

View File

@ -83,7 +83,16 @@ CreateColocatedJoinChecker(Query *subquery, PlannerRestrictionContext *restricti
* functions (i.e., FilterPlannerRestrictionForQuery()) rely on queries * functions (i.e., FilterPlannerRestrictionForQuery()) rely on queries
* not relations. * not relations.
*/ */
anchorSubquery = WrapRteRelationIntoSubquery(anchorRangeTblEntry, NIL); #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, NULL);
#endif
} }
else if (anchorRangeTblEntry->rtekind == RTE_SUBQUERY) else if (anchorRangeTblEntry->rtekind == RTE_SUBQUERY)
{ {
@ -266,7 +275,9 @@ SubqueryColocated(Query *subquery, ColocatedJoinChecker *checker)
* designed for generating a stub query. * designed for generating a stub query.
*/ */
Query * Query *
WrapRteRelationIntoSubquery(RangeTblEntry *rteRelation, List *requiredAttributes) WrapRteRelationIntoSubquery(RangeTblEntry *rteRelation,
List *requiredAttributes,
RTEPermissionInfo *perminfo)
{ {
Query *subquery = makeNode(Query); Query *subquery = makeNode(Query);
RangeTblRef *newRangeTableRef = makeNode(RangeTblRef); RangeTblRef *newRangeTableRef = makeNode(RangeTblRef);
@ -277,6 +288,14 @@ WrapRteRelationIntoSubquery(RangeTblEntry *rteRelation, List *requiredAttributes
RangeTblEntry *newRangeTableEntry = copyObject(rteRelation); RangeTblEntry *newRangeTableEntry = copyObject(rteRelation);
subquery->rtable = list_make1(newRangeTableEntry); 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 */ /* set the FROM expression to the subquery */
newRangeTableRef = makeNode(RangeTblRef); newRangeTableRef = makeNode(RangeTblRef);
newRangeTableRef->rtindex = SINGLE_RTE_INDEX; newRangeTableRef->rtindex = SINGLE_RTE_INDEX;

View File

@ -1915,6 +1915,9 @@ SubqueryPushdownMultiNodeTree(Query *originalQuery)
pushedDownQuery->targetList = subqueryTargetEntryList; pushedDownQuery->targetList = subqueryTargetEntryList;
pushedDownQuery->jointree = copyObject(queryTree->jointree); pushedDownQuery->jointree = copyObject(queryTree->jointree);
pushedDownQuery->rtable = copyObject(queryTree->rtable); pushedDownQuery->rtable = copyObject(queryTree->rtable);
#if PG_VERSION_NUM >= PG_VERSION_16
pushedDownQuery->rteperminfos = copyObject(queryTree->rteperminfos);
#endif
pushedDownQuery->setOperations = copyObject(queryTree->setOperations); pushedDownQuery->setOperations = copyObject(queryTree->setOperations);
pushedDownQuery->querySource = queryTree->querySource; pushedDownQuery->querySource = queryTree->querySource;
pushedDownQuery->hasSubLinks = queryTree->hasSubLinks; pushedDownQuery->hasSubLinks = queryTree->hasSubLinks;

View File

@ -80,6 +80,7 @@
#include "optimizer/optimizer.h" #include "optimizer/optimizer.h"
#include "optimizer/planner.h" #include "optimizer/planner.h"
#include "optimizer/prep.h" #include "optimizer/prep.h"
#include "parser/parse_relation.h"
#include "parser/parsetree.h" #include "parser/parsetree.h"
#include "nodes/makefuncs.h" #include "nodes/makefuncs.h"
#include "nodes/nodeFuncs.h" #include "nodes/nodeFuncs.h"
@ -886,8 +887,19 @@ RecursivelyPlanDistributedJoinNode(Node *node, Query *query,
List *requiredAttributes = List *requiredAttributes =
RequiredAttrNumbersForRelation(distributedRte, restrictionContext); RequiredAttrNumbersForRelation(distributedRte, restrictionContext);
#if PG_VERSION_NUM >= PG_VERSION_16
RTEPermissionInfo *perminfo = NULL;
if (distributedRte->perminfoindex)
{
perminfo = getRTEPermissionInfo(query->rteperminfos, distributedRte);
}
ReplaceRTERelationWithRteSubquery(distributedRte, requiredAttributes, ReplaceRTERelationWithRteSubquery(distributedRte, requiredAttributes,
recursivePlanningContext); recursivePlanningContext, perminfo);
#else
ReplaceRTERelationWithRteSubquery(distributedRte, requiredAttributes,
recursivePlanningContext, NULL);
#endif
} }
else if (distributedRte->rtekind == RTE_SUBQUERY) else if (distributedRte->rtekind == RTE_SUBQUERY)
{ {
@ -1751,9 +1763,11 @@ NodeContainsSubqueryReferencingOuterQuery(Node *node)
void void
ReplaceRTERelationWithRteSubquery(RangeTblEntry *rangeTableEntry, ReplaceRTERelationWithRteSubquery(RangeTblEntry *rangeTableEntry,
List *requiredAttrNumbers, List *requiredAttrNumbers,
RecursivePlanningContext *context) RecursivePlanningContext *context,
RTEPermissionInfo *perminfo)
{ {
Query *subquery = WrapRteRelationIntoSubquery(rangeTableEntry, requiredAttrNumbers); Query *subquery = WrapRteRelationIntoSubquery(rangeTableEntry, requiredAttrNumbers,
perminfo);
List *outerQueryTargetList = CreateAllTargetListForRelation(rangeTableEntry->relid, List *outerQueryTargetList = CreateAllTargetListForRelation(rangeTableEntry->relid,
requiredAttrNumbers); requiredAttrNumbers);
@ -1778,6 +1792,9 @@ ReplaceRTERelationWithRteSubquery(RangeTblEntry *rangeTableEntry,
/* replace the function with the constructed subquery */ /* replace the function with the constructed subquery */
rangeTableEntry->rtekind = RTE_SUBQUERY; rangeTableEntry->rtekind = RTE_SUBQUERY;
#if PG_VERSION_NUM >= PG_VERSION_16
rangeTableEntry->perminfoindex = 0;
#endif
rangeTableEntry->subquery = subquery; rangeTableEntry->subquery = subquery;
/* /*
@ -1850,6 +1867,15 @@ CreateOuterSubquery(RangeTblEntry *rangeTableEntry, List *outerSubqueryTargetLis
innerSubqueryRTE->eref->colnames = innerSubqueryColNames; innerSubqueryRTE->eref->colnames = innerSubqueryColNames;
outerSubquery->rtable = list_make1(innerSubqueryRTE); 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 */ /* set the FROM expression to the subquery */
RangeTblRef *newRangeTableRef = makeNode(RangeTblRef); RangeTblRef *newRangeTableRef = makeNode(RangeTblRef);
newRangeTableRef->rtindex = 1; newRangeTableRef->rtindex = 1;
@ -2022,6 +2048,15 @@ TransformFunctionRTE(RangeTblEntry *rangeTblEntry)
/* set the FROM expression to the subquery */ /* set the FROM expression to the subquery */
subquery->rtable = list_make1(newRangeTableEntry); 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; newRangeTableRef->rtindex = 1;
subquery->jointree = makeFromExpr(list_make1(newRangeTableRef), NULL); subquery->jointree = makeFromExpr(list_make1(newRangeTableRef), NULL);
@ -2392,6 +2427,9 @@ BuildReadIntermediateResultsQuery(List *targetEntryList, List *columnAliasList,
Query *resultQuery = makeNode(Query); Query *resultQuery = makeNode(Query);
resultQuery->commandType = CMD_SELECT; resultQuery->commandType = CMD_SELECT;
resultQuery->rtable = list_make1(rangeTableEntry); resultQuery->rtable = list_make1(rangeTableEntry);
#if PG_VERSION_NUM >= PG_VERSION_16
resultQuery->rteperminfos = NIL;
#endif
resultQuery->jointree = joinTree; resultQuery->jointree = joinTree;
resultQuery->targetList = targetList; resultQuery->targetList = targetList;

View File

@ -45,9 +45,6 @@ RelationGetNamespaceName(Relation relation)
* we are dealing with GetUserId(). * we are dealing with GetUserId().
* Currently the following entries are filled like this: * Currently the following entries are filled like this:
* perminfo->checkAsUser = GetUserId(); * perminfo->checkAsUser = GetUserId();
* perminfo->selectedCols = NULL;
* perminfo->insertedCols = NULL;
* perminfo->updatedCols = NULL;
*/ */
RTEPermissionInfo * RTEPermissionInfo *
GetFilledPermissionInfo(Oid relid, bool inh, AclMode requiredPerms) GetFilledPermissionInfo(Oid relid, bool inh, AclMode requiredPerms)
@ -57,9 +54,6 @@ GetFilledPermissionInfo(Oid relid, bool inh, AclMode requiredPerms)
perminfo->inh = inh; perminfo->inh = inh;
perminfo->requiredPerms = requiredPerms; perminfo->requiredPerms = requiredPerms;
perminfo->checkAsUser = GetUserId(); perminfo->checkAsUser = GetUserId();
perminfo->selectedCols = NULL;
perminfo->insertedCols = NULL;
perminfo->updatedCols = NULL;
return perminfo; return perminfo;
} }

View File

@ -35,7 +35,8 @@ extern ColocatedJoinChecker CreateColocatedJoinChecker(Query *subquery,
restrictionContext); restrictionContext);
extern bool SubqueryColocated(Query *subquery, ColocatedJoinChecker *context); extern bool SubqueryColocated(Query *subquery, ColocatedJoinChecker *context);
extern Query * WrapRteRelationIntoSubquery(RangeTblEntry *rteRelation, extern Query * WrapRteRelationIntoSubquery(RangeTblEntry *rteRelation,
List *requiredAttributes); List *requiredAttributes,
RTEPermissionInfo *perminfo);
extern List * CreateAllTargetListForRelation(Oid relationId, List *requiredAttributes); extern List * CreateAllTargetListForRelation(Oid relationId, List *requiredAttributes);
#endif /* QUERY_COLOCATION_CHECKER_H */ #endif /* QUERY_COLOCATION_CHECKER_H */

View File

@ -42,7 +42,8 @@ extern bool GeneratingSubplans(void);
extern bool ContainsLocalTableDistributedTableJoin(List *rangeTableList); extern bool ContainsLocalTableDistributedTableJoin(List *rangeTableList);
extern void ReplaceRTERelationWithRteSubquery(RangeTblEntry *rangeTableEntry, extern void ReplaceRTERelationWithRteSubquery(RangeTblEntry *rangeTableEntry,
List *requiredAttrNumbers, List *requiredAttrNumbers,
RecursivePlanningContext *context); RecursivePlanningContext *context,
RTEPermissionInfo *perminfo);
extern bool IsRecursivelyPlannableRelation(RangeTblEntry *rangeTableEntry); extern bool IsRecursivelyPlannableRelation(RangeTblEntry *rangeTableEntry);
extern bool IsRelationLocalTableOrMatView(Oid relationId); extern bool IsRelationLocalTableOrMatView(Oid relationId);
extern bool ContainsReferencesToOuterQuery(Query *query); extern bool ContainsReferencesToOuterQuery(Query *query);

View File

@ -144,6 +144,13 @@ object_aclcheck(Oid classid, Oid objectid, Oid roleid, AclMode mode)
typedef bool TU_UpdateIndexes; typedef bool TU_UpdateIndexes;
/*
* we define RTEPermissionInfo for PG16 compatibility
* There are some functions that need to include RTEPermissionInfo in their signature
* for PG14/PG15 we pass a NULL argument in these functions
*/
typedef RangeTblEntry RTEPermissionInfo;
#endif #endif
#if PG_VERSION_NUM >= PG_VERSION_15 #if PG_VERSION_NUM >= PG_VERSION_15