You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Previously, row-level security (RLS) was not enforced for UPSERT
statements. This change introduces full RLS support for the following
UPSERT variants:
- UPSERT
- INSERT … ON CONFLICT DO UPDATE
- INSERT … ON CONFLICT DO NOTHING
The specific RLS policies enforced during an UPSERT depend on whether a
row conflict occurs:
- No Conflict (row is inserted):
- SELECT/ALL: used to scan for potential conflicts.
- INSERT/ALL: enforced on the newly inserted row.
- Conflict (row is updated):
- SELECT/ALL: enforced to verify access to the conflicting row.
- UPDATE/ALL: enforced on the row being updated.
Importantly, SELECT/ALL policies used in conflict detection are not
applied as filters. Filtering out unauthorized rows would permit
inserting duplicates. Instead, we enforce these policies via explicit
checks: if the user is not authorized to see the conflicting row, the
UPSERT fails.
To support this behavior, we reused the single synthetic check
constraint per table. It now has a combined expression that captures all
relevant RLS checks for UPSERTs:
1. Enforce SELECT/ALL on existing rows during conflict detection.
2. Enforce UPDATE/ALL on conflicting rows that are updated.
3. Enforce INSERT/ALL on new rows that are inserted.
This implementation differs from PostgreSQL in one key way. In Postgres,
the VALUES clause is always subject to constraint and policy checks—even
if the row is not written due to a conflict. This is a known limitation
discussed in #35370.
As a result, we allow statements like the following to succeed if a
conflict occurs, even when the VALUES clause violates RLS:
```
INSERT INTO t VALUES (...violates RLS...) ON CONFLICT DO UPDATE SET ...complies with RLS...;
INSERT INTO t VALUES (...violates RLS...) ON CONFLICT DO NOTHING;
```
Closes#141998
Epic: CRDB-11724
Release note: none
0 commit comments