'Options for merging two separate complex postgres functions

I have two separate plpgsql functions for my project, that I would like to merge into one, or come up with an alternative solution.

The first function uses a domain address and path, to retrieve the domain_id and webpage_id, along other things (such as whether the domain uses a liking system or voting system or neither for its posts).

And the second function uses the webpage_id from the first function to retrieve appropriate posts for that page and whether to get post likes/votes/neither.

As of now, what I'm doing is to call the following function, first. What it does is that it checks for the domain_id and webpage_id based off the domain_url and slug.

If the values don't exist, it checks whether the domain is registered, and if it is, it makes an insert into the webpages table, else it returns an error.

create or replace function get_domain_details(query_domain_url text, query_slug text) returns table(id bigint, owner_id uuid page_id bigint, post_count int, is_likes boolean, is_votes boolean
) 
 as $$
DECLARE new_domain_id int; 
        new_page_id bigint;
BEGIN
RETURN query
WITH domain_row AS (
SELECT domains.id, domains.owner_id, webpages.id as page_id, webpages.post_count, domain_settings.is_likes, domain_settings.is_votes
FROM domains
JOIN domain_settings
ON domain_settings.domain_id = domains.id
RIGHT JOIN webpages
ON webpages.domain_id = domains.id AND webpages.slug = query_slug
WHERE domains.domain_address = query_domain_url),
abc as (
INSERT INTO page_visits (domain_id, page_id)
SELECT domain_row.id, domain_row.page_id FROM domain_row
)
TABLE domain_row;
    IF NOT FOUND THEN
      IF EXISTS (SELECT domains.id FROM domains WHERE domain_address = query_domain_url) THEN
      WITH webpage_rows AS (INSERT INTO webpages (domain_id, slug)
      VALUES ((SELECT domains.id FROM domains WHERE domain_address = query_domain_url), query_slug)
      RETURNING *
      )
      SELECT webpage_rows.id, webpage_rows.domain_id
      INTO new_page_id, new_domain_id
      FROM webpage_rows;
      RETURN query
      WITH domain_row_2 AS (
        SELECT domains.id, domains.owner_id, new_page_id as page_id, 0 as post_count, domain_settings.is_likes, domain_settings.is_votes
  FROM domains
  JOIN domain_settings
  ON domain_settings.domain_id = domains.id
  WHERE domains.id = new_domain_id),
  abc_2 as (
    INSERT INTO page_visits  (domain_id, page_id)
    SELECT domain_row_2.id, domain_row_2.page_id FROM domain_row_2
    )
    TABLE domain_row_2;
      ELSE 
        RAISE EXCEPTION 'This is not a valid domain!';
      END IF;
    END IF;
    RETURN;
END;
$$ language plpgsql;

And once I've received the page_id and liking/voting system info from the database, I use that to make another request to the database from my nodejs server to retrieve the posts and its details.

If is_votes is true, it joins with the votes table, else if is_likes is true, it joins with the likes table, else it doesn't join with either.

create or replace function get_page_posts (
  query_page_id bigint, is_votes boolean, is_likes boolean
) 
 returns table (id bigint, full_name text, avatar_url text, author_id uuid, post_text text, created_at timestamptz, comment_count int, vote_count int, like_count int
 )
as $$
BEGIN
IF is_votes = true THEN
RETURN query 
  SELECT posts.id, users.full_name, users.avatar_url, posts.author_id, posts.post_text, posts.created_at, post_data.comment_count, post_data.vote_count, post_data.like_count
FROM posts
LEFT JOIN users
ON users.user_id = posts.author_id
 LEFT JOIN post_data
 ON post_data.post_id = posts.id
 LEFT JOIN votes v1
 ON v1.post_id = posts.id
LEFT JOIN webpages 
ON webpages.id = posts.page_id 
WHERE webpages.id = query_page_id
AND NOT posts.status = 'deleted' 
ORDER BY posts.id DESC;
ELSIF is_likes = true THEN
RETURN query 
  SELECT posts.id, users.full_name, users.avatar_url, posts.author_id, posts.post_text, posts.created_at, post_data.comment_count, post_data.vote_count, post_data.like_count
FROM posts
LEFT JOIN users
ON users.user_id = posts.author_id
 LEFT JOIN post_data
 ON post_data.post_id = posts.id
LEFT JOIN webpages 
ON webpages.id = posts.page_id 
LEFT JOIN likes
 ON likes.post_id = posts.id
WHERE webpages.id = query_page_id
AND NOT posts.status = 'deleted' 
ORDER BY posts.id DESC;
ELSE
RETURN query
  SELECT posts.id, users.full_name, users.avatar_url, posts.author_id, posts.comment_text, posts.created_at, post_data.comment_count, post_data.vote_count, post_data.like_count
 FROM posts
LEFT JOIN users
ON users.user_id = posts.author_id
 LEFT JOIN post_data
 ON post_data.post_id = posts.id
LEFT JOIN webpages 
ON webpages.id = posts.page_id 
WHERE posts.parent_id IS NULL
AND webpages.id = query_page_id
AND NOT posts.status = 'deleted' 
ORDER BY posts.id DESC;
END IF;
END;
$$
language plpgsql

Now, the issue that I have is that this is slowing this entire loading process down, so I'm trying to merge both functions together so that I don't have to make two separate requests to the database.

I have currently combined both of them into a new function such that it looks like this.

However, I am unsure if this is a safe and viable approach.

... as $$
BEGIN
RETURN query 
WITH abc AS (
  SELECT * FROM get_domain_details(query_domain_url, query_slug)
),
def AS (
  SELECT * FROM get_page_posts((SELECT abc.page_id FROM abc), (SELECT abc.is_votes FROM abc), (SELECT abc.is_likes FROM abc))
)
SELECT * FROM abc UNION ALL SELECT * FROM def;
END;
$$ language plpgsql;


Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source