context_in_check_constraints.patch

text/plain

Filename: context_in_check_constraints.patch
Type: text/plain
Part: 0
Message: [patch] Include detailed information about a row failing a CHECK constraint into the error message

Patch

Same data as JSON: GET /api/v1/attachments/:id/patch the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes. API reference →
Format: unified
File+
src/backend/executor/execMain.c 23 1
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)));
+		}
 	}
 }