Retain relkind too in RTE_SUBQUERY entries for views.
47bb9db75 modified the ApplyRetrieveRule()'s conversion of a view's original RTE_RELATION entry into an RTE_SUBQUERY one to retain relid, rellockmode, and perminfoindex so that the executor can lock the view and check its permissions. It seems better to also retain relkind for cross-checking that the exception of an RTE_SUBQUERY entry being allowed to carry relation details only applies to views, so do so. Bump catversion because this changes the output format of RTE_SUBQUERY RTEs. Suggested-by: David Steele <david@pgmasters.net> Reviewed-by: David Steele <david@pgmasters.net> Reviewed-by: Álvaro Herrera <alvherre@alvh.no-ip.org> Discussion: https://postgr.es/m/3953179e-9540-e5d1-a743-4bef368785b0%40pgmasters.net
This commit is contained in:
parent
ae66716bf3
commit
0f8cfaf892
@ -595,6 +595,15 @@ ExecCheckPermissions(List *rangeTable, List *rteperminfos,
|
||||
if (rte->perminfoindex != 0)
|
||||
{
|
||||
/* Sanity checks */
|
||||
|
||||
/*
|
||||
* Only relation RTEs and subquery RTEs that were once relation
|
||||
* RTEs (views) have their perminfoindex set.
|
||||
*/
|
||||
Assert(rte->rtekind == RTE_RELATION ||
|
||||
(rte->rtekind == RTE_SUBQUERY &&
|
||||
rte->relkind == RELKIND_VIEW));
|
||||
|
||||
(void) getRTEPermissionInfo(rteperminfos, rte);
|
||||
/* Many-to-one mapping not allowed */
|
||||
Assert(!bms_is_member(rte->perminfoindex, indexset));
|
||||
|
@ -513,6 +513,7 @@ _outRangeTblEntry(StringInfo str, const RangeTblEntry *node)
|
||||
WRITE_BOOL_FIELD(security_barrier);
|
||||
/* we re-use these RELATION fields, too: */
|
||||
WRITE_OID_FIELD(relid);
|
||||
WRITE_CHAR_FIELD(relkind);
|
||||
WRITE_INT_FIELD(rellockmode);
|
||||
WRITE_UINT_FIELD(perminfoindex);
|
||||
break;
|
||||
|
@ -503,6 +503,7 @@ _readRangeTblEntry(void)
|
||||
READ_BOOL_FIELD(security_barrier);
|
||||
/* we re-use these RELATION fields, too: */
|
||||
READ_OID_FIELD(relid);
|
||||
READ_CHAR_FIELD(relkind);
|
||||
READ_INT_FIELD(rellockmode);
|
||||
READ_UINT_FIELD(perminfoindex);
|
||||
break;
|
||||
|
@ -1851,11 +1851,10 @@ ApplyRetrieveRule(Query *parsetree,
|
||||
|
||||
/*
|
||||
* Clear fields that should not be set in a subquery RTE. Note that we
|
||||
* leave the relid, rellockmode, and perminfoindex fields set, so that the
|
||||
* view relation can be appropriately locked before execution and its
|
||||
* permissions checked.
|
||||
* leave the relid, relkind, rellockmode, and perminfoindex fields set, so
|
||||
* that the view relation can be appropriately locked before execution and
|
||||
* its permissions checked.
|
||||
*/
|
||||
rte->relkind = 0;
|
||||
rte->tablesample = NULL;
|
||||
rte->inh = false; /* must not be set for a subquery */
|
||||
|
||||
|
@ -57,6 +57,6 @@
|
||||
*/
|
||||
|
||||
/* yyyymmddN */
|
||||
#define CATALOG_VERSION_NO 202305211
|
||||
#define CATALOG_VERSION_NO 202306141
|
||||
|
||||
#endif
|
||||
|
@ -1056,13 +1056,13 @@ typedef struct RangeTblEntry
|
||||
* this RTE in the containing struct's list of same; 0 if permissions need
|
||||
* not be checked for this RTE.
|
||||
*
|
||||
* As a special case, relid, rellockmode, and perminfoindex can also be
|
||||
* set (nonzero) in an RTE_SUBQUERY RTE. This occurs when we convert an
|
||||
* RTE_RELATION RTE naming a view into an RTE_SUBQUERY containing the
|
||||
* view's query. We still need to perform run-time locking and permission
|
||||
* checks on the view, even though it's not directly used in the query
|
||||
* anymore, and the most expedient way to do that is to retain these
|
||||
* fields from the old state of the RTE.
|
||||
* As a special case, relid, relkind, rellockmode, and perminfoindex can
|
||||
* also be set (nonzero) in an RTE_SUBQUERY RTE. This occurs when we
|
||||
* convert an RTE_RELATION RTE naming a view into an RTE_SUBQUERY
|
||||
* containing the view's query. We still need to perform run-time locking
|
||||
* and permission checks on the view, even though it's not directly used
|
||||
* in the query anymore, and the most expedient way to do that is to
|
||||
* retain these fields from the old state of the RTE.
|
||||
*
|
||||
* As a special case, RTE_NAMEDTUPLESTORE can also set relid to indicate
|
||||
* that the tuple format of the tuplestore is the same as the referenced
|
||||
|
Loading…
x
Reference in New Issue
Block a user