aboutsummaryrefslogtreecommitdiff
path: root/src/backend/rewrite
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/rewrite')
-rw-r--r--src/backend/rewrite/rewriteDefine.c27
-rw-r--r--src/backend/rewrite/rewriteHandler.c205
-rw-r--r--src/backend/rewrite/rewriteManip.c33
-rw-r--r--src/backend/rewrite/rowsecurity.c25
4 files changed, 172 insertions, 118 deletions
diff --git a/src/backend/rewrite/rewriteDefine.c b/src/backend/rewrite/rewriteDefine.c
index 8ac2c81b06b..9f3afe965a7 100644
--- a/src/backend/rewrite/rewriteDefine.c
+++ b/src/backend/rewrite/rewriteDefine.c
@@ -632,14 +632,14 @@ checkRuleResultList(List *targetList, TupleDesc resultDesc, bool isSelect,
/*
* setRuleCheckAsUser
* Recursively scan a query or expression tree and set the checkAsUser
- * field to the given userid in all rtable entries.
+ * field to the given userid in all RTEPermissionInfos of the query.
*
* Note: for a view (ON SELECT rule), the checkAsUser field of the OLD
- * RTE entry will be overridden when the view rule is expanded, and the
- * checkAsUser field of the NEW entry is irrelevant because that entry's
- * requiredPerms bits will always be zero. However, for other types of rules
- * it's important to set these fields to match the rule owner. So we just set
- * them always.
+ * RTE entry's RTEPermissionInfo will be overridden when the view rule is
+ * expanded, and the checkAsUser for the NEW RTE entry's RTEPermissionInfo is
+ * irrelevant because its requiredPerms bits will always be zero. However, for
+ * other types of rules it's important to set these fields to match the rule
+ * owner. So we just set them always.
*/
void
setRuleCheckAsUser(Node *node, Oid userid)
@@ -666,18 +666,21 @@ setRuleCheckAsUser_Query(Query *qry, Oid userid)
{
ListCell *l;
- /* Set all the RTEs in this query node */
+ /* Set in all RTEPermissionInfos for this query. */
+ foreach(l, qry->rteperminfos)
+ {
+ RTEPermissionInfo *perminfo = lfirst_node(RTEPermissionInfo, l);
+
+ perminfo->checkAsUser = userid;
+ }
+
+ /* Now recurse to any subquery RTEs */
foreach(l, qry->rtable)
{
RangeTblEntry *rte = (RangeTblEntry *) lfirst(l);
if (rte->rtekind == RTE_SUBQUERY)
- {
- /* Recurse into subquery in FROM */
setRuleCheckAsUser_Query(rte->subquery, userid);
- }
- else
- rte->checkAsUser = userid;
}
/* Recurse into subquery-in-WITH */
diff --git a/src/backend/rewrite/rewriteHandler.c b/src/backend/rewrite/rewriteHandler.c
index 1e3efbbd36f..ea56ff79c86 100644
--- a/src/backend/rewrite/rewriteHandler.c
+++ b/src/backend/rewrite/rewriteHandler.c
@@ -395,36 +395,43 @@ rewriteRuleAction(Query *parsetree,
* Generate expanded rtable consisting of main parsetree's rtable plus
* rule action's rtable; this becomes the complete rtable for the rule
* action. Some of the entries may be unused after we finish rewriting,
- * but we leave them all in place for two reasons:
+ * but we leave them all in place to avoid having to adjust the query's
+ * varnos. RT entries that are not referenced in the completed jointree
+ * will be ignored by the planner, so they do not affect query semantics.
*
- * We'd have a much harder job to adjust the query's varnos if we
- * selectively removed RT entries.
+ * Also merge RTEPermissionInfo lists to ensure that all permissions are
+ * checked correctly.
*
* If the rule is INSTEAD, then the original query won't be executed at
- * all, and so its rtable must be preserved so that the executor will do
- * the correct permissions checks on it.
+ * all, and so its rteperminfos must be preserved so that the executor
+ * will do the correct permissions checks on the relations referenced in
+ * it. This allows us to check that the caller has, say, insert-permission
+ * on a view, when the view is not semantically referenced at all in the
+ * resulting query.
*
- * RT entries that are not referenced in the completed jointree will be
- * ignored by the planner, so they do not affect query semantics. But any
- * permissions checks specified in them will be applied during executor
- * startup (see ExecCheckRTEPerms()). This allows us to check that the
- * caller has, say, insert-permission on a view, when the view is not
- * semantically referenced at all in the resulting query.
+ * When a rule is not INSTEAD, the permissions checks done using the
+ * copied entries will be redundant with those done during execution of
+ * the original query, but we don't bother to treat that case differently.
*
- * When a rule is not INSTEAD, the permissions checks done on its copied
- * RT entries will be redundant with those done during execution of the
- * original query, but we don't bother to treat that case differently.
- *
- * NOTE: because planner will destructively alter rtable, we must ensure
- * that rule action's rtable is separate and shares no substructure with
- * the main rtable. Hence do a deep copy here.
- *
- * Note also that RewriteQuery() relies on the fact that RT entries from
- * the original query appear at the start of the expanded rtable, so
- * beware of changing this.
+ * NOTE: because planner will destructively alter rtable and rteperminfos,
+ * we must ensure that rule action's lists are separate and shares no
+ * substructure with the main query's lists. Hence do a deep copy here
+ * for both.
*/
- sub_action->rtable = list_concat(copyObject(parsetree->rtable),
- sub_action->rtable);
+ {
+ List *rtable_tail = sub_action->rtable;
+ List *perminfos_tail = sub_action->rteperminfos;
+
+ /*
+ * RewriteQuery relies on the fact that RT entries from the original
+ * query appear at the start of the expanded rtable, so we put the
+ * action's original table at the end of the list.
+ */
+ sub_action->rtable = copyObject(parsetree->rtable);
+ sub_action->rteperminfos = copyObject(parsetree->rteperminfos);
+ CombineRangeTables(&sub_action->rtable, &sub_action->rteperminfos,
+ rtable_tail, perminfos_tail);
+ }
/*
* There could have been some SubLinks in parsetree's rtable, in which
@@ -1628,10 +1635,13 @@ rewriteValuesRTEToNulls(Query *parsetree, RangeTblEntry *rte)
/*
* Record in target_rte->extraUpdatedCols the indexes of any generated columns
- * that depend on any columns mentioned in target_rte->updatedCols.
+ * columns that depend on any columns mentioned in
+ * target_perminfo->updatedCols.
*/
void
-fill_extraUpdatedCols(RangeTblEntry *target_rte, Relation target_relation)
+fill_extraUpdatedCols(RangeTblEntry *target_rte,
+ RTEPermissionInfo *target_perminfo,
+ Relation target_relation)
{
TupleDesc tupdesc = RelationGetDescr(target_relation);
TupleConstr *constr = tupdesc->constr;
@@ -1654,7 +1664,7 @@ fill_extraUpdatedCols(RangeTblEntry *target_rte, Relation target_relation)
expr = stringToNode(defval->adbin);
pull_varattnos(expr, 1, &attrs_used);
- if (bms_overlap(target_rte->updatedCols, attrs_used))
+ if (bms_overlap(target_perminfo->updatedCols, attrs_used))
target_rte->extraUpdatedCols =
bms_add_member(target_rte->extraUpdatedCols,
defval->adnum - FirstLowInvalidHeapAttributeNumber);
@@ -1747,6 +1757,8 @@ ApplyRetrieveRule(Query *parsetree,
Query *rule_action;
RangeTblEntry *rte,
*subrte;
+ RTEPermissionInfo *perminfo,
+ *sub_perminfo;
RowMarkClause *rc;
if (list_length(rule->actions) != 1)
@@ -1788,18 +1800,6 @@ ApplyRetrieveRule(Query *parsetree,
parsetree->resultRelation = list_length(parsetree->rtable);
/*
- * There's no need to do permissions checks twice, so wipe out the
- * permissions info for the original RTE (we prefer to keep the
- * bits set on the result RTE).
- */
- rte->requiredPerms = 0;
- rte->checkAsUser = InvalidOid;
- rte->selectedCols = NULL;
- rte->insertedCols = NULL;
- rte->updatedCols = NULL;
- rte->extraUpdatedCols = NULL;
-
- /*
* For the most part, Vars referencing the view should remain as
* they are, meaning that they implicitly represent OLD values.
* But in the RETURNING list if any, we want such Vars to
@@ -1862,12 +1862,6 @@ ApplyRetrieveRule(Query *parsetree,
/*
* Recursively expand any view references inside the view.
- *
- * Note: this must happen after markQueryForLocking. That way, any UPDATE
- * permission bits needed for sub-views are initially applied to their
- * RTE_RELATION RTEs by markQueryForLocking, and then transferred to their
- * OLD rangetable entries by the action below (in a recursive call of this
- * routine).
*/
rule_action = fireRIRrules(rule_action, activeRIRs);
@@ -1876,6 +1870,7 @@ ApplyRetrieveRule(Query *parsetree,
* original RTE to a subquery RTE.
*/
rte = rt_fetch(rt_index, parsetree->rtable);
+ perminfo = getRTEPermissionInfo(parsetree->rteperminfos, rte);
rte->rtekind = RTE_SUBQUERY;
rte->subquery = rule_action;
@@ -1885,6 +1880,7 @@ ApplyRetrieveRule(Query *parsetree,
rte->relkind = 0;
rte->rellockmode = 0;
rte->tablesample = NULL;
+ rte->perminfoindex = 0; /* no permission checking for this RTE */
rte->inh = false; /* must not be set for a subquery */
/*
@@ -1893,19 +1889,12 @@ ApplyRetrieveRule(Query *parsetree,
*/
subrte = rt_fetch(PRS2_OLD_VARNO, rule_action->rtable);
Assert(subrte->relid == relation->rd_id);
- subrte->requiredPerms = rte->requiredPerms;
- subrte->checkAsUser = rte->checkAsUser;
- subrte->selectedCols = rte->selectedCols;
- subrte->insertedCols = rte->insertedCols;
- subrte->updatedCols = rte->updatedCols;
- subrte->extraUpdatedCols = rte->extraUpdatedCols;
-
- rte->requiredPerms = 0; /* no permission check on subquery itself */
- rte->checkAsUser = InvalidOid;
- rte->selectedCols = NULL;
- rte->insertedCols = NULL;
- rte->updatedCols = NULL;
- rte->extraUpdatedCols = NULL;
+ sub_perminfo = getRTEPermissionInfo(rule_action->rteperminfos, subrte);
+ sub_perminfo->requiredPerms = perminfo->requiredPerms;
+ sub_perminfo->checkAsUser = perminfo->checkAsUser;
+ sub_perminfo->selectedCols = perminfo->selectedCols;
+ sub_perminfo->insertedCols = perminfo->insertedCols;
+ sub_perminfo->updatedCols = perminfo->updatedCols;
return parsetree;
}
@@ -1935,8 +1924,12 @@ markQueryForLocking(Query *qry, Node *jtnode,
if (rte->rtekind == RTE_RELATION)
{
+ RTEPermissionInfo *perminfo;
+
applyLockingClause(qry, rti, strength, waitPolicy, pushedDown);
- rte->requiredPerms |= ACL_SELECT_FOR_UPDATE;
+
+ perminfo = getRTEPermissionInfo(qry->rteperminfos, rte);
+ perminfo->requiredPerms |= ACL_SELECT_FOR_UPDATE;
}
else if (rte->rtekind == RTE_SUBQUERY)
{
@@ -3077,6 +3070,9 @@ rewriteTargetView(Query *parsetree, Relation view)
RangeTblEntry *base_rte;
RangeTblEntry *view_rte;
RangeTblEntry *new_rte;
+ RTEPermissionInfo *base_perminfo;
+ RTEPermissionInfo *view_perminfo;
+ RTEPermissionInfo *new_perminfo;
Relation base_rel;
List *view_targetlist;
ListCell *lc;
@@ -3213,6 +3209,7 @@ rewriteTargetView(Query *parsetree, Relation view)
base_rt_index = rtr->rtindex;
base_rte = rt_fetch(base_rt_index, viewquery->rtable);
Assert(base_rte->rtekind == RTE_RELATION);
+ base_perminfo = getRTEPermissionInfo(viewquery->rteperminfos, base_rte);
/*
* Up to now, the base relation hasn't been touched at all in our query.
@@ -3284,57 +3281,69 @@ rewriteTargetView(Query *parsetree, Relation view)
0);
/*
- * If the view has "security_invoker" set, mark the new target RTE for the
- * permissions checks that we want to enforce against the query caller.
- * Otherwise we want to enforce them against the view owner.
+ * If the view has "security_invoker" set, mark the new target relation
+ * for the permissions checks that we want to enforce against the query
+ * caller. Otherwise we want to enforce them against the view owner.
*
* At the relation level, require the same INSERT/UPDATE/DELETE
* permissions that the query caller needs against the view. We drop the
- * ACL_SELECT bit that is presumably in new_rte->requiredPerms initially.
+ * ACL_SELECT bit that is presumably in new_perminfo->requiredPerms
+ * initially.
*
- * Note: the original view RTE remains in the query's rangetable list.
- * Although it will be unused in the query plan, we need it there so that
- * the executor still performs appropriate permissions checks for the
- * query caller's use of the view.
+ * Note: the original view's RTEPermissionInfo remains in the query's
+ * rteperminfos so that the executor still performs appropriate
+ * permissions checks for the query caller's use of the view.
*/
+ view_perminfo = getRTEPermissionInfo(parsetree->rteperminfos, view_rte);
+
+ /*
+ * Disregard the perminfo in viewquery->rteperminfos that the base_rte
+ * would currently be pointing at, because we'd like it to point now to a
+ * new one that will be filled below. Must set perminfoindex to 0 to not
+ * trip over the Assert in addRTEPermissionInfo().
+ */
+ new_rte->perminfoindex = 0;
+ new_perminfo = addRTEPermissionInfo(&parsetree->rteperminfos, new_rte);
if (RelationHasSecurityInvoker(view))
- new_rte->checkAsUser = InvalidOid;
+ new_perminfo->checkAsUser = InvalidOid;
else
- new_rte->checkAsUser = view->rd_rel->relowner;
-
- new_rte->requiredPerms = view_rte->requiredPerms;
+ new_perminfo->checkAsUser = view->rd_rel->relowner;
+ new_perminfo->requiredPerms = view_perminfo->requiredPerms;
/*
* Now for the per-column permissions bits.
*
- * Initially, new_rte contains selectedCols permission check bits for all
- * base-rel columns referenced by the view, but since the view is a SELECT
- * query its insertedCols/updatedCols is empty. We set insertedCols and
- * updatedCols to include all the columns the outer query is trying to
- * modify, adjusting the column numbers as needed. But we leave
- * selectedCols as-is, so the view owner must have read permission for all
- * columns used in the view definition, even if some of them are not read
- * by the outer query. We could try to limit selectedCols to only columns
- * used in the transformed query, but that does not correspond to what
- * happens in ordinary SELECT usage of a view: all referenced columns must
- * have read permission, even if optimization finds that some of them can
- * be discarded during query transformation. The flattening we're doing
- * here is an optional optimization, too. (If you are unpersuaded and
- * want to change this, note that applying adjust_view_column_set to
- * view_rte->selectedCols is clearly *not* the right answer, since that
- * neglects base-rel columns used in the view's WHERE quals.)
+ * Initially, new_perminfo (base_perminfo) contains selectedCols
+ * permission check bits for all base-rel columns referenced by the view,
+ * but since the view is a SELECT query its insertedCols/updatedCols is
+ * empty. We set insertedCols and updatedCols to include all the columns
+ * the outer query is trying to modify, adjusting the column numbers as
+ * needed. But we leave selectedCols as-is, so the view owner must have
+ * read permission for all columns used in the view definition, even if
+ * some of them are not read by the outer query. We could try to limit
+ * selectedCols to only columns used in the transformed query, but that
+ * does not correspond to what happens in ordinary SELECT usage of a view:
+ * all referenced columns must have read permission, even if optimization
+ * finds that some of them can be discarded during query transformation.
+ * The flattening we're doing here is an optional optimization, too. (If
+ * you are unpersuaded and want to change this, note that applying
+ * adjust_view_column_set to view_perminfo->selectedCols is clearly *not*
+ * the right answer, since that neglects base-rel columns used in the
+ * view's WHERE quals.)
*
* This step needs the modified view targetlist, so we have to do things
* in this order.
*/
- Assert(bms_is_empty(new_rte->insertedCols) &&
- bms_is_empty(new_rte->updatedCols));
+ Assert(bms_is_empty(new_perminfo->insertedCols) &&
+ bms_is_empty(new_perminfo->updatedCols));
+
+ new_perminfo->selectedCols = base_perminfo->selectedCols;
- new_rte->insertedCols = adjust_view_column_set(view_rte->insertedCols,
- view_targetlist);
+ new_perminfo->insertedCols =
+ adjust_view_column_set(view_perminfo->insertedCols, view_targetlist);
- new_rte->updatedCols = adjust_view_column_set(view_rte->updatedCols,
- view_targetlist);
+ new_perminfo->updatedCols =
+ adjust_view_column_set(view_perminfo->updatedCols, view_targetlist);
/*
* Move any security barrier quals from the view RTE onto the new target
@@ -3438,7 +3447,7 @@ rewriteTargetView(Query *parsetree, Relation view)
* from the view, hence we need a new column alias list). This should
* match transformOnConflictClause. In particular, note that the
* relkind is set to composite to signal that we're not dealing with
- * an actual relation, and no permissions checks are wanted.
+ * an actual relation.
*/
old_exclRelIndex = parsetree->onConflict->exclRelIndex;
@@ -3449,8 +3458,8 @@ rewriteTargetView(Query *parsetree, Relation view)
false, false);
new_exclRte = new_exclNSItem->p_rte;
new_exclRte->relkind = RELKIND_COMPOSITE_TYPE;
- new_exclRte->requiredPerms = 0;
- /* other permissions fields in new_exclRte are already empty */
+ /* Ignore the RTEPermissionInfo that would've been added. */
+ new_exclRte->perminfoindex = 0;
parsetree->rtable = lappend(parsetree->rtable, new_exclRte);
new_exclRelIndex = parsetree->onConflict->exclRelIndex =
@@ -3728,6 +3737,7 @@ RewriteQuery(Query *parsetree, List *rewrite_events, int orig_rt_length)
{
int result_relation;
RangeTblEntry *rt_entry;
+ RTEPermissionInfo *rt_perminfo;
Relation rt_entry_relation;
List *locks;
int product_orig_rt_length;
@@ -3740,6 +3750,7 @@ RewriteQuery(Query *parsetree, List *rewrite_events, int orig_rt_length)
Assert(result_relation != 0);
rt_entry = rt_fetch(result_relation, parsetree->rtable);
Assert(rt_entry->rtekind == RTE_RELATION);
+ rt_perminfo = getRTEPermissionInfo(parsetree->rteperminfos, rt_entry);
/*
* We can use NoLock here since either the parser or
@@ -3833,7 +3844,7 @@ RewriteQuery(Query *parsetree, List *rewrite_events, int orig_rt_length)
NULL, 0, NULL);
/* Also populate extraUpdatedCols (for generated columns) */
- fill_extraUpdatedCols(rt_entry, rt_entry_relation);
+ fill_extraUpdatedCols(rt_entry, rt_perminfo, rt_entry_relation);
}
else if (event == CMD_MERGE)
{
diff --git a/src/backend/rewrite/rewriteManip.c b/src/backend/rewrite/rewriteManip.c
index 101c39553ae..2a07502030b 100644
--- a/src/backend/rewrite/rewriteManip.c
+++ b/src/backend/rewrite/rewriteManip.c
@@ -316,6 +316,39 @@ contains_multiexpr_param(Node *node, void *context)
return expression_tree_walker(node, contains_multiexpr_param, context);
}
+/*
+ * CombineRangeTables
+ * Adds the RTEs of 'src_rtable' into 'dst_rtable'
+ *
+ * This also adds the RTEPermissionInfos of 'src_perminfos' (belonging to the
+ * RTEs in 'src_rtable') into *dst_perminfos and also updates perminfoindex of
+ * the RTEs in 'src_rtable' to now point to the perminfos' indexes in
+ * *dst_perminfos.
+ *
+ * Note that this changes both 'dst_rtable' and 'dst_perminfo' destructively,
+ * so the caller should have better passed safe-to-modify copies.
+ */
+void
+CombineRangeTables(List **dst_rtable, List **dst_perminfos,
+ List *src_rtable, List *src_perminfos)
+{
+ ListCell *l;
+ int offset = list_length(*dst_perminfos);
+
+ if (offset > 0)
+ {
+ foreach(l, src_rtable)
+ {
+ RangeTblEntry *rte = lfirst_node(RangeTblEntry, l);
+
+ if (rte->perminfoindex > 0)
+ rte->perminfoindex += offset;
+ }
+ }
+
+ *dst_perminfos = list_concat(*dst_perminfos, src_perminfos);
+ *dst_rtable = list_concat(*dst_rtable, src_rtable);
+}
/*
* OffsetVarNodes - adjust Vars when appending one query's RT to another
diff --git a/src/backend/rewrite/rowsecurity.c b/src/backend/rewrite/rowsecurity.c
index f49cfb6cc66..f03b36a6e4e 100644
--- a/src/backend/rewrite/rowsecurity.c
+++ b/src/backend/rewrite/rowsecurity.c
@@ -47,6 +47,7 @@
#include "nodes/pg_list.h"
#include "nodes/plannodes.h"
#include "parser/parsetree.h"
+#include "parser/parse_relation.h"
#include "rewrite/rewriteDefine.h"
#include "rewrite/rewriteHandler.h"
#include "rewrite/rewriteManip.h"
@@ -115,6 +116,7 @@ get_row_security_policies(Query *root, RangeTblEntry *rte, int rt_index,
CmdType commandType;
List *permissive_policies;
List *restrictive_policies;
+ RTEPermissionInfo *perminfo;
/* Defaults for the return values */
*securityQuals = NIL;
@@ -122,16 +124,21 @@ get_row_security_policies(Query *root, RangeTblEntry *rte, int rt_index,
*hasRowSecurity = false;
*hasSubLinks = false;
+ Assert(rte->rtekind == RTE_RELATION);
+
/* If this is not a normal relation, just return immediately */
if (rte->relkind != RELKIND_RELATION &&
rte->relkind != RELKIND_PARTITIONED_TABLE)
return;
+ perminfo = getRTEPermissionInfo(root->rteperminfos, rte);
+
/* Switch to checkAsUser if it's set */
- user_id = OidIsValid(rte->checkAsUser) ? rte->checkAsUser : GetUserId();
+ user_id = OidIsValid(perminfo->checkAsUser) ?
+ perminfo->checkAsUser : GetUserId();
/* Determine the state of RLS for this, pass checkAsUser explicitly */
- rls_status = check_enable_rls(rte->relid, rte->checkAsUser, false);
+ rls_status = check_enable_rls(rte->relid, perminfo->checkAsUser, false);
/* If there is no RLS on this table at all, nothing to do */
if (rls_status == RLS_NONE)
@@ -196,7 +203,7 @@ get_row_security_policies(Query *root, RangeTblEntry *rte, int rt_index,
* which the user does not have access to via the UPDATE USING policies,
* similar to how we require normal UPDATE rights for these queries.
*/
- if (commandType == CMD_SELECT && rte->requiredPerms & ACL_UPDATE)
+ if (commandType == CMD_SELECT && perminfo->requiredPerms & ACL_UPDATE)
{
List *update_permissive_policies;
List *update_restrictive_policies;
@@ -243,7 +250,7 @@ get_row_security_policies(Query *root, RangeTblEntry *rte, int rt_index,
*/
if ((commandType == CMD_UPDATE || commandType == CMD_DELETE ||
commandType == CMD_MERGE) &&
- rte->requiredPerms & ACL_SELECT)
+ perminfo->requiredPerms & ACL_SELECT)
{
List *select_permissive_policies;
List *select_restrictive_policies;
@@ -286,7 +293,7 @@ get_row_security_policies(Query *root, RangeTblEntry *rte, int rt_index,
* raised if a policy is violated; otherwise, we might end up silently
* dropping rows to be added.
*/
- if (rte->requiredPerms & ACL_SELECT)
+ if (perminfo->requiredPerms & ACL_SELECT)
{
List *select_permissive_policies = NIL;
List *select_restrictive_policies = NIL;
@@ -342,7 +349,7 @@ get_row_security_policies(Query *root, RangeTblEntry *rte, int rt_index,
* for this relation, also as WCO policies, again, to avoid
* silently dropping data. See above.
*/
- if (rte->requiredPerms & ACL_SELECT)
+ if (perminfo->requiredPerms & ACL_SELECT)
{
get_policies_for_relation(rel, CMD_SELECT, user_id,
&conflict_select_permissive_policies,
@@ -371,7 +378,7 @@ get_row_security_policies(Query *root, RangeTblEntry *rte, int rt_index,
* path of an INSERT .. ON CONFLICT DO UPDATE, if SELECT rights
* are required for this relation.
*/
- if (rte->requiredPerms & ACL_SELECT)
+ if (perminfo->requiredPerms & ACL_SELECT)
add_with_check_options(rel, rt_index,
WCO_RLS_UPDATE_CHECK,
conflict_select_permissive_policies,
@@ -474,8 +481,8 @@ get_row_security_policies(Query *root, RangeTblEntry *rte, int rt_index,
* Copy checkAsUser to the row security quals and WithCheckOption checks,
* in case they contain any subqueries referring to other relations.
*/
- setRuleCheckAsUser((Node *) *securityQuals, rte->checkAsUser);
- setRuleCheckAsUser((Node *) *withCheckOptions, rte->checkAsUser);
+ setRuleCheckAsUser((Node *) *securityQuals, perminfo->checkAsUser);
+ setRuleCheckAsUser((Node *) *withCheckOptions, perminfo->checkAsUser);
/*
* Mark this query as having row security, so plancache can invalidate it