diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2009-08-01 19:59:41 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2009-08-01 19:59:41 +0000 |
commit | b680ae4bdbf1c7fd78e6988bbe8f89e1e1b5db86 (patch) | |
tree | c8a7f8bc0084a15ff3cdbb5b1b4476c69185ca80 /src/backend/access/index/genam.c | |
parent | 2487d872e025312e7c16f0dd772190c6787efeea (diff) |
Improve unique-constraint-violation error messages to include the exact
values being complained of.
In passing, also remove the arbitrary length limitation in the similar
error detail message for foreign key violations.
Itagaki Takahiro
Diffstat (limited to 'src/backend/access/index/genam.c')
-rw-r--r-- | src/backend/access/index/genam.c | 57 |
1 files changed, 56 insertions, 1 deletions
diff --git a/src/backend/access/index/genam.c b/src/backend/access/index/genam.c index a79c3920713..6482aaa6a70 100644 --- a/src/backend/access/index/genam.c +++ b/src/backend/access/index/genam.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/access/index/genam.c,v 1.74 2009/06/11 14:48:54 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/access/index/genam.c,v 1.75 2009/08/01 19:59:41 tgl Exp $ * * NOTES * many of the old access method routines have been turned into @@ -24,6 +24,8 @@ #include "miscadmin.h" #include "pgstat.h" #include "storage/bufmgr.h" +#include "utils/builtins.h" +#include "utils/lsyscache.h" #include "utils/rel.h" #include "utils/tqual.h" @@ -130,6 +132,59 @@ IndexScanEnd(IndexScanDesc scan) pfree(scan); } +/* + * ReportUniqueViolation -- Report a unique-constraint violation. + * + * The index entry represented by values[]/isnull[] violates the unique + * constraint enforced by this index. Throw a suitable error. + */ +void +ReportUniqueViolation(Relation indexRelation, Datum *values, bool *isnull) +{ + /* + * XXX for the moment we use the index's tupdesc as a guide to the + * datatypes of the values. This is okay for btree indexes but is in + * fact the wrong thing in general. This will have to be fixed if we + * are ever to support non-btree unique indexes. + */ + TupleDesc tupdesc = RelationGetDescr(indexRelation); + char *key_names; + StringInfoData key_values; + int i; + + key_names = pg_get_indexdef_columns(RelationGetRelid(indexRelation), true); + + /* Get printable versions of the key values */ + initStringInfo(&key_values); + for (i = 0; i < tupdesc->natts; i++) + { + char *val; + + if (isnull[i]) + val = "null"; + else + { + Oid foutoid; + bool typisvarlena; + + getTypeOutputInfo(tupdesc->attrs[i]->atttypid, + &foutoid, &typisvarlena); + val = OidOutputFunctionCall(foutoid, values[i]); + } + + if (i > 0) + appendStringInfoString(&key_values, ", "); + appendStringInfoString(&key_values, val); + } + + ereport(ERROR, + (errcode(ERRCODE_UNIQUE_VIOLATION), + errmsg("duplicate key value violates unique constraint \"%s\"", + RelationGetRelationName(indexRelation)), + errdetail("Key (%s)=(%s) already exists.", + key_names, key_values.data))); +} + /* ---------------------------------------------------------------- * heap-or-index-scan access to system catalogs |