Reputation: 1516
This PostgreSQL function successfully returns JSON; however, the function name is associated with the result:
CREATE OR REPLACE FUNCTION public.find_classes(
search_text character varying,
current_page integer DEFAULT 1,
page_size integer DEFAULT 10,
sort_by character varying DEFAULT 'name'::character varying,
direction character varying DEFAULT 'ASC'::character varying
)
RETURNS json AS
$$
WITH classes_found AS (
SELECT
classes._id AS id, classes.name, classes.description, classes.active
FROM classes
WHERE search_text IS NULL OR search_text = '' OR LOWER(classes.name) LIKE LOWER(search_text) || '%'
ORDER BY
CASE
WHEN direction = 'ASC' THEN
CASE
WHEN sort_by = 'name' THEN classes.name
WHEN sort_by = 'active' THEN classes.active::varchar
END
END ASC,
CASE
WHEN direction = 'DESC' THEN
CASE
WHEN sort_by = 'name' THEN classes.name
WHEN sort_by = 'active' THEN classes.active::varchar
END
END DESC
)
SELECT json_build_object(
'totalItems',(SELECT COUNT(*) FROM classes_found),
'currentPage', current_page,
'pageSize', page_size,
'classes', COALESCE((SELECT json_agg(l.*) FROM (SELECT classes_found.* FROM classes_found LIMIT page_size OFFSET ((current_page - 1) * page_size)) l ), '[]')
) AS results;
$$ LANGUAGE SQL;
As far as both pgAdmin and node-postgres go, the data returned looks like one row with a JSON column named "find_classes".
If it has to have a name, I want it to be "results" so I can handle it on on the calling side in a more modular way.
In the SELECT at the bottom, "AS results" didn't help. I also tried writing it in plpgsql but that didn't give me any finer-grained control over this.
Here's the code that calls the PostgreSQL function...
import pg from 'pg'
const pgNativePool = new pg.native.Pool({
max: 10, // default
connectionString: <string> import.meta.env.VITE_DATABASE_URL,
ssl: {
rejectUnauthorized: false
}
})
type QueryResponse = (sql: string, params?: Array<number|string|boolean|StudioLocation>) => Promise<pg.QueryResult<any>>
const query: QueryResponse = (sql: string, params?: Array<number|string|boolean>) => pgNativePool.query(sql, params)
type FindLocationsResponse = (searchText: string | null, currentPage: number | null, pageSize: number | null, sortBy: string | null, direction: string | null) => Promise<{ body: ClassSearchResults }>
const find: FindLocationsResponse = async (searchText, currentPage, pageSize, sortBy, direction) => {
const sql = `SELECT * FROM find_classes(search_text:=$1, current_page:=$2, page_size:=$3, sort_by:=$4, direction:=$5);`
const { rows } = await query(sql, [searchText, currentPage, pageSize, sortBy, direction])
return { body: <ClassSearchResults> rows[0].find_classes }
}
Any idea how to change the column name returned?
Upvotes: 0
Views: 249
Reputation: 6167
Name of output columns is generated by the clause that generates the output. So if you want to change it, you can't do that in the function but in the clause using it.
Something like SELECT find_classes(...) AS results;
will do.
Upvotes: 1