Skip to content

Commit

Permalink
Merge pull request #220 from dbmdz/subjects_unique_constraint
Browse files Browse the repository at this point in the history
Table subjects: unique constraint
  • Loading branch information
daforster authored Jan 16, 2025
2 parents 996c17d + 86f4477 commit afc102b
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 0 deletions.
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$;

0 comments on commit afc102b

Please sign in to comment.