diff options
Diffstat (limited to 'src/include')
-rw-r--r-- | src/include/catalog/catversion.h | 2 | ||||
-rw-r--r-- | src/include/commands/copyfrom_internal.h | 3 | ||||
-rw-r--r-- | src/include/executor/executor.h | 10 | ||||
-rw-r--r-- | src/include/nodes/execnodes.h | 3 | ||||
-rw-r--r-- | src/include/nodes/parsenodes.h | 94 | ||||
-rw-r--r-- | src/include/nodes/pathnodes.h | 3 | ||||
-rw-r--r-- | src/include/nodes/plannodes.h | 3 | ||||
-rw-r--r-- | src/include/optimizer/inherit.h | 2 | ||||
-rw-r--r-- | src/include/parser/parse_node.h | 9 | ||||
-rw-r--r-- | src/include/parser/parse_relation.h | 4 | ||||
-rw-r--r-- | src/include/rewrite/rewriteHandler.h | 1 | ||||
-rw-r--r-- | src/include/rewrite/rewriteManip.h | 2 |
12 files changed, 95 insertions, 41 deletions
diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h index 8e80a075a27..51e5acfe4fb 100644 --- a/src/include/catalog/catversion.h +++ b/src/include/catalog/catversion.h @@ -57,6 +57,6 @@ */ /* yyyymmddN */ -#define CATALOG_VERSION_NO 202212011 +#define CATALOG_VERSION_NO 202212061 #endif diff --git a/src/include/commands/copyfrom_internal.h b/src/include/commands/copyfrom_internal.h index 8d9cc5accdb..c5e5875eb87 100644 --- a/src/include/commands/copyfrom_internal.h +++ b/src/include/commands/copyfrom_internal.h @@ -97,7 +97,8 @@ typedef struct CopyFromStateData int *defmap; /* array of default att numbers */ ExprState **defexprs; /* array of default att expressions */ bool volatile_defexprs; /* is any of defexprs volatile? */ - List *range_table; + List *range_table; /* single element list of RangeTblEntry */ + List *rteperminfos; /* single element list of RTEPermissionInfo */ ExprState *qualexpr; TransitionCaptureState *transition_capture; diff --git a/src/include/executor/executor.h b/src/include/executor/executor.h index aaf2bc78b9c..a1202a0cf5f 100644 --- a/src/include/executor/executor.h +++ b/src/include/executor/executor.h @@ -80,8 +80,10 @@ extern PGDLLIMPORT ExecutorFinish_hook_type ExecutorFinish_hook; typedef void (*ExecutorEnd_hook_type) (QueryDesc *queryDesc); extern PGDLLIMPORT ExecutorEnd_hook_type ExecutorEnd_hook; -/* Hook for plugins to get control in ExecCheckRTPerms() */ -typedef bool (*ExecutorCheckPerms_hook_type) (List *, bool); +/* Hook for plugins to get control in ExecCheckPermissions() */ +typedef bool (*ExecutorCheckPerms_hook_type) (List *rangeTable, + List *rtePermInfos, + bool ereport_on_violation); extern PGDLLIMPORT ExecutorCheckPerms_hook_type ExecutorCheckPerms_hook; @@ -196,7 +198,8 @@ extern void standard_ExecutorFinish(QueryDesc *queryDesc); extern void ExecutorEnd(QueryDesc *queryDesc); extern void standard_ExecutorEnd(QueryDesc *queryDesc); extern void ExecutorRewind(QueryDesc *queryDesc); -extern bool ExecCheckRTPerms(List *rangeTable, bool ereport_on_violation); +extern bool ExecCheckPermissions(List *rangeTable, + List *rteperminfos, bool ereport_on_violation); extern void CheckValidResultRel(ResultRelInfo *resultRelInfo, CmdType operation); extern void InitResultRelInfo(ResultRelInfo *resultRelInfo, Relation resultRelationDesc, @@ -602,6 +605,7 @@ extern TupleTableSlot *ExecGetReturningSlot(EState *estate, ResultRelInfo *relIn extern TupleConversionMap *ExecGetChildToRootMap(ResultRelInfo *resultRelInfo); extern TupleConversionMap *ExecGetRootToChildMap(ResultRelInfo *resultRelInfo, EState *estate); +extern Oid ExecGetResultRelCheckAsUser(ResultRelInfo *relInfo, EState *estate); extern Bitmapset *ExecGetInsertedCols(ResultRelInfo *relinfo, EState *estate); extern Bitmapset *ExecGetUpdatedCols(ResultRelInfo *relinfo, EState *estate); extern Bitmapset *ExecGetExtraUpdatedCols(ResultRelInfo *relinfo, EState *estate); diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h index 71248a94660..08ad9d6be3f 100644 --- a/src/include/nodes/execnodes.h +++ b/src/include/nodes/execnodes.h @@ -617,8 +617,9 @@ typedef struct EState * pointers, or NULL if not yet opened */ struct ExecRowMark **es_rowmarks; /* Array of per-range-table-entry * ExecRowMarks, or NULL if none */ + List *es_rteperminfos; /* List of RTEPermissionInfo */ PlannedStmt *es_plannedstmt; /* link to top of plan tree */ - List *es_part_prune_infos; /* PlannedStmt.partPruneInfos */ + List *es_part_prune_infos; /* PlannedStmt.partPruneInfos */ const char *es_sourceText; /* Source text from QueryDesc */ JunkFilter *es_junkFilter; /* top-level junk filter, if any */ diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h index f17846e30e2..6a6d3293e41 100644 --- a/src/include/nodes/parsenodes.h +++ b/src/include/nodes/parsenodes.h @@ -154,6 +154,8 @@ typedef struct Query List *cteList; /* WITH list (of CommonTableExpr's) */ List *rtable; /* list of range table entries */ + List *rteperminfos; /* list of RTEPermissionInfo nodes for the + * rtable entries having perminfoindex > 0 */ FromExpr *jointree; /* table join tree (FROM and WHERE clauses); * also USING clause for MERGE */ @@ -968,37 +970,6 @@ typedef struct PartitionCmd * control visibility. But it is needed by ruleutils.c to determine * whether RTEs should be shown in decompiled queries. * - * requiredPerms and checkAsUser specify run-time access permissions - * checks to be performed at query startup. The user must have *all* - * of the permissions that are OR'd together in requiredPerms (zero - * indicates no permissions checking). If checkAsUser is not zero, - * then do the permissions checks using the access rights of that user, - * not the current effective user ID. (This allows rules to act as - * setuid gateways.) Permissions checks only apply to RELATION RTEs. - * - * For SELECT/INSERT/UPDATE permissions, if the user doesn't have - * table-wide permissions then it is sufficient to have the permissions - * on all columns identified in selectedCols (for SELECT) and/or - * insertedCols and/or updatedCols (INSERT with ON CONFLICT DO UPDATE may - * have all 3). selectedCols, insertedCols and updatedCols are bitmapsets, - * which cannot have negative integer members, so we subtract - * FirstLowInvalidHeapAttributeNumber from column numbers before storing - * them in these fields. A whole-row Var reference is represented by - * setting the bit for InvalidAttrNumber. - * - * updatedCols is also used in some other places, for example, to determine - * which triggers to fire and in FDWs to know which changed columns they - * need to ship off. - * - * Generated columns that are caused to be updated by an update to a base - * column are listed in extraUpdatedCols. This is not considered for - * permission checking, but it is useful in those places that want to know - * the full set of columns being updated as opposed to only the ones the - * user explicitly mentioned in the query. (There is currently no need for - * an extraInsertedCols, but it could exist.) Note that extraUpdatedCols - * is populated during query rewrite, NOT in the parser, since generated - * columns could be added after a rule has been parsed and stored. - * * securityQuals is a list of security barrier quals (boolean expressions), * to be tested in the listed order before returning a row from the * relation. It is always NIL in parser output. Entries are added by the @@ -1054,11 +1025,16 @@ typedef struct RangeTblEntry * current query; this happens if a DO ALSO rule simply scans the original * target table. We leave such RTEs with their original lockmode so as to * avoid getting an additional, lesser lock. + * + * perminfoindex is 1-based index of the RTEPermissionInfo belonging to + * this RTE in the containing struct's list of same; 0 if permissions need + * not be checked for this RTE. */ Oid relid; /* OID of the relation */ char relkind; /* relation kind (see pg_class.relkind) */ int rellockmode; /* lock level that query requires on the rel */ struct TableSampleClause *tablesample; /* sampling info, or NULL */ + Index perminfoindex; /* * Fields valid for a subquery RTE (else NULL): @@ -1178,14 +1154,64 @@ typedef struct RangeTblEntry bool lateral; /* subquery, function, or values is LATERAL? */ bool inh; /* inheritance requested? */ bool inFromCl; /* present in FROM clause? */ + Bitmapset *extraUpdatedCols; /* generated columns being updated */ + List *securityQuals; /* security barrier quals to apply, if any */ +} RangeTblEntry; + +/* + * RTEPermissionInfo + * Per-relation information for permission checking. Added to the Query + * node by the parser when adding the corresponding RTE to the query + * range table and subsequently editorialized on by the rewriter if + * needed after rule expansion. + * + * Only the relations directly mentioned in the query are checked for + * accesss permissions by the core executor, so only their RTEPermissionInfos + * are present in the Query. However, extensions may want to check inheritance + * children too, depending on the value of rte->inh, so it's copied in 'inh' + * for their perusal. + * + * requiredPerms and checkAsUser specify run-time access permissions checks + * to be performed at query startup. The user must have *all* of the + * permissions that are OR'd together in requiredPerms (never 0!). If + * checkAsUser is not zero, then do the permissions checks using the access + * rights of that user, not the current effective user ID. (This allows rules + * to act as setuid gateways.) + * + * For SELECT/INSERT/UPDATE permissions, if the user doesn't have table-wide + * permissions then it is sufficient to have the permissions on all columns + * identified in selectedCols (for SELECT) and/or insertedCols and/or + * updatedCols (INSERT with ON CONFLICT DO UPDATE may have all 3). + * selectedCols, insertedCols and updatedCols are bitmapsets, which cannot have + * negative integer members, so we subtract FirstLowInvalidHeapAttributeNumber + * from column numbers before storing them in these fields. A whole-row Var + * reference is represented by setting the bit for InvalidAttrNumber. + * + * updatedCols is also used in some other places, for example, to determine + * which triggers to fire and in FDWs to know which changed columns they need + * to ship off. + * + * Generated columns that are caused to be updated by an update to a base + * column are listed in extraUpdatedCols. This is not considered for + * permission checking, but it is useful in those places that want to know the + * full set of columns being updated as opposed to only the ones the user + * explicitly mentioned in the query. (There is currently no need for an + * extraInsertedCols, but it could exist.) Note that extraUpdatedCols is + * populated during query rewrite, NOT in the parser, since generated columns + * could be added after a rule has been parsed and stored. + */ +typedef struct RTEPermissionInfo +{ + NodeTag type; + + Oid relid; /* relation OID */ + bool inh; /* separately check inheritance children? */ AclMode requiredPerms; /* bitmask of required access permissions */ Oid checkAsUser; /* if valid, check access as this role */ Bitmapset *selectedCols; /* columns needing SELECT permission */ Bitmapset *insertedCols; /* columns needing INSERT permission */ Bitmapset *updatedCols; /* columns needing UPDATE permission */ - Bitmapset *extraUpdatedCols; /* generated columns being updated */ - List *securityQuals; /* security barrier quals to apply, if any */ -} RangeTblEntry; +} RTEPermissionInfo; /* * RangeTblFunction - diff --git a/src/include/nodes/pathnodes.h b/src/include/nodes/pathnodes.h index 12624e6adb1..654dba61aa0 100644 --- a/src/include/nodes/pathnodes.h +++ b/src/include/nodes/pathnodes.h @@ -113,6 +113,9 @@ typedef struct PlannerGlobal /* "flat" rangetable for executor */ List *finalrtable; + /* "flat" list of RTEPermissionInfos */ + List *finalrteperminfos; + /* "flat" list of PlanRowMarks */ List *finalrowmarks; diff --git a/src/include/nodes/plannodes.h b/src/include/nodes/plannodes.h index c36a15bd09d..bddfe861912 100644 --- a/src/include/nodes/plannodes.h +++ b/src/include/nodes/plannodes.h @@ -75,6 +75,9 @@ typedef struct PlannedStmt List *rtable; /* list of RangeTblEntry nodes */ + List *permInfos; /* list of RTEPermissionInfo nodes for rtable + * entries needing one */ + /* rtable indexes of target relations for INSERT/UPDATE/DELETE/MERGE */ List *resultRelations; /* integer list of RT indexes, or NIL */ diff --git a/src/include/optimizer/inherit.h b/src/include/optimizer/inherit.h index adcb1d73722..8ebd42b757a 100644 --- a/src/include/optimizer/inherit.h +++ b/src/include/optimizer/inherit.h @@ -20,6 +20,8 @@ extern void expand_inherited_rtentry(PlannerInfo *root, RelOptInfo *rel, RangeTblEntry *rte, Index rti); +extern Bitmapset *get_rel_all_updated_cols(PlannerInfo *root, RelOptInfo *rel); + extern bool apply_child_basequals(PlannerInfo *root, RelOptInfo *parentrel, RelOptInfo *childrel, RangeTblEntry *childRTE, AppendRelInfo *appinfo); diff --git a/src/include/parser/parse_node.h b/src/include/parser/parse_node.h index 962ebf65de1..3fd56ceccdf 100644 --- a/src/include/parser/parse_node.h +++ b/src/include/parser/parse_node.h @@ -111,6 +111,9 @@ typedef Node *(*CoerceParamHook) (ParseState *pstate, Param *param, * Note that neither relname nor refname of these entries are necessarily * unique; searching the rtable by name is a bad idea. * + * p_rteperminfos: list of RTEPermissionInfo containing an entry corresponding + * to each RTE_RELATION entry in p_rtable. + * * p_joinexprs: list of JoinExpr nodes associated with p_rtable entries. * This is one-for-one with p_rtable, but contains NULLs for non-join * RTEs, and may be shorter than p_rtable if the last RTE(s) aren't joins. @@ -181,6 +184,8 @@ struct ParseState ParseState *parentParseState; /* stack link */ const char *p_sourcetext; /* source text, or NULL if not available */ List *p_rtable; /* range table so far */ + List *p_rteperminfos; /* list of RTEPermissionInfo nodes for each + * RTE_RELATION entry in rtable */ List *p_joinexprs; /* JoinExprs for RTE_JOIN p_rtable entries */ List *p_joinlist; /* join items so far (will become FromExpr * node's fromlist) */ @@ -234,7 +239,8 @@ struct ParseState * join's first N columns, the net effect is just that we expose only those * join columns via this nsitem.) * - * p_rte and p_rtindex link to the underlying rangetable entry. + * p_rte and p_rtindex link to the underlying rangetable entry, and + * p_perminfo to the entry in rteperminfos. * * The p_nscolumns array contains info showing how to construct Vars * referencing the names appearing in the p_names->colnames list. @@ -271,6 +277,7 @@ struct ParseNamespaceItem Alias *p_names; /* Table and column names */ RangeTblEntry *p_rte; /* The relation's rangetable entry */ int p_rtindex; /* The relation's index in the rangetable */ + RTEPermissionInfo *p_perminfo; /* The relation's rteperminfos entry */ /* array of same length as p_names->colnames: */ ParseNamespaceColumn *p_nscolumns; /* per-column data */ bool p_rel_visible; /* Relation name is visible? */ diff --git a/src/include/parser/parse_relation.h b/src/include/parser/parse_relation.h index 484db165dbf..2f8d417709f 100644 --- a/src/include/parser/parse_relation.h +++ b/src/include/parser/parse_relation.h @@ -99,6 +99,10 @@ extern ParseNamespaceItem *addRangeTableEntryForCTE(ParseState *pstate, extern ParseNamespaceItem *addRangeTableEntryForENR(ParseState *pstate, RangeVar *rv, bool inFromCl); +extern RTEPermissionInfo *addRTEPermissionInfo(List **rteperminfos, + RangeTblEntry *rte); +extern RTEPermissionInfo *getRTEPermissionInfo(List *rteperminfos, + RangeTblEntry *rte); extern bool isLockedRefname(ParseState *pstate, const char *refname); extern void addNSItemToQuery(ParseState *pstate, ParseNamespaceItem *nsitem, bool addToJoinList, diff --git a/src/include/rewrite/rewriteHandler.h b/src/include/rewrite/rewriteHandler.h index 90ecf109afc..05c3680cd6a 100644 --- a/src/include/rewrite/rewriteHandler.h +++ b/src/include/rewrite/rewriteHandler.h @@ -25,6 +25,7 @@ extern void AcquireRewriteLocks(Query *parsetree, extern Node *build_column_default(Relation rel, int attrno); extern void fill_extraUpdatedCols(RangeTblEntry *target_rte, + RTEPermissionInfo *target_perminfo, Relation target_relation); extern Query *get_view_query(Relation view); diff --git a/src/include/rewrite/rewriteManip.h b/src/include/rewrite/rewriteManip.h index f001ca41bbc..05e6fe1f4b9 100644 --- a/src/include/rewrite/rewriteManip.h +++ b/src/include/rewrite/rewriteManip.h @@ -41,6 +41,8 @@ typedef enum ReplaceVarsNoMatchOption } ReplaceVarsNoMatchOption; +extern void CombineRangeTables(List **dst_rtable, List **dst_perminfos, + List *src_rtable, List *src_perminfos); extern void OffsetVarNodes(Node *node, int offset, int sublevels_up); extern void ChangeVarNodes(Node *node, int rt_index, int new_index, int sublevels_up); |