Trigger function creation in PostgreSQL - Time & Space Complexity
Start learning this pattern below
Jump into concepts and practice - no test required
When we create a trigger function in PostgreSQL, it runs automatically when certain events happen. Understanding how the time it takes to run grows helps us know if it will slow down our database.
We want to see how the work done by the trigger function changes as the data it handles grows.
Analyze the time complexity of the following trigger function.
CREATE OR REPLACE FUNCTION update_timestamp()
RETURNS TRIGGER AS $$
BEGIN
NEW.updated_at = NOW();
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER set_timestamp
BEFORE UPDATE ON my_table
FOR EACH ROW
EXECUTE FUNCTION update_timestamp();
This trigger function updates a timestamp column every time a row in the table is updated.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: The trigger runs once for each row updated.
- How many times: It runs exactly once per updated row, no loops inside the function.
Each row update causes the trigger to run once, so the total work grows directly with the number of rows updated.
| Input Size (rows updated) | Approx. Operations |
|---|---|
| 10 | 10 trigger executions |
| 100 | 100 trigger executions |
| 1000 | 1000 trigger executions |
Pattern observation: The work grows linearly as more rows are updated.
Time Complexity: O(n)
This means the time to run the trigger grows directly in proportion to the number of rows updated.
[X] Wrong: "The trigger runs once per update statement no matter how many rows are changed."
[OK] Correct: In PostgreSQL, row-level triggers run once for each row affected, so the time grows with the number of rows, not just the statement.
Knowing how triggers scale helps you design efficient database logic that won't slow down as data grows. This skill shows you understand how database internals affect performance.
"What if we changed the trigger to a statement-level trigger instead of row-level? How would the time complexity change?"
Practice
Solution
Step 1: Understand trigger function requirements
Trigger functions must return a special type that PostgreSQL recognizes for triggers.Step 2: Identify the correct return type
The return type for trigger functions is alwaystrigger, not standard types like void or integer.Final Answer:
trigger -> Option BQuick Check:
Trigger functions return type = trigger [OK]
- Using void or integer as return type
- Forgetting to specify return type
- Confusing trigger function with normal function
Solution
Step 1: Check syntax for trigger function creation
Trigger functions must be created withCREATE FUNCTION, return typetrigger, and useplpgsqllanguage.Step 2: Identify correct function body and return statement
Trigger functions must returnNEWorOLDrow, soRETURN NEW;is correct here.Final Answer:
CREATE FUNCTION my_trigger() RETURNS trigger AS $$ BEGIN RETURN NEW; END; $$ LANGUAGE plpgsql; -> Option AQuick Check:
Trigger function syntax = CREATE FUNCTION my_trigger() RETURNS trigger AS $$ BEGIN RETURN NEW; END; $$ LANGUAGE plpgsql; [OK]
- Using RETURNS void instead of trigger
- Using CREATE TRIGGER instead of CREATE FUNCTION
- Returning boolean or void instead of NEW or OLD
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;Solution
Step 1: Analyze the condition in the trigger function
The function checks ifNEW.age < 18and raises an exception if true.Step 2: Understand effect of exception and return
If age is less than 18, insertion stops with error. Otherwise,RETURN NEW;allows insertion.Final Answer:
The row is inserted only if age is 18 or older -> Option DQuick Check:
Exception blocks underage inserts = The row is inserted only if age is 18 or older [OK]
- Thinking all rows insert regardless
- Assuming RETURN NEW inserts row without checks
- Confusing RAISE EXCEPTION with warnings
CREATE FUNCTION update_timestamp() RETURNS trigger AS $$ BEGIN NEW.updated_at = NOW(); RETURN NEW END; $$ LANGUAGE plpgsql;
Solution
Step 1: Check syntax for statements inside function
Each statement must end with a semicolon in PL/pgSQL.Step 2: Identify missing semicolon
The lineRETURN NEWlacks a semicolon at the end, causing syntax error.Final Answer:
Missing semicolon after RETURN NEW -> Option CQuick Check:
PL/pgSQL statements end with semicolon [OK]
- Forgetting semicolon after RETURN NEW
- Thinking NEW cannot be assigned
- Confusing return type with void
last_modified to the current timestamp whenever a row is updated. Which of the following trigger function definitions correctly achieves this?Solution
Step 1: Identify correct assignment operator in PL/pgSQL
PL/pgSQL uses := for assignment, not =.Step 2: Check return type and returned row
Trigger functions must return type trigger and return NEW for BEFORE UPDATE triggers.Step 3: Evaluate each option
CREATE FUNCTION set_last_modified() RETURNS trigger AS $$ BEGIN NEW.last_modified := NOW(); RETURN NEW; END; $$ LANGUAGE plpgsql; uses correct assignment :=, returns NEW, and has correct return type. CREATE FUNCTION set_last_modified() RETURNS trigger AS $$ BEGIN NEW.last_modified = NOW(); RETURN NEW; END; $$ LANGUAGE plpgsql; uses = which is invalid for assignment. CREATE FUNCTION set_last_modified() RETURNS trigger AS $$ BEGIN OLD.last_modified := NOW(); RETURN OLD; END; $$ LANGUAGE plpgsql; assigns to OLD which is read-only. CREATE FUNCTION set_last_modified() RETURNS void AS $$ BEGIN NEW.last_modified := NOW(); END; $$ LANGUAGE plpgsql; returns void which is invalid.Final Answer:
CREATE FUNCTION set_last_modified() RETURNS trigger AS $$ BEGIN NEW.last_modified := NOW(); RETURN NEW; END; $$ LANGUAGE plpgsql; -> Option AQuick Check:
Use := for assignment and return NEW [OK]
- Using = instead of := for assignment
- Returning OLD instead of NEW
- Using void return type for trigger function
