mirror of
https://github.com/sqlite/sqlite.git
synced 2025-07-30 19:03:16 +03:00
Fix the handling of "PRAGMA count_changes=ON" with UPSERT. Also improved
the implementation of count_changes in other places, without changing the behavior. FossilOrigin-Name: c6f71115eb933c2aee295bc31e5139112463c28e15a3b3ea242fd9bac168aed9
This commit is contained in:
18
manifest
18
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
|
||||
|
@ -1 +1 @@
|
||||
e657c1d60f5fca9464e9bcab24bc328855bec9986e0a029877f639355da4b201
|
||||
c6f71115eb933c2aee295bc31e5139112463c28e15a3b3ea242fd9bac168aed9
|
13
src/delete.c
13
src/delete.c
@ -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);
|
||||
|
@ -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);
|
||||
|
15
src/update.c
15
src/update.c
@ -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);
|
||||
|
@ -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
|
||||
|
Reference in New Issue
Block a user