aboutsummaryrefslogtreecommitdiff
path: root/src/backend/executor/execMain.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/executor/execMain.c')
-rw-r--r--src/backend/executor/execMain.c64
1 files changed, 50 insertions, 14 deletions
diff --git a/src/backend/executor/execMain.c b/src/backend/executor/execMain.c
index 90d37b566ae..df4da3faa97 100644
--- a/src/backend/executor/execMain.c
+++ b/src/backend/executor/execMain.c
@@ -1673,9 +1673,15 @@ ExecConstraints(ResultRelInfo *resultRelInfo,
/*
* ExecWithCheckOptions -- check that tuple satisfies any WITH CHECK OPTIONs
+ * of the specified kind.
+ *
+ * Note that this needs to be called multiple times to ensure that all kinds of
+ * WITH CHECK OPTIONs are handled (both those from views which have the WITH
+ * CHECK OPTION set and from row level security policies). See ExecInsert()
+ * and ExecUpdate().
*/
void
-ExecWithCheckOptions(ResultRelInfo *resultRelInfo,
+ExecWithCheckOptions(WCOKind kind, ResultRelInfo *resultRelInfo,
TupleTableSlot *slot, EState *estate)
{
Relation rel = resultRelInfo->ri_RelationDesc;
@@ -1701,6 +1707,13 @@ ExecWithCheckOptions(ResultRelInfo *resultRelInfo,
ExprState *wcoExpr = (ExprState *) lfirst(l2);
/*
+ * Skip any WCOs which are not the kind we are looking for at this
+ * time.
+ */
+ if (wco->kind != kind)
+ continue;
+
+ /*
* WITH CHECK OPTION checks are intended to ensure that the new tuple
* is visible (in the case of a view) or that it passes the
* 'with-check' policy (in the case of row security).
@@ -1714,19 +1727,42 @@ ExecWithCheckOptions(ResultRelInfo *resultRelInfo,
char *val_desc;
Bitmapset *modifiedCols;
- modifiedCols = GetModifiedColumns(resultRelInfo, estate);
- val_desc = ExecBuildSlotValueDescription(RelationGetRelid(rel),
- slot,
- tupdesc,
- modifiedCols,
- 64);
-
- ereport(ERROR,
- (errcode(ERRCODE_WITH_CHECK_OPTION_VIOLATION),
- errmsg("new row violates WITH CHECK OPTION for \"%s\"",
- wco->viewname),
- val_desc ? errdetail("Failing row contains %s.", val_desc) :
- 0));
+ switch (wco->kind)
+ {
+ /*
+ * For WITH CHECK OPTIONs coming from views, we might be able to
+ * provide the details on the row, depending on the permissions
+ * on the relation (that is, if the user could view it directly
+ * anyway). For RLS violations, we don't include the data since
+ * we don't know if the user should be able to view the tuple as
+ * as that depends on the USING policy.
+ */
+ case WCO_VIEW_CHECK:
+ modifiedCols = GetModifiedColumns(resultRelInfo, estate);
+ val_desc = ExecBuildSlotValueDescription(RelationGetRelid(rel),
+ slot,
+ tupdesc,
+ modifiedCols,
+ 64);
+
+ ereport(ERROR,
+ (errcode(ERRCODE_WITH_CHECK_OPTION_VIOLATION),
+ errmsg("new row violates WITH CHECK OPTION for \"%s\"",
+ wco->relname),
+ val_desc ? errdetail("Failing row contains %s.",
+ val_desc) : 0));
+ break;
+ case WCO_RLS_INSERT_CHECK:
+ case WCO_RLS_UPDATE_CHECK:
+ ereport(ERROR,
+ (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
+ errmsg("new row violates row level security policy for \"%s\"",
+ wco->relname)));
+ break;
+ default:
+ elog(ERROR, "unrecognized WCO kind: %u", wco->kind);
+ break;
+ }
}
}
}