| From: | jian he <jian(dot)universality(at)gmail(dot)com> |
|---|---|
| To: | Bryan Green <dbryan(dot)green(at)gmail(dot)com> |
| Cc: | pgsql-hackers(at)lists(dot)postgresql(dot)org |
| Subject: | Re: COPY FROM with RLS |
| Date: | 2026-09-23 19:05:37 |
| Message-ID: | CACJufxEX3GD9XaG63M76fr-_QTt9ezVeSS3XvW=ZGhgr7K9LDg@mail.gmail.com |
| Views: | Whole Thread | Raw Message | Download mbox | Resend email |
| Thread: | |
| Lists: | pgsql-hackers |
On Fri, Sep 11, 2026 at 1:21 AM Bryan Green <dbryan(dot)green(at)gmail(dot)com> wrote:
>
> v15 checks out on the v3 items. Crash is gone on both an assert and a
> non-assert build, context is right, the rule cases error instead of
> redirecting, and quoting is fixed.
>
> The new one is the result of a forgotten guard. The WCO quals aren't in
> the volatile test that forces CIM_SINGLE, so under multi-insert a
> self-referential policy doesn't see the still-buffered rows and accepts
> ones a plain INSERT would reject.
>
> CREATE FUNCTION under_quota(o text) RETURNS bool LANGUAGE plpgsql VOLATILE
> AS $$ BEGIN RETURN (SELECT count(*) FROM q WHERE owner = o) < 3; END $$;
> CREATE POLICY ins ON q FOR INSERT WITH CHECK (under_quota(owner));
>
> INSERT of ten rows stops at the fourth. COPY takes all ten. A no-op
> BEFORE ROW trigger makes COPY stop at four as well, so it's the
> batching. Probably wants ri_WithCheckOptions in that CIM_SINGLE test,
> or just forced under RLS.
>
+ foreach_node(WithCheckOption, wco, resultRelInfo->ri_WithCheckOptions)
+ {
+ if (contain_subplans(wco->qual) ||
+ contain_volatile_functions(wco->qual))
+ {
+ volatile_wco = true;
+ break;
+ }
+ }
Make volatile expression and sub-select fall back to CIM_SINGLE should be fine.
> The wording "any rule that would apply to an INSERT" isn't quite right
> either. A conditional DO INSTEAD NOTHING stays one QSRC_ORIGINAL query
> and slips the three screens, so COPY inserts the row that would have
> dropped under INSERT with the rule.
>
We can use RelationData->rd_rules to check if a relation has rules
defined on it or not.
> Also, relname_only wraps the whole ExecWithCheckOptions call, so a
> non-violation error from a policy expression loses the "line x". This
> is because relname_only is true for anything the call raises, including
> errors that are not due to policy rejection. Maybe set the flag only
> around the violation report instead of the whole evaluation?
>
I am not sure about "non-violation error from a policy expression".
Currently check constraint violations produce an error line, but RLS
violations do not.
| Attachment | Content-Type | Size |
|---|---|---|
| v16-0001-COPY-FROM-with-RLS.patch | text/x-patch | 35.3 KB |
| From | Date | Subject | |
|---|---|---|---|
| Next Message | Nathan Bossart | 2026-09-23 19:10:29 | Re: add list of major features to the v19 release notes |
| Previous Message | Masahiko Sawada | 2026-09-23 19:04:15 | Re: Add REPACK progress phases for logical decoding setup |