question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Supabase Self-Hosted not load correctly postgres schema

See original GitHub issue

Bug report

Describe the bug

I have those functions:

-- Set up is_member_of function
CREATE FUNCTION is_member_of(_user_email text, _channel_id int8) RETURNS bool AS $$
SELECT EXISTS (
  SELECT 1
  FROM public.channel_users cu
  WHERE cu.channel_id::int8 = _channel_id::int8
  AND cu.user_mail::text = _user_email::text
);
$$ LANGUAGE sql SECURITY DEFINER;

-- Set up is_admin function
CREATE FUNCTION is_admin(_user_email text) RETURNS bool AS $$
SELECT EXISTS (
  SELECT 1
  FROM auth.users u
  WHERE u.email::text = _user_email
  AND u.raw_user_meta_data->>'role' = 'admin'
);
$$ LANGUAGE sql SECURITY DEFINER;

-- Set up get_channel_list function
CREATE FUNCTION public.get_channel_list(mail text)
 RETURNS TABLE(id bigint, created_at timestamp with time zone, starter_email character varying, shop_id bigint, logo character varying, name character varying, total_message bigint, last_message_read bigint, to_read bigint)
 LANGUAGE plpgsql
AS $function$
begin
	return query
	select init.id,init.created_at,init.starter_mail,init.shop_id,init.logo,init.name,init.total_messages,
		(case when init.last_message_read > 0 then init.last_message_read else 0 end) as last_message_read,
		(select count(cm2.id) from public.channel_messages cm2 where cm2.id > init.last_message_read) to_read
	from 
	(
		select *,
		(select count(cm.id) from public.channel_messages cm where cm.channel_id = c.id ) as total_messages,
		(select cu.last_message_read from public.channel_users cu where cu.channel_id = c.id and cu.user_mail = mail ) as last_message_read 
		from public.channel as c
	) as init
	order by init.shop_id asc, to_read desc, init.total_messages desc;
end
$function$
;

-- Set up get_channel_list_shop function
CREATE FUNCTION public.get_channel_list_shop(mail text, shopID int8)
 RETURNS TABLE(id bigint, created_at timestamp with time zone, starter_email character varying, shop_id bigint, logo character varying, name character varying, total_message bigint, last_message_read bigint, to_read bigint)
 LANGUAGE plpgsql
AS $function$
begin
	return query
	select init.id,init.created_at,init.starter_mail,init.shop_id,init.logo,init.name,init.total_messages,
		(case when init.last_message_read > 0 then init.last_message_read else 0 end) as last_message_read,
		(select count(cm2.id) from public.channel_messages cm2 where cm2.id > init.last_message_read) to_read
	from 
	(
		select *,
		(select count(cm.id) from public.channel_messages cm where cm.channel_id = c.id ) as total_messages,
		(select cu.last_message_read from public.channel_users cu where cu.channel_id = c.id and cu.user_mail = mail ) as last_message_read 
		from public.channel as c
		where c.shop_id = shopID
	) as init
	order by init.shop_id asc, to_read desc, init.total_messages desc;
end
$function$
;

-- Set up get_channel_list_user function
CREATE FUNCTION public.get_channel_list_user(mail text)
 RETURNS TABLE(id bigint, created_at timestamp with time zone, starter_email character varying, shop_id bigint, logo character varying, name character varying, total_message bigint, last_message_read bigint, to_read bigint)
 LANGUAGE plpgsql
AS $function$
begin
	return query
	select init.id,init.created_at,init.starter_mail,init.shop_id,init.logo,init.name,init.total_messages,
		(case when init.last_message_read > 0 then init.last_message_read else 0 end) as last_message_read,
		(select count(cm2.id) from public.channel_messages cm2 where cm2.id > init.last_message_read) to_read
	from 
	(
		select *,
		(select count(cm.id) from public.channel_messages cm where cm.channel_id = c.id ) as total_messages,
		(select cu.last_message_read from public.channel_users cu where cu.channel_id = c.id and cu.user_mail = mail ) as last_message_read 
		from public.channel as c
		where c.starter_mail = mail
	) as init
	order by init.shop_id asc, to_read desc, init.total_messages desc;
end
$function$
;

-- Set up get_specific_channel_data function
CREATE FUNCTION public.get_specific_channel_data(mail text, cid int8)
 RETURNS TABLE(id bigint, created_at timestamp with time zone, starter_email character varying, shop_id bigint, logo character varying, name character varying, total_message bigint, last_message_read bigint, to_read bigint)
 LANGUAGE plpgsql
AS $function$
begin
	return query
	select init.id,init.created_at,init.starter_mail,init.shop_id,init.logo,init.name,init.total_messages,
		(case when init.last_message_read > 0 then init.last_message_read else 0 end) as last_message_read,
		(select count(cm2.id) from public.channel_messages cm2 where cm2.id > init.last_message_read) to_read
	from 
	(
		select *,
		(select count(cm.id) from public.channel_messages cm where cm.channel_id = c.id ) as total_messages,
		(select cu.last_message_read from public.channel_users cu where cu.channel_id = c.id and cu.user_mail = mail ) as last_message_read 
		from public.channel as c
		where c.id = cid
	) as init
	order by init.shop_id asc, to_read desc, init.total_messages desc;
end
$function$
;

But supabase load only three: get_channel_list, is_admin, is_member_of

image

Of course all functions exist into postgres and work perfectly if runned by SQL editor on postgres, checking the permission ect are equal of all the three loaded by supabase-studio

To Reproduce

  1. Execute the create function queries
  2. Reload the supabase-db container using: “[sudo] docker-compose restart supabase-db”
  3. Connect to supabase studio and go to API section
  4. See error

Expected behavior

I need execute those function via supabase-js using supabase.rpc function

System information

  • OS: Linux
  • Browser: Chrome
  • Version of supabase-js: ^1.28.5
  • Version of Node.js: 16.0.0

Issue Analytics

  • State:open
  • Created 2 years ago
  • Reactions:1
  • Comments:10 (6 by maintainers)

github_iconTop GitHub Comments

2reactions
WilliamFalcicommented, May 23, 2022

I’m running into this issue and it really cripples local development for me.

Hi dbmikus,

personally I fixed in this way:

  1. Create a sql file into: docker/volumes/db/init - for example in my case I make 04-custom.sql
  2. Then copy the following code:
-- watch create and alter
CREATE OR REPLACE FUNCTION pgrst_ddl_watch() RETURNS event_trigger AS $$
DECLARE
  cmd record;
BEGIN
  FOR cmd IN SELECT * FROM pg_event_trigger_ddl_commands()
  LOOP
    IF cmd.command_tag IN (
      'CREATE SCHEMA', 'ALTER SCHEMA'
    , 'CREATE TABLE', 'CREATE TABLE AS', 'SELECT INTO', 'ALTER TABLE'
    , 'CREATE FOREIGN TABLE', 'ALTER FOREIGN TABLE'
    , 'CREATE VIEW', 'ALTER VIEW'
    , 'CREATE MATERIALIZED VIEW', 'ALTER MATERIALIZED VIEW'
    , 'CREATE FUNCTION', 'ALTER FUNCTION'
    , 'CREATE TRIGGER'
    , 'CREATE TYPE'
    , 'CREATE RULE'
    , 'COMMENT'
    )
    -- don't notify in case of CREATE TEMP table or other objects created on pg_temp
    AND cmd.schema_name is distinct from 'pg_temp'
    THEN
      NOTIFY pgrst, 'reload schema';
    END IF;
  END LOOP;
END; $$ LANGUAGE plpgsql;

-- watch drop
CREATE OR REPLACE FUNCTION pgrst_drop_watch() RETURNS event_trigger AS $$
DECLARE
  obj record;
BEGIN
  FOR obj IN SELECT * FROM pg_event_trigger_dropped_objects()
  LOOP
    IF obj.object_type IN (
      'schema'
    , 'table'
    , 'foreign table'
    , 'view'
    , 'materialized view'
    , 'function'
    , 'trigger'
    , 'type'
    , 'rule'
    )
    AND obj.is_temporary IS false -- no pg_temp objects
    THEN
      NOTIFY pgrst, 'reload schema';
    END IF;
  END LOOP;
END; $$ LANGUAGE plpgsql;

CREATE EVENT TRIGGER pgrst_ddl_watch
  ON ddl_command_end
  EXECUTE PROCEDURE pgrst_ddl_watch();

CREATE EVENT TRIGGER pgrst_drop_watch
  ON sql_drop
  EXECUTE PROCEDURE pgrst_drop_watch();

This SQL will create a function to watch schema changes and force the cache to reload schemas + the various triggers on it, for more info this is the documentation: https://postgrest.org/en/latest/schema_cache.html

Probably you will need rebuild the containers pruning the volumes

0reactions
dbmikuscommented, May 30, 2022

Please ignore my comment above above the filepath. I was using an old version of the Supabase CLI.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Self-Hosting - Supabase
Supabase requires some Postgres extensions to be enabled by default for the API and Auth system to work. You can find the extensions...
Read more >
Self-hosting with Supabase - DEV Community ‍ ‍
Supabase is an open-source database solution based on Postgres. It includes all the standard features of Postgres with some killer additions ...
Read more >
Supabase Self hosting issue - postgresql - Stack Overflow
According to their docs, they say that Supabase uses pgjwt for auth. However, AWS RDS or Azure PosrgreSQL doesnt not support pgjwt ....
Read more >
External PostgreSQL database instead of a db service with ...
I'm trying to self-host Supabase , a Firebase open source alternative, ... My external db is working, I can correctly access with psql...
Read more >
Supabase - User Guide - What is Jet Admin?
​Supabase is an open-source Firebase alternative with an array of ... from writing queries or creating schemas using UI to simply uploading CSV...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found