How to change column names returned from below function?
Executing:
select * from get_parameterbased_return_Table('condition2');
Column names should change to (col3 text, col4 text)
Sample table and function:
CREATE TABLE public.parameterbased_return_table (
col1 text NULL,
col2 text NULL,
col3 int4 NULL,
col4 int4 NULL
);
INSERT INTO public.parameterbased_return_table (col1, col2, col3, col4)
VALUES
('A', 'B', 11, 22)
, ('dfdf', 'dfe', 14, 545)
;
CREATE OR REPLACE FUNCTION get_parameterbased_return_Table(condition TEXT)
RETURNS TABLE (col1 text, col2 text) AS
$$
BEGIN
IF condition = 'condition1' THEN
RETURN QUERY SELECT t.col1::text, t.col2::text FROM parameterbased_return_Table t;
ELSIF condition = 'condition2' THEN
RETURN QUERY SELECT t.col3::text, t.col4::text FROM parameterbased_return_Table t;
ELSE
-- Handle other conditions or return an empty result set
RETURN QUERY SELECT NULL::record;
END IF;
END;
$$
LANGUAGE plpgsql;
Postgres (like SQL) is strictly typed. Functions cannot change their return type on the fly - including number, names and types of columns for a function returning a row type.
There are a limited workarounds, but you have to pass the required information with the function call one or the other way.
Here, the trick is to pass the actual return type to the function. See:
Only makes sense for exotic use cases.
That said, here is how you pull off such a stunt:
-- create desired return types
CREATE TYPE public.result1 AS (col1 text, col2 text);
CREATE TYPE public.result2 AS (col2 int, col3 int);
-- create polymorphis function
CREATE OR REPLACE FUNCTION public.get_parameterbased_return_table1(_return_type anyelement)
RETURNS SETOF anyelement
LANGUAGE plpgsql AS
$func$
BEGIN
CASE pg_typeof(_return_type)
WHEN 'public.result1'::regtype THEN
RETURN QUERY
SELECT t.col1, t.col2
FROM parameterbased_return_table t;
WHEN 'public.result2'::regtype THEN
RETURN QUERY
SELECT t.col3, t.col4 -- returning actual int values
FROM parameterbased_return_table t;
ELSE
-- Handle other conditions or return an empty result set
-- just don't return anything (simpler)
END CASE;
END
$func$;
Call:
SELECT * FROM public.get_parameterbased_return_table1(null::public.result1);
col1 | col2 |
---|---|
A | B |
dfdf | dfe |
SELECT * FROM public.get_parameterbased_return_table1(null::public.result2);
col3 | col4 |
---|---|
11 | 22 |
14 | 545 |
This also returns original data types. You can really return anything here.
Again, you have to provide the information in the call. Keeping your original function, you can use column aliases in the call:
SELECT * FROM public.get_parameterbased_return_table('condition2') AS t(col3, col4);
col3 | col4 |
---|---|
11 | 22 |
14 | 545 |