drop extension if exists pg_liquid cascade; drop table if exists public.film_performances; drop table if exists public.no_primary_key_films; create extension pg_liquid; create table public.film_performances ( id bigint generated always as identity primary key, actor_name text, role_name text, film_title text ); insert into public.film_performances (actor_name, role_name, film_title) values ('Harrison Ford', 'Han Solo', 'Star Wars'), ('Carrie Fisher', 'Leia Organa', 'Star Wars'); do $$ begin perform * from liquid.query($liquid$ DefCompound("FilmPerf", "actor", "0", "liquid/node"). DefCompound("FilmPerf", "role", "0", "liquid/node"). DefCompound("FilmPerf", "film", "0", "liquid/node"). Edge("FilmPerf", "liquid/mutable", "false"). $liquid$) as t(ignored text); exception when invalid_parameter_value then null; end $$; do $$ begin perform liquid.create_row_normalizer( 'public.film_performances'::regclass, 'film_perf', 'FilmPerf', '{"actor":"actor_name","film":"film_title","role":"role_name"}'::jsonb ); end $$; select cid, actor, role, film from liquid.query($$ FilmPerf@(cid=cid, actor=actor, role=role, film=film)? $$) as t(cid text, actor text, role text, film text) order by 1; insert into public.film_performances (actor_name, role_name, film_title) values ('Mark Hamill', 'Luke Skywalker', 'Star Wars'); select count(*) as projected_compound_count_after_insert from liquid.query($$ FilmPerf@(cid=cid, actor=actor, role=role, film=film)? $$) as t(cid text, actor text, role text, film text); insert into public.film_performances (actor_name, role_name, film_title) values ('Mark Hamill', 'Luke Skywalker', 'Star Wars'); select count(*) as duplicate_compound_count from liquid.query($$ FilmPerf@(cid=cid, actor=actor, role=role, film=film)? $$) as t(cid text, actor text, role text, film text) where cid = liquid.compound_identity_literal( 'FilmPerf', '{"actor":"Mark Hamill","film":"Star Wars","role":"Luke Skywalker"}'::jsonb ); select count(*) as duplicate_binding_edge_count from liquid.row_normalizer_bindings where normalizer_id = ( select id from liquid.row_normalizers where normalizer_name = 'film_perf' ) and subject_literal = liquid.compound_identity_literal( 'FilmPerf', '{"actor":"Mark Hamill","film":"Star Wars","role":"Luke Skywalker"}'::jsonb ); update public.film_performances set role_name = 'General Leia' where actor_name = 'Carrie Fisher'; select count(*) as old_carrie_compound_count from liquid.query($$ FilmPerf@(cid=cid, actor="Carrie Fisher", role="Leia Organa", film="Star Wars")? $$) as t(cid text); select count(*) as new_carrie_compound_count from liquid.query($$ FilmPerf@(cid=cid, actor="Carrie Fisher", role="General Leia", film="Star Wars")? $$) as t(cid text); update public.film_performances set role_name = null where actor_name = 'Carrie Fisher'; select count(*) as carrie_compound_count_after_null from liquid.query($$ FilmPerf@(cid=cid, actor="Carrie Fisher", role=role, film="Star Wars")? $$) as t(cid text, role text); delete from public.film_performances where id = ( select min(id) from public.film_performances where actor_name = 'Mark Hamill' ); select count(*) as luke_compound_count_after_first_delete from liquid.query($$ FilmPerf@(cid=cid, actor="Mark Hamill", role="Luke Skywalker", film="Star Wars")? $$) as t(cid text); delete from public.film_performances where actor_name = 'Mark Hamill'; select count(*) as luke_compound_count_after_second_delete from liquid.query($$ FilmPerf@(cid=cid, actor="Mark Hamill", role="Luke Skywalker", film="Star Wars")? $$) as t(cid text); do $$ begin begin perform liquid.create_row_normalizer( 'public.film_performances'::regclass, 'bad_role', 'FilmPerf', '{"actor":"actor_name","film":"film_title","wrong":"role_name"}'::jsonb, false ); raise exception 'expected invalid role mapping failure'; exception when raise_exception then raise notice 'invalid role mapping rejected'; end; begin perform liquid.create_row_normalizer( 'public.film_performances'::regclass, 'bad_column', 'FilmPerf', '{"actor":"actor_name","film":"film_title","role":"missing_column"}'::jsonb, false ); raise exception 'expected invalid column mapping failure'; exception when raise_exception then raise notice 'invalid column mapping rejected'; end; end $$; create table public.no_primary_key_films ( actor_name text, role_name text, film_title text ); do $$ begin begin perform liquid.create_row_normalizer( 'public.no_primary_key_films'::regclass, 'no_pk', 'FilmPerf', '{"actor":"actor_name","film":"film_title","role":"role_name"}'::jsonb, false ); raise exception 'expected missing primary key failure'; exception when raise_exception then raise notice 'missing primary key rejected'; end; end $$; do $$ begin begin perform liquid.create_row_normalizer( 'public.film_performances'::regclass, 'bad_json_type', 'FilmPerf', '[]'::jsonb, false ); raise exception 'expected non-object role_columns failure'; exception when raise_exception then raise notice 'non-object role_columns rejected'; end; begin perform liquid.create_row_normalizer( 'public.film_performances'::regclass, 'film_perf', 'FilmPerf', '{"actor":"actor_name","film":"film_title","role":"role_name"}'::jsonb, false ); raise exception 'expected duplicate normalizer failure'; exception when raise_exception then raise notice 'duplicate normalizer rejected'; end; begin perform liquid.rebuild_row_normalizer( 'public.film_performances'::regclass, 'missing_normalizer' ); raise exception 'expected missing normalizer rebuild failure'; exception when raise_exception then raise notice 'missing normalizer rebuild rejected'; end; begin perform liquid.drop_row_normalizer( 'public.film_performances'::regclass, 'missing_normalizer' ); raise exception 'expected missing normalizer drop failure'; exception when raise_exception then raise notice 'missing normalizer drop rejected'; end; end $$; do $$ declare compound_id bigint; role_id bigint; begin select id into compound_id from liquid.vertices where literal = liquid.compound_identity_literal( 'FilmPerf', '{"actor":"Harrison Ford","film":"Star Wars","role":"Han Solo"}'::jsonb ); select id into role_id from liquid.vertices where literal = 'role'; update liquid.edges set is_deleted = true where subject_id = compound_id and predicate_id = role_id; end $$; select count(*) as harrison_compound_count_after_manual_tombstone from liquid.query($$ FilmPerf@(cid=cid, actor="Harrison Ford", role="Han Solo", film="Star Wars")? $$) as t(cid text); do $$ begin perform liquid.rebuild_row_normalizer( 'public.film_performances'::regclass, 'film_perf' ); end $$; select count(*) as harrison_compound_count_after_rebuild from liquid.query($$ FilmPerf@(cid=cid, actor="Harrison Ford", role="Han Solo", film="Star Wars")? $$) as t(cid text); do $$ begin perform liquid.drop_row_normalizer( 'public.film_performances'::regclass, 'film_perf' ); end $$; select count(*) as remaining_binding_count_after_drop from liquid.row_normalizer_bindings;