0

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".

enter image description here

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?

2
  • How are you calling the function (in the calling side)? Commented Aug 12, 2021 at 15:06
  • 1
    Hi @SalmanA, I've added the calling code above. Commented Aug 12, 2021 at 15:15

1 Answer 1

1

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.

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you -I figured there'd have to be a way!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.