Thread: Check constraint failure messages
ERROR: value for domain po.email violates check constraint "email_check" SQL state: 23514
I've got a domain that validates email addresses. When inserting a bunch of entries I simply get the error messageERROR: value for domain po.email violates check constraint "email_check" SQL state: 23514When inserting 1000+ entries in a batch, finding the exact entry with the problem is noticeably harder than with other error types. For example when a column should be a uuid but you pass in 'Mary had a little lamb', the error message tells you what the invalid value is as well as the column name you're trying to put it into.Are there any quick hacks floating around out there to solve or at least mitigate this?
Is it a deferred constraint?
Angular momentum makes the world go 'round.
On 4/6/21 2:40 PM, Miles Elam wrote:I've got a domain that validates email addresses. When inserting a bunch of entries I simply get the error messageERROR: value for domain po.email violates check constraint "email_check" SQL state: 23514When inserting 1000+ entries in a batch, finding the exact entry with the problem is noticeably harder than with other error types. For example when a column should be a uuid but you pass in 'Mary had a little lamb', the error message tells you what the invalid value is as well as the column name you're trying to put it into.Are there any quick hacks floating around out there to solve or at least mitigate this?
Is it a deferred constraint?
CREATE DOMAIN po.email AS varcharCHECK (VALUE IS NULL OR (po.length_in(VALUE, 1, 254) AND NOT po.email_expanded(VALUE) IS NULL));
CREATE TABLE IF NOT EXISTS profile (id uuid PRIMARY KEY,email po.email NOT NULL,
manager_email po.email NOT NULL
);
INSERT INTO profile (id, email, manager_email) VALUES(gen_random_uuid(), 'user1@example.com', 'manager1@example.com'),(gen_random_uuid(), 'user2@example.com', 'manager2@example.com'),
On Tue, Apr 6, 2021 at 1:03 PM Ron <ronljohnsonjr@gmail.com> wrote:On 4/6/21 2:40 PM, Miles Elam wrote:I've got a domain that validates email addresses. When inserting a bunch of entries I simply get the error messageERROR: value for domain po.email violates check constraint "email_check" SQL state: 23514When inserting 1000+ entries in a batch, finding the exact entry with the problem is noticeably harder than with other error types. For example when a column should be a uuid but you pass in 'Mary had a little lamb', the error message tells you what the invalid value is as well as the column name you're trying to put it into.Are there any quick hacks floating around out there to solve or at least mitigate this?
Is it a deferred constraint?Plain ole domain CHECK constraint.CREATE DOMAIN po.email AS varcharCHECK (VALUE IS NULL OR (po.length_in(VALUE, 1, 254) AND NOT po.email_expanded(VALUE) IS NULL));where "po" is another schema, po.length_in(...) is an IMMUTABLE range check, and po.email_expanded(...) is a function returning a record. Same behavior happens if I remove the functions and define the check constraint in place. The only info returned in a bulk insert is the name of the violated check constraint, aka email_check.
The blunt force answer is to not use bulk inserts. Try COPY; it's good at saying which record throws an error.
Angular momentum makes the world go 'round.
The blunt force answer is to not use bulk inserts. Try COPY; it's good at saying which record throws an error.
From: Miles Elam <miles.elam@productops.com>
Sent: Tuesday, April 6, 2021 4:19 PM
Sadly, this is a cloud-managed database without direct access to 5432 from outside the VPC and bastian instances are frowned upon by our security folks. Guess I'm stuck with bisecting. Thanks for the confirmation.
====================
It'd slow you down a little, but you could install a before trigger to do the check and if it fails you'll have all the info you need and can call RAISE to communicate a record identifier, bad value, whatever.
If performance is really a big deal, set up the trigger only after you get a failure so you only have to run it on the 'bad batches'.
Or else write a precheck program that looks at the data first and looks only for this and therefore can report the exact record before it feeds the good data to your real loader.
Or there's probably other ways I'm not thinking of. The question is what options does your process allow, I suppose.
HTH,
Kevin
.
CREATE OR REPLACE FUNCTION po.confirm(p_val anyelement, p_validated boolean)
RETURNS boolean LANGUAGE plpgsql STRICT IMMUTABLE PARALLEL SAFE AS $$
BEGIN
IF NOT p_validated THEN
RAISE WARNING 'Invalid value: %', p_val;
END IF;
RETURN p_validated;
END;
$$;
COMMENT ON FUNCTION po.confirm(anyelement,boolean) IS
'Raises a warning when a condition is false; useful for outputting CHECK constraint error values.';CREATE DOMAIN po.email AS varcharCHECK (po.confirm(VALUE, VALUE IS NULL OR NOT po.email_expanded(VALUE) IS NULL));
On Tue, Apr 6, 2021 at 1:59 PM Ron <ronljohnsonjr@gmail.com> wrote:
The blunt force answer is to not use bulk inserts. Try COPY; it's good at saying which record throws an error.Sadly, this is a cloud-managed database without direct access to 5432 from outside the VPC and bastian instances are frowned upon by our security folks. Guess I'm stuck with bisecting. Thanks for the confirmation.
On 4/6/21 3:50 PM, Miles Elam wrote:On Tue, Apr 6, 2021 at 1:03 PM Ron <ronljohnsonjr@gmail.com> wrote:On 4/6/21 2:40 PM, Miles Elam wrote:I've got a domain that validates email addresses. When inserting a bunch of entries I simply get the error messageERROR: value for domain po.email violates check constraint "email_check" SQL state: 23514When inserting 1000+ entries in a batch, finding the exact entry with the problem is noticeably harder than with other error types. For example when a column should be a uuid but you pass in 'Mary had a little lamb', the error message tells you what the invalid value is as well as the column name you're trying to put it into.Are there any quick hacks floating around out there to solve or at least mitigate this?
Is it a deferred constraint?Plain ole domain CHECK constraint.CREATE DOMAIN po.email AS varcharCHECK (VALUE IS NULL OR (po.length_in(VALUE, 1, 254) AND NOT po.email_expanded(VALUE) IS NULL));where "po" is another schema, po.length_in(...) is an IMMUTABLE range check, and po.email_expanded(...) is a function returning a record. Same behavior happens if I remove the functions and define the check constraint in place. The only info returned in a bulk insert is the name of the violated check constraint, aka email_check.
The blunt force answer is to not use bulk inserts. Try COPY; it's good at saying which record throws an error.--
Angular momentum makes the world go 'round.
An error message that includes the table name and column name would also be helpful for non-bulk inserts: