Skip to content

fix: dump and diff RLS enabled on partitioned tables (#471)#490

Merged
tianzhou merged 1 commit into
mainfrom
fix/issue-471-rls-partitioned-tables
Jun 23, 2026
Merged

fix: dump and diff RLS enabled on partitioned tables (#471)#490
tianzhou merged 1 commit into
mainfrom
fix/issue-471-rls-partitioned-tables

Conversation

@tianzhou

Copy link
Copy Markdown
Contributor

Summary

Fixes #471. ENABLE ROW LEVEL SECURITY on a partitioned table (relkind 'p') was neither dumped nor diffed, while policies on the same table were dumped — so a database bootstrapped from a dump ended up with all policies present but RLS not enabled, silently leaving the policies unenforced.

Root cause

GetRLSTables and GetRLSTablesForSchema (ir/queries/queries.sql) filtered on c.relkind = 'r', excluding partitioned tables. table.RLSEnabled was therefore never set for relkind 'p', in both current-state and desired-state inspection — which is why plan also reported "No changes detected" even after hand-adding the ENABLE ROW LEVEL SECURITY statement (both sides of the comparison saw false).

The policy queries have no relkind filter, which is why policies survived and the gap was silent.

Fix

Include relkind 'p' alongside 'r' in both RLS queries (.sql source + regenerated .sql.go).

Tests

  • New regression case testdata/diff/create_policy/enable_rls_partitioned/ (mirrors the issue repro: partitioned events table + org-isolation policy).
  • TestDiffFromFiles and TestPlanAndApply pass for the new case and the full create_policy/ suite.

🤖 Generated with Claude Code

ENABLE ROW LEVEL SECURITY on a partitioned table (relkind 'p') was
neither dumped nor diffed because GetRLSTables and GetRLSTablesForSchema
filtered on relkind = 'r'. Policies on partitioned tables are dumped
(those queries have no relkind filter), so a dump rebuilt a database
with all policies present but RLS not enabled on partitioned tables —
silently leaving the policies unenforced.

Include relkind 'p' in both RLS queries so RLSEnabled is populated for
partitioned tables in both current- and desired-state inspection.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings June 23, 2026 10:55

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes a gap in RLS introspection so that ALTER TABLE ... ENABLE ROW LEVEL SECURITY is correctly dumped and diffed for partitioned tables (pg_class.relkind = 'p'), preventing policies from being emitted/applied without RLS actually being enabled.

Changes:

  • Updated RLS table discovery queries to include relkind IN ('r','p') so partitioned tables are considered RLS-enabled when appropriate.
  • Regenerated ir/queries/queries.sql.go to reflect the updated SQL.
  • Added a regression diff test case covering RLS enablement + policy on a partitioned table.

Reviewed changes

Copilot reviewed 7 out of 8 changed files in this pull request and generated no comments.

Show a summary per file
File Description
testdata/diff/create_policy/enable_rls_partitioned/plan.txt Expected human-readable plan output showing RLS enable + policy creation on a partitioned table.
testdata/diff/create_policy/enable_rls_partitioned/plan.sql Expected SQL plan output for enabling RLS and creating the policy.
testdata/diff/create_policy/enable_rls_partitioned/plan.json Expected JSON plan output including a table.rls step for the partitioned table.
testdata/diff/create_policy/enable_rls_partitioned/old.sql Old-state schema fixture where the partitioned table exists and RLS is not enabled.
testdata/diff/create_policy/enable_rls_partitioned/new.sql New-state schema fixture enabling RLS and adding a policy (issue #471 repro).
testdata/diff/create_policy/enable_rls_partitioned/diff.sql Expected diff SQL output matching the enablement + policy changes.
ir/queries/queries.sql Fixes the root cause by including partitioned tables in the RLS-enabled table queries.
ir/queries/queries.sql.go Regenerated sqlc output reflecting the updated RLS queries used by inspectors/plans.
Files not reviewed (1)
  • ir/queries/queries.sql.go: Generated file

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@greptile-apps

greptile-apps Bot commented Jun 23, 2026

Copy link
Copy Markdown

Greptile Summary

Fixes a silent bug where ENABLE ROW LEVEL SECURITY on partitioned tables (relkind = 'p') was excluded from both dump output and diff/plan calculations because the two RLS catalog queries filtered only on relkind = 'r'. Since the policy queries had no such filter, policies were correctly emitted while the enabling ALTER TABLE statement was silently dropped.

  • Core fix (ir/queries/queries.sql + regenerated .sql.go): both GetRLSTables and GetRLSTablesForSchema now use c.relkind IN ('r', 'p'), covering ordinary and partitioned tables.
  • Regression test (testdata/diff/create_policy/enable_rls_partitioned/): new diff test case mirrors the reported issue — partitioned events table going from no RLS to RLS-enabled with an org-isolation policy.
  • Note: GetRLSTables (the all-schemas variant) is defined and fixed but does not appear to be called anywhere in the codebase; only GetRLSTablesForSchema is actually invoked in ir/inspector.go.

Confidence Score: 4/5

The change is a minimal, targeted catalog query fix with a corresponding diff/plan regression test. The dump command, which also relies on the same fixed query, has no new regression test verifying that partitioned-table RLS is correctly emitted in dump output.

The two-line query change is correct and the test fixtures validate the diff/plan path end-to-end. The only gap is the absence of a dump-level regression test, which means the dump half of the stated fix is untested even though the underlying query fix should cover it.

No core logic files need special attention; the only gap is a missing testdata/dump/issue_471_*/ suite to cover the dump output path.

Important Files Changed

Filename Overview
ir/queries/queries.sql Adds relkind = 'p' (partitioned tables) to the relkind filter in both GetRLSTables and GetRLSTablesForSchema — the root cause fix for issue #471.
ir/queries/queries.sql.go Regenerated sqlc file that mirrors the .sql source change; query strings are in sync with the source.
testdata/diff/create_policy/enable_rls_partitioned/new.sql New regression test fixture — desired state: partitioned events table with RLS enabled and an org-isolation policy.
testdata/diff/create_policy/enable_rls_partitioned/old.sql New regression test fixture — baseline state: same partitioned table without RLS.
testdata/diff/create_policy/enable_rls_partitioned/plan.json Expected plan JSON for the new regression case; contains both the table.rls create step and the table.policy create step in correct order.
testdata/diff/create_policy/enable_rls_partitioned/diff.sql Expected diff DDL: ALTER TABLE events ENABLE ROW LEVEL SECURITY followed by the policy creation.
testdata/diff/create_policy/enable_rls_partitioned/plan.sql Expected plan SQL output; identical to diff.sql as expected for this simple case.
testdata/diff/create_policy/enable_rls_partitioned/plan.txt Expected human-readable plan summary; correctly shows 1 table modified with both a new policy and RLS enable step.

Sequence Diagram

%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
    participant User as User SQL Files
    participant EmbeddedPG as Embedded PG
    participant Inspector as Inspector
    participant Catalog as pg_catalog
    participant Diff as Diff Engine

    User->>EmbeddedPG: Apply SQL (partitioned table + ENABLE ROW LEVEL SECURITY)
    EmbeddedPG->>Inspector: Inspect desired state
    Inspector->>Catalog: GetRLSTablesForSchema (relkind IN r,p — FIXED)
    Catalog-->>Inspector: "events row (partitioned, rowsecurity=true)"
    Inspector->>Inspector: "table.RLSEnabled = true"
    Note over Inspector,Catalog: Same flow runs against the live target DB for current state
    Inspector-->>Diff: "Desired IR (RLSEnabled=true) vs Current IR (RLSEnabled=false)"
    Diff-->>User: ALTER TABLE events ENABLE ROW LEVEL SECURITY + CREATE POLICY
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
    participant User as User SQL Files
    participant EmbeddedPG as Embedded PG
    participant Inspector as Inspector
    participant Catalog as pg_catalog
    participant Diff as Diff Engine

    User->>EmbeddedPG: Apply SQL (partitioned table + ENABLE ROW LEVEL SECURITY)
    EmbeddedPG->>Inspector: Inspect desired state
    Inspector->>Catalog: GetRLSTablesForSchema (relkind IN r,p — FIXED)
    Catalog-->>Inspector: "events row (partitioned, rowsecurity=true)"
    Inspector->>Inspector: "table.RLSEnabled = true"
    Note over Inspector,Catalog: Same flow runs against the live target DB for current state
    Inspector-->>Diff: "Desired IR (RLSEnabled=true) vs Current IR (RLSEnabled=false)"
    Diff-->>User: ALTER TABLE events ENABLE ROW LEVEL SECURITY + CREATE POLICY
Loading

Reviews (1): Last reviewed commit: "fix: dump and diff RLS enabled on partit..." | Re-trigger Greptile

Comment on lines +1 to +14
CREATE TABLE events (
id uuid NOT NULL,
org_id uuid NOT NULL,
created_at timestamptz NOT NULL,
PRIMARY KEY (created_at, id)
) PARTITION BY RANGE (created_at);

-- RLS is now enabled with a policy on a partitioned table (issue #471)
ALTER TABLE events ENABLE ROW LEVEL SECURITY;

CREATE POLICY events_org_isolation ON events
FOR ALL
TO PUBLIC
USING (org_id = NULLIF(current_setting('app.current_org_id', true), '')::uuid);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Missing dump regression test for the fix

The PR title and description both claim to fix "dump and diff", but only a testdata/diff/ test is added. The dump command uses the same GetRLSTablesForSchema query (fixed here), so a partitioned table with RLS enabled was also silently omitted from schema dumps. Without a corresponding testdata/dump/issue_471_*/ test (with raw.sql, pgschema.sql, etc.), a future regression that re-breaks dump output for partitioned RLS tables would go undetected.

@tianzhou tianzhou merged commit 2abde30 into main Jun 23, 2026
3 checks passed
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.

ENABLE ROW LEVEL SECURITY on partitioned tables is neither dumped nor diffed (policies are, so the gap is silent)

2 participants