1
0
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:
Amit Langote 2023-06-13 12:52:47 +09:00
parent ae66716bf3
commit 0f8cfaf892
6 changed files with 22 additions and 12 deletions

View File

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

View File

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

View File

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

View File

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

View File

@ -57,6 +57,6 @@
*/ */
/* yyyymmddN */ /* yyyymmddN */
#define CATALOG_VERSION_NO 202305211 #define CATALOG_VERSION_NO 202306141
#endif #endif

View File

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