Skip to content

Add pg_get_policy_ddl() function to reconstruct CREATE POLICY stateme… - #5

Open
akshay-joshi wants to merge 1 commit into
masterfrom
new_get_policy_ddl
Open

Add pg_get_policy_ddl() function to reconstruct CREATE POLICY stateme…#5
akshay-joshi wants to merge 1 commit into
masterfrom
new_get_policy_ddl

Conversation

@akshay-joshi

Copy link
Copy Markdown
Owner

…nts.

This patch introduces a new system function:
pg_get_policy_ddl(table regclass, policy_name name,
VARIADIC options text[]) RETURNS setof text

which reconstructs the CREATE POLICY statement for the named row-level security policy on the specified table. The result is returned as a single row.
 
The supported option is:

pretty (boolean) - format the output for readability.

Usage examples:
-- non-pretty formatted DDL (default)
SELECT * FROM pg_get_policy_ddl('rls_table', 'pol1');
SELECT * FROM pg_get_policy_ddl(16564, 'pol1');

-- pretty formatted DDL
SELECT * FROM pg_get_policy_ddl('rls_table', 'pol1', 'pretty', 'true');
SELECT * FROM pg_get_policy_ddl(16564, 'pol1', 'pretty', 'true');

Reference: PG-163
Author: Akshay Joshi akshay.joshi@enterprisedb.com

@akshay-joshi
akshay-joshi force-pushed the new_get_policy_ddl branch 2 times, most recently from e3c1007 to f62ea39 Compare May 29, 2026 06:12
@akshay-joshi
akshay-joshi force-pushed the new_get_policy_ddl branch 2 times, most recently from 8d53305 to 2bc8410 Compare June 29, 2026 07:52
@akshay-joshi
akshay-joshi force-pushed the new_get_policy_ddl branch 6 times, most recently from 59b3799 to 30aa1e5 Compare July 6, 2026 10:52
@akshay-joshi
akshay-joshi force-pushed the new_get_policy_ddl branch 3 times, most recently from 4d82fcf to 38054fe Compare July 13, 2026 08:44
  pg_get_policy_ddl(table regclass,
                    policyname name,
                    pretty bool DEFAULT false)
  RETURNS SETOF text

reconstructs the CREATE POLICY statement for the named row-level
security policy on the specified table.  Although a single statement is
produced, the function returns a SETOF text result so its calling
convention matches the rest of the pg_get_*_ddl family.

The reconstructed DDL includes all clauses of the CREATE POLICY syntax:
the policy's permissiveness (AS RESTRICTIVE), command type (FOR
SELECT/INSERT/UPDATE/DELETE), role list (TO <roles>), USING
qualification, and WITH CHECK expression.  Clauses whose value equals
the parser's default -- PERMISSIVE, FOR ALL, and TO PUBLIC -- are
omitted from the output, matching the convention used by pg_get_indexdef,
pg_get_constraintdef, pg_get_viewdef, and similar functions.  The result
is therefore semantically equivalent to the original DDL, not lexically
identical.

The pretty parameter controls output formatting and defaults to false,
following the same convention as pg_get_role_ddl, pg_get_tablespace_ddl,
and pg_get_database_ddl.  NULL passed explicitly for pretty is treated
as false.

NULL inputs for the table or policy name yield no rows.  An invalid
relation name surfaces the regclass resolution error; a non-existent
policy raises an explicit "policy ... does not exist" error.

Usage examples:

  -- compact form (default)
  SELECT * FROM pg_get_policy_ddl('rls_table', 'pol1');
  SELECT * FROM pg_get_policy_ddl(16564, 'pol1');

  -- pretty-printed form
  SELECT * FROM pg_get_policy_ddl('rls_table', 'pol1', true);

Regression coverage is added to src/test/regress/sql/rowsecurity.sql
and exercises all valid combinations of the CREATE POLICY syntax:
PERMISSIVE/RESTRICTIVE, all FOR command variants (ALL/SELECT/INSERT/
UPDATE/DELETE), multi-role TO lists, USING-only, WITH CHECK-only, and
USING+WITH CHECK policies for both ALL and UPDATE commands (the only
two that accept both), RESTRICTIVE on a specific command type,
subquery expressions, pretty and non-pretty output, all boolean
representations for the pretty argument (true/false, on/off, 1/0),
NULL and error paths, and a round-trip test that drops and re-executes
the generated DDL.

Author: Akshay Joshi <akshay.joshi@enterprisedb.com>
Reviewed-by: Rui Zhao <zhaorui126@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant