Hello 👋 ! I am messing around with testing functi...
# help
f
Hello 👋 ! I am messing around with testing functions, but am having trouble getting a response and I am unsure why.
Hello 👋 ! I am messing around with testing functions, but am having trouble getting a response and I am unsure why.
I created a function 'test' and I just want to get all of the columns of my table and output them on the front end. I don't need to send anything back to the DB. The function 'test' is a return type void and looks like this
Copy code
plpgsql
begin

PERFORM *
FROM "SolanaFloorTracker";

end;
and my code to run it looks like this:
Copy code
javascript
  const test = () => {
    supabase.rpc("test").then(({ error, data, count, status, statusText }) => {
      if (error) console.error({error});
      else console.log({data});
    });
  };
  test();
The output is
{data: ''}
which looks like a 'success' but the response is empty for some reason
g
From PostgREST docs (Supabase uses) CREATE FUNCTION getallfilms() RETURNS SETOF films AS $$ SELECT * FROM films; $$ LANGUAGE SQL IMMUTABLE;
the important part is you have to return values, and setof returns records
f
so I have to return something?
g
returns setof "solana..." as
f
but it let me select return type void for the function - do I need to change that to records?
g
Using the UI? That might be what it uses.
f
I am using the UI within Supabase
g
BUT you need to change the name of the function or delete the old one first...
f
What do you mean?
Is this what you are suggesting it should look like? When trying to confirm it says there is a syntax error near SELECT
Copy code
plpgsql
begin
CREATE FUNCTION getall() RETURNS SETOF "SolanaFloorTracker" AS $$
  SELECT *
  FROM "SolanaFloorTracker";
$$ LANGUAGE SQL IMMUTABLE;
end;
and I am unclear on if the return type should be 'void' or 'record' (or something else)
g
You have to return a table or records array, not sure the UI does that... here is another example I found... create or replace function get_tags (tag text) returns setof products_view language plpgsql as $$ begin return query select * from products_view where tag % any(categories); end; $$
That is run in the sql editor
You would just have select * from table name, no where
f
hmm
g
you would also not have (tag text) as you are not passing a variable to the function
f
If I create a function in the SQL Editor, is there a way to call it in my javascript?
Or does that have to be a Function in the UI?
g
I think this is what you want create or replace function test1() returns setof films language plpgsql as $$ begin return query select * from films; end; $$
No rpc calls any function
f
Not sure what you mean
g
rpc does not depend on the UI. You can create function in UI-function section or in the SQL editor
just in your case I'm not sure UI function editor does arrays, tables, but once again I really don't use it much.
f
so if I put that into the SQL editor, how do I reference it in my JS?
g
test1() rpc call
f
like this?
Copy code
javascript
  const test = () => {
    supabase.rpc("test1").then(({ error, data, count, status, statusText }) => {
      if (error) console.error({ error });
      else console.log({ data });
    });
  };
  test();
g
yes
f
So in the SQL Editor when I run
Copy code
create or replace function test1()
  returns setof "SolanaFloorTracker"
  language plpgsql
  as $$
    begin
    return query
      select * from "SolanaFloorTracker";
    end;
  $$
it says 'success. no rows returned'
shouldn't it return everything in the table?
g
Do you have rls on?\
f
not enabled currently
g
do select * test1() in the sql editor
see if you get results
on the "success" message than just means it create the function without error.
f
should the select * test1() in the editor be in a new query?
I tried in a new query and it is saying syntax error at or near 'test1'
g
sorry select test1()
f
Ah it outputs a table but it seems funky.
I did call test1 in my rpc and it does appear to be working though
g
sorry for the round abouts, so many ways to write a function...
f
No worries. I am just learning as well 🙂
I am open to trying things in different ways too!
I don't suppose you might understand this?
Copy code
create view SolanaFloorTrackers AS 
-- this is a CTE
with psft as (
  SELECT *, rank() over (partition by (sft.name) order by sft."timestamp" desc),
select c.id , c."timestamp", c.name, c.price, c.volume, p.price, p.volume
from psft c. -- c for current
left outer join psft p ON c.name = p.name. -- p for previous
where c.rank = 1 and p.rank =2;
It is from a thread in the sql channel from like a month ago where I was asking for some help trying to do something like this
g
I've not used views, but they are just a different presentation of your table data.
f
Gotcha. Someone else wrote this. Its a bit above my SQL level
This was my original question on what I was trying to do https://discord.com/channels/839993398554656828/869405720934744086/916162551123951736
When I try to 'run' this view in the SQL editor I get a syntax error at or near "select" though
g
No idea on that view code but it looks pretty odd to me. Just remember with your table function you can do alot more processing on the table (sorting/filtering) etc. and return far less than the full table.
Also suggest you make sure you understand what ever you use, or simplify and do multiple steps if you are using this eventually for real project.
f
I suppose I need to learn more about SQL. I'm not too sure how I can write a query on the table that would group by name and then order by timestamp and get the two most recent entries...
So something like this between return query and end; in the last function (with your table/column names might work).... SELECT rank_filter.* FROM ( SELECT items.*, rank() OVER ( PARTITION BY color ORDER BY created_at DESC ) FROM items ) rank_filter WHERE RANK <=2
.... then "items" is your table, "color" is your group name and "create_at" is your timestamp
But, I'm just reading that example, so could be off a bit.
f
I think I set up a function similar to what you described
Copy code
create or replace function fetch_data()
  returns setof "SolanaFloorTracker"
  language plpgsql
  as $$
    begin
    return query
      SELECT rank_filter.* 
      FROM (
        SELECT "SolanaFloorTracker".*, 
        rank() OVER (
            PARTITION BY "CollectionName"
            ORDER BY created_at DESC
        )
        FROM "SolanaFloorTracker"
      ) rank_filter WHERE RANK <=2;
    end;
  $$
but when I call
select fetch_data
it says "structure of query does not match function result type"
g
try setof rank_filter, but I was just trying to point you in the right direction. I believe somewhere in that article and function is your solution, but I can't really get you much further without doing research.
f
when trying setof rank_filter when I try to run it it says 'type "rank_filter" does not exist'
g
It appears the issue is the setof "" gets messed up as the result comes back processed by the rankfilter stuff. Either play with it using some stuff here: https://www.postgresql.org/docs/9.2/xfunc-sql.html starting at 35.4.8. SQL Functions Returning Sets, or ask in the sql section showing your function with the returns setof "SolanaF...." and the "structure of query does not match" error. Without playing with it myself, I would have to learn what syntax is needed. You could also as a test run everything after return up to end in the SQL editor to verify at least that part does what you want.
I did run the inner sql part on my message table and it grouped them by chat room in date order desc and gave me last two of each. So I believe that code is what you want ... just how to return the records in the function now.