Fix permission info

naisila/check_router_fix
naisila 2023-07-27 13:37:50 +03:00
parent 0d4604ba86
commit abfdf48aa0
10 changed files with 144 additions and 95 deletions

View File

@ -1474,7 +1474,7 @@ FinalizeNonRouterPlan(PlannedStmt *localPlan, DistributedPlan *distributedPlan,
#if PG_VERSION_NUM >= PG_VERSION_16
/*
* Original range table list is concatented to final plan's range table list
* 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.
*/

View File

@ -31,7 +31,6 @@
#include "distributed/pg_dist_partition.h"
#include "distributed/query_pushdown_planning.h"
#include "distributed/recursive_planning.h"
#include "distributed/relation_utils.h"
#include "distributed/repartition_executor.h"
#include "distributed/resource_lock.h"
#include "distributed/version_compat.h"
@ -605,18 +604,18 @@ CreateCombineQueryForRouterPlan(DistributedPlan *distPlan)
combineQuery->rtable = list_make1(rangeTableEntry);
#if PG_VERSION_NUM >= PG_VERSION_16
combineQuery->rteperminfos = NIL;
if (rangeTableEntry->perminfoindex != 0)
{
/* create permission info for newRangeTableEntry */
RTEPermissionInfo *perminfo = GetFilledPermissionInfo(rangeTableEntry->relid,
rangeTableEntry->inh,
CMD_SELECT);
/* update the subquery's rteperminfos accordingly */
rangeTableEntry->perminfoindex = 1;
combineQuery->rteperminfos = list_make1(perminfo);
}
/*
* 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;
@ -1557,18 +1556,17 @@ WrapSubquery(Query *subquery)
outerQuery->rtable = list_make1(newRangeTableEntry);
#if PG_VERSION_NUM >= PG_VERSION_16
outerQuery->rteperminfos = NIL;
if (newRangeTableEntry->perminfoindex != 0)
{
/* create permission info for newRangeTableEntry */
RTEPermissionInfo *perminfo = GetFilledPermissionInfo(newRangeTableEntry->relid,
newRangeTableEntry->inh,
CMD_SELECT);
/* update the subquery's rteperminfos accordingly */
newRangeTableEntry->perminfoindex = 1;
outerQuery->rteperminfos = list_make1(perminfo);
}
/*
* 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 */

View File

@ -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) ||

View File

@ -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"
@ -31,7 +32,6 @@
#include "distributed/pg_version_constants.h"
#include "distributed/query_pushdown_planning.h"
#include "distributed/query_colocation_checker.h"
#include "distributed/relation_utils.h"
#include "distributed/repartition_executor.h"
#include "distributed/shared_library_init.h"
#include "distributed/shard_pruning.h"
@ -776,7 +776,9 @@ ConvertCteRTEIntoSubquery(Query *mergeQuery, RangeTblEntry *sourceRte)
sourceRte->rtekind = RTE_SUBQUERY;
#if PG_VERSION_NUM >= PG_VERSION_16
sourceRte->perminfoindex = 0;
/* sanity check - sourceRte was RTE_CTE previously so it should have no perminfo */
Assert(sourceRte->perminfoindex == 0);
#endif
/*
@ -830,12 +832,11 @@ ConvertRelationRTEIntoSubquery(Query *mergeQuery, RangeTblEntry *sourceRte,
#if PG_VERSION_NUM >= PG_VERSION_16
sourceResultsQuery->rteperminfos = NIL;
if (newRangeTableEntry->perminfoindex != 0)
if (newRangeTableEntry->perminfoindex)
{
/* create permission info for newRangeTableEntry */
RTEPermissionInfo *perminfo = GetFilledPermissionInfo(newRangeTableEntry->relid,
newRangeTableEntry->inh,
CMD_SELECT);
RTEPermissionInfo *perminfo = getRTEPermissionInfo(mergeQuery->rteperminfos,
newRangeTableEntry);
/* update the subquery's rteperminfos accordingly */
newRangeTableEntry->perminfoindex = 1;
@ -870,6 +871,12 @@ ConvertRelationRTEIntoSubquery(Query *mergeQuery, RangeTblEntry *sourceRte,
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;

View File

@ -28,7 +28,6 @@
#include "distributed/query_colocation_checker.h"
#include "distributed/pg_dist_partition.h"
#include "distributed/relation_restriction_equivalence.h"
#include "distributed/relation_utils.h"
#include "distributed/metadata_cache.h"
#include "distributed/multi_logical_planner.h" /* only to access utility functions */
@ -84,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)
{
@ -267,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);
@ -279,16 +293,8 @@ WrapRteRelationIntoSubquery(RangeTblEntry *rteRelation, List *requiredAttributes
subquery->rtable = list_make1(newRangeTableEntry);
#if PG_VERSION_NUM >= PG_VERSION_16
subquery->rteperminfos = NIL;
newRangeTableEntry->perminfoindex = 0;
if (rteRelation->perminfoindex != 0)
if (perminfo)
{
/* create permission info for newRangeTableEntry */
RTEPermissionInfo *perminfo = GetFilledPermissionInfo(newRangeTableEntry->relid,
newRangeTableEntry->inh,
ACL_SELECT);
/* update the subquery's rteperminfos accordingly */
newRangeTableEntry->perminfoindex = 1;
subquery->rteperminfos = list_make1(perminfo);
}

View File

@ -72,7 +72,6 @@
#include "distributed/query_pushdown_planning.h"
#include "distributed/recursive_planning.h"
#include "distributed/relation_restriction_equivalence.h"
#include "distributed/relation_utils.h"
#include "distributed/log_utils.h"
#include "distributed/shard_pruning.h"
#include "distributed/version_compat.h"
@ -81,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"
@ -89,7 +89,6 @@
#include "nodes/pg_list.h"
#include "nodes/primnodes.h"
#include "nodes/pathnodes.h"
#include "parser/parse_relation.h"
#include "utils/builtins.h"
#include "utils/guc.h"
#include "utils/lsyscache.h"
@ -888,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)
{
@ -1753,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);
@ -1781,6 +1805,12 @@ 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;
@ -1856,20 +1886,11 @@ CreateOuterSubquery(RangeTblEntry *rangeTableEntry, List *outerSubqueryTargetLis
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;
innerSubqueryRTE->perminfoindex = 0;
if (rangeTableEntry->perminfoindex != 0)
{
/* create permission info for innerSubqueryRTE */
RTEPermissionInfo *perminfo = GetFilledPermissionInfo(innerSubqueryRTE->relid,
innerSubqueryRTE->inh,
ACL_SELECT);
/* update the outerSubquery's rteperminfos accordingly */
innerSubqueryRTE->perminfoindex = 1;
outerSubquery->rteperminfos = list_make1(perminfo);
}
#endif
@ -2047,20 +2068,11 @@ TransformFunctionRTE(RangeTblEntry *rangeTblEntry)
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;
newRangeTableEntry->perminfoindex = 0;
if (rangeTblEntry->perminfoindex != 0)
{
/* create permission info for newRangeTableEntry */
RTEPermissionInfo *perminfo = GetFilledPermissionInfo(newRangeTableEntry->relid,
newRangeTableEntry->inh,
CMD_SELECT);
/* update the subquery's rteperminfos accordingly */
newRangeTableEntry->perminfoindex = 1;
subquery->rteperminfos = list_make1(perminfo);
}
#endif
newRangeTableRef->rtindex = 1;
@ -2196,9 +2208,6 @@ TransformFunctionRTE(RangeTblEntry *rangeTblEntry)
/* replace the function with the constructed subquery */
rangeTblEntry->rtekind = RTE_SUBQUERY;
#if PG_VERSION_NUM >= PG_VERSION_16
rangeTblEntry->perminfoindex = 0;
#endif
rangeTblEntry->subquery = subquery;
}
@ -2436,22 +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;
if (rangeTableEntry->perminfoindex != 0)
{
/* create permission info for newRangeTableEntry */
RTEPermissionInfo *perminfo = GetFilledPermissionInfo(rangeTableEntry->relid,
rangeTableEntry->inh,
CMD_SELECT);
/* update the subquery's rteperminfos accordingly */
rangeTableEntry->perminfoindex = 1;
resultQuery->rteperminfos = list_make1(perminfo);
}
#endif
resultQuery->jointree = joinTree;
resultQuery->targetList = targetList;

View File

@ -148,9 +148,6 @@ SetRangeTblExtraData(RangeTblEntry *rte, CitusRTEKind rteKind, char *fragmentSch
fauxFunction->funccolcollations = funcCollations;
rte->rtekind = RTE_FUNCTION;
#if PG_VERSION_NUM >= PG_VERSION_16
rte->perminfoindex = 0;
#endif
rte->functions = list_make1(fauxFunction);
}

View File

@ -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;
}

View File

@ -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 */

View File

@ -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);