BEFORE trigger behavior in PostgreSQL - Time & Space Complexity
Start learning this pattern below
Jump into concepts and practice - no test required
We want to understand how the time it takes to run a BEFORE trigger changes as the number of rows affected grows.
How does the trigger's work scale when many rows are inserted or updated?
Analyze the time complexity of this BEFORE trigger on a table.
CREATE OR REPLACE FUNCTION check_price()
RETURNS trigger AS $$
BEGIN
IF NEW.price < 0 THEN
RAISE EXCEPTION 'Price cannot be negative';
END IF;
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER price_check
BEFORE INSERT OR UPDATE ON products
FOR EACH ROW EXECUTE FUNCTION check_price();
This trigger checks each new or updated row's price before saving it.
Look at what repeats when the trigger runs.
- Primary operation: The trigger function runs once for each row inserted or updated.
- How many times: Exactly as many times as there are rows affected by the query.
As the number of rows grows, the trigger runs more times.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | 10 trigger executions |
| 100 | 100 trigger executions |
| 1000 | 1000 trigger executions |
Pattern observation: The work grows directly with the number of rows; doubling rows doubles work.
Time Complexity: O(n)
This means the trigger's total work grows in a straight line with the number of rows processed.
[X] Wrong: "The trigger runs once per query, so time stays the same no matter how many rows."
[OK] Correct: BEFORE triggers defined FOR EACH ROW run once per row, so more rows mean more trigger executions.
Understanding how triggers scale helps you design efficient database logic and avoid surprises when data grows.
"What if the trigger was defined FOR EACH STATEMENT instead of FOR EACH ROW? How would the time complexity change?"
Practice
BEFORE trigger in PostgreSQL?Solution
Step 1: Understand trigger timing
BEFORE triggers execute before the actual data change happens in the table.Step 2: Identify trigger purpose
They allow checking or modifying data before it is saved, preventing bad data if needed.Final Answer:
To run custom code before data is inserted or updated -> Option CQuick Check:
BEFORE trigger = runs before data change [OK]
- Confusing BEFORE with AFTER triggers
- Thinking triggers create or delete tables
- Assuming triggers run only after data changes
users?Solution
Step 1: Check trigger timing and event
The trigger must be BEFORE INSERT on the table users.Step 2: Verify syntax for calling function
PostgreSQL uses EXECUTE FUNCTION to call the trigger function.Final Answer:
CREATE TRIGGER trg BEFORE INSERT ON users EXECUTE FUNCTION func(); -> Option DQuick Check:
Correct syntax uses BEFORE INSERT ON and EXECUTE FUNCTION [OK]
- Using AFTER instead of BEFORE
- Writing INTO instead of ON
- Using CALL instead of EXECUTE FUNCTION
status to 'active':CREATE FUNCTION set_status() RETURNS trigger AS $$ BEGIN NEW.status := 'active'; RETURN NEW; END; $$ LANGUAGE plpgsql; CREATE TRIGGER trg_set_status BEFORE INSERT ON accounts FOR EACH ROW EXECUTE FUNCTION set_status(); INSERT INTO accounts (id, status) VALUES (1, 'pending'); SELECT status FROM accounts WHERE id = 1;
What will be the output of the SELECT query?
Solution
Step 1: Understand BEFORE INSERT trigger effect
The trigger sets NEW.status to 'active' before the row is inserted.Step 2: Check inserted data
Even though 'pending' was given, the trigger changes it to 'active' before saving.Final Answer:
active -> Option AQuick Check:
BEFORE trigger modifies data before insert [OK]
- Assuming original value 'pending' is saved
- Thinking trigger runs after insert
- Expecting NULL or error without reason
CREATE FUNCTION check_age() RETURNS trigger AS $$
BEGIN
IF NEW.age < 18 THEN
RAISE EXCEPTION 'Age must be 18 or older';
END IF;
RETURN NEW;
END;
$$ LANGUAGE plpgsql;Which problem will occur if you create a BEFORE INSERT trigger using this function and try to insert a row with
age = 16?Solution
Step 1: Analyze trigger logic
If NEW.age is less than 18, the trigger raises an exception.Step 2: Understand effect of RAISE EXCEPTION
Raising an exception stops the insert and returns an error to the client.Final Answer:
An error will be raised and insertion will stop -> Option AQuick Check:
RAISE EXCEPTION stops insert with error [OK]
- Thinking the row inserts anyway
- Assuming age auto-corrects
- Ignoring that exceptions stop execution
products table that prevents the price from being set below zero. Which trigger function code correctly enforces this rule?Solution
Step 1: Identify correct condition check
The trigger must check NEW.price to prevent negative values before update.Step 2: Choose proper action on invalid data
Raising an exception stops the update and prevents invalid price.Step 3: Eliminate incorrect options
BEGIN IF NEW.price < 0 THEN NEW.price := 0; END IF; RETURN NEW; END;silently changes price to 0 (may hide errors), C checks OLD.price (wrong), D deletes row (not appropriate).Final Answer:
BEGIN IF NEW.price < 0 THEN RAISE EXCEPTION 'Price cannot be negative'; END IF; RETURN NEW; END; -> Option BQuick Check:
Use RAISE EXCEPTION on NEW.price < 0 to stop update [OK]
- Checking OLD.price instead of NEW.price
- Silently fixing invalid data instead of error
- Deleting rows inside BEFORE trigger
