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)));
+               }
        }
 }
 

Attachment: signature.asc
Description: OpenPGP digital signature

Reply via email to