aboutsummaryrefslogtreecommitdiff
path: root/src/backend/commands
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/commands')
-rw-r--r--src/backend/commands/copy.c23
-rw-r--r--src/backend/commands/copyfrom.c11
-rw-r--r--src/backend/commands/view.c33
3 files changed, 51 insertions, 16 deletions
diff --git a/src/backend/commands/copy.c b/src/backend/commands/copy.c
index db4c9dbc231..b8bd78d358b 100644
--- a/src/backend/commands/copy.c
+++ b/src/backend/commands/copy.c
@@ -109,7 +109,7 @@ DoCopy(ParseState *pstate, const CopyStmt *stmt,
{
LOCKMODE lockmode = is_from ? RowExclusiveLock : AccessShareLock;
ParseNamespaceItem *nsitem;
- RangeTblEntry *rte;
+ RTEPermissionInfo *perminfo;
TupleDesc tupDesc;
List *attnums;
ListCell *cur;
@@ -123,8 +123,9 @@ DoCopy(ParseState *pstate, const CopyStmt *stmt,
nsitem = addRangeTableEntryForRelation(pstate, rel, lockmode,
NULL, false, false);
- rte = nsitem->p_rte;
- rte->requiredPerms = (is_from ? ACL_INSERT : ACL_SELECT);
+
+ perminfo = nsitem->p_perminfo;
+ perminfo->requiredPerms = (is_from ? ACL_INSERT : ACL_SELECT);
if (stmt->whereClause)
{
@@ -150,15 +151,15 @@ DoCopy(ParseState *pstate, const CopyStmt *stmt,
attnums = CopyGetAttnums(tupDesc, rel, stmt->attlist);
foreach(cur, attnums)
{
- int attno = lfirst_int(cur) -
- FirstLowInvalidHeapAttributeNumber;
+ int attno;
+ Bitmapset **bms;
- if (is_from)
- rte->insertedCols = bms_add_member(rte->insertedCols, attno);
- else
- rte->selectedCols = bms_add_member(rte->selectedCols, attno);
+ attno = lfirst_int(cur) - FirstLowInvalidHeapAttributeNumber;
+ bms = is_from ? &perminfo->insertedCols : &perminfo->selectedCols;
+
+ *bms = bms_add_member(*bms, attno);
}
- ExecCheckRTPerms(pstate->p_rtable, true);
+ ExecCheckPermissions(pstate->p_rtable, list_make1(perminfo), true);
/*
* Permission check for row security policies.
@@ -174,7 +175,7 @@ DoCopy(ParseState *pstate, const CopyStmt *stmt,
* If RLS is not enabled for this, then just fall through to the
* normal non-filtering relation handling.
*/
- if (check_enable_rls(rte->relid, InvalidOid, false) == RLS_ENABLED)
+ if (check_enable_rls(relid, InvalidOid, false) == RLS_ENABLED)
{
SelectStmt *select;
ColumnRef *cr;
diff --git a/src/backend/commands/copyfrom.c b/src/backend/commands/copyfrom.c
index 504afcb8110..0371f512208 100644
--- a/src/backend/commands/copyfrom.c
+++ b/src/backend/commands/copyfrom.c
@@ -761,6 +761,12 @@ CopyFrom(CopyFromState cstate)
resultRelInfo = target_resultRelInfo = makeNode(ResultRelInfo);
ExecInitResultRelation(estate, resultRelInfo, 1);
+ /*
+ * Copy the RTEPermissionInfos into estate as well, so that
+ * ExecGetInsertedCols() et al will work correctly.
+ */
+ estate->es_rteperminfos = cstate->rteperminfos;
+
/* Verify the named relation is a valid target for INSERT */
CheckValidResultRel(resultRelInfo, CMD_INSERT);
@@ -1525,9 +1531,12 @@ BeginCopyFrom(ParseState *pstate,
initStringInfo(&cstate->attribute_buf);
- /* Assign range table, we'll need it in CopyFrom. */
+ /* Assign range table and rteperminfos, we'll need them in CopyFrom. */
if (pstate)
+ {
cstate->range_table = pstate->p_rtable;
+ cstate->rteperminfos = pstate->p_rteperminfos;
+ }
tupDesc = RelationGetDescr(cstate->rel);
num_phys_attrs = tupDesc->natts;
diff --git a/src/backend/commands/view.c b/src/backend/commands/view.c
index b5a0fc02e5c..8e3c1efae40 100644
--- a/src/backend/commands/view.c
+++ b/src/backend/commands/view.c
@@ -367,7 +367,7 @@ DefineViewRules(Oid viewOid, Query *viewParse, bool replace)
* by 2...
*
* These extra RT entries are not actually used in the query,
- * except for run-time locking and permission checking.
+ * except for run-time locking.
*---------------------------------------------------------------
*/
static Query *
@@ -378,7 +378,9 @@ UpdateRangeTableOfViewParse(Oid viewOid, Query *viewParse)
ParseNamespaceItem *nsitem;
RangeTblEntry *rt_entry1,
*rt_entry2;
+ RTEPermissionInfo *rte_perminfo1;
ParseState *pstate;
+ ListCell *lc;
/*
* Make a copy of the given parsetree. It's not so much that we don't
@@ -405,15 +407,38 @@ UpdateRangeTableOfViewParse(Oid viewOid, Query *viewParse)
makeAlias("old", NIL),
false, false);
rt_entry1 = nsitem->p_rte;
+ rte_perminfo1 = nsitem->p_perminfo;
nsitem = addRangeTableEntryForRelation(pstate, viewRel,
AccessShareLock,
makeAlias("new", NIL),
false, false);
rt_entry2 = nsitem->p_rte;
- /* Must override addRangeTableEntry's default access-check flags */
- rt_entry1->requiredPerms = 0;
- rt_entry2->requiredPerms = 0;
+ /*
+ * Add only the "old" RTEPermissionInfo at the head of view query's list
+ * and update the other RTEs' perminfoindex accordingly. When rewriting a
+ * query on the view, ApplyRetrieveRule() will transfer the view
+ * relation's permission details into this RTEPermissionInfo. That's
+ * needed because the view's RTE itself will be transposed into a subquery
+ * RTE that can't carry the permission details; see the code stanza toward
+ * the end of ApplyRetrieveRule() for how that's done.
+ */
+ viewParse->rteperminfos = lcons(rte_perminfo1, viewParse->rteperminfos);
+ foreach(lc, viewParse->rtable)
+ {
+ RangeTblEntry *rte = lfirst(lc);
+
+ if (rte->perminfoindex > 0)
+ rte->perminfoindex += 1;
+ }
+
+ /*
+ * Also make the "new" RTE's RTEPermissionInfo undiscoverable. This is a
+ * bit of a hack given that all the non-child RTE_RELATION entries really
+ * should have a RTEPermissionInfo, but this dummy "new" RTE is going to
+ * go away anyway in the very near future.
+ */
+ rt_entry2->perminfoindex = 0;
new_rt = lcons(rt_entry1, lcons(rt_entry2, viewParse->rtable));