I am getting this error:
ERROR: structure of query does not match function result type DETAIL: Returned type information_schema.sql_identifier does not match expected type character varying in column 1. CONTEXT: PL/pgSQL function app.get_custom_task_fields(integer,character varying,integer) line 10 at RETURN QUERY
To fix it, I need to know the type of column_name
, ordinal_position
and data_type
in my query. Or more generally, what is the data type of columns in information_schema.columns
and how do I convert sql_identifier
to an 'outputable' format to get it out of my function?
This is my function:
CREATE OR REPLACE FUNCTION app.get_custom_task_fields(sess_identity_id int
,session_code_str varchar
,sess_company_id int)
RETURNS TABLE(field_name varchar,ordinal_position integer,field_type varchar)
AS $$
DECLARE
BEGIN
RETURN QUERY
SELECT t.column_name,t.ordinal_position,t.data_type
FROM INFORMATION_SCHEMA.COLUMNS as t
WHERE table_name = 'task_custom' order by t.ordinal_position;
END;
$$ LANGUAGE PLPGSQL;
What is the data type of columns in
information_schema.columns
?
You can either look it up in the manual:
Or you can ask Postgres directly (using the catalog table pg_attribute
):
SELECT attname, atttypid::regtype
FROM pg_attribute
WHERE attrelid = 'information_schema.columns'::regclass
ORDER BY attnum;
attname | atttypid ---------------+---------------------------------- table_catalog | information_schema.sql_identifier table_schema | information_schema.sql_identifier table_name | information_schema.sql_identifier ...
And how do I convert
sql_identifier
to an 'outputable' format to get it out of my function?
To find out specifics of any data type:
SELECT typname, typtype -- 'd' is for 'domain'
, typbasetype::regtype
FROM pg_type
WHERE oid = 'information_schema.sql_identifier'::regtype;
typname | typtype | typbasetype ----------------+---------+----------- sql_identifier | d | character varying
So the data type information_schema.sql_identifier
is a DOMAIN
on varchar
. To find out possible casts:
SELECT casttarget::regtype, castcontext
FROM pg_cast
WHERE castsource = 'character varying'::regtype;
casttarget | castcontext ------------+------------ regclass | i text | i character | i ...
You can cast to a desired output type. But there is a ...
You don't need to know any of this. Just reference the data type of columns. The manual about CREATE FUNCTION
The type of a column is referenced by writing
table_name.column_name%TYPE
.
Write your function like this and you can't go wrong:
CREATE OR REPLACE FUNCTION app.get_custom_task_fields(sess_identity_id int
, session_code_str varchar
, sess_company_id int)
RETURNS TABLE(field_name information_schema.columns.column_name%TYPE
, ordinal_position information_schema.columns.ordinal_position%TYPE
, field_type information_schema.columns.data_type%TYPE) AS
$FUNC$
BEGIN
RETURN QUERY
SELECT t.column_name, t.ordinal_position, t.data_type
FROM information_schema.columns t
WHERE t.table_name = 'task_custom'
ORDER BY t.ordinal_position;
END
$FUNC$ LANGUAGE plpgsql;
The column reference is converted to the underlying type at function creation time. You'll see notices informing you about that.