]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Fix the handling of "PRAGMA count_changes=ON" with UPSERT. Also improved
authordrh <drh@noemail.net>
Thu, 19 Apr 2018 23:52:39 +0000 (23:52 +0000)
committerdrh <drh@noemail.net>
Thu, 19 Apr 2018 23:52:39 +0000 (23:52 +0000)
the implementation of count_changes in other places, without changing the
behavior.

FossilOrigin-Name: c6f71115eb933c2aee295bc31e5139112463c28e15a3b3ea242fd9bac168aed9

manifest
manifest.uuid
src/delete.c
src/insert.c
src/update.c
test/upsert1.test

index dd60c0f6882dd5a21b962520a420cab3f9864e3a..333a1c93ac557ea18791c54aacb8359cb240a658 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Minor\ssimplification\sto\sthe\supsert\slogic.
-D 2018-04-19T21:29:52.191
+C Fix\sthe\shandling\sof\s"PRAGMA\scount_changes=ON"\swith\sUPSERT.\s\sAlso\simproved\nthe\simplementation\sof\scount_changes\sin\sother\splaces,\swithout\schanging\sthe\nbehavior.
+D 2018-04-19T23:52:39.113
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F Makefile.in 5ce9343cba9c189046f1afe6d2bcc1f68079439febc05267b98aec6ecc752439
@@ -443,7 +443,7 @@ F src/ctime.c 849d4cebe008cfc6e4799b034a172b4eaf8856b100739632a852732ba66eee48
 F src/date.c ebe1dc7c8a347117bb02570f1a931c62dd78f4a2b1b516f4837d45b7d6426957
 F src/dbpage.c 8db4c97f630e7d83f884ea75caf1ffd0988c160e9d530194d93721c80821e0f6
 F src/dbstat.c edabb82611143727511a45ca0859b8cd037851ebe756ae3db289859dd18b6f91
-F src/delete.c 20c8788451dc737a967c87ea53ad43544d617f5b57d32ccce8bd52a0daf9e89b
+F src/delete.c 333aca5587c690bbc460c9b2e6842e7080b1f7abac0e6ca4d3f82c2aea328def
 F src/expr.c 53df437b3a4a404f039645919b2d6a56a2f59b9883e858940cd2a8858a25cd3d
 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
 F src/fkey.c d617daf66b5515e2b42c1405b2b4984c30ca50fb705ab164271a9bf66c69e331
@@ -453,7 +453,7 @@ F src/hash.c a12580e143f10301ed5166ea4964ae2853d3905a511d4e0c44497245c7ce1f7a
 F src/hash.h ab34c5c54a9e9de2e790b24349ba5aab3dbb4fd4
 F src/hwtime.h 747c1bbe9df21a92e9c50f3bbec1de841dc5e5da
 F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71
-F src/insert.c b382941c8f86cda8aa91452e80d02cea2c2631d52ab7cf7523314ee46bab7f39
+F src/insert.c 87b1854f48145d1db15b97128922348d90fbb2a0bd317e4d0ad6eee1361f4b66
 F src/legacy.c 134ab3e3fae00a0f67a5187981d6935b24b337bcf0f4b3e5c9fa5763da95bf4e
 F src/loadext.c f6e4e416a736369f9e80eba609f0acda97148a8b0453784d670c78d3eed2f302
 F src/main.c 10e3897f5d78cef6bcbd1eedc8ccc3fe9e9783d07e052d9d70e57364ded19274
@@ -557,7 +557,7 @@ F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c
 F src/tokenize.c 5b0c661a85f783d35b9883830736eeb63be4aefc4f6b7d9cd081d48782c041e2
 F src/treeview.c 14d5d1254702ec96876aa52642cb31548612384134970409fae333b25b39d6bb
 F src/trigger.c 4ace6d1d5ba9a89822deb287317f33c810440526eafe185c2d8a48c31df1e995
-F src/update.c 5787acf0a12a20cf31c0c50db644a667590f720e404b3616bc2efeb9bd5bbc06
+F src/update.c cc691c8b63b22be9e00d6fa2d1c5d561a5cee871f4ed5c456762398c6c991d05
 F src/upsert.c ee5c9e44fac181e86a561c2d315c28f4c0f94e9d3283544bd39aa0e201b0c61c
 F src/utf.c 810fbfebe12359f10bc2a011520a6e10879ab2a163bcb26c74768eab82ea62a5
 F src/util.c d9eb0a6c4aae1b00a7369eadd7ca0bbe946cb4c953b6751aa20d357c2f482157
@@ -1509,7 +1509,7 @@ F test/unixexcl.test d936ba2b06794018e136418addd59a2354eeae97
 F test/unordered.test ca7adce0419e4ca0c50f039885e76ed2c531eda8
 F test/update.test 1148de8d913e9817717990603aadeca07aab9ddbb10a30f167cbfd8d3a3ccb60
 F test/update2.test 5e67667e1c54017d964e626db765cf8bedcf87483c184f4c575bdb8c1dd2313e
-F test/upsert1.test 3b4e8e5932516115bfffb2269a44c416c5c26d0d57cc7dd16954d0b77fbc4cd9
+F test/upsert1.test 934315888a04b4e119ebb6abf558d92bf01d9f94fc8ff0bbc1c7c6015005340f
 F test/upsert2.test 9c3cdbb1a890227f6504ce4b0e3de68f4cdfa16bb21d8641208a9239896c5a09
 F test/upsert3.test 88d7d590a1948a9cb6eac1b54b0642f67a9f35a1fc0f19b200e97d5d39e3179c
 F test/upsert4.test 83b37a92f315217c9319f320966c044ddccf8bc525501fa09e2ee47779e3920b
@@ -1724,7 +1724,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
 F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P 893e6089c875e947ddadb23f031a81bc36da8b060d2212363098992ddb90378b
-R 55c8d974783bb4b8502a146618675105
+P e657c1d60f5fca9464e9bcab24bc328855bec9986e0a029877f639355da4b201
+R 7cdcf758f67dbc731422788f5f4662ec
 U drh
-Z 7c8bbf0c90fa7ebf24724a77ea4ecc1b
+Z 0ab3e82b91f879d52dd2122af2ad30bf
index 08b688798fc962f6c8506cc3cd0aa97df4139264..0a2e1812744da4aa800ee449f0153fc146f71d75 100644 (file)
@@ -1 +1 @@
-e657c1d60f5fca9464e9bcab24bc328855bec9986e0a029877f639355da4b201
\ No newline at end of file
+c6f71115eb933c2aee295bc31e5139112463c28e15a3b3ea242fd9bac168aed9
\ No newline at end of file
index 2b69e4763af11ae7b9cd403c6062e25ff36a63ce..7a33fcf6cd1298d0894ed412c96f6286427f4bb7 100644 (file)
@@ -238,7 +238,7 @@ void sqlite3DeleteFrom(
   AuthContext sContext;  /* Authorization context */
   NameContext sNC;       /* Name context to resolve expressions in */
   int iDb;               /* Database number */
-  int memCnt = -1;       /* Memory cell used for change counting */
+  int memCnt = 0;        /* Memory cell used for change counting */
   int rcauth;            /* Value returned by authorization callback */
   int eOnePass;          /* ONEPASS_OFF or _SINGLE or _MULTI */
   int aiCurOnePass[2];   /* The write cursors opened by WHERE_ONEPASS */
@@ -371,7 +371,10 @@ void sqlite3DeleteFrom(
   /* Initialize the counter of the number of rows deleted, if
   ** we are counting rows.
   */
-  if( db->flags & SQLITE_CountRows ){
+  if( (db->flags & SQLITE_CountRows)!=0
+   && !pParse->nested
+   && !pParse->pTriggerTab
+  ){
     memCnt = ++pParse->nMem;
     sqlite3VdbeAddOp2(v, OP_Integer, 0, memCnt);
   }
@@ -399,7 +402,7 @@ void sqlite3DeleteFrom(
     assert( !isView );
     sqlite3TableLock(pParse, iDb, pTab->tnum, 1, pTab->zName);
     if( HasRowid(pTab) ){
-      sqlite3VdbeAddOp4(v, OP_Clear, pTab->tnum, iDb, memCnt,
+      sqlite3VdbeAddOp4(v, OP_Clear, pTab->tnum, iDb, memCnt ? memCnt : -1,
                         pTab->zName, P4_STATIC);
     }
     for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
@@ -446,7 +449,7 @@ void sqlite3DeleteFrom(
     assert( IsVirtual(pTab) || bComplex || eOnePass!=ONEPASS_OFF );
   
     /* Keep track of the number of rows to be deleted */
-    if( db->flags & SQLITE_CountRows ){
+    if( memCnt ){
       sqlite3VdbeAddOp2(v, OP_AddImm, memCnt, 1);
     }
   
@@ -589,7 +592,7 @@ void sqlite3DeleteFrom(
   ** generating code because of a call to sqlite3NestedParse(), do not
   ** invoke the callback function.
   */
-  if( (db->flags&SQLITE_CountRows) && !pParse->nested && !pParse->pTriggerTab ){
+  if( memCnt ){
     sqlite3VdbeAddOp2(v, OP_ResultRow, memCnt, 1);
     sqlite3VdbeSetNumCols(v, 1);
     sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows deleted", SQLITE_STATIC);
index e522d4664fe57077b3e8e63190ade11921b900ef..b3a313836e6170e1d9efffbbfbf006320b043d5b 100644 (file)
@@ -784,7 +784,10 @@ void sqlite3Insert(
     
   /* Initialize the count of rows to be inserted
   */
-  if( db->flags & SQLITE_CountRows ){
+  if( (db->flags & SQLITE_CountRows)!=0
+   && !pParse->nested
+   && !pParse->pTriggerTab
+  ){
     regRowCount = ++pParse->nMem;
     sqlite3VdbeAddOp2(v, OP_Integer, 0, regRowCount);
   }
@@ -1040,7 +1043,7 @@ void sqlite3Insert(
 
   /* Update the count of rows that are inserted
   */
-  if( (db->flags & SQLITE_CountRows)!=0 ){
+  if( regRowCount ){
     sqlite3VdbeAddOp2(v, OP_AddImm, regRowCount, 1);
   }
 
@@ -1077,7 +1080,7 @@ insert_end:
   ** generating code because of a call to sqlite3NestedParse(), do not
   ** invoke the callback function.
   */
-  if( (db->flags&SQLITE_CountRows) && !pParse->nested && !pParse->pTriggerTab ){
+  if( regRowCount ){
     sqlite3VdbeAddOp2(v, OP_ResultRow, regRowCount, 1);
     sqlite3VdbeSetNumCols(v, 1);
     sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows inserted", SQLITE_STATIC);
index 4da63a98ec76db383b3445402020510483cf12fc..c817153e8e8e9901b04f1f181383050c20f3ffc4 100644 (file)
@@ -384,7 +384,11 @@ void sqlite3Update(
 #endif
 
   /* Initialize the count of updated rows */
-  if( (db->flags & SQLITE_CountRows) && !pParse->pTriggerTab ){
+  if( (db->flags&SQLITE_CountRows)!=0
+   && !pParse->pTriggerTab
+   && !pParse->nested
+   && !pUpsert
+  ){
     regRowCount = ++pParse->nMem;
     sqlite3VdbeAddOp2(v, OP_Integer, 0, regRowCount);
   }
@@ -699,7 +703,7 @@ void sqlite3Update(
 
   /* Increment the row counter 
   */
-  if( (db->flags & SQLITE_CountRows) && !pParse->pTriggerTab){
+  if( regRowCount ){
     sqlite3VdbeAddOp2(v, OP_AddImm, regRowCount, 1);
   }
 
@@ -731,11 +735,10 @@ void sqlite3Update(
   }
 
   /*
-  ** Return the number of rows that were changed. If this routine is 
-  ** generating code because of a call to sqlite3NestedParse(), do not
-  ** invoke the callback function.
+  ** Return the number of rows that were changed, if we are tracking
+  ** that information.
   */
-  if( (db->flags&SQLITE_CountRows) && !pParse->pTriggerTab && !pParse->nested ){
+  if( regRowCount ){
     sqlite3VdbeAddOp2(v, OP_ResultRow, regRowCount, 1);
     sqlite3VdbeSetNumCols(v, 1);
     sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows updated", SQLITE_STATIC);
index 8b53fe0c15bfb79fc00acfb4565524db08533c5b..c9139f1163998672b34971dc15bd40093576b11d 100644 (file)
@@ -89,4 +89,19 @@ do_execsql_test upsert1-320 {
   SELECT *, 'x' FROM t1 ORDER BY b, a;
 } {1 2 0 x 3 2 0 x 4 20 0 x}
 
+# Upsert works with count_changes=on;
+do_execsql_test upsert1-400 {
+  DROP TABLE IF EXISTS t2;
+  CREATE TABLE t2(a TEXT UNIQUE, b INT DEFAULT 1);
+  INSERT INTO t2(a) VALUES('one'),('two'),('three');
+  PRAGMA count_changes=ON;
+  INSERT INTO t2(a) VALUES('one'),('one'),('three'),('four')
+      ON CONFLICT(a) DO UPDATE SET b=b+1;
+} {1}
+do_execsql_test upsert1-410 {
+  PRAGMA count_changes=OFF;
+  SELECT a, b FROM t2 ORDER BY a;
+} {four 1 one 3 three 2 two 1}
+
+
 finish_test