Provide a more informative error message when a uniqueness constraint
fails.  Ticket #419. (CVS 1068)

FossilOrigin-Name: 086aa1c9922b7bf399b3ee8b73ba7353d126b119
diff --git a/src/insert.c b/src/insert.c
index 7c2b611..b61572c 100644
--- a/src/insert.c
+++ b/src/insert.c
@@ -12,7 +12,7 @@
 ** This file contains C code routines that are called by the parser
 ** to handle INSERT statements in SQLite.
 **
-** $Id: insert.c,v 1.88 2003/06/04 16:24:39 drh Exp $
+** $Id: insert.c,v 1.89 2003/08/05 13:13:38 drh Exp $
 */
 #include "sqliteInt.h"
 
@@ -817,8 +817,30 @@
       case OE_Rollback:
       case OE_Abort:
       case OE_Fail: {
+        int j, n1, n2;
+        char zErrMsg[200];
+        strcpy(zErrMsg, pIdx->nColumn>1 ? "columns " : "column ");
+        n1 = strlen(zErrMsg);
+        for(j=0; j<pIdx->nColumn && n1<sizeof(zErrMsg)-30; j++){
+          char *zCol = pTab->aCol[pIdx->aiColumn[j]].zName;
+          n2 = strlen(zCol);
+          if( j>0 ){
+            strcpy(&zErrMsg[n1], ", ");
+            n1 += 2;
+          }
+          if( n1+n2>sizeof(zErrMsg)-30 ){
+            strcpy(&zErrMsg[n1], "...");
+            n1 += 3;
+            break;
+          }else{
+            strcpy(&zErrMsg[n1], zCol);
+            n1 += n2;
+          }
+        }
+        strcpy(&zErrMsg[n1], 
+            pIdx->nColumn>1 ? " are not unique" : " is not unique");
         sqliteVdbeAddOp(v, OP_Halt, SQLITE_CONSTRAINT, onError);
-        sqliteVdbeChangeP3(v, -1, "uniqueness constraint failed", P3_STATIC);
+        sqliteVdbeChangeP3(v, -1, sqliteStrDup(zErrMsg), P3_DYNAMIC);
         break;
       }
       case OE_Ignore: {