Hi, when I insert/update many rows at once using INSERT ... SELECT into a table which has plenty of CHECK constraints, the error message that Postgres returns has no indication of which row failed the constraint check. The attached patch tries to provide information in a similar way to how duplicate items in a UNIQUE constraint are handled.
Originally, I tried to simply check the new row's t_ctid, but it was always (0,0) -- I guess that's expected, maybe it's still in memory at that time and maybe such nodes don't have a ctid assigned yet. Please let me know if this patch is suitable for inclusion. It's based on REL9_0_STABLE, because that's the version I'm running. I'd like to thank intgr on IRC for his feedback when I was wondering about the t_ctid. With kind regards, 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..eb4f595 100644 --- a/src/backend/executor/execMain.c +++ b/src/backend/executor/execMain.c @@ -1364,10 +1364,32 @@ 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; + 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, ", "); + 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("New row with data (%s) violates check constraint \"%s\".", + buf.data, failed))); + } } }
signature.asc
Description: OpenPGP digital signature