From 616c84c79d85eb2f20858de4cfc43932dd319295 Mon Sep 17 00:00:00 2001 From: amitlan Date: Wed, 18 Jan 2023 16:49:49 +0900 Subject: [PATCH v4] Correctly set userid of subquery rel's child rels For a RTE_SUBQUERY parent baserel's child relation that itself is a RTE_RELATION rel, build_simple_rel() should explicitly look up the latter's RTEPermissionInfo instead of copying the parent rel's userid, which would be 0 given that it's a subquery rel. --- src/backend/optimizer/util/relnode.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/backend/optimizer/util/relnode.c b/src/backend/optimizer/util/relnode.c index a70a16238a..6c4550b90f 100644 --- a/src/backend/optimizer/util/relnode.c +++ b/src/backend/optimizer/util/relnode.c @@ -233,12 +233,22 @@ build_simple_rel(PlannerInfo *root, int relid, RelOptInfo *parent) rel->serverid = InvalidOid; if (rte->rtekind == RTE_RELATION) { + Assert(parent == NULL || + parent->rtekind == RTE_RELATION || + parent->rtekind == RTE_SUBQUERY); + /* - * Get the userid from the relation's RTEPermissionInfo, though only - * the tables mentioned in query are assigned RTEPermissionInfos. - * Child relations (otherrels) simply use the parent's value. + * For any RELATION rte, we need a userid with which to check + * permission access. Baserels simply use their own RTEPermissionInfo's + * checkAsUser. + * + * For otherrels normally there's no RTEPermissionInfo, so we use the + * parent's, which normally has one. The exceptional case is that the + * parent is a subquery, in which case the otherrel will have its own. */ - if (parent == NULL) + if (rel->reloptkind == RELOPT_BASEREL || + (rel->reloptkind == RELOPT_OTHER_MEMBER_REL && + parent->rtekind == RTE_SUBQUERY)) { RTEPermissionInfo *perminfo; -- 2.35.3