]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Add extended error codes for constraint errors.
authordrh <drh@noemail.net>
Sat, 9 Feb 2013 13:58:25 +0000 (13:58 +0000)
committerdrh <drh@noemail.net>
Sat, 9 Feb 2013 13:58:25 +0000 (13:58 +0000)
FossilOrigin-Name: 5461104668a49529577f21df97f6a0e7d8f0c679

12 files changed:
manifest
manifest.uuid
src/build.c
src/expr.c
src/fkey.c
src/insert.c
src/sqlite.h.in
src/sqliteInt.h
src/test1.c
src/test_spellfix.c
src/vdbe.c
src/vdbeaux.c

index 1df599f7dbb8e04ed73ab2197753a835280a5742..8270487d51596ba8523a9828c422b2c37d58a1ae 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Fix\sharmless\scompiler\swarnings.
-D 2013-02-07T09:33:56.594
+C Add\sextended\serror\scodes\sfor\sconstraint\serrors.
+D 2013-02-09T13:58:25.162
 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
 F Makefile.in a48faa9e7dd7d556d84f5456eabe5825dd8a6282
 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -124,21 +124,21 @@ F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7
 F src/btree.c 7a80e4a67f32a2494c383a28a495bf3bd71cc230
 F src/btree.h 3ad7964d6c5b1c7bff569aab6adfa075f8bf06cd
 F src/btreeInt.h 4e5c2bd0f9b36b2a815a6d84f771a61a65830621
-F src/build.c f4f86c07002c6f3ee96c1e34e0e993a962ef2c73
+F src/build.c 73ca65f32938e4e0d94e831b61b5749b211b79be
 F src/callback.c d7e46f40c3cf53c43550b7da7a1d0479910b62cc
 F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac
 F src/ctime.c 72a70dcfda75d3a1f81041ce4573e7afddcd8e4e
 F src/date.c 067a81c9942c497aafd2c260e13add8a7d0c7dd4
 F src/delete.c 9b8d308979114991e5dc7cee958316e07186941d
-F src/expr.c 4dff0b04eaaf133789279c6b8cd69175dfbb1691
+F src/expr.c 44714c8f0e553de54e9648815ef940b20eb6fb4b
 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
-F src/fkey.c 5b7a12e2f8620e855b0478a9a6798df9967bb277
+F src/fkey.c e16942bd5c8a868ac53287886464a5ed0e72b179
 F src/func.c 8147799b048065a1590805be464d05b4913e652c
 F src/global.c e59ecd2c553ad0d4bfbc84ca71231336f8993a7a
 F src/hash.c ac3470bbf1ca4ae4e306a8ecb0fdf1731810ffe4
 F src/hash.h 2894c932d84d9f892d4b4023a75e501f83050970
 F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08
-F src/insert.c dc197aa9293a26d300eb5378880e701f7b20fefa
+F src/insert.c f7cb141e8ce257cb6b15c497f09e4e23d6055599
 F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d
 F src/legacy.c a199d7683d60cef73089e892409113e69c23a99f
 F src/lempar.c cdf0a000315332fc9b50b62f3b5e22e080a0952b
@@ -176,15 +176,15 @@ F src/resolve.c 652ae6dc0f185b01b4536bb2fa7d878f13f0f1df
 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0
 F src/select.c 741c623c70c09b5fbe55d8ae6413d9215c1dedbf
 F src/shell.c 266791241d7add796ccce2317977ae6c3c67d77f
-F src/sqlite.h.in 39cc33bb08897c748fe3383c29ccf56585704177
+F src/sqlite.h.in 7cf6485b8a5cd88139e9d05c2a73368dd79863af
 F src/sqlite3.rc fea433eb0a59f4c9393c8e6d76a6e2596b1fe0c0
 F src/sqlite3ext.h 6904f4aadf976f95241311fbffb00823075d9477
-F src/sqliteInt.h 6267485592261a1420ae9195e388242d9e451bdb
+F src/sqliteInt.h 8e01aa31d5337ca0c0d0000745994f63762ec1bb
 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d
 F src/status.c bedc37ec1a6bb9399944024d63f4c769971955a9
 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e
 F src/tclsqlite.c 3213f3101e3b85f047d6e389da5a53d76d3d7540
-F src/test1.c 834e38420a5c604d4351741c27ebe6d78a1be907
+F src/test1.c ca2a9870a6654dd6d5b8fe5666e64ac31b6647f2
 F src/test2.c 4178056dd1e7d70f954ad8a1e3edb71a2a784daf
 F src/test3.c 3c3c2407fa6ec7a19e24ae23f7cb439d0275a60d
 F src/test4.c bf9fa9bece01de08e6f5e02314e4af5c13590dfa
@@ -222,7 +222,7 @@ F src/test_regexp.c 58e0349f155bc307dfa209df4b03add0a7749866
 F src/test_rtree.c aba603c949766c4193f1068b91c787f57274e0d9
 F src/test_schema.c 8c06ef9ddb240c7a0fcd31bc221a6a2aade58bf0
 F src/test_server.c 2f99eb2837dfa06a4aacf24af24c6affdf66a84f
-F src/test_spellfix.c 4b3fb3ef465736499e5c34ccb51fad6c53ee1e78
+F src/test_spellfix.c 860eb723100d4e3cff846ba5d25e02815b2a5cac
 F src/test_sqllog.c 8acb843ddb9928dea8962e31bb09f421a72ffccb
 F src/test_stat.c d1569c7a4839f13e80187e2c26b2ab4da2d03935
 F src/test_superlock.c 2b97936ca127d13962c3605dbc9a4ef269c424cd
@@ -239,11 +239,11 @@ F src/update.c 28d2d098b43a2c70dae399896ea8a02f622410ef
 F src/utf.c 8d819e2e5104a430fc2005f018db14347c95a38f
 F src/util.c 0af2e515dc0dabacec931bca39525f6c3f1c5455
 F src/vacuum.c 2727bdd08847fcb6b2d2da6d14f018910e8645d3
-F src/vdbe.c f51eb3207594703d24e91335cb16906e894b48aa
+F src/vdbe.c 292f8f7ced59c29c63fe17830cbe5f5a0230cdf0
 F src/vdbe.h b52887278cb173e66188da84dfab216bea61119d
 F src/vdbeInt.h 396bb03eec560f768d1b86092b00f46c25575d3b
 F src/vdbeapi.c 4c2418161cf45392ba76a7ca92f9a5f06b96f89c
-F src/vdbeaux.c 8b5d13a2e0a2430f35881eceec762fab8d24e64d
+F src/vdbeaux.c 735a6905df302a7f3c715a82bd3af06dc7d74ef2
 F src/vdbeblob.c 32f2a4899d67f69634ea4dd93e3f651936d732cb
 F src/vdbemem.c cb55e84b8e2c15704968ee05f0fae25883299b74
 F src/vdbesort.c c61ca318681c0e7267da8be3abfca8469652a7e9
@@ -1034,7 +1034,10 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381
 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381
 F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac
-P e1640876df7ed6fb4e84292e5ce1f78635df64ab
-R ed650c137d06abf5e97862ecc9965eee
+P 4a7b4ee011fea911b981206c242e3d5553303b52
+R 270848b00a612583295cde2d6d289ebe
+T *branch * constraint-error-codes
+T *sym-constraint-error-codes *
+T -sym-trunk *
 U drh
-Z 0e5ff063c96a5d0e787292d2749e52de
+Z e6d281a3555aa6072b0a1a3d4e35cfe5
index 3c0ca4ea396c8d7f9eb3f36c93977342d663f439..697f1ff45473118979bd261da5913f96a1668df6 100644 (file)
@@ -1 +1 @@
-4a7b4ee011fea911b981206c242e3d5553303b52
\ No newline at end of file
+5461104668a49529577f21df97f6a0e7d8f0c679
\ No newline at end of file
index c21f0172a9b1829cf969e4f95489e65faa1a700d..4ce65a43d784e9d4352da65e18d46e8bdb06604d 100644 (file)
@@ -2447,8 +2447,8 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){
     sqlite3VdbeAddOp2(v, OP_Goto, 0, j2);
     addr2 = sqlite3VdbeCurrentAddr(v);
     sqlite3VdbeAddOp3(v, OP_SorterCompare, iSorter, j2, regRecord);
-    sqlite3HaltConstraint(
-        pParse, OE_Abort, "indexed columns are not unique", P4_STATIC
+    sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_UNIQUE,
+        OE_Abort, "indexed columns are not unique", P4_STATIC
     );
   }else{
     addr2 = sqlite3VdbeCurrentAddr(v);
@@ -2474,8 +2474,8 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){
     ** since sqlite3ReleaseTempRange() was called, it is safe to do so.
     */
     sqlite3VdbeAddOp4(v, OP_IsUnique, iIdx, j2, regRowid, pRegKey, P4_INT32);
-    sqlite3HaltConstraint(
-        pParse, OE_Abort, "indexed columns are not unique", P4_STATIC);
+    sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_UNIQUE,
+        "indexed columns are not unique", P4_STATIC);
   }
   sqlite3VdbeAddOp3(v, OP_IdxInsert, iIdx, regRecord, 0);
   sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
@@ -3692,12 +3692,19 @@ void sqlite3MayAbort(Parse *pParse){
 ** error. The onError parameter determines which (if any) of the statement
 ** and/or current transaction is rolled back.
 */
-void sqlite3HaltConstraint(Parse *pParse, int onError, char *p4, int p4type){
+void sqlite3HaltConstraint(
+  Parse *pParse,    /* Parsing context */
+  int errCode,      /* extended error code */
+  int onError,      /* Constraint type */
+  char *p4,         /* Error message */
+  int p4type        /* P4_STATIC or P4_TRANSIENT */
+){
   Vdbe *v = sqlite3GetVdbe(pParse);
+  assert( (errCode&0xff)==SQLITE_CONSTRAINT );
   if( onError==OE_Abort ){
     sqlite3MayAbort(pParse);
   }
-  sqlite3VdbeAddOp4(v, OP_Halt, SQLITE_CONSTRAINT, onError, 0, p4, p4type);
+  sqlite3VdbeAddOp4(v, OP_Halt, errCode, onError, 0, p4, p4type);
 }
 
 /*
index 5ba26169195556cb9e402549fe80db15cb173797..51fa03695178f056d84bbcfee2518a0cfeee1fde 100644 (file)
@@ -2935,7 +2935,8 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){
         sqlite3VdbeAddOp4(
             v, OP_Halt, SQLITE_OK, OE_Ignore, 0, pExpr->u.zToken,0);
       }else{
-        sqlite3HaltConstraint(pParse, pExpr->affinity, pExpr->u.zToken, 0);
+        sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_RAISE,
+                              pExpr->affinity, pExpr->u.zToken, 0);
       }
 
       break;
index 421311dc3562ad55f240ac3f2fdfe6de60c92124..ac35bc194cdeb127989b094035cee06f57376f5e 100644 (file)
@@ -21,8 +21,9 @@
 ** --------------------------
 **
 ** Foreign keys in SQLite come in two flavours: deferred and immediate.
-** If an immediate foreign key constraint is violated, SQLITE_CONSTRAINT
-** is returned and the current statement transaction rolled back. If a 
+** If an immediate foreign key constraint is violated,
+** SQLITE_CONSTRAINT_FOREIGNKEY is returned and the current
+** statement transaction rolled back. If a 
 ** deferred foreign key constraint is violated, no action is taken 
 ** immediately. However if the application attempts to commit the 
 ** transaction before fixing the constraint violation, the attempt fails.
@@ -86,7 +87,8 @@
 ** Immediate constraints are usually handled similarly. The only difference 
 ** is that the counter used is stored as part of each individual statement
 ** object (struct Vdbe). If, after the statement has run, its immediate
-** constraint counter is greater than zero, it returns SQLITE_CONSTRAINT
+** constraint counter is greater than zero,
+** it returns SQLITE_CONSTRAINT_FOREIGNKEY
 ** and the statement transaction is rolled back. An exception is an INSERT
 ** statement that inserts a single row only (no triggers). In this case,
 ** instead of using a counter, an exception is thrown immediately if the
@@ -426,8 +428,8 @@ static void fkLookupParent(
     ** incrementing a counter. This is necessary as the VM code is being
     ** generated for will not open a statement transaction.  */
     assert( nIncr==1 );
-    sqlite3HaltConstraint(
-        pParse, OE_Abort, "foreign key constraint failed", P4_STATIC
+    sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_FOREIGNKEY,
+        OE_Abort, "foreign key constraint failed", P4_STATIC
     );
   }else{
     if( nIncr>0 && pFKey->isDeferred==0 ){
@@ -667,8 +669,8 @@ void sqlite3FkDropTable(Parse *pParse, SrcList *pName, Table *pTab){
     ** any modifications to the schema are made. This is because statement
     ** transactions are not able to rollback schema changes.  */
     sqlite3VdbeAddOp2(v, OP_FkIfZero, 0, sqlite3VdbeCurrentAddr(v)+2);
-    sqlite3HaltConstraint(
-        pParse, OE_Abort, "foreign key constraint failed", P4_STATIC
+    sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_FOREIGNKEY,
+        OE_Abort, "foreign key constraint failed", P4_STATIC
     );
 
     if( iSkip ){
index 89a5dc8a13e71aeb98255546e306a9375cc4cbaf..9a5661f59a72952be6c167a0c2db159b91b71fae 100644 (file)
@@ -1245,7 +1245,7 @@ void sqlite3GenerateConstraintChecks(
       case OE_Fail: {
         char *zMsg;
         sqlite3VdbeAddOp3(v, OP_HaltIfNull,
-                                  SQLITE_CONSTRAINT, onError, regData+i);
+                          SQLITE_CONSTRAINT_NOTNULL, onError, regData+i);
         zMsg = sqlite3MPrintf(db, "%s.%s may not be NULL",
                               pTab->zName, pTab->aCol[i].zName);
         sqlite3VdbeChangeP4(v, -1, zMsg, P4_DYNAMIC);
@@ -1285,7 +1285,8 @@ void sqlite3GenerateConstraintChecks(
         }else{
           zConsName = 0;
         }
-        sqlite3HaltConstraint(pParse, onError, zConsName, P4_DYNAMIC);
+        sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_CHECK,
+                              onError, zConsName, P4_DYNAMIC);
       }
       sqlite3VdbeResolveLabel(v, allOk);
     }
@@ -1316,8 +1317,8 @@ void sqlite3GenerateConstraintChecks(
       case OE_Rollback:
       case OE_Abort:
       case OE_Fail: {
-        sqlite3HaltConstraint(
-          pParse, onError, "PRIMARY KEY must be unique", P4_STATIC);
+        sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_PRIMARYKEY,
+           onError, "PRIMARY KEY must be unique", P4_STATIC);
         break;
       }
       case OE_Replace: {
@@ -1444,7 +1445,8 @@ void sqlite3GenerateConstraintChecks(
         sqlite3StrAccumAppend(&errMsg,
             pIdx->nColumn>1 ? " are not unique" : " is not unique", -1);
         zErr = sqlite3StrAccumFinish(&errMsg);
-        sqlite3HaltConstraint(pParse, onError, zErr, 0);
+        sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_UNIQUE,
+                              onError, zErr, 0);
         sqlite3DbFree(errMsg.db, zErr);
         break;
       }
@@ -1852,8 +1854,8 @@ static int xferOptimization(
   if( pDest->iPKey>=0 ){
     addr1 = sqlite3VdbeAddOp2(v, OP_Rowid, iSrc, regRowid);
     addr2 = sqlite3VdbeAddOp3(v, OP_NotExists, iDest, 0, regRowid);
-    sqlite3HaltConstraint(
-        pParse, onError, "PRIMARY KEY must be unique", P4_STATIC);
+    sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_PRIMARYKEY,
+        onError, "PRIMARY KEY must be unique", P4_STATIC);
     sqlite3VdbeJumpHere(v, addr2);
     autoIncStep(pParse, regAutoinc, regRowid);
   }else if( pDest->pIndex==0 ){
index 48f7381212bed32136c21a3339662137e1f89bc5..3b55339ca87549318463e9213fdac9edaae585b7 100644 (file)
@@ -479,6 +479,15 @@ int sqlite3_exec(
 #define SQLITE_READONLY_RECOVERY       (SQLITE_READONLY | (1<<8))
 #define SQLITE_READONLY_CANTLOCK       (SQLITE_READONLY | (2<<8))
 #define SQLITE_ABORT_ROLLBACK          (SQLITE_ABORT | (2<<8))
+#define SQLITE_CONSTRAINT_UNIQUE       (SQLITE_CONSTRAINT | (1<<8))
+#define SQLITE_CONSTRAINT_RAISE        (SQLITE_CONSTRAINT | (2<<8))
+#define SQLITE_CONSTRAINT_FOREIGNKEY   (SQLITE_CONSTRAINT | (3<<8))
+#define SQLITE_CONSTRAINT_CHECK        (SQLITE_CONSTRAINT | (4<<8))
+#define SQLITE_CONSTRAINT_PRIMARYKEY   (SQLITE_CONSTRAINT | (5<<8))
+#define SQLITE_CONSTRAINT_NOTNULL      (SQLITE_CONSTRAINT | (6<<8))
+#define SQLITE_CONSTRAINT_COMMITHOOK   (SQLITE_CONSTRAINT | (7<<8))
+#define SQLITE_CONSTRAINT_VTAB         (SQLITE_CONSTRAINT | (8<<8))
+#define SQLITE_CONSTRAINT_FUNCTION     (SQLITE_CONSTRAINT | (9<<8))
 
 /*
 ** CAPI3REF: Flags For File Open Operations
index f036970931950a3e38f76835e1ff9a0e92bc8772..f936c0605c9c6269838d93cce8dc7e2cd8346a43 100644 (file)
@@ -2904,7 +2904,7 @@ int sqlite3OpenTableAndIndices(Parse*, Table*, int, int);
 void sqlite3BeginWriteOperation(Parse*, int, int);
 void sqlite3MultiWrite(Parse*);
 void sqlite3MayAbort(Parse*);
-void sqlite3HaltConstraint(Parse*, int, char*, int);
+void sqlite3HaltConstraint(Parse*, int, int, char*, int);
 Expr *sqlite3ExprDup(sqlite3*,Expr*,int);
 ExprList *sqlite3ExprListDup(sqlite3*,ExprList*,int);
 SrcList *sqlite3SrcListDup(sqlite3*,SrcList*,int);
index 889d0db21403a13667baa517d7aad07f1a218413..c8faa31dd1cfaca024b67ee4a7cc685d00fd1b36 100644 (file)
@@ -138,6 +138,18 @@ const char *sqlite3TestErrorName(int rc){
     case SQLITE_SCHEMA:              zName = "SQLITE_SCHEMA";            break;
     case SQLITE_TOOBIG:              zName = "SQLITE_TOOBIG";            break;
     case SQLITE_CONSTRAINT:          zName = "SQLITE_CONSTRAINT";        break;
+    case SQLITE_CONSTRAINT_UNIQUE:   zName = "SQLITE_CONSTRAINT_UNIQUE"; break;
+    case SQLITE_CONSTRAINT_RAISE:    zName = "SQLITE_CONSTRAINT_RAISE";  break;
+    case SQLITE_CONSTRAINT_FOREIGNKEY:
+                                 zName = "SQLITE_CONSTRAINT_FOREIGNKEY"; break;
+    case SQLITE_CONSTRAINT_CHECK:    zName = "SQLITE_CONSTRAINT_CHECK";  break;
+    case SQLITE_CONSTRAINT_PRIMARYKEY:
+                                 zName = "SQLITE_CONSTRAINT_PRIMARYKEY"; break;
+    case SQLITE_CONSTRAINT_NOTNULL:  zName = "SQLITE_CONSTRAINT_NOTNULL";break;
+    case SQLITE_CONSTRAINT_COMMITHOOK:
+                                 zName = "SQLITE_CONSTRAINT_COMMITHOOK"; break;
+    case SQLITE_CONSTRAINT_VTAB:     zName = "SQLITE_CONSTRAINT_VTAB";   break;
+    case SQLITE_CONSTRAINT_FUNCTION: zName = "SQLITE_CONSTRAINT_FUNCTION";break;
     case SQLITE_MISMATCH:            zName = "SQLITE_MISMATCH";          break;
     case SQLITE_MISUSE:              zName = "SQLITE_MISUSE";            break;
     case SQLITE_NOLFS:               zName = "SQLITE_NOLFS";             break;
index e59712157e0f6f99d2192a6af96bf405d26ab003..543dccbf66bb4b5c3a83a19ae7785b6b65991d31 100644 (file)
@@ -2673,7 +2673,7 @@ static int spellfix1Update(
       if( zCmd==0 ){
         pVTab->zErrMsg = sqlite3_mprintf("%s.word may not be NULL",
                                          p->zTableName);
-        return SQLITE_CONSTRAINT;
+        return SQLITE_CONSTRAINT_NOTNULL;
       }
       if( strcmp(zCmd,"reset")==0 ){
         /* Reset the  edit cost table (if there is one). */
index a2ab31e879a8cda8fada9fe6a9f685de93edbc87..b18661c1d396eaf2a4a6fb9d21a0faacf1eb9071 100644 (file)
@@ -869,7 +869,7 @@ case OP_Halt: {
   if( rc==SQLITE_BUSY ){
     p->rc = rc = SQLITE_BUSY;
   }else{
-    assert( rc==SQLITE_OK || p->rc==SQLITE_CONSTRAINT );
+    assert( rc==SQLITE_OK || (p->rc&0xff)==SQLITE_CONSTRAINT );
     assert( rc==SQLITE_OK || db->nDeferredCons>0 );
     rc = p->rc ? SQLITE_ERROR : SQLITE_DONE;
   }
@@ -6063,7 +6063,7 @@ case OP_VUpdate: {
       assert( nArg>1 && apArg[0] && (apArg[0]->flags&MEM_Null) );
       db->lastRowid = lastRowid = rowid;
     }
-    if( rc==SQLITE_CONSTRAINT && pOp->p4.pVtab->bConstraint ){
+    if( (rc&0xff)==SQLITE_CONSTRAINT && pOp->p4.pVtab->bConstraint ){
       if( pOp->p5==OE_Ignore ){
         rc = SQLITE_OK;
       }else{
index 3d1fa6ca6e0658e3686ca73abf4cc7e567e97f7e..cf9237f286871a87670f8eeae02e8e79a9fb6bfc 100644 (file)
@@ -367,7 +367,7 @@ int sqlite3VdbeAssertMayAbort(Vdbe *v, int mayAbort){
      || (opcode==OP_FkCounter && pOp->p1==0 && pOp->p2==1) 
 #endif
      || ((opcode==OP_Halt || opcode==OP_HaltIfNull) 
-      && (pOp->p1==SQLITE_CONSTRAINT && pOp->p2==OE_Abort))
+      && ((pOp->p1&0xff)==SQLITE_CONSTRAINT && pOp->p2==OE_Abort))
     ){
       hasAbort = 1;
       break;
@@ -1770,7 +1770,7 @@ static int vdbeCommit(sqlite3 *db, Vdbe *p){
   if( needXcommit && db->xCommitCallback ){
     rc = db->xCommitCallback(db->pCommitArg);
     if( rc ){
-      return SQLITE_CONSTRAINT;
+      return SQLITE_CONSTRAINT_COMMITHOOK;
     }
   }
 
@@ -2062,14 +2062,14 @@ int sqlite3VdbeCloseStatement(Vdbe *p, int eOp){
 ** violations, return SQLITE_ERROR. Otherwise, SQLITE_OK.
 **
 ** If there are outstanding FK violations and this function returns 
-** SQLITE_ERROR, set the result of the VM to SQLITE_CONSTRAINT and write
-** an error message to it. Then return SQLITE_ERROR.
+** SQLITE_ERROR, set the result of the VM to SQLITE_CONSTRAINT_FOREIGNKEY
+** and write an error message to it. Then return SQLITE_ERROR.
 */
 #ifndef SQLITE_OMIT_FOREIGN_KEY
 int sqlite3VdbeCheckFk(Vdbe *p, int deferred){
   sqlite3 *db = p->db;
   if( (deferred && db->nDeferredCons>0) || (!deferred && p->nFkConstraint>0) ){
-    p->rc = SQLITE_CONSTRAINT;
+    p->rc = SQLITE_CONSTRAINT_FOREIGNKEY;
     p->errorAction = OE_Abort;
     sqlite3SetString(&p->zErrMsg, db, "foreign key constraint failed");
     return SQLITE_ERROR;
@@ -2184,7 +2184,7 @@ int sqlite3VdbeHalt(Vdbe *p){
             sqlite3VdbeLeave(p);
             return SQLITE_ERROR;
           }
-          rc = SQLITE_CONSTRAINT;
+          rc = SQLITE_CONSTRAINT_FOREIGNKEY;
         }else{ 
           /* The auto-commit flag is true, the vdbe program was successful 
           ** or hit an 'OR FAIL' constraint and there are no deferred foreign
@@ -2227,7 +2227,7 @@ int sqlite3VdbeHalt(Vdbe *p){
     if( eStatementOp ){
       rc = sqlite3VdbeCloseStatement(p, eStatementOp);
       if( rc ){
-        if( p->rc==SQLITE_OK || p->rc==SQLITE_CONSTRAINT ){
+        if( p->rc==SQLITE_OK || (p->rc&0xff)==SQLITE_CONSTRAINT ){
           p->rc = rc;
           sqlite3DbFree(db, p->zErrMsg);
           p->zErrMsg = 0;