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
143587: sql: add RLS policy support for UPSERT r=spilchen a=spilchen
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 behaviour, 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#141998Closes#144802
Epic: CRDB-11724
Release note: none
Co-authored-by: Matt Spilchen <[email protected]>
0 commit comments