Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Table subjects: unique constraint #220

Merged
merged 3 commits into from
Jan 16, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,19 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)

## Unreleased

### Added

- SQL status code in error message
- All transactional errors cause setting of `ProblemHint.RETRY_RECOMMENDED`

### Fixed

- Check constraint on table `subjects` obeys empty `identifiers`:
If there are no identifiers then type and label must be unique
among those entries without identifiers. Therefore entries are allowed
that have the same type and label but one is with and one w/o
identifiers.

## [9.4.1](https://github.com/dbmdz/metadata-service/releases/tag/9.4.1) - 2025-01-09

### Fixed
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
CREATE OR REPLACE FUNCTION public.subjects_is_unique_type_identifier(puuid uuid, ptype character varying, ids dbidentifier[], plabel jsonb)
RETURNS boolean
STABLE LANGUAGE plpgsql
AS $function$
/**
* Ensures uniqueness of `type` and single identifier across table `subjects`.
*
* If there are not any identifiers then `type` and `label` must be unique.
* It is intended for check constraints and
* returns `false` on violation.
*/
declare
db_ident record; --dbidentifier actually but makes trouble in backups
tuple_exists boolean;
begin
if ids is null or cardinality(ids) = 0 then
execute 'select exists(select 1 from public.subjects where $1 = type and $2 = label and coalesce(identifiers, array[]::dbidentifier[]) = array[]::dbidentifier[] and $3 <> uuid)'
into tuple_exists
using ptype, plabel, puuid;
if tuple_exists then
return false;
end if;
else
foreach db_ident in array ids loop
execute 'select exists(select 1 from public.subjects where $1 = type and $2 = any (identifiers) and $3 <> uuid)'
into tuple_exists
using ptype, db_ident, puuid;
if tuple_exists then
return false;
end if;
end loop;
end if;
return true;
end;
$function$;

Loading