mirror of
https://github.com/postgres/postgres.git
synced 2025-04-29 13:56:47 +03:00
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)
|
if (rte->perminfoindex != 0)
|
||||||
{
|
{
|
||||||
/* Sanity checks */
|
/* 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);
|
(void) getRTEPermissionInfo(rteperminfos, rte);
|
||||||
/* Many-to-one mapping not allowed */
|
/* Many-to-one mapping not allowed */
|
||||||
Assert(!bms_is_member(rte->perminfoindex, indexset));
|
Assert(!bms_is_member(rte->perminfoindex, indexset));
|
||||||
|
@ -513,6 +513,7 @@ _outRangeTblEntry(StringInfo str, const RangeTblEntry *node)
|
|||||||
WRITE_BOOL_FIELD(security_barrier);
|
WRITE_BOOL_FIELD(security_barrier);
|
||||||
/* we re-use these RELATION fields, too: */
|
/* we re-use these RELATION fields, too: */
|
||||||
WRITE_OID_FIELD(relid);
|
WRITE_OID_FIELD(relid);
|
||||||
|
WRITE_CHAR_FIELD(relkind);
|
||||||
WRITE_INT_FIELD(rellockmode);
|
WRITE_INT_FIELD(rellockmode);
|
||||||
WRITE_UINT_FIELD(perminfoindex);
|
WRITE_UINT_FIELD(perminfoindex);
|
||||||
break;
|
break;
|
||||||
|
@ -503,6 +503,7 @@ _readRangeTblEntry(void)
|
|||||||
READ_BOOL_FIELD(security_barrier);
|
READ_BOOL_FIELD(security_barrier);
|
||||||
/* we re-use these RELATION fields, too: */
|
/* we re-use these RELATION fields, too: */
|
||||||
READ_OID_FIELD(relid);
|
READ_OID_FIELD(relid);
|
||||||
|
READ_CHAR_FIELD(relkind);
|
||||||
READ_INT_FIELD(rellockmode);
|
READ_INT_FIELD(rellockmode);
|
||||||
READ_UINT_FIELD(perminfoindex);
|
READ_UINT_FIELD(perminfoindex);
|
||||||
break;
|
break;
|
||||||
|
@ -1851,11 +1851,10 @@ ApplyRetrieveRule(Query *parsetree,
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Clear fields that should not be set in a subquery RTE. Note that we
|
* 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
|
* leave the relid, relkind, rellockmode, and perminfoindex fields set, so
|
||||||
* view relation can be appropriately locked before execution and its
|
* that the view relation can be appropriately locked before execution and
|
||||||
* permissions checked.
|
* its permissions checked.
|
||||||
*/
|
*/
|
||||||
rte->relkind = 0;
|
|
||||||
rte->tablesample = NULL;
|
rte->tablesample = NULL;
|
||||||
rte->inh = false; /* must not be set for a subquery */
|
rte->inh = false; /* must not be set for a subquery */
|
||||||
|
|
||||||
|
@ -57,6 +57,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* yyyymmddN */
|
/* yyyymmddN */
|
||||||
#define CATALOG_VERSION_NO 202305211
|
#define CATALOG_VERSION_NO 202306141
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -1056,13 +1056,13 @@ typedef struct RangeTblEntry
|
|||||||
* this RTE in the containing struct's list of same; 0 if permissions need
|
* this RTE in the containing struct's list of same; 0 if permissions need
|
||||||
* not be checked for this RTE.
|
* not be checked for this RTE.
|
||||||
*
|
*
|
||||||
* As a special case, relid, rellockmode, and perminfoindex can also be
|
* As a special case, relid, relkind, rellockmode, and perminfoindex can
|
||||||
* set (nonzero) in an RTE_SUBQUERY RTE. This occurs when we convert an
|
* also be set (nonzero) in an RTE_SUBQUERY RTE. This occurs when we
|
||||||
* RTE_RELATION RTE naming a view into an RTE_SUBQUERY containing the
|
* convert an RTE_RELATION RTE naming a view into an RTE_SUBQUERY
|
||||||
* view's query. We still need to perform run-time locking and permission
|
* containing the view's query. We still need to perform run-time locking
|
||||||
* checks on the view, even though it's not directly used in the query
|
* and permission checks on the view, even though it's not directly used
|
||||||
* anymore, and the most expedient way to do that is to retain these
|
* in the query anymore, and the most expedient way to do that is to
|
||||||
* fields from the old state of the RTE.
|
* retain these fields from the old state of the RTE.
|
||||||
*
|
*
|
||||||
* As a special case, RTE_NAMEDTUPLESTORE can also set relid to indicate
|
* 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
|
* that the tuple format of the tuplestore is the same as the referenced
|
||||||
|
Loading…
x
Reference in New Issue
Block a user