I am managing a legacy web-app which process data using Firebird 2.5-based DB (runs on Ubuntu 18.04 server). All was OK for years, but I got something very strange recently.
There is a table with combined keys:
/******************************************************************************/
/* Tables */
/******************************************************************************/
CREATE TABLE STAT_VALIDATION (
DATAREPORTID D$BIGINT NOT NULL /* D$BIGINT = BIGINT */,
PARAMGROUPID D$INTEGER NOT NULL /* D$INTEGER = INTEGER */,
KINDID D$BIGINT NOT NULL /* D$BIGINT = BIGINT */,
VALIDATIONID D$BIGINT NOT NULL /* D$BIGINT = BIGINT */,
ARG1 U$VARCHAR500 NOT NULL /* U$VARCHAR500 = VARCHAR(500) */,
ARG2 U$VARCHAR500 /* U$VARCHAR500 = VARCHAR(500) */,
NOTE U$TEXTBLOB NOT NULL /* U$TEXTBLOB = BLOB SUB_TYPE 1 SEGMENT SIZE 80 */
);
/******************************************************************************/
/* Primary keys */
/******************************************************************************/
ALTER TABLE STAT_VALIDATION ADD CONSTRAINT PK_STAT_VALIDATION PRIMARY KEY (DATAREPORTID, PARAMGROUPID, KINDID, VALIDATIONID);
/******************************************************************************/
/* Foreign keys */
/******************************************************************************/
ALTER TABLE STAT_VALIDATION ADD CONSTRAINT FK_STAT_VALIDATION_DATAREPORTID FOREIGN KEY (DATAREPORTID, PARAMGROUPID, KINDID) REFERENCES STAT_DATA (DATAREPORTID, PARAMGROUPID, KINDID) ON DELETE CASCADE ON UPDATE CASCADE;
ALTER TABLE STAT_VALIDATION ADD CONSTRAINT FK_STAT_VALIDATION_VALIDATIONID FOREIGN KEY (VALIDATIONID) REFERENCES CONTENTTREE (NODEID) ON UPDATE CASCADE;
It also has a "before insert" trigger
/* Trigger: STAT_VALIDATION_BI0 */
CREATE OR ALTER TRIGGER STAT_VALIDATION_BI0 FOR STAT_VALIDATION
ACTIVE BEFORE INSERT POSITION 0
as
declare variable PARAMS D$VARCHAR500;
begin
if (exists (
select *
from STAT_VALIDATION SV
where SV.DATAREPORTID = new.DATAREPORTID
and SV.PARAMGROUPID = new.PARAMGROUPID
and SV.KINDID = new.KINDID
and SV.VALIDATIONID = new.VALIDATIONID
)) then
begin
select list(VSPG.PARAMNAME || '=' || VSPG.PARAMVALUE, ';')
from V_STAT_PARAMGROUPS VSPG
where VSPG.PARAMGROUPID = new.PARAMGROUPID
into :PARAMS;
exception E_CUSTOM_EXCEPTION 'Validation already exists: '
|| 'DATAREPORTID=' || new.DATAREPORTID
|| '; PARAMGROUPID=' || new.PARAMGROUPID
|| '; KINDID=' || new.KINDID
|| '; VALIDATIONID=' || new.VALIDATIONID
|| '; PARAMS: ' || :PARAMS;
end
end
Data in the table looks like this
Table data sample, so values in each of DATAREPORTID, PARAMGROUPID, KINDID, VALIDATIONID repeats - and only their combination must be unique.
The problem
A NEW record going to be inserted with the following values
DATAREPORTID=214746; PARAMGROUPID=45542; KINDID=48062; VALIDATIONID=99517
(ARGs also exist but those content are insignificant there)
And I got the following error message
Firebird statement execute error : exception 1 E_CUSTOM_EXCEPTION Validation already exists: DATAREPORTID=214746; PARAMGROUPID=45542; KINDID=48062; VALIDATIONID=99517; PARAMS: STAT_PARAM_SPECIALITYID=454;STAT_PARAM_EDUFORMID=444;STAT_P ARAM_EDUBASISID=449;STAT_PARAM_COUNTRYID=545;STAT_PARAM_COURSE=740 At trigger 'STAT_VALIDATION_BI0' line: 19, col: 5
An attempt of investigation
For investigation, I have executed a select part of the query from trigger manually (using IB Expert remotely):
select *
from STAT_VALIDATION SV
where SV.DATAREPORTID = 214746
and SV.PARAMGROUPID = 45542
and SV.KINDID = 48062
and SV.VALIDATIONID = 99517
As I expect, no records found:

Same way I have checked for only DATAREPORTID value:
select *
from STAT_VALIDATION SV
where SV.DATAREPORTID = 214746
Also - no records found (which is correct)
Some additional info: When I remove condition and run test query again:
select *
from STAT_VALIDATION SV
where SV.PARAMGROUPID = 45542
and SV.KINDID = 48062
and SV.VALIDATIONID = 99517
- I am receiving existing record:

- which is expected by logic of this app. But in this record value of DATAREPORTID is different.
Almost in desperation I have deactivated trigger and tried to insert mentioned record again This time I got the following error
Firebird statement execute error : violation of PRIMARY or UNIQUE KEY constraint "PK_STAT_VALIDATION" on table "STAT_VALIDATION" Problematic key value is ("DATAREPORTID" = 214746, "PARAMGROUPID" = 45542, "KINDID" = 48062, "VALIDATIONID" = 99517)
Could somebody at least explain for: Why trigger has been fired? Why PK violation has happens? We have a composite PK based on 4 fields DATAREPORTID, PARAMGROUPID, KINDID, VALIDATIONID Within given new record:
- value of DATAREPORTID not available in this DB table,
- values of PARAMGROUPID, KINDID, VALIDATIONID - have been repeated in this DB table. As for me final combination must be unique and PK requiremets have to be fulfilled. But trigger has been fired / PC violation ossurs. How it is possible? Or do I miss (do not know) something important?
As I noted in post - I have tried to execute sub-query manually and got expected responses. But of the trigger and PK constraints is incorrect.