cli icon indicating copy to clipboard operation
cli copied to clipboard

`db diff`: Incorrect definition order in migration (Declarative Schema)

Open Revadike opened this issue 9 months ago • 0 comments

I added a function and constraints using that function. The command supabase db diff generated this migration:

alter table "public"."users" add constraint "users_avatar_check" CHECK (((avatar IS NULL) OR is_allowed_host(avatar, ARRAY['localhost'::text, '127.0.0.1'::text, 'avatars.steamstatic.com'::text, '*.supabase.co'::text]))) not valid;

alter table "public"."users" validate constraint "users_avatar_check";

alter table "public"."users" add constraint "users_background_check" CHECK (((background IS NULL) OR is_allowed_host(background, ARRAY['localhost'::text, '127.0.0.1'::text, '*.supabase.co'::text]))) not valid;

alter table "public"."users" validate constraint "users_background_check";

set check_function_bodies = off;

CREATE OR REPLACE FUNCTION public.is_allowed_host(url text, allowed_hosts text[])
 RETURNS boolean
 LANGUAGE plpgsql
 IMMUTABLE STRICT
 SET search_path TO ''
AS $function$
declare
  raw_host text;
  host text;
  pattern text;
  regex_pattern text;
begin
  if url !~ '^https?://' then
    return false;
  end if;

  raw_host := substring(url from '^https?://([^/]+)');
  raw_host := regexp_replace(raw_host, '^[^@]+@', '');
  host := regexp_replace(raw_host, ':\d+$', '');

  foreach pattern in array allowed_hosts loop
    regex_pattern := '^' || replace(pattern, '*', '.*') || '$';
    if host ~ regex_pattern then
      return true;
    end if;
  end loop;

  return false;
end;
$function$
;

This does not work, as the function is referenced before it's defined, resulting in the following error:

Applying migration 20250523122453_patch.sql...
ERROR: function is_allowed_host(text, text[]) does not exist (SQLSTATE 42883)           
                                         
At statement 0:                

alter table "public"."users" add constraint "users_avatar_check" CHECK (((avatar IS NULL) OR is_allowed_host(avatar, ARRAY['localhost'::text, '127.0.0.1'::text, 'avatars.steamstatic.com'::text, '*.supabase.co'::text]))) not valid

Revadike avatar May 23 '25 12:05 Revadike