aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/adt/selfuncs.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2024-01-08 11:48:44 -0500
committerTom Lane <tgl@sss.pgh.pa.us>2024-01-08 11:48:44 -0500
commit89b69db82adf742cadc36ee9a365cf47a632cdb0 (patch)
treef923f0e4c3f988f6cbe7e4c179c38d606f459fb6 /src/backend/utils/adt/selfuncs.c
parentbea18b1c949145ba2ca79d4765dba3cc9494a480 (diff)
downloadpostgresql-89b69db82adf742cadc36ee9a365cf47a632cdb0.tar.gz
postgresql-89b69db82adf742cadc36ee9a365cf47a632cdb0.zip
Allow examine_simple_variable() to work on INSERT RETURNING Vars.
Since commit 599b33b94, this function assumed that every RTE_RELATION RangeTblEntry would have an associated RelOptInfo. But that's not so: we only build RelOptInfos for relations that are scanned by the query. In particular the target of an INSERT won't have one, so that Vars appearing in an INSERT ... RETURNING list will not have an associated RelOptInfo. This apparently wasn't a problem before commit f7816aec2 taught examine_simple_variable() to drill down into CTEs containing INSERT RETURNING, but it is now. To fix, add a fallback code path that gets the userid to use directly from the RTEPermissionInfo associated with the RTE. (Sadly, we must have two code paths, because not every RTE has a RTEPermissionInfo either.) Per report from Alexander Lakhin. No back-patch, since the case is apparently unreachable before f7816aec2. Discussion: https://postgr.es/m/608a4886-6c60-0f9e-97d5-591256bd4150@gmail.com
Diffstat (limited to 'src/backend/utils/adt/selfuncs.c')
-rw-r--r--src/backend/utils/adt/selfuncs.c24
1 files changed, 19 insertions, 5 deletions
diff --git a/src/backend/utils/adt/selfuncs.c b/src/backend/utils/adt/selfuncs.c
index dbcd98d9851..cea777e9d40 100644
--- a/src/backend/utils/adt/selfuncs.c
+++ b/src/backend/utils/adt/selfuncs.c
@@ -119,6 +119,7 @@
#include "optimizer/paths.h"
#include "optimizer/plancat.h"
#include "parser/parse_clause.h"
+#include "parser/parse_relation.h"
#include "parser/parsetree.h"
#include "statistics/statistics.h"
#include "storage/bufmgr.h"
@@ -5434,17 +5435,30 @@ examine_simple_variable(PlannerInfo *root, Var *var,
if (HeapTupleIsValid(vardata->statsTuple))
{
- RelOptInfo *onerel = find_base_rel(root, var->varno);
+ RelOptInfo *onerel = find_base_rel_noerr(root, var->varno);
Oid userid;
/*
* Check if user has permission to read this column. We require
* all rows to be accessible, so there must be no securityQuals
- * from security barrier views or RLS policies. Use
- * onerel->userid if it's set, in case we're accessing the table
- * via a view.
+ * from security barrier views or RLS policies.
+ *
+ * Normally the Var will have an associated RelOptInfo from which
+ * we can find out which userid to do the check as; but it might
+ * not if it's a RETURNING Var for an INSERT target relation. In
+ * that case use the RTEPermissionInfo associated with the RTE.
*/
- userid = OidIsValid(onerel->userid) ? onerel->userid : GetUserId();
+ if (onerel)
+ userid = onerel->userid;
+ else
+ {
+ RTEPermissionInfo *perminfo;
+
+ perminfo = getRTEPermissionInfo(root->parse->rteperminfos, rte);
+ userid = perminfo->checkAsUser;
+ }
+ if (!OidIsValid(userid))
+ userid = GetUserId();
vardata->acl_ok =
rte->securityQuals == NIL &&