Row-level security policies in PostgreSQL - Time & Space Complexity
Start learning this pattern below
Jump into concepts and practice - no test required
When using row-level security policies, the database checks each row to decide if it should be visible or not.
We want to understand how the time to run a query changes as the number of rows grows.
Analyze the time complexity of the following policy and query.
CREATE POLICY user_policy ON orders
FOR SELECT
USING (user_id = current_user);
SELECT * FROM orders;
This policy filters rows so each user sees only their own orders when running the SELECT query.
Look at what repeats as the query runs.
- Primary operation: Checking the policy condition on each row.
- How many times: Once for every row in the orders table.
As the number of rows increases, the database must check more rows against the policy.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | 10 policy checks |
| 100 | 100 policy checks |
| 1000 | 1000 policy checks |
Pattern observation: The number of checks grows directly with the number of rows.
Time Complexity: O(n)
This means the time to apply the policy grows in a straight line as the number of rows grows.
[X] Wrong: "The policy is applied once, so it doesn't matter how many rows there are."
[OK] Correct: The policy condition is checked for each row to decide if it should be included, so more rows mean more checks.
Understanding how row-level security affects query time helps you explain how databases keep data safe without slowing down too much.
"What if the policy condition used a complex subquery instead of a simple user ID check? How would the time complexity change?"
Practice
Row-level security (RLS) on a PostgreSQL table?Solution
Step 1: Understand what RLS does
Row-level security allows filtering which rows a user can see or modify based on policies.Step 2: Compare options
Only To control access to individual rows based on user-defined policies describes controlling access to individual rows, which is the purpose of RLS.Final Answer:
To control access to individual rows based on user-defined policies -> Option CQuick Check:
RLS controls row access = D [OK]
- Confusing RLS with indexing or encryption
- Thinking RLS backs up data
- Assuming RLS applies to entire tables, not rows
employees?Solution
Step 1: Recall the correct command to enable RLS
The correct syntax isALTER TABLE table_name ENABLE ROW LEVEL SECURITY;.Step 2: Match options with syntax
Only ALTER TABLE employees ENABLE ROW LEVEL SECURITY; matches the exact syntax for enabling RLS on a table.Final Answer:
ALTER TABLE employees ENABLE ROW LEVEL SECURITY; -> Option BQuick Check:
Enable RLS uses ALTER TABLE ... ENABLE ROW LEVEL SECURITY [OK]
- Using SET instead of ENABLE
- Trying to enable RLS without ALTER TABLE
- Using incorrect keywords like ACTIVATE
documents:
CREATE POLICY user_policy ON documents FOR SELECT USING (owner = current_user);What rows will a user see when they run
SELECT * FROM documents;?Solution
Step 1: Understand the policy condition
The policy allows SELECT only ifowner = current_user, so only rows owned by the current user are visible.Step 2: Determine visible rows
Rows where the owner matches the current user will be returned; others are filtered out.Final Answer:
Only rows where the owner column matches the current user -> Option AQuick Check:
Policy filters rows by owner = current_user [OK]
- Assuming all rows are visible despite policy
- Thinking NULL owners are included
- Ignoring the current_user condition
CREATE POLICY update_own ON orders FOR UPDATE USING (user_id = current_user);But users report they can update other users' rows too. What is the likely problem?
Solution
Step 1: Check if RLS is enabled
Policies only work if row-level security is enabled on the table; otherwise, they have no effect.Step 2: Understand the symptom
If users can update rows despite the policy, likely RLS is disabled, ignoring policies and allowing full access.Final Answer:
Row-level security is not enabled on the orders table -> Option DQuick Check:
RLS must be enabled for policies to work [OK]
- Confusing USING and WITH CHECK clauses
- Assuming current_user is unsupported
- Creating policy for wrong command type
projects table only if they are either the project owner or the project is marked as public (is_public = true). Which policy condition correctly implements this?Solution
Step 1: Translate the requirement to logic
Users can see rows if they own the project OR if the project is public.Step 2: Match logic to condition
The OR condition matches the requirement:owner = current_user OR is_public = true.Final Answer:
USING (owner = current_user OR is_public = true) -> Option AQuick Check:
Owner or public projects visible = A [OK]
- Using AND instead of OR, restricting access too much
- Negating conditions incorrectly
- Confusing true and false values
