On 11/10/11 16:05, Tom Lane wrote: > I agree with Jan that this is probably useful; I'm pretty sure there > have been requests for it before. We just have to make sure that the > length of the message stays in bounds. > > One tip for keeping the length down: there is no value in repeating > information from the primary error message, such as the name of the > constraint.
Thanks to your comments and suggestions, I appreciate the time of the reviewers. Attached is a second version of this patch which keeps the size of the output at 64 characters per column (which is an arbitrary value defined as a const int, which I hope matches your style). Longer values have their last three characters replaced by "...", so there's no way to distinguish them from a legitimate string that ends with just that. There's also no escaping of special-string values, similar to how the BuildIndexValueDescription operates. Cheers, Jan -- Trojita, a fast e-mail client -- http://trojita.flaska.net/
diff --git a/src/backend/executor/execMain.c b/src/backend/executor/execMain.c
index 504f4de..9c2b285 100644
--- a/src/backend/executor/execMain.c
+++ b/src/backend/executor/execMain.c
@@ -1364,10 +1364,42 @@ ExecConstraints(ResultRelInfo *resultRelInfo,
const char *failed;
if ((failed = ExecRelCheck(resultRelInfo, slot, estate)) !=
NULL)
+ {
+ StringInfoData buf;
+ int natts = rel->rd_att->natts;
+ int i;
+ initStringInfo(&buf);
+ for (i = 0; i < natts; ++i)
+ {
+ char *val;
+ Oid foutoid;
+ bool typisvarlena;
+ size_t fieldlen;
+ const int cutofflen = 64;
+
getTypeOutputInfo(rel->rd_att->attrs[i]->atttypid, &foutoid, &typisvarlena);
+ if (slot->tts_isnull[i])
+ val = "NULL";
+ else
+ val = OidOutputFunctionCall(foutoid,
slot->tts_values[i]);
+ if (i > 0)
+ appendStringInfoString(&buf, ", ");
+ fieldlen = strlen(val);
+ if (fieldlen > cutofflen)
+ {
+ appendBinaryStringInfo(&buf, val,
cutofflen - 3);
+ appendStringInfoString(&buf, "...");
+ }
+ else
+ {
+ appendStringInfoString(&buf, val);
+ }
+ }
ereport(ERROR,
(errcode(ERRCODE_CHECK_VIOLATION),
errmsg("new row for relation \"%s\"
violates check constraint \"%s\"",
-
RelationGetRelationName(rel), failed)));
+
RelationGetRelationName(rel), failed),
+ errdetail("Failing row: (%s).",
buf.data)));
+ }
}
}
signature.asc
Description: OpenPGP digital signature
