Bird
Raised Fist0
PostgreSQLquery~10 mins

Functions returning SETOF in PostgreSQL - Step-by-Step Execution

Choose your learning style10 modes available

Start learning this pattern below

Jump into concepts and practice - no test required

or
Recommended
Test this pattern10 questions across easy, medium, and hard to know if this pattern is strong
Concept Flow - Functions returning SETOF
Call function with parameters
Function starts execution
Loop or query returns multiple rows
Each row is yielded one by one
Result set accumulates
Function ends, returns full set
The function is called, executes a query or loop that yields multiple rows, and returns them as a set.
Execution Sample
PostgreSQL
CREATE FUNCTION get_even_numbers(max_num INT) RETURNS SETOF INT AS $$
BEGIN
  FOR i IN 2..max_num BY 2 LOOP
    RETURN NEXT i;
  END LOOP;
  RETURN;
END;
$$ LANGUAGE plpgsql;
This function returns all even numbers from 2 up to the given max_num.
Execution Table
StepiConditionActionOutput
122 <= max_numRETURN NEXT 22
244 <= max_numRETURN NEXT 42, 4
366 <= max_numRETURN NEXT 62, 4, 6
488 <= max_numRETURN NEXT 82, 4, 6, 8
51010 <= max_numRETURN NEXT 102, 4, 6, 8, 10
61212 <= max_num is FalseExit loop2, 4, 6, 8, 10
💡 Loop ends when i exceeds max_num, function returns accumulated set
Variable Tracker
VariableStartAfter 1After 2After 3After 4After 5Final
iundefined24681012
Output Setempty[2][2,4][2,4,6][2,4,6,8][2,4,6,8,10][2,4,6,8,10]
Key Moments - 2 Insights
Why does the function use RETURN NEXT instead of RETURN?
RETURN NEXT adds one row to the output set without ending the function, allowing multiple rows to be returned as shown in execution_table rows 1-5.
What happens when the loop condition becomes false?
The loop exits (see execution_table row 6), and the function returns the full set of rows collected so far.
Visual Quiz - 3 Questions
Test your understanding
Look at the execution_table, what is the value of 'i' at step 3?
A4
B8
C6
D10
💡 Hint
Check the 'i' column in execution_table row 3.
At which step does the loop condition become false and the function stops adding rows?
AStep 5
BStep 6
CStep 4
DStep 7
💡 Hint
Look at the 'Condition' and 'Action' columns in execution_table row 6.
If max_num was 6 instead of 10, how many rows would the function return?
A3
B5
C6
D2
💡 Hint
Check variable_tracker for values of 'i' up to 6.
Concept Snapshot
CREATE FUNCTION name(params) RETURNS SETOF type AS $$
BEGIN
  LOOP or query yielding rows
  RETURN NEXT row; -- adds row to output
END LOOP;
  RETURN;
END;
$$ LANGUAGE plpgsql;

Use RETURN NEXT to return multiple rows one by one.
Function returns all rows as a set after finishing.
Full Transcript
Functions returning SETOF in PostgreSQL allow returning multiple rows from a single function call. The function runs a loop or query that yields rows one by one using RETURN NEXT. Each RETURN NEXT adds a row to the output set without ending the function. When the loop or query finishes, the function returns the full set of rows. This is useful to return lists or tables from functions. The example function get_even_numbers returns all even numbers up to a given maximum by looping from 2 to max_num in steps of 2, returning each number with RETURN NEXT. The execution table shows each step where a number is added to the output. The variable tracker shows how the loop variable and output set change over time. Key moments include understanding why RETURN NEXT is used instead of RETURN, and when the loop ends. The visual quiz tests understanding of loop steps, termination, and output size changes.

Practice

(1/5)
1.

What does a PostgreSQL function declared with RETURNS SETOF do?

easy
A. It returns multiple rows as a set of values.
B. It returns a single scalar value.
C. It returns a boolean indicating success or failure.
D. It returns a JSON object.

Solution

  1. Step 1: Understand the meaning of RETURNS SETOF

    In PostgreSQL, RETURNS SETOF means the function returns multiple rows, not just one value.
  2. Step 2: Compare with other return types

    Other return types like scalar or boolean return single values, not sets of rows.
  3. Final Answer:

    It returns multiple rows as a set of values. -> Option A
  4. Quick Check:

    RETURNS SETOF = multiple rows [OK]
Hint: SETOF means multiple rows, not one value [OK]
Common Mistakes:
  • Thinking it returns a single value
  • Confusing SETOF with JSON return
  • Assuming it returns a boolean
2.

Which of the following is the correct syntax to declare a PostgreSQL function that returns a set of integers?

CREATE FUNCTION get_numbers() RETURNS SETOF integer AS $$ BEGIN RETURN QUERY SELECT ...; END; $$ LANGUAGE plpgsql;
easy
A. CREATE FUNCTION get_numbers() RETURNS SETOF integer AS $$ BEGIN RETURN 1; END; $$ LANGUAGE plpgsql;
B. CREATE FUNCTION get_numbers() RETURNS integer AS $$ BEGIN RETURN QUERY SELECT 1; END; $$ LANGUAGE plpgsql;
C. CREATE FUNCTION get_numbers() RETURNS SETOF integer AS $$ BEGIN RETURN QUERY SELECT 1; END; $$ LANGUAGE plpgsql;
D. CREATE FUNCTION get_numbers() RETURNS TABLE(integer) AS $$ BEGIN RETURN QUERY SELECT 1; END; $$ LANGUAGE plpgsql;

Solution

  1. Step 1: Check the correct RETURNS clause

    To return multiple rows of integers, use RETURNS SETOF integer.
  2. Step 2: Use RETURN QUERY for sets

    Inside the function, RETURN QUERY SELECT ... returns multiple rows properly.
  3. Final Answer:

    CREATE FUNCTION get_numbers() RETURNS SETOF integer AS $$ BEGIN RETURN QUERY SELECT 1; END; $$ LANGUAGE plpgsql; -> Option C
  4. Quick Check:

    RETURNS SETOF + RETURN QUERY = CREATE FUNCTION get_numbers() RETURNS SETOF integer AS $$ BEGIN RETURN QUERY SELECT 1; END; $$ LANGUAGE plpgsql; [OK]
Hint: Use RETURNS SETOF and RETURN QUERY for multiple rows [OK]
Common Mistakes:
  • Using RETURNS integer instead of SETOF integer
  • Using RETURN instead of RETURN QUERY for sets
  • Confusing RETURNS TABLE with RETURNS SETOF
3.

Given this function:

CREATE FUNCTION get_even_numbers() RETURNS SETOF integer AS $$ BEGIN RETURN QUERY SELECT generate_series(1,5) WHERE generate_series % 2 = 0; END; $$ LANGUAGE plpgsql;

What will SELECT * FROM get_even_numbers(); return?

medium
A. Empty set
B. [1, 3, 5]
C. [1, 2, 3, 4, 5]
D. [2, 4]

Solution

  1. Step 1: Understand generate_series and filter

    The function selects numbers from 1 to 5 but filters only even numbers using WHERE generate_series % 2 = 0.
  2. Step 2: Identify even numbers in range

    Even numbers between 1 and 5 are 2 and 4.
  3. Final Answer:

    [2, 4] -> Option D
  4. Quick Check:

    Even numbers 1-5 = [2,4] [OK]
Hint: Filter generate_series with modulo for evens [OK]
Common Mistakes:
  • Including odd numbers by mistake
  • Returning all numbers without filter
  • Expecting empty set due to syntax confusion
4.

Identify the error in this function that returns a set of text values:

CREATE FUNCTION get_names() RETURNS SETOF text AS $$ BEGIN RETURN SELECT name FROM users; END; $$ LANGUAGE plpgsql;

medium
A. Missing RETURN QUERY before SELECT statement.
B. RETURNS SETOF text is invalid syntax.
C. Function must return TABLE, not SETOF.
D. LANGUAGE plpgsql is not allowed for set-returning functions.

Solution

  1. Step 1: Check how to return multiple rows in plpgsql

    To return multiple rows, use RETURN QUERY SELECT ... inside the function.
  2. Step 2: Identify missing keyword

    The function uses RETURN SELECT ... which is invalid; it must be RETURN QUERY SELECT ....
  3. Final Answer:

    Missing RETURN QUERY before SELECT statement. -> Option A
  4. Quick Check:

    Use RETURN QUERY for sets [OK]
Hint: Use RETURN QUERY to return sets inside plpgsql [OK]
Common Mistakes:
  • Using RETURN instead of RETURN QUERY
  • Confusing RETURNS SETOF with RETURNS TABLE
  • Thinking LANGUAGE plpgsql disallows set returns
5.

You want to create a function that returns all employees with salary above a given amount. Which is the best way to write this function?

CREATE FUNCTION get_high_salary(min_salary numeric) RETURNS SETOF employees AS $$ BEGIN RETURN QUERY SELECT * FROM employees WHERE salary > min_salary; END; $$ LANGUAGE plpgsql;

What is the correct way to call this function to get all employees earning more than 50000?

hard
A. SELECT get_high_salary(50000);
B. SELECT * FROM get_high_salary(50000);
C. CALL get_high_salary(50000);
D. EXECUTE get_high_salary(50000);

Solution

  1. Step 1: Understand function returns SETOF employees

    The function returns multiple rows, so it must be called in a FROM clause to get rows.
  2. Step 2: Choose correct call syntax

    Use SELECT * FROM function_name(args); to get all rows returned by the function.
  3. Final Answer:

    SELECT * FROM get_high_salary(50000); -> Option B
  4. Quick Check:

    Call set-returning function in FROM clause [OK]
Hint: Call set-returning functions with SELECT * FROM [OK]
Common Mistakes:
  • Using SELECT function() without FROM
  • Using CALL which is for procedures
  • Using EXECUTE which is for dynamic SQL