Omit NOT NULL checks on unchanging columns in an UPDATE.

FossilOrigin-Name: 6a3aaedfb41735996470abbae6d3cd1be1f508b3
diff --git a/manifest b/manifest
index 6b82b46..b811604 100644
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C When\sgenerating\sthe\ssnapshot-tarball,\struncate\sthe\sdate/time\sin\sthe\sname\sto\s\n12\ssignificant\sdigits\s(YYYYMMDDhhmm)\somitting\sthe\sseconds\sand\sfractional\nseconds.
-D 2016-02-10T13:36:17.175
+C Omit\sNOT\sNULL\schecks\son\sunchanging\scolumns\sin\san\sUPDATE.
+D 2016-02-10T16:03:20.793
 F Makefile.in 4e90dc1521879022aa9479268a4cd141d1771142
 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
 F Makefile.msc 0fe3b22f8e29bcde0533ada7957a5f15835d797a
@@ -309,7 +309,7 @@
 F src/hash.c 4263fbc955f26c2e8cdc0cf214bc42435aa4e4f5
 F src/hash.h c8f3c31722cf3277d03713909761e152a5b81094
 F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08
-F src/insert.c 046199e085e69e05af7bef197d53c5b4b402b6fa
+F src/insert.c f2e7592be43c7101ee8b991ff1cd976f027f7eb9
 F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d
 F src/legacy.c b1b0880fc474abfab89e737b0ecfde0bd7a60902
 F src/loadext.c 84996d7d70a605597d79c1f1d7b2012a5fd34f2b
@@ -353,7 +353,7 @@
 F src/sqlite.h.in cf22ad1d52dca2c9862d63833e581028119aab7e
 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
 F src/sqlite3ext.h dfbe62ffd95b99afe2140d8c35b180d11924072d
-F src/sqliteInt.h b1850d30a1333de1df076eca979683f696f9d4b4
+F src/sqliteInt.h 8eff197a6c0934e19f34c1b072bc4abd48bfee6b
 F src/sqliteLimit.h 216557999cb45f2e3578ed53ebefe228d779cb46
 F src/status.c 70912d7be68e9e2dbc4010c93d344af61d4c59ba
 F src/table.c 51b46b2a62d1b3a959633d593b89bab5e2c9155e
@@ -409,7 +409,7 @@
 F src/tokenize.c 813934be70597edfbb685ae08fc4c8b549cf5a1e
 F src/treeview.c dc39ccf04e9331237388b9cb73289c9d87ea050b
 F src/trigger.c e14840ee0c3e549e758ec9bf3e4146e166002280
-F src/update.c 310ca7adb86a7d1f2afae46905b21c83580f3e17
+F src/update.c a7eeeaffad59c6506f01303a071dac11de8269ca
 F src/utf.c 10cc2519e82e3369344d0969ad4b1a333dc86d18
 F src/util.c 49ce0a65306c1c51d61cb5bc214c71cb62452de6
 F src/vacuum.c 2ddd5cad2a7b9cef7f9e431b8c7771634c6b1701
@@ -1427,7 +1427,7 @@
 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b
 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
-P a3e911e3aa3e35446bed7f300bfe03f66e1494db
-R 30240c9ea7a51d9fb3097cfc2aff9b45
+P 604f77754797a4066f6cf275c7bc8a68d2839c2d
+R 311aef0cc6bd481061bf1dc7cd93a2e3
 U drh
-Z 38d599a4bb70ac4c3aebf51493f6b3e5
+Z 273046c163b5169406e9a0408477555f
diff --git a/manifest.uuid b/manifest.uuid
index c9229ce..d0a34f8 100644
--- a/manifest.uuid
+++ b/manifest.uuid
@@ -1 +1 @@
-604f77754797a4066f6cf275c7bc8a68d2839c2d
\ No newline at end of file
+6a3aaedfb41735996470abbae6d3cd1be1f508b3
\ No newline at end of file
diff --git a/src/insert.c b/src/insert.c
index 650f397..95321cd 100644
--- a/src/insert.c
+++ b/src/insert.c
@@ -995,7 +995,7 @@
     {
       int isReplace;    /* Set to true if constraints may cause a replace */
       sqlite3GenerateConstraintChecks(pParse, pTab, aRegIdx, iDataCur, iIdxCur,
-          regIns, 0, ipkColumn>=0, onError, endOfLoop, &isReplace
+          regIns, 0, ipkColumn>=0, onError, endOfLoop, &isReplace, 0
       );
       sqlite3FkCheck(pParse, pTab, 0, regIns, 0, 0);
       sqlite3CompleteInsertion(pParse, pTab, iDataCur, iIdxCur,
@@ -1171,7 +1171,8 @@
   u8 pkChng,           /* Non-zero if the rowid or PRIMARY KEY changed */
   u8 overrideError,    /* Override onError to this if not OE_Default */
   int ignoreDest,      /* Jump to this label on an OE_Ignore resolution */
-  int *pbMayReplace    /* OUT: Set to true if constraint may cause a replace */
+  int *pbMayReplace,   /* OUT: Set to true if constraint may cause a replace */
+  int *aiChng          /* column i is unchanged if aiChng[i]<0 */
 ){
   Vdbe *v;             /* VDBE under constrution */
   Index *pIdx;         /* Pointer to one of the indices */
@@ -1217,10 +1218,14 @@
   */
   for(i=0; i<nCol; i++){
     if( i==pTab->iPKey ){
+      continue;        /* ROWID is never NULL */
+    }
+    if( aiChng && aiChng[i]<0 ){
+      /* Don't bother checking for NOT NULL on columns that do not change */
       continue;
     }
     onError = pTab->aCol[i].notNull;
-    if( onError==OE_None ) continue;
+    if( onError==OE_None ) continue;  /* This column is allowed to be NULL */
     if( overrideError!=OE_Default ){
       onError = overrideError;
     }else if( onError==OE_Default ){
diff --git a/src/sqliteInt.h b/src/sqliteInt.h
index f86e9da..ef80e8d 100644
--- a/src/sqliteInt.h
+++ b/src/sqliteInt.h
@@ -3545,7 +3545,7 @@
 int sqlite3GenerateIndexKey(Parse*, Index*, int, int, int, int*,Index*,int);
 void sqlite3ResolvePartIdxLabel(Parse*,int);
 void sqlite3GenerateConstraintChecks(Parse*,Table*,int*,int,int,int,int,
-                                     u8,u8,int,int*);
+                                     u8,u8,int,int*,int*);
 void sqlite3CompleteInsertion(Parse*,Table*,int,int,int,int*,int,int,int);
 int sqlite3OpenTableAndIndices(Parse*, Table*, int, u8, int, u8*, int*, int*);
 void sqlite3BeginWriteOperation(Parse*, int, int);
diff --git a/src/update.c b/src/update.c
index 20951aa..2a436b9 100644
--- a/src/update.c
+++ b/src/update.c
@@ -572,7 +572,8 @@
     /* Do constraint checks. */
     assert( regOldRowid>0 );
     sqlite3GenerateConstraintChecks(pParse, pTab, aRegIdx, iDataCur, iIdxCur,
-        regNewRowid, regOldRowid, chngKey, onError, labelContinue, &bReplace);
+        regNewRowid, regOldRowid, chngKey, onError, labelContinue, &bReplace,
+        aXRef);
 
     /* Do FK constraint checks. */
     if( hasFK ){