From: | Akshay Joshi <akshay(dot)joshi(at)enterprisedb(dot)com> |
---|---|
To: | jian he <jian(dot)universality(at)gmail(dot)com> |
Cc: | Philip Alger <paalger0(at)gmail(dot)com>, pgsql-hackers <pgsql-hackers(at)postgresql(dot)org> |
Subject: | Re: [PATCH] Add pg_get_policy_ddl() function to reconstruct CREATE POLICY statement |
Date: | 2025-10-22 13:21:50 |
Message-ID: | CANxoLDccMKZXA7qWAu6bGXRqVGu_DNPFxP4ssQ5Q4yq9Hwiq-g@mail.gmail.com |
Views: | Whole Thread | Raw Message | Download mbox | Resend email |
Thread: | |
Lists: | pgsql-hackers |
On Wed, Oct 22, 2025 at 12:51 PM jian he <jian(dot)universality(at)gmail(dot)com>
wrote:
> On Thu, Oct 16, 2025 at 8:51 PM Akshay Joshi
> <akshay(dot)joshi(at)enterprisedb(dot)com> wrote:
> >
> > Please find attached the v3 patch, which resolves all compilation errors
> and warnings.
> >
>
> drop table if exists t, ts, ts1;
> create table t(a int);
> CREATE POLICY p0 ON t FOR ALL TO PUBLIC USING (a % 2 = 1);
> SELECT pg_get_policy_ddl('t', 'p0', false);
>
> pg_get_policy_ddl
> ---------------------------------------------------------------------
> CREATE POLICY p0 ON t AS PERMISSIVE FOR ALL USING (((a % 2) = 1));
> (1 row)
>
> "TO PUBLIC" part is missing, maybe it's ok.
>
I used the logic below, which did not return PUBLIC as a role. I have added
logic to default the TO clause to PUBLIC when no specific role name is
provided
valueDatum = heap_getattr(tuplePolicy,
Anum_pg_policy_polroles,
RelationGetDescr(pgPolicyRel),
&attrIsNull);
if (!attrIsNull)
{
ArrayType *policy_roles = DatumGetArrayTypePCopy(valueDatum);
int nitems = ARR_DIMS(policy_roles)[0];
Oid *roles = (Oid *) ARR_DATA_PTR(policy_roles);
>
>
> SELECT pg_get_policy_ddl(-1, 'p0', false);
> ERROR: could not open relation with OID 4294967295
> as I mentioned in a nearby thread [1], this should be NULL instead of
> ERROR.
> [1]
> https://postgr.es/m/CACJufxGbE4uJWu1YuqdmOx+7PMBpHvX_fbRMmHu=r4SrsuW9tg@mail.gmail.com
>
> Fixed in v4 patch.
>
> IMHO, get_formatted_string is not needed, most of the time, if pretty is
> true,
> we append "\t" and "\n", for that we can simply do
> ```
> appendStringInfo(&buf, "CREATE POLICY %s ON %s ",
> quote_identifier(NameStr(*policyName)),
> generate_qualified_relation_name(policy_form->polrelid));
> if (pretty)
> appendStringInfoString(buf, "\t\n");
> ```
>
>
The get_formatted_string function is needed. Instead of using multiple if
statements for the pretty flag, it’s better to have a generic function.
This will be useful if the pretty-format DDL implementation is accepted by
the community, as it can be reused by other pg_get_<object>_ddl() DDL
functions added in the future.
>
> in pg_get_triggerdef_worker, I found the below code pattern:
> /*
> * In non-pretty mode, always schema-qualify the target table name for
> * safety. In pretty mode, schema-qualify only if not visible.
> */
> appendStringInfo(&buf, " ON %s ",
> pretty ?
> generate_relation_name(trigrec->tgrelid, NIL) :
> generate_qualified_relation_name(trigrec->tgrelid));
>
> maybe we can apply it too while construct query string:
> "CREATE POLICY %s ON %s",
>
In my opinion, the table name should always be schema-qualified, which I
have addressed in the v4 patch. The implementation of the pretty flag here
differs from pg_get_triggerdef_worker, which is used only for the target
table name. In my patch, the pretty flag adds \t and \n to each different
clause (example AS, FOR, USING ...)
Attachment | Content-Type | Size |
---|---|---|
v4-0001-Add-pg_get_policy_ddl-function-to-reconstruct-CREATE.patch | application/octet-stream | 24.5 KB |
From | Date | Subject | |
---|---|---|---|
Next Message | Fujii Masao | 2025-10-22 13:31:22 | Re: Invalid primary_slot_name triggers warnings in all processes on reload |
Previous Message | Aleksander Alekseev | 2025-10-22 13:20:01 | Re: [PATCH] Remove make_temptable_name_n() |