Last active
March 22, 2018 21:03
-
-
Save loveencounterflow/ce623d2905535c9e2dcbc0111e35aa9e to your computer and use it in GitHub Desktop.
Three Examples where PostgreSQL has Horrible Error Messages
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
drop schema if exists X cascade; | |
create schema X; | |
create domain X.an_illegal_regex as text check ( value ~ '(' ); | |
create table X.table_with_illegal_constraint ( | |
a text, | |
constraint "column a must have a bogus value" check ( a::X.an_illegal_regex = a ) ); | |
select * from X.table_with_illegal_constraint; | |
insert into X.table_with_illegal_constraint values | |
( 'xxx' ), | |
-- ( 'xxx' ), | |
( 'foo' ), | |
( 'xyx' ); | |
⛔⛔⛔⛔⛔⛔⛔⛔⛔⛔⛔⛔⛔⛔⛔⛔⛔⛔⛔⛔⛔⛔⛔⛔⛔⛔⛔⛔⛔⛔⛔⛔⛔⛔⛔⛔⛔⛔⛔ | |
╔═══╗ | |
║ a ║ | |
╠═══╣ | |
╚═══╝ | |
psql:db/experiments/pg-error-fail-illegal-regex.sql:17: ERROR: | |
invalid regular expression: parentheses () not balanced | |
⛔⛔⛔⛔⛔⛔⛔⛔⛔⛔⛔⛔⛔⛔⛔⛔⛔⛔⛔⛔⛔⛔⛔⛔⛔⛔⛔⛔⛔⛔⛔⛔⛔⛔⛔⛔⛔⛔⛔ | |
FAILURE: the error is really in line 5 where a syntactically invalid | |
RegEx is created; the fact that it is a RegEx and not a general | |
string is obvious from the semantics of the `~` (tilde) operator at | |
that point in time. | |
FAILURE: the offending RegEx is not referred to and not quoted in the error | |
message. As such, it could be anywhere in my many, many kLOCs big | |
DB definition. I cannot even search the RegEx with a RegEx because all | |
I know is some parenthesis is missing, somewhere: RegExes cannot match | |
parentheses, and PG RegExes do not have a unique syntactic marker to them. | |
FAILURE: before the `insert` statement, everything runs dandy. We could have | |
built an entire data warehouse application on top of a table definition | |
that can never be syntactically processed but which will only fail when | |
someone accidentally tries to insert a line. | |
FAILURE: I can select from a table with a syntactically invalid definition. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
drop schema if exists X cascade; | |
create schema X; | |
create domain X.a_legal_regex as text check ( value ~ '^x' ); | |
create table X.table_with_constraints ( | |
a text, | |
constraint "column a must start with x" check ( a::X.a_legal_regex = a ), | |
constraint "field b must have 3 characters" check ( character_length( a ) = 3 ) ); | |
insert into X.table_with_constraints values | |
( 'xxx' ), | |
( 'foo' ), /* A: violates first constraint */ | |
-- ( 'xxxx' ), /* B: violates second constraint */ | |
( 'xyx' ); | |
\quit | |
——————————————————————————————————————————————————————————————————————————————— | |
With only line B active: | |
✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱ | |
psql:db/experiments/pg-error-fail-no-constraint-name.sql:16: | |
ERROR: new row for relation "table_with_constraints" violates | |
check constraint "field b must have 3 characters" | |
DETAIL: Failing row contains (xxxx). | |
✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱ | |
SUCCESS: we get the name of the relation *and* the name of the violated | |
rule. | |
SUCCESS: the offending piece of data is quoted. | |
FAILURE: we don't get the full name of the relation, which is | |
"X"."table_with_constraints". Ideally, we'd also be told that | |
the relation in question is a table (not a materialized view). | |
Frankly, when you say 'relation', that should be 'tuple', not 'row'; | |
but when you say 'row', you might as well say 'table'. | |
——————————————————————————————————————————————————————————————————————————————— | |
With only line A active: | |
⛔⛔⛔⛔⛔⛔⛔⛔⛔⛔⛔⛔⛔⛔⛔⛔⛔⛔⛔⛔⛔⛔⛔⛔⛔⛔⛔⛔⛔⛔⛔⛔⛔⛔⛔⛔⛔⛔⛔ | |
psql:db/experiments/pg-error-fail-no-constraint-name.sql:16: | |
ERROR: value for domain x.a_legal_regex violates check constraint "a_legal_regex_check" | |
⛔⛔⛔⛔⛔⛔⛔⛔⛔⛔⛔⛔⛔⛔⛔⛔⛔⛔⛔⛔⛔⛔⛔⛔⛔⛔⛔⛔⛔⛔⛔⛔⛔⛔⛔⛔⛔⛔⛔ | |
FAILURE: no reference to the affected table is made. | |
FAILURE: no reference to the offending piece of data is made. | |
FAILURE: ne reference to the offended constraint is made ("column a must start with x"). | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
drop schema if exists X cascade; | |
create schema X; | |
create domain X.only_a as text check ( value ~ '^a+$' ); | |
create domain X.only_b as text check ( value ~ '^b+$' ); | |
create function X.count_a( X.only_a ) returns integer language sql as $$ | |
select character_length( $1 ); $$; | |
create function X.foo( X.only_b ) returns integer language sql as $$ | |
select X.count_a( $1 ); $$; | |
-- select X.count_a( 'aaaa'::X.only_a ); | |
select X.count_a( 'bbbb'::X.only_b ); /* A */ | |
-- select X.foo( 'bbbb'::X.only_b ); /* B */ | |
\quit | |
——————————————————————————————————————————————————————————————————————————————— | |
With only line A active: | |
✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱ | |
psql:db/experiments/pg-error-fail-wrong-domain.sql:15: ERROR: | |
value for domain x.only_a violates check constraint "only_a_check" | |
✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱ | |
OK so far except the overall information given is too sparse to be truly useful. | |
——————————————————————————————————————————————————————————————————————————————— | |
With only line B active: | |
✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱ | |
psql:db/experiments/pg-error-fail-wrong-domain.sql:16: ERROR: | |
value for domain x.only_a violates check constraint "only_a_check" | |
✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱✱ | |
Misleading in more than one way. `X.count_a()` was called by `X.foo()` because | |
it happened to be the closest match for a function called `X.count_a` with a | |
textual argument. Because no context is given at all, the user is left alone to | |
puzzle over how in the world `X.foo( 'bbbb'::X.only_b )` violates an `only_a` | |
constraint check. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment