Created
July 11, 2022 12:04
-
-
Save bhvngt/d351c6a19b388e9d365484ca9672c4fa to your computer and use it in GitHub Desktop.
docker realtime logs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
realtime-realtime-1 | 2022-07-11 11:56:01.778 [error] Postgrex.Protocol (#PID<0.233.0>) failed to connect: ** (DBConnection.ConnectionError) tcp connect (db:5432): connection refused - :econnrefused | |
realtime-realtime-1 | 2022-07-11 11:56:01.778 [error] Postgrex.Protocol (#PID<0.232.0>) failed to connect: ** (DBConnection.ConnectionError) tcp connect (db:5432): connection refused - :econnrefused | |
realtime-realtime-1 | 2022-07-11 11:56:01.900 [error] Postgrex.Protocol (#PID<0.232.0>) failed to connect: ** (DBConnection.ConnectionError) tcp connect (db:5432): connection refused - :econnrefused | |
realtime-realtime-1 | 2022-07-11 11:56:01.981 [error] Postgrex.Protocol (#PID<0.233.0>) failed to connect: ** (DBConnection.ConnectionError) tcp connect (db:5432): connection refused - :econnrefused | |
realtime-realtime-1 | 2022-07-11 11:56:02.219 [error] Postgrex.Protocol (#PID<0.232.0>) failed to connect: ** (DBConnection.ConnectionError) tcp connect (db:5432): connection refused - :econnrefused | |
realtime-realtime-1 | 2022-07-11 11:56:02.564 [error] Postgrex.Protocol (#PID<0.233.0>) failed to connect: ** (DBConnection.ConnectionError) tcp connect (db:5432): connection refused - :econnrefused | |
realtime-realtime-1 | 2022-07-11 11:56:02.797 [error] Postgrex.Protocol (#PID<0.232.0>) failed to connect: ** (DBConnection.ConnectionError) tcp connect (db:5432): connection refused - :econnrefused | |
realtime-realtime-1 | 2022-07-11 11:56:03.388 [error] Postgrex.Protocol (#PID<0.232.0>) failed to connect: ** (DBConnection.ConnectionError) tcp connect (db:5432): connection refused - :econnrefused | |
realtime-realtime-1 | 2022-07-11 11:56:03.438 [error] Postgrex.Protocol (#PID<0.233.0>) failed to connect: ** (DBConnection.ConnectionError) tcp connect (db:5432): connection refused - :econnrefused | |
realtime-realtime-1 | 2022-07-11 11:56:04.445 [error] Postgrex.Protocol (#PID<0.232.0>) failed to connect: ** (DBConnection.ConnectionError) tcp connect (db:5432): connection refused - :econnrefused | |
realtime-realtime-1 | 2022-07-11 11:56:05.184 [error] Postgrex.Protocol (#PID<0.233.0>) failed to connect: ** (DBConnection.ConnectionError) tcp connect (db:5432): connection refused - :econnrefused | |
realtime-realtime-1 | 2022-07-11 11:56:07.512 [info] == Running 20211116024918 Realtime.RLS.Repo.Migrations.CreateRealtimeSubscriptionTable.change/0 forward | |
realtime-realtime-1 | 2022-07-11 11:56:07.512 [info] execute "create type realtime.equality_op as enum(\n 'eq', 'neq', 'lt', 'lte', 'gt', 'gte'\n );" | |
realtime-realtime-1 | 2022-07-11 11:56:07.527 [info] execute "create type realtime.user_defined_filter as (\n column_name text,\n op realtime.equality_op,\n value text\n );" | |
realtime-realtime-1 | 2022-07-11 11:56:07.534 [info] execute "create table realtime.subscription (\n -- Tracks which users are subscribed to each table\n id bigint not null generated always as identity,\n user_id uuid not null,\n -- Populated automatically by trigger. Required to enable auth.email()\n email varchar(255),\n entity regclass not null,\n filters realtime.user_defined_filter[] not null default '{}',\n created_at timestamp not null default timezone('utc', now()),\n\n constraint pk_subscription primary key (id),\n unique (entity, user_id, filters)\n )" | |
realtime-realtime-1 | 2022-07-11 11:56:07.568 [info] execute "create index ix_realtime_subscription_entity on realtime.subscription using hash (entity)" | |
realtime-realtime-1 | 2022-07-11 11:56:07.572 [info] == Migrated 20211116024918 in 0.0s | |
realtime-realtime-1 | 2022-07-11 11:56:07.603 [info] == Running 20211116045059 Realtime.RLS.Repo.Migrations.CreateRealtimeCheckFiltersTrigger.change/0 forward | |
realtime-realtime-1 | 2022-07-11 11:56:07.603 [info] execute "create function realtime.subscription_check_filters()\n returns trigger\n language plpgsql\n as $$\n /*\n Validates that the user defined filters for a subscription:\n - refer to valid columns that 'authenticated' may access\n - values are coercable to the correct column type\n */\n declare\n col_names text[] = coalesce(\n array_agg(c.column_name order by c.ordinal_position),\n '{}'::text[]\n )\n from\n information_schema.columns c\n where\n (quote_ident(c.table_schema) || '.' || quote_ident(c.table_name))::regclass = new.entity\n and pg_catalog.has_column_privilege('authenticated', new.entity, c.column_name, 'SELECT');\n filter realtime.user_defined_filter;\n col_type text;\n begin\n for filter in select * from unnest(new.filters) loop\n -- Filtered column is valid\n if not filter.column_name = any(col_names) then\n raise exception 'invalid column for filter %', filter.column_name;\n end if;\n\n -- Type is sanitized and safe for string interpolation\n col_type = (\n select atttypid::regtype\n from pg_catalog.pg_attribute\n where attrelid = new.entity\n and attname = filter.column_name\n )::text;\n if col_type is null then\n raise exception 'failed to lookup type for column %', filter.column_name;\n end if;\n -- raises an exception if value is not coercable to type\n perform format('select %s::%I', filter.value, col_type);\n end loop;\n\n -- Apply consistent order to filters so the unique constraint on\n -- (user_id, entity, filters) can't be tricked by a different filter order\n new.filters = coalesce(\n array_agg(f order by f.column_name, f.op, f.value),\n '{}'\n ) from unnest(new.filters) f;\n\n return new;\n end;\n $$;" | |
realtime-realtime-1 | 2022-07-11 11:56:07.614 [info] execute "create trigger tr_check_filters\n before insert or update on realtime.subscription\n for each row\n execute function realtime.subscription_check_filters();" | |
realtime-realtime-1 | 2022-07-11 11:56:07.618 [info] == Migrated 20211116045059 in 0.0s | |
realtime-realtime-1 | 2022-07-11 11:56:07.625 [info] == Running 20211116050929 Realtime.RLS.Repo.Migrations.CreateRealtimeQuoteWal2jsonFunction.change/0 forward | |
realtime-realtime-1 | 2022-07-11 11:56:07.626 [info] execute "create function realtime.quote_wal2json(entity regclass)\n returns text\n language sql\n immutable\n strict\n as $$\n select\n (\n select string_agg('' || ch,'')\n from unnest(string_to_array(nsp.nspname::text, null)) with ordinality x(ch, idx)\n where\n not (x.idx = 1 and x.ch = '\"')\n and not (\n x.idx = array_length(string_to_array(nsp.nspname::text, null), 1)\n and x.ch = '\"'\n )\n )\n || '.'\n || (\n select string_agg('' || ch,'')\n from unnest(string_to_array(pc.relname::text, null)) with ordinality x(ch, idx)\n where\n not (x.idx = 1 and x.ch = '\"')\n and not (\n x.idx = array_length(string_to_array(nsp.nspname::text, null), 1)\n and x.ch = '\"'\n )\n )\n from\n pg_class pc\n join pg_namespace nsp\n on pc.relnamespace = nsp.oid\n where\n pc.oid = entity\n $$;" | |
realtime-realtime-1 | 2022-07-11 11:56:07.637 [info] == Migrated 20211116050929 in 0.0s | |
realtime-realtime-1 | 2022-07-11 11:56:07.673 [info] == Running 20211116051442 Realtime.RLS.Repo.Migrations.CreateRealtimeCheckEqualityOpFunction.change/0 forward | |
realtime-realtime-1 | 2022-07-11 11:56:07.674 [info] execute "create function realtime.check_equality_op(\n op realtime.equality_op,\n type_ regtype,\n val_1 text,\n val_2 text\n )\n returns bool\n immutable\n language plpgsql\n as $$\n /*\n Casts *val_1* and *val_2* as type *type_* and check the *op* condition for truthiness\n */\n declare\n op_symbol text = (\n case\n when op = 'eq' then '='\n when op = 'neq' then '!='\n when op = 'lt' then '<'\n when op = 'lte' then '<='\n when op = 'gt' then '>'\n when op = 'gte' then '>='\n else 'UNKNOWN OP'\n end\n );\n res boolean;\n begin\n execute format('select %L::'|| type_::text || ' ' || op_symbol || ' %L::'|| type_::text, val_1, val_2) into res;\n return res;\n end;\n $$;" | |
realtime-realtime-1 | 2022-07-11 11:56:07.677 [info] == Migrated 20211116051442 in 0.0s | |
realtime-realtime-1 | 2022-07-11 11:56:07.679 [info] == Running 20211116212300 Realtime.RLS.Repo.Migrations.CreateRealtimeBuildPreparedStatementSqlFunction.change/0 forward | |
realtime-realtime-1 | 2022-07-11 11:56:07.679 [info] execute "create type realtime.wal_column as (\n name text,\n type text,\n value jsonb,\n is_pkey boolean,\n is_selectable boolean\n );" | |
realtime-realtime-1 | 2022-07-11 11:56:07.681 [info] execute "create function realtime.build_prepared_statement_sql(\n prepared_statement_name text,\n entity regclass,\n columns realtime.wal_column[]\n )\n returns text\n language sql\n as $$\n /*\n Builds a sql string that, if executed, creates a prepared statement to\n tests retrive a row from *entity* by its primary key columns.\n\n Example\n select realtime.build_prepared_statment_sql('public.notes', '{\"id\"}'::text[], '{\"bigint\"}'::text[])\n */\n select\n 'prepare ' || prepared_statement_name || ' as\n select\n exists(\n select\n 1\n from\n ' || entity || '\n where\n ' || string_agg(quote_ident(pkc.name) || '=' || quote_nullable(pkc.value) , ' and ') || '\n )'\n from\n unnest(columns) pkc\n where\n pkc.is_pkey\n group by\n entity\n $$;" | |
realtime-realtime-1 | 2022-07-11 11:56:07.684 [info] == Migrated 20211116212300 in 0.0s | |
realtime-realtime-1 | 2022-07-11 11:56:07.687 [info] == Running 20211116213355 Realtime.RLS.Repo.Migrations.CreateRealtimeCastFunction.change/0 forward | |
realtime-realtime-1 | 2022-07-11 11:56:07.687 [info] execute "create function realtime.cast(val text, type_ regtype)\n returns jsonb\n immutable\n language plpgsql\n as $$\n declare\n res jsonb;\n begin\n execute format('select to_jsonb(%L::'|| type_::text || ')', val) into res;\n return res;\n end\n $$;" | |
realtime-realtime-1 | 2022-07-11 11:56:07.688 [info] == Migrated 20211116213355 in 0.0s | |
realtime-realtime-1 | 2022-07-11 11:56:07.690 [info] == Running 20211116213934 Realtime.RLS.Repo.Migrations.CreateRealtimeIsVisibleThroughFiltersFunction.change/0 forward | |
realtime-realtime-1 | 2022-07-11 11:56:07.690 [info] execute "create function realtime.is_visible_through_filters(columns realtime.wal_column[], filters realtime.user_defined_filter[])\n returns bool\n language sql\n immutable\n as $$\n /*\n Should the record be visible (true) or filtered out (false) after *filters* are applied\n */\n select\n -- Default to allowed when no filters present\n coalesce(\n sum(\n realtime.check_equality_op(\n op:=f.op,\n type_:=col.type::regtype,\n -- cast jsonb to text\n val_1:=col.value #>> '{}',\n val_2:=f.value\n )::int\n ) = count(1),\n true\n )\n from\n unnest(filters) f\n join unnest(columns) col\n on f.column_name = col.name;\n $$;" | |
realtime-realtime-1 | 2022-07-11 11:56:07.693 [info] == Migrated 20211116213934 in 0.0s | |
realtime-realtime-1 | 2022-07-11 11:56:07.695 [info] == Running 20211116214523 Realtime.RLS.Repo.Migrations.CreateRealtimeApplyRlsFunction.change/0 forward | |
realtime-realtime-1 | 2022-07-11 11:56:07.695 [info] execute "create type realtime.action as enum ('INSERT', 'UPDATE', 'DELETE', 'TRUNCATE', 'ERROR');" | |
realtime-realtime-1 | 2022-07-11 11:56:07.697 [info] execute "create type realtime.wal_rls as (\n wal jsonb,\n is_rls_enabled boolean,\n users uuid[],\n errors text[]\n );" | |
realtime-realtime-1 | 2022-07-11 11:56:07.700 [info] execute "create function realtime.apply_rls(wal jsonb, max_record_bytes int = 1024 * 1024)\n returns realtime.wal_rls\n language plpgsql\n volatile\n as $$\n declare\n -- Regclass of the table e.g. public.notes\n entity_ regclass = (quote_ident(wal ->> 'schema') || '.' || quote_ident(wal ->> 'table'))::regclass;\n\n -- I, U, D, T: insert, update ...\n action realtime.action = (\n case wal ->> 'action'\n when 'I' then 'INSERT'\n when 'U' then 'UPDATE'\n when 'D' then 'DELETE'\n when 'T' then 'TRUNCATE'\n else 'ERROR'\n end\n );\n\n -- Is row level security enabled for the table\n is_rls_enabled bool = relrowsecurity from pg_class where oid = entity_;\n\n -- Subscription vars\n user_id uuid;\n email varchar(255);\n user_has_access bool;\n is_visible_to_user boolean;\n visible_to_user_ids uuid[] = '{}';\n\n -- user subscriptions to the wal record's table\n subscriptions realtime.subscription[] =\n array_agg(sub)\n from\n realtime.subscription sub\n where\n sub.entity = entity_;\n\n -- structured info for wal's columns\n columns realtime.wal_column[] =\n array_agg(\n (\n x->>'name',\n x->>'type',\n realtime.cast((x->'value') #>> '{}', (x->>'type')::regtype),\n (pks ->> 'name') is not null,\n pg_catalog.has_column_privilege('authenticated', entity_, x->>'name', 'SELECT')\n )::realtime.wal_column\n )\n from\n jsonb_array_elements(wal -> 'columns') x\n left join jsonb_array_elements(wal -> 'pk') pks\n on (x ->> 'name') = (pks ->> 'name');\n\n -- previous identity values for update/delete\n old_columns realtime.wal_column[] =\n array_agg(\n (\n x->>'name',\n x->>'type',\n realtime.cast((x->'value') #>> '{}', (x->>'type')::regtype),\n (pks ->> 'name') is not null,\n pg_catalog.has_column_privilege('authenticated', entity_, x->>'name', 'SELECT')\n )::realtime.wal_column\n )\n from\n jsonb_array_elements(wal -> 'identity') x\n left join jsonb_array_elements(wal -> 'pk') pks\n on (x ->> 'name') = (pks ->> 'name');\n\n output jsonb;\n\n -- Error states\n error_record_exceeds_max_size boolean = octet_length(wal::text) > max_record_bytes;\n error_unauthorized boolean = not pg_catalog.has_any_column_privilege('authenticated', entity_, 'SELECT');\n\n errors text[] = case\n when error_record_exceeds_max_size then array['Error 413: Payload Too Large']\n else '{}'::text[]\n end;\n begin\n\n -- The 'authenticated' user does not have SELECT permission on any of the columns for the entity_\n if error_unauthorized is true then\n return (\n null,\n null,\n visible_to_user_ids,\n array['Error 401: Unauthorized']\n )::realtime.wal_rls;\n end if;\n\n -------------------------------\n -- Build Output JSONB Object --\n -------------------------------\n output = jsonb_build_object(\n 'schema', wal ->> 'schema',\n 'table', wal ->> 'table',\n 'type', action,\n 'commit_timestamp', (wal ->> 'timestamp')::text::timestamp with time zone,\n 'columns', (\n select\n jsonb_agg(\n jsonb_build_object(\n 'name', pa.attname,\n 'type', pt.typname\n )\n order by pa.attnum asc\n )\n from\n pg_attribute pa\n join pg_type pt\n on pa.atttypid = pt.oid\n where\n attrelid = entity_\n and attnum > 0\n and pg_catalog.has_column_privilege('authenticated', entity_, pa.attname, 'SELECT')\n )\n )\n -- Add \"record\" key for insert and update\n || case\n when error_record_exceeds_max_size then jsonb_build_object('record', '{}'::jsonb)\n when action in ('INSERT'," <> ... | |
realtime-realtime-1 | 2022-07-11 11:56:07.708 [info] == Migrated 20211116214523 in 0.0s | |
realtime-realtime-1 | 2022-07-11 11:56:07.710 [info] == Running 20211122062447 Realtime.RLS.Repo.Migrations.GrantRealtimeUsageToAuthenticatedRole.change/0 forward | |
realtime-realtime-1 | 2022-07-11 11:56:07.710 [info] execute "grant usage on schema realtime to authenticated;" | |
realtime-realtime-1 | 2022-07-11 11:56:07.713 [info] == Migrated 20211122062447 in 0.0s | |
realtime-realtime-1 | 2022-07-11 11:56:07.716 [info] == Running 20211124070109 Realtime.RLS.Repo.Migrations.EnableRealtimeApplyRlsFunctionPostgrest9Compatibility.change/0 forward | |
realtime-realtime-1 | 2022-07-11 11:56:07.716 [info] execute "create or replace function realtime.apply_rls(wal jsonb, max_record_bytes int = 1024 * 1024)\n returns realtime.wal_rls\n language plpgsql\n volatile\n as $$\n declare\n -- Regclass of the table e.g. public.notes\n entity_ regclass = (quote_ident(wal ->> 'schema') || '.' || quote_ident(wal ->> 'table'))::regclass;\n\n -- I, U, D, T: insert, update ...\n action realtime.action = (\n case wal ->> 'action'\n when 'I' then 'INSERT'\n when 'U' then 'UPDATE'\n when 'D' then 'DELETE'\n when 'T' then 'TRUNCATE'\n else 'ERROR'\n end\n );\n\n -- Is row level security enabled for the table\n is_rls_enabled bool = relrowsecurity from pg_class where oid = entity_;\n\n -- Subscription vars\n user_id uuid;\n email varchar(255);\n user_has_access bool;\n is_visible_to_user boolean;\n visible_to_user_ids uuid[] = '{}';\n\n -- user subscriptions to the wal record's table\n subscriptions realtime.subscription[] =\n array_agg(sub)\n from\n realtime.subscription sub\n where\n sub.entity = entity_;\n\n -- structured info for wal's columns\n columns realtime.wal_column[] =\n array_agg(\n (\n x->>'name',\n x->>'type',\n realtime.cast((x->'value') #>> '{}', (x->>'type')::regtype),\n (pks ->> 'name') is not null,\n pg_catalog.has_column_privilege('authenticated', entity_, x->>'name', 'SELECT')\n )::realtime.wal_column\n )\n from\n jsonb_array_elements(wal -> 'columns') x\n left join jsonb_array_elements(wal -> 'pk') pks\n on (x ->> 'name') = (pks ->> 'name');\n\n -- previous identity values for update/delete\n old_columns realtime.wal_column[] =\n array_agg(\n (\n x->>'name',\n x->>'type',\n realtime.cast((x->'value') #>> '{}', (x->>'type')::regtype),\n (pks ->> 'name') is not null,\n pg_catalog.has_column_privilege('authenticated', entity_, x->>'name', 'SELECT')\n )::realtime.wal_column\n )\n from\n jsonb_array_elements(wal -> 'identity') x\n left join jsonb_array_elements(wal -> 'pk') pks\n on (x ->> 'name') = (pks ->> 'name');\n\n output jsonb;\n\n -- Error states\n error_record_exceeds_max_size boolean = octet_length(wal::text) > max_record_bytes;\n error_unauthorized boolean = not pg_catalog.has_any_column_privilege('authenticated', entity_, 'SELECT');\n\n errors text[] = case\n when error_record_exceeds_max_size then array['Error 413: Payload Too Large']\n else '{}'::text[]\n end;\n begin\n\n -- The 'authenticated' user does not have SELECT permission on any of the columns for the entity_\n if error_unauthorized is true then\n return (\n null,\n null,\n visible_to_user_ids,\n array['Error 401: Unauthorized']\n )::realtime.wal_rls;\n end if;\n\n -------------------------------\n -- Build Output JSONB Object --\n -------------------------------\n output = jsonb_build_object(\n 'schema', wal ->> 'schema',\n 'table', wal ->> 'table',\n 'type', action,\n 'commit_timestamp', (wal ->> 'timestamp')::text::timestamp with time zone,\n 'columns', (\n select\n jsonb_agg(\n jsonb_build_object(\n 'name', pa.attname,\n 'type', pt.typname\n )\n order by pa.attnum asc\n )\n from\n pg_attribute pa\n join pg_type pt\n on pa.atttypid = pt.oid\n where\n attrelid = entity_\n and attnum > 0\n and pg_catalog.has_column_privilege('authenticated', entity_, pa.attname, 'SELECT')\n )\n )\n -- Add \"record\" key for insert and update\n || case\n when error_record_exceeds_max_size then jsonb_build_object('record', '{}'::jsonb)\n when action in" <> ... | |
realtime-realtime-1 | 2022-07-11 11:56:07.723 [info] == Migrated 20211124070109 in 0.0s | |
realtime-realtime-1 | 2022-07-11 11:56:07.726 [info] == Running 20211202204204 Realtime.RLS.Repo.Migrations.UpdateRealtimeSubscriptionCheckFiltersFunctionSecurity.change/0 forward | |
realtime-realtime-1 | 2022-07-11 11:56:07.727 [info] execute "create or replace function realtime.subscription_check_filters()\n returns trigger\n language plpgsql\n as $$\n /*\n Validates that the user defined filters for a subscription:\n - refer to valid columns that 'authenticated' may access\n - values are coercable to the correct column type\n */\n declare\n col_names text[] = coalesce(\n array_agg(c.column_name order by c.ordinal_position),\n '{}'::text[]\n )\n from\n information_schema.columns c\n where\n (quote_ident(c.table_schema) || '.' || quote_ident(c.table_name))::regclass = new.entity\n and pg_catalog.has_column_privilege('authenticated', new.entity, c.column_name, 'SELECT');\n filter realtime.user_defined_filter;\n col_type regtype;\n begin\n for filter in select * from unnest(new.filters) loop\n -- Filtered column is valid\n if not filter.column_name = any(col_names) then\n raise exception 'invalid column for filter %', filter.column_name;\n end if;\n\n -- Type is sanitized and safe for string interpolation\n col_type = (\n select atttypid::regtype\n from pg_catalog.pg_attribute\n where attrelid = new.entity\n and attname = filter.column_name\n );\n if col_type is null then\n raise exception 'failed to lookup type for column %', filter.column_name;\n end if;\n -- raises an exception if value is not coercable to type\n perform realtime.cast(filter.value, col_type);\n end loop;\n\n -- Apply consistent order to filters so the unique constraint on\n -- (user_id, entity, filters) can't be tricked by a different filter order\n new.filters = coalesce(\n array_agg(f order by f.column_name, f.op, f.value),\n '{}'\n ) from unnest(new.filters) f;\n\n return new;\n end;\n $$;" | |
realtime-realtime-1 | 2022-07-11 11:56:07.737 [info] == Migrated 20211202204204 in 0.0s | |
realtime-realtime-1 | 2022-07-11 11:56:07.739 [info] == Running 20211202204605 Realtime.RLS.Repo.Migrations.UpdateRealtimeBuildPreparedStatementSqlFunctionForCompatibilityWithAllTypes.change/0 forward | |
realtime-realtime-1 | 2022-07-11 11:56:07.739 [info] execute "create or replace function realtime.build_prepared_statement_sql(\n prepared_statement_name text,\n entity regclass,\n columns realtime.wal_column[]\n )\n returns text\n language sql\n as $$\n /*\n Builds a sql string that, if executed, creates a prepared statement to\n tests retrive a row from *entity* by its primary key columns.\n\n Example\n select realtime.build_prepared_statment_sql('public.notes', '{\"id\"}'::text[], '{\"bigint\"}'::text[])\n */\n select\n 'prepare ' || prepared_statement_name || ' as\n select\n exists(\n select\n 1\n from\n ' || entity || '\n where\n ' || string_agg(quote_ident(pkc.name) || '=' || quote_nullable(pkc.value #>> '{}') , ' and ') || '\n )'\n from\n unnest(columns) pkc\n where\n pkc.is_pkey\n group by\n entity\n $$;" | |
realtime-realtime-1 | 2022-07-11 11:56:07.745 [info] == Migrated 20211202204605 in 0.0s | |
realtime-realtime-1 | 2022-07-11 11:56:07.747 [info] == Running 20211210212804 Realtime.RLS.Repo.Migrations.EnableGenericSubscriptionClaims.change/0 forward | |
realtime-realtime-1 | 2022-07-11 11:56:07.748 [info] execute "truncate table realtime.subscription restart identity" | |
realtime-realtime-1 | 2022-07-11 11:56:07.756 [info] execute "alter table realtime.subscription\n drop constraint subscription_entity_user_id_filters_key cascade,\n drop column email cascade,\n drop column created_at cascade" | |
realtime-realtime-1 | 2022-07-11 11:56:07.762 [info] execute "alter table realtime.subscription rename user_id to subscription_id" | |
realtime-realtime-1 | 2022-07-11 11:56:07.763 [info] execute "create function realtime.to_regrole(role_name text)\n returns regrole\n immutable\n language sql\n -- required to allow use in generated clause\n as $$ select role_name::regrole $$;" | |
realtime-realtime-1 | 2022-07-11 11:56:07.764 [info] execute "alter table realtime.subscription\n add column claims jsonb not null,\n add column claims_role regrole not null generated always as (realtime.to_regrole(claims ->> 'role')) stored,\n add column created_at timestamp not null default timezone('utc', now())" | |
realtime-realtime-1 | 2022-07-11 11:56:07.780 [info] execute "create unique index subscription_subscription_id_entity_filters_key on realtime.subscription (subscription_id, entity, filters)" | |
realtime-realtime-1 | 2022-07-11 11:56:07.783 [info] execute "revoke usage on schema realtime from authenticated;" | |
realtime-realtime-1 | 2022-07-11 11:56:07.784 [info] execute "revoke all on realtime.subscription from authenticated;" | |
realtime-realtime-1 | 2022-07-11 11:56:07.785 [info] execute "create or replace function realtime.subscription_check_filters()\n returns trigger\n language plpgsql\n as $$\n /*\n Validates that the user defined filters for a subscription:\n - refer to valid columns that the claimed role may access\n - values are coercable to the correct column type\n */\n declare\n col_names text[] = coalesce(\n array_agg(c.column_name order by c.ordinal_position),\n '{}'::text[]\n )\n from\n information_schema.columns c\n where\n format('%I.%I', c.table_schema, c.table_name)::regclass = new.entity\n and pg_catalog.has_column_privilege((new.claims ->> 'role'), new.entity, c.column_name, 'SELECT');\n filter realtime.user_defined_filter;\n col_type regtype;\n begin\n for filter in select * from unnest(new.filters) loop\n -- Filtered column is valid\n if not filter.column_name = any(col_names) then\n raise exception 'invalid column for filter %', filter.column_name;\n end if;\n\n -- Type is sanitized and safe for string interpolation\n col_type = (\n select atttypid::regtype\n from pg_catalog.pg_attribute\n where attrelid = new.entity\n and attname = filter.column_name\n );\n if col_type is null then\n raise exception 'failed to lookup type for column %', filter.column_name;\n end if;\n -- raises an exception if value is not coercable to type\n perform realtime.cast(filter.value, col_type);\n end loop;\n\n -- Apply consistent order to filters so the unique constraint on\n -- (subscription_id, entity, filters) can't be tricked by a different filter order\n new.filters = coalesce(\n array_agg(f order by f.column_name, f.op, f.value),\n '{}'\n ) from unnest(new.filters) f;\n\n return new;\n end;\n $$;" | |
realtime-realtime-1 | 2022-07-11 11:56:07.788 [info] execute "alter type realtime.wal_rls rename attribute users to subscription_ids cascade;" | |
realtime-realtime-1 | 2022-07-11 11:56:07.789 [info] execute "drop function realtime.apply_rls(jsonb, integer);" | |
realtime-realtime-1 | 2022-07-11 11:56:07.792 [info] execute "create function realtime.apply_rls(wal jsonb, max_record_bytes int = 1024 * 1024)\n returns setof realtime.wal_rls\n language plpgsql\n volatile\n as $$\n declare\n -- Regclass of the table e.g. public.notes\n entity_ regclass = (quote_ident(wal ->> 'schema') || '.' || quote_ident(wal ->> 'table'))::regclass;\n\n -- I, U, D, T: insert, update ...\n action realtime.action = (\n case wal ->> 'action'\n when 'I' then 'INSERT'\n when 'U' then 'UPDATE'\n when 'D' then 'DELETE'\n else 'ERROR'\n end\n );\n\n -- Is row level security enabled for the table\n is_rls_enabled bool = relrowsecurity from pg_class where oid = entity_;\n\n subscriptions realtime.subscription[] = array_agg(subs)\n from\n realtime.subscription subs\n where\n subs.entity = entity_;\n\n -- Subscription vars\n roles regrole[] = array_agg(distinct us.claims_role)\n from\n unnest(subscriptions) us;\n\n working_role regrole;\n claimed_role regrole;\n claims jsonb;\n\n subscription_id uuid;\n subscription_has_access bool;\n visible_to_subscription_ids uuid[] = '{}';\n\n -- structured info for wal's columns\n columns realtime.wal_column[];\n -- previous identity values for update/delete\n old_columns realtime.wal_column[];\n\n error_record_exceeds_max_size boolean = octet_length(wal::text) > max_record_bytes;\n\n -- Primary jsonb output for record\n output jsonb;\n\n begin\n perform set_config('role', null, true);\n\n columns =\n array_agg(\n (\n x->>'name',\n x->>'type',\n realtime.cast((x->'value') #>> '{}', (x->>'type')::regtype),\n (pks ->> 'name') is not null,\n true\n )::realtime.wal_column\n )\n from\n jsonb_array_elements(wal -> 'columns') x\n left join jsonb_array_elements(wal -> 'pk') pks\n on (x ->> 'name') = (pks ->> 'name');\n\n old_columns =\n array_agg(\n (\n x->>'name',\n x->>'type',\n realtime.cast((x->'value') #>> '{}', (x->>'type')::regtype),\n (pks ->> 'name') is not null,\n true\n )::realtime.wal_column\n )\n from\n jsonb_array_elements(wal -> 'identity') x\n left join jsonb_array_elements(wal -> 'pk') pks\n on (x ->> 'name') = (pks ->> 'name');\n\n for working_role in select * from unnest(roles) loop\n\n -- Update `is_selectable` for columns and old_columns\n columns =\n array_agg(\n (\n c.name,\n c.type,\n c.value,\n c.is_pkey,\n pg_catalog.has_column_privilege(working_role, entity_, c.name, 'SELECT')\n )::realtime.wal_column\n )\n from\n unnest(columns) c;\n\n old_columns =\n array_agg(\n (\n c.name,\n c.type,\n c.value,\n c.is_pkey,\n pg_catalog.has_column_privilege(working_role, entity_, c.name, 'SELECT')\n )::realtime.wal_column\n )\n from\n unnest(old_columns) c;\n\n if action <> 'DELETE' and count(1) = 0 from unnest(columns) c where c.is_pkey then\n return next (\n null,\n is_rls_enabled,\n -- subscriptions is already filtered by entity\n (select array_agg(s.subscription_id) from unnest(subscriptions) as s where claims_role = working_role),\n array['Error 400: Bad Request, no primary key']\n )::realtime.wal_rls;\n\n -- The claims role does not have SELECT permission to the primary key of entity\n elsif action <> 'DELETE' and sum(c.is_selectable::int) <> count(1) from unnest(columns) c where c.is_pkey t" <> ... | |
realtime-realtime-1 | 2022-07-11 11:56:07.799 [info] == Migrated 20211210212804 in 0.0s | |
realtime-realtime-1 | 2022-07-11 11:56:07.804 [info] == Running 20211228014915 Realtime.RLS.Repo.Migrations.AddWalPayloadOnErrorsInApplyRlsFunction.change/0 forward | |
realtime-realtime-1 | 2022-07-11 11:56:07.805 [info] execute "create or replace function realtime.apply_rls(wal jsonb, max_record_bytes int = 1024 * 1024)\n returns setof realtime.wal_rls\n language plpgsql\n volatile\n as $$\n declare\n -- Regclass of the table e.g. public.notes\n entity_ regclass = (quote_ident(wal ->> 'schema') || '.' || quote_ident(wal ->> 'table'))::regclass;\n\n -- I, U, D, T: insert, update ...\n action realtime.action = (\n case wal ->> 'action'\n when 'I' then 'INSERT'\n when 'U' then 'UPDATE'\n when 'D' then 'DELETE'\n else 'ERROR'\n end\n );\n\n -- Is row level security enabled for the table\n is_rls_enabled bool = relrowsecurity from pg_class where oid = entity_;\n\n subscriptions realtime.subscription[] = array_agg(subs)\n from\n realtime.subscription subs\n where\n subs.entity = entity_;\n\n -- Subscription vars\n roles regrole[] = array_agg(distinct us.claims_role)\n from\n unnest(subscriptions) us;\n\n working_role regrole;\n claimed_role regrole;\n claims jsonb;\n\n subscription_id uuid;\n subscription_has_access bool;\n visible_to_subscription_ids uuid[] = '{}';\n\n -- structured info for wal's columns\n columns realtime.wal_column[];\n -- previous identity values for update/delete\n old_columns realtime.wal_column[];\n\n error_record_exceeds_max_size boolean = octet_length(wal::text) > max_record_bytes;\n\n -- Primary jsonb output for record\n output jsonb;\n\n begin\n perform set_config('role', null, true);\n\n columns =\n array_agg(\n (\n x->>'name',\n x->>'type',\n realtime.cast((x->'value') #>> '{}', (x->>'type')::regtype),\n (pks ->> 'name') is not null,\n true\n )::realtime.wal_column\n )\n from\n jsonb_array_elements(wal -> 'columns') x\n left join jsonb_array_elements(wal -> 'pk') pks\n on (x ->> 'name') = (pks ->> 'name');\n\n old_columns =\n array_agg(\n (\n x->>'name',\n x->>'type',\n realtime.cast((x->'value') #>> '{}', (x->>'type')::regtype),\n (pks ->> 'name') is not null,\n true\n )::realtime.wal_column\n )\n from\n jsonb_array_elements(wal -> 'identity') x\n left join jsonb_array_elements(wal -> 'pk') pks\n on (x ->> 'name') = (pks ->> 'name');\n\n for working_role in select * from unnest(roles) loop\n\n -- Update `is_selectable` for columns and old_columns\n columns =\n array_agg(\n (\n c.name,\n c.type,\n c.value,\n c.is_pkey,\n pg_catalog.has_column_privilege(working_role, entity_, c.name, 'SELECT')\n )::realtime.wal_column\n )\n from\n unnest(columns) c;\n\n old_columns =\n array_agg(\n (\n c.name,\n c.type,\n c.value,\n c.is_pkey,\n pg_catalog.has_column_privilege(working_role, entity_, c.name, 'SELECT')\n )::realtime.wal_column\n )\n from\n unnest(old_columns) c;\n\n if action <> 'DELETE' and count(1) = 0 from unnest(columns) c where c.is_pkey then\n return next (\n jsonb_build_object(\n 'schema', wal ->> 'schema',\n 'table', wal ->> 'table',\n 'type', action\n ),\n is_rls_enabled,\n -- subscriptions is already filtered by entity\n (select array_agg(s.subscription_id) from unnest(subscriptions) as s where claims_role = working_role),\n array['Error 400: Bad Request, no primary key']\n )::realtime.wal_rls;\n\n -- The claims role does not have SELECT permission to the primary key of entity\n elsif action <> 'DELETE' and sum(c.is_selectable::int) <> count(1) from unnest(columns) c where c.is_pkey then\n return next (\n jsonb_build_object(\n 'schema', wal ->> 'schema',\n 'table', wal ->> 'table',\n 'type', action\n ),\n " <> ... | |
realtime-realtime-1 | 2022-07-11 11:56:07.810 [info] == Migrated 20211228014915 in 0.0s | |
realtime-realtime-1 | 2022-07-11 11:56:07.813 [info] == Running 20220107221237 Realtime.RLS.Repo.Migrations.UpdateChangeTimestampToIso8601ZuluFormat.change/0 forward | |
realtime-realtime-1 | 2022-07-11 11:56:07.813 [info] execute "create or replace function realtime.apply_rls(wal jsonb, max_record_bytes int = 1024 * 1024)\n returns setof realtime.wal_rls\n language plpgsql\n volatile\n as $$\n declare\n -- Regclass of the table e.g. public.notes\n entity_ regclass = (quote_ident(wal ->> 'schema') || '.' || quote_ident(wal ->> 'table'))::regclass;\n\n -- I, U, D, T: insert, update ...\n action realtime.action = (\n case wal ->> 'action'\n when 'I' then 'INSERT'\n when 'U' then 'UPDATE'\n when 'D' then 'DELETE'\n else 'ERROR'\n end\n );\n\n -- Is row level security enabled for the table\n is_rls_enabled bool = relrowsecurity from pg_class where oid = entity_;\n\n subscriptions realtime.subscription[] = array_agg(subs)\n from\n realtime.subscription subs\n where\n subs.entity = entity_;\n\n -- Subscription vars\n roles regrole[] = array_agg(distinct us.claims_role)\n from\n unnest(subscriptions) us;\n\n working_role regrole;\n claimed_role regrole;\n claims jsonb;\n\n subscription_id uuid;\n subscription_has_access bool;\n visible_to_subscription_ids uuid[] = '{}';\n\n -- structured info for wal's columns\n columns realtime.wal_column[];\n -- previous identity values for update/delete\n old_columns realtime.wal_column[];\n\n error_record_exceeds_max_size boolean = octet_length(wal::text) > max_record_bytes;\n\n -- Primary jsonb output for record\n output jsonb;\n\n begin\n perform set_config('role', null, true);\n\n columns =\n array_agg(\n (\n x->>'name',\n x->>'type',\n realtime.cast((x->'value') #>> '{}', (x->>'type')::regtype),\n (pks ->> 'name') is not null,\n true\n )::realtime.wal_column\n )\n from\n jsonb_array_elements(wal -> 'columns') x\n left join jsonb_array_elements(wal -> 'pk') pks\n on (x ->> 'name') = (pks ->> 'name');\n\n old_columns =\n array_agg(\n (\n x->>'name',\n x->>'type',\n realtime.cast((x->'value') #>> '{}', (x->>'type')::regtype),\n (pks ->> 'name') is not null,\n true\n )::realtime.wal_column\n )\n from\n jsonb_array_elements(wal -> 'identity') x\n left join jsonb_array_elements(wal -> 'pk') pks\n on (x ->> 'name') = (pks ->> 'name');\n\n for working_role in select * from unnest(roles) loop\n\n -- Update `is_selectable` for columns and old_columns\n columns =\n array_agg(\n (\n c.name,\n c.type,\n c.value,\n c.is_pkey,\n pg_catalog.has_column_privilege(working_role, entity_, c.name, 'SELECT')\n )::realtime.wal_column\n )\n from\n unnest(columns) c;\n\n old_columns =\n array_agg(\n (\n c.name,\n c.type,\n c.value,\n c.is_pkey,\n pg_catalog.has_column_privilege(working_role, entity_, c.name, 'SELECT')\n )::realtime.wal_column\n )\n from\n unnest(old_columns) c;\n\n if action <> 'DELETE' and count(1) = 0 from unnest(columns) c where c.is_pkey then\n return next (\n null,\n is_rls_enabled,\n -- subscriptions is already filtered by entity\n (select array_agg(s.subscription_id) from unnest(subscriptions) as s where claims_role = working_role),\n array['Error 400: Bad Request, no primary key']\n )::realtime.wal_rls;\n\n -- The claims role does not have SELECT permission to the primary key of entity\n elsif action <> 'DELETE' and sum(c.is_selectable::int) <> count(1) from unnest(columns) c where " <> ... | |
realtime-realtime-1 | 2022-07-11 11:56:07.818 [info] == Migrated 20220107221237 in 0.0s | |
realtime-realtime-1 | 2022-07-11 11:56:07.820 [info] == Running 20220228202821 Realtime.RLS.Repo.Migrations.UpdateSubscriptionCheckFiltersFunctionDynamicTableName.change/0 forward | |
realtime-realtime-1 | 2022-07-11 11:56:07.820 [info] execute "create or replace function realtime.subscription_check_filters()\n returns trigger\n language plpgsql\n as $$\n /*\n Validates that the user defined filters for a subscription:\n - refer to valid columns that the claimed role may access\n - values are coercable to the correct column type\n */\n declare\n col_names text[] = coalesce(\n array_agg(c.column_name order by c.ordinal_position),\n '{}'::text[]\n )\n from\n information_schema.columns c\n where\n format('%I.%I', c.table_schema, c.table_name)::regclass = new.entity\n and pg_catalog.has_column_privilege(\n (new.claims ->> 'role'),\n format('%I.%I', c.table_schema, c.table_name)::regclass,\n c.column_name,\n 'SELECT'\n );\n filter realtime.user_defined_filter;\n col_type regtype;\n begin\n for filter in select * from unnest(new.filters) loop\n -- Filtered column is valid\n if not filter.column_name = any(col_names) then\n raise exception 'invalid column for filter %', filter.column_name;\n end if;\n\n -- Type is sanitized and safe for string interpolation\n col_type = (\n select atttypid::regtype\n from pg_catalog.pg_attribute\n where attrelid = new.entity\n and attname = filter.column_name\n );\n if col_type is null then\n raise exception 'failed to lookup type for column %', filter.column_name;\n end if;\n -- raises an exception if value is not coercable to type\n perform realtime.cast(filter.value, col_type);\n end loop;\n\n -- Apply consistent order to filters so the unique constraint on\n -- (subscription_id, entity, filters) can't be tricked by a different filter order\n new.filters = coalesce(\n array_agg(f order by f.column_name, f.op, f.value),\n '{}'\n ) from unnest(new.filters) f;\n\n return new;\n end;\n $$;" | |
realtime-realtime-1 | 2022-07-11 11:56:07.822 [info] == Migrated 20220228202821 in 0.0s | |
realtime-realtime-1 | 2022-07-11 11:56:07.824 [info] == Running 20220312004840 Realtime.RLS.Repo.Migrations.UpdateApplyRlsFunctionToApplyIso8601.change/0 forward | |
realtime-realtime-1 | 2022-07-11 11:56:07.824 [info] execute "create or replace function realtime.apply_rls(wal jsonb, max_record_bytes int = 1024 * 1024)\n returns setof realtime.wal_rls\n language plpgsql\n volatile\n as $$\n declare\n -- Regclass of the table e.g. public.notes\n entity_ regclass = (quote_ident(wal ->> 'schema') || '.' || quote_ident(wal ->> 'table'))::regclass;\n\n -- I, U, D, T: insert, update ...\n action realtime.action = (\n case wal ->> 'action'\n when 'I' then 'INSERT'\n when 'U' then 'UPDATE'\n when 'D' then 'DELETE'\n else 'ERROR'\n end\n );\n\n -- Is row level security enabled for the table\n is_rls_enabled bool = relrowsecurity from pg_class where oid = entity_;\n\n subscriptions realtime.subscription[] = array_agg(subs)\n from\n realtime.subscription subs\n where\n subs.entity = entity_;\n\n -- Subscription vars\n roles regrole[] = array_agg(distinct us.claims_role)\n from\n unnest(subscriptions) us;\n\n working_role regrole;\n claimed_role regrole;\n claims jsonb;\n\n subscription_id uuid;\n subscription_has_access bool;\n visible_to_subscription_ids uuid[] = '{}';\n\n -- structured info for wal's columns\n columns realtime.wal_column[];\n -- previous identity values for update/delete\n old_columns realtime.wal_column[];\n\n error_record_exceeds_max_size boolean = octet_length(wal::text) > max_record_bytes;\n\n -- Primary jsonb output for record\n output jsonb;\n\n begin\n perform set_config('role', null, true);\n\n columns =\n array_agg(\n (\n x->>'name',\n x->>'type',\n realtime.cast((x->'value') #>> '{}', (x->>'type')::regtype),\n (pks ->> 'name') is not null,\n true\n )::realtime.wal_column\n )\n from\n jsonb_array_elements(wal -> 'columns') x\n left join jsonb_array_elements(wal -> 'pk') pks\n on (x ->> 'name') = (pks ->> 'name');\n\n old_columns =\n array_agg(\n (\n x->>'name',\n x->>'type',\n realtime.cast((x->'value') #>> '{}', (x->>'type')::regtype),\n (pks ->> 'name') is not null,\n true\n )::realtime.wal_column\n )\n from\n jsonb_array_elements(wal -> 'identity') x\n left join jsonb_array_elements(wal -> 'pk') pks\n on (x ->> 'name') = (pks ->> 'name');\n\n for working_role in select * from unnest(roles) loop\n\n -- Update `is_selectable` for columns and old_columns\n columns =\n array_agg(\n (\n c.name,\n c.type,\n c.value,\n c.is_pkey,\n pg_catalog.has_column_privilege(working_role, entity_, c.name, 'SELECT')\n )::realtime.wal_column\n )\n from\n unnest(columns) c;\n\n old_columns =\n array_agg(\n (\n c.name,\n c.type,\n c.value,\n c.is_pkey,\n pg_catalog.has_column_privilege(working_role, entity_, c.name, 'SELECT')\n )::realtime.wal_column\n )\n from\n unnest(old_columns) c;\n\n if action <> 'DELETE' and count(1) = 0 from unnest(columns) c where c.is_pkey then\n return next (\n null,\n is_rls_enabled,\n -- subscriptions is already filtered by entity\n (select array_agg(s.subscription_id) from unnest(subscriptions) as s where claims_role = working_role),\n array['Error 400: Bad Request, no primary key']\n )::realtime.wal_rls;\n\n -- The claims role does not have SELECT permission to the primary key of entity\n elsif action <> 'DELETE' and sum(c.is_selectable::int) <> count(1) from unnest(columns) c where " <> ... | |
realtime-realtime-1 | 2022-07-11 11:56:07.828 [info] == Migrated 20220312004840 in 0.0s | |
realtime-realtime-1 | 2022-07-11 11:56:07.830 [info] == Running 20220603231003 Realtime.RLS.Repo.Migrations.AddQuotedRegtypesSupport.change/0 forward | |
realtime-realtime-1 | 2022-07-11 11:56:07.830 [info] execute "drop type if exists realtime.wal_column cascade;" | |
realtime-realtime-1 | 2022-07-11 11:56:07.835 [info] drop cascades to 2 other objects | |
realtime-realtime-1 | 2022-07-11 11:56:07.835 [info] execute "\n create type realtime.wal_column as (\n name text,\n type_name text,\n type_oid oid,\n value jsonb,\n is_pkey boolean,\n is_selectable boolean\n );\n " | |
realtime-realtime-1 | 2022-07-11 11:56:07.837 [info] execute "\n create or replace function realtime.is_visible_through_filters(columns realtime.wal_column[], filters realtime.user_defined_filter[])\n returns bool\n language sql\n immutable\n as $$\n /*\n Should the record be visible (true) or filtered out (false) after *filters* are applied\n */\n select\n -- Default to allowed when no filters present\n coalesce(\n sum(\n realtime.check_equality_op(\n op:=f.op,\n type_:=col.type_oid::regtype,\n -- cast jsonb to text\n val_1:=col.value #>> '{}',\n val_2:=f.value\n )::int\n ) = count(1),\n true\n )\n from\n unnest(filters) f\n join unnest(columns) col\n on f.column_name = col.name;\n $$;" | |
realtime-realtime-1 | 2022-07-11 11:56:07.840 [info] execute "\n create or replace function realtime.apply_rls(wal jsonb, max_record_bytes int = 1024 * 1024)\n returns setof realtime.wal_rls\n language plpgsql\n volatile\n as $$\n declare\n -- Regclass of the table e.g. public.notes\n entity_ regclass = (quote_ident(wal ->> 'schema') || '.' || quote_ident(wal ->> 'table'))::regclass;\n -- I, U, D, T: insert, update ...\n action realtime.action = (\n case wal ->> 'action'\n when 'I' then 'INSERT'\n when 'U' then 'UPDATE'\n when 'D' then 'DELETE'\n else 'ERROR'\n end\n );\n -- Is row level security enabled for the table\n is_rls_enabled bool = relrowsecurity from pg_class where oid = entity_;\n subscriptions realtime.subscription[] = array_agg(subs)\n from\n realtime.subscription subs\n where\n subs.entity = entity_;\n -- Subscription vars\n roles regrole[] = array_agg(distinct us.claims_role)\n from\n unnest(subscriptions) us;\n working_role regrole;\n claimed_role regrole;\n claims jsonb;\n subscription_id uuid;\n subscription_has_access bool;\n visible_to_subscription_ids uuid[] = '{}';\n -- structured info for wal's columns\n columns realtime.wal_column[];\n -- previous identity values for update/delete\n old_columns realtime.wal_column[];\n\n error_record_exceeds_max_size boolean = octet_length(wal::text) > max_record_bytes;\n\n -- Primary jsonb output for record\n output jsonb;\n\n begin\n perform set_config('role', null, true);\n\n columns =\n array_agg(\n (\n x->>'name',\n x->>'type',\n x->>'typeoid',\n realtime.cast(\n (x->'value') #>> '{}',\n (x->>'typeoid')::regtype\n ),\n (pks ->> 'name') is not null,\n true\n )::realtime.wal_column\n )\n from\n jsonb_array_elements(wal -> 'columns') x\n left join jsonb_array_elements(wal -> 'pk') pks\n on (x ->> 'name') = (pks ->> 'name');\n\n old_columns =\n array_agg(\n (\n x->>'name',\n x->>'type',\n x->>'typeoid',\n realtime.cast(\n (x->'value') #>> '{}',\n (x->>'typeoid')::regtype\n ),\n (pks ->> 'name') is not null,\n true\n )::realtime.wal_column\n )\n from\n jsonb_array_elements(wal -> 'identity') x\n left join jsonb_array_elements(wal -> 'pk') pks\n on (x ->> 'name') = (pks ->> 'name');\n\n for working_role in select * from unnest(roles) loop\n\n -- Update `is_selectable` for columns and old_columns\n columns =\n array_agg(\n (\n c.name,\n c.type_name,\n c.type_oid,\n c.value,\n c.is_pkey,\n pg_catalog.has_column_privilege(working_role, entity_, c.name, 'SELECT')\n )::realtime.wal_column\n )\n from\n unnest(columns) c;\n\n old_columns =\n array_agg(\n (\n c.name,\n " <> ... | |
realtime-realtime-1 | 2022-07-11 11:56:07.844 [info] == Migrated 20220603231003 in 0.0s | |
realtime-realtime-1 | 2022-07-11 11:56:07.847 [info] == Running 20220603232444 Realtime.RLS.Repo.Migrations.AddOutputForDataLessThanEqual64BytesWhenPayloadTooLarge.change/0 forward | |
realtime-realtime-1 | 2022-07-11 11:56:07.847 [info] execute "\n create or replace function realtime.apply_rls(wal jsonb, max_record_bytes int = 1024 * 1024)\n returns setof realtime.wal_rls\n language plpgsql\n volatile\n as $$\n declare\n -- Regclass of the table e.g. public.notes\n entity_ regclass = (quote_ident(wal ->> 'schema') || '.' || quote_ident(wal ->> 'table'))::regclass;\n -- I, U, D, T: insert, update ...\n action realtime.action = (\n case wal ->> 'action'\n when 'I' then 'INSERT'\n when 'U' then 'UPDATE'\n when 'D' then 'DELETE'\n else 'ERROR'\n end\n );\n -- Is row level security enabled for the table\n is_rls_enabled bool = relrowsecurity from pg_class where oid = entity_;\n subscriptions realtime.subscription[] = array_agg(subs)\n from\n realtime.subscription subs\n where\n subs.entity = entity_;\n -- Subscription vars\n roles regrole[] = array_agg(distinct us.claims_role)\n from\n unnest(subscriptions) us;\n working_role regrole;\n claimed_role regrole;\n claims jsonb;\n subscription_id uuid;\n subscription_has_access bool;\n visible_to_subscription_ids uuid[] = '{}';\n -- structured info for wal's columns\n columns realtime.wal_column[];\n -- previous identity values for update/delete\n old_columns realtime.wal_column[];\n\n error_record_exceeds_max_size boolean = octet_length(wal::text) > max_record_bytes;\n\n -- Primary jsonb output for record\n output jsonb;\n\n begin\n perform set_config('role', null, true);\n\n columns =\n array_agg(\n (\n x->>'name',\n x->>'type',\n x->>'typeoid',\n realtime.cast(\n (x->'value') #>> '{}',\n (x->>'typeoid')::regtype\n ),\n (pks ->> 'name') is not null,\n true\n )::realtime.wal_column\n )\n from\n jsonb_array_elements(wal -> 'columns') x\n left join jsonb_array_elements(wal -> 'pk') pks\n on (x ->> 'name') = (pks ->> 'name');\n\n old_columns =\n array_agg(\n (\n x->>'name',\n x->>'type',\n x->>'typeoid',\n realtime.cast(\n (x->'value') #>> '{}',\n (x->>'typeoid')::regtype\n ),\n (pks ->> 'name') is not null,\n true\n )::realtime.wal_column\n )\n from\n jsonb_array_elements(wal -> 'identity') x\n left join jsonb_array_elements(wal -> 'pk') pks\n on (x ->> 'name') = (pks ->> 'name');\n\n for working_role in select * from unnest(roles) loop\n\n -- Update `is_selectable` for columns and old_columns\n columns =\n array_agg(\n (\n c.name,\n c.type_name,\n c.type_oid,\n c.value,\n c.is_pkey,\n pg_catalog.has_column_privilege(working_role, entity_, c.name, 'SELECT')\n )::realtime.wal_column\n )\n from\n unnest(columns) c;\n\n old_columns =\n array_agg(\n (\n c.name,\n c.type_name,\n c.type_oid,\n c.value,\n c.is_pkey,\n pg_ca" <> ... | |
realtime-realtime-1 | 2022-07-11 11:56:07.853 [info] == Migrated 20220603232444 in 0.0s | |
realtime-realtime-1 | 2022-07-11 11:56:07.855 [info] == Running 20220615214548 Realtime.RLS.Repo.Migrations.AddQuotedRegtypesBackwardCompatibilitySupport.change/0 forward | |
realtime-realtime-1 | 2022-07-11 11:56:07.855 [info] execute "\n create or replace function realtime.is_visible_through_filters(columns realtime.wal_column[], filters realtime.user_defined_filter[])\n returns bool\n language sql\n immutable\n as $$\n /*\n Should the record be visible (true) or filtered out (false) after *filters* are applied\n */\n select\n -- Default to allowed when no filters present\n coalesce(\n sum(\n realtime.check_equality_op(\n op:=f.op,\n type_:=coalesce(\n col.type_oid::regtype, -- null when wal2json version <= 2.4\n col.type_name::regtype\n ),\n -- cast jsonb to text\n val_1:=col.value #>> '{}',\n val_2:=f.value\n )::int\n ) = count(1),\n true\n )\n from\n unnest(filters) f\n join unnest(columns) col\n on f.column_name = col.name;\n $$;\n " | |
realtime-realtime-1 | 2022-07-11 11:56:07.858 [info] execute "\n create or replace function realtime.apply_rls(wal jsonb, max_record_bytes int = 1024 * 1024)\n returns setof realtime.wal_rls\n language plpgsql\n volatile\n as $$\n declare\n -- Regclass of the table e.g. public.notes\n entity_ regclass = (quote_ident(wal ->> 'schema') || '.' || quote_ident(wal ->> 'table'))::regclass;\n\n -- I, U, D, T: insert, update ...\n action realtime.action = (\n case wal ->> 'action'\n when 'I' then 'INSERT'\n when 'U' then 'UPDATE'\n when 'D' then 'DELETE'\n else 'ERROR'\n end\n );\n\n -- Is row level security enabled for the table\n is_rls_enabled bool = relrowsecurity from pg_class where oid = entity_;\n\n subscriptions realtime.subscription[] = array_agg(subs)\n from\n realtime.subscription subs\n where\n subs.entity = entity_;\n\n -- Subscription vars\n roles regrole[] = array_agg(distinct us.claims_role)\n from\n unnest(subscriptions) us;\n\n working_role regrole;\n claimed_role regrole;\n claims jsonb;\n\n subscription_id uuid;\n subscription_has_access bool;\n visible_to_subscription_ids uuid[] = '{}';\n\n -- structured info for wal's columns\n columns realtime.wal_column[];\n -- previous identity values for update/delete\n old_columns realtime.wal_column[];\n\n error_record_exceeds_max_size boolean = octet_length(wal::text) > max_record_bytes;\n\n -- Primary jsonb output for record\n output jsonb;\n\n begin\n perform set_config('role', null, true);\n\n columns =\n array_agg(\n (\n x->>'name',\n x->>'type',\n x->>'typeoid',\n realtime.cast(\n (x->'value') #>> '{}',\n coalesce(\n (x->>'typeoid')::regtype, -- null when wal2json version <= 2.4\n (x->>'type')::regtype\n )\n ),\n (pks ->> 'name') is not null,\n true\n )::realtime.wal_column\n )\n from\n jsonb_array_elements(wal -> 'columns') x\n left join jsonb_array_elements(wal -> 'pk') pks\n on (x ->> 'name') = (pks ->> 'name');\n\n old_columns =\n array_agg(\n (\n x->>'name',\n x->>'type',\n x->>'typeoid',\n realtime.cast(\n (x->'value') #>> '{}',\n coalesce(\n (x->>'typeoid')::regtype, -- null when wal2json version <= 2.4\n (x->>'type')::regtype\n )\n ),\n (pks ->> 'name') is not null,\n true\n )::realtime.wal_column\n )\n from\n jsonb_array_elements(wal -> 'identity') x\n left join jsonb_array_elements(wal -> 'pk') pks\n on (x ->> 'name') = (pks ->> 'name');\n\n for working_role in select * from unnest(roles) loop\n\n -- Update `is_selectable` for columns and old_columns\n columns =\n array_agg(\n (\n c.name,\n c.type_name,\n c.type_oid,\n c.value,\n c.is_pkey,\n pg_catalog.has_column_privilege(working_role, entity_, c.name, 'SELECT')\n )::realtime.wal_column\n )\n from\n unnest(columns) c;\n\n " <> ... | |
realtime-realtime-1 | 2022-07-11 11:56:07.863 [info] == Migrated 20220615214548 in 0.0s | |
realtime-realtime-1 | 2022-07-11 11:56:11.275 [info] Running RealtimeWeb.Endpoint with cowboy 2.8.0 at :::4000 (http) | |
realtime-realtime-1 | 2022-07-11 11:56:11.275 [info] Access RealtimeWeb.Endpoint at http://localhost:4000 | |
realtime-realtime-1 | 2022-07-11 11:56:11.354 [info] CONNECTED TO RealtimeWeb.UserSocket in 113µs | |
realtime-realtime-1 | Transport: :websocket | |
realtime-realtime-1 | Serializer: Phoenix.Socket.V1.JSONSerializer | |
realtime-realtime-1 | Parameters: %{"apikey" => "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlIjoiYXV0aGVudGljYXRlZCJ9.jNLynx_4nCpPv1fNkNFOzPQ-Y_vPxJAlDV8sp-590ZM", "vsn" => "1.0.0"} | |
realtime-realtime-1 | 2022-07-11 11:56:11.553 [info] JOINED realtime:* in 190ms | |
realtime-realtime-1 | Parameters: %{} | |
realtime-realtime-1 | 2022-07-11 11:56:11.686 [info] JOINED realtime:public in 131ms | |
realtime-realtime-1 | Parameters: %{} | |
realtime-realtime-1 | 2022-07-11 11:56:11.695 [info] JOINED realtime:public:users in 9ms | |
realtime-realtime-1 | Parameters: %{} | |
realtime-realtime-1 | 2022-07-11 11:56:15.476 [info] tzdata release in place is from a file last modified Wed, 21 Oct 2020 18:40:20 GMT. Release file on server was last modified Wed, 16 Mar 2022 13:36:02 GMT. | |
realtime-realtime-1 | 2022-07-11 11:56:17.533 [info] Tzdata has updated the release from 2020d to 2022a | |
realtime-realtime-1 | 2022-07-11 12:00:17.448 [error] %Postgrex.Error{connection_id: 184, message: nil, postgres: %{code: :undefined_function, file: "parse_func.c", hint: "No function matches the given name and argument types. You might need to add explicit type casts.", internal_position: "1", internal_query: "realtime.build_prepared_statement_sql('walrus_rls_stmt', entity_, columns)", line: "629", message: "function realtime.build_prepared_statement_sql(unknown, regclass, realtime.wal_column[]) does not exist", pg_code: "42883", routine: "ParseFuncOrColumn", severity: "ERROR", unknown: "ERROR", where: "PL/pgSQL function realtime.apply_rls(jsonb,integer) line 228 at EXECUTE"}, query: nil} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment