How to change column names returned from a function?

38 Views Asked by At

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;
1

There are 1 best solutions below

0
Erwin Brandstetter On BEST ANSWER

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.

Polymorphic function to change the whole return type

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

fiddle

This also returns original data types. You can really return anything here.

Plain column aliases

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

fiddle